@linxin666/dsh-client-ui-task-board 0.4.6 → 0.4.7

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.
Files changed (58) hide show
  1. package/README.i18n.yaml +2 -2
  2. package/README.md +14 -6
  3. package/README.zh.md +14 -6
  4. package/lib/client.js +1502 -820
  5. package/lib/client.js.map +1 -1
  6. package/lib/index.js +674 -75
  7. package/lib/types/client/CardDefaultPresetField.d.ts +35 -0
  8. package/lib/types/client/TaskBoardSettingsCard.d.ts +49 -0
  9. package/lib/types/client/board/ReasoningEffortField.d.ts +25 -0
  10. package/lib/types/client/board/model-options.d.ts +67 -0
  11. package/lib/types/client/board/preset-label.d.ts +21 -0
  12. package/lib/types/client/board/preset-roster.d.ts +45 -0
  13. package/lib/types/client/board/team-run-promotion.d.ts +26 -0
  14. package/lib/types/client/locales.d.ts +16 -0
  15. package/lib/types/core/card-defaults.d.ts +78 -0
  16. package/lib/types/core/controller.d.ts +32 -7
  17. package/lib/types/core/launch-width.d.ts +31 -0
  18. package/lib/types/core/reasoning-effort.d.ts +57 -0
  19. package/lib/types/core/subtask.d.ts +30 -8
  20. package/lib/types/core/tasks.d.ts +19 -0
  21. package/lib/types/core/use-cases/task-create.d.ts +10 -5
  22. package/lib/types/core/use-cases/task-update.d.ts +1 -1
  23. package/lib/types/host/launch-admission.d.ts +72 -0
  24. package/lib/types/host-ledger.d.ts +9 -4
  25. package/lib/types/host-runner.d.ts +79 -4
  26. package/lib/types/host-service.d.ts +85 -2
  27. package/lib/types/index.d.ts +87 -0
  28. package/lib/types/protocol.d.ts +13 -0
  29. package/package.json +28 -28
  30. package/src/client/CardDefaultPresetField.tsx +101 -0
  31. package/src/client/TaskBoardSettingsCard.tsx +214 -16
  32. package/src/client/board/LinkSubtaskModal.tsx +8 -0
  33. package/src/client/board/NewTaskModal.tsx +86 -40
  34. package/src/client/board/ReasoningEffortField.tsx +50 -0
  35. package/src/client/board/TaskDetail.tsx +42 -6
  36. package/src/client/board/model-options.ts +178 -0
  37. package/src/client/board/preset-label.ts +32 -0
  38. package/src/client/board/preset-roster.ts +58 -0
  39. package/src/client/board/team-run-promotion.ts +39 -0
  40. package/src/client/index.ts +98 -94
  41. package/src/client/locales.ts +34 -2
  42. package/src/client/settings-entry-form.ts +0 -1
  43. package/src/core/card-defaults.ts +132 -0
  44. package/src/core/controller.ts +44 -9
  45. package/src/core/launch-width.ts +38 -0
  46. package/src/core/reasoning-effort.ts +92 -0
  47. package/src/core/store.ts +5 -0
  48. package/src/core/subtask.ts +48 -13
  49. package/src/core/tasks.ts +20 -0
  50. package/src/core/use-cases/task-create.ts +27 -16
  51. package/src/core/use-cases/task-update.ts +6 -1
  52. package/src/host/agent-tools.ts +21 -8
  53. package/src/host/launch-admission.ts +140 -0
  54. package/src/host-ledger.ts +18 -6
  55. package/src/host-runner.ts +184 -18
  56. package/src/host-service.ts +247 -23
  57. package/src/index.ts +149 -2
  58. package/src/protocol.ts +28 -4
