@linxin666/dsh-client-ui-task-board 0.1.16 → 0.1.18
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.i18n.yaml +2 -2
- package/README.md +11 -7
- package/README.zh.md +11 -7
- package/lib/client.js +821 -145
- package/lib/client.js.map +1 -1
- package/lib/index.js +1 -1
- package/lib/types/client/PluginSettingsCard.d.ts +11 -0
- package/lib/types/client/locales.d.ts +21 -0
- package/lib/types/client/schedule-presets.d.ts +10 -0
- package/lib/types/core/controller.d.ts +57 -1
- package/lib/types/core/execution.d.ts +65 -4
- package/lib/types/core/scheduler.d.ts +7 -0
- package/lib/types/core/store.d.ts +1 -1
- package/lib/types/core/tasks.d.ts +43 -0
- package/lib/types/core/use-cases/task-archive.d.ts +22 -0
- package/lib/types/core/use-cases/task-create.d.ts +1 -6
- package/lib/types/core/use-cases/task-update.d.ts +9 -4
- package/lib/types/index.d.ts +1 -1
- package/package.json +1 -1
- package/src/client/PluginSettingsCard.tsx +50 -47
- package/src/client/board/NewTaskModal.tsx +136 -3
- package/src/client/board/TaskBoard.tsx +48 -19
- package/src/client/board/TaskDetail.tsx +97 -8
- package/src/client/board.module.css +16 -0
- package/src/client/index.ts +71 -2
- package/src/client/locales.ts +42 -0
- package/src/client/schedule-presets.ts +13 -0
- package/src/client/settings-card.module.css +9 -0
- package/src/core/controller.ts +92 -2
- package/src/core/execution.ts +179 -12
- package/src/core/scheduler.ts +15 -0
- package/src/core/store.ts +16 -2
- package/src/core/tasks.ts +56 -0
- package/src/core/use-cases/task-archive.ts +48 -0
- package/src/core/use-cases/task-create.ts +12 -3
- package/src/core/use-cases/task-update.ts +34 -5
- package/src/index.ts +1 -1
package/lib/client.js
CHANGED
|
@@ -9,6 +9,18 @@ window.__ModuleLoader__.load({
|
|
|
9
9
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
10
10
|
let _deepseek_ai_dsh_client_runtime_client = require("@deepseek-ai/dsh-client-runtime/client");
|
|
11
11
|
//#region src/core/tasks.ts
|
|
12
|
+
/** Statuses a settled task may be archived from. */
|
|
13
|
+
const ARCHIVABLE_STATUSES = ["done", "failed"];
|
|
14
|
+
/** Permission presets a task may pin on its execution session (the `/permission <id>` ids). */
|
|
15
|
+
const TASK_PERMISSIONS = [
|
|
16
|
+
"read-only",
|
|
17
|
+
"workspace-write",
|
|
18
|
+
"danger-full-access"
|
|
19
|
+
];
|
|
20
|
+
/** Whether an unknown value is a known permission preset id. */
|
|
21
|
+
function isTaskPermission(value) {
|
|
22
|
+
return typeof value === "string" && TASK_PERMISSIONS.includes(value);
|
|
23
|
+
}
|
|
12
24
|
/** The five kanban columns, in display order. */
|
|
13
25
|
const COLUMNS = [
|
|
14
26
|
{
|
|
@@ -46,6 +58,11 @@ window.__ModuleLoader__.load({
|
|
|
46
58
|
function isTaskStatus(value) {
|
|
47
59
|
return typeof value === "string" && ALL_STATUSES.includes(value);
|
|
48
60
|
}
|
|
61
|
+
/** Normalize one optional execution-target string: trim; blank collapses to undefined. */
|
|
62
|
+
function normalizeTargetId$2(value) {
|
|
63
|
+
const trimmed = value?.trim();
|
|
64
|
+
return trimmed === void 0 || trimmed === "" ? void 0 : trimmed;
|
|
65
|
+
}
|
|
49
66
|
/** Create a task from user input. */
|
|
50
67
|
function createTask(input, now, id) {
|
|
51
68
|
return {
|
|
@@ -56,7 +73,10 @@ window.__ModuleLoader__.load({
|
|
|
56
73
|
status: "todo",
|
|
57
74
|
createdAt: now,
|
|
58
75
|
updatedAt: now,
|
|
59
|
-
executions: []
|
|
76
|
+
executions: [],
|
|
77
|
+
workspaceId: normalizeTargetId$2(input.workspaceId),
|
|
78
|
+
mode: normalizeTargetId$2(input.mode),
|
|
79
|
+
permission: isTaskPermission(input.permission) ? input.permission : void 0
|
|
60
80
|
};
|
|
61
81
|
}
|
|
62
82
|
/** Clone a task with an updated status and a fresh updatedAt. */
|
|
@@ -148,44 +168,42 @@ window.__ModuleLoader__.load({
|
|
|
148
168
|
return "running";
|
|
149
169
|
}
|
|
150
170
|
//#endregion
|
|
151
|
-
//#region src/core/use-cases/task-
|
|
171
|
+
//#region src/core/use-cases/task-archive.ts
|
|
152
172
|
/**
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
*/
|
|
157
|
-
/**
|
|
158
|
-
* Apply a create against the current ledger. Returns the new task and the
|
|
159
|
-
* appended ledger, or the unchanged ledger when the title is blank.
|
|
160
|
-
* @param tasks - current ledger.
|
|
161
|
-
* @param input - raw user input (title/description/prompt).
|
|
162
|
-
* @param now - clock instant (ms epoch).
|
|
163
|
-
* @param id - minted task id.
|
|
173
|
+
* Archive one task: only settled statuses (done/failed) can be archived;
|
|
174
|
+
* a running or not-yet-settled task stays on the board (its runner still
|
|
175
|
+
* owns its lifecycle). Already-archived tasks are a no-op.
|
|
164
176
|
*/
|
|
165
|
-
function
|
|
166
|
-
|
|
167
|
-
task: void 0,
|
|
168
|
-
tasks
|
|
169
|
-
};
|
|
170
|
-
const task = createTask(input, now, id);
|
|
177
|
+
function applyArchiveTask(tasks, id, now) {
|
|
178
|
+
let applied = false;
|
|
171
179
|
return {
|
|
172
|
-
task
|
|
173
|
-
|
|
180
|
+
tasks: tasks.map((task) => {
|
|
181
|
+
if (task.id !== id || task.archivedAt !== void 0) return task;
|
|
182
|
+
if (!ARCHIVABLE_STATUSES.includes(task.status)) return task;
|
|
183
|
+
applied = true;
|
|
184
|
+
return {
|
|
185
|
+
...task,
|
|
186
|
+
archivedAt: now,
|
|
187
|
+
updatedAt: now
|
|
188
|
+
};
|
|
189
|
+
}),
|
|
190
|
+
archived: applied
|
|
174
191
|
};
|
|
175
192
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
* Apply a delete across the ledger. The selection (a task id) is cleared when
|
|
180
|
-
* it matches the removed task, so the UI never lingers on a vanished detail.
|
|
181
|
-
* @param tasks - current ledger.
|
|
182
|
-
* @param selectedTaskId - the currently selected task id (may be undefined).
|
|
183
|
-
* @param id - the task to remove.
|
|
184
|
-
*/
|
|
185
|
-
function applyDeleteTask(tasks, selectedTaskId, id) {
|
|
193
|
+
/** Restore one task back onto the main board (clears the archive marker). */
|
|
194
|
+
function applyRestoreTask(tasks, id, now) {
|
|
195
|
+
let applied = false;
|
|
186
196
|
return {
|
|
187
|
-
tasks: tasks.
|
|
188
|
-
|
|
197
|
+
tasks: tasks.map((task) => {
|
|
198
|
+
if (task.id !== id || task.archivedAt === void 0) return task;
|
|
199
|
+
applied = true;
|
|
200
|
+
const { archivedAt: _archived, ...rest } = task;
|
|
201
|
+
return {
|
|
202
|
+
...rest,
|
|
203
|
+
updatedAt: now
|
|
204
|
+
};
|
|
205
|
+
}),
|
|
206
|
+
archived: applied
|
|
189
207
|
};
|
|
190
208
|
}
|
|
191
209
|
//#endregion
|
|
@@ -290,6 +308,56 @@ window.__ModuleLoader__.load({
|
|
|
290
308
|
return /^\d+$/.test(value);
|
|
291
309
|
}
|
|
292
310
|
//#endregion
|
|
311
|
+
//#region src/core/use-cases/task-create.ts
|
|
312
|
+
/**
|
|
313
|
+
* Create-task use case: mint a new task from user input, rejecting a blank
|
|
314
|
+
* title. Pure ledger transition (no persistence or notify — the controller
|
|
315
|
+
* orchestrates those), so it is unit-testable without any runtime face.
|
|
316
|
+
*/
|
|
317
|
+
/**
|
|
318
|
+
* Apply a create against the current ledger. Returns the new task and the
|
|
319
|
+
* appended ledger, or the unchanged ledger when the title is blank.
|
|
320
|
+
* @param tasks - current ledger.
|
|
321
|
+
* @param input - raw user input (title/description/prompt + optional schedule).
|
|
322
|
+
* @param now - clock instant (ms epoch).
|
|
323
|
+
* @param id - minted task id.
|
|
324
|
+
*/
|
|
325
|
+
function applyCreateTask(tasks, input, now, id) {
|
|
326
|
+
if (input.title.trim() === "") return {
|
|
327
|
+
task: void 0,
|
|
328
|
+
tasks
|
|
329
|
+
};
|
|
330
|
+
let task = createTask(input, now, id);
|
|
331
|
+
const requested = input.schedule;
|
|
332
|
+
if (requested?.enabled === true && requested.cron.trim() !== "" && isValidCron(requested.cron)) {
|
|
333
|
+
const cron = requested.cron.trim();
|
|
334
|
+
task = withSchedule(task, {
|
|
335
|
+
enabled: true,
|
|
336
|
+
cron,
|
|
337
|
+
nextRunAt: nextRunAtMs(cron, now)
|
|
338
|
+
}, now);
|
|
339
|
+
}
|
|
340
|
+
return {
|
|
341
|
+
task,
|
|
342
|
+
tasks: [...tasks, task]
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
//#endregion
|
|
346
|
+
//#region src/core/use-cases/task-delete.ts
|
|
347
|
+
/**
|
|
348
|
+
* Apply a delete across the ledger. The selection (a task id) is cleared when
|
|
349
|
+
* it matches the removed task, so the UI never lingers on a vanished detail.
|
|
350
|
+
* @param tasks - current ledger.
|
|
351
|
+
* @param selectedTaskId - the currently selected task id (may be undefined).
|
|
352
|
+
* @param id - the task to remove.
|
|
353
|
+
*/
|
|
354
|
+
function applyDeleteTask(tasks, selectedTaskId, id) {
|
|
355
|
+
return {
|
|
356
|
+
tasks: tasks.filter((task) => task.id !== id),
|
|
357
|
+
selectionCleared: selectedTaskId === id
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
//#endregion
|
|
293
361
|
//#region src/core/use-cases/task-schedule.ts
|
|
294
362
|
/**
|
|
295
363
|
* Schedule use case: arm/disarm a task's cron rule and roll a rule forward.
|
|
@@ -348,6 +416,25 @@ window.__ModuleLoader__.load({
|
|
|
348
416
|
//#endregion
|
|
349
417
|
//#region src/core/use-cases/task-update.ts
|
|
350
418
|
/**
|
|
419
|
+
* Update-task use case: apply an editable-field patch (title/description/
|
|
420
|
+
* prompt plus the execution targets workspaceId/mode/permission) with a
|
|
421
|
+
* fresh updatedAt. Pure ledger transition (no persistence or notify — the
|
|
422
|
+
* controller orchestrates those).
|
|
423
|
+
*
|
|
424
|
+
* An explicit `undefined` in the patch clears the field (the task falls
|
|
425
|
+
* back to the runtime default); an unknown permission string is ignored so
|
|
426
|
+
* stale UI can never persist a value the execution service rejects.
|
|
427
|
+
*/
|
|
428
|
+
/** Collapse a blank target string to undefined (clears the pin). */
|
|
429
|
+
function normalizeTargetId$1(value) {
|
|
430
|
+
return value !== void 0 && value.trim() === "" ? void 0 : value;
|
|
431
|
+
}
|
|
432
|
+
/** Keep an unknown permission string from entering the ledger. */
|
|
433
|
+
function normalizePermission(current, value) {
|
|
434
|
+
if (value === void 0) return void 0;
|
|
435
|
+
return isTaskPermission(value) ? value : current;
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
351
438
|
* Apply an update across the ledger. Tasks that do not match the id are left
|
|
352
439
|
* untouched; the matched task receives the patch plus a fresh updatedAt.
|
|
353
440
|
* @param tasks - current ledger.
|
|
@@ -356,11 +443,21 @@ window.__ModuleLoader__.load({
|
|
|
356
443
|
* @param now - clock instant (ms epoch).
|
|
357
444
|
*/
|
|
358
445
|
function applyUpdateTask(tasks, id, patch, now) {
|
|
359
|
-
return tasks.map((task) =>
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
446
|
+
return tasks.map((task) => {
|
|
447
|
+
if (task.id !== id) return task;
|
|
448
|
+
const workspaceId = "workspaceId" in patch ? normalizeTargetId$1(patch.workspaceId) : void 0;
|
|
449
|
+
const mode = "mode" in patch ? normalizeTargetId$1(patch.mode) : void 0;
|
|
450
|
+
const permission = "permission" in patch ? normalizePermission(task.permission, patch.permission) : void 0;
|
|
451
|
+
const next = {
|
|
452
|
+
...task,
|
|
453
|
+
...patch,
|
|
454
|
+
updatedAt: now
|
|
455
|
+
};
|
|
456
|
+
if (workspaceId !== void 0 || "workspaceId" in patch) next.workspaceId = workspaceId;
|
|
457
|
+
if (mode !== void 0 || "mode" in patch) next.mode = mode;
|
|
458
|
+
if (permission !== void 0 || "permission" in patch) next.permission = permission;
|
|
459
|
+
return next;
|
|
460
|
+
});
|
|
364
461
|
}
|
|
365
462
|
//#endregion
|
|
366
463
|
//#region src/core/controller.ts
|
|
@@ -389,7 +486,12 @@ window.__ModuleLoader__.load({
|
|
|
389
486
|
deps;
|
|
390
487
|
tasks = [];
|
|
391
488
|
boardOpen = false;
|
|
489
|
+
archiveView = false;
|
|
392
490
|
selectedTaskId;
|
|
491
|
+
executionOptions = {
|
|
492
|
+
workspaces: [],
|
|
493
|
+
presets: []
|
|
494
|
+
};
|
|
393
495
|
listeners = /* @__PURE__ */ new Set();
|
|
394
496
|
disposers = [];
|
|
395
497
|
now;
|
|
@@ -425,7 +527,9 @@ window.__ModuleLoader__.load({
|
|
|
425
527
|
return {
|
|
426
528
|
tasks: this.tasks,
|
|
427
529
|
boardOpen: this.boardOpen,
|
|
428
|
-
|
|
530
|
+
archiveView: this.archiveView,
|
|
531
|
+
selectedTaskId: this.selectedTaskId,
|
|
532
|
+
executionOptions: this.executionOptions
|
|
429
533
|
};
|
|
430
534
|
}
|
|
431
535
|
subscribe(fn) {
|
|
@@ -449,6 +553,18 @@ window.__ModuleLoader__.load({
|
|
|
449
553
|
if (this.boardOpen) this.closeBoard();
|
|
450
554
|
else this.openBoard();
|
|
451
555
|
}
|
|
556
|
+
/**
|
|
557
|
+
* Switch between the kanban columns and the archive view. Leaving the
|
|
558
|
+
* archive view with an archived task still selected closes the selection —
|
|
559
|
+
* the detail overlay must not linger over a task that is off-board.
|
|
560
|
+
*/
|
|
561
|
+
toggleArchiveView() {
|
|
562
|
+
this.archiveView = !this.archiveView;
|
|
563
|
+
if (!this.archiveView && this.selectedTaskId !== void 0) {
|
|
564
|
+
if (this.tasks.find((task) => task.id === this.selectedTaskId)?.archivedAt !== void 0) this.selectedTaskId = void 0;
|
|
565
|
+
}
|
|
566
|
+
this.notify();
|
|
567
|
+
}
|
|
452
568
|
openTask(id) {
|
|
453
569
|
if (this.tasks.some((task) => task.id === id)) {
|
|
454
570
|
this.selectedTaskId = id;
|
|
@@ -471,6 +587,17 @@ window.__ModuleLoader__.load({
|
|
|
471
587
|
this.tasks = [...applyUpdateTask(this.tasks, id, patch, this.now())];
|
|
472
588
|
this.persistAndNotify();
|
|
473
589
|
}
|
|
590
|
+
/**
|
|
591
|
+
* Replace (a part of) the picker option sets the UI feeds (workspace list
|
|
592
|
+
* and agent-preset roster come from the runtime, not the ledger).
|
|
593
|
+
*/
|
|
594
|
+
setExecutionOptions(patch) {
|
|
595
|
+
this.executionOptions = {
|
|
596
|
+
...this.executionOptions,
|
|
597
|
+
...patch
|
|
598
|
+
};
|
|
599
|
+
this.notify();
|
|
600
|
+
}
|
|
474
601
|
moveTask(id, status) {
|
|
475
602
|
this.tasks = this.tasks.map((task) => task.id === id ? withStatus(task, status, this.now()) : task);
|
|
476
603
|
this.persistAndNotify();
|
|
@@ -482,6 +609,27 @@ window.__ModuleLoader__.load({
|
|
|
482
609
|
this.persistAndNotify();
|
|
483
610
|
}
|
|
484
611
|
/**
|
|
612
|
+
* Archive a settled task (done/failed). Running or on-board-unsettled
|
|
613
|
+
* tasks are refused so the runner keeps exclusive ownership of their
|
|
614
|
+
* lifecycle.
|
|
615
|
+
* @returns true when applied.
|
|
616
|
+
*/
|
|
617
|
+
archiveTask(id) {
|
|
618
|
+
const { tasks, archived } = applyArchiveTask(this.tasks, id, this.now());
|
|
619
|
+
if (!archived) return false;
|
|
620
|
+
this.tasks = [...tasks];
|
|
621
|
+
this.persistAndNotify();
|
|
622
|
+
return true;
|
|
623
|
+
}
|
|
624
|
+
/** Restore an archived task back onto the board (same status column). */
|
|
625
|
+
restoreTask(id) {
|
|
626
|
+
const { tasks, archived } = applyRestoreTask(this.tasks, id, this.now());
|
|
627
|
+
if (!archived) return false;
|
|
628
|
+
this.tasks = [...tasks];
|
|
629
|
+
this.persistAndNotify();
|
|
630
|
+
return true;
|
|
631
|
+
}
|
|
632
|
+
/**
|
|
485
633
|
* Update a task's schedule rule. A blank or invalid cron expression is
|
|
486
634
|
* rejected (returns false, state untouched). When the rule ends up enabled
|
|
487
635
|
* the next run instant is computed immediately; a disabled rule carries no
|
|
@@ -508,6 +656,17 @@ window.__ModuleLoader__.load({
|
|
|
508
656
|
this.persistAndNotify();
|
|
509
657
|
}
|
|
510
658
|
/**
|
|
659
|
+
* Reload the ledger from the persisted store without notifying subscribers.
|
|
660
|
+
* The scheduler calls this before every tick so a task deleted in another
|
|
661
|
+
* tab (or a stale in-memory copy) can never be fired from this tab: the
|
|
662
|
+
* fire decision and the subsequent roll-forward both run on the freshest
|
|
663
|
+
* persisted truth. Deliberately silent — same-origin external changes still
|
|
664
|
+
* reach subscribers through the storage-event subscription.
|
|
665
|
+
*/
|
|
666
|
+
reloadFromStore() {
|
|
667
|
+
this.tasks = this.deps.store.load();
|
|
668
|
+
}
|
|
669
|
+
/**
|
|
511
670
|
* Jump to an execution's session transcript. Selecting the session changes
|
|
512
671
|
* `current`, which closes the board (the conversation view takes over).
|
|
513
672
|
* @param sessionId - the execution session to open.
|
|
@@ -637,6 +796,18 @@ window.__ModuleLoader__.load({
|
|
|
637
796
|
if (error instanceof Error) return error.message;
|
|
638
797
|
return String(error);
|
|
639
798
|
}
|
|
799
|
+
/**
|
|
800
|
+
* Whether a rejected preset switch actually means "the session already runs
|
|
801
|
+
* this preset" (the host's agent-preset-conflict with a matching
|
|
802
|
+
* existingPreset). A blank-session reuse race can produce this even though
|
|
803
|
+
* the requested composition is in place.
|
|
804
|
+
*/
|
|
805
|
+
function presetAlreadyRuns(error, mode) {
|
|
806
|
+
if (typeof error !== "object" || error === null) return false;
|
|
807
|
+
const details = error.details;
|
|
808
|
+
if (typeof details !== "object" || details === null) return false;
|
|
809
|
+
return details.existingPreset === mode;
|
|
810
|
+
}
|
|
640
811
|
/** Whether a `turn/end` payload closed the turn with an error reason. */
|
|
641
812
|
function isErrorTurnEnd(data) {
|
|
642
813
|
if (typeof data !== "object" || data === null) return false;
|
|
@@ -654,13 +825,31 @@ window.__ModuleLoader__.load({
|
|
|
654
825
|
*/
|
|
655
826
|
var ExecutionService = class {
|
|
656
827
|
env;
|
|
828
|
+
/**
|
|
829
|
+
* In-flight preset switches keyed by `sessionId\u0000mode`. The session
|
|
830
|
+
* list mirror can lag behind a just-applied switch, so concurrent runs
|
|
831
|
+
* against one blank session would otherwise each issue the same select
|
|
832
|
+
* RPC (an amplified storm); sharing one in-flight call keeps the wire to
|
|
833
|
+
* a single request. The settled entry is forgotten so a later run can
|
|
834
|
+
* switch again.
|
|
835
|
+
*/
|
|
836
|
+
presetSwitches = /* @__PURE__ */ new Map();
|
|
657
837
|
/** @param env - the runtime faces (real or fake). */
|
|
658
838
|
constructor(env) {
|
|
659
839
|
this.env = env;
|
|
660
840
|
}
|
|
661
841
|
async run(task, execution, onEvent) {
|
|
842
|
+
const settleFailed = (error) => {
|
|
843
|
+
onEvent({
|
|
844
|
+
kind: "settled",
|
|
845
|
+
taskId: task.id,
|
|
846
|
+
executionId: execution.id,
|
|
847
|
+
outcome: "failed",
|
|
848
|
+
error
|
|
849
|
+
});
|
|
850
|
+
};
|
|
662
851
|
try {
|
|
663
|
-
const sessionId = await this.connectSession();
|
|
852
|
+
const sessionId = await this.connectSession(task.workspaceId);
|
|
664
853
|
onEvent({
|
|
665
854
|
kind: "started",
|
|
666
855
|
taskId: task.id,
|
|
@@ -669,38 +858,100 @@ window.__ModuleLoader__.load({
|
|
|
669
858
|
});
|
|
670
859
|
const driver = this.driverOf(sessionId);
|
|
671
860
|
if (driver === void 0) {
|
|
672
|
-
|
|
673
|
-
kind: "settled",
|
|
674
|
-
taskId: task.id,
|
|
675
|
-
executionId: execution.id,
|
|
676
|
-
outcome: "failed",
|
|
677
|
-
error: "execution session is not ready"
|
|
678
|
-
});
|
|
861
|
+
settleFailed("execution session is not ready");
|
|
679
862
|
return;
|
|
680
863
|
}
|
|
864
|
+
if (!await this.applyMode(driver, task, sessionId, settleFailed)) return;
|
|
865
|
+
if (!await this.applyPermission(driver, task, settleFailed)) return;
|
|
681
866
|
await driver.rename(task.title).catch(() => {});
|
|
682
867
|
const baseline = driver.getSnapshot().turnEnds.size;
|
|
683
868
|
const accepted = await this.sendPrompt(driver, task);
|
|
684
869
|
if (!accepted.ok) {
|
|
685
|
-
|
|
686
|
-
kind: "settled",
|
|
687
|
-
taskId: task.id,
|
|
688
|
-
executionId: execution.id,
|
|
689
|
-
outcome: "failed",
|
|
690
|
-
error: messageOf(accepted.error)
|
|
691
|
-
});
|
|
870
|
+
settleFailed(messageOf(accepted.error));
|
|
692
871
|
return;
|
|
693
872
|
}
|
|
694
873
|
this.watchForSettlement(driver, task.id, execution.id, onEvent, baseline);
|
|
695
874
|
} catch (error) {
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
875
|
+
settleFailed(messageOf(error));
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
/**
|
|
879
|
+
* Recompose the execution session's agent from the task-pinned preset.
|
|
880
|
+
* No-op when the task pins none or the session already runs it; fails the
|
|
881
|
+
* run when the session is no longer blank, the preset face is missing, or
|
|
882
|
+
* the wire refuses.
|
|
883
|
+
*/
|
|
884
|
+
async applyMode(driver, task, sessionId, settleFailed) {
|
|
885
|
+
const mode = task.mode;
|
|
886
|
+
if (mode === void 0 || mode === "") return true;
|
|
887
|
+
const summary = this.env.sessions.list.getSnapshot().byId[sessionId];
|
|
888
|
+
if (summary?.blank === false) {
|
|
889
|
+
settleFailed(`cannot switch agent preset to ${mode}: the execution session is not blank`);
|
|
890
|
+
return false;
|
|
891
|
+
}
|
|
892
|
+
if (summary?.agentPreset === mode) return true;
|
|
893
|
+
const presets = this.env.presets;
|
|
894
|
+
if (presets === void 0) {
|
|
895
|
+
settleFailed(`this deployment does not support agent presets (task asks for ${mode})`);
|
|
896
|
+
return false;
|
|
897
|
+
}
|
|
898
|
+
try {
|
|
899
|
+
const result = await this.switchPreset(presets, sessionId, mode);
|
|
900
|
+
if (!result.ok) {
|
|
901
|
+
if (presetAlreadyRuns(result.error, mode)) {
|
|
902
|
+
this.env.sessions.noteAgentPreset?.(sessionId, mode);
|
|
903
|
+
return true;
|
|
904
|
+
}
|
|
905
|
+
settleFailed(`agent preset switch to ${mode} rejected: ${messageOf(result.error)}`);
|
|
906
|
+
return false;
|
|
907
|
+
}
|
|
908
|
+
} catch (error) {
|
|
909
|
+
settleFailed(`agent preset switch to ${mode} failed: ${messageOf(error)}`);
|
|
910
|
+
return false;
|
|
703
911
|
}
|
|
912
|
+
this.env.sessions.noteAgentPreset?.(sessionId, mode);
|
|
913
|
+
return true;
|
|
914
|
+
}
|
|
915
|
+
/**
|
|
916
|
+
* One in-flight `select` per (session, preset): concurrent runs against
|
|
917
|
+
* the same blank session share the same wire call instead of each issuing
|
|
918
|
+
* a duplicate RPC. The entry is removed once the call settles, so a later
|
|
919
|
+
* run (after a shared failure, say) issues a fresh switch.
|
|
920
|
+
*/
|
|
921
|
+
switchPreset(presets, sessionId, mode) {
|
|
922
|
+
const key = `${sessionId}\u0000${mode}`;
|
|
923
|
+
const inflight = this.presetSwitches.get(key);
|
|
924
|
+
if (inflight !== void 0) return inflight;
|
|
925
|
+
const attempt = presets.select(sessionId, mode).finally(() => {
|
|
926
|
+
if (this.presetSwitches.get(key) === attempt) this.presetSwitches.delete(key);
|
|
927
|
+
});
|
|
928
|
+
this.presetSwitches.set(key, attempt);
|
|
929
|
+
return attempt;
|
|
930
|
+
}
|
|
931
|
+
/**
|
|
932
|
+
* Apply the task-pinned permission preset through the `/permission <id>`
|
|
933
|
+
* slash command. No-op when the task pins none; fails the run when the
|
|
934
|
+
* admission is rejected or no command claimed the line.
|
|
935
|
+
*/
|
|
936
|
+
async applyPermission(driver, task, settleFailed) {
|
|
937
|
+
const permission = task.permission;
|
|
938
|
+
if (permission === void 0) return true;
|
|
939
|
+
const line = `/permission ${permission}`;
|
|
940
|
+
try {
|
|
941
|
+
const result = await driver.command(line);
|
|
942
|
+
if (!result.ok) {
|
|
943
|
+
settleFailed(`permission command rejected: ${messageOf(result.error)}`);
|
|
944
|
+
return false;
|
|
945
|
+
}
|
|
946
|
+
if (!result.matched) {
|
|
947
|
+
settleFailed(`permission command not recognized: ${line}`);
|
|
948
|
+
return false;
|
|
949
|
+
}
|
|
950
|
+
} catch (error) {
|
|
951
|
+
settleFailed(`permission command failed: ${messageOf(error)}`);
|
|
952
|
+
return false;
|
|
953
|
+
}
|
|
954
|
+
return true;
|
|
704
955
|
}
|
|
705
956
|
/**
|
|
706
957
|
* Inspect a reloaded/background task that was left 'running' and emit a
|
|
@@ -773,8 +1024,12 @@ window.__ModuleLoader__.load({
|
|
|
773
1024
|
return false;
|
|
774
1025
|
}
|
|
775
1026
|
}
|
|
776
|
-
async connectSession() {
|
|
1027
|
+
async connectSession(taskWorkspaceId) {
|
|
777
1028
|
const workspace = this.env.workspaces.list.getSnapshot();
|
|
1029
|
+
if (taskWorkspaceId !== void 0 && taskWorkspaceId !== "") {
|
|
1030
|
+
if (!workspace.items.some((item) => item.workspaceId === taskWorkspaceId)) throw new Error(`task workspace is not available: ${taskWorkspaceId}`);
|
|
1031
|
+
return this.env.workspaces.connectWorkspace(taskWorkspaceId);
|
|
1032
|
+
}
|
|
778
1033
|
const workspaceId = workspace.recentWorkspaceId ?? workspace.items[0]?.workspaceId;
|
|
779
1034
|
if (workspaceId === void 0) throw new Error("no workspace available to run the task in");
|
|
780
1035
|
return this.env.workspaces.connectWorkspace(workspaceId);
|
|
@@ -836,6 +1091,11 @@ window.__ModuleLoader__.load({
|
|
|
836
1091
|
* a task still running at its due instant is skipped by the controller's
|
|
837
1092
|
* runTask guard and simply waits for the next cron match.
|
|
838
1093
|
*
|
|
1094
|
+
* A deleted task can never fire again from a stale in-memory copy: every
|
|
1095
|
+
* tick first re-reads the persisted ledger through the optional `refresh`
|
|
1096
|
+
* hook (the controller reloads its store), so the fire decision and the
|
|
1097
|
+
* subsequent roll-forward both run on the freshest persisted truth.
|
|
1098
|
+
*
|
|
839
1099
|
* The ticker is controlled: `start` arms a single interval guarded by an
|
|
840
1100
|
* idempotence check (a second start while running is a no-op, so wiring can
|
|
841
1101
|
* never leak a duplicate timer), and `stop`/`dispose` clear the timer and
|
|
@@ -910,6 +1170,7 @@ window.__ModuleLoader__.load({
|
|
|
910
1170
|
async tick() {
|
|
911
1171
|
if (this.disposed) return;
|
|
912
1172
|
if (this.deps.ready !== void 0 && !this.deps.ready()) return;
|
|
1173
|
+
this.deps.refresh?.();
|
|
913
1174
|
const now = this.deps.now();
|
|
914
1175
|
for (const task of this.deps.tasks()) {
|
|
915
1176
|
const schedule = task.schedule;
|
|
@@ -960,6 +1221,9 @@ window.__ModuleLoader__.load({
|
|
|
960
1221
|
if (typeof record.prompt !== "string") return false;
|
|
961
1222
|
if (typeof record.createdAt !== "number") return false;
|
|
962
1223
|
if (typeof record.updatedAt !== "number") return false;
|
|
1224
|
+
if (record.workspaceId !== void 0 && typeof record.workspaceId !== "string") return false;
|
|
1225
|
+
if (record.mode !== void 0 && typeof record.mode !== "string") return false;
|
|
1226
|
+
if (record.permission !== void 0 && typeof record.permission !== "string") return false;
|
|
963
1227
|
if (!Array.isArray(record.executions)) return false;
|
|
964
1228
|
for (const execution of record.executions) {
|
|
965
1229
|
if (typeof execution !== "object" || execution === null) return false;
|
|
@@ -973,6 +1237,10 @@ window.__ModuleLoader__.load({
|
|
|
973
1237
|
}
|
|
974
1238
|
return true;
|
|
975
1239
|
}
|
|
1240
|
+
/** Collapse a blank persisted target string to undefined (clears the pin). */
|
|
1241
|
+
function normalizeTargetId(value) {
|
|
1242
|
+
return value !== void 0 && value.trim() === "" ? void 0 : value;
|
|
1243
|
+
}
|
|
976
1244
|
/** Normalize an unknown persisted status back into the closed status union. */
|
|
977
1245
|
function normalizeStatus(status) {
|
|
978
1246
|
return isTaskStatus(status) ? status : "todo";
|
|
@@ -1019,6 +1287,10 @@ window.__ModuleLoader__.load({
|
|
|
1019
1287
|
status: normalizeStatus(row.status)
|
|
1020
1288
|
};
|
|
1021
1289
|
task.schedule = normalizeSchedule(row.schedule);
|
|
1290
|
+
task.workspaceId = normalizeTargetId(row.workspaceId);
|
|
1291
|
+
task.mode = normalizeTargetId(row.mode);
|
|
1292
|
+
task.archivedAt = typeof row.archivedAt === "number" && Number.isFinite(row.archivedAt) ? row.archivedAt : void 0;
|
|
1293
|
+
task.permission = isTaskPermission(row.permission) ? row.permission : void 0;
|
|
1022
1294
|
tasks.push(task);
|
|
1023
1295
|
}
|
|
1024
1296
|
return tasks;
|
|
@@ -1117,6 +1389,10 @@ window.__ModuleLoader__.load({
|
|
|
1117
1389
|
"board.search": "筛选任务…",
|
|
1118
1390
|
"board.empty": "这个状态还没有任务",
|
|
1119
1391
|
"board.filterAll": "全部",
|
|
1392
|
+
"board.archive": "归档",
|
|
1393
|
+
"board.archiveView": "归档 ({count})",
|
|
1394
|
+
"board.backToBoard": "返回看板",
|
|
1395
|
+
"archive.empty": "没有已归档的任务",
|
|
1120
1396
|
"board.status": "状态",
|
|
1121
1397
|
"board.status.backlog": "待规划",
|
|
1122
1398
|
"board.status.todo": "待办",
|
|
@@ -1144,6 +1420,9 @@ window.__ModuleLoader__.load({
|
|
|
1144
1420
|
"detail.run": "执行",
|
|
1145
1421
|
"detail.rerun": "重新执行",
|
|
1146
1422
|
"detail.delete": "删除",
|
|
1423
|
+
"detail.archive": "归档",
|
|
1424
|
+
"detail.restore": "恢复",
|
|
1425
|
+
"detail.archivedAt": "已归档 · {time}",
|
|
1147
1426
|
"detail.viewSession": "查看会话",
|
|
1148
1427
|
"detail.noSession": "暂无会话",
|
|
1149
1428
|
"detail.executionStarted": "已启动",
|
|
@@ -1176,6 +1455,20 @@ window.__ModuleLoader__.load({
|
|
|
1176
1455
|
"detail.schedule.notScheduled": "尚未排程",
|
|
1177
1456
|
"detail.schedule.dueSoon": "即将运行",
|
|
1178
1457
|
"card.scheduled": "定时",
|
|
1458
|
+
"new.workspace": "工作区",
|
|
1459
|
+
"new.mode": "模式",
|
|
1460
|
+
"new.permission": "权限",
|
|
1461
|
+
"exec.workspace.recent": "最近使用(默认)",
|
|
1462
|
+
"exec.mode.default": "部署默认",
|
|
1463
|
+
"exec.mode.defaultSuffix": "(默认)",
|
|
1464
|
+
"exec.mode.brokenSuffix": "(不可用)",
|
|
1465
|
+
"exec.mode.removed": "(已移除)",
|
|
1466
|
+
"exec.permission.default": "会话默认",
|
|
1467
|
+
"exec.permission.read-only": "只读",
|
|
1468
|
+
"exec.permission.workspace-write": "工作区可写",
|
|
1469
|
+
"exec.permission.danger-full-access": "完全访问",
|
|
1470
|
+
"detail.executionSettings": "执行设置",
|
|
1471
|
+
"exec.hint": "执行时生效:工作区决定执行会话落在哪个工作区;模式决定会话的 agent 预设;权限经 /permission 命令应用到会话。留空则使用运行时默认。",
|
|
1179
1472
|
"settings.title": "任务看板",
|
|
1180
1473
|
"settings.description": "控制看板在 agent 系统提示中的播报行为。",
|
|
1181
1474
|
"settings.enabled": "启用任务看板",
|
|
@@ -1207,6 +1500,10 @@ window.__ModuleLoader__.load({
|
|
|
1207
1500
|
"board.search": "Filter tasks…",
|
|
1208
1501
|
"board.empty": "No tasks in this column",
|
|
1209
1502
|
"board.filterAll": "All",
|
|
1503
|
+
"board.archive": "Archive",
|
|
1504
|
+
"board.archiveView": "Archived ({count})",
|
|
1505
|
+
"board.backToBoard": "Back to board",
|
|
1506
|
+
"archive.empty": "No archived tasks",
|
|
1210
1507
|
"board.status": "Status",
|
|
1211
1508
|
"board.status.backlog": "Backlog",
|
|
1212
1509
|
"board.status.todo": "To Do",
|
|
@@ -1234,6 +1531,9 @@ window.__ModuleLoader__.load({
|
|
|
1234
1531
|
"detail.run": "Run",
|
|
1235
1532
|
"detail.rerun": "Run Again",
|
|
1236
1533
|
"detail.delete": "Delete",
|
|
1534
|
+
"detail.archive": "Archive",
|
|
1535
|
+
"detail.restore": "Restore",
|
|
1536
|
+
"detail.archivedAt": "Archived · {time}",
|
|
1237
1537
|
"detail.viewSession": "View Session",
|
|
1238
1538
|
"detail.noSession": "No session",
|
|
1239
1539
|
"detail.executionStarted": "Started",
|
|
@@ -1266,6 +1566,20 @@ window.__ModuleLoader__.load({
|
|
|
1266
1566
|
"detail.schedule.notScheduled": "Not scheduled yet",
|
|
1267
1567
|
"detail.schedule.dueSoon": "Due soon",
|
|
1268
1568
|
"card.scheduled": "scheduled",
|
|
1569
|
+
"new.workspace": "Workspace",
|
|
1570
|
+
"new.mode": "Mode",
|
|
1571
|
+
"new.permission": "Permission",
|
|
1572
|
+
"exec.workspace.recent": "Most recent (default)",
|
|
1573
|
+
"exec.mode.default": "Deployment default",
|
|
1574
|
+
"exec.mode.defaultSuffix": " (default)",
|
|
1575
|
+
"exec.mode.brokenSuffix": " (unavailable)",
|
|
1576
|
+
"exec.mode.removed": " (removed)",
|
|
1577
|
+
"exec.permission.default": "Session default",
|
|
1578
|
+
"exec.permission.read-only": "Read-only",
|
|
1579
|
+
"exec.permission.workspace-write": "Workspace Write",
|
|
1580
|
+
"exec.permission.danger-full-access": "Full Access",
|
|
1581
|
+
"detail.executionSettings": "Execution Settings",
|
|
1582
|
+
"exec.hint": "Applied when the task runs: the workspace decides where the execution session lands; the mode composes the session's agent preset; the permission is applied through the /permission command. Blank = runtime default.",
|
|
1269
1583
|
"settings.title": "Task Board",
|
|
1270
1584
|
"settings.description": "How the board announces itself in each agent system prompt.",
|
|
1271
1585
|
"settings.enabled": "Enable the task board",
|
|
@@ -1300,7 +1614,7 @@ window.__ModuleLoader__.load({
|
|
|
1300
1614
|
}
|
|
1301
1615
|
//#endregion
|
|
1302
1616
|
//#region \0dsh-css:packages/dsh-task-board/src/client/board.module.css.mjs
|
|
1303
|
-
const css$1 = "[data-pane=conversation],[class*=centerCol]{position:relative}[data-dsh-taskboard-view]{z-index:60;background:var(--dsw-alias-bg-base);display:none;position:absolute;inset:0}html[data-dsh-taskboard-active]:not([data-dsh-ssh-active]) [data-dsh-taskboard-view]{display:block}html[data-dsh-taskboard-active]:not([data-dsh-ssh-active]) [data-pane=conversation]>:not([data-dsh-taskboard-view]),html[data-dsh-taskboard-active]:not([data-dsh-ssh-active]) [class*=centerCol]>:not([data-dsh-taskboard-view]){display:none!important}._7D6uKa_entry{width:100%;height:32px;color:var(--dsw-alias-label-secondary);cursor:pointer;white-space:nowrap;background:0 0;border:none;border-radius:8px;align-items:center;gap:8px;padding:0 12px;font-size:13px;display:flex}._7D6uKa_entry:hover{background:var(--dsw-specific-sidebar-nav-item-hover);color:var(--dsw-alias-label-primary)}._7D6uKa_entry[data-active]{background:var(--dsw-specific-sidebar-nav-item-active);color:var(--dsw-alias-label-primary);font-weight:600}._7D6uKa_entryIcon{flex:none;justify-content:center;align-items:center;display:inline-flex}._7D6uKa_entryLabel{text-overflow:ellipsis;overflow:hidden}[data-dsh-frame][data-sidebar-collapsed] ._7D6uKa_entry{justify-content:center;width:100%;padding:0}[data-dsh-frame][data-sidebar-collapsed] ._7D6uKa_entryLabel{display:none}._7D6uKa_board{background:var(--dsw-alias-bg-base);min-width:0;height:100%;min-height:0;color:var(--dsw-alias-label-primary);font-family:var(--dsw-font-family);flex-direction:column;gap:12px;padding:14px 16px 16px;display:flex}._7D6uKa_boardHeader{flex:none;align-items:center;gap:10px;display:flex}._7D6uKa_boardTitle{color:var(--dsw-alias-label-primary);white-space:nowrap;margin:0;font-size:16px;font-weight:700}._7D6uKa_search{min-width:120px;color:var(--dsw-alias-label-primary);background:var(--dsw-specific-input-major);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;outline:none;flex:0 260px;padding:6px 10px;font-size:13px}._7D6uKa_search::placeholder{color:var(--dsw-alias-label-tertiary)}._7D6uKa_columns{flex:1;grid-template-columns:repeat(5,minmax(0,1fr));gap:12px;min-height:0;display:grid}._7D6uKa_column{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:12px;flex-direction:column;min-height:0;display:flex;overflow:hidden}._7D6uKa_columnHeader{flex:none;align-items:center;gap:6px;padding:10px 12px;display:flex}._7D6uKa_columnTitle{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;flex:1;margin:0;font-size:13px;font-weight:700;overflow:hidden}._7D6uKa_columnCount{min-width:0;color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-interactive-bg-hover);border-radius:999px;flex:none;padding:1px 8px;font-size:12px}._7D6uKa_statusDot{border-radius:50%;flex:none;width:8px;height:8px}._7D6uKa_statusDot[data-status=backlog]{background:var(--dsw-alias-label-tertiary)}._7D6uKa_statusDot[data-status=todo]{background:var(--dsw-alias-state-business-primary)}._7D6uKa_statusDot[data-status=running]{background:var(--dsw-alias-state-warn-primary)}._7D6uKa_statusDot[data-status=done]{background:var(--dsw-alias-state-success-primary)}._7D6uKa_statusDot[data-status=failed]{background:var(--dsw-alias-state-error-primary)}._7D6uKa_cards{flex-direction:column;flex:1;gap:8px;min-height:0;padding:2px 8px 10px;display:flex;overflow-y:auto}._7D6uKa_columnEmpty{text-align:center;color:var(--dsw-alias-label-tertiary);padding:24px 8px;font-size:12px}._7D6uKa_card{text-align:left;background:var(--dsw-alias-bg-base);border:1px solid var(--dsw-alias-border-l2);cursor:pointer;color:var(--dsw-alias-label-primary);border-radius:10px;flex-direction:column;gap:6px;padding:10px 12px;font-family:inherit;transition:box-shadow .12s,border-color .12s,transform .12s;display:flex}._7D6uKa_card:hover{box-shadow:var(--dsw-shadow-lv2);border-color:var(--dsw-alias-border-l3);transform:translateY(-1px)}._7D6uKa_card[data-status=running]{border-color:var(--dsw-alias-state-warn-primary)}._7D6uKa_cardTitle{-webkit-line-clamp:2;-webkit-box-orient:vertical;font-size:13px;font-weight:600;line-height:1.35;display:-webkit-box;overflow:hidden}._7D6uKa_cardExcerpt{color:var(--dsw-alias-label-secondary);-webkit-line-clamp:2;-webkit-box-orient:vertical;font-size:12px;line-height:1.4;display:-webkit-box;overflow:hidden}._7D6uKa_cardMeta{color:var(--dsw-alias-label-tertiary);align-items:center;gap:8px;font-size:11px;display:flex}._7D6uKa_cardTime{text-overflow:ellipsis;white-space:nowrap;flex:1;overflow:hidden}._7D6uKa_cardSchedule{white-space:nowrap;min-width:0;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-interactive-bg-hover);border-radius:999px;flex:none;padding:2px 6px;font-size:12px;line-height:1}._7D6uKa_cardRun{flex:none}._7D6uKa_cardRun[data-result=failed]{color:var(--dsw-alias-state-error-primary)}._7D6uKa_cardRun[data-result=succeeded]{color:var(--dsw-alias-state-success-primary)}._7D6uKa_cardSession{color:var(--dsw-alias-state-business-primary);flex:none}._7D6uKa_cardRunningLabel{color:var(--dsw-alias-state-warn-primary);font-size:11px}._7D6uKa_cardSpinner{border:2px solid var(--dsw-alias-state-warn-primary);border-top-color:#0000;border-radius:50%;flex:none;width:10px;height:10px;animation:.8s linear infinite _7D6uKa_dshTbSpin}@keyframes _7D6uKa_dshTbSpin{to{transform:rotate(360deg)}}._7D6uKa_primaryButton{color:var(--dsw-alias-label-primary-foreground);background:var(--dsw-alias-button-info-fill);cursor:pointer;white-space:nowrap;border:none;border-radius:8px;padding:6px 14px;font-size:13px;font-weight:600}._7D6uKa_primaryButton:hover:not(:disabled){background:var(--dsw-alias-button-info-hover)}._7D6uKa_primaryButton:disabled{opacity:.5;cursor:default}._7D6uKa_ghostButton{color:var(--dsw-alias-label-primary);border:1px solid var(--dsw-alias-border-l2);cursor:pointer;white-space:nowrap;background:0 0;border-radius:8px;padding:5px 12px;font-size:12px}._7D6uKa_ghostButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}._7D6uKa_ghostButton:disabled{opacity:.45;cursor:default}._7D6uKa_dangerButton{color:#fff;background:var(--dsw-alias-state-error-primary);cursor:pointer;white-space:nowrap;border:none;border-radius:8px;padding:6px 14px;font-size:13px;font-weight:600}._7D6uKa_dangerButton:hover:not(:disabled){filter:brightness(1.08)}._7D6uKa_dangerButton:active:not(:disabled){filter:brightness(.94)}._7D6uKa_dangerButton:disabled{opacity:.5;cursor:default}._7D6uKa_iconButton{width:26px;height:26px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;padding:0;font-size:13px;display:inline-flex}._7D6uKa_iconButton:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}._7D6uKa_linkButton{color:var(--dsw-alias-state-business-primary);cursor:pointer;white-space:nowrap;background:0 0;border:none;padding:0;font-size:12px}._7D6uKa_linkButton:hover{text-decoration:underline}._7D6uKa_modalBackdrop{z-index:1300;background:var(--dsw-alias-bg-mask-1);justify-content:center;align-items:center;display:flex;position:fixed;inset:0}._7D6uKa_modal{background:var(--dsw-alias-bg-base);border:1px solid var(--dsw-alias-border-l2);width:min(520px,100vw - 48px);max-height:calc(100vh - 96px);box-shadow:var(--dsw-shadow-lv3);color:var(--dsw-alias-label-primary);border-radius:14px;flex-direction:column;gap:12px;padding:18px;display:flex;overflow-y:auto}._7D6uKa_modalTitle{margin:0;font-size:15px;font-weight:700}._7D6uKa_confirmMessage{color:var(--dsw-alias-label-secondary);white-space:pre-wrap;overflow-wrap:anywhere;margin:0;font-size:13px;line-height:1.5}._7D6uKa_modalFooter{justify-content:flex-end;gap:10px;margin-top:4px;display:flex}._7D6uKa_field{flex-direction:column;gap:5px;display:flex}._7D6uKa_fieldLabel{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:600}._7D6uKa_input{color:var(--dsw-alias-label-primary);background:var(--dsw-specific-input-major);border:1px solid var(--dsw-alias-border-l2);resize:vertical;border-radius:8px;outline:none;padding:7px 10px;font-family:inherit;font-size:13px}._7D6uKa_input:focus{border-color:var(--dsw-alias-state-business-primary)}._7D6uKa_input::placeholder{color:var(--dsw-alias-label-tertiary)}._7D6uKa_formError{color:var(--dsw-alias-state-error-primary);margin:0;font-size:12px}._7D6uKa_detail{background:var(--dsw-alias-bg-base);border:1px solid var(--dsw-alias-border-l2);width:min(640px,100vw - 48px);max-height:calc(100vh - 80px);box-shadow:var(--dsw-shadow-lv3);color:var(--dsw-alias-label-primary);border-radius:14px;flex-direction:column;display:flex;overflow:hidden}._7D6uKa_detailHeader{border-bottom:1px solid var(--dsw-alias-separator-primary);flex:none;align-items:center;gap:10px;padding:14px 18px;display:flex}._7D6uKa_detailTitle{overflow-wrap:anywhere;flex:1;margin:0;font-size:15px;font-weight:700}._7D6uKa_statusBadge{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:2px 10px;font-size:12px}._7D6uKa_statusBadge[data-status=running]{color:var(--dsw-alias-state-warn-primary);border-color:var(--dsw-alias-state-warn-primary)}._7D6uKa_statusBadge[data-status=done]{color:var(--dsw-alias-state-success-primary);border-color:var(--dsw-alias-state-success-primary)}._7D6uKa_statusBadge[data-status=failed]{color:var(--dsw-alias-state-error-primary);border-color:var(--dsw-alias-state-error-primary)}._7D6uKa_detailBody{flex-direction:column;flex:1;gap:16px;padding:14px 18px;display:flex;overflow-y:auto}._7D6uKa_detailSection{flex-direction:column;gap:6px;display:flex}._7D6uKa_detailSection h4{color:var(--dsw-alias-label-tertiary);text-transform:none;margin:0;font-size:12px;font-weight:700}._7D6uKa_detailText{color:var(--dsw-alias-label-primary);white-space:pre-wrap;overflow-wrap:anywhere;margin:0;font-size:13px;line-height:1.55}._7D6uKa_scheduleToggle{color:var(--dsw-alias-label-primary);cursor:pointer;user-select:none;align-items:center;gap:8px;font-size:13px;display:flex}._7D6uKa_scheduleToggle input{accent-color:var(--dsw-alias-state-business-primary)}._7D6uKa_scheduleRow{align-items:center;gap:8px;display:flex}._7D6uKa_scheduleInput{min-width:0;font-family:var(--dsw-font-markdown-code-block-small);flex:1;font-size:12.5px}._7D6uKa_scheduleInputInvalid,._7D6uKa_scheduleInputInvalid:focus{border-color:var(--dsw-alias-state-error-primary)}._7D6uKa_schedulePreset{color:var(--dsw-alias-label-primary);background:var(--dsw-specific-input-major);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;outline:none;flex:none;padding:7px 8px;font-size:12.5px}._7D6uKa_scheduleMeta{color:var(--dsw-alias-label-secondary);overflow-wrap:anywhere;margin:0;font-size:12px}._7D6uKa_promptBlock{font-size:12.5px;line-height:1.5;font-family:var(--dsw-font-markdown-code-block-small);color:var(--dsw-alias-label-primary);background:var(--dsw-alias-markdown-code-block);border:1px solid var(--dsw-alias-border-l1);white-space:pre-wrap;overflow-wrap:anywhere;border-radius:8px;max-height:240px;margin:0;padding:10px 12px;overflow-y:auto}._7D6uKa_executionList{flex-direction:column;gap:8px;margin:0;padding:0;list-style:none;display:flex}._7D6uKa_executionRow{border:1px solid var(--dsw-alias-border-l1);border-radius:8px;flex-wrap:wrap;align-items:center;gap:10px;padding:8px 10px;display:flex}._7D6uKa_executionBadge{color:var(--dsw-alias-state-warn-primary);background:var(--dsw-alias-state-warn-secondary);border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:600}._7D6uKa_executionBadge[data-result=succeeded]{color:var(--dsw-alias-state-success-primary);background:0 0}._7D6uKa_executionBadge[data-result=failed]{color:var(--dsw-alias-state-error-primary);background:0 0}._7D6uKa_executionBadge[data-result=cancelled]{color:var(--dsw-alias-label-tertiary);background:0 0}._7D6uKa_executionTimes{color:var(--dsw-alias-label-secondary);font-size:12px}._7D6uKa_executionError{width:100%;color:var(--dsw-alias-state-error-primary);overflow-wrap:anywhere;font-size:12px}._7D6uKa_moveRow{flex-wrap:wrap;gap:8px;display:flex}._7D6uKa_detailFooter{border-top:1px solid var(--dsw-alias-separator-primary);flex:none;align-items:center;gap:10px;padding:12px 18px;display:flex}._7D6uKa_detailMeta{color:var(--dsw-alias-label-tertiary);margin-left:auto;font-size:11px}._7D6uKa_entry:focus-visible,._7D6uKa_card:focus-visible,._7D6uKa_primaryButton:focus-visible,._7D6uKa_ghostButton:focus-visible,._7D6uKa_dangerButton:focus-visible,._7D6uKa_iconButton:focus-visible,._7D6uKa_linkButton:focus-visible,._7D6uKa_search:focus-visible,._7D6uKa_input:focus-visible,._7D6uKa_schedulePreset:focus-visible,._7D6uKa_scheduleToggle input:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}._7D6uKa_entry,._7D6uKa_primaryButton,._7D6uKa_ghostButton,._7D6uKa_dangerButton,._7D6uKa_iconButton,._7D6uKa_linkButton,._7D6uKa_search,._7D6uKa_input,._7D6uKa_schedulePreset,._7D6uKa_scheduleToggle input{transition:background-color .12s,color .12s,border-color .12s,outline-color .12s,box-shadow .12s,transform .12s}._7D6uKa_card:active{box-shadow:var(--dsw-shadow-lv1);transform:translateY(0)}._7D6uKa_entry:active,._7D6uKa_primaryButton:active:not(:disabled),._7D6uKa_ghostButton:active:not(:disabled),._7D6uKa_dangerButton:active:not(:disabled),._7D6uKa_iconButton:active:not(:disabled),._7D6uKa_linkButton:active:not(:disabled){transform:translateY(1px)}._7D6uKa_entry[data-active]:hover{background:var(--dsw-specific-sidebar-nav-item-active)}._7D6uKa_iconButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}._7D6uKa_linkButton:hover:not(:disabled){text-decoration:underline}._7D6uKa_iconButton:disabled,._7D6uKa_linkButton:disabled{opacity:.45;cursor:default}._7D6uKa_search:focus,._7D6uKa_schedulePreset:focus{border-color:var(--dsw-alias-state-business-primary)}._7D6uKa_scheduleToggle input{margin:0}@media (prefers-reduced-motion:reduce){._7D6uKa_entry,._7D6uKa_card,._7D6uKa_primaryButton,._7D6uKa_ghostButton,._7D6uKa_dangerButton,._7D6uKa_iconButton,._7D6uKa_linkButton,._7D6uKa_search,._7D6uKa_input,._7D6uKa_schedulePreset,._7D6uKa_scheduleToggle input{transition:none}._7D6uKa_cardSpinner{animation:none}}";
|
|
1617
|
+
const css$1 = "[data-pane=conversation],[class*=centerCol]{position:relative}[data-dsh-taskboard-view]{z-index:60;background:var(--dsw-alias-bg-base);display:none;position:absolute;inset:0}html[data-dsh-taskboard-active]:not([data-dsh-ssh-active]) [data-dsh-taskboard-view]{display:block}html[data-dsh-taskboard-active]:not([data-dsh-ssh-active]) [data-pane=conversation]>:not([data-dsh-taskboard-view]),html[data-dsh-taskboard-active]:not([data-dsh-ssh-active]) [class*=centerCol]>:not([data-dsh-taskboard-view]){display:none!important}._7D6uKa_entry{width:100%;height:32px;color:var(--dsw-alias-label-secondary);cursor:pointer;white-space:nowrap;background:0 0;border:none;border-radius:8px;align-items:center;gap:8px;padding:0 12px;font-size:13px;display:flex}._7D6uKa_entry:hover{background:var(--dsw-specific-sidebar-nav-item-hover);color:var(--dsw-alias-label-primary)}._7D6uKa_entry[data-active]{background:var(--dsw-specific-sidebar-nav-item-active);color:var(--dsw-alias-label-primary);font-weight:600}._7D6uKa_entryIcon{flex:none;justify-content:center;align-items:center;display:inline-flex}._7D6uKa_entryLabel{text-overflow:ellipsis;overflow:hidden}[data-dsh-frame][data-sidebar-collapsed] ._7D6uKa_entry{justify-content:center;width:100%;padding:0}[data-dsh-frame][data-sidebar-collapsed] ._7D6uKa_entryLabel{display:none}._7D6uKa_board{background:var(--dsw-alias-bg-base);min-width:0;height:100%;min-height:0;color:var(--dsw-alias-label-primary);font-family:var(--dsw-font-family);flex-direction:column;gap:12px;padding:14px 16px 16px;display:flex}._7D6uKa_boardHeader{flex:none;align-items:center;gap:10px;display:flex}._7D6uKa_boardTitle{color:var(--dsw-alias-label-primary);white-space:nowrap;margin:0;font-size:16px;font-weight:700}._7D6uKa_search{min-width:120px;color:var(--dsw-alias-label-primary);background:var(--dsw-specific-input-major);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;outline:none;flex:0 260px;padding:6px 10px;font-size:13px}._7D6uKa_search::placeholder{color:var(--dsw-alias-label-tertiary)}._7D6uKa_columns{flex:1;grid-template-columns:repeat(5,minmax(0,1fr));gap:12px;min-height:0;display:grid}._7D6uKa_column{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:12px;flex-direction:column;min-height:0;display:flex;overflow:hidden}._7D6uKa_columnHeader{flex:none;align-items:center;gap:6px;padding:10px 12px;display:flex}._7D6uKa_columnTitle{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;flex:1;margin:0;font-size:13px;font-weight:700;overflow:hidden}._7D6uKa_columnCount{min-width:0;color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-interactive-bg-hover);border-radius:999px;flex:none;padding:1px 8px;font-size:12px}._7D6uKa_statusDot{border-radius:50%;flex:none;width:8px;height:8px}._7D6uKa_statusDot[data-status=backlog]{background:var(--dsw-alias-label-tertiary)}._7D6uKa_statusDot[data-status=todo]{background:var(--dsw-alias-state-business-primary)}._7D6uKa_statusDot[data-status=running]{background:var(--dsw-alias-state-warn-primary)}._7D6uKa_statusDot[data-status=done]{background:var(--dsw-alias-state-success-primary)}._7D6uKa_statusDot[data-status=failed]{background:var(--dsw-alias-state-error-primary)}._7D6uKa_cards{flex-direction:column;flex:1;gap:8px;min-height:0;padding:2px 8px 10px;display:flex;overflow-y:auto}._7D6uKa_columnEmpty{text-align:center;color:var(--dsw-alias-label-tertiary);padding:24px 8px;font-size:12px}._7D6uKa_card{text-align:left;background:var(--dsw-alias-bg-base);border:1px solid var(--dsw-alias-border-l2);cursor:pointer;color:var(--dsw-alias-label-primary);border-radius:10px;flex-direction:column;gap:6px;padding:10px 12px;font-family:inherit;transition:box-shadow .12s,border-color .12s,transform .12s;display:flex}._7D6uKa_card:hover{box-shadow:var(--dsw-shadow-lv2);border-color:var(--dsw-alias-border-l3);transform:translateY(-1px)}._7D6uKa_card[data-status=running]{border-color:var(--dsw-alias-state-warn-primary)}._7D6uKa_cardTitle{-webkit-line-clamp:2;-webkit-box-orient:vertical;font-size:13px;font-weight:600;line-height:1.35;display:-webkit-box;overflow:hidden}._7D6uKa_cardExcerpt{color:var(--dsw-alias-label-secondary);-webkit-line-clamp:2;-webkit-box-orient:vertical;font-size:12px;line-height:1.4;display:-webkit-box;overflow:hidden}._7D6uKa_cardMeta{color:var(--dsw-alias-label-tertiary);align-items:center;gap:8px;font-size:11px;display:flex}._7D6uKa_cardTime{text-overflow:ellipsis;white-space:nowrap;flex:1;overflow:hidden}._7D6uKa_cardSchedule{white-space:nowrap;min-width:0;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-interactive-bg-hover);border-radius:999px;flex:none;padding:2px 6px;font-size:12px;line-height:1}._7D6uKa_cardRun{flex:none}._7D6uKa_cardRun[data-result=failed]{color:var(--dsw-alias-state-error-primary)}._7D6uKa_cardRun[data-result=succeeded]{color:var(--dsw-alias-state-success-primary)}._7D6uKa_cardSession{color:var(--dsw-alias-state-business-primary);flex:none}._7D6uKa_cardRunningLabel{color:var(--dsw-alias-state-warn-primary);font-size:11px}._7D6uKa_cardSpinner{border:2px solid var(--dsw-alias-state-warn-primary);border-top-color:#0000;border-radius:50%;flex:none;width:10px;height:10px;animation:.8s linear infinite _7D6uKa_dshTbSpin}@keyframes _7D6uKa_dshTbSpin{to{transform:rotate(360deg)}}._7D6uKa_primaryButton{color:var(--dsw-alias-label-primary-foreground);background:var(--dsw-alias-button-info-fill);cursor:pointer;white-space:nowrap;border:none;border-radius:8px;padding:6px 14px;font-size:13px;font-weight:600}._7D6uKa_primaryButton:hover:not(:disabled){background:var(--dsw-alias-button-info-hover)}._7D6uKa_primaryButton:disabled{opacity:.5;cursor:default}._7D6uKa_ghostButton{color:var(--dsw-alias-label-primary);border:1px solid var(--dsw-alias-border-l2);cursor:pointer;white-space:nowrap;background:0 0;border-radius:8px;padding:5px 12px;font-size:12px}._7D6uKa_ghostButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}._7D6uKa_ghostButton:disabled{opacity:.45;cursor:default}._7D6uKa_dangerButton{color:#fff;background:var(--dsw-alias-state-error-primary);cursor:pointer;white-space:nowrap;border:none;border-radius:8px;padding:6px 14px;font-size:13px;font-weight:600}._7D6uKa_dangerButton:hover:not(:disabled){filter:brightness(1.08)}._7D6uKa_dangerButton:active:not(:disabled){filter:brightness(.94)}._7D6uKa_dangerButton:disabled{opacity:.5;cursor:default}._7D6uKa_iconButton{width:26px;height:26px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;padding:0;font-size:13px;display:inline-flex}._7D6uKa_iconButton:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}._7D6uKa_linkButton{color:var(--dsw-alias-state-business-primary);cursor:pointer;white-space:nowrap;background:0 0;border:none;padding:0;font-size:12px}._7D6uKa_linkButton:hover{text-decoration:underline}._7D6uKa_modalBackdrop{z-index:1300;background:var(--dsw-alias-bg-mask-1);justify-content:center;align-items:center;display:flex;position:fixed;inset:0}._7D6uKa_modal{background:var(--dsw-alias-bg-base);border:1px solid var(--dsw-alias-border-l2);width:min(520px,100vw - 48px);max-height:calc(100vh - 96px);box-shadow:var(--dsw-shadow-lv3);color:var(--dsw-alias-label-primary);border-radius:14px;flex-direction:column;gap:12px;padding:18px;display:flex;overflow-y:auto}._7D6uKa_modalTitle{margin:0;font-size:15px;font-weight:700}._7D6uKa_confirmMessage{color:var(--dsw-alias-label-secondary);white-space:pre-wrap;overflow-wrap:anywhere;margin:0;font-size:13px;line-height:1.5}._7D6uKa_modalFooter{justify-content:flex-end;gap:10px;margin-top:4px;display:flex}._7D6uKa_field{flex-direction:column;gap:5px;display:flex}._7D6uKa_fieldLabel{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:600}._7D6uKa_input{color:var(--dsw-alias-label-primary);background:var(--dsw-specific-input-major);border:1px solid var(--dsw-alias-border-l2);resize:vertical;border-radius:8px;outline:none;padding:7px 10px;font-family:inherit;font-size:13px}._7D6uKa_input:focus{border-color:var(--dsw-alias-state-business-primary)}._7D6uKa_select{color:var(--dsw-alias-label-primary);background:var(--dsw-specific-input-major);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;outline:none;max-width:100%;padding:7px 10px;font-family:inherit;font-size:13px}._7D6uKa_input::placeholder{color:var(--dsw-alias-label-tertiary)}._7D6uKa_formError{color:var(--dsw-alias-state-error-primary);margin:0;font-size:12px}._7D6uKa_detail{background:var(--dsw-alias-bg-base);border:1px solid var(--dsw-alias-border-l2);width:min(640px,100vw - 48px);max-height:calc(100vh - 80px);box-shadow:var(--dsw-shadow-lv3);color:var(--dsw-alias-label-primary);border-radius:14px;flex-direction:column;display:flex;overflow:hidden}._7D6uKa_detailHeader{border-bottom:1px solid var(--dsw-alias-separator-primary);flex:none;align-items:center;gap:10px;padding:14px 18px;display:flex}._7D6uKa_detailTitle{overflow-wrap:anywhere;flex:1;margin:0;font-size:15px;font-weight:700}._7D6uKa_statusBadge{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:2px 10px;font-size:12px}._7D6uKa_statusBadge[data-status=running]{color:var(--dsw-alias-state-warn-primary);border-color:var(--dsw-alias-state-warn-primary)}._7D6uKa_statusBadge[data-status=done]{color:var(--dsw-alias-state-success-primary);border-color:var(--dsw-alias-state-success-primary)}._7D6uKa_statusBadge[data-status=failed]{color:var(--dsw-alias-state-error-primary);border-color:var(--dsw-alias-state-error-primary)}._7D6uKa_detailBody{flex-direction:column;flex:1;gap:16px;padding:14px 18px;display:flex;overflow-y:auto}._7D6uKa_detailSection{flex-direction:column;gap:6px;display:flex}._7D6uKa_detailSection h4{color:var(--dsw-alias-label-tertiary);text-transform:none;margin:0;font-size:12px;font-weight:700}._7D6uKa_detailText{color:var(--dsw-alias-label-primary);white-space:pre-wrap;overflow-wrap:anywhere;margin:0;font-size:13px;line-height:1.55}._7D6uKa_scheduleToggle{color:var(--dsw-alias-label-primary);cursor:pointer;user-select:none;align-items:center;gap:8px;font-size:13px;display:flex}._7D6uKa_scheduleToggle input{accent-color:var(--dsw-alias-state-business-primary)}._7D6uKa_scheduleRow{align-items:center;gap:8px;display:flex}._7D6uKa_scheduleInput{min-width:0;font-family:var(--dsw-font-markdown-code-block-small);flex:1;font-size:12.5px}._7D6uKa_scheduleInputInvalid,._7D6uKa_scheduleInputInvalid:focus{border-color:var(--dsw-alias-state-error-primary)}._7D6uKa_schedulePreset{color:var(--dsw-alias-label-primary);background:var(--dsw-specific-input-major);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;outline:none;flex:none;padding:7px 8px;font-size:12.5px}._7D6uKa_scheduleMeta{color:var(--dsw-alias-label-secondary);overflow-wrap:anywhere;margin:0;font-size:12px}._7D6uKa_promptBlock{font-size:12.5px;line-height:1.5;font-family:var(--dsw-font-markdown-code-block-small);color:var(--dsw-alias-label-primary);background:var(--dsw-alias-markdown-code-block);border:1px solid var(--dsw-alias-border-l1);white-space:pre-wrap;overflow-wrap:anywhere;border-radius:8px;max-height:240px;margin:0;padding:10px 12px;overflow-y:auto}._7D6uKa_executionList{flex-direction:column;gap:8px;margin:0;padding:0;list-style:none;display:flex}._7D6uKa_executionRow{border:1px solid var(--dsw-alias-border-l1);border-radius:8px;flex-wrap:wrap;align-items:center;gap:10px;padding:8px 10px;display:flex}._7D6uKa_executionBadge{color:var(--dsw-alias-state-warn-primary);background:var(--dsw-alias-state-warn-secondary);border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:600}._7D6uKa_executionBadge[data-result=succeeded]{color:var(--dsw-alias-state-success-primary);background:0 0}._7D6uKa_executionBadge[data-result=failed]{color:var(--dsw-alias-state-error-primary);background:0 0}._7D6uKa_executionBadge[data-result=cancelled]{color:var(--dsw-alias-label-tertiary);background:0 0}._7D6uKa_executionTimes{color:var(--dsw-alias-label-secondary);font-size:12px}._7D6uKa_executionError{width:100%;color:var(--dsw-alias-state-error-primary);overflow-wrap:anywhere;font-size:12px}._7D6uKa_moveRow{flex-wrap:wrap;gap:8px;display:flex}._7D6uKa_detailFooter{border-top:1px solid var(--dsw-alias-separator-primary);flex:none;align-items:center;gap:10px;padding:12px 18px;display:flex}._7D6uKa_detailMeta{color:var(--dsw-alias-label-tertiary);margin-left:auto;font-size:11px}._7D6uKa_entry:focus-visible,._7D6uKa_card:focus-visible,._7D6uKa_primaryButton:focus-visible,._7D6uKa_ghostButton:focus-visible,._7D6uKa_dangerButton:focus-visible,._7D6uKa_iconButton:focus-visible,._7D6uKa_linkButton:focus-visible,._7D6uKa_search:focus-visible,._7D6uKa_input:focus-visible,._7D6uKa_select:focus-visible,._7D6uKa_schedulePreset:focus-visible,._7D6uKa_scheduleToggle input:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}._7D6uKa_entry,._7D6uKa_primaryButton,._7D6uKa_ghostButton,._7D6uKa_dangerButton,._7D6uKa_iconButton,._7D6uKa_linkButton,._7D6uKa_search,._7D6uKa_input,._7D6uKa_select,._7D6uKa_schedulePreset,._7D6uKa_scheduleToggle input{transition:background-color .12s,color .12s,border-color .12s,outline-color .12s,box-shadow .12s,transform .12s}._7D6uKa_card:active{box-shadow:var(--dsw-shadow-lv1);transform:translateY(0)}._7D6uKa_entry:active,._7D6uKa_primaryButton:active:not(:disabled),._7D6uKa_ghostButton:active:not(:disabled),._7D6uKa_dangerButton:active:not(:disabled),._7D6uKa_iconButton:active:not(:disabled),._7D6uKa_linkButton:active:not(:disabled){transform:translateY(1px)}._7D6uKa_entry[data-active]:hover{background:var(--dsw-specific-sidebar-nav-item-active)}._7D6uKa_iconButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}._7D6uKa_linkButton:hover:not(:disabled){text-decoration:underline}._7D6uKa_iconButton:disabled,._7D6uKa_linkButton:disabled{opacity:.45;cursor:default}._7D6uKa_search:focus,._7D6uKa_select:focus,._7D6uKa_schedulePreset:focus{border-color:var(--dsw-alias-state-business-primary)}._7D6uKa_scheduleToggle input{margin:0}@media (prefers-reduced-motion:reduce){._7D6uKa_entry,._7D6uKa_card,._7D6uKa_primaryButton,._7D6uKa_ghostButton,._7D6uKa_dangerButton,._7D6uKa_iconButton,._7D6uKa_linkButton,._7D6uKa_search,._7D6uKa_input,._7D6uKa_select,._7D6uKa_schedulePreset,._7D6uKa_scheduleToggle input{transition:none}._7D6uKa_cardSpinner{animation:none}}";
|
|
1304
1618
|
const tagId$1 = "@linxin666/dsh-client-ui-task-board/board.module.css";
|
|
1305
1619
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
1306
1620
|
const tag = document.createElement("style");
|
|
@@ -1370,10 +1684,32 @@ window.__ModuleLoader__.load({
|
|
|
1370
1684
|
"scheduleRow": "_7D6uKa_scheduleRow",
|
|
1371
1685
|
"scheduleToggle": "_7D6uKa_scheduleToggle",
|
|
1372
1686
|
"search": "_7D6uKa_search",
|
|
1687
|
+
"select": "_7D6uKa_select",
|
|
1373
1688
|
"statusBadge": "_7D6uKa_statusBadge",
|
|
1374
1689
|
"statusDot": "_7D6uKa_statusDot"
|
|
1375
1690
|
};
|
|
1376
1691
|
//#endregion
|
|
1692
|
+
//#region src/client/schedule-presets.ts
|
|
1693
|
+
/** Common scheduled-run presets (cron → locale label). */
|
|
1694
|
+
const SCHEDULE_PRESETS = [
|
|
1695
|
+
{
|
|
1696
|
+
cron: "0 9 * * *",
|
|
1697
|
+
label: "detail.schedule.preset.daily9"
|
|
1698
|
+
},
|
|
1699
|
+
{
|
|
1700
|
+
cron: "0 * * * *",
|
|
1701
|
+
label: "detail.schedule.preset.hourly"
|
|
1702
|
+
},
|
|
1703
|
+
{
|
|
1704
|
+
cron: "*/10 * * * *",
|
|
1705
|
+
label: "detail.schedule.preset.tenMin"
|
|
1706
|
+
},
|
|
1707
|
+
{
|
|
1708
|
+
cron: "0 9 * * 1",
|
|
1709
|
+
label: "detail.schedule.preset.weeklyMon9"
|
|
1710
|
+
}
|
|
1711
|
+
];
|
|
1712
|
+
//#endregion
|
|
1377
1713
|
//#region src/client/board/NewTaskModal.tsx
|
|
1378
1714
|
/**
|
|
1379
1715
|
* New-task modal: title + description + the prompt that execution will send.
|
|
@@ -1384,18 +1720,42 @@ window.__ModuleLoader__.load({
|
|
|
1384
1720
|
const [title, setTitle] = (0, react.useState)("");
|
|
1385
1721
|
const [description, setDescription] = (0, react.useState)("");
|
|
1386
1722
|
const [prompt, setPrompt] = (0, react.useState)("");
|
|
1723
|
+
const [workspaceId, setWorkspaceId] = (0, react.useState)("");
|
|
1724
|
+
const [mode, setMode] = (0, react.useState)("");
|
|
1725
|
+
const [permission, setPermission] = (0, react.useState)("");
|
|
1726
|
+
const [scheduleEnabled, setScheduleEnabled] = (0, react.useState)(false);
|
|
1727
|
+
const [scheduleCron, setScheduleCron] = (0, react.useState)("");
|
|
1728
|
+
const [scheduleError, setScheduleError] = (0, react.useState)(void 0);
|
|
1387
1729
|
const [error, setError] = (0, react.useState)(void 0);
|
|
1730
|
+
const [options, setOptions] = (0, react.useState)(controller.getSnapshot().executionOptions);
|
|
1731
|
+
(0, react.useEffect)(() => controller.subscribe(() => setOptions(controller.getSnapshot().executionOptions)), [controller]);
|
|
1388
1732
|
const submit = () => {
|
|
1733
|
+
if (scheduleEnabled) {
|
|
1734
|
+
const cron = scheduleCron.trim();
|
|
1735
|
+
if (cron === "" || !isValidCron(cron)) {
|
|
1736
|
+
setScheduleError(t("detail.schedule.invalid"));
|
|
1737
|
+
return;
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1389
1740
|
if (controller.createTask({
|
|
1390
1741
|
title,
|
|
1391
1742
|
description,
|
|
1392
|
-
prompt
|
|
1743
|
+
prompt,
|
|
1744
|
+
workspaceId: workspaceId === "" ? void 0 : workspaceId,
|
|
1745
|
+
mode: mode === "" ? void 0 : mode,
|
|
1746
|
+
permission: permission === "" ? void 0 : permission,
|
|
1747
|
+
schedule: scheduleEnabled ? {
|
|
1748
|
+
enabled: true,
|
|
1749
|
+
cron: scheduleCron.trim()
|
|
1750
|
+
} : void 0
|
|
1393
1751
|
}) === void 0) {
|
|
1394
1752
|
setError(t("new.required"));
|
|
1395
1753
|
return;
|
|
1396
1754
|
}
|
|
1397
1755
|
onClose();
|
|
1398
1756
|
};
|
|
1757
|
+
/** Next-run preview for a valid armed cron (creation-time only). */
|
|
1758
|
+
const scheduleNextRun = scheduleEnabled && scheduleCron.trim() !== "" && isValidCron(scheduleCron) ? nextRunAtMs(scheduleCron, Date.now()) : void 0;
|
|
1399
1759
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1400
1760
|
className: board_module_css_default.modalBackdrop,
|
|
1401
1761
|
onMouseDown: (event) => {
|
|
@@ -1460,6 +1820,132 @@ window.__ModuleLoader__.load({
|
|
|
1460
1820
|
}
|
|
1461
1821
|
})]
|
|
1462
1822
|
}),
|
|
1823
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
1824
|
+
className: board_module_css_default.field,
|
|
1825
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1826
|
+
className: board_module_css_default.fieldLabel,
|
|
1827
|
+
children: t("new.workspace")
|
|
1828
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
1829
|
+
className: board_module_css_default.select,
|
|
1830
|
+
value: workspaceId,
|
|
1831
|
+
onChange: (event) => {
|
|
1832
|
+
setWorkspaceId(event.target.value);
|
|
1833
|
+
},
|
|
1834
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1835
|
+
value: "",
|
|
1836
|
+
children: t("exec.workspace.recent")
|
|
1837
|
+
}), options.workspaces.map((workspace) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1838
|
+
value: workspace.workspaceId,
|
|
1839
|
+
children: workspace.title
|
|
1840
|
+
}, workspace.workspaceId))]
|
|
1841
|
+
})]
|
|
1842
|
+
}),
|
|
1843
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
1844
|
+
className: board_module_css_default.field,
|
|
1845
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1846
|
+
className: board_module_css_default.fieldLabel,
|
|
1847
|
+
children: t("new.mode")
|
|
1848
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
1849
|
+
className: board_module_css_default.select,
|
|
1850
|
+
value: mode,
|
|
1851
|
+
onChange: (event) => {
|
|
1852
|
+
setMode(event.target.value);
|
|
1853
|
+
},
|
|
1854
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1855
|
+
value: "",
|
|
1856
|
+
children: t("exec.mode.default")
|
|
1857
|
+
}), options.presets.map((preset) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("option", {
|
|
1858
|
+
value: preset.id,
|
|
1859
|
+
disabled: preset.broken !== void 0,
|
|
1860
|
+
children: [
|
|
1861
|
+
preset.name ?? preset.id,
|
|
1862
|
+
preset.isDefault ? t("exec.mode.defaultSuffix") : "",
|
|
1863
|
+
preset.broken !== void 0 ? t("exec.mode.brokenSuffix") : ""
|
|
1864
|
+
]
|
|
1865
|
+
}, preset.id))]
|
|
1866
|
+
})]
|
|
1867
|
+
}),
|
|
1868
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
1869
|
+
className: board_module_css_default.field,
|
|
1870
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1871
|
+
className: board_module_css_default.fieldLabel,
|
|
1872
|
+
children: t("new.permission")
|
|
1873
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
1874
|
+
className: board_module_css_default.select,
|
|
1875
|
+
value: permission,
|
|
1876
|
+
onChange: (event) => {
|
|
1877
|
+
setPermission(event.target.value);
|
|
1878
|
+
},
|
|
1879
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1880
|
+
value: "",
|
|
1881
|
+
children: t("exec.permission.default")
|
|
1882
|
+
}), TASK_PERMISSIONS.map((id) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1883
|
+
value: id,
|
|
1884
|
+
children: t(`exec.permission.${id}`)
|
|
1885
|
+
}, id))]
|
|
1886
|
+
})]
|
|
1887
|
+
}),
|
|
1888
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
1889
|
+
className: board_module_css_default.detailSection,
|
|
1890
|
+
children: [
|
|
1891
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h4", { children: t("detail.schedule") }),
|
|
1892
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
1893
|
+
className: board_module_css_default.scheduleToggle,
|
|
1894
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1895
|
+
type: "checkbox",
|
|
1896
|
+
checked: scheduleEnabled,
|
|
1897
|
+
onChange: (event) => {
|
|
1898
|
+
setScheduleEnabled(event.target.checked);
|
|
1899
|
+
if (!event.target.checked) setScheduleError(void 0);
|
|
1900
|
+
}
|
|
1901
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("detail.schedule.enable") })]
|
|
1902
|
+
}),
|
|
1903
|
+
scheduleEnabled && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
1904
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1905
|
+
className: board_module_css_default.scheduleRow,
|
|
1906
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1907
|
+
className: `${board_module_css_default.input} ${board_module_css_default.scheduleInput}${scheduleError !== void 0 ? ` ${board_module_css_default.scheduleInputInvalid}` : ""}`,
|
|
1908
|
+
value: scheduleCron,
|
|
1909
|
+
placeholder: "0 9 * * *",
|
|
1910
|
+
spellCheck: false,
|
|
1911
|
+
"aria-label": t("detail.schedule.cron"),
|
|
1912
|
+
onChange: (event) => {
|
|
1913
|
+
setScheduleCron(event.target.value);
|
|
1914
|
+
setScheduleError(void 0);
|
|
1915
|
+
}
|
|
1916
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
1917
|
+
className: board_module_css_default.schedulePreset,
|
|
1918
|
+
value: "",
|
|
1919
|
+
"aria-label": t("detail.schedule.presets"),
|
|
1920
|
+
onChange: (event) => {
|
|
1921
|
+
if (event.target.value === "") return;
|
|
1922
|
+
setScheduleCron(event.target.value);
|
|
1923
|
+
setScheduleError(void 0);
|
|
1924
|
+
},
|
|
1925
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("option", {
|
|
1926
|
+
value: "",
|
|
1927
|
+
children: [t("detail.schedule.presets"), "…"]
|
|
1928
|
+
}), SCHEDULE_PRESETS.map((preset) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1929
|
+
value: preset.cron,
|
|
1930
|
+
children: t(preset.label)
|
|
1931
|
+
}, preset.cron))]
|
|
1932
|
+
})]
|
|
1933
|
+
}),
|
|
1934
|
+
scheduleError !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1935
|
+
className: board_module_css_default.formError,
|
|
1936
|
+
children: scheduleError
|
|
1937
|
+
}),
|
|
1938
|
+
scheduleError === void 0 && scheduleNextRun !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
1939
|
+
className: board_module_css_default.scheduleMeta,
|
|
1940
|
+
children: [
|
|
1941
|
+
t("detail.schedule.nextRun"),
|
|
1942
|
+
" ",
|
|
1943
|
+
new Date(scheduleNextRun).toLocaleString()
|
|
1944
|
+
]
|
|
1945
|
+
})
|
|
1946
|
+
] })
|
|
1947
|
+
]
|
|
1948
|
+
}),
|
|
1463
1949
|
error !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1464
1950
|
className: board_module_css_default.formError,
|
|
1465
1951
|
children: error
|
|
@@ -1667,25 +2153,105 @@ window.__ModuleLoader__.load({
|
|
|
1667
2153
|
]
|
|
1668
2154
|
});
|
|
1669
2155
|
}
|
|
1670
|
-
/**
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
2156
|
+
/** The execution-target editor: workspace / mode / permission pickers. */
|
|
2157
|
+
function ExecutionSettingsSection({ controller, task }) {
|
|
2158
|
+
const [options, setOptions] = (0, react.useState)(controller.getSnapshot().executionOptions);
|
|
2159
|
+
(0, react.useEffect)(() => controller.subscribe(() => setOptions(controller.getSnapshot().executionOptions)), [controller]);
|
|
2160
|
+
const workspaceId = task.workspaceId ?? "";
|
|
2161
|
+
const mode = task.mode ?? "";
|
|
2162
|
+
const permission = task.permission ?? "";
|
|
2163
|
+
const workspaceKnown = workspaceId === "" || options.workspaces.some((item) => item.workspaceId === workspaceId);
|
|
2164
|
+
const modeKnown = mode === "" || options.presets.some((item) => item.id === mode);
|
|
2165
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
2166
|
+
className: board_module_css_default.detailSection,
|
|
2167
|
+
children: [
|
|
2168
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h4", { children: t("detail.executionSettings") }),
|
|
2169
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2170
|
+
className: board_module_css_default.detailText,
|
|
2171
|
+
children: t("exec.hint")
|
|
2172
|
+
}),
|
|
2173
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
2174
|
+
className: board_module_css_default.field,
|
|
2175
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2176
|
+
className: board_module_css_default.fieldLabel,
|
|
2177
|
+
children: t("new.workspace")
|
|
2178
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
2179
|
+
className: board_module_css_default.select,
|
|
2180
|
+
value: workspaceId,
|
|
2181
|
+
onChange: (event) => {
|
|
2182
|
+
controller.updateTask(task.id, { workspaceId: event.target.value });
|
|
2183
|
+
},
|
|
2184
|
+
children: [
|
|
2185
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
2186
|
+
value: "",
|
|
2187
|
+
children: t("exec.workspace.recent")
|
|
2188
|
+
}),
|
|
2189
|
+
!workspaceKnown && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("option", {
|
|
2190
|
+
value: workspaceId,
|
|
2191
|
+
children: [workspaceId, t("exec.mode.removed")]
|
|
2192
|
+
}),
|
|
2193
|
+
options.workspaces.map((workspace) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
2194
|
+
value: workspace.workspaceId,
|
|
2195
|
+
children: workspace.title
|
|
2196
|
+
}, workspace.workspaceId))
|
|
2197
|
+
]
|
|
2198
|
+
})]
|
|
2199
|
+
}),
|
|
2200
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
2201
|
+
className: board_module_css_default.field,
|
|
2202
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2203
|
+
className: board_module_css_default.fieldLabel,
|
|
2204
|
+
children: t("new.mode")
|
|
2205
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
2206
|
+
className: board_module_css_default.select,
|
|
2207
|
+
value: mode,
|
|
2208
|
+
onChange: (event) => {
|
|
2209
|
+
controller.updateTask(task.id, { mode: event.target.value });
|
|
2210
|
+
},
|
|
2211
|
+
children: [
|
|
2212
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
2213
|
+
value: "",
|
|
2214
|
+
children: t("exec.mode.default")
|
|
2215
|
+
}),
|
|
2216
|
+
!modeKnown && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("option", {
|
|
2217
|
+
value: mode,
|
|
2218
|
+
children: [mode, t("exec.mode.removed")]
|
|
2219
|
+
}),
|
|
2220
|
+
options.presets.map((preset) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("option", {
|
|
2221
|
+
value: preset.id,
|
|
2222
|
+
disabled: preset.broken !== void 0,
|
|
2223
|
+
children: [
|
|
2224
|
+
preset.name ?? preset.id,
|
|
2225
|
+
preset.isDefault ? t("exec.mode.defaultSuffix") : "",
|
|
2226
|
+
preset.broken !== void 0 ? t("exec.mode.brokenSuffix") : ""
|
|
2227
|
+
]
|
|
2228
|
+
}, preset.id))
|
|
2229
|
+
]
|
|
2230
|
+
})]
|
|
2231
|
+
}),
|
|
2232
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
2233
|
+
className: board_module_css_default.field,
|
|
2234
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2235
|
+
className: board_module_css_default.fieldLabel,
|
|
2236
|
+
children: t("new.permission")
|
|
2237
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
2238
|
+
className: board_module_css_default.select,
|
|
2239
|
+
value: permission,
|
|
2240
|
+
onChange: (event) => {
|
|
2241
|
+
controller.updateTask(task.id, { permission: event.target.value === "" ? void 0 : event.target.value });
|
|
2242
|
+
},
|
|
2243
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
2244
|
+
value: "",
|
|
2245
|
+
children: t("exec.permission.default")
|
|
2246
|
+
}), TASK_PERMISSIONS.map((id) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
2247
|
+
value: id,
|
|
2248
|
+
children: t(`exec.permission.${id}`)
|
|
2249
|
+
}, id))]
|
|
2250
|
+
})]
|
|
2251
|
+
})
|
|
2252
|
+
]
|
|
2253
|
+
});
|
|
2254
|
+
}
|
|
1689
2255
|
/** The scheduled-runs editor: enable toggle, cron input + presets, next-run info. */
|
|
1690
2256
|
function ScheduleSection({ controller, task }) {
|
|
1691
2257
|
const schedule = task.schedule;
|
|
@@ -1863,6 +2429,10 @@ window.__ModuleLoader__.load({
|
|
|
1863
2429
|
children: current.prompt !== "" ? current.prompt : current.title
|
|
1864
2430
|
})]
|
|
1865
2431
|
}),
|
|
2432
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ExecutionSettingsSection, {
|
|
2433
|
+
controller,
|
|
2434
|
+
task: current
|
|
2435
|
+
}),
|
|
1866
2436
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ScheduleSection, {
|
|
1867
2437
|
controller,
|
|
1868
2438
|
task: current
|
|
@@ -1912,6 +2482,23 @@ window.__ModuleLoader__.load({
|
|
|
1912
2482
|
},
|
|
1913
2483
|
children: current.executions.length === 0 ? t("detail.run") : t("detail.rerun")
|
|
1914
2484
|
}),
|
|
2485
|
+
current.archivedAt !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2486
|
+
type: "button",
|
|
2487
|
+
className: board_module_css_default.primaryButton,
|
|
2488
|
+
onClick: () => {
|
|
2489
|
+
controller.restoreTask(current.id);
|
|
2490
|
+
controller.closeTask();
|
|
2491
|
+
},
|
|
2492
|
+
children: t("detail.restore")
|
|
2493
|
+
}) : (current.status === "done" || current.status === "failed") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2494
|
+
type: "button",
|
|
2495
|
+
className: board_module_css_default.ghostButton,
|
|
2496
|
+
onClick: () => {
|
|
2497
|
+
controller.archiveTask(current.id);
|
|
2498
|
+
controller.closeTask();
|
|
2499
|
+
},
|
|
2500
|
+
children: t("detail.archive")
|
|
2501
|
+
}),
|
|
1915
2502
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1916
2503
|
type: "button",
|
|
1917
2504
|
className: board_module_css_default.dangerButton,
|
|
@@ -1925,7 +2512,8 @@ window.__ModuleLoader__.load({
|
|
|
1925
2512
|
children: [
|
|
1926
2513
|
t("board.created"),
|
|
1927
2514
|
" ",
|
|
1928
|
-
formatTime(current.createdAt)
|
|
2515
|
+
formatTime(current.createdAt),
|
|
2516
|
+
current.archivedAt !== void 0 && ` · ${t("detail.archivedAt", { time: formatTime(current.archivedAt) })}`
|
|
1929
2517
|
]
|
|
1930
2518
|
})
|
|
1931
2519
|
]
|
|
@@ -1989,7 +2577,8 @@ window.__ModuleLoader__.load({
|
|
|
1989
2577
|
const [filter, setFilter] = (0, react.useState)("");
|
|
1990
2578
|
const [showNew, setShowNew] = (0, react.useState)(false);
|
|
1991
2579
|
const selected = selectedTaskOf(snapshot);
|
|
1992
|
-
const
|
|
2580
|
+
const archiveView = snapshot.archiveView;
|
|
2581
|
+
const visible = snapshot.tasks.filter((task) => (archiveView ? task.archivedAt !== void 0 : task.archivedAt === void 0) && matchesFilter(task, filter));
|
|
1993
2582
|
const openTask = (0, react.useCallback)((id) => {
|
|
1994
2583
|
controller.openTask(id);
|
|
1995
2584
|
}, [controller]);
|
|
@@ -2014,6 +2603,14 @@ window.__ModuleLoader__.load({
|
|
|
2014
2603
|
},
|
|
2015
2604
|
"aria-label": t("board.search")
|
|
2016
2605
|
}),
|
|
2606
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2607
|
+
type: "button",
|
|
2608
|
+
className: archiveView ? board_module_css_default.primaryButton : board_module_css_default.ghostButton,
|
|
2609
|
+
onClick: () => {
|
|
2610
|
+
controller.toggleArchiveView();
|
|
2611
|
+
},
|
|
2612
|
+
children: archiveView ? t("board.backToBoard") : t("board.archiveView", { count: String(snapshot.tasks.filter((task) => task.archivedAt !== void 0).length) })
|
|
2613
|
+
}),
|
|
2017
2614
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
2018
2615
|
type: "button",
|
|
2019
2616
|
className: board_module_css_default.primaryButton,
|
|
@@ -2034,7 +2631,29 @@ window.__ModuleLoader__.load({
|
|
|
2034
2631
|
}),
|
|
2035
2632
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2036
2633
|
className: board_module_css_default.columns,
|
|
2037
|
-
children:
|
|
2634
|
+
children: archiveView ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
2635
|
+
className: board_module_css_default.column,
|
|
2636
|
+
"data-status": "archived",
|
|
2637
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
|
|
2638
|
+
className: board_module_css_default.columnHeader,
|
|
2639
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
2640
|
+
className: board_module_css_default.columnTitle,
|
|
2641
|
+
children: t("board.archive")
|
|
2642
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2643
|
+
className: board_module_css_default.columnCount,
|
|
2644
|
+
children: visible.length
|
|
2645
|
+
})]
|
|
2646
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2647
|
+
className: board_module_css_default.cards,
|
|
2648
|
+
children: [visible.map((task) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MemoTaskCard, {
|
|
2649
|
+
task,
|
|
2650
|
+
onOpen: openTask
|
|
2651
|
+
}, task.id)), visible.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2652
|
+
className: board_module_css_default.columnEmpty,
|
|
2653
|
+
children: t("archive.empty")
|
|
2654
|
+
})]
|
|
2655
|
+
})]
|
|
2656
|
+
}) : COLUMNS.map((column) => {
|
|
2038
2657
|
const tasks = visible.filter((task) => task.status === column.status);
|
|
2039
2658
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
2040
2659
|
className: board_module_css_default.column,
|
|
@@ -2274,7 +2893,7 @@ window.__ModuleLoader__.load({
|
|
|
2274
2893
|
}
|
|
2275
2894
|
//#endregion
|
|
2276
2895
|
//#region \0dsh-css:packages/dsh-task-board/src/client/settings-card.module.css.mjs
|
|
2277
|
-
const css = ".Jh0q7G_card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;list-style:none;transition:border-color .16s,background .16s}.Jh0q7G_card:hover{border-color:var(--dsw-alias-label-dimmed)}.Jh0q7G_cardOpen{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}.Jh0q7G_header{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}.Jh0q7G_header:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}.Jh0q7G_headText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.Jh0q7G_name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}.Jh0q7G_description{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}.Jh0q7G_pending{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.Jh0q7G_chevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}.Jh0q7G_chevronOpen{transform:rotate(180deg)}.Jh0q7G_body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}.Jh0q7G_readOnly{color:var(--dsw-alias-label-tertiary);margin:12px 0 0;font-size:12px;line-height:1.5}.Jh0q7G_notExposed{color:var(--dsw-alias-state-warn-primary);margin:12px 0 0;font-size:12px;line-height:1.5}.Jh0q7G_footer{border-top:1px solid var(--dsw-alias-border-l2);justify-content:flex-end;align-items:center;gap:8px;padding:12px 0 4px;display:flex}.Jh0q7G_failed{min-width:0;color:var(--dsw-alias-label-error);text-overflow:ellipsis;white-space:nowrap;flex:1;margin:0;font-size:12px;line-height:1.5;overflow:hidden}.Jh0q7G_discard,.Jh0q7G_save{appearance:none;font:inherit;cursor:pointer;border:1px solid #0000;border-radius:8px;padding:5px 14px;font-size:13px;line-height:1.5}.Jh0q7G_discard{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:0 0}.Jh0q7G_discard:hover:not(:disabled){color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed)}.Jh0q7G_save{background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3)}.Jh0q7G_discard:disabled,.Jh0q7G_save:disabled{opacity:.4;cursor:default}.Jh0q7G_discard:focus-visible,.Jh0q7G_save:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}.Jh0q7G_field{flex-direction:column;gap:6px;padding:12px 0;display:flex}.Jh0q7G_field+.Jh0q7G_field{border-top:1px solid var(--dsw-alias-border-l2)}.Jh0q7G_head{align-items:center;gap:8px;display:flex}.Jh0q7G_label{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:500;line-height:1.5}.Jh0q7G_badges{align-items:center;gap:8px;display:inline-flex}.Jh0q7G_badge{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.Jh0q7G_reset{font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;padding:0;font-size:12px;line-height:1.5}.Jh0q7G_reset:hover:not(:disabled){color:var(--dsw-alias-label-primary)}.Jh0q7G_reset:disabled{cursor:default}.Jh0q7G_reset:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px;outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}.Jh0q7G_input,.Jh0q7G_select{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);height:34px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 12px;font-size:13px;line-height:1.5}.Jh0q7G_input:focus-visible,.Jh0q7G_select:focus-visible{border-color:var(--dsw-alias-brand-primary);outline:none}.Jh0q7G_input:disabled,.Jh0q7G_select:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.Jh0q7G_inputInvalid{border:1px solid var(--dsw-alias-label-error);background:var(--dsw-alias-bg-layer-3);height:34px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 12px;font-size:13px;line-height:1.5}.Jh0q7G_inputInvalid:focus-visible{outline:2px solid var(--dsw-alias-label-error);outline-offset:1px;border-color:var(--dsw-alias-label-error)}.Jh0q7G_invalid{color:var(--dsw-alias-label-error);margin:0;font-size:12px;line-height:1.5}.Jh0q7G_hint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}@media (prefers-reduced-motion:reduce){.Jh0q7G_card,.Jh0q7G_header,.Jh0q7G_chevron,.Jh0q7G_chevronOpen,.Jh0q7G_discard,.Jh0q7G_save{transition:none}}";
|
|
2896
|
+
const css = ".Jh0q7G_card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;list-style:none;transition:border-color .16s,background .16s}.Jh0q7G_card:hover{border-color:var(--dsw-alias-label-dimmed)}.Jh0q7G_cardOpen{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}.Jh0q7G_header{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}.Jh0q7G_header:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}.Jh0q7G_headerStatic{border-radius:12px;align-items:center;gap:12px;width:100%;padding:14px 16px;display:flex}.Jh0q7G_headText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.Jh0q7G_name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}.Jh0q7G_description{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}.Jh0q7G_pending{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.Jh0q7G_chevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}.Jh0q7G_chevronOpen{transform:rotate(180deg)}.Jh0q7G_body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}.Jh0q7G_readOnly{color:var(--dsw-alias-label-tertiary);margin:12px 0 0;font-size:12px;line-height:1.5}.Jh0q7G_notExposed{color:var(--dsw-alias-state-warn-primary);margin:12px 0 0;font-size:12px;line-height:1.5}.Jh0q7G_footer{border-top:1px solid var(--dsw-alias-border-l2);justify-content:flex-end;align-items:center;gap:8px;padding:12px 0 4px;display:flex}.Jh0q7G_failed{min-width:0;color:var(--dsw-alias-label-error);text-overflow:ellipsis;white-space:nowrap;flex:1;margin:0;font-size:12px;line-height:1.5;overflow:hidden}.Jh0q7G_discard,.Jh0q7G_save{appearance:none;font:inherit;cursor:pointer;border:1px solid #0000;border-radius:8px;padding:5px 14px;font-size:13px;line-height:1.5}.Jh0q7G_discard{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:0 0}.Jh0q7G_discard:hover:not(:disabled){color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed)}.Jh0q7G_save{background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3)}.Jh0q7G_discard:disabled,.Jh0q7G_save:disabled{opacity:.4;cursor:default}.Jh0q7G_discard:focus-visible,.Jh0q7G_save:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}.Jh0q7G_field{flex-direction:column;gap:6px;padding:12px 0;display:flex}.Jh0q7G_field+.Jh0q7G_field{border-top:1px solid var(--dsw-alias-border-l2)}.Jh0q7G_head{align-items:center;gap:8px;display:flex}.Jh0q7G_label{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:500;line-height:1.5}.Jh0q7G_badges{align-items:center;gap:8px;display:inline-flex}.Jh0q7G_badge{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.Jh0q7G_reset{font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;padding:0;font-size:12px;line-height:1.5}.Jh0q7G_reset:hover:not(:disabled){color:var(--dsw-alias-label-primary)}.Jh0q7G_reset:disabled{cursor:default}.Jh0q7G_reset:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px;outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}.Jh0q7G_input,.Jh0q7G_select{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);height:34px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 12px;font-size:13px;line-height:1.5}.Jh0q7G_input:focus-visible,.Jh0q7G_select:focus-visible{border-color:var(--dsw-alias-brand-primary);outline:none}.Jh0q7G_input:disabled,.Jh0q7G_select:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.Jh0q7G_inputInvalid{border:1px solid var(--dsw-alias-label-error);background:var(--dsw-alias-bg-layer-3);height:34px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 12px;font-size:13px;line-height:1.5}.Jh0q7G_inputInvalid:focus-visible{outline:2px solid var(--dsw-alias-label-error);outline-offset:1px;border-color:var(--dsw-alias-label-error)}.Jh0q7G_invalid{color:var(--dsw-alias-label-error);margin:0;font-size:12px;line-height:1.5}.Jh0q7G_hint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}@media (prefers-reduced-motion:reduce){.Jh0q7G_card,.Jh0q7G_header,.Jh0q7G_chevron,.Jh0q7G_chevronOpen,.Jh0q7G_discard,.Jh0q7G_save{transition:none}}";
|
|
2278
2897
|
const tagId = "@linxin666/dsh-client-ui-task-board/settings-card.module.css";
|
|
2279
2898
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
2280
2899
|
const tag = document.createElement("style");
|
|
@@ -2299,6 +2918,7 @@ window.__ModuleLoader__.load({
|
|
|
2299
2918
|
"head": "Jh0q7G_head",
|
|
2300
2919
|
"headText": "Jh0q7G_headText",
|
|
2301
2920
|
"header": "Jh0q7G_header",
|
|
2921
|
+
"headerStatic": "Jh0q7G_headerStatic",
|
|
2302
2922
|
"hint": "Jh0q7G_hint",
|
|
2303
2923
|
"input": "Jh0q7G_input",
|
|
2304
2924
|
"inputInvalid": "Jh0q7G_inputInvalid",
|
|
@@ -2328,24 +2948,42 @@ window.__ModuleLoader__.load({
|
|
|
2328
2948
|
* @returns the card, or nothing while the namespace is still loading.
|
|
2329
2949
|
*/
|
|
2330
2950
|
function PluginSettingsCard(props) {
|
|
2331
|
-
const [open, setOpen] = (0, react.useState)(
|
|
2332
|
-
const { state } = props;
|
|
2951
|
+
const [open, setOpen] = (0, react.useState)(props.defaultOpen ?? true);
|
|
2952
|
+
const { state, alwaysOpen } = props;
|
|
2333
2953
|
if (!state.available) return null;
|
|
2334
2954
|
const title = props.t(props.titleKey);
|
|
2335
2955
|
const description = props.t(props.descriptionKey);
|
|
2336
2956
|
const blocked = !state.dirty || state.invalid || state.saving;
|
|
2337
|
-
const
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
className: settings_card_module_css_default.
|
|
2343
|
-
"
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
},
|
|
2348
|
-
|
|
2957
|
+
const expanded = alwaysOpen === true || open;
|
|
2958
|
+
const cardClass = expanded ? `${settings_card_module_css_default.cardOpen} ${settings_card_module_css_default.card}` : settings_card_module_css_default.card;
|
|
2959
|
+
const header = alwaysOpen === true ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2960
|
+
className: settings_card_module_css_default.headerStatic,
|
|
2961
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2962
|
+
className: settings_card_module_css_default.headText,
|
|
2963
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2964
|
+
className: settings_card_module_css_default.name,
|
|
2965
|
+
title,
|
|
2966
|
+
children: title
|
|
2967
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2968
|
+
className: settings_card_module_css_default.description,
|
|
2969
|
+
title: description,
|
|
2970
|
+
children: description
|
|
2971
|
+
})]
|
|
2972
|
+
}), state.dirty ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2973
|
+
className: settings_card_module_css_default.pending,
|
|
2974
|
+
title: props.t("settings.unsaved"),
|
|
2975
|
+
children: props.t("settings.unsaved")
|
|
2976
|
+
}) : null]
|
|
2977
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
2978
|
+
type: "button",
|
|
2979
|
+
className: settings_card_module_css_default.header,
|
|
2980
|
+
"aria-expanded": open,
|
|
2981
|
+
"aria-label": `${props.t(open ? "settings.collapse" : "settings.expand")}: ${title}`,
|
|
2982
|
+
onClick: () => {
|
|
2983
|
+
setOpen(!open);
|
|
2984
|
+
},
|
|
2985
|
+
children: [
|
|
2986
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2349
2987
|
className: settings_card_module_css_default.headText,
|
|
2350
2988
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2351
2989
|
className: settings_card_module_css_default.name,
|
|
@@ -2356,7 +2994,13 @@ window.__ModuleLoader__.load({
|
|
|
2356
2994
|
title: description,
|
|
2357
2995
|
children: description
|
|
2358
2996
|
})]
|
|
2359
|
-
}),
|
|
2997
|
+
}),
|
|
2998
|
+
state.dirty ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2999
|
+
className: settings_card_module_css_default.pending,
|
|
3000
|
+
title: props.t("settings.unsaved"),
|
|
3001
|
+
children: props.t("settings.unsaved")
|
|
3002
|
+
}) : null,
|
|
3003
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
2360
3004
|
width: "14",
|
|
2361
3005
|
height: "14",
|
|
2362
3006
|
viewBox: "0 0 14 14",
|
|
@@ -2367,8 +3011,12 @@ window.__ModuleLoader__.load({
|
|
|
2367
3011
|
d: "M11.8486 5.5L11.4238 5.92383L8.69727 8.65137C8.44157 8.90706 8.21562 9.13382 8.01172 9.29785C7.79912 9.46883 7.55595 9.61756 7.25 9.66602C7.08435 9.69222 6.91565 9.69222 6.75 9.66602C6.44405 9.61756 6.20088 9.46883 5.98828 9.29785C5.78438 9.13382 5.55843 8.90706 5.30273 8.65137L2.57617 5.92383L2.15137 5.5L3 4.65137L3.42383 5.07617L6.15137 7.80273C6.42595 8.07732 6.59876 8.24849 6.74023 8.3623C6.87291 8.46904 6.92272 8.47813 6.9375 8.48047C6.97895 8.48703 7.02105 8.48703 7.0625 8.48047C7.07728 8.47813 7.12709 8.46904 7.25977 8.3623C7.40124 8.24849 7.57405 8.07732 7.84863 7.80273L10.5762 5.07617L11 4.65137L11.8486 5.5Z",
|
|
2368
3012
|
fill: "currentColor"
|
|
2369
3013
|
})
|
|
2370
|
-
})
|
|
2371
|
-
|
|
3014
|
+
})
|
|
3015
|
+
]
|
|
3016
|
+
});
|
|
3017
|
+
if (!state.exposed) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
3018
|
+
className: cardClass,
|
|
3019
|
+
children: [header, expanded ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2372
3020
|
className: settings_card_module_css_default.body,
|
|
2373
3021
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2374
3022
|
className: settings_card_module_css_default.notExposed,
|
|
@@ -2379,46 +3027,7 @@ window.__ModuleLoader__.load({
|
|
|
2379
3027
|
});
|
|
2380
3028
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
2381
3029
|
className: cardClass,
|
|
2382
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("
|
|
2383
|
-
type: "button",
|
|
2384
|
-
className: settings_card_module_css_default.header,
|
|
2385
|
-
"aria-expanded": open,
|
|
2386
|
-
"aria-label": `${props.t(open ? "settings.collapse" : "settings.expand")}: ${title}`,
|
|
2387
|
-
onClick: () => {
|
|
2388
|
-
setOpen(!open);
|
|
2389
|
-
},
|
|
2390
|
-
children: [
|
|
2391
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2392
|
-
className: settings_card_module_css_default.headText,
|
|
2393
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2394
|
-
className: settings_card_module_css_default.name,
|
|
2395
|
-
title,
|
|
2396
|
-
children: title
|
|
2397
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2398
|
-
className: settings_card_module_css_default.description,
|
|
2399
|
-
title: description,
|
|
2400
|
-
children: description
|
|
2401
|
-
})]
|
|
2402
|
-
}),
|
|
2403
|
-
state.dirty ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2404
|
-
className: settings_card_module_css_default.pending,
|
|
2405
|
-
title: props.t("settings.unsaved"),
|
|
2406
|
-
children: props.t("settings.unsaved")
|
|
2407
|
-
}) : null,
|
|
2408
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
2409
|
-
width: "14",
|
|
2410
|
-
height: "14",
|
|
2411
|
-
viewBox: "0 0 14 14",
|
|
2412
|
-
fill: "none",
|
|
2413
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
2414
|
-
className: open ? `${settings_card_module_css_default.chevron} ${settings_card_module_css_default.chevronOpen}` : settings_card_module_css_default.chevron,
|
|
2415
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
2416
|
-
d: "M11.8486 5.5L11.4238 5.92383L8.69727 8.65137C8.44157 8.90706 8.21562 9.13382 8.01172 9.29785C7.79912 9.46883 7.55595 9.61756 7.25 9.66602C7.08435 9.69222 6.91565 9.69222 6.75 9.66602C6.44405 9.61756 6.20088 9.46883 5.98828 9.29785C5.78438 9.13382 5.55843 8.90706 5.30273 8.65137L2.57617 5.92383L2.15137 5.5L3 4.65137L3.42383 5.07617L6.15137 7.80273C6.42595 8.07732 6.59876 8.24849 6.74023 8.3623C6.87291 8.46904 6.92272 8.47813 6.9375 8.48047C6.97895 8.48703 7.02105 8.48703 7.0625 8.48047C7.07728 8.47813 7.12709 8.46904 7.25977 8.3623C7.40124 8.24849 7.57405 8.07732 7.84863 7.80273L10.5762 5.07617L11 4.65137L11.8486 5.5Z",
|
|
2417
|
-
fill: "currentColor"
|
|
2418
|
-
})
|
|
2419
|
-
})
|
|
2420
|
-
]
|
|
2421
|
-
}), open ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3030
|
+
children: [header, expanded ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2422
3031
|
className: settings_card_module_css_default.body,
|
|
2423
3032
|
children: [
|
|
2424
3033
|
!state.writable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
@@ -2883,12 +3492,50 @@ window.__ModuleLoader__.load({
|
|
|
2883
3492
|
exec: new ExecutionService({
|
|
2884
3493
|
sessions: {
|
|
2885
3494
|
list: sessions.list,
|
|
2886
|
-
binding: (id) =>
|
|
3495
|
+
binding: (id) => {
|
|
3496
|
+
const binding = sessions.binding(id);
|
|
3497
|
+
if (binding === void 0) return void 0;
|
|
3498
|
+
const { session } = binding;
|
|
3499
|
+
return { session: {
|
|
3500
|
+
rename: (title) => session.rename(title),
|
|
3501
|
+
prompt: (content, mode) => session.prompt(content, mode).then((result) => result.ok ? { ok: true } : {
|
|
3502
|
+
ok: false,
|
|
3503
|
+
error: result.error
|
|
3504
|
+
}),
|
|
3505
|
+
command: (line) => session.command(line).then((result) => result.ok ? {
|
|
3506
|
+
ok: true,
|
|
3507
|
+
matched: result.value.matched
|
|
3508
|
+
} : {
|
|
3509
|
+
ok: false,
|
|
3510
|
+
error: result.error
|
|
3511
|
+
}),
|
|
3512
|
+
getSnapshot: () => session.getSnapshot(),
|
|
3513
|
+
subscribe: (fn) => session.subscribe(fn)
|
|
3514
|
+
} };
|
|
3515
|
+
},
|
|
3516
|
+
noteAgentPreset: (sessionId, agentPreset) => sessions.noteAgentPreset(sessionId, agentPreset)
|
|
2887
3517
|
},
|
|
2888
3518
|
workspaces: {
|
|
2889
3519
|
list: workspaces.list,
|
|
2890
3520
|
connectWorkspace: (id) => workspaces.connectWorkspace(id)
|
|
2891
3521
|
},
|
|
3522
|
+
presets: { select: async (sessionId, agentPreset) => {
|
|
3523
|
+
try {
|
|
3524
|
+
const response = await connection.api.agentPresets.select({
|
|
3525
|
+
sessionId,
|
|
3526
|
+
agentPreset
|
|
3527
|
+
});
|
|
3528
|
+
return response.result.ok ? { ok: true } : {
|
|
3529
|
+
ok: false,
|
|
3530
|
+
error: response.result.error
|
|
3531
|
+
};
|
|
3532
|
+
} catch (error) {
|
|
3533
|
+
return {
|
|
3534
|
+
ok: false,
|
|
3535
|
+
error
|
|
3536
|
+
};
|
|
3537
|
+
}
|
|
3538
|
+
} },
|
|
2892
3539
|
history: { loadTail: async (sessionId) => {
|
|
2893
3540
|
const response = await connection.api.sessions.history({
|
|
2894
3541
|
sessionId,
|
|
@@ -2905,6 +3552,7 @@ window.__ModuleLoader__.load({
|
|
|
2905
3552
|
controller.start();
|
|
2906
3553
|
const scheduler = new SchedulerService({
|
|
2907
3554
|
tasks: () => controller.getSnapshot().tasks,
|
|
3555
|
+
refresh: () => controller.reloadFromStore(),
|
|
2908
3556
|
now: () => Date.now(),
|
|
2909
3557
|
runTask: (id) => controller.runTask(id),
|
|
2910
3558
|
applySchedule: (id, nextRunAt, lastTriggeredAt) => controller.applyScheduleNextRun(id, nextRunAt, lastTriggeredAt),
|
|
@@ -2916,6 +3564,34 @@ window.__ModuleLoader__.load({
|
|
|
2916
3564
|
});
|
|
2917
3565
|
scheduler.start();
|
|
2918
3566
|
const disposers = [];
|
|
3567
|
+
const pushWorkspaceOptions = () => {
|
|
3568
|
+
const snapshot = workspaces.list.getSnapshot();
|
|
3569
|
+
controller.setExecutionOptions({ workspaces: snapshot.items.map((item) => ({
|
|
3570
|
+
workspaceId: item.workspaceId,
|
|
3571
|
+
title: item.title !== "" ? item.title : item.path
|
|
3572
|
+
})) });
|
|
3573
|
+
};
|
|
3574
|
+
pushWorkspaceOptions();
|
|
3575
|
+
disposers.push(workspaces.list.subscribe(pushWorkspaceOptions));
|
|
3576
|
+
const pushPresetOptions = async () => {
|
|
3577
|
+
try {
|
|
3578
|
+
const response = await connection.api.agentPresets.list({});
|
|
3579
|
+
if (!response.result.ok) return;
|
|
3580
|
+
controller.setExecutionOptions({ presets: response.result.value.presets.map((preset) => ({
|
|
3581
|
+
id: preset.id,
|
|
3582
|
+
name: preset.name,
|
|
3583
|
+
description: preset.description,
|
|
3584
|
+
broken: preset.broken,
|
|
3585
|
+
isDefault: preset.isDefault
|
|
3586
|
+
})) });
|
|
3587
|
+
} catch (error) {
|
|
3588
|
+
console.error("[dsh-task-board] agent preset roster read failed", error);
|
|
3589
|
+
}
|
|
3590
|
+
};
|
|
3591
|
+
pushPresetOptions();
|
|
3592
|
+
disposers.push(ctx.on("connection/reset", () => {
|
|
3593
|
+
pushPresetOptions();
|
|
3594
|
+
}));
|
|
2919
3595
|
try {
|
|
2920
3596
|
disposers.push(mountSidebarEntry(controller));
|
|
2921
3597
|
disposers.push(mountBoard(controller));
|