@chainingintention/pi-web-cn 1.202606.3 → 1.202606.4

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.
@@ -1,11 +1,11 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" role="img" aria-labelledby="title desc">
2
- <title id="title">PI WEB mark</title>
3
- <desc id="desc">A horizontal brand bar.</desc>
4
- <style>
5
- .bar { fill: #00f0d8; }
6
- @media (prefers-color-scheme: light) {
7
- .bar { fill: #008c82; }
8
- }
9
- </style>
10
- <rect class="bar" x="128" y="448" width="768" height="128"/>
11
- </svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" role="img" aria-labelledby="title desc">
2
+ <title id="title">PI WEB mark</title>
3
+ <desc id="desc">A horizontal brand bar.</desc>
4
+ <style>
5
+ .bar { fill: #00f0d8; }
6
+ @media (prefers-color-scheme: light) {
7
+ .bar { fill: #008c82; }
8
+ }
9
+ </style>
10
+ <rect class="bar" x="128" y="448" width="768" height="128"/>
11
+ </svg>
@@ -1,13 +1,13 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
6
- <title>PI WEB</title>
7
- <meta name="theme-color" content="#0d1117" />
8
- <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
9
- <link rel="apple-touch-icon" href="/apple-touch-icon.png" />
10
- <link rel="manifest" href="/manifest.webmanifest" />
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
6
+ <title>PI WEB</title>
7
+ <meta name="theme-color" content="#0d1117" />
8
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
9
+ <link rel="apple-touch-icon" href="/apple-touch-icon.png" />
10
+ <link rel="manifest" href="/manifest.webmanifest" />
11
11
  <style>
12
12
  :root {
13
13
  color-scheme: dark;
@@ -49,12 +49,12 @@
49
49
  }
50
50
  html, body { margin: 0; height: 100%; overflow: hidden; background: var(--pi-bg); color: var(--pi-text); }
51
51
  body { min-height: 100dvh; }
52
- </style>
53
- <script type="module" crossorigin src="/assets/index-BjUH4a8R.js"></script>
52
+ </style>
53
+ <script type="module" crossorigin src="/assets/index-Csx3hC75.js"></script>
54
54
  <link rel="modulepreload" crossorigin href="/assets/vendor-editor-core-B4Sq6exx.js">
55
55
  <link rel="modulepreload" crossorigin href="/assets/vendor-editor-languages-DznYbTkJ.js">
56
- </head>
57
- <body>
58
- <pi-web-app></pi-web-app>
59
- </body>
60
- </html>
56
+ </head>
57
+ <body>
58
+ <pi-web-app></pi-web-app>
59
+ </body>
60
+ </html>
@@ -1,24 +1,24 @@
1
- {
2
- "name": "PI WEB",
3
- "short_name": "PI WEB",
4
- "description": "Remote web UI and browser control plane for persistent Pi Coding Agent sessions.",
5
- "start_url": "/",
6
- "scope": "/",
7
- "display": "standalone",
8
- "background_color": "#0d1117",
9
- "theme_color": "#0d1117",
10
- "icons": [
11
- {
12
- "src": "/pwa-icon-192.png",
13
- "sizes": "192x192",
14
- "type": "image/png",
15
- "purpose": "any maskable"
16
- },
17
- {
18
- "src": "/pwa-icon-512.png",
19
- "sizes": "512x512",
20
- "type": "image/png",
21
- "purpose": "any maskable"
22
- }
23
- ]
24
- }
1
+ {
2
+ "name": "PI WEB",
3
+ "short_name": "PI WEB",
4
+ "description": "Remote web UI and browser control plane for persistent Pi Coding Agent sessions.",
5
+ "start_url": "/",
6
+ "scope": "/",
7
+ "display": "standalone",
8
+ "background_color": "#0d1117",
9
+ "theme_color": "#0d1117",
10
+ "icons": [
11
+ {
12
+ "src": "/pwa-icon-192.png",
13
+ "sizes": "192x192",
14
+ "type": "image/png",
15
+ "purpose": "any maskable"
16
+ },
17
+ {
18
+ "src": "/pwa-icon-512.png",
19
+ "sizes": "512x512",
20
+ "type": "image/png",
21
+ "purpose": "any maskable"
22
+ }
23
+ ]
24
+ }
@@ -1,9 +1,9 @@
1
- {
2
- "name": "@pi-web/info-plugin",
3
- "private": true,
4
- "piWeb": {
5
- "plugins": [
6
- { "id": "info", "module": "pi-web-plugin.js" }
7
- ]
8
- }
9
- }
1
+ {
2
+ "name": "@pi-web/info-plugin",
3
+ "private": true,
4
+ "piWeb": {
5
+ "plugins": [
6
+ { "id": "info", "module": "pi-web-plugin.js" }
7
+ ]
8
+ }
9
+ }
@@ -1,4 +1,4 @@
1
- // Generated from pi-web-plugins\info\pi-web-plugin.ts. Do not edit directly.
1
+ // Generated from pi-web-plugins/info/pi-web-plugin.ts. Do not edit directly.
2
2
  const plugin = {
3
3
  apiVersion: 1,
4
4
  name: "信息插件",
@@ -27,21 +27,21 @@ const plugin = {
27
27
  {
28
28
  id: "workspace.info",
29
29
  title: "信息",
30
- icon: svg `
31
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
32
- <circle cx="12" cy="12" r="9"></circle>
33
- <path d="M12 11v5"></path>
34
- <path d="M12 8h.01"></path>
35
- </svg>
30
+ icon: svg `
31
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
32
+ <circle cx="12" cy="12" r="9"></circle>
33
+ <path d="M12 11v5"></path>
34
+ <path d="M12 8h.01"></path>
35
+ </svg>
36
36
  `,
37
37
  order: 1000,
38
- render: (context) => html `
39
- <section class="toolbar"><strong>信息</strong></section>
40
- <section class="viewer">
41
- <p><strong>工作区</strong></p>
42
- <p class="muted">${context.workspace.label}</p>
43
- <p class="muted">${context.workspace.path}</p>
44
- </section>
38
+ render: (context) => html `
39
+ <section class="toolbar"><strong>信息</strong></section>
40
+ <section class="viewer">
41
+ <p><strong>工作区</strong></p>
42
+ <p class="muted">${context.workspace.label}</p>
43
+ <p class="muted">${context.workspace.path}</p>
44
+ </section>
45
45
  `,
46
46
  },
47
47
  ],
@@ -1,9 +1,9 @@
1
- {
2
- "name": "@pi-web/updates-plugin",
3
- "private": true,
4
- "piWeb": {
5
- "plugins": [
6
- { "id": "updates", "module": "pi-web-plugin.js" }
7
- ]
8
- }
9
- }
1
+ {
2
+ "name": "@pi-web/updates-plugin",
3
+ "private": true,
4
+ "piWeb": {
5
+ "plugins": [
6
+ { "id": "updates", "module": "pi-web-plugin.js" }
7
+ ]
8
+ }
9
+ }
@@ -1,4 +1,4 @@
1
- // Generated from pi-web-plugins\updates\pi-web-plugin.ts. Do not edit directly.
1
+ // Generated from pi-web-plugins/updates/pi-web-plugin.ts. Do not edit directly.
2
2
  function messagesFor(state) {
3
3
  return state?.piWebStatus?.messages ?? [];
4
4
  }
@@ -57,22 +57,22 @@ function renderComponent(html, component) {
57
57
  : component.stale
58
58
  ? "需要重启"
59
59
  : "当前版本";
60
- return html `
61
- <div class="updates-version-row">
62
- <strong>${componentLabel(component.label)}</strong>
63
- <span>${status}</span>
64
- <small>运行中 ${formatVersion(component.runtimeVersion)} · 已安装 ${formatVersion(component.installedVersion)}</small>
65
- <small>${installationLabel(component.installation)}${component.installation?.path === undefined ? "" : ` · ${component.installation.path}`}</small>
66
- </div>
60
+ return html `
61
+ <div class="updates-version-row">
62
+ <strong>${componentLabel(component.label)}</strong>
63
+ <span>${status}</span>
64
+ <small>运行中 ${formatVersion(component.runtimeVersion)} · 已安装 ${formatVersion(component.installedVersion)}</small>
65
+ <small>${installationLabel(component.installation)}${component.installation?.path === undefined ? "" : ` · ${component.installation.path}`}</small>
66
+ </div>
67
67
  `;
68
68
  }
69
69
  function renderCommand(html, label, command) {
70
- return html `
71
- <div class="updates-command">
72
- <span>${label}</span>
73
- <code>${command}</code>
74
- <button @click=${() => { void navigator.clipboard.writeText(command); }}>复制</button>
75
- </div>
70
+ return html `
71
+ <div class="updates-command">
72
+ <span>${label}</span>
73
+ <code>${command}</code>
74
+ <button @click=${() => { void navigator.clipboard.writeText(command); }}>复制</button>
75
+ </div>
76
76
  `;
77
77
  }
78
78
  function renderCommands(html, status) {
@@ -85,68 +85,68 @@ function renderCommands(html, status) {
85
85
  ].filter((entry) => typeof entry[1] === "string" && entry[1] !== "");
86
86
  if (commands.length === 0)
87
87
  return undefined;
88
- return html `
89
- <section>
90
- <strong>建议命令</strong>
91
- ${commands.map(([label, command]) => renderCommand(html, label, command))}
92
- </section>
88
+ return html `
89
+ <section>
90
+ <strong>建议命令</strong>
91
+ ${commands.map(([label, command]) => renderCommand(html, label, command))}
92
+ </section>
93
93
  `;
94
94
  }
95
95
  function renderUpdatesPanel(html, state) {
96
96
  const status = statusFor(state);
97
97
  if (status === undefined) {
98
- return html `
99
- <section class="toolbar"><strong>更新</strong></section>
100
- <section class="viewer"><p class="muted">正在检查 PI WEB 更新状态…</p></section>
98
+ return html `
99
+ <section class="toolbar"><strong>更新</strong></section>
100
+ <section class="viewer"><p class="muted">正在检查 PI WEB 更新状态…</p></section>
101
101
  `;
102
102
  }
103
103
  const messages = status.messages;
104
- return html `
105
- <style>
106
- .viewer.updates-status { flex: 1 1 auto; min-height: 0; box-sizing: border-box; display: flex; flex-direction: column; gap: 14px; padding: 12px; overflow-y: auto; overflow-x: hidden; }
107
- .viewer.updates-status section { flex: 0 0 auto; min-width: 0; display: grid; gap: 8px; }
108
- .updates-message { display: grid; gap: 5px; border: 1px solid var(--pi-border); border-radius: 8px; padding: 10px; background: var(--pi-surface); }
109
- .updates-message.warning { border-color: var(--pi-warning-border); background: var(--pi-warning-surface); }
110
- .updates-message.error { border-color: var(--pi-danger); }
111
- .updates-message-title { display: flex; gap: 8px; align-items: baseline; }
112
- .updates-message-title span { color: var(--pi-muted); font-size: 12px; text-transform: uppercase; }
113
- .updates-version-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 3px 10px; border-bottom: 1px solid var(--pi-border-muted); padding: 6px 0; }
114
- .updates-version-row small { grid-column: 1 / -1; color: var(--pi-muted); }
115
- .updates-command { min-width: 0; display: grid; grid-template-columns: minmax(90px, auto) minmax(0, 1fr) auto; gap: 8px; align-items: center; }
116
- .updates-command code { overflow: auto; border: 1px solid var(--pi-border-muted); border-radius: 6px; background: var(--pi-bg); padding: 5px 7px; white-space: nowrap; }
117
- .updates-meta { display: grid; gap: 2px; color: var(--pi-muted); font-size: 12px; }
118
- @media (max-width: 520px) {
119
- .updates-command { grid-template-columns: minmax(0, 1fr) auto; }
120
- .updates-command > span { grid-column: 1 / -1; }
121
- }
122
- </style>
123
- <section class="toolbar"><strong>更新</strong><span class="stale">测试版</span>${messages.length > 0 ? html `<span class="stale">${String(messages.length)}</span>` : null}</section>
124
- <section class="viewer updates-status">
125
- <section>
126
- ${messages.length === 0 ? html `<p class="muted">没有 PI WEB 更新或重启消息。</p>` : messages.map((message) => html `
127
- <article class=${`updates-message ${message.severity}`}>
128
- <div class="updates-message-title"><strong>${message.title}</strong><span>${severityLabel(message.severity)}</span></div>
129
- <p>${message.body}</p>
130
- ${message.command === undefined ? null : html `<code>${message.command}</code>`}
131
- </article>
132
- `)}
133
- </section>
134
-
135
- <section>
136
- <strong>已安装服务</strong>
137
- ${renderComponent(html, status.components.web)}
138
- ${renderComponent(html, status.components.sessiond)}
139
- </section>
140
-
141
- ${renderCommands(html, status)}
142
-
143
- <section class="updates-meta">
144
- <span>生成时间 ${status.generatedAt}</span>
145
- ${status.release.latestVersion === undefined ? null : html `<span>最新 npm 版本 ${status.release.latestVersion}</span>`}
146
- ${status.release.skipped === true ? html `<span>远程版本检查已跳过。</span>` : null}
147
- ${status.release.error === undefined ? null : html `<span>远程版本检查失败:${status.release.error}</span>`}
148
- </section>
149
- </section>
104
+ return html `
105
+ <style>
106
+ .viewer.updates-status { flex: 1 1 auto; min-height: 0; box-sizing: border-box; display: flex; flex-direction: column; gap: 14px; padding: 12px; overflow-y: auto; overflow-x: hidden; }
107
+ .viewer.updates-status section { flex: 0 0 auto; min-width: 0; display: grid; gap: 8px; }
108
+ .updates-message { display: grid; gap: 5px; border: 1px solid var(--pi-border); border-radius: 8px; padding: 10px; background: var(--pi-surface); }
109
+ .updates-message.warning { border-color: var(--pi-warning-border); background: var(--pi-warning-surface); }
110
+ .updates-message.error { border-color: var(--pi-danger); }
111
+ .updates-message-title { display: flex; gap: 8px; align-items: baseline; }
112
+ .updates-message-title span { color: var(--pi-muted); font-size: 12px; text-transform: uppercase; }
113
+ .updates-version-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 3px 10px; border-bottom: 1px solid var(--pi-border-muted); padding: 6px 0; }
114
+ .updates-version-row small { grid-column: 1 / -1; color: var(--pi-muted); }
115
+ .updates-command { min-width: 0; display: grid; grid-template-columns: minmax(90px, auto) minmax(0, 1fr) auto; gap: 8px; align-items: center; }
116
+ .updates-command code { overflow: auto; border: 1px solid var(--pi-border-muted); border-radius: 6px; background: var(--pi-bg); padding: 5px 7px; white-space: nowrap; }
117
+ .updates-meta { display: grid; gap: 2px; color: var(--pi-muted); font-size: 12px; }
118
+ @media (max-width: 520px) {
119
+ .updates-command { grid-template-columns: minmax(0, 1fr) auto; }
120
+ .updates-command > span { grid-column: 1 / -1; }
121
+ }
122
+ </style>
123
+ <section class="toolbar"><strong>更新</strong><span class="stale">测试版</span>${messages.length > 0 ? html `<span class="stale">${String(messages.length)}</span>` : null}</section>
124
+ <section class="viewer updates-status">
125
+ <section>
126
+ ${messages.length === 0 ? html `<p class="muted">没有 PI WEB 更新或重启消息。</p>` : messages.map((message) => html `
127
+ <article class=${`updates-message ${message.severity}`}>
128
+ <div class="updates-message-title"><strong>${message.title}</strong><span>${severityLabel(message.severity)}</span></div>
129
+ <p>${message.body}</p>
130
+ ${message.command === undefined ? null : html `<code>${message.command}</code>`}
131
+ </article>
132
+ `)}
133
+ </section>
134
+
135
+ <section>
136
+ <strong>已安装服务</strong>
137
+ ${renderComponent(html, status.components.web)}
138
+ ${renderComponent(html, status.components.sessiond)}
139
+ </section>
140
+
141
+ ${renderCommands(html, status)}
142
+
143
+ <section class="updates-meta">
144
+ <span>生成时间 ${status.generatedAt}</span>
145
+ ${status.release.latestVersion === undefined ? null : html `<span>最新 npm 版本 ${status.release.latestVersion}</span>`}
146
+ ${status.release.skipped === true ? html `<span>远程版本检查已跳过。</span>` : null}
147
+ ${status.release.error === undefined ? null : html `<span>远程版本检查失败:${status.release.error}</span>`}
148
+ </section>
149
+ </section>
150
150
  `;
151
151
  }
152
152
  const plugin = {
@@ -158,13 +158,13 @@ const plugin = {
158
158
  {
159
159
  id: "workspace.updates",
160
160
  title: "更新",
161
- icon: svg `
162
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
163
- <path d="M20 6v5h-5"></path>
164
- <path d="M4 18v-5h5"></path>
165
- <path d="M18.4 9A7 7 0 0 0 6.1 6.7L4 8.8"></path>
166
- <path d="M5.6 15A7 7 0 0 0 17.9 17.3L20 15.2"></path>
167
- </svg>
161
+ icon: svg `
162
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
163
+ <path d="M20 6v5h-5"></path>
164
+ <path d="M4 18v-5h5"></path>
165
+ <path d="M18.4 9A7 7 0 0 0 6.1 6.7L4 8.8"></path>
166
+ <path d="M5.6 15A7 7 0 0 0 17.9 17.3L20 15.2"></path>
167
+ </svg>
168
168
  `,
169
169
  order: 100,
170
170
  visible: (context) => shouldShowUpdatesPanel(context.state),
@@ -1,4 +1,4 @@
1
- // Generated from pi-web-plugins\workspace-tasks\config.ts. Do not edit directly.
1
+ // Generated from pi-web-plugins/workspace-tasks/config.ts. Do not edit directly.
2
2
  export const TASKS_CONFIG_PATH = ".pi-web/tasks.json";
3
3
  export const TASKS_CONFIG_VERSION = 1;
4
4
  const taskIdPattern = /^[a-z][a-z0-9.-]*$/u;
@@ -1,9 +1,9 @@
1
- {
2
- "name": "@pi-web/workspace-tasks-plugin",
3
- "private": true,
4
- "piWeb": {
5
- "plugins": [
6
- { "id": "workspace-tasks", "module": "pi-web-plugin.js" }
7
- ]
8
- }
9
- }
1
+ {
2
+ "name": "@pi-web/workspace-tasks-plugin",
3
+ "private": true,
4
+ "piWeb": {
5
+ "plugins": [
6
+ { "id": "workspace-tasks", "module": "pi-web-plugin.js" }
7
+ ]
8
+ }
9
+ }
@@ -1,4 +1,4 @@
1
- // Generated from pi-web-plugins\workspace-tasks\pi-web-plugin.ts. Do not edit directly.
1
+ // Generated from pi-web-plugins/workspace-tasks/pi-web-plugin.ts. Do not edit directly.
2
2
  import { TASKS_CONFIG_PATH } from "./config.js";
3
3
  import { defineTasksPanelElement, tasksPanelBadge } from "./tasksPanelElement.js";
4
4
  const plugin = {
@@ -26,15 +26,15 @@ const plugin = {
26
26
  {
27
27
  id: "workspace.tasks",
28
28
  title: "任务",
29
- icon: svg `
30
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
31
- <path d="M9 6h11"></path>
32
- <path d="M9 12h11"></path>
33
- <path d="M9 18h11"></path>
34
- <path d="m4 6 .8 .8L6.5 5"></path>
35
- <path d="m4 12 .8 .8 1.7-1.8"></path>
36
- <path d="m4 18 .8 .8 1.7-1.8"></path>
37
- </svg>
29
+ icon: svg `
30
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
31
+ <path d="M9 6h11"></path>
32
+ <path d="M9 12h11"></path>
33
+ <path d="M9 18h11"></path>
34
+ <path d="m4 6 .8 .8L6.5 5"></path>
35
+ <path d="m4 12 .8 .8 1.7-1.8"></path>
36
+ <path d="m4 18 .8 .8 1.7-1.8"></path>
37
+ </svg>
38
38
  `,
39
39
  order: 40,
40
40
  badge: (context) => tasksPanelBadge(context),
@@ -1,4 +1,4 @@
1
- // Generated from pi-web-plugins\workspace-tasks\taskRunner.ts. Do not edit directly.
1
+ // Generated from pi-web-plugins/workspace-tasks/taskRunner.ts. Do not edit directly.
2
2
  export function runWorkspaceTaskInTerminal(terminal, task) {
3
3
  return terminal.runCommand({
4
4
  title: task.title,
@@ -1,4 +1,4 @@
1
- // Generated from pi-web-plugins\workspace-tasks\tasksPanelElement.ts. Do not edit directly.
1
+ // Generated from pi-web-plugins/workspace-tasks/tasksPanelElement.ts. Do not edit directly.
2
2
  import { TASKS_CONFIG_PATH } from "./config.js";
3
3
  import { runWorkspaceTaskInTerminal } from "./taskRunner.js";
4
4
  import { loadWorkspaceTasksConfig, tasksConfigRefreshHint, tasksConfigUnavailableMessage } from "./workspaceTasksClient.js";
@@ -55,19 +55,19 @@ class PiWebTasksPanel extends HTMLElement {
55
55
  return;
56
56
  }
57
57
  const state = getOrLoadWorkspaceConfig(context);
58
- this.root.innerHTML = `
59
- ${taskStyles()}
60
- <section class="toolbar">
61
- <strong>工作区任务</strong>
62
- <span class="toolbar-tasks">
63
- <button class="secondary" data-refresh-config ${state.kind === "loading" ? "disabled" : ""}>刷新</button>
64
- <button class="secondary" data-open-terminal>打开终端</button>
65
- </span>
66
- </section>
67
- ${this.renderStatus()}
68
- <section class="viewer tasks-viewer">
69
- ${this.renderConfigState(state)}
70
- </section>
58
+ this.root.innerHTML = `
59
+ ${taskStyles()}
60
+ <section class="toolbar">
61
+ <strong>工作区任务</strong>
62
+ <span class="toolbar-tasks">
63
+ <button class="secondary" data-refresh-config ${state.kind === "loading" ? "disabled" : ""}>刷新</button>
64
+ <button class="secondary" data-open-terminal>打开终端</button>
65
+ </span>
66
+ </section>
67
+ ${this.renderStatus()}
68
+ <section class="viewer tasks-viewer">
69
+ ${this.renderConfigState(state)}
70
+ </section>
71
71
  `;
72
72
  this.root.querySelector("button[data-refresh-config]")?.addEventListener("click", () => {
73
73
  void this.refreshConfig(context);
@@ -104,9 +104,9 @@ class PiWebTasksPanel extends HTMLElement {
104
104
  return renderUnavailableState(state);
105
105
  if (state.config.tasks.length === 0)
106
106
  return `<p class="muted">${escapeHtml(state.path)} 中没有定义任务。请在文件中添加任务,然后点击刷新。</p>`;
107
- return `
108
- <p class="muted">任务会在专用工作区终端中运行,并切换到该终端。编辑 ${escapeHtml(state.path)} 后点击刷新重新加载。</p>
109
- ${renderTaskGroups(state.config.tasks, this.runningTaskId)}
107
+ return `
108
+ <p class="muted">任务会在专用工作区终端中运行,并切换到该终端。编辑 ${escapeHtml(state.path)} 后点击刷新重新加载。</p>
109
+ ${renderTaskGroups(state.config.tasks, this.runningTaskId)}
110
110
  `;
111
111
  }
112
112
  renderStatus() {
@@ -233,15 +233,15 @@ function renderTask(task, runningTaskId) {
233
233
  const running = runningTaskId === task.id;
234
234
  const disabled = runningTaskId !== undefined;
235
235
  const description = task.description === undefined ? "" : `<span>${escapeHtml(task.description)}</span>`;
236
- return `
237
- <article class="task-card">
238
- <div class="task-copy">
239
- <strong>${escapeHtml(task.title)}</strong>
240
- ${description}
241
- <code>${escapeHtml(task.command)}</code>
242
- </div>
243
- <button data-task-id="${escapeAttr(task.id)}" ${disabled ? "disabled" : ""}>${running ? "正在分发…" : "运行"}</button>
244
- </article>
236
+ return `
237
+ <article class="task-card">
238
+ <div class="task-copy">
239
+ <strong>${escapeHtml(task.title)}</strong>
240
+ ${description}
241
+ <code>${escapeHtml(task.command)}</code>
242
+ </div>
243
+ <button data-task-id="${escapeAttr(task.id)}" ${disabled ? "disabled" : ""}>${running ? "正在分发…" : "运行"}</button>
244
+ </article>
245
245
  `;
246
246
  }
247
247
  function taskFromConfigState(state, taskId) {
@@ -250,38 +250,38 @@ function taskFromConfigState(state, taskId) {
250
250
  return state.config.tasks.find((task) => task.id === taskId);
251
251
  }
252
252
  function taskStyles() {
253
- return `
254
- <style>
255
- :host { display: contents; }
256
- .toolbar { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 10px 12px; border-bottom: 1px solid var(--pi-border-muted); }
257
- .toolbar-tasks { display: inline-flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; }
258
- .viewer { box-sizing: border-box; min-height: 0; overflow: auto; padding: 12px; }
259
- .tasks-viewer { display: grid; align-content: start; gap: 12px; }
260
- .tasks { display: grid; gap: 14px; }
261
- .task-group { display: grid; gap: 10px; }
262
- .task-group h3 { margin: 4px 0 0; color: var(--pi-text-secondary); font-size: 13px; text-transform: uppercase; letter-spacing: 0.04em; }
263
- .task-card { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 12px; align-items: center; border: 1px solid var(--pi-border); border-radius: 10px; background: var(--pi-surface); padding: 12px; }
264
- .task-copy { display: grid; min-width: 0; gap: 5px; }
265
- .task-copy span, .muted { color: var(--pi-muted); }
266
- code, pre { border: 1px solid var(--pi-border-muted); border-radius: 6px; background: var(--pi-bg); color: var(--pi-text-secondary); font: 12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
267
- code { overflow: auto; padding: 5px 7px; white-space: nowrap; }
268
- pre { margin: 8px 0 0; overflow: auto; padding: 8px; white-space: pre-wrap; }
269
- button { border: 1px solid var(--pi-accent-border); border-radius: 7px; background: var(--pi-accent); color: var(--pi-bg); cursor: pointer; padding: 6px 10px; font: inherit; }
270
- button.secondary { border-color: var(--pi-border); background: var(--pi-surface); color: var(--pi-text); }
271
- button:disabled { cursor: wait; opacity: 0.65; }
272
- .empty-state { border: 1px dashed var(--pi-border-muted); border-radius: 8px; color: var(--pi-muted); padding: 12px; }
273
- .empty-state p { margin: 6px 0 0; }
274
- .panel-status { margin: 12px 12px 0; }
275
- .status { border: 1px solid var(--pi-border); border-radius: 8px; padding: 10px; }
276
- .status.info { border-color: var(--pi-accent-border); background: var(--pi-bg-overlay-soft); }
277
- .status.success { border-color: var(--pi-success-border); background: var(--pi-success-surface); color: var(--pi-success); }
278
- .status.error { border-color: var(--pi-danger); color: var(--pi-danger); }
279
- .empty { padding: 16px; color: var(--pi-muted); }
280
- @media (max-width: 760px) {
281
- .task-card { grid-template-columns: 1fr; }
282
- .task-card button { justify-self: start; }
283
- }
284
- </style>
253
+ return `
254
+ <style>
255
+ :host { display: contents; }
256
+ .toolbar { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 10px 12px; border-bottom: 1px solid var(--pi-border-muted); }
257
+ .toolbar-tasks { display: inline-flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; }
258
+ .viewer { box-sizing: border-box; min-height: 0; overflow: auto; padding: 12px; }
259
+ .tasks-viewer { display: grid; align-content: start; gap: 12px; }
260
+ .tasks { display: grid; gap: 14px; }
261
+ .task-group { display: grid; gap: 10px; }
262
+ .task-group h3 { margin: 4px 0 0; color: var(--pi-text-secondary); font-size: 13px; text-transform: uppercase; letter-spacing: 0.04em; }
263
+ .task-card { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 12px; align-items: center; border: 1px solid var(--pi-border); border-radius: 10px; background: var(--pi-surface); padding: 12px; }
264
+ .task-copy { display: grid; min-width: 0; gap: 5px; }
265
+ .task-copy span, .muted { color: var(--pi-muted); }
266
+ code, pre { border: 1px solid var(--pi-border-muted); border-radius: 6px; background: var(--pi-bg); color: var(--pi-text-secondary); font: 12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
267
+ code { overflow: auto; padding: 5px 7px; white-space: nowrap; }
268
+ pre { margin: 8px 0 0; overflow: auto; padding: 8px; white-space: pre-wrap; }
269
+ button { border: 1px solid var(--pi-accent-border); border-radius: 7px; background: var(--pi-accent); color: var(--pi-bg); cursor: pointer; padding: 6px 10px; font: inherit; }
270
+ button.secondary { border-color: var(--pi-border); background: var(--pi-surface); color: var(--pi-text); }
271
+ button:disabled { cursor: wait; opacity: 0.65; }
272
+ .empty-state { border: 1px dashed var(--pi-border-muted); border-radius: 8px; color: var(--pi-muted); padding: 12px; }
273
+ .empty-state p { margin: 6px 0 0; }
274
+ .panel-status { margin: 12px 12px 0; }
275
+ .status { border: 1px solid var(--pi-border); border-radius: 8px; padding: 10px; }
276
+ .status.info { border-color: var(--pi-accent-border); background: var(--pi-bg-overlay-soft); }
277
+ .status.success { border-color: var(--pi-success-border); background: var(--pi-success-surface); color: var(--pi-success); }
278
+ .status.error { border-color: var(--pi-danger); color: var(--pi-danger); }
279
+ .empty { padding: 16px; color: var(--pi-muted); }
280
+ @media (max-width: 760px) {
281
+ .task-card { grid-template-columns: 1fr; }
282
+ .task-card button { justify-self: start; }
283
+ }
284
+ </style>
285
285
  `;
286
286
  }
287
287
  function escapeHtml(value) {
@@ -1,4 +1,4 @@
1
- // Generated from pi-web-plugins\workspace-tasks\workspaceTasksClient.ts. Do not edit directly.
1
+ // Generated from pi-web-plugins/workspace-tasks/workspaceTasksClient.ts. Do not edit directly.
2
2
  import { TASKS_CONFIG_PATH, parseTasksConfigText } from "./config.js";
3
3
  export const tasksConfigMissingMessage = "这里还没有配置工作区任务。";
4
4
  export const tasksConfigMissingHint = `${TASKS_CONFIG_PATH} 是可选文件。如果需要自定义任务,请在当前工作区创建它。`;
@@ -1,11 +1,11 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" role="img" aria-labelledby="title desc">
2
- <title id="title">PI WEB mark</title>
3
- <desc id="desc">A horizontal brand bar.</desc>
4
- <style>
5
- .bar { fill: #00f0d8; }
6
- @media (prefers-color-scheme: light) {
7
- .bar { fill: #008c82; }
8
- }
9
- </style>
10
- <rect class="bar" x="128" y="448" width="768" height="128"/>
11
- </svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" role="img" aria-labelledby="title desc">
2
+ <title id="title">PI WEB mark</title>
3
+ <desc id="desc">A horizontal brand bar.</desc>
4
+ <style>
5
+ .bar { fill: #00f0d8; }
6
+ @media (prefers-color-scheme: light) {
7
+ .bar { fill: #008c82; }
8
+ }
9
+ </style>
10
+ <rect class="bar" x="128" y="448" width="768" height="128"/>
11
+ </svg>