package/src/protocol.ts CHANGED
@@ -93,6 +93,14 @@ export interface TaskBoardSnapshot {
93
93
  * flight.
94
94
  */
95
95
  goalRunEnabled?: boolean
96
+ /**
97
+ * New-card defaults this deployment configures: what the create dialog opens
98
+ * with, and what the create path fills an omitted target from when the caller
99
+ * opts in (`applyCardDefaults`). A target the board configures nothing for is
100
+ * omitted rather than published blank, so the browser can tell "no default
101
+ * model" from "a blank one".
102
+ */
103
+ cardDefaults?: { mode?: string; permission?: TaskPermission; model?: string; reasoningEffort?: string }
96
104
  /**
97
105
  * Read-only summaries published by running extensions, keyed by extension id.
98
106
  * The board forwards them verbatim; it never interprets their shape.
@@ -263,6 +271,9 @@ function validImportedKnownFields(value: Record<string, unknown>): boolean {
263
271
  // must carry a well-formed list or none at all, so a hand-edited export
264
272
  // cannot smuggle a malformed tag past the gate.
265
273
  if (value.tags !== undefined && !isTaskTagList(value.tags)) return false
274
+ // The model pin is carried by the import (with the level bound to it), so a
275
+ // non-string value is refused here like the other carried known fields.
276
+ if (value.model !== undefined && typeof value.model !== 'string') return false
266
277
  if (value.integrations !== undefined && normalizeTaskIntegrations(value.integrations) === undefined) return false
267
278
  if (value.schedule !== undefined && !validImportedSchedule(value.schedule)) return false
268
279
  if (value.executions !== undefined) {
@@ -326,7 +337,15 @@ function importedTask(value: unknown): TaskRecord | undefined {
326
337
  ...(task.parentId === undefined ? {} : { parentId: task.parentId }),
327
338
  ...(task.workspaceId === undefined ? {} : { workspaceId: task.workspaceId }),
328
339
  ...(task.mode === undefined ? {} : { mode: task.mode }),
340
+ // The model pin rides the import together with the level bound to it: the
341
+ // two are one pair, and an imported level without its model would run at
342
+ // whatever route the session happens to be on. Blank text means "no pin",
343
+ // like every other target, so it is not carried as a pin of its own.
344
+ ...(typeof task.model !== 'string' || task.model.trim() === '' ? {} : { model: task.model }),
329
345
  ...(task.permission === undefined ? {} : { permission: task.permission }),
346
+ // The reasoning effort rides the import like the other execution targets: it
347
+ // is the user's own card preference, not a verdict.
348
+ ...(task.reasoningEffort === undefined ? {} : { reasoningEffort: task.reasoningEffort }),
330
349
  ...(task.reuseSession === undefined ? {} : { reuseSession: task.reuseSession }),
331
350
  ...(task.goalRun === undefined ? {} : { goalRun: task.goalRun }),
332
351
  // The per-card acceptance opt-out rides the import like the /goal opt-in:
@@ -372,10 +391,15 @@ function handoverPayload(value: unknown): TaskHandoverInput | undefined {
372
391
 
373
392
  function createInput(value: unknown): value is NewTaskInput {
374
393
  const input = record(value)
375
- if (input === undefined || !exactKeys(input, ['title', 'description', 'prompt', 'parentId', 'workspaceId', 'mode', 'permission', 'schedule', 'freeze', 'handover', 'model', 'reuseSession', 'teamRun', 'goalRun', 'skipVerification', 'tags', 'integrations'])) return false
394
+ if (input === undefined || !exactKeys(input, ['title', 'description', 'prompt', 'parentId', 'workspaceId', 'mode', 'permission', 'schedule', 'freeze', 'handover', 'model', 'reasoningEffort', 'applyCardDefaults', 'reuseSession', 'teamRun', 'goalRun', 'skipVerification', 'tags', 'integrations'])) return false
376
395
  if (input.parentId !== undefined && (typeof input.parentId !== 'string' || input.parentId.trim() === '')) return false
377
396
  if (typeof input.title !== 'string' || typeof input.description !== 'string' || typeof input.prompt !== 'string') return false
378
- if (!optionalString(input.workspaceId) || !optionalString(input.mode) || !optionalString(input.model)) return false
397
+ // The reasoning effort is an adapter-owned id the Host resolves against the
398
+ // live model catalog, so this gate only keeps a malformed value (a number, an
399
+ // object, null) off the ledger; blank text means "inherit" like every other
400
+ // pinned target.
401
+ if (!optionalString(input.workspaceId) || !optionalString(input.mode) || !optionalString(input.model) || !optionalString(input.reasoningEffort)) return false
402
+ if (input.applyCardDefaults !== undefined && typeof input.applyCardDefaults !== 'boolean') return false
379
403
  if (input.reuseSession !== undefined && typeof input.reuseSession !== 'boolean') return false
380
404
  if (input.teamRun !== undefined && typeof input.teamRun !== 'boolean') return false
381
405
  if (input.goalRun !== undefined && typeof input.goalRun !== 'boolean') return false
@@ -402,7 +426,7 @@ function createInput(value: unknown): value is NewTaskInput {
402
426
 
403
427
  function updatePatch(value: unknown): boolean {
404
428
  const patch = record(value)
405
- if (patch === undefined || !exactKeys(patch, ['title', 'description', 'prompt', 'workspaceId', 'mode', 'permission', 'freeze', 'handover', 'model', 'reuseSession', 'teamRun', 'goalRun', 'skipVerification', 'tags'])) return false
429
+ if (patch === undefined || !exactKeys(patch, ['title', 'description', 'prompt', 'workspaceId', 'mode', 'permission', 'freeze', 'handover', 'model', 'reasoningEffort', 'reuseSession', 'teamRun', 'goalRun', 'skipVerification', 'tags'])) return false
406
430
  // null (or false) clears the reuse opt-in; only a real boolean is accepted.
407
431
  if (patch.reuseSession !== undefined && patch.reuseSession !== null && typeof patch.reuseSession !== 'boolean') return false
408
432
  if (patch.teamRun !== undefined && patch.teamRun !== null && typeof patch.teamRun !== 'boolean') return false
@@ -412,7 +436,7 @@ function updatePatch(value: unknown): boolean {
412
436
  // The acceptance opt-out is the mirror tri-state: null/false return the card
413
437
  // to inheriting the board-wide switch, true pins it out of the gate.
414
438
  if (patch.skipVerification !== undefined && patch.skipVerification !== null && typeof patch.skipVerification !== 'boolean') return false
415
- for (const key of ['title', 'description', 'prompt', 'workspaceId', 'mode', 'model'] as const) {
439
+ for (const key of ['title', 'description', 'prompt', 'workspaceId', 'mode', 'model', 'reasoningEffort'] as const) {
416
440
  if (!optionalString(patch[key])) return false
417
441
  }
418
442
  if (patch.permission !== undefined && !isTaskPermission(patch.permission)) return false