@jetcrab/pi-desk 1.1.33 → 1.1.38-dev
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -10
- package/README.zh-CN.md +10 -10
- package/docs/commands.md +13 -2
- package/docs/plugins.md +10 -0
- package/package.json +3 -3
- package/src/client/l2_biz/pi-settings/l2-pi-settings-locale.ts +3 -3
- package/src/client/l2_biz/plugin-host/l2-plugin-host-runtime.ts +5 -6
- package/src/client/l2_biz/settings/l2-region-settings.tsx +30 -9
- package/src/client/l3_modules/region/l3-region-biz.ts +2 -2
- package/src/client/l4_foundation/plugin-host/l4-plugin-host-runtime.ts +20 -2
- package/src/common/l2_biz/plugin/l2-plugin-management-messages.ts +29 -17
- package/src/common/l2_biz/project-preview/l2-project-history-messages.ts +9 -7
- package/src/common/l2_biz/settings/l2-settings-messages.ts +82 -69
- package/src/common/l2_biz/terminal/l2-terminal-locale-messages.ts +1 -1
- package/src/common/l2_biz/workbench/l2-workbench-locale-messages.ts +48 -38
- package/src/common/l2_biz/workbench/l2-workbench-picker-messages.ts +12 -8
- package/src/common/l3_modules/conversation/l3-conversation-locale-messages.ts +24 -20
- package/src/common/l3_modules/project-files/l3-project-files-locale-messages.ts +29 -17
- package/src/common/l4_foundation/locale/l4-host-error-messages.ts +5 -5
- package/src/server/l2_biz/plugin-management/l2-plugin-commands.ts +8 -7
- package/src/server/l2_biz/plugin-management/l2-plugin-management.ts +51 -2
- package/src/server/l4_foundation/pi/l4-pi-global-plugin-runtime.ts +9 -1
- package/src/server/l4_foundation/pi/l4-pi-local-extension-maintenance.ts +118 -0
- package/src/server/l4_foundation/pi/l4-pi-plugin-owner-runtime.ts +4 -1
- package/src/server/l4_foundation/pi/l4-pi-plugin-source-changes.ts +4 -0
- package/src/server/l4_foundation/pidesk/l4-pidesk-command.ts +1 -1
- package/temp/build/pi-desk/release/.next/BUILD_ID +1 -1
- package/temp/build/pi-desk/release/.next/build-manifest.json +2 -2
- package/temp/build/pi-desk/release/.next/prerender-manifest.json +3 -3
- package/temp/build/pi-desk/release/.next/required-server-files.js +3 -3
- package/temp/build/pi-desk/release/.next/required-server-files.json +3 -3
- package/temp/build/pi-desk/release/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/_global-error.html +1 -1
- package/temp/build/pi-desk/release/.next/server/app/_global-error.rsc +1 -1
- package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/temp/build/pi-desk/release/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/health/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/page.js +3 -3
- package/temp/build/pi-desk/release/.next/server/app/page_client-reference-manifest.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/project-preview/page_client-reference-manifest.js +1 -1
- package/temp/build/pi-desk/release/.next/server/chunks/16438.js +1 -1
- package/temp/build/pi-desk/release/.next/server/chunks/25406.js +2 -2
- package/temp/build/pi-desk/release/.next/server/chunks/35985.js +2 -2
- package/temp/build/pi-desk/release/.next/server/chunks/36361.js +3 -3
- package/temp/build/pi-desk/release/.next/server/chunks/47757.js +1 -1
- package/temp/build/pi-desk/release/.next/server/chunks/50520.js +2 -2
- package/temp/build/pi-desk/release/.next/server/chunks/84231.js +3 -3
- package/temp/build/pi-desk/release/.next/server/chunks/{18748.js → 88353.js} +1 -1
- package/temp/build/pi-desk/release/.next/server/chunks/92386.js +4 -4
- package/temp/build/pi-desk/release/.next/server/instrumentation.js +1 -1
- package/temp/build/pi-desk/release/.next/server/middleware-build-manifest.js +1 -1
- package/temp/build/pi-desk/release/.next/server/pages/500.html +1 -1
- package/temp/build/pi-desk/release/.next/server/server-reference-manifest.json +1 -1
- package/temp/build/pi-desk/release/.next/static/chunks/11937-c21edad81915b999.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/15302-e9fd56a464b5267b.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/layout-1ec03fc5766568f6.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/page-402842ab5d6afb08.js +158 -0
- package/temp/build/pi-desk/release/.next/trace-build +1 -1
- package/temp/build/pi-desk/release/.next/static/chunks/11937-d5d4d2199356c3ed.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/15302-6e070e13fa65c863.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/layout-fdea504082053156.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/page-eb5c2229f59dda1a.js +0 -158
- /package/temp/build/pi-desk/release/.next/static/{IDVi-aOj0xwp4DoZljk5f → ljXlpZIQpD6BvWyD8Fmc3}/_buildManifest.js +0 -0
- /package/temp/build/pi-desk/release/.next/static/{IDVi-aOj0xwp4DoZljk5f → ljXlpZIQpD6BvWyD8Fmc3}/_ssgManifest.js +0 -0
package/README.md
CHANGED
|
@@ -87,16 +87,16 @@ Open **<http://localhost:6233>**.
|
|
|
87
87
|
|
|
88
88
|
The web service runs Pi sessions. Browser, desktop, and mobile clients connect to the same service.
|
|
89
89
|
|
|
90
|
-
| Application
|
|
91
|
-
|
|
|
92
|
-
| Web service
|
|
93
|
-
| Windows
|
|
94
|
-
| macOS
|
|
95
|
-
| Android
|
|
96
|
-
| iOS (experimental)
|
|
97
|
-
| Tunnel
|
|
98
|
-
|
|
99
|
-
>
|
|
90
|
+
| Application | Source | Purpose |
|
|
91
|
+
| ------------------ | ----------------------------------- | --------------------------------- |
|
|
92
|
+
| Web service | [`src/`](./src) and [`bin/`](./bin) | Browser client and Pi integration |
|
|
93
|
+
| Windows | [`apps/desktop/`](./apps/desktop) | Tauri desktop shell |
|
|
94
|
+
| macOS | [`apps/desktop/`](./apps/desktop) | Tauri desktop shell |
|
|
95
|
+
| Android | [`apps/android/`](./apps/android) | Native Android client for Pi Desk |
|
|
96
|
+
| iOS (experimental) | [`apps/ios/`](./apps/ios) | SwiftUI / WKWebView client |
|
|
97
|
+
| Tunnel | [`apps/tunnel/`](./apps/tunnel) | Rust TCP tunnel server and client |
|
|
98
|
+
|
|
99
|
+
> iOS clients are experimental and are not included in stable releases. The author does not own an iOS device, so these clients have not been tested on real hardware and may not work.
|
|
100
100
|
|
|
101
101
|
## Plugins and SDK
|
|
102
102
|
|
package/README.zh-CN.md
CHANGED
|
@@ -87,16 +87,16 @@ pi-desk
|
|
|
87
87
|
|
|
88
88
|
Web 服务负责运行 Pi 会话,浏览器、桌面和手机客户端连接同一个服务。
|
|
89
89
|
|
|
90
|
-
| 应用
|
|
91
|
-
|
|
|
92
|
-
| Web 服务
|
|
93
|
-
| Windows
|
|
94
|
-
| macOS
|
|
95
|
-
| Android
|
|
96
|
-
| iOS(实验性)
|
|
97
|
-
| 隧道
|
|
98
|
-
|
|
99
|
-
>
|
|
90
|
+
| 应用 | 源码 | 用途 |
|
|
91
|
+
| ------------- | ---------------------------------- | ---------------------------------- |
|
|
92
|
+
| Web 服务 | [`src/`](./src) 与 [`bin/`](./bin) | 浏览器客户端与 Pi 集成 |
|
|
93
|
+
| Windows | [`apps/desktop/`](./apps/desktop) | Tauri 桌面壳 |
|
|
94
|
+
| macOS | [`apps/desktop/`](./apps/desktop) | Tauri 桌面壳 |
|
|
95
|
+
| Android | [`apps/android/`](./apps/android) | 连接 Pi Desk 的原生 Android 客户端 |
|
|
96
|
+
| iOS(实验性) | [`apps/ios/`](./apps/ios) | SwiftUI / WKWebView 客户端 |
|
|
97
|
+
| 隧道 | [`apps/tunnel/`](./apps/tunnel) | Rust TCP 隧道服务与客户端 |
|
|
98
|
+
|
|
99
|
+
> iOS 客户端目前为实验性支持,尚未纳入稳定版本。作者没有 iOS 设备,未进行实机验证,可能无法正常使用。
|
|
100
100
|
|
|
101
101
|
## 插件与 SDK
|
|
102
102
|
|
package/docs/commands.md
CHANGED
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
| 安装并跟随 dev | `["plugins", "install", "<name>", "--scope", "global", "--tag", "dev"]` |
|
|
40
40
|
| 安装指定 npm 版本 | `["plugins", "install", "<name>", "--scope", "global", "--version", "1.2.3"]` |
|
|
41
41
|
| 重载已安装插件当前代码 | `["plugins", "reload", "<name-1>", "<name-2>", "--scope", "global"]` |
|
|
42
|
-
|
|
|
42
|
+
| 卸载插件并释放实例 | `["plugins", "remove", "<name-1>", "<name-2>", "--scope", "global"]` |
|
|
43
43
|
|
|
44
44
|
`install` 包含首次安装、更新和重装;目标版本已安装也会重装。`reload` 只重新加载本机现有码,不下载、不修改版本或渠道、不重启宿主,也不重载已有 Pi 会话;它不接受 `--version` 或 `--tag`。
|
|
45
45
|
|
|
@@ -59,7 +59,18 @@
|
|
|
59
59
|
- `list --check-updates` 不安装;附加 `--tag dev` 只筛选跟随 dev 的插件,不改变渠道。标签缺失或查询失败报告对应项错误,不回退 `latest`。
|
|
60
60
|
- 只调整渠道而不安装:在插件管理界面多选后使用“设置渠道”。
|
|
61
61
|
|
|
62
|
-
包文件与 Pi `settings.json`
|
|
62
|
+
包文件与 Pi `settings.json` 由官方包管理器维护,不手动覆盖安装目录或包声明。
|
|
63
|
+
|
|
64
|
+
### 卸载
|
|
65
|
+
|
|
66
|
+
`remove` 在同一操作中等待目标调用结束、撤销 Node/Browser 注册、等待有界清理,再移除来源;成功通知表示该来源已从管理清单移除,不清理业务配置和业务数据。
|
|
67
|
+
|
|
68
|
+
- 包来源沿用官方 Pi 包卸载;本地目录形式的包不会被当作裸扩展删除源码。
|
|
69
|
+
- `<AgentDir>/extensions/` 中的本地扩展会删除对应的直接文件或目录;符号链接只删除链接,保留目标源码。
|
|
70
|
+
- 全局配置精确引用的外部扩展只移除加载声明,保留外部源码。无法精确拆分的模式规则需先调整原规则,不新增禁用项代替卸载。
|
|
71
|
+
- 目录已删除但仍有已应用来源记录时,清单保留原名称,可用 `remove` 释放残留实例并移除记录,然后加载同名新来源。
|
|
72
|
+
|
|
73
|
+
卸载不会自动重载已有 Pi 会话的 Native 工具;需要已有会话采用移除结果时使用 `session reload`。
|
|
63
74
|
|
|
64
75
|
## 让已有会话采用当前配置
|
|
65
76
|
|
package/docs/plugins.md
CHANGED
|
@@ -339,6 +339,16 @@ try {
|
|
|
339
339
|
|
|
340
340
|
## 更新生效
|
|
341
341
|
|
|
342
|
+
插件界面可在用户点击按钮后重载指定会话的 Pi 配置:
|
|
343
|
+
|
|
344
|
+
```ts
|
|
345
|
+
if (!host.pi.reload) throw new Error('请使用输入框「更多 → 重载 Pi 配置」')
|
|
346
|
+
await host.pi.reload(target.source.workId)
|
|
347
|
+
// 确认视图仍有效后,调用自己的 Session Method 重新查询。
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
`reload(workId: string): Promise<void>` 等同输入框「更多 → 重载 Pi 配置」,宿主按 workId 查找调用时工作窗口当前绑定的 Pi 会话,保留其聊天历史、sessionId 和当前分支,重新加载配置、Skills 及已安装插件的本机代码;插件无需指定 sessionId 或 branchId。不下载包、不重载 Node/Browser Entry、不刷新网页。仅人工操作触发,不在 mount、缺少方法或重连时自动执行。会话忙碌、workId 不存在或 Browser Owner 失效时拒绝;传输期间绑定变化仍由现有重载流程校验并返回错误,断线或超时结果未知时不得自动重试。Promise 等待重载流程结束,不保证每个插件成功加载;结束后重新查询功能状态,仍不可用时保留错误和手动恢复入口。调用期间禁用重复操作;关闭视图不取消已提交重载,迟到结果不得更新旧视图。旧宿主可能没有可选 `host.pi.reload`,缺失时引导使用宿主菜单;不能只更新 SDK 依赖就获得此能力。
|
|
351
|
+
|
|
342
352
|
包维护不阻塞聊天订阅、刷新或其他会话。缺失或版本不符的包会被跳过,导入/工厂失败的入口不加载;Pi 生命周期回调和插件 Provider 注册的明确错误保留在插件管理诊断中,不升级为整会话失败。正常扩展继续加载。此隔离不终止同步死循环,也不回滚插件已发生的外部副作用;整体初始化超时仍可能使当前会话回退基础聊天,不阻塞其他会话的历史同步。
|
|
343
353
|
|
|
344
354
|
`plugins install/reload` 应用 Node/Browser 能力;目标插件活动视图重挂,旧 Browser Owner 失效。现有 Native 会话不自动重载,新 UI 可能连接旧会话方法,需兼容既有消息和方法数据;需要现有会话加载当前原生代码时使用 `session reload`。热加载无法处理的资源按宿主已有重启流程处理,不把重新挂载界面当作后端任务已停止。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jetcrab/pi-desk",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.38-dev",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"viewerjs": "^1.11.8",
|
|
71
71
|
"ws": "^8.21.3",
|
|
72
72
|
"zod": "^4.4.3",
|
|
73
|
-
"@jetcrab/pi-desk-sdk": "^1.1.
|
|
73
|
+
"@jetcrab/pi-desk-sdk": "^1.1.14-dev"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
76
|
"@earendil-works/pi-agent-core": "1.2.0",
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
"build:plugin-host-runtime": "pnpm --filter @jetcrab/pi-desk-sdk build",
|
|
113
113
|
"start": "node bin/pi-desk.js --no-open",
|
|
114
114
|
"test:package": "node --test tests/l4-pi-desk-package.test.mjs",
|
|
115
|
-
"test:pidesk": "node --import tsx --test --test-concurrency=1 tests/l4-pidesk-command.test.ts tests/l2-plugin-commands.test.ts tests/l4-pidesk-session-reload.test.ts tests/l4-pidesk-runtime.test.ts tests/l4-pidesk-runtime-bundle.test.mjs tests/l4-pidesk-docs.test.mjs tests/l4-pidesk-installed-runners.test.mjs tests/l4-pidesk-package-maintenance.test.ts tests/l4-pidesk-release-gate.test.mjs tests/l4-pi-desk-process-tree.test.mjs tests/l4-pi-runner-process.test.ts tests/l4-pi-global-runtime.test.mjs tests/l4-pi-desk-supervisor-cli.test.mjs",
|
|
115
|
+
"test:pidesk": "node --import tsx --test --test-concurrency=1 tests/l4-pidesk-command.test.ts tests/l2-plugin-commands.test.ts tests/l2-plugin-management-remove.test.ts tests/l2-plugin-management-batch.test.ts tests/l4-pi-local-extension-maintenance.test.ts tests/l4-pidesk-session-reload.test.ts tests/l4-pidesk-runtime.test.ts tests/l4-pidesk-runtime-bundle.test.mjs tests/l4-pidesk-docs.test.mjs tests/l4-pidesk-installed-runners.test.mjs tests/l4-pidesk-package-maintenance.test.ts tests/l4-pidesk-release-gate.test.mjs tests/l4-pi-desk-process-tree.test.mjs tests/l4-pi-runner-process.test.ts tests/l4-pi-global-runtime.test.mjs tests/l4-pi-desk-supervisor-cli.test.mjs && node --conditions=react-server --import tsx --test --test-concurrency=1 tests/l4-pi-plugin-owner-replace.test.ts tests/l4-pi-plugin-source-changes.test.ts",
|
|
116
116
|
"test:app-websocket": "pnpm build && node --import tsx --test tests/l2-chat-state.test.ts tests/l2-workbench-chat-repository.test.ts tests/l2-workbench-chat.test.ts tests/l2-workbench-layout.test.ts tests/l2-work-session-column-layout.test.ts tests/l2-work-session-update.test.ts tests/l1-app-websocket.test.mjs",
|
|
117
117
|
"lint": "eslint .",
|
|
118
118
|
"lint:production": "eslint . --ignore-pattern \"apps/desktop/**\" --ignore-pattern \"**/tests/**\" --ignore-pattern \"**/__tests__/**\" --ignore-pattern \"**/*.test.*\" --ignore-pattern \"**/*.spec.*\"",
|
|
@@ -85,11 +85,11 @@ const piSettings: Record<string, string> = {
|
|
|
85
85
|
启动程序: 'Command',
|
|
86
86
|
'参数(每行一个)': 'Arguments (one per line)',
|
|
87
87
|
'服务说明(可选)': 'Description (optional)',
|
|
88
|
-
工具使用方式: 'Tool
|
|
88
|
+
工具使用方式: 'Tool access',
|
|
89
89
|
沿用默认: 'Use default',
|
|
90
|
-
通过脚本调用: 'Via
|
|
90
|
+
通过脚本调用: 'Via codemode',
|
|
91
91
|
按需发现: 'On-demand discovery',
|
|
92
|
-
直接使用: 'Direct
|
|
92
|
+
直接使用: 'Direct call',
|
|
93
93
|
隐藏: 'Hidden',
|
|
94
94
|
'高级配置(JSON)': 'Advanced configuration (JSON)',
|
|
95
95
|
'继承全局连接,仅保存本项目启用与曝光设置,不复制全局凭据。':
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
3
|
import { replaceL4HostSettings } from '@client/l4_foundation/locale/l4-region-store'
|
|
4
|
-
import type {
|
|
5
|
-
PiNativeBrowserChannel,
|
|
6
|
-
PiDeskBrowserChannel,
|
|
7
|
-
PluginPushMessage
|
|
8
|
-
} from '@jetcrab/pi-desk-sdk/browser'
|
|
4
|
+
import type { PiDeskBrowserChannel, PluginPushMessage } from '@jetcrab/pi-desk-sdk/browser'
|
|
9
5
|
import { L2ChatSocketContracts } from '@common/l2_biz/chat/l2-chat-websocket-contract'
|
|
10
6
|
import { L2PluginSocketContracts } from '@common/l2_biz/plugin/l2-plugin-websocket-contract'
|
|
11
7
|
import {
|
|
@@ -41,7 +37,7 @@ function createTransport(
|
|
|
41
37
|
owner: L4AppSocketOwner,
|
|
42
38
|
canLoadEntries: () => boolean
|
|
43
39
|
): L4PluginHostTransport {
|
|
44
|
-
const pi:
|
|
40
|
+
const pi: L4PluginHostTransport['pi'] = {
|
|
45
41
|
prompt: (source, input) =>
|
|
46
42
|
owner.request(L2ChatSocketContracts.send, {
|
|
47
43
|
source,
|
|
@@ -79,6 +75,9 @@ function createTransport(
|
|
|
79
75
|
},
|
|
80
76
|
interrupt: async (source): Promise<void> => {
|
|
81
77
|
await owner.request(L2ChatSocketContracts.interrupt, { source })
|
|
78
|
+
},
|
|
79
|
+
reload: async (source): Promise<void> => {
|
|
80
|
+
await owner.request(L2ChatSocketContracts.reload, { source })
|
|
82
81
|
}
|
|
83
82
|
}
|
|
84
83
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
|
-
import { useEffect, useMemo, useState } from 'react'
|
|
3
|
+
import { useEffect, useMemo, useRef, useState } from 'react'
|
|
4
4
|
import { useTranslation } from 'react-i18next'
|
|
5
5
|
import type { L4Locale } from '@common/l4_foundation/locale/l4-locale'
|
|
6
6
|
import { useL4AppSocket } from '@client/l4_foundation/realtime/app-socket/l4-app-socket'
|
|
7
7
|
import { useL4Region } from '@client/l4_foundation/locale/l4-region-provider'
|
|
8
8
|
import { L4SearchSelect } from '@client/l4_foundation/ui/l4-search-select'
|
|
9
|
+
import { useL4ConfirmDialog } from '@client/l4_foundation/ui/l4-confirm-dialog'
|
|
9
10
|
import { Button } from '@client/l4_foundation/ui/shadcn/button'
|
|
10
11
|
import {
|
|
11
12
|
Select,
|
|
@@ -28,6 +29,9 @@ export function L2RegionSettings({
|
|
|
28
29
|
const { t } = useTranslation('settings')
|
|
29
30
|
const region = useL4Region()
|
|
30
31
|
const { appSocket } = useL4AppSocket()
|
|
32
|
+
const { confirm, dialog } = useL4ConfirmDialog()
|
|
33
|
+
const [changingLanguage, setChangingLanguage] = useState(false)
|
|
34
|
+
const languagePending = useRef(false)
|
|
31
35
|
const [error, setError] = useState<string | null>(null)
|
|
32
36
|
const [sampleTime, setSampleTime] = useState(() => new Date())
|
|
33
37
|
useEffect(() => {
|
|
@@ -42,15 +46,29 @@ export function L2RegionSettings({
|
|
|
42
46
|
)
|
|
43
47
|
|
|
44
48
|
const chooseLanguage = async (value: L4Locale): Promise<void> => {
|
|
49
|
+
if (languagePending.current) return
|
|
50
|
+
languagePending.current = true
|
|
51
|
+
setChangingLanguage(true)
|
|
45
52
|
setError(null)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
try {
|
|
54
|
+
const result = await changeL3RegionLanguage(
|
|
55
|
+
value,
|
|
56
|
+
() =>
|
|
57
|
+
confirm({
|
|
58
|
+
title: t('language'),
|
|
59
|
+
description: t('common:reloadConfirm'),
|
|
60
|
+
confirmLabel: t('common:reload'),
|
|
61
|
+
confirmVariant: 'default'
|
|
62
|
+
}),
|
|
63
|
+
appSocket,
|
|
64
|
+
canLeave
|
|
65
|
+
)
|
|
66
|
+
if (result === 'save-failed') setError(t('common:localeError'))
|
|
67
|
+
if (result === 'blocked') setError(t('common:reloadBlocked'))
|
|
68
|
+
} finally {
|
|
69
|
+
languagePending.current = false
|
|
70
|
+
setChangingLanguage(false)
|
|
71
|
+
}
|
|
54
72
|
}
|
|
55
73
|
|
|
56
74
|
const chooseTimeZone = async (value: string): Promise<void> => {
|
|
@@ -59,6 +77,7 @@ export function L2RegionSettings({
|
|
|
59
77
|
|
|
60
78
|
return (
|
|
61
79
|
<section className="@container min-w-0 space-y-6" aria-labelledby="region-settings-title">
|
|
80
|
+
{dialog}
|
|
62
81
|
<h2 id="region-settings-title" className="text-xl font-semibold">
|
|
63
82
|
{t('region')}
|
|
64
83
|
</h2>
|
|
@@ -69,6 +88,7 @@ export function L2RegionSettings({
|
|
|
69
88
|
</label>
|
|
70
89
|
<Select
|
|
71
90
|
value={region.localePreference}
|
|
91
|
+
disabled={changingLanguage}
|
|
72
92
|
onValueChange={(value) => {
|
|
73
93
|
if (value === 'zh-CN' || value === 'en') void chooseLanguage(value)
|
|
74
94
|
}}
|
|
@@ -93,6 +113,7 @@ export function L2RegionSettings({
|
|
|
93
113
|
type="button"
|
|
94
114
|
size="sm"
|
|
95
115
|
variant="outline"
|
|
116
|
+
disabled={changingLanguage}
|
|
96
117
|
onClick={() => void chooseLanguage(region.localePreference)}
|
|
97
118
|
>
|
|
98
119
|
{t('reloadLanguage')}
|
|
@@ -7,14 +7,14 @@ import { readL4Region } from '@client/l4_foundation/locale/l4-region-store'
|
|
|
7
7
|
|
|
8
8
|
export async function changeL3RegionLanguage(
|
|
9
9
|
locale: L4Locale,
|
|
10
|
-
|
|
10
|
+
confirmReload: () => Promise<boolean>,
|
|
11
11
|
appSocket: L4AppSocketClient,
|
|
12
12
|
canLeave?: () => boolean | Promise<boolean>
|
|
13
13
|
): Promise<'changed' | 'cancelled' | 'blocked' | 'save-failed'> {
|
|
14
14
|
const current = readL4Region()
|
|
15
15
|
if (!current) return 'cancelled'
|
|
16
16
|
const reload = locale !== current.locale
|
|
17
|
-
if (reload && !
|
|
17
|
+
if (reload && !(await confirmReload())) return 'cancelled'
|
|
18
18
|
if (reload && canLeave && !(await canLeave())) return 'blocked'
|
|
19
19
|
try {
|
|
20
20
|
await appSocket.request(L3AppRuntimeSocketContracts.apply, {
|
|
@@ -140,7 +140,9 @@ export interface L4PluginRegistrySnapshot {
|
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
export interface L4PluginHostTransport {
|
|
143
|
-
readonly pi: PiNativeBrowserChannel
|
|
143
|
+
readonly pi: Omit<PiNativeBrowserChannel, 'reload'> & {
|
|
144
|
+
reload?(source: PluginSource): Promise<void>
|
|
145
|
+
}
|
|
144
146
|
listBrowserEntries(): Promise<readonly L4PluginBrowserEntryDescriptor[]>
|
|
145
147
|
subscribePush(listener: (message: PluginPushMessage) => void): () => void
|
|
146
148
|
createPiDeskChannel(pluginName: string): PiDeskBrowserChannel
|
|
@@ -1885,6 +1887,7 @@ export class L4PluginHostRuntime {
|
|
|
1885
1887
|
}
|
|
1886
1888
|
const piDesk = this.transport.createPiDeskChannel(pluginName)
|
|
1887
1889
|
const pi = this.transport.pi
|
|
1890
|
+
const reloadPi = pi.reload
|
|
1888
1891
|
const subscribe = (
|
|
1889
1892
|
listeners: Set<() => void>,
|
|
1890
1893
|
listener: () => void,
|
|
@@ -1987,7 +1990,22 @@ export class L4PluginHostRuntime {
|
|
|
1987
1990
|
execute: (source, input) => invoke(() => pi.bash.execute(source, input)),
|
|
1988
1991
|
abort: (source) => invoke(() => pi.bash.abort(source))
|
|
1989
1992
|
},
|
|
1990
|
-
interrupt: (source) => invoke(() => pi.interrupt(source))
|
|
1993
|
+
interrupt: (source) => invoke(() => pi.interrupt(source)),
|
|
1994
|
+
...(reloadPi
|
|
1995
|
+
? {
|
|
1996
|
+
reload: (workId: string): Promise<void> =>
|
|
1997
|
+
invoke(async () => {
|
|
1998
|
+
if (typeof workId !== 'string' || !workId.trim()) {
|
|
1999
|
+
throw new Error('重载 Pi 配置需要有效 workId')
|
|
2000
|
+
}
|
|
2001
|
+
const workSession = this.workSessions.find(
|
|
2002
|
+
(item) => item.source.workId === workId
|
|
2003
|
+
)
|
|
2004
|
+
if (!workSession) throw new Error('工作会话不存在')
|
|
2005
|
+
await reloadPi(structuredClone(workSession.source))
|
|
2006
|
+
})
|
|
2007
|
+
}
|
|
2008
|
+
: {})
|
|
1991
2009
|
},
|
|
1992
2010
|
workSessions,
|
|
1993
2011
|
workSessionFiles: {
|
|
@@ -25,7 +25,7 @@ export const L2_PLUGIN_MANAGEMENT_MESSAGES = {
|
|
|
25
25
|
phase_applying: 'Applying',
|
|
26
26
|
phase_waiting: 'Waiting to activate',
|
|
27
27
|
phase_failed: 'Failed',
|
|
28
|
-
updateCheckFailed: 'Could not check plugin updates',
|
|
28
|
+
updateCheckFailed: 'Could not check for plugin updates',
|
|
29
29
|
actionFailed: '{{action}} failed',
|
|
30
30
|
retrying: 'Retrying {{name}}',
|
|
31
31
|
retryFailed: 'Could not retry plugin UI',
|
|
@@ -35,7 +35,7 @@ export const L2_PLUGIN_MANAGEMENT_MESSAGES = {
|
|
|
35
35
|
title: 'Plugins',
|
|
36
36
|
description: 'Manage plugin packages and local extensions.',
|
|
37
37
|
noPluginDescription: 'No description available',
|
|
38
|
-
checkUpdates: 'Check updates',
|
|
38
|
+
checkUpdates: 'Check for updates',
|
|
39
39
|
checkingUpdates: 'Checking…',
|
|
40
40
|
restartApply: 'Restart to finish',
|
|
41
41
|
installPlugin: 'Install plugin',
|
|
@@ -89,12 +89,18 @@ export const L2_PLUGIN_MANAGEMENT_MESSAGES = {
|
|
|
89
89
|
contributionSidebar: 'Session sidebar',
|
|
90
90
|
contributionWidget: 'Composer widget',
|
|
91
91
|
contributionSessionHeader: 'Session header item',
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
92
|
+
tagTools_one: '{{count}} tool',
|
|
93
|
+
tagTools_other: '{{count}} tools',
|
|
94
|
+
tagFixed_one: '{{count}} fixed prompt',
|
|
95
|
+
tagFixed_other: '{{count}} fixed prompts',
|
|
96
|
+
tagDynamic_one: '{{count}} dynamic hook',
|
|
97
|
+
tagDynamic_other: '{{count}} dynamic hooks',
|
|
98
|
+
tagOverride_one: '{{count}} built-in override',
|
|
99
|
+
tagOverride_other: '{{count}} built-in overrides',
|
|
100
|
+
tagManual_one: '{{count}} manual prompt',
|
|
101
|
+
tagManual_other: '{{count}} manual prompts',
|
|
102
|
+
tagInteraction_one: '{{count}} interaction',
|
|
103
|
+
tagInteraction_other: '{{count}} interactions',
|
|
98
104
|
unknown: 'Unknown',
|
|
99
105
|
stateActive: 'Active',
|
|
100
106
|
stateInactive: 'Inactive',
|
|
@@ -113,7 +119,7 @@ export const L2_PLUGIN_MANAGEMENT_MESSAGES = {
|
|
|
113
119
|
rawSchema: 'Raw schema',
|
|
114
120
|
toolCapabilities: 'Tool capabilities',
|
|
115
121
|
toolDescription: 'Each tool shows its purpose, parameters and declared system prompts.',
|
|
116
|
-
overridesBuiltin: 'Overrides a Pi
|
|
122
|
+
overridesBuiltin: 'Overrides a Pi built-in tool',
|
|
117
123
|
noDescription: 'No description provided',
|
|
118
124
|
systemPrompts: 'System prompts',
|
|
119
125
|
inactivePrompt: 'This tool is inactive; its prompts do not enter the system prompt.',
|
|
@@ -195,7 +201,7 @@ export const L2_PLUGIN_MANAGEMENT_MESSAGES = {
|
|
|
195
201
|
download_local: 'No override (local configuration)',
|
|
196
202
|
download_auto: 'Automatic',
|
|
197
203
|
download_domestic: 'China mirror',
|
|
198
|
-
download_official: 'Official npm',
|
|
204
|
+
download_official: 'Official npm registry',
|
|
199
205
|
download_custom: 'Custom',
|
|
200
206
|
registryUrl: 'Registry URL',
|
|
201
207
|
sourceDetails: 'View source URL',
|
|
@@ -235,7 +241,7 @@ export const L2_PLUGIN_MANAGEMENT_MESSAGES = {
|
|
|
235
241
|
compatibilityUnknown: 'Compatibility not verified',
|
|
236
242
|
homepage: 'Website',
|
|
237
243
|
repository: 'Source code',
|
|
238
|
-
removeDescription: '
|
|
244
|
+
removeDescription: 'Uninstall this plugin. Saved configuration and data will be kept.',
|
|
239
245
|
thirdPartyDescription:
|
|
240
246
|
'This plugin can execute code on your computer. Only install it if you trust its publisher and source.',
|
|
241
247
|
confirmChange: 'Apply this change to the selected plugin.',
|
|
@@ -328,12 +334,18 @@ export const L2_PLUGIN_MANAGEMENT_MESSAGES = {
|
|
|
328
334
|
contributionSidebar: '会话侧栏',
|
|
329
335
|
contributionWidget: '输入区挂件',
|
|
330
336
|
contributionSessionHeader: '会话标题项',
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
+
tagTools_one: '工具 {{count}}',
|
|
338
|
+
tagTools_other: '工具 {{count}}',
|
|
339
|
+
tagFixed_one: '固定提示 {{count}}',
|
|
340
|
+
tagFixed_other: '固定提示 {{count}}',
|
|
341
|
+
tagDynamic_one: '动态影响 {{count}}',
|
|
342
|
+
tagDynamic_other: '动态影响 {{count}}',
|
|
343
|
+
tagOverride_one: '替换内置 {{count}}',
|
|
344
|
+
tagOverride_other: '替换内置 {{count}}',
|
|
345
|
+
tagManual_one: '手动提示 {{count}}',
|
|
346
|
+
tagManual_other: '手动提示 {{count}}',
|
|
347
|
+
tagInteraction_one: '交互 {{count}}',
|
|
348
|
+
tagInteraction_other: '交互 {{count}}',
|
|
337
349
|
unknown: '未知',
|
|
338
350
|
stateActive: '启用',
|
|
339
351
|
stateInactive: '未启用',
|
|
@@ -17,7 +17,7 @@ export const L2_PROJECT_HISTORY_MESSAGES = {
|
|
|
17
17
|
noRecentProjects: 'No project history. Enter a path or browse directories.',
|
|
18
18
|
currentHead: 'Current HEAD',
|
|
19
19
|
localBranch: 'Local branch',
|
|
20
|
-
remoteBranch: 'Remote branch
|
|
20
|
+
remoteBranch: 'Remote-tracking branch',
|
|
21
21
|
retry: 'Retry',
|
|
22
22
|
compareDirect: 'Compare directly',
|
|
23
23
|
loadingCommits: 'Loading commits…',
|
|
@@ -29,17 +29,18 @@ export const L2_PROJECT_HISTORY_MESSAGES = {
|
|
|
29
29
|
loadedLimit: '2,000 commits loaded. Narrow your search.',
|
|
30
30
|
noMoreCommits: 'All commits loaded',
|
|
31
31
|
backCommits: 'Back to commits',
|
|
32
|
-
commitChanges: '
|
|
32
|
+
commitChanges: 'Changes in commit',
|
|
33
33
|
cumulativeChanges: 'Cumulative changes',
|
|
34
|
-
|
|
34
|
+
loadedFiles_one: '{{count}} file loaded',
|
|
35
|
+
loadedFiles_other: '{{count}} files loaded',
|
|
35
36
|
backCumulative: 'Back to cumulative changes',
|
|
36
37
|
loadingChanges: 'Loading changes…',
|
|
37
38
|
noDiff: 'No file differences',
|
|
38
39
|
loadMoreFiles: 'Load more files',
|
|
39
|
-
changesLimit: '
|
|
40
|
+
changesLimit: 'Too many changed files to display.',
|
|
40
41
|
commitDetails: 'Commit details',
|
|
41
42
|
copySha: 'Copy commit SHA',
|
|
42
|
-
compareParent: 'Compare parent commit',
|
|
43
|
+
compareParent: 'Compare with parent commit',
|
|
43
44
|
parentCommit: 'Parent {{count}} · {{oid}}',
|
|
44
45
|
mergeBaseToTarget: 'Common ancestor → target commit',
|
|
45
46
|
baseToTarget: 'Base commit → target commit',
|
|
@@ -61,7 +62,7 @@ export const L2_PROJECT_HISTORY_MESSAGES = {
|
|
|
61
62
|
author: 'Commit author',
|
|
62
63
|
searchCommits: 'Search commit message or SHA',
|
|
63
64
|
refreshGit: 'Refresh Git history',
|
|
64
|
-
localRecord: '
|
|
65
|
+
localRecord: 'Cached locally',
|
|
65
66
|
refUnavailable: 'Reference unavailable',
|
|
66
67
|
aheadBehind: '{{ahead}} ahead · {{behind}} behind',
|
|
67
68
|
chooseBaseBranch: 'Choose a base branch',
|
|
@@ -122,7 +123,8 @@ export const L2_PROJECT_HISTORY_MESSAGES = {
|
|
|
122
123
|
backCommits: '返回提交列表',
|
|
123
124
|
commitChanges: '提交变更',
|
|
124
125
|
cumulativeChanges: '累计变更',
|
|
125
|
-
|
|
126
|
+
loadedFiles_one: '已加载 {{count}} 个文件',
|
|
127
|
+
loadedFiles_other: '已加载 {{count}} 个文件',
|
|
126
128
|
backCumulative: '返回累计变更',
|
|
127
129
|
loadingChanges: '读取变更…',
|
|
128
130
|
noDiff: '没有文件差异',
|