@hyperdreamer/pi-webui 1.14.1 → 1.15.0

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.
@@ -54,7 +54,7 @@
54
54
  html, body { margin: 0; height: 100%; overflow: hidden; background: var(--pi-bg); color: var(--pi-text); }
55
55
  body { min-height: 100dvh; }
56
56
  </style>
57
- <script type="module" crossorigin src="./assets/index-2EIg2vwJ.js"></script>
57
+ <script type="module" crossorigin src="./assets/index-DEhtRZU8.js"></script>
58
58
  <link rel="modulepreload" crossorigin href="./assets/vendor-editor-core-vyMPzMNA.js">
59
59
  <link rel="modulepreload" crossorigin href="./assets/vendor-editor-languages-DlEQaRIv.js">
60
60
  <link rel="modulepreload" crossorigin href="./assets/vendor-terminal-D8k4UKM2.js">
@@ -2,6 +2,80 @@
2
2
  export const TASKS_CONFIG_PATH = ".pi-webui/tasks.json";
3
3
  export const TASKS_CONFIG_VERSION = 1;
4
4
  const taskIdPattern = /^[a-z][a-z0-9.-]*$/u;
5
+ export const emptyWorkspaceTasksConfig = {
6
+ version: TASKS_CONFIG_VERSION,
7
+ tasks: [],
8
+ };
9
+ export function suggestWorkspaceTaskId(title) {
10
+ const id = title.toLowerCase().replace(/[^a-z0-9]+/gu, "-").replace(/^-+|-+$/gu, "");
11
+ if (id === "")
12
+ return "task";
13
+ return /^\d/u.test(id) ? `task-${id}` : id;
14
+ }
15
+ export function validateAndNormalizeDraft(draft, existingTasks, originalIndex) {
16
+ const id = draft.id.trim();
17
+ const title = draft.title.trim();
18
+ const description = draft.description.trim();
19
+ const group = draft.group.trim();
20
+ const errors = {};
21
+ if (id === "") {
22
+ errors.id = "ID is required.";
23
+ }
24
+ else if (!taskIdPattern.test(id)) {
25
+ errors.id = `ID must match ${taskIdPattern.source}.`;
26
+ }
27
+ else if (existingTasks.some((task, index) => index !== originalIndex && task.id === id)) {
28
+ errors.id = `Task ID "${id}" already exists.`;
29
+ }
30
+ if (title === "")
31
+ errors.title = "Title is required.";
32
+ if (draft.command.trim() === "")
33
+ errors.command = "Command script is required.";
34
+ if (Object.keys(errors).length > 0)
35
+ return { ok: false, errors };
36
+ return {
37
+ ok: true,
38
+ task: {
39
+ id,
40
+ title,
41
+ command: draft.command,
42
+ ...(description === "" ? {} : { description }),
43
+ ...(group === "" ? {} : { group }),
44
+ confirm: draft.confirm,
45
+ },
46
+ };
47
+ }
48
+ export function appendWorkspaceTask(config, task) {
49
+ return { version: config.version, tasks: [...config.tasks, task] };
50
+ }
51
+ export function replaceWorkspaceTaskAt(config, index, task) {
52
+ assertWorkspaceTaskIndex(config, index);
53
+ return {
54
+ version: config.version,
55
+ tasks: [...config.tasks.slice(0, index), task, ...config.tasks.slice(index + 1)],
56
+ };
57
+ }
58
+ export function removeWorkspaceTaskAt(config, index) {
59
+ assertWorkspaceTaskIndex(config, index);
60
+ return {
61
+ version: config.version,
62
+ tasks: [...config.tasks.slice(0, index), ...config.tasks.slice(index + 1)],
63
+ };
64
+ }
65
+ export function serializeWorkspaceTasksConfig(config) {
66
+ const canonicalConfig = {
67
+ version: config.version,
68
+ tasks: config.tasks.map((task) => ({
69
+ id: task.id,
70
+ title: task.title,
71
+ command: task.command,
72
+ ...(task.description === undefined ? {} : { description: task.description }),
73
+ ...(task.group === undefined ? {} : { group: task.group }),
74
+ confirm: task.confirm,
75
+ })),
76
+ };
77
+ return `${JSON.stringify(canonicalConfig, null, 2)}\n`;
78
+ }
5
79
  export function parseTasksConfigText(text) {
6
80
  let parsed;
7
81
  try {
@@ -83,6 +157,11 @@ function optionalNonEmptyString(record, key, label) {
83
157
  return invalid(`${label} ${key} must be a non-empty string when provided`);
84
158
  return { ok: true, value };
85
159
  }
160
+ function assertWorkspaceTaskIndex(config, index) {
161
+ if (!Number.isInteger(index) || index < 0 || index >= config.tasks.length) {
162
+ throw new RangeError(`Task index ${String(index)} is out of range`);
163
+ }
164
+ }
86
165
  function invalid(error) {
87
166
  return { ok: false, error };
88
167
  }