@chainingintention/pi-web-cn 2.202610.2 → 2.202610.3
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/client/assets/CommandPicker-gK2biReF.js +70 -0
- package/dist/client/assets/PiWebApp-DccVSAFd.js +3761 -0
- package/dist/client/assets/SettingsDialog-vGDo1-BJ.js +1015 -0
- package/dist/client/assets/index-Chn9pQPv.js +2 -0
- package/dist/client/assets/managementEmbed-Bx8Mwzdw.js +2 -0
- package/dist/client/assets/preload-helper-XpATwJ5c.js +1 -0
- package/dist/client/index.html +3 -2
- package/dist/pi-web-plugins/custom-ui-codex/LICENSE-icons +35 -0
- package/dist/pi-web-plugins/custom-ui-codex/README.md +25 -0
- package/dist/pi-web-plugins/custom-ui-codex/chat-settings.css +251 -0
- package/dist/pi-web-plugins/custom-ui-codex/codex.css +77 -0
- package/dist/{client/assets/graphite-DquaqFXU.css → pi-web-plugins/custom-ui-codex/graphite.css} +4 -2
- package/dist/pi-web-plugins/custom-ui-codex/package.json +10 -0
- package/dist/{client/assets/paper-CB1oLuRr.css → pi-web-plugins/custom-ui-codex/paper.css} +7 -5
- package/dist/pi-web-plugins/custom-ui-codex/pi-web-plugin.js +56 -0
- package/dist/pi-web-plugins/files/browser/pi-web-plugin.js +29 -29
- package/dist/pi-web-plugins/workspace-tasks/tasksPanelElement.js +3 -3
- package/dist/pi-web-plugins/zh-cn/components.json +6 -1
- package/dist/plugin-api.d.ts +48 -0
- package/dist/server/terminals/requiredTerminalService.js +2 -53
- package/dist/server/terminals/requiredTerminalService.js.map +1 -1
- package/dist/shared/terminalCommandRun.js +56 -0
- package/dist/shared/terminalCommandRun.js.map +1 -0
- package/docs/config.md +6 -2
- package/docs/plugins.md +22 -1
- package/package.json +2 -2
- package/dist/client/assets/PiWebApp-BVnLs9Kj.js +0 -4938
- package/dist/client/assets/external-B9K8duyP.js +0 -2
- package/dist/client/assets/index-pOnX1cs_.js +0 -2
|
@@ -222,11 +222,11 @@ function cacheKeyForContext(context) {
|
|
|
222
222
|
return `${context.machine.id}:${context.workspace.projectId}:${context.workspace.id}`;
|
|
223
223
|
}
|
|
224
224
|
function renderMissingState(state) {
|
|
225
|
-
return `<div class="empty-state"><strong
|
|
225
|
+
return `<div class="empty-state"><strong>${escapeHtml(state.message)}</strong><p>${escapeHtml(state.hint)}</p></div>`;
|
|
226
226
|
}
|
|
227
227
|
function renderUnavailableState(state) {
|
|
228
228
|
const detail = state.detail === undefined ? "" : `<pre>${escapeHtml(state.detail)}</pre>`;
|
|
229
|
-
return `<div class="status error"><strong
|
|
229
|
+
return `<div class="status error"><strong>${escapeHtml(state.message)}</strong><p>${escapeHtml(state.hint)}</p>${detail}</div>`;
|
|
230
230
|
}
|
|
231
231
|
function renderTaskGroups(tasks, runningTaskId) {
|
|
232
232
|
return `<div class="tasks">${groupTasks(tasks).map((group) => renderTaskGroup(group, runningTaskId)).join("")}</div>`;
|
|
@@ -255,7 +255,7 @@ function renderTask(task, runningTaskId) {
|
|
|
255
255
|
return `
|
|
256
256
|
<article class="task-card">
|
|
257
257
|
<div class="task-copy">
|
|
258
|
-
<strong
|
|
258
|
+
<strong>${escapeHtml(task.title)}</strong>
|
|
259
259
|
${description}
|
|
260
260
|
<code>${escapeHtml(task.command)}</code>
|
|
261
261
|
</div>
|
|
@@ -1229,6 +1229,9 @@
|
|
|
1229
1229
|
"ui.navigation.agentSubsessionsActive": "代理子会话正在运行",
|
|
1230
1230
|
"ui.navigation.unreadSubsessionActivity": "子会话有未读活动",
|
|
1231
1231
|
"ui.navigation.collapsePanel": "折叠导航面板",
|
|
1232
|
+
"ui.navigation.expandPanel": "展开导航面板",
|
|
1233
|
+
"ui.workspacePanel.expandPanel": "展开工作区面板",
|
|
1234
|
+
"ui.workspacePanel.collapsePanel": "折叠工作区面板",
|
|
1232
1235
|
"ui.navigation.resizeSection": "调整{section}高度",
|
|
1233
1236
|
"ui.navigation.resizeSectionReset": "调整{section}高度。双击或轻点两次以重置。",
|
|
1234
1237
|
"ui.navigation.otherMachinesTerminalActive": "其他机器上的终端正在运行",
|
|
@@ -1248,5 +1251,7 @@
|
|
|
1248
1251
|
"ui.projectDialog.remoteFolders": "远端机器 {machineId} 上的文件夹。",
|
|
1249
1252
|
"ui.projectDialog.machinePaths": "路径属于此机器,而非浏览器所在设备。",
|
|
1250
1253
|
"ui.projectDialog.folderLookupFailed": "无法读取此机器上的文件夹。请检查连接后重试,或直接输入文件夹路径。",
|
|
1251
|
-
"ui.projectDialog.retryFolderLookup": "重新查找文件夹"
|
|
1254
|
+
"ui.projectDialog.retryFolderLookup": "重新查找文件夹",
|
|
1255
|
+
"ui.settingsDialog.backToApp": "返回应用",
|
|
1256
|
+
"ui.sessionSearchDialog.searchSessions": "搜索会话"
|
|
1252
1257
|
}
|
package/dist/plugin-api.d.ts
CHANGED
|
@@ -34,6 +34,7 @@ export type SessionLabelContextV5 = SessionLabelContext & PluginDiscoveryContext
|
|
|
34
34
|
export type MessageActionContextV5 = MessageActionContext & PluginDiscoveryContext;
|
|
35
35
|
export type DisplayedMessageActionContextV5 = DisplayedMessageActionContext & PluginDiscoveryContext;
|
|
36
36
|
export interface PluginContributionsV5 extends Omit<PluginContributions, "actions" | "applicationPanels" | "workspacePanels" | "workspaceLabels" | "sessionLabels" | "messageActions" | "contentRenderers" | "themes"> {
|
|
37
|
+
uiPresentations?: UiPresentationContributionV1[];
|
|
37
38
|
stylesheets?: StylesheetContribution[];
|
|
38
39
|
syntaxHighlighters?: SyntaxHighlighterContribution[];
|
|
39
40
|
contentRenderers?: ContentRendererContributionV5[];
|
|
@@ -45,6 +46,53 @@ export interface PluginContributionsV5 extends Omit<PluginContributions, "action
|
|
|
45
46
|
sessionLabels?: SessionLabelContributionV5[];
|
|
46
47
|
messageActions?: MessageActionContributionV5[];
|
|
47
48
|
}
|
|
49
|
+
export type UiPresentationRegion = "navigation" | "context-bar" | "chat-chrome" | "settings-navigation";
|
|
50
|
+
/** Host-supplied actions remain bound to the selection and permissions that created them. */
|
|
51
|
+
export interface UiPresentationActionV1 {
|
|
52
|
+
readonly id: string;
|
|
53
|
+
readonly label: string;
|
|
54
|
+
readonly disabled?: boolean;
|
|
55
|
+
readonly run: () => void | Promise<void>;
|
|
56
|
+
}
|
|
57
|
+
/** Display-only selection; no credentials, transcript, internal paths, or session connection. */
|
|
58
|
+
export interface UiPresentationContextV1 {
|
|
59
|
+
readonly mode: "normal" | "management";
|
|
60
|
+
readonly compact?: boolean;
|
|
61
|
+
readonly machine?: Readonly<{
|
|
62
|
+
id: string;
|
|
63
|
+
name: string;
|
|
64
|
+
}>;
|
|
65
|
+
readonly project?: Readonly<{
|
|
66
|
+
id: string;
|
|
67
|
+
name: string;
|
|
68
|
+
}>;
|
|
69
|
+
readonly workspace?: Readonly<{
|
|
70
|
+
id: string;
|
|
71
|
+
label: string;
|
|
72
|
+
}>;
|
|
73
|
+
readonly session?: Readonly<{
|
|
74
|
+
id: string;
|
|
75
|
+
label: string;
|
|
76
|
+
}>;
|
|
77
|
+
readonly actions?: readonly UiPresentationActionV1[];
|
|
78
|
+
}
|
|
79
|
+
export interface UiPresentationRenderContextV1 extends UiPresentationContextV1 {
|
|
80
|
+
readonly region: UiPresentationRegion;
|
|
81
|
+
/** Named slots for host-owned controls. Render slots, never inspect or move host DOM. */
|
|
82
|
+
readonly slots: readonly string[];
|
|
83
|
+
}
|
|
84
|
+
/** One gateway-owned renderer per region. Editor/transcript stay mounted; navigation may recompose. */
|
|
85
|
+
export interface UiPresentationContributionV1 {
|
|
86
|
+
readonly id: LocalContributionId;
|
|
87
|
+
readonly region: UiPresentationRegion;
|
|
88
|
+
/** Navigation only: compose the host-owned lists as a selected-branch tree. */
|
|
89
|
+
readonly navigationLayout?: "tree";
|
|
90
|
+
render(context: UiPresentationRenderContextV1): TemplateResult;
|
|
91
|
+
}
|
|
92
|
+
export interface UiPresentationCapabilityV1 {
|
|
93
|
+
readonly version: 1;
|
|
94
|
+
readonly regions: readonly UiPresentationRegion[];
|
|
95
|
+
}
|
|
48
96
|
export type PluginActionV5 = Omit<PluginAction, "enabled" | "disabledReason" | "run"> & {
|
|
49
97
|
enabled?: (context: PluginRuntimeContextV5) => boolean;
|
|
50
98
|
disabledReason?: (context: PluginRuntimeContextV5) => string | undefined;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { REQUIRED_TERMINAL_PLUGIN_ID } from "../../shared/requiredTerminalPlugin.js";
|
|
2
|
+
import { requireTerminalCommandRun } from "../../shared/terminalCommandRun.js";
|
|
2
3
|
/** Core's typed view of the bundled Terminal service capability. */
|
|
3
4
|
export const REQUIRED_TERMINAL_SERVICE_CAPABILITY = Object.freeze({
|
|
4
5
|
pluginId: REQUIRED_TERMINAL_PLUGIN_ID,
|
|
@@ -23,7 +24,7 @@ export function snapshotRequiredTerminalService(value) {
|
|
|
23
24
|
}
|
|
24
25
|
return Object.freeze({
|
|
25
26
|
closeForCwd: (cwd) => { Reflect.apply(closeForCwd, value, [cwd]); },
|
|
26
|
-
runCommand: (options) =>
|
|
27
|
+
runCommand: (options) => requireTerminalCommandRun(Reflect.apply(runCommand, value, [options]), invalidCommandRun),
|
|
27
28
|
bindActivitySink: (sink) => {
|
|
28
29
|
Reflect.apply(bindActivitySink, value, [Object.freeze({
|
|
29
30
|
updateTerminal: (terminal) => { sink.updateTerminal(terminal); },
|
|
@@ -42,58 +43,6 @@ export function unavailableRequiredTerminalService() {
|
|
|
42
43
|
bindActivitySink: () => undefined,
|
|
43
44
|
});
|
|
44
45
|
}
|
|
45
|
-
function requireCommandRun(value) {
|
|
46
|
-
if (!isRecord(value))
|
|
47
|
-
throw invalidCommandRun();
|
|
48
|
-
const status = value["status"];
|
|
49
|
-
const exitCode = optionalFiniteNumber(value["exitCode"]);
|
|
50
|
-
const startedAt = optionalString(value["startedAt"]);
|
|
51
|
-
const completedAt = optionalString(value["completedAt"]);
|
|
52
|
-
if (typeof value["id"] !== "string"
|
|
53
|
-
|| typeof value["origin"] !== "string"
|
|
54
|
-
|| typeof value["projectId"] !== "string"
|
|
55
|
-
|| typeof value["workspaceId"] !== "string"
|
|
56
|
-
|| typeof value["terminalId"] !== "string"
|
|
57
|
-
|| typeof value["title"] !== "string"
|
|
58
|
-
|| typeof value["command"] !== "string"
|
|
59
|
-
|| (status !== "queued" && status !== "running" && status !== "succeeded" && status !== "failed")
|
|
60
|
-
|| exitCode === invalidOptionalField
|
|
61
|
-
|| typeof value["createdAt"] !== "string"
|
|
62
|
-
|| startedAt === invalidOptionalField
|
|
63
|
-
|| completedAt === invalidOptionalField
|
|
64
|
-
|| !isStringRecord(value["metadata"])) {
|
|
65
|
-
throw invalidCommandRun();
|
|
66
|
-
}
|
|
67
|
-
return {
|
|
68
|
-
id: value["id"],
|
|
69
|
-
origin: value["origin"],
|
|
70
|
-
projectId: value["projectId"],
|
|
71
|
-
workspaceId: value["workspaceId"],
|
|
72
|
-
terminalId: value["terminalId"],
|
|
73
|
-
title: value["title"],
|
|
74
|
-
command: value["command"],
|
|
75
|
-
status,
|
|
76
|
-
...(exitCode === undefined ? {} : { exitCode }),
|
|
77
|
-
createdAt: value["createdAt"],
|
|
78
|
-
...(startedAt === undefined ? {} : { startedAt }),
|
|
79
|
-
...(completedAt === undefined ? {} : { completedAt }),
|
|
80
|
-
metadata: { ...value["metadata"] },
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
const invalidOptionalField = Symbol("invalid optional Terminal field");
|
|
84
|
-
function optionalFiniteNumber(value) {
|
|
85
|
-
if (value === undefined)
|
|
86
|
-
return undefined;
|
|
87
|
-
return typeof value === "number" && Number.isFinite(value) ? value : invalidOptionalField;
|
|
88
|
-
}
|
|
89
|
-
function optionalString(value) {
|
|
90
|
-
if (value === undefined)
|
|
91
|
-
return undefined;
|
|
92
|
-
return typeof value === "string" ? value : invalidOptionalField;
|
|
93
|
-
}
|
|
94
|
-
function isStringRecord(value) {
|
|
95
|
-
return isRecord(value) && Object.values(value).every((child) => typeof child === "string");
|
|
96
|
-
}
|
|
97
46
|
function invalidCommandRun() {
|
|
98
47
|
return new Error("Required Terminal server entry returned an invalid command run");
|
|
99
48
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requiredTerminalService.js","sourceRoot":"","sources":["../../../src/server/terminals/requiredTerminalService.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,2BAA2B,EAAE,MAAM,wCAAwC,CAAC;
|
|
1
|
+
{"version":3,"file":"requiredTerminalService.js","sourceRoot":"","sources":["../../../src/server/terminals/requiredTerminalService.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,2BAA2B,EAAE,MAAM,wCAAwC,CAAC;AACrF,OAAO,EAAE,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AAuC/E,oEAAoE;AACpE,MAAM,CAAC,MAAM,oCAAoC,GAAG,MAAM,CAAC,MAAM,CAAC;IAChE,QAAQ,EAAE,2BAA2B;IACrC,EAAE,EAAE,SAAS;IACb,OAAO,EAAE,CAAC;IACV,KAAK,EAAE,+BAA+B;CACvC,CAAwD,CAAC;AAE1D,MAAM,OAAO,gCAAiC,SAAQ,KAAK;IAA3D;;QACW,SAAI,GAAG,kCAAkC,CAAC;IACrD,CAAC;CAAA;AAED,MAAM,UAAU,+BAA+B,CAAC,KAAc;IAC5D,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,wEAAwE,CAAC,CAAC;IAChH,MAAM,WAAW,GAAG,KAAK,CAAC,aAAa,CAAC,CAAC;IACzC,MAAM,UAAU,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC;IACvC,MAAM,gBAAgB,GAAG,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACnD,IAAI,OAAO,WAAW,KAAK,UAAU,IAAI,OAAO,UAAU,KAAK,UAAU,IAAI,OAAO,gBAAgB,KAAK,UAAU,EAAE,CAAC;QACpH,MAAM,IAAI,KAAK,CAAC,wEAAwE,CAAC,CAAC;IAC5F,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,WAAW,EAAE,CAAC,GAAW,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3E,UAAU,EAAE,CAAC,OAAkC,EAAE,EAAE,CAAC,yBAAyB,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,iBAAiB,CAAC;QAC7I,gBAAgB,EAAE,CAAC,IAAkC,EAAE,EAAE;YACvD,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC;oBACpD,cAAc,EAAE,CAAC,QAAkC,EAAE,EAAE,GAAG,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;oBAC1F,cAAc,EAAE,CAAC,UAAkB,EAAE,GAAY,EAAE,EAAE,GAAG,IAAI,CAAC,cAAc,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;iBAChG,CAAC,CAAC,CAAC,CAAC;QACP,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,kCAAkC;IAChD,MAAM,WAAW,GAAG,GAAU,EAAE;QAC9B,MAAM,IAAI,gCAAgC,CACxC,mGAAmG,CACpG,CAAC;IACJ,CAAC,CAAC;IACF,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,WAAW,EAAE,WAAW;QACxB,UAAU,EAAE,WAAW;QACvB,gBAAgB,EAAE,GAAG,EAAE,CAAC,SAAS;KAClC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,iBAAiB;IACxB,OAAO,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;AACrF,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export function requireTerminalCommandRun(value, invalidCommandRun) {
|
|
2
|
+
if (!isRecord(value))
|
|
3
|
+
throw invalidCommandRun();
|
|
4
|
+
const status = value["status"];
|
|
5
|
+
const exitCode = optionalFiniteNumber(value["exitCode"]);
|
|
6
|
+
const startedAt = optionalString(value["startedAt"]);
|
|
7
|
+
const completedAt = optionalString(value["completedAt"]);
|
|
8
|
+
if (typeof value["id"] !== "string"
|
|
9
|
+
|| typeof value["origin"] !== "string"
|
|
10
|
+
|| typeof value["projectId"] !== "string"
|
|
11
|
+
|| typeof value["workspaceId"] !== "string"
|
|
12
|
+
|| typeof value["terminalId"] !== "string"
|
|
13
|
+
|| typeof value["title"] !== "string"
|
|
14
|
+
|| typeof value["command"] !== "string"
|
|
15
|
+
|| (status !== "queued" && status !== "running" && status !== "succeeded" && status !== "failed")
|
|
16
|
+
|| exitCode === invalidOptionalField
|
|
17
|
+
|| typeof value["createdAt"] !== "string"
|
|
18
|
+
|| startedAt === invalidOptionalField
|
|
19
|
+
|| completedAt === invalidOptionalField
|
|
20
|
+
|| !isStringRecord(value["metadata"])) {
|
|
21
|
+
throw invalidCommandRun();
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
id: value["id"],
|
|
25
|
+
origin: value["origin"],
|
|
26
|
+
projectId: value["projectId"],
|
|
27
|
+
workspaceId: value["workspaceId"],
|
|
28
|
+
terminalId: value["terminalId"],
|
|
29
|
+
title: value["title"],
|
|
30
|
+
command: value["command"],
|
|
31
|
+
status,
|
|
32
|
+
...(exitCode === undefined ? {} : { exitCode }),
|
|
33
|
+
createdAt: value["createdAt"],
|
|
34
|
+
...(startedAt === undefined ? {} : { startedAt }),
|
|
35
|
+
...(completedAt === undefined ? {} : { completedAt }),
|
|
36
|
+
metadata: { ...value["metadata"] },
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
const invalidOptionalField = Symbol("invalid optional Terminal field");
|
|
40
|
+
function optionalFiniteNumber(value) {
|
|
41
|
+
if (value === undefined)
|
|
42
|
+
return undefined;
|
|
43
|
+
return typeof value === "number" && Number.isFinite(value) ? value : invalidOptionalField;
|
|
44
|
+
}
|
|
45
|
+
function optionalString(value) {
|
|
46
|
+
if (value === undefined)
|
|
47
|
+
return undefined;
|
|
48
|
+
return typeof value === "string" ? value : invalidOptionalField;
|
|
49
|
+
}
|
|
50
|
+
function isStringRecord(value) {
|
|
51
|
+
return isRecord(value) && Object.values(value).every((child) => typeof child === "string");
|
|
52
|
+
}
|
|
53
|
+
function isRecord(value) {
|
|
54
|
+
return typeof value === "object" && value !== null;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=terminalCommandRun.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminalCommandRun.js","sourceRoot":"","sources":["../../src/shared/terminalCommandRun.ts"],"names":[],"mappings":"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"}
|
package/docs/config.md
CHANGED
|
@@ -59,7 +59,11 @@ Pi 包由目标机器的 `pi install`、`pi remove`、`pi update` 或 **设置
|
|
|
59
59
|
|
|
60
60
|
`defaultTheme` 是网关配置,形如 `{ "themeId": "plugin-id:theme-id", "auto": true }`:`themeId` 必须为限定贡献 ID,`auto` 必须为布尔值。`auto: true` 在该主题有明暗配对时跟随系统明暗,否则使用所选主题。浏览器设备已保存的主题覆盖优先;主题暂不可用时使用回退,不删除原选择。主题属于整个应用,不保存到当前远端机器;保存/刷新配置后生效,无需重启 daemon。
|
|
61
61
|
|
|
62
|
-
在 **设置 → 通用 → 主题**
|
|
62
|
+
在 **设置 → 通用 → 主题** 中,“在此设备使用”保存浏览器覆盖,“设为默认”保存网关默认且不覆盖已有设备选择,“使用默认值”清除此浏览器覆盖并采用应用默认。设置页的“默认主题”说明与应用的默认选择一致;网关未显式配置 `defaultTheme` 时,也会反映 Custom UI Codex 可用时的隐式默认。读取默认值或清除设备覆盖均不写入网关配置。Auto 只在主题有明暗配对时跟随设备。
|
|
63
|
+
|
|
64
|
+
内置 **Custom UI Codex** 展示插件默认启用,配置 ID 为 `pi-web.custom-ui-codex`。在网关的插件设置中禁用,或在网关有效机器配置设置 `plugins["pi-web.custom-ui-codex"].enabled: false`,刷新页面后恢复宿主默认布局;中文语言插件与权限模式不受影响,无需重启 daemon。远端机器不能替网关接管整个应用界面。
|
|
65
|
+
|
|
66
|
+
该插件启用且设备、网关均未显式选择主题时,使用 Paper / Graphite 明暗配对并跟随系统。已有设备或网关主题选择仍优先。主题限定 ID 为 `pi-web.custom-ui-codex:paper`、`pi-web.custom-ui-codex:graphite`;旧的 `themes:paper`、`themes:graphite` 在插件可用时继续解析到对应主题,设置页的名称、选项及保存操作同样识别这些旧 ID。读取和显示不改写原有配置,只有显式保存才使用当前可用主题的限定 ID。插件不可用时按正常主题回退规则显示,保留原选择以便恢复;设置页仍标记原主题不可用,不允许把回退主题当作原选择保存。
|
|
63
67
|
|
|
64
68
|
网关 `defaultStreamingBehavior` 为 `"steer"`(默认)或 `"followUp"`,决定流式工作期间编辑器的默认发送方式,不改变已在 daemon 中排队的消息。浏览器分区尺寸、编辑器偏好与普通导航顺序不是新的项目配置文件;导航顺序是按机器管理的托管状态,管理模式不共用普通存储。
|
|
65
69
|
|
|
@@ -399,7 +403,7 @@ daemon 日志记录忽略的配置变更与模型列表应用,不输出提供
|
|
|
399
403
|
|
|
400
404
|
优先级与 Pi 无交互提示时一致:没有需要信任资源则正常加载;全局扩展 `project_trust` 决定优先,可请求 `remember` 写入 agent `trust.json`;否则已保存决定优先;最后 `defaultProjectTrust` 的 `always` 加载,`never`/`ask` 跳过(没有浏览器运行时信任弹窗)。
|
|
401
405
|
|
|
402
|
-
|
|
406
|
+
添加项目可显式勾选“信任此项目”,不操作不写决定;普通文件夹项目可在项目的“⋯”菜单切换“已信任”,提供器工作区在工作区菜单切换。服务器解析授权工作区路径,远端保存于远端。下次运行时创建/打开读决定,既有运行时不立即重新加载,`/reload` 保留运行时信任状态。项目 auth/model/preferences 存储不迁入 trust;管理嵌入不读取/写入普通信任 API,继续独立授权资源与沙箱。
|
|
403
407
|
|
|
404
408
|
<a id="session-daemon-tools"></a>
|
|
405
409
|
<a id="session-tools"></a>
|
package/docs/plugins.md
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
| 添加仪表盘、文件查看器或项目工具 | 工作区面板、文件帮助方法与浏览器 UI |
|
|
22
22
|
| 方便查找常用操作 | 操作面板命令与快捷键 |
|
|
23
23
|
| 运行构建、测试或开发服务器 | 工作区终端命令 |
|
|
24
|
-
|
|
|
24
|
+
| 定制外观与界面布局 | 主题、明暗主题组合与网关展示区域 |
|
|
25
25
|
| 在聊天和文件中预览图表、文本格式 | 浏览器内容渲染器 |
|
|
26
26
|
| 读取或修改工作区文件 | 列出、读取、写入、移动、删除及上传文件 |
|
|
27
27
|
| 显示后端实时结果 | 浏览器入口与服务端入口之间的请求或流式通道 |
|
|
@@ -76,10 +76,30 @@ v5 `stylesheets` 贡献包含 `id`、HTTP(S) `url` 和可选 `order`(默认 `1
|
|
|
76
76
|
|
|
77
77
|
基础主题同步提供默认布局与控件表现,主题 CSS 可扩展配色与布局;基础规则在 `pi-web-base` cascade layer,普通未分层主题规则遵循 CSS cascade 覆盖。内部选择器、共享类和外观仍属实验性,不因能力版本而冻结;具体控件入口见[共享 UI 导航](https://github.com/nayuto-wakusei/pi-web-ChineseTranslation/blob/main/docs/ui-primitives.md)。
|
|
78
78
|
|
|
79
|
+
宿主锚点弹层支持面板 CSS 变量 `--ui-popup-placement`,可取 `below-end`、`below-start`、`above-start` 或 `left-end`。宿主显式定位选项优先;未指定选项时读取该变量,空值或不支持的值使用默认 `below-end`。样式只选择首选对齐,宿主仍按可见视口约束尺寸并在必要时切换上下方向,继续管理焦点和弹层关闭。
|
|
80
|
+
|
|
79
81
|
v5 `syntaxHighlighters` 返回有序、不重叠的 UTF-16 范围 token,不返回 HTML;宿主负责安全显示,插件遵守输入 `signal`。v5 内容渲染器还可提供 `title`、同步 `supports(request)`,并接收机器、语言和文件路径提示;正文仍是不可信输入,净化与清理要求不变。精确签名以公开声明为准。
|
|
80
82
|
|
|
81
83
|
Pi 的 Markdown transformer 链在 daemon 的浏览器投影阶段运行,仅对完成及历史的用户、assistant 文本和 thinking 派生 `displayText`;部分流式文本完成后才应用,文件预览不受影响。canonical 消息、持久化历史、模型输入、审计原文和实际 `thinkingLevel` 不变。“复制消息”和消息操作使用原文;代码围栏的 Raw/Copy 使用变换后的围栏源码。
|
|
82
84
|
|
|
85
|
+
<a id="ui-presentation"></a>
|
|
86
|
+
### 界面展示区域
|
|
87
|
+
|
|
88
|
+
浏览器 API v5 的 `uiPresentations` 贡献以 `id`、`region` 和同步 `render(context)` 声明展示区域。插件必须声明 `{ pluginId: "pi-web", id: "ui-presentation", version: 1, parse }` 依赖。展示贡献属于整个网关应用,不接受远端或机器专属注册;每个区域只允许一个所有者,重复贡献会拒绝激活。
|
|
89
|
+
|
|
90
|
+
| `region` | 宿主提供的命名插槽 |
|
|
91
|
+
| --- | --- |
|
|
92
|
+
| `navigation` | `header`、`machines`、`projects`、`project-resize`、`workspaces`、`workspace-resize`、`sessions` |
|
|
93
|
+
| `context-bar` | `content`、`actions` |
|
|
94
|
+
| `chat-chrome` | `transcript`、`composer` |
|
|
95
|
+
| `settings-navigation` | `navigation` |
|
|
96
|
+
|
|
97
|
+
`navigation` 贡献可选声明 `navigationLayout: "tree"`,请求宿主将原有列表组合为选中分支树:在选中项目下展开工作区,在选中工作区下展开会话;普通文件夹省略重复的工作区层。其他区域不能声明该字段,不支持的布局值会拒绝激活。树模式采用静态分区标题,由节点展开控件管理分支,不沿用手机独立列表的单层互斥折叠;定向定位工作区或会话时先展开所选祖先。展开和选择由宿主控件处理,数据仍由原有 controller 按当前选择加载;插件不会因此获得未选中分支的会话数据。未声明时保留宿主的独立列表布局与折叠偏好。
|
|
98
|
+
|
|
99
|
+
渲染器使用 `context.slots` 中的名称输出 `<slot name="...">`,不查找、移动或重建宿主控件。宿主持有编辑器和消息视图的生命周期,界面切换不重建它们;导航列表可随树形与独立布局切换重新装配,操作仍复用宿主菜单、信任入口和权限检查。上下文仅含普通/管理模式、紧凑布局标记及机器、项目、工作区、会话的只读标识和显示名称;可选操作由宿主按权限提供,并在选择或生命周期变化后失效。调用操作时还会核对展示贡献当前是否活动,未重绘前失去活动资格也不能执行保留的回调;界面回退后,旧快照不会因贡献恢复活动而重新生效。它不提供凭据、消息正文、内部路径或普通宿主会话连接,管理视图也不因此获得额外权限。
|
|
100
|
+
|
|
101
|
+
禁用或缺少展示贡献时使用宿主默认界面,并恢复独立导航列表。展示渲染失败时,宿主停止使用该插件的展示贡献、样式和主题,报告错误并回退;插件仍是可信代码,此机制不是执行沙箱。布局 API 与样式表互补,精确类型以公开 `plugin-api` 声明为准。
|
|
102
|
+
|
|
83
103
|
### 应用级面板与选择
|
|
84
104
|
|
|
85
105
|
`applicationPanels` 与 `workspacePanels` 由同一个浏览器工具区域装配。前者依附当前机器,无需先选项目、工作区或会话;后者需要已选工作区。应用级面板获得当前机器与公开选择快照,`workspace` 和工作区终端按可用性提供。内置 Info 使用应用级面板;无工作区时仍可显示机器和 PI WEB 状态。
|
|
@@ -211,6 +231,7 @@ ln -s /path/to/plugin-folder ~/.pi-web/plugins/my-plugin
|
|
|
211
231
|
<a id="included-tools-and-optional-packages"></a>
|
|
212
232
|
## 内置工具与可选包
|
|
213
233
|
|
|
234
|
+
- **Custom UI Codex** 随包提供且默认启用,提供 Codex 风格导航、聊天外围布局、设置导航及明暗主题。它只改变展示,中文语言插件与功能权限保持独立。可在网关的插件设置中禁用并刷新页面,恢复宿主默认界面;浏览器插件变更不要求重启 daemon。
|
|
214
235
|
- **终端**提供终端和命令运行,是普通启动的必需插件,仅紧急安全启动可跳过。
|
|
215
236
|
- **文件**提供文件浏览、预览、上传;禁用面板不移除其他插件的文件帮助方法。
|
|
216
237
|
- **Git**发现工作区并显示状态/差异;禁用后保留项目目录工作区,除非其他提供器认领。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chainingintention/pi-web-cn",
|
|
3
|
-
"version": "2.202610.
|
|
3
|
+
"version": "2.202610.3",
|
|
4
4
|
"description": "Web UI for persistent Pi Coding Agent sessions in real workspaces.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Federico Jaramillo Martinez",
|
|
@@ -111,7 +111,7 @@
|
|
|
111
111
|
"marked": "^18.1.1",
|
|
112
112
|
"node-pty": "^1.1.0",
|
|
113
113
|
"pi-web-typebox": "npm:typebox@1.3.37",
|
|
114
|
-
"undici": "^8.
|
|
114
|
+
"undici": "^8.12.2",
|
|
115
115
|
"ws": "^8.22.0",
|
|
116
116
|
"yauzl": "^3.4.0"
|
|
117
117
|
},
|