@bud.sh/app 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/README.md +41 -31
  2. package/dist/client/assets/bud/design.js +1 -1
  3. package/dist/client/assets/canvas-Bih9EdKJ.js +1 -0
  4. package/dist/client/assets/difference-worker-Bzg-rizy.js +8 -0
  5. package/dist/client/assets/dist-CdE5wBkg.js +5 -0
  6. package/dist/client/assets/files-1dLuoM2f.js +1 -0
  7. package/dist/client/assets/i18n-CkO6VFI0.js +1 -0
  8. package/dist/client/assets/index-Cn2mxroU.css +2 -0
  9. package/dist/client/assets/{index-ChANGtl-.js → index-DtISWZp9.js} +2 -2
  10. package/dist/client/assets/pages-BJ-tNJ4J.js +1 -0
  11. package/dist/client/assets/{project-branches-DO897zM6.js → project-branches-Ce3rXrkc.js} +1 -1
  12. package/dist/client/assets/project-comments-CPUONfs8.js +1 -0
  13. package/dist/client/assets/project-thread-links-C-TGkq59.js +1 -0
  14. package/dist/client/assets/{project-threads-Lay351p4.js → project-threads-Bv7IDBgi.js} +105 -105
  15. package/dist/client/assets/project-work-DAE9-olg.js +1 -0
  16. package/dist/client/assets/{task-design-Avb2RO4w.js → task-design-CwySIAOl.js} +3 -3
  17. package/dist/client/assets/tasks-KWsCLi_h.js +3 -0
  18. package/dist/client/assets/wasm-inline-DSUyFn1L.js +1 -0
  19. package/dist/client/assets/workspace-CVdcfaaB.js +2 -0
  20. package/dist/client/index.html +3 -3
  21. package/dist/hosted/assets/{canvas-V36732ER.js → canvas-AII16n9i.js} +97 -6
  22. package/dist/hosted/assets/{comment-data-CF2ZV_3k.js → comment-data-BXfMElfx.js} +2004 -402
  23. package/dist/hosted/assets/dist-BCSTeNf4.js +4785 -0
  24. package/dist/hosted/assets/{files-DjSCjfU7.js → files-D_1yeAVO.js} +10 -5
  25. package/dist/hosted/assets/{pages-BzjzeuPu.js → pages-CN_SbKWA.js} +3 -3
  26. package/dist/hosted/assets/{project-branches-BT97J9i7.js → project-branches-Bxp0DCwg.js} +1 -1
  27. package/dist/hosted/assets/{project-thread-links-BRLgByEe.js → project-thread-links-KqQoKBLE.js} +76 -4
  28. package/dist/{node-host/assets/screen-CZXWJEds.js → hosted/assets/screen-DpAcDUKR.js} +29 -1
  29. package/dist/hosted/assets/tasks-D66LlwxM.js +1423 -0
  30. package/dist/hosted/assets/wasm-inline-Dl9tqabx.js +4 -0
  31. package/dist/hosted/hosted.js +7885 -6219
  32. package/dist/node/assets/Stream-CAm1eJ2n.js +16604 -0
  33. package/dist/{server/assets/bridge-B_Blt55E.js → node/assets/bridge-DQSBYHmw.js} +124 -290
  34. package/dist/node/assets/config-9_jWwNBh.js +1067 -0
  35. package/dist/node/assets/load-config.server-CMVtRVmO.js +261 -0
  36. package/dist/node/assets/module-3GgtT4Xs.js +308 -0
  37. package/dist/node/assets/server-DTQFuoX2.js +846 -0
  38. package/dist/node/assets/src-D-kG1GxB.js +2 -0
  39. package/dist/node/assets/{src-CerrKjID.js → src-Dwe9APUx.js} +93 -3
  40. package/dist/node/assets/src-DysjfbM8.js +8592 -0
  41. package/dist/node/bridge.js +1 -845
  42. package/dist/node/cli.js +206 -0
  43. package/dist/node/design.js +811 -13
  44. package/dist/node/index.js +2 -739
  45. package/dist/node/plugins.js +5711 -0
  46. package/dist/node/server.js +1 -6746
  47. package/dist/node/vite.js +121 -0
  48. package/dist/{server/assets/canvas-Dc1mYCwQ.js → node-host/assets/canvas-BeDoufy1.js} +97 -7
  49. package/dist/node-host/assets/{comment-data-DyIZNpfG.js → comment-data-DE2T9yTj.js} +1980 -376
  50. package/dist/node-host/assets/dist-BCSTeNf4.js +4785 -0
  51. package/dist/node-host/assets/{files-Dh2TiQZq.js → files-Dl-PTS09.js} +11 -6
  52. package/dist/node-host/assets/{pages-BxpjbYhs.js → pages-DL2sk6_U.js} +3 -3
  53. package/dist/node-host/assets/{project-branches-B7HUGiVK.js → project-branches-DGp5ELct.js} +1 -1
  54. package/dist/{server/assets/project-thread-links-CBOpf6zk.js → node-host/assets/project-thread-links-CgBV3Jcm.js} +76 -5
  55. package/dist/{hosted/assets/screen-CKp2C7kx.js → node-host/assets/screen-B55yyVfb.js} +29 -1
  56. package/dist/node-host/assets/tasks-DZRNkoxe.js +1425 -0
  57. package/dist/node-host/assets/wasm-inline-Dl9tqabx.js +4 -0
  58. package/dist/node-host/node-host.js +6127 -4438
  59. package/dist/server/assets/{branch-previews-ClkoJ0lM.js → branch-previews-DedrpnVR.js} +1555 -673
  60. package/dist/{node-host/assets/canvas-TRUfxfL5.js → server/assets/canvas-CJWQ-jjv.js} +98 -6
  61. package/dist/server/assets/{comment-data-CsjukwAW.js → comment-data-Rg42ToTW.js} +1666 -47
  62. package/dist/server/assets/dist-BCSTeNf4.js +4785 -0
  63. package/dist/server/assets/{events-iHpLGr3k.js → events-BH_rAu7O.js} +155 -20
  64. package/dist/server/assets/{files-E9mSFeoc.js → files-CPJqKeMo.js} +12 -7
  65. package/dist/server/assets/{listener-DN5TyOjJ.js → listener-D61O6PzF.js} +708 -12
  66. package/dist/server/assets/{pages-BBBXyJWV.js → pages-KJY_Ba92.js} +4 -4
  67. package/dist/server/assets/{project-branches-B0YIK6Ur.js → project-branches-qG9ACZvo.js} +2 -2
  68. package/dist/{node-host/assets/project-thread-links-CauJF0Cz.js → server/assets/project-thread-links-CqK0lqCF.js} +77 -4
  69. package/dist/{node-host/assets/tasks-request-ZWmbc8fE.js → server/assets/project-work-DoIwxWMm.js} +87 -2
  70. package/dist/server/assets/run-BJ8r5jSh.js +572 -0
  71. package/dist/server/assets/{screen-BIQA2mr4.js → screen-CBrHPFug.js} +30 -2
  72. package/dist/server/assets/{server-DxK-UB_Z.js → server-Dkbp5stG.js} +1521 -793
  73. package/dist/server/assets/{services-BRrgXYlT.js → services-BTfig8A8.js} +234 -997
  74. package/dist/server/assets/tasks-Bgu5Lg9Y.js +1427 -0
  75. package/dist/server/assets/wasm-inline-Dl9tqabx.js +4 -0
  76. package/dist/server/capture.js +1 -2
  77. package/dist/server/migration.js +569 -12
  78. package/dist/server/runtime.js +7 -5
  79. package/dist/server/server.js +3 -3
  80. package/dist/types/assets/{config-DIC2cf_S.d.ts → config-CvcYmE2s.d.ts} +188 -50
  81. package/dist/types/assets/{contract-CAT-XFNq.d.ts → contract-B7yuuqSn.d.ts} +44 -2
  82. package/dist/types/assets/{items-CaVkByHk.d.ts → items-BQdaVksf.d.ts} +12 -1
  83. package/dist/types/assets/memory-state-BBW-FAVA.d.ts +236 -0
  84. package/dist/types/assets/picker-Be5Gx4WR.d.ts +9 -0
  85. package/dist/types/assets/{task-design-xJOhRNWh.d.ts → task-design-BDHKFHpp.d.ts} +3 -1
  86. package/dist/types/bridge.d.ts +1 -1
  87. package/dist/types/companion.d.ts +3 -3
  88. package/dist/types/design.d.ts +2 -2
  89. package/dist/types/hosted.d.ts +3 -3
  90. package/dist/types/index.d.ts +2 -2
  91. package/dist/types/node-host.d.ts +2 -2
  92. package/dist/types/plugins.d.ts +445 -0
  93. package/dist/types/screen.d.ts +2 -2
  94. package/dist/types/server.d.ts +2 -228
  95. package/dist/types/vite.d.ts +16 -0
  96. package/package.json +19 -3
  97. package/dist/client/assets/canvas-Cu6R6xxT.js +0 -1
  98. package/dist/client/assets/difference-worker-jfTSn-Tw.js +0 -8
  99. package/dist/client/assets/files-js6ElfkU.js +0 -1
  100. package/dist/client/assets/i18n-DxqFr2mi.js +0 -1
  101. package/dist/client/assets/index-CFFxP0gS.css +0 -2
  102. package/dist/client/assets/pages-6_lhiQmz.js +0 -1
  103. package/dist/client/assets/project-comments-DFFKVpia.js +0 -1
  104. package/dist/client/assets/project-thread-links-NLFWQRD2.js +0 -1
  105. package/dist/client/assets/project-work-du0Y-L5Y.js +0 -1
  106. package/dist/client/assets/tasks-CA-E8bbK.js +0 -1
  107. package/dist/client/assets/tasks-request-C55IeuiP.js +0 -1
  108. package/dist/client/assets/workspace-Cw5HvX5d.js +0 -2
  109. package/dist/hosted/assets/tasks-Dj7AyBJB.js +0 -649
  110. package/dist/hosted/assets/tasks-request-DZob623r.js +0 -113
  111. package/dist/node-host/assets/tasks-Bs1IOpeU.js +0 -651
  112. package/dist/server/assets/project-work-qSKFO5yj.js +0 -88
  113. package/dist/server/assets/tasks-CiXodsLN.js +0 -652
  114. package/dist/server/assets/tasks-request-DhwCzpRi.js +0 -115
  115. package/dist/types/assets/picker-D1Bw3ndx.d.ts +0 -14
@@ -2,10 +2,10 @@ import { n as __exportAll$1 } from "./rolldown-runtime-DktXgydw.js";
2
2
  import { $ as INDEX_LINE_METADATA, A as Registry$1, B as DEFAULT_THEMES, C as getFiletypeFromFileName, D as EncodedTokenMetadata, E as queueRender, F as DEFAULT_CODE_VIEW_FILE_METRICS, G as DIFFS_SCROLLBAR_MEASURE_ATTRIBUTE, H as DEFAULT_VIRTUAL_FILE_METRICS, I as DEFAULT_CODE_VIEW_LAYOUT, J as FILENAME_HEADER_REGEX, K as DIFFS_TAG_NAME, L as DEFAULT_EXPANDED_REGION, M as CODE_VIEW_FOOTER_ATTRIBUTE, N as CODE_VIEW_HEADER_ATTRIBUTE, O as FontStyle, P as CUSTOM_HEADER_SLOT_ID, Q as HEADER_PREFIX_SLOT_ID, R as DEFAULT_RENDER_RANGE, T as dequeueRender, U as DIFFS_DEVELOPMENT_BUILD, V as DEFAULT_TOKENIZE_MAX_LENGTH, W as DIFFS_SCROLLBAR_GUTTER_MEASURED_PROPERTY, X as HEADER_FILENAME_SUFFIX_SLOT_ID, Y as GIT_DIFF_FILE_BREAK_REGEX, Z as HEADER_METADATA_SLOT_ID, a as isSafari, b as getLineAnnotationName, et as SPLIT_WITH_NEWLINES, g as isFullyTransparent, j as Theme, k as INITIAL, m as hoverWouldEraseText, n as cloneHunks, nt as UNSAFE_CSS_ATTRIBUTE, o as getLineAnnotationSource, q as EMPTY_RENDER_RANGE, r as isFirefox, t as cloneFileDiffMetadata, tt as THEME_CSS_ATTRIBUTE, u as linesFromFileContents, w as isGutterUtilityPath, z as DEFAULT_SMOOTH_SCROLL_SETTINGS } from "./cloneFileDiffMetadata-C1BcNpxN.js";
3
3
  import { any, array, boolean, createSchema, defaulted, enum_, fail, instanceof_, literal, nullable, number, object, optional, parse, parseSafe, record, string, undefined_, variant } from "remix/data-schema";
4
4
  import { max, maxLength, min, minLength } from "remix/data-schema/checks";
5
+ import { get, post, route } from "remix/routes";
5
6
  import { createElement, createRoot, on, ref, unsafeHTML } from "remix/component";
6
7
  import { Fragment, jsx, jsxs } from "remix/component/jsx-runtime";
7
8
  import { createMatcher, createMultiMatcher } from "remix/route-pattern/match";
8
- import { get, post, route } from "remix/routes";
9
9
  //#region ../previews/src/lib/parsers.ts
10
10
  /** Pages taller than this many CSS pixels are captured to this height. */
11
11
  var MAX_PREVIEW_HEIGHT = 1e5;
@@ -51,7 +51,7 @@ function list$6(item, maximum, message) {
51
51
  let items = array(item);
52
52
  return createSchema((value, context) => !Array.isArray(value) || value.length > maximum ? fail(message, context.path) : items["~run"](value, context));
53
53
  }
54
- function text$8(maximum) {
54
+ function text$7(maximum) {
55
55
  return string().pipe(maxLength(maximum), noNul$2);
56
56
  }
57
57
  function integer$2(maximum = Number.MAX_SAFE_INTEGER, minimum = 0) {
@@ -71,7 +71,7 @@ function strict$2(shape) {
71
71
  });
72
72
  }
73
73
  /** A route identity used in preview URLs. */
74
- var PreviewIdSchema = text$8(512).refine((id) => id !== "", "Expected a preview identity.");
74
+ var PreviewIdSchema = text$7(512).refine((id) => id !== "", "Expected a preview identity.");
75
75
  /** A color scheme. */
76
76
  var PreviewThemeSchema = described$2(enum_(["light", "dark"]), "Unsupported preview theme.");
77
77
  /** The SHA-256 content hash that addresses a captured image. */
@@ -92,7 +92,7 @@ var MAX_PREVIEW_PINS = 1e3;
92
92
  var coordinate = (maximum) => nullable(number().refine((value) => Number.isFinite(value) && value >= 0 && value <= maximum));
93
93
  /** Where a capture found a commented element. */
94
94
  var PreviewPinSchema = strict$2({
95
- id: text$8(512).refine((id) => id.length > 0),
95
+ id: text$7(512).refine((id) => id.length > 0),
96
96
  match: described$2(enum_([
97
97
  "element",
98
98
  "block",
@@ -128,17 +128,17 @@ var PreviewCaptureSchema = strict$2({
128
128
  var oneCapturePerTheme = "Expected at most one capture per theme and viewport.";
129
129
  var captureVariant = (capture) => `${capture.theme}\0${capture.viewport ?? capture.width}`;
130
130
  /** A branch name, as Git allows it for a local branch. */
131
- var PreviewBranchSchema = described$2(text$8(255).refine((value) => /^[A-Za-z0-9._/-]+$/.test(value) && !value.startsWith("-") && !value.startsWith("/") && !value.endsWith("/") && !value.endsWith(".lock") && !value.includes("..") && !value.includes("//")), "Expected a branch name.");
131
+ var PreviewBranchSchema = described$2(text$7(255).refine((value) => /^[A-Za-z0-9._/-]+$/.test(value) && !value.startsWith("-") && !value.startsWith("/") && !value.endsWith("/") && !value.endsWith(".lock") && !value.includes("..") && !value.includes("//")), "Expected a branch name.");
132
132
  /** One preview from the API. */
133
133
  var PreviewSchema = strict$2({
134
134
  id: PreviewIdSchema,
135
- path: text$8(4096),
135
+ path: text$7(4096),
136
136
  state: described$2(enum_([
137
137
  "pending",
138
138
  "ready",
139
139
  "failed"
140
140
  ]), "Unsupported preview state."),
141
- error: nullable(text$8(2048)),
141
+ error: nullable(text$7(2048)),
142
142
  captures: list$6(PreviewCaptureSchema, 8, oneCapturePerTheme).refine((captures) => new Set(captures.map(captureVariant)).size === captures.length, oneCapturePerTheme),
143
143
  updating: boolean(),
144
144
  sequence: integer$2(),
@@ -396,7 +396,7 @@ function matches$2(pattern) {
396
396
  * @param maximum - The longest length allowed.
397
397
  * @returns The string schema.
398
398
  */
399
- function text$7(maximum = 6e4) {
399
+ function text$6(maximum = 6e4) {
400
400
  return string().pipe(maxLength(maximum), noNul$1);
401
401
  }
402
402
  /**
@@ -405,7 +405,7 @@ function text$7(maximum = 6e4) {
405
405
  * @returns The string schema.
406
406
  */
407
407
  function nonempty(maximum = 512) {
408
- return text$7(maximum).refine((value) => !!value.trim());
408
+ return text$6(maximum).refine((value) => !!value.trim());
409
409
  }
410
410
  var identifier$1 = nonempty().pipe(matches$2(/^[a-zA-Z0-9][a-zA-Z0-9._:-]*$/), { check: (value) => !reserved$1.includes(value) });
411
411
  /**
@@ -425,9 +425,9 @@ function number$2(minimum = -Number.MAX_SAFE_INTEGER, maximum = Number.MAX_SAFE_
425
425
  function integer$1(maximum = Number.MAX_SAFE_INTEGER) {
426
426
  return number$2(0, maximum).pipe(safeInteger$1);
427
427
  }
428
- var timestamp$2 = text$7(64).pipe(matches$2(/^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d(?:\.\d+)?(?:Z|[+-]\d\d:\d\d)$/)).refine((value) => Number.isFinite(Date.parse(value)));
429
- var date$1 = text$7(10).pipe(matches$2(/^\d{4}-\d\d-\d\d$/)).refine((value) => Number.isFinite(Date.parse(value)) && new Date(value).toISOString().slice(0, 10) === value);
430
- var revision$2 = nullable(nonempty(256));
428
+ var timestamp$2 = text$6(64).pipe(matches$2(/^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d(?:\.\d+)?(?:Z|[+-]\d\d:\d\d)$/)).refine((value) => Number.isFinite(Date.parse(value)));
429
+ var date$1 = text$6(10).pipe(matches$2(/^\d{4}-\d\d-\d\d$/)).refine((value) => Number.isFinite(Date.parse(value)) && new Date(value).toISOString().slice(0, 10) === value);
430
+ var revision$1 = nullable(nonempty(256));
431
431
  var InvalidJson = class {
432
432
  path;
433
433
  constructor(path) {
@@ -659,7 +659,7 @@ function statusCategory(schema, value) {
659
659
  var MessageAuthorSchema = field("author", strict$1({
660
660
  id: nonempty(256),
661
661
  name: nonempty(1e3),
662
- email: text$7(1e3)
662
+ email: text$6(1e3)
663
663
  }));
664
664
  /** A message returned by storage, never a browser write request. */
665
665
  var MessageSchema = field("message", strict$1({
@@ -742,11 +742,11 @@ function cached(schema, key, build) {
742
742
  var PersonSchema = strict$1({
743
743
  id: nonempty(),
744
744
  name: nonempty(),
745
- email: optional(text$7(1e3))
745
+ email: optional(text$6(1e3))
746
746
  });
747
747
  var itemRefShape = strict$1({
748
748
  id: identifier$1,
749
- title: optional(text$7(1e3)),
749
+ title: optional(text$6(1e3)),
750
750
  status: optional(identifier$1),
751
751
  type: optional(identifier$1),
752
752
  priority: optional(number$2())
@@ -763,14 +763,14 @@ function webUrl(value) {
763
763
  }
764
764
  function kindSchema(field, schema) {
765
765
  switch (field.kind) {
766
- case "text": return field.required ? nonempty(6e4) : text$7();
767
- case "markdown": return text$7();
766
+ case "text": return field.required ? nonempty(6e4) : text$6();
767
+ case "markdown": return text$6();
768
768
  case "number": return number$2();
769
769
  case "duration": return number$2(0);
770
770
  case "boolean": return boolean();
771
771
  case "date": return date$1;
772
772
  case "datetime": return timestamp$2;
773
- case "url": return text$7(4096).refine((url) => !url && !field.required || webUrl(url));
773
+ case "url": return text$6(4096).refine((url) => !url && !field.required || webUrl(url));
774
774
  case "person": return PersonSchema;
775
775
  case "people": return uniqueList(PersonSchema, 100, (person) => person.id);
776
776
  case "labels": return uniqueList(nonempty(128), 100, (label) => label);
@@ -826,6 +826,25 @@ var counts = verify(both(record$1, record(enum_([
826
826
  "incoming"
827
827
  ]), integer$1())), (counts) => counts.children !== void 0 && counts.childrenDone !== void 0 && counts.childrenDone > counts.children ? ["childrenDone"] : void 0);
828
828
  /**
829
+ * Summarizes the run record an adapter keeps on an item (`budRun`) for its board badge.
830
+ * @param value - The stored record; anything else gives no summary.
831
+ * @returns The run's state and error, or undefined without a readable run.
832
+ */
833
+ function workRunSummary(value) {
834
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
835
+ let { state, error } = value;
836
+ if (typeof state !== "string" || !/^[a-z_]{1,32}$/.test(state)) return void 0;
837
+ let message = error && typeof error === "object" && typeof error.message === "string" ? error.message.slice(0, 500) : null;
838
+ return value.asleep === true ? {
839
+ state,
840
+ error: message,
841
+ asleep: true
842
+ } : {
843
+ state,
844
+ error: message
845
+ };
846
+ }
847
+ /**
829
848
  * Creates the schema for an adapter item against its current schema.
830
849
  * @param schema - Its adapter's validated field and relation declarations.
831
850
  * @returns The schema for a complete or explicitly brief item.
@@ -839,12 +858,17 @@ function createWorkItemSchema(schema) {
839
858
  });
840
859
  let item = (mode) => strict$1({
841
860
  id: identifier$1,
842
- revision: revision$2,
861
+ revision: revision$1,
843
862
  values: field("values", valuesSchema(schema, mode)),
844
863
  relations: uniqueList(relation, MAX_WORK_ITEMS, (entry) => `${entry.type}:${entry.direction}:${entry.item.id}`),
845
864
  counts,
846
865
  ready: optional(boolean()),
847
866
  closeable: optional(boolean()),
867
+ run: optional(strict$1({
868
+ state: identifier$1,
869
+ error: nullable(text$6(500)),
870
+ asleep: optional(boolean())
871
+ })),
848
872
  contentLoaded: boolean(),
849
873
  extra: JsonSchema
850
874
  });
@@ -942,8 +966,8 @@ var WorkActivitySchema = field("activity", strict$1({
942
966
  ]),
943
967
  summary: nonempty(4e3),
944
968
  field: optional(identifier$1),
945
- from: optional(nullable(text$7(4e3))),
946
- to: optional(nullable(text$7(4e3)))
969
+ from: optional(nullable(text$6(4e3))),
970
+ to: optional(nullable(text$6(4e3)))
947
971
  }));
948
972
  /**
949
973
  * Creates the schema for a historical item snapshot; a backend may expose only its revision.
@@ -1070,7 +1094,7 @@ function createWorkMutationResultSchema(schema) {
1070
1094
  /** Optional list modifiers and a bounded result limit. */
1071
1095
  var WorkQuerySchema = field("query", strict$1({
1072
1096
  limit: defaulted(integer$1(MAX_WORK_ITEMS).refine((limit) => limit !== 0), MAX_WORK_ITEMS),
1073
- search: optional(text$7(1e3)),
1097
+ search: optional(text$6(1e3)),
1074
1098
  status: optional(identifier$1)
1075
1099
  }));
1076
1100
  var direction = enum_([
@@ -1099,16 +1123,6 @@ function parseWorkItemRef(value, field = "itemRef") {
1099
1123
  return parseWork(itemRefShape, value, field);
1100
1124
  }
1101
1125
  /**
1102
- * Validates a field value against its declared kind and options.
1103
- * @param value - Untrusted data from a request, adapter or response.
1104
- * @param field - The field declaration whose kind and options apply.
1105
- * @param schema - The adapter’s validated schema.
1106
- * @returns The validated value for the declared field kind.
1107
- */
1108
- function parseWorkValue(value, field, schema) {
1109
- return parseWork(createWorkValueSchema(field, schema), value, `values.${field.id}`);
1110
- }
1111
- /**
1112
1126
  * Validates an adapter item against its current schema.
1113
1127
  * @param value - The untrusted record.
1114
1128
  * @param schema - Its adapter's validated field and relation declarations.
@@ -1291,7 +1305,7 @@ var ElementAnchorSchema = strict$1({
1291
1305
  contentHash: nonempty(128),
1292
1306
  label: nonempty(500),
1293
1307
  tagName: nonempty(100),
1294
- text: text$7(1e3),
1308
+ text: text$6(1e3),
1295
1309
  offsetX: number$2(0, 1),
1296
1310
  offsetY: number$2(0, 1),
1297
1311
  block: optional(nullable(ElementBlockSchema)),
@@ -1454,7 +1468,7 @@ function keyed(keys, schema) {
1454
1468
  * @param requireWellFormed - Whether lone surrogates are rejected.
1455
1469
  * @returns The string schema.
1456
1470
  */
1457
- function text$6(maximum = 4096, requireWellFormed = false) {
1471
+ function text$5(maximum = 4096, requireWellFormed = false) {
1458
1472
  let checks = [maxLength(maximum), noNul];
1459
1473
  if (requireWellFormed) checks.push(wellFormed);
1460
1474
  return string().pipe(...checks);
@@ -1489,9 +1503,9 @@ function list$4(item, maximum, minimum = 0, message = "Expected a bounded list."
1489
1503
  function unique$1(values, key) {
1490
1504
  return new Set(values.map(key)).size === values.length;
1491
1505
  }
1492
- var revision$1 = described$1(string().pipe(matches$1(/^[a-f0-9]{64}$/)), "Expected a complete content revision.");
1506
+ var revision = described$1(string().pipe(matches$1(/^[a-f0-9]{64}$/)), "Expected a complete content revision.");
1493
1507
  var identifier = described$1(string().pipe(matches$1(/^[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}$/)), "Invalid identifier.");
1494
- var timestamp$1 = text$6(30).refine((value) => Number.isFinite(Date.parse(value)) && new Date(value).toISOString() === value, "Invalid timestamp.");
1508
+ var timestamp$1 = text$5(30).refine((value) => Number.isFinite(Date.parse(value)) && new Date(value).toISOString() === value, "Invalid timestamp.");
1495
1509
  //#endregion
1496
1510
  //#region ../files/src/lib/paths.ts
1497
1511
  var reserved = /* @__PURE__ */ new Set([
@@ -1593,7 +1607,7 @@ strict({
1593
1607
  includeIgnored: fallback(boolean(), false),
1594
1608
  includeDotfiles: fallback(boolean(), true),
1595
1609
  visibility: fallback(enum_(["all", ...visibilities]), "all"),
1596
- search: fallback(text$6(256), "")
1610
+ search: fallback(text$5(256), "")
1597
1611
  });
1598
1612
  var FileEntrySchema = strict({
1599
1613
  path: FilePathSchema,
@@ -1624,22 +1638,22 @@ var FileWatchStatusSchema = strict({
1624
1638
  }).refine((status) => status.directories <= status.limit, "Expected a bounded integer.");
1625
1639
  var FileIndexSchema = strict({
1626
1640
  directory: FileDirectorySchema,
1627
- revision: revision$1,
1641
+ revision,
1628
1642
  entries: list$4(FileEntrySchema, 1e5).refine((entries) => unique$1(entries, (entry) => entry.path), "Duplicate file paths."),
1629
1643
  truncated: boolean(),
1630
1644
  maxEntries: integer(1e5),
1631
1645
  issues: list$4(strict({
1632
- path: text$6(),
1646
+ path: text$5(),
1633
1647
  code: enum_(issueCodes),
1634
- message: text$6(512)
1648
+ message: text$5(512)
1635
1649
  }), 256),
1636
1650
  git: enum_(["available", "unavailable"]),
1637
1651
  watch: FileWatchStatusSchema
1638
1652
  }).refine((index) => index.entries.length <= index.maxEntries, "Expected a bounded list.");
1639
1653
  var FileDocumentSchema = strict({
1640
1654
  entry: FileEntrySchema,
1641
- contents: nullable(text$6(67108864)),
1642
- revision: nullable(revision$1),
1655
+ contents: nullable(text$5(67108864)),
1656
+ revision: nullable(revision),
1643
1657
  encoding: nullable(enum_(["utf8", "utf8-bom"])),
1644
1658
  lineEnding: nullable(enum_([
1645
1659
  "lf",
@@ -1757,11 +1771,11 @@ function ordered(match) {
1757
1771
  strict(matchShape).refine(ordered, "Expected a bounded integer.");
1758
1772
  var FileSearchResultSchema = strict({
1759
1773
  query: FileSearchQuerySchema,
1760
- indexRevision: revision$1,
1774
+ indexRevision: revision,
1761
1775
  matches: list$4(strict({
1762
1776
  ...matchShape,
1763
1777
  path: FilePathSchema,
1764
- revision: revision$1
1778
+ revision
1765
1779
  }).refine(ordered, "Expected a bounded integer."), 500, 0, "Invalid search matches."),
1766
1780
  scannedFiles: integer(1e5),
1767
1781
  scannedBytes: integer(134217728),
@@ -8293,7 +8307,7 @@ function replacementEdits(contents, pattern, replacement, expectedContents, sele
8293
8307
  }
8294
8308
  //#endregion
8295
8309
  //#region ../files/src/lib/review-parsers.ts
8296
- var oid = text$6(64).refine((value) => /^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(value), "Expected a full Git object ID.");
8310
+ var oid = text$5(64).refine((value) => /^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(value), "Expected a full Git object ID.");
8297
8311
  var mode = enum_([
8298
8312
  "100644",
8299
8313
  "100755",
@@ -8312,7 +8326,7 @@ var statusCodes = [
8312
8326
  "?",
8313
8327
  "!"
8314
8328
  ];
8315
- var ReviewRevisionSchema = text$6(1024).refine((input) => input === "HEAD" || /^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(input) || input.startsWith("refs/") && !/[\x00-\x20\x7f~^:?*\[\\]/.test(input) && !input.includes("..") && !input.includes("@{") && !input.endsWith(".") && !input.split("/").some((part) => !part || part.startsWith(".") || part.endsWith(".lock")), "Choose HEAD, a full object ID, or a full refs/... name.");
8329
+ var ReviewRevisionSchema = text$5(1024).refine((input) => input === "HEAD" || /^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(input) || input.startsWith("refs/") && !/[\x00-\x20\x7f~^:?*\[\\]/.test(input) && !input.includes("..") && !input.includes("@{") && !input.endsWith(".") && !input.split("/").some((part) => !part || part.startsWith(".") || part.endsWith(".lock")), "Choose HEAD, a full object ID, or a full refs/... name.");
8316
8330
  var noEndpoint = described$1(undefined_(), "Commit endpoints require a commit comparison.");
8317
8331
  var ReviewComparisonSchema = keyed([
8318
8332
  "mode",
@@ -8338,14 +8352,14 @@ var ReviewComparisonSchema = keyed([
8338
8352
  strict({
8339
8353
  comparison: ReviewComparisonSchema,
8340
8354
  path: FilePathSchema,
8341
- expectedRevision: optional(revision$1)
8355
+ expectedRevision: optional(revision)
8342
8356
  });
8343
8357
  var commit = oid.refine((value) => !/^0+$/.test(value), "Expected a nonzero commit ID.");
8344
8358
  strict({
8345
8359
  path: FilePathSchema,
8346
8360
  commit
8347
8361
  });
8348
- var cursor = text$6(80).refine((value) => /^(?:[a-f0-9]{40}|[a-f0-9]{64}):(?:0|[1-9]\d{0,4})$/.test(value), "Invalid history cursor.").refine((value) => Number(value.split(":")[1]) <= 1e4, "History cursor exceeds the history bound.");
8362
+ var cursor = text$5(80).refine((value) => /^(?:[a-f0-9]{40}|[a-f0-9]{64}):(?:0|[1-9]\d{0,4})$/.test(value), "Invalid history cursor.").refine((value) => Number(value.split(":")[1]) <= 1e4, "History cursor exceeds the history bound.");
8349
8363
  strict({
8350
8364
  path: FilePathSchema,
8351
8365
  revision: optional(ReviewRevisionSchema),
@@ -8381,7 +8395,7 @@ var ReviewRepositorySchema = strict({
8381
8395
  references: list$4(ReviewReferenceSchema, 1e3),
8382
8396
  status: list$4(ReviewStatusSchema, 1e4),
8383
8397
  truncated: boolean(),
8384
- revision: revision$1
8398
+ revision
8385
8399
  }).refine(({ available, head, branch, unborn, detached }) => unborn === (available && head === null) && detached === (available && head !== null && branch === null) && (branch === null || branch.startsWith("refs/heads/")) && (available || head === null && branch === null), "Inconsistent repository state.");
8386
8400
  var ReviewEntrySchema = strict({
8387
8401
  path: FilePathSchema,
@@ -8413,7 +8427,7 @@ function pinned({ comparison, base, target }) {
8413
8427
  var unpinned = "Inconsistent pinned comparison endpoints.";
8414
8428
  var ReviewSnapshotSchema = strict({
8415
8429
  ...endpointShape,
8416
- revision: revision$1,
8430
+ revision,
8417
8431
  entries: list$4(ReviewEntrySchema, 1e4).refine((entries) => unique$1(entries, (entry) => entry.path), "Duplicate review paths."),
8418
8432
  truncated: boolean()
8419
8433
  }).refine(pinned, unpinned);
@@ -8430,7 +8444,7 @@ var ReviewFileSchema = strict({
8430
8444
  "unavailable"
8431
8445
  ]),
8432
8446
  size: nullable(integer()),
8433
- contents: nullable(text$6(67108864)),
8447
+ contents: nullable(text$5(67108864)),
8434
8448
  encoding: nullable(enum_(["utf8", "utf8-bom"])),
8435
8449
  lineEnding: nullable(enum_([
8436
8450
  "lf",
@@ -8438,8 +8452,8 @@ var ReviewFileSchema = strict({
8438
8452
  "mixed",
8439
8453
  "none"
8440
8454
  ])),
8441
- revision: nullable(revision$1),
8442
- cacheKey: revision$1
8455
+ revision: nullable(revision),
8456
+ cacheKey: revision
8443
8457
  }).refine((file) => file.kind === "text" === (file.contents !== null && file.revision !== null && file.encoding !== null && file.lineEnding !== null), "Inconsistent review content.").refine((file) => file.kind === "text" || file.contents === null && file.encoding === null && file.lineEnding === null, "Unsupported review files cannot expose text.").refine((file) => file.kind === "symlink" === (file.mode === "120000") && file.kind === "gitlink" === (file.mode === "160000") && (file.kind === "text" || file.kind === "binary" || file.revision === null), "Inconsistent review file descriptor.");
8444
8458
  var ReviewSourceSchema = strict({
8445
8459
  path: FilePathSchema,
@@ -8448,8 +8462,8 @@ var ReviewSourceSchema = strict({
8448
8462
  }).refine(({ path, commit, file }) => !file || file.name === path && file.oid !== null && file.oid.length === commit.length, "Inconsistent immutable file source.");
8449
8463
  var ReviewDiffSchema = strict({
8450
8464
  ...endpointShape,
8451
- metadataRevision: revision$1,
8452
- revision: revision$1,
8465
+ metadataRevision: revision,
8466
+ revision,
8453
8467
  entry: ReviewEntrySchema,
8454
8468
  oldFile: nullable(ReviewFileSchema),
8455
8469
  newFile: nullable(ReviewFileSchema),
@@ -8463,15 +8477,15 @@ var ReviewCommitSchema = strict({
8463
8477
  commit: oid,
8464
8478
  parents: list$4(oid, 256),
8465
8479
  author: strict({
8466
- name: text$6(),
8467
- email: text$6()
8480
+ name: text$5(),
8481
+ email: text$5()
8468
8482
  }),
8469
- authoredAt: text$6(40).refine((value) => Number.isFinite(Date.parse(value)), "Invalid commit date."),
8470
- subject: text$6(65536),
8471
- message: text$6(1048576),
8483
+ authoredAt: text$5(40).refine((value) => Number.isFinite(Date.parse(value)), "Invalid commit date."),
8484
+ subject: text$5(65536),
8485
+ message: text$5(1048576),
8472
8486
  path: FilePathSchema,
8473
8487
  previousPath: optional(FilePathSchema),
8474
- change: nullable(text$6(4).refine((value) => /^[ACDMRTU](?:\d{1,3})?$/.test(value), "Invalid history change."))
8488
+ change: nullable(text$5(4).refine((value) => /^[ACDMRTU](?:\d{1,3})?$/.test(value), "Invalid history change."))
8475
8489
  });
8476
8490
  var ReviewHistorySchema = strict({
8477
8491
  path: FilePathSchema,
@@ -8594,7 +8608,7 @@ var FileMutationIntentSchema = keyed([
8594
8608
  "create-file": strict({
8595
8609
  kind: literal("create-file"),
8596
8610
  path: FilePathSchema,
8597
- contents: text$6(2097152, true)
8611
+ contents: text$5(2097152, true)
8598
8612
  }),
8599
8613
  "create-folder": strict({
8600
8614
  kind: literal("create-folder"),
@@ -8613,14 +8627,14 @@ var FileMutationIntentSchema = keyed([
8613
8627
  }));
8614
8628
  strict({
8615
8629
  id: identifier,
8616
- revision: revision$1
8630
+ revision
8617
8631
  });
8618
8632
  var itemShape = {
8619
8633
  source: nullable(FilePathSchema),
8620
8634
  destination: nullable(FilePathSchema),
8621
8635
  kind: enum_(["file", "directory"]),
8622
8636
  bytes: integer(),
8623
- revision: nullable(revision$1)
8637
+ revision: nullable(revision)
8624
8638
  };
8625
8639
  var endpoint = "A file action needs a source or destination.";
8626
8640
  function hasEndpoint(item) {
@@ -8629,14 +8643,14 @@ function hasEndpoint(item) {
8629
8643
  var FileMutationItemSchema = strict(itemShape).refine(hasEndpoint, endpoint);
8630
8644
  var FileMutationPlanSchema = strict({
8631
8645
  id: identifier,
8632
- revision: revision$1,
8646
+ revision,
8633
8647
  kind: enum_(kinds$1),
8634
8648
  expiresAt: timestamp$1,
8635
8649
  items: list$4(FileMutationItemSchema, 100, 1)
8636
8650
  });
8637
8651
  var FileMutationProblemSchema = strict({
8638
8652
  code: enum_(codes),
8639
- message: text$6(512, true),
8653
+ message: text$5(512, true),
8640
8654
  path: nullable(FilePathSchema)
8641
8655
  });
8642
8656
  var FileMutationResultSchema = strict({
@@ -8723,13 +8737,13 @@ var maxFileSaveBytes = 2097152;
8723
8737
  var encoder$1 = new TextEncoder();
8724
8738
  var FileSaveRequestSchema = strict({
8725
8739
  path: FilePathSchema,
8726
- expectedRevision: revision$1,
8740
+ expectedRevision: revision,
8727
8741
  contents: described$1(string().pipe(maxLength(maxFileSaveBytes)).refine((contents) => !contents.includes("\0") && contents.isWellFormed() && encoder$1.encode(contents).byteLength <= 2097152), "Save a valid UTF-8 text file of at most 2 MiB.")
8728
8742
  });
8729
8743
  var FileSaveResultSchema = strict({
8730
8744
  path: FilePathSchema,
8731
- previousRevision: revision$1,
8732
- revision: revision$1,
8745
+ previousRevision: revision,
8746
+ revision,
8733
8747
  bytes: integer(maxFileSaveBytes),
8734
8748
  status: enum_(["saved", "unchanged"]),
8735
8749
  refresh: enum_(["complete", "failed"])
@@ -8798,7 +8812,7 @@ function selectionIntent(kind) {
8798
8812
  return strict({
8799
8813
  kind: literal(kind),
8800
8814
  path: FilePathSchema,
8801
- expectedRevision: revision$1,
8815
+ expectedRevision: revision,
8802
8816
  selection: ReviewActionSelectionSchema
8803
8817
  });
8804
8818
  }
@@ -8816,7 +8830,7 @@ keyed([
8816
8830
  "mark-resolved": strict({
8817
8831
  kind: literal("mark-resolved"),
8818
8832
  path: FilePathSchema,
8819
- expectedRevision: revision$1,
8833
+ expectedRevision: revision,
8820
8834
  conflict: described$1(string().pipe(matches$1(conflictIdentity)).refine((conflict) => conflict !== "-|-|-"), "The original conflict stages are required.")
8821
8835
  }),
8822
8836
  undo: strict({
@@ -8826,11 +8840,11 @@ keyed([
8826
8840
  }));
8827
8841
  strict({
8828
8842
  id: identifier,
8829
- revision: revision$1
8843
+ revision
8830
8844
  });
8831
8845
  var ReviewActionPlanSchema = strict({
8832
8846
  id: identifier,
8833
- revision: revision$1,
8847
+ revision,
8834
8848
  kind: enum_(kinds),
8835
8849
  target,
8836
8850
  paths: paths$1,
@@ -14634,7 +14648,7 @@ var textEntitySubset = ["<", "&"];
14634
14648
  * @returns {string}
14635
14649
  * Serialized node.
14636
14650
  */
14637
- function text$5(node, _, parent, state) {
14651
+ function text$4(node, _, parent, state) {
14638
14652
  return parent && parent.type === "element" && (parent.tagName === "script" || parent.tagName === "style") ? node.value : stringifyEntities(node.value, Object.assign({}, state.settings.characterReferences, { subset: textEntitySubset }));
14639
14653
  }
14640
14654
  //#endregion
@@ -14659,7 +14673,7 @@ function text$5(node, _, parent, state) {
14659
14673
  * Serialized node.
14660
14674
  */
14661
14675
  function raw(node, index, parent, state) {
14662
- return state.settings.allowDangerousHtml ? node.value : text$5(node, index, parent, state);
14676
+ return state.settings.allowDangerousHtml ? node.value : text$4(node, index, parent, state);
14663
14677
  }
14664
14678
  //#endregion
14665
14679
  //#region ../../node_modules/.pnpm/hast-util-to-html@9.0.5/node_modules/hast-util-to-html/lib/handle/root.js
@@ -14702,7 +14716,7 @@ var handle = zwitch("type", {
14702
14716
  element,
14703
14717
  raw,
14704
14718
  root,
14705
- text: text$5
14719
+ text: text$4
14706
14720
  }
14707
14721
  });
14708
14722
  /**
@@ -37244,7 +37258,7 @@ var ThreadSchema = field("thread", verify(strict$1({
37244
37258
  messagesTruncated: boolean(),
37245
37259
  createdAt: timestamp$2,
37246
37260
  updatedAt: timestamp$2,
37247
- revision: revision$2,
37261
+ revision: revision$1,
37248
37262
  metadata: optional(JsonSchema)
37249
37263
  }), (thread) => {
37250
37264
  let { messages, messageCount, messagesLoaded, messagesTruncated } = thread;
@@ -37316,7 +37330,7 @@ var ThreadLinkInputSchema = field("link", verify(strict$1({
37316
37330
  /** Optional discussion filters, without a store, root or capability. */
37317
37331
  var ThreadFilterSchema = field("filter", strict$1({
37318
37332
  anchorKind: optional(enum_(["canvas", "code"])),
37319
- pagePath: optional(both(text$7(4096), field("anchor.pagePath", PagePathSchema))),
37333
+ pagePath: optional(both(text$6(4096), field("anchor.pagePath", PagePathSchema))),
37320
37334
  itemId: optional(identifier$1)
37321
37335
  }));
37322
37336
  /**
@@ -37352,14 +37366,6 @@ function parseThread(value) {
37352
37366
  return parseWork(ThreadSchema, value, "thread");
37353
37367
  }
37354
37368
  /**
37355
- * Validates which discussion operations an adapter supports.
37356
- * @param value - Untrusted data from a request, adapter or response.
37357
- * @returns The supported discussion operations.
37358
- */
37359
- function parseThreadCapabilities(value) {
37360
- return parseWork(ThreadCapabilitiesSchema, value, "capabilities");
37361
- }
37362
- /**
37363
37369
  * Validates a thread list with its availability and operation capabilities.
37364
37370
  * @param value - Untrusted data from a request, adapter or response.
37365
37371
  * @returns The validated connection and thread list.
@@ -37649,6 +37655,149 @@ function parseLiveId(id) {
37649
37655
  function parseLiveEvent(value) {
37650
37656
  return parse(LiveEventSchema, value);
37651
37657
  }
37658
+ //#endregion
37659
+ //#region ../ui/src/lib/routes.ts
37660
+ /** Places in Bud's task screen, shared by links and the screen's matcher. */
37661
+ var taskRoutes = route("/tasks", {
37662
+ index: get("/"),
37663
+ show: get("/:id"),
37664
+ agent: get("/:id/agent")
37665
+ });
37666
+ /** Places in Bud's browser of the project's live pages: a page's own path follows the screen's. */
37667
+ var pageRoutes = route("/pages", {
37668
+ index: get("/"),
37669
+ page: get("/*path")
37670
+ });
37671
+ /** Places in Bud's file browser and review. */
37672
+ var fileRoutes = route("/files", {
37673
+ index: get("/"),
37674
+ file: get("/*path"),
37675
+ escaped: get("/path/*path"),
37676
+ review: get("/review/:mode(/*path)"),
37677
+ compare: get("/compare/:base...:target(/*path)")
37678
+ });
37679
+ /** A conversation's stable place, independent of its canvas or code anchor. */
37680
+ var conversationRoutes = route("/comments", { show: get("/:id") });
37681
+ //#endregion
37682
+ //#region app/routes.ts
37683
+ var routes = route({
37684
+ screen: get("/(:screen)(/*rest)"),
37685
+ screenModule: get("/__bud/screens/:name.js"),
37686
+ logo: get("/__bud/logo/:theme"),
37687
+ health: get("/health"),
37688
+ conversation: conversationRoutes.show,
37689
+ agentApi: {
37690
+ tasks: post("/api/agent/tasks"),
37691
+ tasksStream: get("/api/agent/tasks")
37692
+ },
37693
+ factoryApi: {
37694
+ status: get("/api/factory"),
37695
+ addStatuses: post("/api/factory/statuses"),
37696
+ run: get("/api/factory/tasks/:id/run"),
37697
+ start: post("/api/factory/tasks/:id/start"),
37698
+ changes: post("/api/factory/tasks/:id/changes"),
37699
+ answer: post("/api/factory/tasks/:id/answer"),
37700
+ approve: post("/api/factory/tasks/:id/approve"),
37701
+ discard: post("/api/factory/tasks/:id/discard"),
37702
+ retry: post("/api/factory/tasks/:id/retry"),
37703
+ preview: get("/api/factory/tasks/:id/preview"),
37704
+ wake: post("/api/factory/tasks/:id/wake"),
37705
+ touch: post("/api/factory/tasks/:id/touch"),
37706
+ terminal: get("/api/factory/tasks/:id/terminal/:session"),
37707
+ terminalInput: post("/api/factory/tasks/:id/terminal/:session/input"),
37708
+ terminalResize: post("/api/factory/tasks/:id/terminal/:session/resize")
37709
+ },
37710
+ tasksApi: {
37711
+ index: get("/api/tasks"),
37712
+ schema: get("/api/tasks/schema"),
37713
+ workspace: get("/api/tasks/workspace"),
37714
+ show: get("/api/tasks/items/:id"),
37715
+ section: get("/api/tasks/items/:id/sections/:section"),
37716
+ context: get("/api/tasks/items/:id/context"),
37717
+ attachment: get("/api/tasks/attachments/:hash.jpg"),
37718
+ create: post("/api/tasks"),
37719
+ update: post("/api/tasks/items/:id"),
37720
+ mutate: post("/api/tasks/items/:id/actions"),
37721
+ sync: post("/api/tasks/sync")
37722
+ },
37723
+ filesApi: {
37724
+ index: get("/api/files"),
37725
+ entry: get("/api/files/entry"),
37726
+ read: get("/api/files/read"),
37727
+ refresh: post("/api/files/refresh")
37728
+ },
37729
+ fileSearchApi: { search: get("/api/files/search") },
37730
+ fileReviewApi: {
37731
+ repository: get("/api/files/repository"),
37732
+ compare: get("/api/files/compare"),
37733
+ diff: get("/api/files/diff"),
37734
+ source: get("/api/files/source"),
37735
+ history: get("/api/files/history")
37736
+ },
37737
+ fileMutationsApi: {
37738
+ prepare: post("/api/files/mutations/prepare"),
37739
+ apply: post("/api/files/mutations/apply"),
37740
+ recoveries: get("/api/files/mutations/recoveries")
37741
+ },
37742
+ fileSavesApi: { save: post("/api/files/save") },
37743
+ fileReviewActionsApi: {
37744
+ prepare: post("/api/files/review-actions/prepare"),
37745
+ apply: post("/api/files/review-actions/apply"),
37746
+ recoveries: get("/api/files/review-actions/recoveries")
37747
+ },
37748
+ liveApi: { stream: get("/api/live") },
37749
+ previewsApi: {
37750
+ show: get("/api/previews/items/*id"),
37751
+ image: get("/api/previews/images/:hash.jpg"),
37752
+ refresh: post("/api/previews/refresh/*id"),
37753
+ describe: post("/api/previews/describe/*id"),
37754
+ locate: post("/api/previews/locate/*id")
37755
+ },
37756
+ branchesApi: {
37757
+ list: get("/api/branches"),
37758
+ activate: post("/api/branches/activate/*name"),
37759
+ deactivate: post("/api/branches/deactivate/*name"),
37760
+ capture: post("/api/branches/capture/*name")
37761
+ },
37762
+ comments: {
37763
+ list: get("/api/comments"),
37764
+ get: get("/api/comments/:id"),
37765
+ create: post("/api/comments"),
37766
+ update: post("/api/comments/:id"),
37767
+ reply: post("/api/comments/:id/replies"),
37768
+ status: post("/api/comments/:id/status"),
37769
+ link: post("/api/comments/:id/links"),
37770
+ unlink: post("/api/comments/:id/links/remove"),
37771
+ makeTask: post("/api/comments/:id/task"),
37772
+ deleteMessage: post("/api/comments/:id/messages/remove"),
37773
+ sync: post("/api/comments/sync"),
37774
+ viewer: get("/api/viewer")
37775
+ }
37776
+ });
37777
+ /**
37778
+ * @license @lucide/icons v1.58.0 - ISC
37779
+ *
37780
+ * This source code is licensed under the ISC license.
37781
+ * See the LICENSE file in the root directory of this source tree.
37782
+ */
37783
+ /**
37784
+ * @license @lucide/icons v1.58.0 - ISC
37785
+ *
37786
+ * This source code is licensed under the ISC license.
37787
+ * See the LICENSE file in the root directory of this source tree.
37788
+ */
37789
+ /**
37790
+ * @license @lucide/icons v1.58.0 - ISC
37791
+ *
37792
+ * This source code is licensed under the ISC license.
37793
+ * See the LICENSE file in the root directory of this source tree.
37794
+ */
37795
+ /**
37796
+ * @license @lucide/icons v1.58.0 - ISC
37797
+ *
37798
+ * This source code is licensed under the ISC license.
37799
+ * See the LICENSE file in the root directory of this source tree.
37800
+ */
37652
37801
  /**
37653
37802
  * @license @lucide/icons v1.58.0 - ISC
37654
37803
  *
@@ -39592,6 +39741,32 @@ var icons$1 = {
39592
39741
  }]
39593
39742
  ]
39594
39743
  },
39744
+ "task-add": {
39745
+ name: "list-plus",
39746
+ size: 24,
39747
+ node: [
39748
+ ["path", {
39749
+ d: "M16 5H3",
39750
+ key: "m91uny"
39751
+ }],
39752
+ ["path", {
39753
+ d: "M11 12H3",
39754
+ key: "51ecnj"
39755
+ }],
39756
+ ["path", {
39757
+ d: "M16 19H3",
39758
+ key: "zzsher"
39759
+ }],
39760
+ ["path", {
39761
+ d: "M18 9v6",
39762
+ key: "1twb98"
39763
+ }],
39764
+ ["path", {
39765
+ d: "M21 12h-6",
39766
+ key: "bt1uis"
39767
+ }]
39768
+ ]
39769
+ },
39595
39770
  files: {
39596
39771
  name: "files",
39597
39772
  size: 24,
@@ -39990,6 +40165,60 @@ var icons$1 = {
39990
40165
  }]
39991
40166
  ]
39992
40167
  },
40168
+ terminal: {
40169
+ name: "square-terminal",
40170
+ size: 24,
40171
+ node: [
40172
+ ["path", {
40173
+ d: "m7 11 2-2-2-2",
40174
+ key: "1lz0vl"
40175
+ }],
40176
+ ["path", {
40177
+ d: "M11 13h4",
40178
+ key: "1p7l4v"
40179
+ }],
40180
+ ["rect", {
40181
+ width: "18",
40182
+ height: "18",
40183
+ x: "3",
40184
+ y: "3",
40185
+ rx: "2",
40186
+ ry: "2",
40187
+ key: "1m3agn"
40188
+ }]
40189
+ ],
40190
+ aliases: ["terminal-square"]
40191
+ },
40192
+ "panel-right": {
40193
+ name: "panel-right",
40194
+ size: 24,
40195
+ node: [["rect", {
40196
+ width: "18",
40197
+ height: "18",
40198
+ x: "3",
40199
+ y: "3",
40200
+ rx: "2",
40201
+ key: "afitv7"
40202
+ }], ["path", {
40203
+ d: "M15 3v18",
40204
+ key: "14nvp0"
40205
+ }]]
40206
+ },
40207
+ "panel-bottom": {
40208
+ name: "panel-bottom",
40209
+ size: 24,
40210
+ node: [["rect", {
40211
+ width: "18",
40212
+ height: "18",
40213
+ x: "3",
40214
+ y: "3",
40215
+ rx: "2",
40216
+ key: "afitv7"
40217
+ }], ["path", {
40218
+ d: "M3 15h18",
40219
+ key: "5xshup"
40220
+ }]]
40221
+ },
39993
40222
  eye: {
39994
40223
  name: "eye",
39995
40224
  size: 24,
@@ -40819,6 +41048,34 @@ function HeadlessButton(handle) {
40819
41048
  //#region ../ui/src/lib/i18n/de.ts
40820
41049
  /** Bud's interface text in German, by message key. */
40821
41050
  var de = {
41051
+ "app.client.agentPanel.agent": {
41052
+ text: "Agent",
41053
+ source: "f5a4f646"
41054
+ },
41055
+ "app.client.agentPanel.changesRefused": {
41056
+ text: "Der Agent kann Änderungen gerade nicht entgegennehmen",
41057
+ source: "bdb2edb4"
41058
+ },
41059
+ "app.client.agentPanel.changesSent": {
41060
+ text: "An den Agenten gesendet",
41061
+ source: "7f5e7626"
41062
+ },
41063
+ "app.client.agentPanel.devServer": {
41064
+ text: "Dev-Server",
41065
+ source: "27e53ed7"
41066
+ },
41067
+ "app.client.agentPanel.ended": {
41068
+ text: "Die Sitzung wurde beendet. Wenn du dich wieder verbindest, startet sie erneut.",
41069
+ source: "bf6ebbec"
41070
+ },
41071
+ "app.client.agentPanel.failed": {
41072
+ text: "Die Factory hat nicht geantwortet.",
41073
+ source: "3bd3ae7a"
41074
+ },
41075
+ "app.client.agentPanel.shell": {
41076
+ text: "Shell",
41077
+ source: "ba1969a1"
41078
+ },
40822
41079
  "app.client.commentsRequest.emptyResponse": {
40823
41080
  text: "Der Kommentarservice hat eine leere Antwort zurückgegeben.",
40824
41081
  source: "c739d1f9"
@@ -40907,6 +41164,62 @@ var de = {
40907
41164
  text: "Die Bilder konnten nicht verglichen werden.",
40908
41165
  source: "8fd04955"
40909
41166
  },
41167
+ "app.client.factoryRun.discardAndMove": {
41168
+ text: "Lauf verwerfen & verschieben",
41169
+ source: "9b3e9067"
41170
+ },
41171
+ "app.client.factoryRun.failed": {
41172
+ text: "Bud konnte die Factory nicht erreichen.",
41173
+ source: "00cea450"
41174
+ },
41175
+ "app.client.factoryRun.keepRun": {
41176
+ text: "Lauf behalten",
41177
+ source: "88a5de36"
41178
+ },
41179
+ "app.client.factoryRun.moveQuestion": {
41180
+ text: "Für {id} läuft ein Agent. Wenn du die Aufgabe nach {status} verschiebst, werden der Lauf und seine Sandbox verworfen. Es wurde nichts gepusht, daher geht die Arbeit des Agents verloren.",
41181
+ source: "d0c22345"
41182
+ },
41183
+ "app.client.factoryRun.moveTitle": {
41184
+ text: "Lauf des Agents verwerfen?",
41185
+ source: "5ce9ffe3"
41186
+ },
41187
+ "app.client.factoryRun.noPreview": {
41188
+ text: "Der Dev-Server des Runs ist nicht erreichbar.",
41189
+ source: "6dd54cb3"
41190
+ },
41191
+ "app.client.factoryRun.previewFailed": {
41192
+ text: "Die Live-Vorschau konnte nicht geöffnet werden",
41193
+ source: "a96d281a"
41194
+ },
41195
+ "app.client.factoryRun.refused": {
41196
+ text: "Der Run wurde nicht geändert",
41197
+ source: "a5fc457d"
41198
+ },
41199
+ "app.client.factoryRun.statusesMissing": {
41200
+ text: "Füge oben die Factory-Status hinzu, bevor du Aufgaben startest.",
41201
+ source: "2a26077f"
41202
+ },
41203
+ "app.client.factorySetup.add": {
41204
+ text: "Factory-Status hinzufügen",
41205
+ source: "7992be24"
41206
+ },
41207
+ "app.client.factorySetup.added": {
41208
+ text: "Factory-Status hinzugefügt",
41209
+ source: "02f6f293"
41210
+ },
41211
+ "app.client.factorySetup.failed": {
41212
+ text: "Factory-Status konnten nicht hinzugefügt werden",
41213
+ source: "8500af1b"
41214
+ },
41215
+ "app.client.factorySetup.missing": {
41216
+ text: "In deinem Aufgaben-Store braucht die Factory diese Status: {statuses}.",
41217
+ source: "573be4b6"
41218
+ },
41219
+ "app.client.factorySetup.otherKind": {
41220
+ text: "Dein Aufgaben-Store führt diese Factory-Status als anderen Statustyp: {statuses}. Ordne andere Status in factory.statuses zu.",
41221
+ source: "1b96d5e4"
41222
+ },
40910
41223
  "app.client.fileDrafts.deleteWithUnsavedDrafts": {
40911
41224
  text: "Speichere oder verwerfe die ungespeicherten Entwürfe in dieser Auswahl, bevor du sie löschst.",
40912
41225
  source: "1deabbed"
@@ -41315,6 +41628,10 @@ var de = {
41315
41628
  text: "Der Kommentardienst hat eine andere Diskussion zurückgegeben.",
41316
41629
  source: "c0151231"
41317
41630
  },
41631
+ "app.client.projectComments.taskCreated": {
41632
+ text: "Aufgabe erstellt",
41633
+ source: "4e52cadc"
41634
+ },
41318
41635
  "app.client.projectComments.waitForCurrentOperation": {
41319
41636
  text: "Warte, bis der aktuelle Kommentarvorgang abgeschlossen ist.",
41320
41637
  source: "3c6007dd"
@@ -41522,6 +41839,10 @@ var de = {
41522
41839
  text: "Aufgaben konnten nicht geladen werden.",
41523
41840
  source: "b5dd285f"
41524
41841
  },
41842
+ "app.client.projectTasks.closeAgentView": {
41843
+ text: "Agent-Ansicht schliessen",
41844
+ source: "0d888f27"
41845
+ },
41525
41846
  "app.client.projectTasks.couldNotLoadTask": {
41526
41847
  text: "Diese Aufgabe konnte nicht geladen werden.",
41527
41848
  source: "370587a2"
@@ -41538,10 +41859,22 @@ var de = {
41538
41859
  text: "Der Aufgabendienst hat eine andere Aufgabe zurückgegeben. Aktualisiere vor dem erneuten Versuch.",
41539
41860
  source: "91adeaa0"
41540
41861
  },
41862
+ "app.client.projectTasks.openAgentView": {
41863
+ text: "Agent-Ansicht öffnen",
41864
+ source: "99976d29"
41865
+ },
41541
41866
  "app.client.projectTasks.refreshBeforeChanges": {
41542
41867
  text: "Aktualisiere die Aufgaben, bevor du Änderungen vornimmst.",
41543
41868
  source: "9f4e6583"
41544
41869
  },
41870
+ "app.client.projectTasks.runKept": {
41871
+ text: "Die Aufgabe bleibt, wo sie ist, während der Agent läuft.",
41872
+ source: "ed653075"
41873
+ },
41874
+ "app.client.projectTasks.runPushing": {
41875
+ text: "Der Branch der Aufgabe wird gepusht. Verschiebe sie, sobald der Push abgeschlossen ist.",
41876
+ source: "c4f8b8c6"
41877
+ },
41545
41878
  "app.client.projectTasks.undidTaskChange": {
41546
41879
  text: "Bud hat eine Aufgabenänderung rückgängig gemacht",
41547
41880
  source: "7f50e04c"
@@ -41558,6 +41891,10 @@ var de = {
41558
41891
  text: "Aufgaben verknüpfen",
41559
41892
  source: "b6640aab"
41560
41893
  },
41894
+ "app.client.projectThreadLinks.makeTask": {
41895
+ text: "Aufgabe erstellen",
41896
+ source: "f5eaf1d4"
41897
+ },
41561
41898
  "app.client.projectThreadLinks.reviewLinksBeforeSaving": {
41562
41899
  text: "Überprüfe die neuesten Verknüpfungen, bevor du speicherst.",
41563
41900
  source: "c567f897"
@@ -41590,6 +41927,38 @@ var de = {
41590
41927
  text: "Erneut versuchen",
41591
41928
  source: "8036af59"
41592
41929
  },
41930
+ "app.client.taskContextBlock.branch": {
41931
+ text: "Branch",
41932
+ source: "a3e27665"
41933
+ },
41934
+ "app.client.taskContextBlock.code": {
41935
+ text: "Code",
41936
+ source: "795db914"
41937
+ },
41938
+ "app.client.taskContextBlock.context": {
41939
+ text: "Kontext",
41940
+ source: "bd317f1c"
41941
+ },
41942
+ "app.client.taskContextBlock.element": {
41943
+ text: "Element",
41944
+ source: "7d376697"
41945
+ },
41946
+ "app.client.taskContextBlock.page": {
41947
+ text: "Seite",
41948
+ source: "e83d9196"
41949
+ },
41950
+ "app.client.taskContextBlock.screenshot": {
41951
+ text: "Die Seite rund um den Kommentar, mit markierter Stelle",
41952
+ source: "a97331f6"
41953
+ },
41954
+ "app.client.taskContextBlock.source": {
41955
+ text: "Quelle",
41956
+ source: "61e2a3f8"
41957
+ },
41958
+ "app.client.taskContextBlock.viewport": {
41959
+ text: "Ansicht",
41960
+ source: "60b5afe3"
41961
+ },
41593
41962
  "app.client.taskDiscussion.addContextPlaceholder": {
41594
41963
  text: "Füge Kontext für dein Team hinzu…",
41595
41964
  source: "af3fe6ea"
@@ -41697,6 +42066,10 @@ var de = {
41697
42066
  text: "Die Änderung der Aufgabenverknüpfung wurde nicht bestätigt. Überprüfe die neuesten Verknüpfungen, bevor du erneut speicherst.",
41698
42067
  source: "7616ef3c"
41699
42068
  },
42069
+ "app.client.workspace.agentView": {
42070
+ text: "{task} · Agent",
42071
+ source: "d5c33796"
42072
+ },
41700
42073
  "app.client.workspace.connectProjectToOpenDiscussion": {
41701
42074
  text: "Verbinde ein Projekt, um diese Diskussion zu öffnen.",
41702
42075
  source: "fc0ca04e"
@@ -41737,6 +42110,49 @@ var de = {
41737
42110
  text: "Diskussion",
41738
42111
  source: "52a76f71"
41739
42112
  },
42113
+ "app.server.commentTask.discussion": {
42114
+ text: "Diskussion",
42115
+ source: "52a76f71"
42116
+ },
42117
+ "app.server.commentTask.element": {
42118
+ text: "Element",
42119
+ source: "7d376697"
42120
+ },
42121
+ "app.server.commentTask.linkedTasks": {
42122
+ text: "verknüpfte Aufgaben",
42123
+ source: "b827f1f2"
42124
+ },
42125
+ "app.server.commentTask.replies": {
42126
+ text: "Antworten",
42127
+ source: "43e07f5f"
42128
+ },
42129
+ "app.server.commentTask.replyCount": {
42130
+ text: {
42131
+ one: "{count} Antwort",
42132
+ other: "{count} Antworten"
42133
+ },
42134
+ source: "2b046207"
42135
+ },
42136
+ "app.server.commentTask.source": {
42137
+ text: "Quelle",
42138
+ source: "61e2a3f8"
42139
+ },
42140
+ "app.server.commentTask.title": {
42141
+ text: "Kommentar zu {place}",
42142
+ source: "553c8e8c"
42143
+ },
42144
+ "app.server.commentTask.uncommitted": {
42145
+ text: "nicht committet",
42146
+ source: "fa6d4090"
42147
+ },
42148
+ "app.server.commentTask.where": {
42149
+ text: "Wo",
42150
+ source: "91dad0f8"
42151
+ },
42152
+ "app.server.commentTask.workingTree": {
42153
+ text: "Working Tree",
42154
+ source: "7674e9c0"
42155
+ },
41740
42156
  "appShell.mainNavigation": {
41741
42157
  text: "Hauptnavigation",
41742
42158
  source: "c5a8374a"
@@ -41890,10 +42306,6 @@ var de = {
41890
42306
  text: "Leinwand verschieben",
41891
42307
  source: "233eddf0"
41892
42308
  },
41893
- "canvas.canvasWorkspace.reload": {
41894
- text: "Neu laden",
41895
- source: "1a43a2ac"
41896
- },
41897
42309
  "canvas.canvasWorkspace.savingComments": {
41898
42310
  text: "Kommentare werden gespeichert",
41899
42311
  source: "1f15fbfb"
@@ -44818,6 +45230,114 @@ var de = {
44818
45230
  text: "Tabs",
44819
45231
  source: "8ec4824d"
44820
45232
  },
45233
+ "tasks.agentBrowser.address": {
45234
+ text: "Vorschauadresse",
45235
+ source: "37f7f743"
45236
+ },
45237
+ "tasks.agentBrowser.asleep": {
45238
+ text: "Die Sandbox ist im Ruhezustand, um Kosten zu sparen.",
45239
+ source: "662bf5ad"
45240
+ },
45241
+ "tasks.agentBrowser.back": {
45242
+ text: "Zurück",
45243
+ source: "c2954bc2"
45244
+ },
45245
+ "tasks.agentBrowser.commentOnElement": {
45246
+ text: "Kommentiere ein Element für den Agenten",
45247
+ source: "0dd8635f"
45248
+ },
45249
+ "tasks.agentBrowser.forward": {
45250
+ text: "Vorwärts",
45251
+ source: "e50883ba"
45252
+ },
45253
+ "tasks.agentBrowser.newComment": {
45254
+ text: "Änderung für den Agenten",
45255
+ source: "4d74ba2c"
45256
+ },
45257
+ "tasks.agentBrowser.noPreview": {
45258
+ text: "Hier wird die Vorschau angezeigt, sobald die Sandbox des Laufs mit dem Dev-Server läuft.",
45259
+ source: "65d4e271"
45260
+ },
45261
+ "tasks.agentBrowser.openInNewWindow": {
45262
+ text: "Vorschau in einem neuen Fenster öffnen",
45263
+ source: "e0d3f63c"
45264
+ },
45265
+ "tasks.agentBrowser.preview": {
45266
+ text: "Live-Vorschau",
45267
+ source: "7e42b06f"
45268
+ },
45269
+ "tasks.agentBrowser.reload": {
45270
+ text: "Neu laden",
45271
+ source: "1a43a2ac"
45272
+ },
45273
+ "tasks.agentBrowser.status": {
45274
+ text: "Vorschau-Status",
45275
+ source: "94b339ff"
45276
+ },
45277
+ "tasks.agentBrowser.tryAgain": {
45278
+ text: "Erneut versuchen",
45279
+ source: "213e90fa"
45280
+ },
45281
+ "tasks.agentBrowser.wake": {
45282
+ text: "Aufwecken",
45283
+ source: "d0fedeca"
45284
+ },
45285
+ "tasks.agentBrowser.waking": {
45286
+ text: "Sandbox wird aufgeweckt…",
45287
+ source: "1f99ad40"
45288
+ },
45289
+ "tasks.agentTerminal.disconnected": {
45290
+ text: "Verbindung wird wiederhergestellt…",
45291
+ source: "2f039284"
45292
+ },
45293
+ "tasks.agentTerminal.sessions": {
45294
+ text: "Terminal-Sitzungen",
45295
+ source: "0257839a"
45296
+ },
45297
+ "tasks.agentTerminal.terminal": {
45298
+ text: "Terminal {name}",
45299
+ source: "99a8191c"
45300
+ },
45301
+ "tasks.agentView.agentPanes": {
45302
+ text: "Browser oder Terminal",
45303
+ source: "9c5631e4"
45304
+ },
45305
+ "tasks.agentView.browser": {
45306
+ text: "Browser",
45307
+ source: "8df5852f"
45308
+ },
45309
+ "tasks.agentView.browserAndTerminal": {
45310
+ text: "Browser & Terminal",
45311
+ source: "50b6394f"
45312
+ },
45313
+ "tasks.agentView.details": {
45314
+ text: "Details",
45315
+ source: "0ec24245"
45316
+ },
45317
+ "tasks.agentView.hideTerminal": {
45318
+ text: "Terminal ausblenden",
45319
+ source: "b355c54b"
45320
+ },
45321
+ "tasks.agentView.showTerminal": {
45322
+ text: "Terminal anzeigen",
45323
+ source: "93576794"
45324
+ },
45325
+ "tasks.agentView.terminal": {
45326
+ text: "Terminal",
45327
+ source: "93c562d1"
45328
+ },
45329
+ "tasks.agentView.terminalBelow": {
45330
+ text: "Terminal unter dem Browser",
45331
+ source: "8f840a73"
45332
+ },
45333
+ "tasks.agentView.terminalBeside": {
45334
+ text: "Terminal neben dem Browser",
45335
+ source: "9f744076"
45336
+ },
45337
+ "tasks.agentView.view": {
45338
+ text: "Agent-Ansicht",
45339
+ source: "498637bb"
45340
+ },
44821
45341
  "tasks.taskActions.actionInProgress": {
44822
45342
  text: "Eine Aufgabenaktion läuft bereits.",
44823
45343
  source: "1ae83c01"
@@ -45004,6 +45524,14 @@ var de = {
45004
45524
  text: "In Bearbeitung",
45005
45525
  source: "2948b425"
45006
45526
  },
45527
+ "tasks.taskData.label.merged": {
45528
+ text: "Zusammengeführt",
45529
+ source: "28064199"
45530
+ },
45531
+ "tasks.taskData.label.needs_approval": {
45532
+ text: "Benötigt Freigabe",
45533
+ source: "ecf5c9c5"
45534
+ },
45007
45535
  "tasks.taskData.label.open": {
45008
45536
  text: "Offen",
45009
45537
  source: "538b10e9"
@@ -45016,6 +45544,10 @@ var de = {
45016
45544
  text: "Bereit",
45017
45545
  source: "0bca3294"
45018
45546
  },
45547
+ "tasks.taskData.label.ready_to_merge": {
45548
+ text: "Bereit zum Zusammenführen",
45549
+ source: "b0ea5dc5"
45550
+ },
45019
45551
  "tasks.taskData.label.task": {
45020
45552
  text: "Aufgabe",
45021
45553
  source: "76ef3d8c"
@@ -45347,6 +45879,160 @@ var de = {
45347
45879
  text: "Unerledigter Eintrag",
45348
45880
  source: "eee80db8"
45349
45881
  },
45882
+ "tasks.taskRunBadge.failed": {
45883
+ text: "Run fehlgeschlagen",
45884
+ source: "e2b5681f"
45885
+ },
45886
+ "tasks.taskRunBadge.merged": {
45887
+ text: "Zusammengeführt",
45888
+ source: "28064199"
45889
+ },
45890
+ "tasks.taskRunBadge.needsContext": {
45891
+ text: "Braucht Kontext",
45892
+ source: "18701779"
45893
+ },
45894
+ "tasks.taskRunBadge.pushed": {
45895
+ text: "Gepusht",
45896
+ source: "79d81944"
45897
+ },
45898
+ "tasks.taskRunBadge.pushing": {
45899
+ text: "Wird gepusht",
45900
+ source: "5dd372a3"
45901
+ },
45902
+ "tasks.taskRunBadge.review": {
45903
+ text: "Freigabe nötig",
45904
+ source: "ecf5c9c5"
45905
+ },
45906
+ "tasks.taskRunBadge.settingUp": {
45907
+ text: "Wird eingerichtet",
45908
+ source: "aee4ff74"
45909
+ },
45910
+ "tasks.taskRunBadge.working": {
45911
+ text: "Agent arbeitet",
45912
+ source: "102da6c1"
45913
+ },
45914
+ "tasks.taskRunPanel.activity": {
45915
+ text: "Aktivität des Agents",
45916
+ source: "3457114f"
45917
+ },
45918
+ "tasks.taskRunPanel.agent": {
45919
+ text: "Agent",
45920
+ source: "f5a4f646"
45921
+ },
45922
+ "tasks.taskRunPanel.answer": {
45923
+ text: "Dem Agenten antworten",
45924
+ source: "d2d2b425"
45925
+ },
45926
+ "tasks.taskRunPanel.answerPlaceholder": {
45927
+ text: "Was muss der Agent wissen?",
45928
+ source: "92f7895f"
45929
+ },
45930
+ "tasks.taskRunPanel.approve": {
45931
+ text: "Freigeben & pushen",
45932
+ source: "7110783c"
45933
+ },
45934
+ "tasks.taskRunPanel.asleep": {
45935
+ text: "Die Sandbox schläft, um Kosten zu sparen. Sie wacht auf, wenn du die Vorschau öffnest, Änderungen anforderst oder freigibst.",
45936
+ source: "110af9ad"
45937
+ },
45938
+ "tasks.taskRunPanel.cancel": {
45939
+ text: "Abbrechen",
45940
+ source: "35afca3b"
45941
+ },
45942
+ "tasks.taskRunPanel.changesPlaceholder": {
45943
+ text: "Was soll der Agent ändern?",
45944
+ source: "80c05411"
45945
+ },
45946
+ "tasks.taskRunPanel.confirmApprove": {
45947
+ text: "{branch} ins Repository pushen?",
45948
+ source: "2d1354f2"
45949
+ },
45950
+ "tasks.taskRunPanel.confirmDiscard": {
45951
+ text: "Diesen Run und seine Sandbox verwerfen? Es wurde nichts gepusht.",
45952
+ source: "6ac090ee"
45953
+ },
45954
+ "tasks.taskRunPanel.discard": {
45955
+ text: "Verwerfen",
45956
+ source: "1e706c21"
45957
+ },
45958
+ "tasks.taskRunPanel.failed": {
45959
+ text: "Der Run ist fehlgeschlagen.",
45960
+ source: "49b620f0"
45961
+ },
45962
+ "tasks.taskRunPanel.loading": {
45963
+ text: "Run wird geladen …",
45964
+ source: "331b7fa5"
45965
+ },
45966
+ "tasks.taskRunPanel.merged": {
45967
+ text: "{branch} ist zusammengeführt.",
45968
+ source: "e9b50ea9"
45969
+ },
45970
+ "tasks.taskRunPanel.minutes": {
45971
+ text: {
45972
+ one: "1 Min.",
45973
+ other: "{count} Min."
45974
+ },
45975
+ source: "f87c3e0b"
45976
+ },
45977
+ "tasks.taskRunPanel.needsContext": {
45978
+ text: "Der Agent braucht mehr Kontext, um fortzufahren.",
45979
+ source: "98437cea"
45980
+ },
45981
+ "tasks.taskRunPanel.preview": {
45982
+ text: "Live-Vorschau öffnen",
45983
+ source: "62e9491d"
45984
+ },
45985
+ "tasks.taskRunPanel.pushed": {
45986
+ text: "{branch} wurde bei {commit} gepusht.",
45987
+ source: "78703afe"
45988
+ },
45989
+ "tasks.taskRunPanel.pushing": {
45990
+ text: "{branch} wird gepusht …",
45991
+ source: "9b951555"
45992
+ },
45993
+ "tasks.taskRunPanel.requestChanges": {
45994
+ text: "Änderungen anfordern",
45995
+ source: "637e8883"
45996
+ },
45997
+ "tasks.taskRunPanel.retry": {
45998
+ text: "Erneut versuchen",
45999
+ source: "8036af59"
46000
+ },
46001
+ "tasks.taskRunPanel.review": {
46002
+ text: "Der Agent ist fertig und wartet auf deine Prüfung.",
46003
+ source: "7e509cde"
46004
+ },
46005
+ "tasks.taskRunPanel.seconds": {
46006
+ text: {
46007
+ one: "1 s",
46008
+ other: "{count} s"
46009
+ },
46010
+ source: "24364243"
46011
+ },
46012
+ "tasks.taskRunPanel.settingUp": {
46013
+ text: "Sandbox wird eingerichtet …",
46014
+ source: "be97ea8e"
46015
+ },
46016
+ "tasks.taskRunPanel.showOnCanvas": {
46017
+ text: "Auf der Leinwand anzeigen",
46018
+ source: "b076f243"
46019
+ },
46020
+ "tasks.taskRunPanel.start": {
46021
+ text: "Aufgabe starten",
46022
+ source: "dbc9a724"
46023
+ },
46024
+ "tasks.taskRunPanel.startAgain": {
46025
+ text: "Erneut starten",
46026
+ source: "9a468407"
46027
+ },
46028
+ "tasks.taskRunPanel.startHint": {
46029
+ text: "Ein Agent bearbeitet diese Aufgabe in einer Sandbox. Erst nach deiner Freigabe wird etwas gepusht.",
46030
+ source: "ccf1c6a4"
46031
+ },
46032
+ "tasks.taskRunPanel.working": {
46033
+ text: "Der Agent arbeitet …",
46034
+ source: "202318fe"
46035
+ },
45350
46036
  "tasks.taskSections.latestEvents": {
45351
46037
  text: {
45352
46038
  one: "Das neueste Ereignis wird angezeigt.",
@@ -45464,6 +46150,10 @@ var de = {
45464
46150
  text: "Erstelle eine Aufgabe, um mit der Planung deiner Arbeit zu beginnen.",
45465
46151
  source: "7c21b645"
45466
46152
  },
46153
+ "tasks.taskWorkspace.fewerStatuses": {
46154
+ text: "Weniger Statuswerte anzeigen",
46155
+ source: "1de3f0ed"
46156
+ },
45467
46157
  "tasks.taskWorkspace.filterEpic": {
45468
46158
  text: "Epic filtern",
45469
46159
  source: "19c2ed58"
@@ -45532,6 +46222,17 @@ var de = {
45532
46222
  text: "Noch kein {label}-Arbeitsbereich vorhanden",
45533
46223
  source: "233c23c9"
45534
46224
  },
46225
+ "tasks.taskWorkspace.otherStatuses": {
46226
+ text: {
46227
+ one: "+1 in einem anderen Status",
46228
+ other: "+{count} in anderen Statuswerten"
46229
+ },
46230
+ source: "6cae97c5"
46231
+ },
46232
+ "tasks.taskWorkspace.otherStatusesEmpty": {
46233
+ text: "Weitere Status",
46234
+ source: "d56d45a5"
46235
+ },
45535
46236
  "tasks.taskWorkspace.priority": {
45536
46237
  text: "Priorität",
45537
46238
  source: "e68d9f29"
@@ -45603,6 +46304,13 @@ var de = {
45603
46304
  text: "Deine lokalen Aufgabenänderungen teilen",
45604
46305
  source: "1dad116c"
45605
46306
  },
46307
+ "tasks.taskWorkspace.showTasks": {
46308
+ text: {
46309
+ one: "1 Aufgabe anzeigen",
46310
+ other: "{count} Aufgaben anzeigen"
46311
+ },
46312
+ source: "56258faa"
46313
+ },
45606
46314
  "tasks.taskWorkspace.showingCount": {
45607
46315
  text: "Zeigt {shown} von {total}",
45608
46316
  source: "e8675f4a"
@@ -45699,6 +46407,13 @@ var de = {
45699
46407
  * and the thing (`canvas.zoomIn`); `pnpm translate` keeps the other languages in step.
45700
46408
  */
45701
46409
  var en = {
46410
+ "app.client.agentPanel.agent": "Agent",
46411
+ "app.client.agentPanel.changesRefused": "The agent can’t take changes now",
46412
+ "app.client.agentPanel.changesSent": "Sent to the agent",
46413
+ "app.client.agentPanel.devServer": "Dev server",
46414
+ "app.client.agentPanel.ended": "The session ended. It starts again when you reconnect.",
46415
+ "app.client.agentPanel.failed": "The factory didn’t answer.",
46416
+ "app.client.agentPanel.shell": "Shell",
45702
46417
  "app.client.commentsRequest.emptyResponse": "The comments service returned an empty response.",
45703
46418
  "app.client.commentsRequest.invalidData": "The comments service returned invalid data.",
45704
46419
  "app.client.commentsRequest.invalidEndpoint": "Invalid comments endpoint.",
@@ -45721,6 +46436,20 @@ var en = {
45721
46436
  "app.client.differenceView.slideStatus": "{kind} · change {change} of {count} · {index} / {total}",
45722
46437
  "app.client.differenceView.slideshowLabel": "Differences slideshow",
45723
46438
  "app.client.differenceWorker.compareError": "The pictures could not be compared.",
46439
+ "app.client.factoryRun.discardAndMove": "Discard run & move",
46440
+ "app.client.factoryRun.failed": "Bud couldn’t reach the factory.",
46441
+ "app.client.factoryRun.keepRun": "Keep the run",
46442
+ "app.client.factoryRun.moveQuestion": "{id} has an agent run. Moving it to {status} discards the run and its sandbox; nothing was pushed, so the agent’s work is lost.",
46443
+ "app.client.factoryRun.moveTitle": "Discard the agent’s run?",
46444
+ "app.client.factoryRun.noPreview": "The run’s dev server isn’t up.",
46445
+ "app.client.factoryRun.previewFailed": "Couldn’t open the live preview",
46446
+ "app.client.factoryRun.refused": "The run didn’t change",
46447
+ "app.client.factoryRun.statusesMissing": "Add the factory statuses above before starting tasks.",
46448
+ "app.client.factorySetup.add": "Add factory statuses",
46449
+ "app.client.factorySetup.added": "Factory statuses added",
46450
+ "app.client.factorySetup.failed": "Couldn’t add the factory statuses",
46451
+ "app.client.factorySetup.missing": "The factory needs these statuses in your task store: {statuses}.",
46452
+ "app.client.factorySetup.otherKind": "Your task store has these factory statuses as another kind of status: {statuses}. Map other statuses in factory.statuses.",
45724
46453
  "app.client.fileDrafts.deleteWithUnsavedDrafts": "Save or discard the unsaved drafts in this selection before deleting it.",
45725
46454
  "app.client.fileDrafts.destinationDraftConflict": "The destination acquired an unsaved draft while the move was running. Both drafts remain available at their original paths; download or review them before continuing.",
45726
46455
  "app.client.fileDrafts.destinationHasDraft": "A destination has an unsaved draft. Save or discard it before moving files here.",
@@ -45832,6 +46561,7 @@ var en = {
45832
46561
  "app.client.projectComments.refreshBeforeTryingAgain": "The comment write could not be confirmed. Refresh before trying again.",
45833
46562
  "app.client.projectComments.reloadDiscussionBeforeSaving": "Reload this discussion before saving.",
45834
46563
  "app.client.projectComments.serviceReturnedAnotherDiscussion": "The comments service returned another discussion.",
46564
+ "app.client.projectComments.taskCreated": "Task created",
45835
46565
  "app.client.projectComments.waitForCurrentOperation": "Wait for the current comment operation to finish.",
45836
46566
  "app.client.projectDifferences.comparisonFailed": "The pictures could not be compared.",
45837
46567
  "app.client.projectFileReview.commentsUnavailable": "Comments are stored by your storage adapter. Beads: run bd init in this project.",
@@ -45886,15 +46616,20 @@ var en = {
45886
46616
  "app.client.projectPreviews.requestFailed": "Preview request failed ({status}).",
45887
46617
  "app.client.projectTaskPicker.adapterUnavailable": "The task adapter is unavailable.",
45888
46618
  "app.client.projectTaskPicker.loadFailed": "Could not load tasks.",
46619
+ "app.client.projectTasks.closeAgentView": "Close Agent view",
45889
46620
  "app.client.projectTasks.couldNotLoadTask": "Could not load this task.",
45890
46621
  "app.client.projectTasks.couldNotLoadTasks": "Could not load tasks.",
45891
46622
  "app.client.projectTasks.differentTaskRefresh": "The task service returned a different task. Refresh and try again.",
45892
46623
  "app.client.projectTasks.differentTaskRefreshRetry": "The task service returned a different task. Refresh before retrying.",
46624
+ "app.client.projectTasks.openAgentView": "Open Agent view",
45893
46625
  "app.client.projectTasks.refreshBeforeChanges": "Refresh tasks before making changes.",
46626
+ "app.client.projectTasks.runKept": "The task stays where it is while its agent runs.",
46627
+ "app.client.projectTasks.runPushing": "The task’s branch is being pushed; move it once the push is done.",
45894
46628
  "app.client.projectTasks.undidTaskChange": "Bud undid a task change",
45895
46629
  "app.client.projectTasks.writeNotConfirmed": "The write was not confirmed.",
45896
46630
  "app.client.projectThreadLinks.anotherDiscussion": "The service returned another discussion.",
45897
46631
  "app.client.projectThreadLinks.linkTasks": "Link tasks",
46632
+ "app.client.projectThreadLinks.makeTask": "Make task",
45898
46633
  "app.client.projectThreadLinks.reviewLinksBeforeSaving": "Review the latest links before saving.",
45899
46634
  "app.client.screenHost.couldNotOpen": "Could not open {label}.",
45900
46635
  "app.client.screenHost.didntOpen": "{label} didn't open",
@@ -45903,6 +46638,14 @@ var en = {
45903
46638
  "app.client.screenHost.loading": "Loading {label}…",
45904
46639
  "app.client.screenHost.noRouteMatches": "No screen route matches {href}.",
45905
46640
  "app.client.screenHost.retry": "Retry",
46641
+ "app.client.taskContextBlock.branch": "Branch",
46642
+ "app.client.taskContextBlock.code": "Code",
46643
+ "app.client.taskContextBlock.context": "Context",
46644
+ "app.client.taskContextBlock.element": "Element",
46645
+ "app.client.taskContextBlock.page": "Page",
46646
+ "app.client.taskContextBlock.screenshot": "The page around the comment, with its point marked",
46647
+ "app.client.taskContextBlock.source": "Source",
46648
+ "app.client.taskContextBlock.viewport": "Viewport",
45906
46649
  "app.client.taskDiscussion.addContextPlaceholder": "Add context for your team…",
45907
46650
  "app.client.taskDiscussion.addTaskComment": "Add task comment",
45908
46651
  "app.client.taskDiscussion.cancel": "Cancel",
@@ -45932,6 +46675,7 @@ var en = {
45932
46675
  },
45933
46676
  "app.client.threadLinks.taskDiscussionNeedsLinkedTask": "A task discussion needs at least one linked task.",
45934
46677
  "app.client.threadLinks.taskLinkChangeNotConfirmed": "The task link change was not confirmed. Review the latest links before saving again.",
46678
+ "app.client.workspace.agentView": "{task} · Agent",
45935
46679
  "app.client.workspace.connectProjectToOpenDiscussion": "Connect a project to open this discussion.",
45936
46680
  "app.client.workspace.couldNotOpenDiscussion": "Could not open this discussion.",
45937
46681
  "app.client.workspace.discussion": "Discussion",
@@ -45942,6 +46686,19 @@ var en = {
45942
46686
  "app.client.workspace.startProjectWithBudVitePlugin": "Start your project with the Bud Vite plugin, or run Bud from its directory. Its screens appear here when the companion connects.",
45943
46687
  "app.client.workspace.yourProjectSideBySide": "Your project, side by side.",
45944
46688
  "app.controller.discussion": "Discussion",
46689
+ "app.server.commentTask.discussion": "Discussion",
46690
+ "app.server.commentTask.element": "Element",
46691
+ "app.server.commentTask.linkedTasks": "linked tasks",
46692
+ "app.server.commentTask.replies": "Replies",
46693
+ "app.server.commentTask.replyCount": {
46694
+ one: "{count} reply",
46695
+ other: "{count} replies"
46696
+ },
46697
+ "app.server.commentTask.source": "Source",
46698
+ "app.server.commentTask.title": "Comment on {place}",
46699
+ "app.server.commentTask.uncommitted": "uncommitted",
46700
+ "app.server.commentTask.where": "Where",
46701
+ "app.server.commentTask.workingTree": "working tree",
45945
46702
  "appShell.mainNavigation": "Main navigation",
45946
46703
  "breadcrumb.navigationLabel": "Breadcrumb",
45947
46704
  "canvas.artboardCanvas.chooseCollectionPage": "Choose a {collection} page",
@@ -45987,7 +46744,6 @@ var en = {
45987
46744
  "canvas.canvasWorkspace.interactWithPages": "Interact with pages",
45988
46745
  "canvas.canvasWorkspace.newComment": "New comment",
45989
46746
  "canvas.canvasWorkspace.panCanvas": "Pan canvas",
45990
- "canvas.canvasWorkspace.reload": "Reload",
45991
46747
  "canvas.canvasWorkspace.savingComments": "Saving comments",
45992
46748
  "canvas.canvasWorkspace.showDarkPages": "Show dark pages",
45993
46749
  "canvas.canvasWorkspace.showFullPages": "Show full pages",
@@ -46800,6 +47556,33 @@ var en = {
46800
47556
  other: "{count} tabs"
46801
47557
  },
46802
47558
  "shellTabBar.tabsLabel": "Tabs",
47559
+ "tasks.agentBrowser.address": "Preview address",
47560
+ "tasks.agentBrowser.asleep": "The sandbox is asleep to save costs.",
47561
+ "tasks.agentBrowser.back": "Back",
47562
+ "tasks.agentBrowser.commentOnElement": "Comment on an element for the agent",
47563
+ "tasks.agentBrowser.forward": "Forward",
47564
+ "tasks.agentBrowser.newComment": "Change for the agent",
47565
+ "tasks.agentBrowser.noPreview": "The preview shows here while the run’s sandbox is up with its dev server.",
47566
+ "tasks.agentBrowser.openInNewWindow": "Open the preview in a new window",
47567
+ "tasks.agentBrowser.preview": "Live preview",
47568
+ "tasks.agentBrowser.reload": "Reload",
47569
+ "tasks.agentBrowser.status": "Preview status",
47570
+ "tasks.agentBrowser.tryAgain": "Try again",
47571
+ "tasks.agentBrowser.wake": "Wake it",
47572
+ "tasks.agentBrowser.waking": "Waking the sandbox…",
47573
+ "tasks.agentTerminal.disconnected": "Reconnecting…",
47574
+ "tasks.agentTerminal.sessions": "Terminal sessions",
47575
+ "tasks.agentTerminal.terminal": "{name} terminal",
47576
+ "tasks.agentView.agentPanes": "Browser or terminal",
47577
+ "tasks.agentView.browser": "Browser",
47578
+ "tasks.agentView.browserAndTerminal": "Browser & terminal",
47579
+ "tasks.agentView.details": "Details",
47580
+ "tasks.agentView.hideTerminal": "Hide terminal",
47581
+ "tasks.agentView.showTerminal": "Show terminal",
47582
+ "tasks.agentView.terminal": "Terminal",
47583
+ "tasks.agentView.terminalBelow": "Terminal below the browser",
47584
+ "tasks.agentView.terminalBeside": "Terminal beside the browser",
47585
+ "tasks.agentView.view": "Agent view",
46803
47586
  "tasks.taskActions.actionInProgress": "A task action is already in progress.",
46804
47587
  "tasks.taskActions.actions": "Actions",
46805
47588
  "tasks.taskActions.changeNotConfirmed": "The change was not confirmed. Refresh before trying again.",
@@ -46851,9 +47634,12 @@ var en = {
46851
47634
  "tasks.taskData.label.feature": "Feature",
46852
47635
  "tasks.taskData.label.hooked": "Hooked",
46853
47636
  "tasks.taskData.label.in_progress": "In progress",
47637
+ "tasks.taskData.label.merged": "Merged",
47638
+ "tasks.taskData.label.needs_approval": "Needs approval",
46854
47639
  "tasks.taskData.label.open": "Open",
46855
47640
  "tasks.taskData.label.pinned": "Pinned",
46856
47641
  "tasks.taskData.label.ready": "Ready",
47642
+ "tasks.taskData.label.ready_to_merge": "Ready to merge",
46857
47643
  "tasks.taskData.label.task": "Task",
46858
47644
  "tasks.taskData.low": "Low",
46859
47645
  "tasks.taskData.noEpic": "No epic",
@@ -46939,6 +47725,49 @@ var en = {
46939
47725
  "tasks.taskMarkdown.completedItem": "Completed item",
46940
47726
  "tasks.taskMarkdown.image": "Image",
46941
47727
  "tasks.taskMarkdown.incompleteItem": "Incomplete item",
47728
+ "tasks.taskRunBadge.failed": "Run failed",
47729
+ "tasks.taskRunBadge.merged": "Merged",
47730
+ "tasks.taskRunBadge.needsContext": "Needs context",
47731
+ "tasks.taskRunBadge.pushed": "Pushed",
47732
+ "tasks.taskRunBadge.pushing": "Pushing",
47733
+ "tasks.taskRunBadge.review": "Needs approval",
47734
+ "tasks.taskRunBadge.settingUp": "Setting up",
47735
+ "tasks.taskRunBadge.working": "Agent working",
47736
+ "tasks.taskRunPanel.activity": "Agent activity",
47737
+ "tasks.taskRunPanel.agent": "Agent",
47738
+ "tasks.taskRunPanel.answer": "Answer the agent",
47739
+ "tasks.taskRunPanel.answerPlaceholder": "What does the agent need to know?",
47740
+ "tasks.taskRunPanel.approve": "Approve & push",
47741
+ "tasks.taskRunPanel.asleep": "The sandbox sleeps to save cost. It wakes up when you open the preview, request changes or approve.",
47742
+ "tasks.taskRunPanel.cancel": "Cancel",
47743
+ "tasks.taskRunPanel.changesPlaceholder": "What should the agent change?",
47744
+ "tasks.taskRunPanel.confirmApprove": "Push {branch} to the repository?",
47745
+ "tasks.taskRunPanel.confirmDiscard": "Discard this run and its sandbox? Nothing was pushed.",
47746
+ "tasks.taskRunPanel.discard": "Discard",
47747
+ "tasks.taskRunPanel.failed": "The run failed.",
47748
+ "tasks.taskRunPanel.loading": "Loading the run…",
47749
+ "tasks.taskRunPanel.merged": "{branch} is merged.",
47750
+ "tasks.taskRunPanel.minutes": {
47751
+ one: "1 min",
47752
+ other: "{count} min"
47753
+ },
47754
+ "tasks.taskRunPanel.needsContext": "The agent needs more context to go on.",
47755
+ "tasks.taskRunPanel.preview": "Open live preview",
47756
+ "tasks.taskRunPanel.pushed": "Pushed {branch} at {commit}.",
47757
+ "tasks.taskRunPanel.pushing": "Pushing {branch}…",
47758
+ "tasks.taskRunPanel.requestChanges": "Request changes",
47759
+ "tasks.taskRunPanel.retry": "Retry",
47760
+ "tasks.taskRunPanel.review": "The agent is done and waits for your review.",
47761
+ "tasks.taskRunPanel.seconds": {
47762
+ one: "1 s",
47763
+ other: "{count} s"
47764
+ },
47765
+ "tasks.taskRunPanel.settingUp": "Setting up the sandbox…",
47766
+ "tasks.taskRunPanel.showOnCanvas": "Show on canvas",
47767
+ "tasks.taskRunPanel.start": "Start task",
47768
+ "tasks.taskRunPanel.startAgain": "Start again",
47769
+ "tasks.taskRunPanel.startHint": "An agent works on this task in a sandbox. Nothing is pushed until you approve.",
47770
+ "tasks.taskRunPanel.working": "The agent is working…",
46942
47771
  "tasks.taskSections.latestEvents": {
46943
47772
  one: "Showing the latest {count} event.",
46944
47773
  other: "Showing the latest {count} events."
@@ -46975,6 +47804,7 @@ var en = {
46975
47804
  "tasks.taskWorkspace.connectProject": "Connect a project",
46976
47805
  "tasks.taskWorkspace.createTask": "Create task",
46977
47806
  "tasks.taskWorkspace.createToPlan": "Create a task to start planning your work.",
47807
+ "tasks.taskWorkspace.fewerStatuses": "Show fewer statuses",
46978
47808
  "tasks.taskWorkspace.filterEpic": "Filter epic",
46979
47809
  "tasks.taskWorkspace.filterField": "Filter {field}",
46980
47810
  "tasks.taskWorkspace.filters": "Filters",
@@ -46992,6 +47822,11 @@ var en = {
46992
47822
  "tasks.taskWorkspace.noMatches": "No tasks match this view",
46993
47823
  "tasks.taskWorkspace.noRemote": "No {label} remote is configured",
46994
47824
  "tasks.taskWorkspace.noWorkspace": "No {label} workspace yet",
47825
+ "tasks.taskWorkspace.otherStatuses": {
47826
+ one: "+1 in other statuses",
47827
+ other: "+{count} in other statuses"
47828
+ },
47829
+ "tasks.taskWorkspace.otherStatusesEmpty": "Other statuses",
46995
47830
  "tasks.taskWorkspace.priority": "Priority",
46996
47831
  "tasks.taskWorkspace.projectTasks": "Project tasks",
46997
47832
  "tasks.taskWorkspace.pullChanges": "Pull changes",
@@ -47012,6 +47847,10 @@ var en = {
47012
47847
  "tasks.taskWorkspace.searchPlaceholder": "Search tasks, IDs, labels…",
47013
47848
  "tasks.taskWorkspace.searchTasks": "Search tasks",
47014
47849
  "tasks.taskWorkspace.shareLocalChanges": "Share your local task changes",
47850
+ "tasks.taskWorkspace.showTasks": {
47851
+ one: "Show 1 task",
47852
+ other: "Show {count} tasks"
47853
+ },
47015
47854
  "tasks.taskWorkspace.showingCount": "Showing {shown} of {total}",
47016
47855
  "tasks.taskWorkspace.sortTasks": "Sort tasks",
47017
47856
  "tasks.taskWorkspace.startBud": "Start Bud from your web project to see its tasks.",
@@ -59837,28 +60676,6 @@ function CommentComposerCard(handle) {
59837
60676
  });
59838
60677
  }
59839
60678
  //#endregion
59840
- //#region ../ui/src/lib/routes.ts
59841
- /** Places in Bud's task screen, shared by links and the screen's matcher. */
59842
- var taskRoutes = route("/tasks", {
59843
- index: get("/"),
59844
- show: get("/:id")
59845
- });
59846
- /** Places in Bud's browser of the project's live pages: a page's own path follows the screen's. */
59847
- var pageRoutes = route("/pages", {
59848
- index: get("/"),
59849
- page: get("/*path")
59850
- });
59851
- /** Places in Bud's file browser and review. */
59852
- var fileRoutes = route("/files", {
59853
- index: get("/"),
59854
- file: get("/*path"),
59855
- escaped: get("/path/*path"),
59856
- review: get("/review/:mode(/*path)"),
59857
- compare: get("/compare/:base...:target(/*path)")
59858
- });
59859
- /** A conversation's stable place, independent of its canvas or code anchor. */
59860
- var conversationRoutes = route("/comments", { show: get("/:id") });
59861
- //#endregion
59862
60679
  //#region ../ui/src/lib/files/file-location.ts
59863
60680
  var matcher = createMultiMatcher();
59864
60681
  for (let [name, route] of Object.entries(fileRoutes)) matcher.add(route.pattern, name);
@@ -60601,6 +61418,7 @@ function taskFields(item, schema) {
60601
61418
  //#endregion
60602
61419
  //#region ../ui/src/lib/tasks/task-data.ts
60603
61420
  var taskMatcher = createMatcher(taskRoutes.show.pattern);
61421
+ var agentMatcher = createMatcher(taskRoutes.agent.pattern);
60604
61422
  var defaultTaskView = {
60605
61423
  query: "",
60606
61424
  fields: {},
@@ -60782,6 +61600,26 @@ function taskHref(id) {
60782
61600
  }
60783
61601
  }
60784
61602
  /**
61603
+ * Builds the URL of a task's Agent view: its details beside its run's preview and terminal.
61604
+ * @param id - The task's id.
61605
+ * @returns The typed URL.
61606
+ */
61607
+ function taskAgentHref(id) {
61608
+ return taskRoutes.agent.href({ id: parseWorkItemRef({ id }).id });
61609
+ }
61610
+ /**
61611
+ * Whether a location is a task's Agent view.
61612
+ * @param location - The current location.
61613
+ * @returns True for `/tasks/:id/agent`.
61614
+ */
61615
+ function agentViewOpen(location) {
61616
+ try {
61617
+ return Boolean(agentMatcher.match(new URL(location, "http://bud.invalid/tasks")));
61618
+ } catch {
61619
+ return false;
61620
+ }
61621
+ }
61622
+ /**
60785
61623
  * Reads the typed task place, or one older query selection on the board URL.
60786
61624
  * @param location - The current location or legacy query link.
60787
61625
  * @returns The validated task ID, or null for the board or an invalid link.
@@ -60790,7 +61628,7 @@ function selectedTask(location) {
60790
61628
  try {
60791
61629
  let url = new URL(location, "http://bud.invalid/tasks");
60792
61630
  if (url.href.length > 32768) return null;
60793
- let value = url.pathname === taskRoutes.index.href() && url.searchParams.getAll("issue").length === 1 ? url.searchParams.get("issue") : taskMatcher.match(url)?.params.id;
61631
+ let value = url.pathname === taskRoutes.index.href() && url.searchParams.getAll("issue").length === 1 ? url.searchParams.get("issue") : (taskMatcher.match(url) ?? agentMatcher.match(url))?.params.id;
60794
61632
  return value ? parseWorkItemRef({ id: value }).id : null;
60795
61633
  } catch {
60796
61634
  return null;
@@ -74178,40 +75016,6 @@ function object$1(value) {
74178
75016
  return value;
74179
75017
  }
74180
75018
  /**
74181
- * Checks a nonblank string within a length limit.
74182
- * @param value - Untrusted data.
74183
- * @param label - What the error message calls it.
74184
- * @param limit - The most characters it may have.
74185
- * @returns The string.
74186
- */
74187
- function text$4(value, label, limit) {
74188
- return parseRecord(bounded(label, limit), value);
74189
- }
74190
- /**
74191
- * Checks a conversation or message ID.
74192
- * @param value - Untrusted data.
74193
- * @returns The ID.
74194
- */
74195
- function conversationId(value) {
74196
- return parseRecord(ConversationIdSchema, value);
74197
- }
74198
- /**
74199
- * Checks a comments branch revision.
74200
- * @param value - Untrusted data.
74201
- * @returns The revision, or null before the branch's first commit.
74202
- */
74203
- function revision(value) {
74204
- return parseRecord(CommentRevisionSchema, value);
74205
- }
74206
- /**
74207
- * Checks a conversation status.
74208
- * @param value - Untrusted data.
74209
- * @returns The status.
74210
- */
74211
- function commentStatus(value) {
74212
- return parseRecord(CommentStatusSchema, value);
74213
- }
74214
- /**
74215
75019
  * Reads legacy page captures while discarding the extension properties older parsers ignored.
74216
75020
  * @param value - A stored canvas anchor.
74217
75021
  * @returns Its validated canonical capture.
@@ -74306,122 +75110,6 @@ object({
74306
75110
  head: CommentRevisionSchema,
74307
75111
  threads: list$1(CommentThreadSchema, "Invalid comments response.").refine((threads) => unique(threads, (thread) => thread.id), "Duplicate conversation ID.")
74308
75112
  }).refine(({ head, threads }) => head !== null || !threads.length, "Comments are missing their Git revision.");
74309
- /**
74310
- * Validates a stored or requested thread.
74311
- * @param value - Untrusted data.
74312
- * @returns The thread.
74313
- */
74314
- function parseCommentThread(value) {
74315
- return parseRecord(CommentThreadSchema, value);
74316
- }
74317
- //#endregion
74318
- //#region ../comments/src/lib/input.ts
74319
- /** A browser's comment request is invalid; its message is safe to show. */
74320
- var CommentInputError = class extends Error {};
74321
- /**
74322
- * Validates a browser's request to start a conversation, or to reply to or update one.
74323
- * @param value - The request body.
74324
- * @param routes - The routes a new canvas conversation may belong to.
74325
- * @param id - The conversation being replied to or updated; absent for a new one.
74326
- * @returns The revision the request was based on and the change it asks for.
74327
- */
74328
- function parseCommentInput(value, routes, id) {
74329
- try {
74330
- let input = object$1(value);
74331
- let head = revision(input.head);
74332
- let body = input.body === void 0 ? void 0 : text$4(input.body, "Comment", 1e4).trim();
74333
- if (id !== void 0) {
74334
- conversationId(id);
74335
- let status = input.status === void 0 ? void 0 : commentStatus(input.status);
74336
- if (!body && !status) throw new Error("Add a reply or choose a status.");
74337
- let parentId = input.parentId == null ? null : conversationId(input.parentId);
74338
- if (parentId && !body) throw new Error("A reply needs a message.");
74339
- return {
74340
- head,
74341
- change: {
74342
- id,
74343
- body,
74344
- status,
74345
- ...input.parentId === void 0 ? {} : { parentId }
74346
- }
74347
- };
74348
- }
74349
- if (!body) throw new Error("Write a comment before saving.");
74350
- if (input.parentId != null) throw new Error("A new conversation cannot have a parent message.");
74351
- if (object$1(input.anchor).type === "code") return {
74352
- head,
74353
- change: {
74354
- anchor: parseCodeAnchor(input.anchor),
74355
- body
74356
- }
74357
- };
74358
- let anchor = parseCanvasAnchor(input.anchor);
74359
- if (!routes.some((route) => route.id === anchor.pageId && route.path === anchor.pagePath)) throw new Error("The comment must belong to a configured route.");
74360
- return {
74361
- head,
74362
- change: {
74363
- anchor,
74364
- body
74365
- }
74366
- };
74367
- } catch (error) {
74368
- throw new CommentInputError(error instanceof Error ? error.message : "Invalid comment.");
74369
- }
74370
- }
74371
- //#endregion
74372
- //#region ../comments/src/lib/merge.ts
74373
- /** Two versions of a thread conflict and need resolving in Git by hand. */
74374
- var CommentMergeError = class extends Error {};
74375
- /**
74376
- * Serializes a value as JSON with sorted object keys, so equal records compare equal.
74377
- * @param value - The value to serialize.
74378
- * @returns Its JSON text.
74379
- */
74380
- function stableJson(value) {
74381
- if (value === null || typeof value !== "object") return JSON.stringify(value);
74382
- if (Array.isArray(value)) return `[${value.map(stableJson).join(",")}]`;
74383
- return `{${Object.entries(value).sort(([a], [b]) => a.localeCompare(b)).map(([key, child]) => `${JSON.stringify(key)}:${stableJson(child)}`).join(",")}}`;
74384
- }
74385
- /**
74386
- * Merges two versions of one thread: their messages combine and a status change on one side wins.
74387
- * @param local - This checkout's version.
74388
- * @param remote - The fetched version.
74389
- * @param base - Their common ancestor, when there is one.
74390
- * @returns The merged thread, or throws a CommentMergeError when they conflict.
74391
- */
74392
- function mergeThreads(local, remote, base) {
74393
- local = parseCommentThread(local);
74394
- remote = parseCommentThread(remote);
74395
- if (base) base = parseCommentThread(base);
74396
- let { comments: localComments, status: localStatus, updatedAt: localTime, ...localIdentity } = local;
74397
- let { comments: remoteComments, status: remoteStatus, updatedAt: remoteTime, ...remoteIdentity } = remote;
74398
- let baseIdentity = base && {
74399
- version: base.version,
74400
- id: base.id,
74401
- project: base.project,
74402
- branch: base.branch,
74403
- createdCommit: base.createdCommit,
74404
- anchor: base.anchor,
74405
- createdAt: base.createdAt
74406
- };
74407
- if (stableJson(localIdentity) !== stableJson(remoteIdentity) || baseIdentity && stableJson(localIdentity) !== stableJson(baseIdentity)) throw new CommentMergeError("Conflicting thread anchors in the comments branch. Resolve this record in Git before syncing.");
74408
- if (stableJson(local) === stableJson(remote)) return local;
74409
- if (base && stableJson(local) === stableJson(base)) return remote;
74410
- if (base && stableJson(remote) === stableJson(base)) return local;
74411
- let comments = /* @__PURE__ */ new Map();
74412
- for (let comment of [...localComments, ...remoteComments]) {
74413
- if (comments.has(comment.id) && stableJson(comments.get(comment.id)) !== stableJson(comment)) throw new CommentMergeError("Conflicting versions of a comment. Resolve this record in Git before syncing.");
74414
- comments.set(comment.id, comment);
74415
- }
74416
- let status = localStatus === base?.status ? remoteStatus : remoteStatus === base?.status || localStatus === remoteStatus ? localStatus : void 0;
74417
- if (!status) throw new CommentMergeError("Conflicting thread statuses. Resolve this record in Git before syncing.");
74418
- return {
74419
- ...local,
74420
- status,
74421
- updatedAt: localTime > remoteTime ? localTime : remoteTime,
74422
- comments: [...comments.values()].sort((a, b) => a.createdAt.localeCompare(b.createdAt) || a.id.localeCompare(b.id))
74423
- };
74424
- }
74425
75113
  //#endregion
74426
75114
  //#region ../ui/src/lib/canvas/coordinates.ts
74427
75115
  /**
@@ -74888,23 +75576,13 @@ function CanvasWorkspace(handle) {
74888
75576
  if (zoomLabel) zoomLabel.textContent = `${Math.round(scale * 100)}%`;
74889
75577
  }
74890
75578
  }),
74891
- handle.props.error || handle.props.commentsUnavailable || notice ? /* @__PURE__ */ jsxs("div", {
74892
- role: handle.props.error ? "alert" : "status",
74893
- class: `absolute top-3 left-3 max-w-[calc(100%-24px)] bud-overlay rounded-lg px-3 py-2 ${handle.props.error ? "text-red-500" : "text-muted"}`,
74894
- children: [/* @__PURE__ */ jsx(Text, {
75579
+ handle.props.commentsUnavailable || notice ? /* @__PURE__ */ jsx("div", {
75580
+ role: "status",
75581
+ class: "absolute top-3 left-3 max-w-[calc(100%-24px)] bud-overlay rounded-lg px-3 py-2 text-muted",
75582
+ children: /* @__PURE__ */ jsx(Text, {
74895
75583
  variant: "ui-caption",
74896
- children: handle.props.error || handle.props.commentsUnavailable || notice
74897
- }), handle.props.error ? /* @__PURE__ */ jsx("button", {
74898
- type: "button",
74899
- class: "ml-2 underline",
74900
- mix: on("click", () => {
74901
- handle.props.onReload?.();
74902
- }),
74903
- children: /* @__PURE__ */ jsx(Text, {
74904
- variant: "ui-caption",
74905
- children: t$2("canvas.canvasWorkspace.reload")
74906
- })
74907
- }) : null]
75584
+ children: handle.props.commentsUnavailable || notice
75585
+ })
74908
75586
  }) : null,
74909
75587
  panel && !handle.props.commentsUnavailable ? /* @__PURE__ */ jsx(ConversationSidebar, {
74910
75588
  threads: handle.props.snapshot.threads,
@@ -75388,6 +76066,85 @@ function TaskEditor(handle) {
75388
76066
  };
75389
76067
  }
75390
76068
  //#endregion
76069
+ //#region ../ui/src/lib/tasks/task-run-badge.tsx
76070
+ /**
76071
+ * What a factory run's badge says: busy states with a spinner, then review, a question for a
76072
+ * person, pushed or failed.
76073
+ * @param run - The run's state and error.
76074
+ * @returns Its tone, label and whether it spins, or null for a run that leaves no badge.
76075
+ */
76076
+ function taskRunBadge(run) {
76077
+ switch (run.state) {
76078
+ case "provisioning": return {
76079
+ tone: "busy",
76080
+ label: t$2("tasks.taskRunBadge.settingUp")
76081
+ };
76082
+ case "working":
76083
+ case "changes": return {
76084
+ tone: "busy",
76085
+ label: t$2("tasks.taskRunBadge.working")
76086
+ };
76087
+ case "review": return {
76088
+ tone: "review",
76089
+ label: t$2("tasks.taskRunBadge.review")
76090
+ };
76091
+ case "needs_context": return {
76092
+ tone: "question",
76093
+ label: t$2("tasks.taskRunBadge.needsContext")
76094
+ };
76095
+ case "approved":
76096
+ case "pushing": return {
76097
+ tone: "busy",
76098
+ label: t$2("tasks.taskRunBadge.pushing")
76099
+ };
76100
+ case "pushed": return {
76101
+ tone: "done",
76102
+ label: t$2("tasks.taskRunBadge.pushed")
76103
+ };
76104
+ case "merged": return {
76105
+ tone: "done",
76106
+ label: t$2("tasks.taskRunBadge.merged")
76107
+ };
76108
+ case "failed": return {
76109
+ tone: "failed",
76110
+ label: t$2("tasks.taskRunBadge.failed")
76111
+ };
76112
+ default: return null;
76113
+ }
76114
+ }
76115
+ var tones = {
76116
+ busy: "text-muted",
76117
+ review: "text-amber-600 dark:text-amber-400",
76118
+ question: "text-violet-600 dark:text-violet-400",
76119
+ done: "text-emerald-600 dark:text-emerald-400",
76120
+ failed: "text-red-600 dark:text-red-400"
76121
+ };
76122
+ /**
76123
+ * A task card's factory run badge: where the agent's run is, with a failed run's reason on hover.
76124
+ * @param handle - The run's summary.
76125
+ * @returns The badge render function; nothing for a run that leaves no badge.
76126
+ */
76127
+ function TaskRunBadge(handle) {
76128
+ return () => {
76129
+ let badge = taskRunBadge(handle.props.run);
76130
+ if (!badge) return null;
76131
+ return /* @__PURE__ */ jsxs("span", {
76132
+ class: `flex min-w-0 items-center gap-1 ${tones[badge.tone]}`,
76133
+ title: handle.props.run.error ?? void 0,
76134
+ "data-testid": "task-run-badge",
76135
+ "data-state": handle.props.run.state,
76136
+ children: [badge.tone === "busy" ? /* @__PURE__ */ jsx(Spinner, { size: 11 }) : /* @__PURE__ */ jsx(Icon$1, {
76137
+ name: badge.tone === "failed" ? "circle-alert" : handle.props.run.state === "merged" ? "circle-check" : badge.tone === "done" ? "push" : badge.tone === "question" ? "message" : "circle-dot",
76138
+ size: 12
76139
+ }), /* @__PURE__ */ jsx(Text, {
76140
+ variant: "ui-caption",
76141
+ class: "truncate",
76142
+ children: badge.label
76143
+ })]
76144
+ });
76145
+ };
76146
+ }
76147
+ //#endregion
75391
76148
  //#region ../ui/src/lib/tasks/task-card.tsx
75392
76149
  var statusTone = {
75393
76150
  backlog: "bg-violet-400",
@@ -75427,7 +76184,8 @@ function TaskCard(handle) {
75427
76184
  let issue = taskFields(item, schema);
75428
76185
  let linked = issue.dependencyCount ?? issue.dependencies.length;
75429
76186
  let dependents = issue.dependentCount ?? issue.dependents.length;
75430
- let hasMeta = ready || blocked || !!issue.assignee || !!issue.parentId || !!linked || !!dependents || !!issue.commentCount;
76187
+ let run = item.run && taskRunBadge(item.run) ? item.run : null;
76188
+ let hasMeta = !!run || ready || blocked || !!issue.assignee || !!issue.parentId || !!linked || !!dependents || !!issue.commentCount;
75431
76189
  let priority = /* @__PURE__ */ jsx(Text, {
75432
76190
  variant: "ui-caption",
75433
76191
  weight: "medium",
@@ -75436,6 +76194,7 @@ function TaskCard(handle) {
75436
76194
  children: typeof issue.priority === "number" ? `P${issue.priority}` : issue.priorityLabel
75437
76195
  });
75438
76196
  let meta = /* @__PURE__ */ jsxs(Fragment, { children: [
76197
+ run ? /* @__PURE__ */ jsx(TaskRunBadge, { run }) : null,
75439
76198
  ready ? /* @__PURE__ */ jsxs("span", {
75440
76199
  class: "flex items-center gap-1 text-emerald-600 dark:text-emerald-400",
75441
76200
  children: [/* @__PURE__ */ jsx(Icon$1, {
@@ -91112,6 +91871,7 @@ function TaskDetails(handle) {
91112
91871
  ]
91113
91872
  }),
91114
91873
  children: [
91874
+ handle.props.actions ?? null,
91115
91875
  /* @__PURE__ */ jsx(IconButton, {
91116
91876
  icon: "link",
91117
91877
  label: t$2("tasks.taskDetails.copyTaskLink"),
@@ -91137,13 +91897,13 @@ function TaskDetails(handle) {
91137
91897
  }),
91138
91898
  /* @__PURE__ */ jsxs("div", {
91139
91899
  "data-task-detail-scroll": "",
91140
- class: "flex min-h-0 flex-1 flex-col overflow-y-auto overscroll-contain",
91900
+ class: "@container/page flex min-h-0 flex-1 flex-col overflow-y-auto overscroll-contain",
91141
91901
  "aria-busy": loading ? "true" : "false",
91142
91902
  mix: scrollFade("y"),
91143
91903
  children: [
91144
91904
  loading && !issue ? /* @__PURE__ */ jsx(Loader, { label: t$2("tasks.taskDetails.loadingTask") }) : null,
91145
91905
  error ? /* @__PURE__ */ jsx("div", {
91146
- class: "px-4 pb-6 md:px-6",
91906
+ class: "px-4 pb-6 @min-[40rem]/page:px-6",
91147
91907
  children: /* @__PURE__ */ jsxs(FieldCard, {
91148
91908
  class: "max-w-2xl",
91149
91909
  role: "alert",
@@ -91158,7 +91918,7 @@ function TaskDetails(handle) {
91158
91918
  })
91159
91919
  }) : null,
91160
91920
  issue && item && detail ? /* @__PURE__ */ jsxs("div", {
91161
- class: "mx-auto grid w-full max-w-6xl gap-8 px-4 pt-6 pb-12 md:px-6 lg:grid-cols-[minmax(0,1fr)_18rem] lg:gap-12",
91921
+ class: "mx-auto grid w-full max-w-6xl gap-8 px-4 pt-6 pb-12 @min-[40rem]/page:px-6 @min-[56rem]/page:grid-cols-[minmax(0,1fr)_18rem] @min-[56rem]/page:gap-12",
91162
91922
  children: [/* @__PURE__ */ jsxs("article", {
91163
91923
  class: "flex min-w-0 flex-col gap-8",
91164
91924
  children: [
@@ -91280,7 +92040,7 @@ function TaskDetails(handle) {
91280
92040
  })
91281
92041
  ]
91282
92042
  }), /* @__PURE__ */ jsxs("aside", {
91283
- class: "flex min-w-0 flex-col gap-4 lg:sticky lg:top-6 lg:self-start",
92043
+ class: "flex min-w-0 flex-col gap-4 @min-[56rem]/page:sticky @min-[56rem]/page:top-6 @min-[56rem]/page:self-start",
91284
92044
  children: [/* @__PURE__ */ jsx(Properties, {
91285
92045
  ...context,
91286
92046
  item,
@@ -91465,6 +92225,8 @@ function TaskWorkspace(handle) {
91465
92225
  }
91466
92226
  return draft;
91467
92227
  }
92228
+ let expanded = /* @__PURE__ */ new Set();
92229
+ let allColumns = false;
91468
92230
  async function move(id, status) {
91469
92231
  let issue = handle.props.snapshot?.items.find((candidate) => candidate.id === id);
91470
92232
  if (!issue || !handle.props.operations || actionBusy || !handle.props.schema || taskRole(issue, handle.props.schema, "status") === status) return;
@@ -91557,7 +92319,12 @@ function TaskWorkspace(handle) {
91557
92319
  restore = null;
91558
92320
  handle.queueTask(() => scroll?.scrollTo(position));
91559
92321
  }
91560
- let statuses = schema ? taskStatuses(schema, snapshot?.items) : [];
92322
+ let allStatuses = schema ? taskStatuses(schema, snapshot?.items) : [];
92323
+ let columns = handle.props.columns;
92324
+ let arranged = columns ? [...columns.shown, ...columns.collapsed ?? []].flatMap((value) => allStatuses.filter((status) => status.value === value)) : allStatuses;
92325
+ let statuses = columns && !allColumns && !view.status ? arranged : allStatuses;
92326
+ let hiddenStatuses = allStatuses.filter((status) => !arranged.includes(status));
92327
+ let hiddenTasks = (snapshot?.items ?? []).filter((item) => hiddenStatuses.some((status) => status.value === taskRole(item, schema, "status"))).length;
91561
92328
  let ready = new Set(snapshot?.items.filter((item) => item.ready).map((item) => item.id) ?? []);
91562
92329
  let activeFilters = [
91563
92330
  view.status,
@@ -92047,12 +92814,13 @@ function TaskWorkspace(handle) {
92047
92814
  class: "flex w-full min-w-0 flex-col gap-px p-1",
92048
92815
  children: group.issues.map(renderCard)
92049
92816
  })
92050
- })] }) : /* @__PURE__ */ jsx("div", {
92817
+ })] }) : /* @__PURE__ */ jsxs("div", {
92051
92818
  class: "flex items-start gap-3",
92052
- children: statuses.filter((status) => !view.status || view.status === status.value).map((status) => {
92819
+ children: [statuses.filter((status) => !view.status || view.status === status.value).map((status) => {
92053
92820
  let issues = group.issues.filter((issue) => taskRole(issue, schema, "status") === status.value);
92821
+ let collapsedColumn = !!columns?.collapsed?.includes(status.value) && !expanded.has(status.value) && issues.length > 0;
92054
92822
  return /* @__PURE__ */ jsx("section", {
92055
- class: `flex flex-col gap-2 ${issues.length ? "min-w-60 max-w-sm flex-1 basis-0" : "w-32 shrink-0"}`,
92823
+ class: `flex flex-col gap-2 ${issues.length && !collapsedColumn ? "min-w-60 max-w-sm flex-1 basis-0" : "w-max min-w-32 max-w-48 shrink-0"}`,
92056
92824
  "aria-label": t$2("tasks.taskWorkspace.statusColumn", { status: status.label }),
92057
92825
  mix: [on("dragover", (event) => {
92058
92826
  if (event.dataTransfer?.types.includes("application/x-bud-task") && !actionBusy && status.value) {
@@ -92071,10 +92839,29 @@ function TaskWorkspace(handle) {
92071
92839
  item: null,
92072
92840
  status,
92073
92841
  items: issues,
92074
- children: issues.map(renderCard)
92842
+ children: collapsedColumn ? /* @__PURE__ */ jsx(Button, {
92843
+ variant: "ghost",
92844
+ size: "small",
92845
+ class: "justify-start",
92846
+ mix: on("click", () => {
92847
+ expanded.add(status.value);
92848
+ handle.update();
92849
+ }),
92850
+ children: t$2("tasks.taskWorkspace.showTasks", { count: issues.length })
92851
+ }) : issues.map(renderCard)
92075
92852
  })
92076
92853
  }, status.value);
92077
- })
92854
+ }), columns && !view.status && (hiddenStatuses.length || allColumns) ? /* @__PURE__ */ jsx(Button, {
92855
+ variant: "ghost",
92856
+ size: "small",
92857
+ class: "mt-1 shrink-0",
92858
+ "data-testid": "board-other-statuses",
92859
+ mix: on("click", () => {
92860
+ allColumns = !allColumns;
92861
+ handle.update();
92862
+ }),
92863
+ children: allColumns ? t$2("tasks.taskWorkspace.fewerStatuses") : hiddenTasks ? t$2("tasks.taskWorkspace.otherStatuses", { count: hiddenTasks }) : t$2("tasks.taskWorkspace.otherStatusesEmpty")
92864
+ }) : null]
92078
92865
  })]
92079
92866
  }, group.id)) : null
92080
92867
  ]
@@ -92106,7 +92893,7 @@ function TaskWorkspace(handle) {
92106
92893
  }
92107
92894
  })
92108
92895
  }) : null,
92109
- selectedId && schema ? /* @__PURE__ */ createElement(Page, {
92896
+ selectedId && schema ? (handle.props.pageFrame ?? ((page) => page))(/* @__PURE__ */ createElement(Page, {
92110
92897
  ...context(detail?.item.id === selectedId ? detail.item : null),
92111
92898
  item: detail?.item.id === selectedId ? detail.item : null,
92112
92899
  design: handle.props.design,
@@ -92123,10 +92910,876 @@ function TaskWorkspace(handle) {
92123
92910
  loading: detailLoading,
92124
92911
  error: detailError,
92125
92912
  onSelect: select,
92126
- onReload: onReloadDetail
92913
+ onReload: onReloadDetail,
92914
+ actions: handle.props.pageActions
92915
+ })) : null
92916
+ ] })
92917
+ });
92918
+ };
92919
+ }
92920
+ //#endregion
92921
+ //#region ../ui/src/lib/tasks/agent-terminal.tsx
92922
+ function Session(handle) {
92923
+ let state = "connecting";
92924
+ let term = null;
92925
+ let mount = ref((node, signal) => {
92926
+ (async () => {
92927
+ let { WTerm } = await import("./dist-BCSTeNf4.js");
92928
+ if (signal.aborted) return;
92929
+ let connection = null;
92930
+ let size = {
92931
+ cols: 0,
92932
+ rows: 0
92933
+ };
92934
+ let resizing;
92935
+ let pending = [];
92936
+ let instance = new WTerm(node, {
92937
+ cursorBlink: true,
92938
+ renderingPaused: !handle.props.active,
92939
+ onData: (data) => connection ? connection.input(data) : pending.push(data),
92940
+ onResize: (cols, rows) => {
92941
+ clearTimeout(resizing);
92942
+ resizing = setTimeout(() => {
92943
+ if (cols === size.cols && rows === size.rows) return;
92944
+ size = {
92945
+ cols,
92946
+ rows
92947
+ };
92948
+ connection?.resize(cols, rows);
92949
+ }, 150);
92950
+ }
92951
+ });
92952
+ await instance.init();
92953
+ if (signal.aborted) return instance.destroy();
92954
+ requestAnimationFrame(() => {
92955
+ if (!signal.aborted) instance.fit();
92956
+ });
92957
+ document.fonts?.ready.then(() => {
92958
+ if (!signal.aborted) instance.fit();
92959
+ });
92960
+ term = instance;
92961
+ signal.addEventListener("abort", () => instance.destroy(), { once: true });
92962
+ size = {
92963
+ cols: instance.cols,
92964
+ rows: instance.rows
92965
+ };
92966
+ connection = handle.props.connect(handle.props.tab.id, size, {
92967
+ write: (bytes) => instance.write(bytes),
92968
+ state: (next) => {
92969
+ state = next;
92970
+ if (!signal.aborted) handle.update();
92971
+ }
92972
+ }, signal);
92973
+ for (let data of pending.splice(0)) connection.input(data);
92974
+ if (handle.props.active) instance.focus();
92975
+ })();
92976
+ });
92977
+ let shown = false;
92978
+ return () => {
92979
+ let { active, tab } = handle.props;
92980
+ if (active !== shown) {
92981
+ shown = active;
92982
+ term?.setRenderingPaused(!active);
92983
+ if (active) handle.queueTask(() => {
92984
+ term?.fit();
92985
+ term?.focus();
92986
+ });
92987
+ }
92988
+ return /* @__PURE__ */ jsxs("div", {
92989
+ class: `absolute inset-0 ${active ? "" : "invisible"}`,
92990
+ "aria-hidden": active ? void 0 : "true",
92991
+ inert: active ? void 0 : true,
92992
+ "data-terminal-tab": tab.id,
92993
+ "data-terminal-state": state,
92994
+ children: [/* @__PURE__ */ jsx("div", {
92995
+ class: "bud-terminal absolute inset-0 overflow-hidden",
92996
+ "aria-label": t$2("tasks.agentTerminal.terminal", { name: tab.label }),
92997
+ mix: mount
92998
+ }), state === "closed" ? /* @__PURE__ */ jsx(Text, {
92999
+ variant: "ui-caption",
93000
+ tone: "muted",
93001
+ class: "bud-overlay pointer-events-none absolute right-3 bottom-3 rounded-lg px-2.5 py-1",
93002
+ children: t$2("tasks.agentTerminal.disconnected")
93003
+ }) : null]
93004
+ });
93005
+ };
93006
+ }
93007
+ /**
93008
+ * The terminal in Agent view, on @wterm/dom: one session per tab, kept while another tab shows so
93009
+ * its output stays, connected through the app's broker.
93010
+ * @param handle - The tabs, the shown one and how to connect a tab.
93011
+ * @returns The terminal's render function.
93012
+ */
93013
+ function AgentTerminal(handle) {
93014
+ let opened = /* @__PURE__ */ new Set();
93015
+ return () => {
93016
+ let { tabs, active, connect } = handle.props;
93017
+ opened.add(active);
93018
+ return /* @__PURE__ */ jsx("div", {
93019
+ class: "absolute inset-0",
93020
+ "data-testid": "agent-terminal",
93021
+ children: tabs.filter((tab) => opened.has(tab.id)).map((tab) => /* @__PURE__ */ jsx(Session, {
93022
+ tab,
93023
+ connect,
93024
+ active: tab.id === active
93025
+ }, tab.id))
93026
+ });
93027
+ };
93028
+ }
93029
+ //#endregion
93030
+ //#region ../ui/src/lib/tasks/agent-view.tsx
93031
+ var LAYOUT = "bud:agent-view";
93032
+ /**
93033
+ * Reads the person's Agent view layout.
93034
+ * @param value - The stored preference.
93035
+ * @returns The layout, with the terminal shown beside the browser by default.
93036
+ */
93037
+ function agentLayout(value) {
93038
+ let input = value ?? {};
93039
+ return {
93040
+ terminal: input.terminal !== false,
93041
+ placement: input.placement === "below" ? "below" : "right"
93042
+ };
93043
+ }
93044
+ function Segments(handle) {
93045
+ return () => /* @__PURE__ */ jsx("div", {
93046
+ role: "group",
93047
+ "aria-label": handle.props.label,
93048
+ class: `bud-segmented ${handle.props.class ?? ""}`,
93049
+ children: handle.props.options.map((option) => /* @__PURE__ */ jsxs("button", {
93050
+ type: "button",
93051
+ "aria-pressed": handle.props.value === option.id ? "true" : "false",
93052
+ "data-agent-pane": option.id,
93053
+ mix: on("click", () => handle.props.onChange(option.id)),
93054
+ children: [/* @__PURE__ */ jsx(Icon$1, {
93055
+ name: option.icon,
93056
+ size: 15
93057
+ }), /* @__PURE__ */ jsx(Text, {
93058
+ variant: "ui",
93059
+ class: "@max-[24rem]/agent:sr-only",
93060
+ children: option.label
93061
+ })]
93062
+ }, option.id))
93063
+ });
93064
+ }
93065
+ /**
93066
+ * Agent view: a task's details beside the browser on its run's preview and the terminal. It lays
93067
+ * itself out by the room it has (container queries), so it works in tabs and side panels too:
93068
+ * with little room a switch at the top picks details or the agent's panes, and in a narrow agent
93069
+ * column a switch in the browser's toolbar picks the browser or the terminal, unless the terminal
93070
+ * sits below the browser. The layout is remembered per person.
93071
+ * @param handle - The details, the browser and the terminal.
93072
+ * @returns The view's render function.
93073
+ */
93074
+ function AgentView(handle) {
93075
+ let layout = agentLayout(readPreference(LAYOUT));
93076
+ let panes = {
93077
+ main: "agent",
93078
+ agent: "browser"
93079
+ };
93080
+ let setLayout = (next) => {
93081
+ layout = {
93082
+ ...layout,
93083
+ ...next
93084
+ };
93085
+ writePreference(LAYOUT, layout);
93086
+ if (next.terminal) panes = {
93087
+ ...panes,
93088
+ agent: "terminal"
93089
+ };
93090
+ if (next.terminal === false) panes = {
93091
+ ...panes,
93092
+ agent: "browser"
93093
+ };
93094
+ handle.update();
93095
+ };
93096
+ let setPanes = (next) => {
93097
+ panes = {
93098
+ ...panes,
93099
+ ...next
93100
+ };
93101
+ handle.update();
93102
+ };
93103
+ return () => {
93104
+ let { details, browser, terminal } = handle.props;
93105
+ let shown = Boolean(terminal) && layout.terminal;
93106
+ let beside = shown && layout.placement === "right";
93107
+ let below = shown && layout.placement === "below";
93108
+ let switcher = beside ? /* @__PURE__ */ jsx(Segments, {
93109
+ label: t$2("tasks.agentView.agentPanes"),
93110
+ class: "@min-[52rem]/panes:hidden",
93111
+ value: panes.agent,
93112
+ options: [{
93113
+ id: "browser",
93114
+ label: t$2("tasks.agentView.browser"),
93115
+ icon: "browser"
93116
+ }, {
93117
+ id: "terminal",
93118
+ label: t$2("tasks.agentView.terminal"),
93119
+ icon: "terminal"
93120
+ }],
93121
+ onChange: (id) => setPanes({ agent: id })
93122
+ }) : null;
93123
+ let controls = terminal ? /* @__PURE__ */ jsxs(Fragment, { children: [shown ? /* @__PURE__ */ jsx(IconButton, {
93124
+ tooltip: true,
93125
+ class: "@max-[34rem]/panes:hidden",
93126
+ icon: layout.placement === "right" ? "panel-bottom" : "panel-right",
93127
+ label: layout.placement === "right" ? t$2("tasks.agentView.terminalBelow") : t$2("tasks.agentView.terminalBeside"),
93128
+ "data-testid": "agent-terminal-placement",
93129
+ mix: on("click", () => setLayout({ placement: layout.placement === "right" ? "below" : "right" }))
93130
+ }) : null, /* @__PURE__ */ jsx(IconButton, {
93131
+ tooltip: true,
93132
+ icon: "terminal",
93133
+ active: shown,
93134
+ label: shown ? t$2("tasks.agentView.hideTerminal") : t$2("tasks.agentView.showTerminal"),
93135
+ "data-testid": "agent-terminal-toggle",
93136
+ mix: on("click", () => setLayout({ terminal: !shown }))
93137
+ })] }) : null;
93138
+ let hideBrowser = beside && panes.agent === "terminal" ? "@max-[52rem]/panes:hidden" : "";
93139
+ let hideTerminal = beside && panes.agent === "browser" ? "@max-[52rem]/panes:hidden" : "";
93140
+ return /* @__PURE__ */ jsxs("div", {
93141
+ class: "@container/agent flex h-full min-h-0 flex-col",
93142
+ "data-testid": "agent-view",
93143
+ "data-terminal": shown ? layout.placement : "hidden",
93144
+ children: [/* @__PURE__ */ jsx("div", {
93145
+ class: "flex h-12 shrink-0 items-center gap-2 border-b border-line px-2 @min-[48rem]/agent:hidden",
93146
+ children: /* @__PURE__ */ jsx(Segments, {
93147
+ label: t$2("tasks.agentView.view"),
93148
+ value: panes.main,
93149
+ options: [{
93150
+ id: "details",
93151
+ label: t$2("tasks.agentView.details"),
93152
+ icon: "text"
93153
+ }, {
93154
+ id: "agent",
93155
+ label: terminal ? t$2("tasks.agentView.browserAndTerminal") : t$2("tasks.agentView.browser"),
93156
+ icon: "browser"
93157
+ }],
93158
+ onChange: (id) => setPanes({ main: id })
93159
+ })
93160
+ }), /* @__PURE__ */ jsxs("div", {
93161
+ class: "flex min-h-0 flex-1",
93162
+ children: [/* @__PURE__ */ jsx("div", {
93163
+ class: `flex min-h-0 w-full min-w-0 flex-col @min-[48rem]/agent:w-[clamp(20rem,34%,30rem)] @min-[48rem]/agent:shrink-0 @min-[48rem]/agent:border-e @min-[48rem]/agent:border-line ${panes.main === "agent" ? "@max-[48rem]/agent:hidden" : ""}`,
93164
+ "data-agent-region": "details",
93165
+ children: details
93166
+ }), /* @__PURE__ */ jsxs("div", {
93167
+ class: `@container/panes flex min-h-0 min-w-0 flex-1 bg-[var(--bud-editor)] ${below ? "flex-col" : ""} ${panes.main === "details" ? "@max-[48rem]/agent:hidden" : ""}`,
93168
+ "data-agent-region": "agent",
93169
+ children: [/* @__PURE__ */ jsxs("section", {
93170
+ "aria-label": t$2("tasks.agentView.browser"),
93171
+ class: `flex min-h-0 min-w-0 flex-col ${below ? "flex-[3]" : "flex-1"} ${hideBrowser}`,
93172
+ "data-agent-region": "browser",
93173
+ children: [
93174
+ /* @__PURE__ */ jsxs("div", {
93175
+ class: "bud-toolbar flex h-12 shrink-0 items-center gap-1.5 border-b border-line px-2",
93176
+ children: [
93177
+ switcher,
93178
+ /* @__PURE__ */ jsx("div", {
93179
+ class: "flex min-w-0 flex-1 items-center gap-1.5",
93180
+ children: browser.toolbar
93181
+ }),
93182
+ browser.actions,
93183
+ controls
93184
+ ]
93185
+ }),
93186
+ /* @__PURE__ */ jsx("div", {
93187
+ class: "relative min-h-0 flex-1",
93188
+ children: browser.content
93189
+ }),
93190
+ browser.status
93191
+ ]
93192
+ }), shown && terminal ? /* @__PURE__ */ jsxs("section", {
93193
+ "aria-label": t$2("tasks.agentView.terminal"),
93194
+ class: `flex min-h-0 min-w-0 flex-col bg-[var(--bud-editor)] ${below ? "flex-[2] border-t border-line" : "flex-1 @min-[52rem]/panes:max-w-[44rem] @min-[52rem]/panes:border-s @min-[52rem]/panes:border-line"} ${hideTerminal}`,
93195
+ "data-agent-region": "terminal",
93196
+ children: [/* @__PURE__ */ jsxs("div", {
93197
+ class: "bud-toolbar flex h-12 shrink-0 items-center gap-1.5 border-b border-line px-2",
93198
+ children: [
93199
+ beside ? /* @__PURE__ */ jsx("div", {
93200
+ class: "@min-[52rem]/panes:hidden",
93201
+ children: switcher
93202
+ }) : null,
93203
+ /* @__PURE__ */ jsx("div", {
93204
+ class: "flex min-w-0 flex-1 items-center overflow-x-auto [scrollbar-width:none]",
93205
+ children: terminal.tabs
93206
+ }),
93207
+ beside ? /* @__PURE__ */ jsx("div", {
93208
+ class: "flex items-center gap-1.5 @min-[52rem]/panes:hidden",
93209
+ children: controls
93210
+ }) : null
93211
+ ]
93212
+ }), /* @__PURE__ */ jsx("div", {
93213
+ class: "relative min-h-0 flex-1",
93214
+ children: terminal.content
93215
+ })]
93216
+ }) : null]
93217
+ })]
93218
+ })]
93219
+ });
93220
+ };
93221
+ }
93222
+ //#endregion
93223
+ //#region ../ui/src/lib/tasks/agent-browser.tsx
93224
+ /**
93225
+ * Agent view's browser on the run's live preview: a sandboxed frame on the preview's own origin,
93226
+ * never Bud's, followed through the dev bridge the project's pages carry, with back, forward,
93227
+ * reload and the address, and comments on picked elements that go to the agent as changes.
93228
+ * @param handle - The details, the preview, the terminal and their actions.
93229
+ * @returns The view's render function.
93230
+ */
93231
+ function AgentBrowser(handle) {
93232
+ let frame;
93233
+ let path = "/";
93234
+ let title = "";
93235
+ let src = null;
93236
+ let load = 0;
93237
+ let picking = null;
93238
+ let draft = null;
93239
+ let busy = false;
93240
+ let tab = null;
93241
+ let origin = () => {
93242
+ let preview = handle.props.preview;
93243
+ return preview.state === "ready" ? new URL(preview.url).origin : null;
93244
+ };
93245
+ let post = (type, data = {}) => {
93246
+ let target = origin();
93247
+ if (target) frame?.contentWindow?.postMessage({
93248
+ ...data,
93249
+ type
93250
+ }, target);
93251
+ };
93252
+ let update = () => {
93253
+ if (!handle.signal.aborted) handle.update();
93254
+ };
93255
+ let frameRef = ref((node, signal) => {
93256
+ frame = node;
93257
+ signal.addEventListener("abort", () => frame = void 0, { once: true });
93258
+ });
93259
+ let keepInside = ref((card, signal) => {
93260
+ let position = () => {
93261
+ if (!frame) return;
93262
+ card.style.setProperty("--pages-card-x", "0px");
93263
+ card.style.setProperty("--pages-card-y", "0px");
93264
+ let offset = canvasPopoverOffset(card.getBoundingClientRect(), frame.getBoundingClientRect());
93265
+ card.style.setProperty("--pages-card-x", `${offset.x}px`);
93266
+ card.style.setProperty("--pages-card-y", `${offset.y}px`);
93267
+ };
93268
+ let observer = new ResizeObserver(position);
93269
+ observer.observe(card);
93270
+ position();
93271
+ signal.addEventListener("abort", () => observer.disconnect(), { once: true });
93272
+ });
93273
+ let listen = ref((_node, signal) => {
93274
+ window.addEventListener("message", (event) => {
93275
+ if (!frame || event.source !== frame.contentWindow || event.origin !== origin()) return;
93276
+ let data = event.data;
93277
+ if (data?.type === "bud:location" && typeof data.path === "string") {
93278
+ path = data.path.startsWith("/") ? data.path.slice(0, 4096) : path;
93279
+ title = typeof data.title === "string" ? data.title.slice(0, 200) : "";
93280
+ update();
93281
+ } else if (data?.type === "bud:picked" && picking && data.id === picking) {
93282
+ picking = null;
93283
+ draft = readPagePick(data);
93284
+ update();
93285
+ }
93286
+ }, { signal });
93287
+ });
93288
+ let navigate = (to) => {
93289
+ let preview = handle.props.preview;
93290
+ if (preview.state !== "ready") return;
93291
+ let url = new URL(preview.url);
93292
+ let target = new URL(to, url);
93293
+ if (target.origin !== url.origin) return;
93294
+ for (let [key, value] of url.searchParams) if (!target.searchParams.has(key)) target.searchParams.set(key, value);
93295
+ src = target.href;
93296
+ load++;
93297
+ update();
93298
+ };
93299
+ return () => {
93300
+ let { preview, details, terminal, onComment } = handle.props;
93301
+ let ready = preview.state === "ready" ? preview : null;
93302
+ if (ready && src === null) src = ready.url;
93303
+ if (!ready) {
93304
+ src = null;
93305
+ picking = null;
93306
+ }
93307
+ let host = ready ? new URL(ready.url).host : "";
93308
+ let shownTab = terminal?.tabs.find((entry) => entry.id === tab)?.id ?? terminal?.tabs[0]?.id;
93309
+ let toolbar = /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
93310
+ class: "flex shrink-0 items-center gap-0.5",
93311
+ children: [
93312
+ /* @__PURE__ */ jsx(IconButton, {
93313
+ tooltip: true,
93314
+ class: "@max-[34rem]/panes:hidden",
93315
+ icon: "arrow-left",
93316
+ label: t$2("tasks.agentBrowser.back"),
93317
+ disabled: !ready,
93318
+ mix: on("click", () => post("bud:back"))
93319
+ }),
93320
+ /* @__PURE__ */ jsx(IconButton, {
93321
+ tooltip: true,
93322
+ class: "@max-[34rem]/panes:hidden",
93323
+ icon: "arrow-right",
93324
+ label: t$2("tasks.agentBrowser.forward"),
93325
+ disabled: !ready,
93326
+ mix: on("click", () => post("bud:forward"))
93327
+ }),
93328
+ /* @__PURE__ */ jsx(IconButton, {
93329
+ tooltip: true,
93330
+ icon: "sync",
93331
+ label: t$2("tasks.agentBrowser.reload"),
93332
+ disabled: !ready,
93333
+ mix: on("click", () => navigate(path))
93334
+ })
93335
+ ]
93336
+ }), /* @__PURE__ */ jsx("form", {
93337
+ class: "flex min-w-0 flex-1 @max-[34rem]/panes:hidden",
93338
+ mix: on("submit", (event) => {
93339
+ event.preventDefault();
93340
+ let input = event.currentTarget.elements.namedItem("address");
93341
+ navigate(input.value.trim() || "/");
93342
+ }),
93343
+ children: /* @__PURE__ */ jsxs("label", {
93344
+ class: "bud-control bud-field flex h-control min-w-0 flex-1 items-center gap-2 rounded-lg px-2.5 text-muted",
93345
+ children: [/* @__PURE__ */ jsx(Icon$1, {
93346
+ name: "globe",
93347
+ size: 14,
93348
+ class: "shrink-0"
93349
+ }), /* @__PURE__ */ jsx("input", {
93350
+ name: "address",
93351
+ "aria-label": t$2("tasks.agentBrowser.address"),
93352
+ class: "h-full min-w-0 flex-1 bg-transparent pb-0.5 text-sm/5 text-ink outline-none",
93353
+ spellcheck: false,
93354
+ autocomplete: "off",
93355
+ disabled: !ready,
93356
+ value: ready ? path : ""
93357
+ })]
93358
+ })
93359
+ })] });
93360
+ let actions = /* @__PURE__ */ jsxs(Fragment, { children: [onComment ? /* @__PURE__ */ jsx(IconButton, {
93361
+ tooltip: true,
93362
+ icon: "crosshair",
93363
+ label: t$2("tasks.agentBrowser.commentOnElement"),
93364
+ active: Boolean(picking),
93365
+ disabled: !ready,
93366
+ "data-testid": "agent-browser-pick",
93367
+ mix: on("click", () => {
93368
+ if (picking) {
93369
+ post("bud:pick-cancel");
93370
+ picking = null;
93371
+ } else {
93372
+ draft = null;
93373
+ picking = crypto.randomUUID();
93374
+ post("bud:pick", { id: picking });
93375
+ }
93376
+ update();
93377
+ })
93378
+ }) : null, /* @__PURE__ */ jsx(IconButton, {
93379
+ tooltip: true,
93380
+ class: "@max-[34rem]/panes:hidden",
93381
+ icon: "external",
93382
+ label: t$2("tasks.agentBrowser.openInNewWindow"),
93383
+ disabled: !ready,
93384
+ mix: on("click", () => {
93385
+ if (src) window.open(src, "_blank", "noopener,noreferrer");
93386
+ })
93387
+ })] });
93388
+ let content = ready ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("iframe", {
93389
+ title: title || t$2("tasks.agentBrowser.preview"),
93390
+ src: src ?? ready.url,
93391
+ sandbox: "allow-scripts allow-same-origin allow-forms allow-popups allow-modals",
93392
+ referrerpolicy: "no-referrer",
93393
+ class: "absolute inset-0 size-full border-0 bg-white",
93394
+ "data-testid": "agent-browser-frame",
93395
+ mix: [frameRef, on("load", () => {
93396
+ post("bud:hello");
93397
+ if (picking) post("bud:pick", { id: picking });
93398
+ })]
93399
+ }, `${load}`), draft && onComment ? /* @__PURE__ */ jsx("div", {
93400
+ role: "dialog",
93401
+ "aria-label": t$2("tasks.agentBrowser.newComment"),
93402
+ class: `absolute z-10 ${draft.client ? "" : "top-3 right-3"}`,
93403
+ style: draft.client ? {
93404
+ left: `${draft.client.x}px`,
93405
+ top: `${draft.client.y}px`,
93406
+ transform: "translate(calc(12px + var(--pages-card-x, 0px)), calc(-8px + var(--pages-card-y, 0px)))"
93407
+ } : void 0,
93408
+ mix: [...draft.client ? [keepInside] : [], on("keydown", (event) => {
93409
+ if (event.key === "Escape") {
93410
+ draft = null;
93411
+ update();
93412
+ }
93413
+ })],
93414
+ children: /* @__PURE__ */ jsx(CommentComposerCard, {
93415
+ busy,
93416
+ heading: /* @__PURE__ */ jsxs("div", {
93417
+ class: "flex min-w-0 flex-col gap-1 px-1 pt-1",
93418
+ children: [/* @__PURE__ */ jsxs(Text, {
93419
+ variant: "ui-caption",
93420
+ tone: "muted",
93421
+ class: "truncate",
93422
+ children: [
93423
+ draft.path,
93424
+ " · ",
93425
+ draft.element?.label || draft.element?.tagName || ""
93426
+ ]
93427
+ }), draft.element?.source ? /* @__PURE__ */ jsx(ElementSourceLink, { source: draft.element.source }) : null]
93428
+ }),
93429
+ onCancel: () => {
93430
+ draft = null;
93431
+ update();
93432
+ },
93433
+ onSubmit: async (body) => {
93434
+ let pick = draft;
93435
+ busy = true;
93436
+ update();
93437
+ try {
93438
+ await onComment({
93439
+ body,
93440
+ path: pick.path,
93441
+ element: pick.element
93442
+ });
93443
+ draft = null;
93444
+ } finally {
93445
+ busy = false;
93446
+ update();
93447
+ }
93448
+ }
93449
+ })
93450
+ }, draft.client ? `${draft.client.x},${draft.client.y}` : "corner") : null] }) : /* @__PURE__ */ jsx("div", {
93451
+ class: "flex h-full flex-col items-center justify-center gap-3 p-6 text-center",
93452
+ children: preview.state === "waking" ? /* @__PURE__ */ jsx(Loader, { label: t$2("tasks.agentBrowser.waking") }) : /* @__PURE__ */ jsxs(Fragment, { children: [
93453
+ /* @__PURE__ */ jsx(Icon$1, {
93454
+ name: "browser",
93455
+ size: 20,
93456
+ class: "text-muted"
93457
+ }),
93458
+ /* @__PURE__ */ jsx(Text, {
93459
+ as: "p",
93460
+ variant: "ui",
93461
+ tone: "muted",
93462
+ class: "max-w-xs text-balance",
93463
+ children: preview.state === "asleep" ? t$2("tasks.agentBrowser.asleep") : preview.state === "failed" ? preview.message : t$2("tasks.agentBrowser.noPreview")
93464
+ }),
93465
+ preview.state === "asleep" || preview.state === "failed" ? /* @__PURE__ */ jsx(Button, {
93466
+ variant: "secondary",
93467
+ size: "small",
93468
+ "data-testid": "agent-browser-wake",
93469
+ mix: on("click", handle.props.onWake),
93470
+ children: preview.state === "asleep" ? t$2("tasks.agentBrowser.wake") : t$2("tasks.agentBrowser.tryAgain")
92127
93471
  }) : null
92128
93472
  ] })
92129
93473
  });
93474
+ let status = /* @__PURE__ */ jsxs("footer", {
93475
+ class: "flex h-9 shrink-0 items-center gap-3 overflow-hidden whitespace-nowrap border-t border-line ps-3 pe-2 text-muted",
93476
+ "aria-label": t$2("tasks.agentBrowser.status"),
93477
+ children: [/* @__PURE__ */ jsx(Text, {
93478
+ variant: "ui-caption",
93479
+ class: "truncate",
93480
+ children: ready ? title || path : ""
93481
+ }), /* @__PURE__ */ jsx(Text, {
93482
+ variant: "ui-caption",
93483
+ class: "ms-auto truncate",
93484
+ children: host
93485
+ })]
93486
+ });
93487
+ return /* @__PURE__ */ jsx("div", {
93488
+ class: "h-full min-h-0",
93489
+ mix: listen,
93490
+ children: /* @__PURE__ */ jsx(AgentView, {
93491
+ details,
93492
+ browser: {
93493
+ toolbar,
93494
+ actions,
93495
+ content,
93496
+ status
93497
+ },
93498
+ terminal: terminal ? {
93499
+ tabs: /* @__PURE__ */ jsx("div", {
93500
+ class: "bud-segmented",
93501
+ role: "group",
93502
+ "aria-label": t$2("tasks.agentTerminal.sessions"),
93503
+ children: terminal.tabs.map((entry) => /* @__PURE__ */ jsx("button", {
93504
+ type: "button",
93505
+ "aria-pressed": entry.id === shownTab ? "true" : "false",
93506
+ "data-terminal-select": entry.id,
93507
+ mix: on("click", () => {
93508
+ tab = entry.id;
93509
+ update();
93510
+ }),
93511
+ children: /* @__PURE__ */ jsx(Text, {
93512
+ variant: "ui",
93513
+ children: entry.label
93514
+ })
93515
+ }, entry.id))
93516
+ }),
93517
+ content: /* @__PURE__ */ jsx(AgentTerminal, {
93518
+ tabs: terminal.tabs,
93519
+ active: shownTab,
93520
+ connect: terminal.connect
93521
+ })
93522
+ } : null
93523
+ })
93524
+ });
93525
+ };
93526
+ }
93527
+ //#endregion
93528
+ //#region ../ui/src/lib/tasks/task-run-panel.tsx
93529
+ function elapsed(from, now) {
93530
+ let seconds = Math.max(0, Math.round((now - Date.parse(from)) / 1e3));
93531
+ if (seconds < 60) return t$2("tasks.taskRunPanel.seconds", { count: seconds });
93532
+ return t$2("tasks.taskRunPanel.minutes", { count: Math.round(seconds / 60) });
93533
+ }
93534
+ /**
93535
+ * The factory's run on a task, above its discussion: Start task, the agent's progress, its summary
93536
+ * with Request changes, Approve & push and Discard, a failure with Retry, and the pushed branch.
93537
+ * @param handle - The run, whether it can start, and the actions.
93538
+ * @returns The panel render function.
93539
+ */
93540
+ function TaskRunPanel(handle) {
93541
+ let acting = null;
93542
+ let confirming = null;
93543
+ let requesting = false;
93544
+ function update() {
93545
+ if (!handle.signal.aborted) handle.update();
93546
+ }
93547
+ async function act(name, action) {
93548
+ if (acting) return;
93549
+ acting = name;
93550
+ update();
93551
+ try {
93552
+ await action();
93553
+ } catch {} finally {
93554
+ acting = null;
93555
+ confirming = null;
93556
+ update();
93557
+ }
93558
+ }
93559
+ let button = (name, label, action, variant = "secondary") => /* @__PURE__ */ jsxs(Button, {
93560
+ variant,
93561
+ size: "small",
93562
+ disabled: acting !== null,
93563
+ "data-testid": `run-${name}`,
93564
+ mix: on("click", () => void act(name, action)),
93565
+ children: [acting === name ? /* @__PURE__ */ jsx(Spinner, { size: 12 }) : null, label]
93566
+ });
93567
+ let confirm = (kind, question, label) => /* @__PURE__ */ jsxs("div", {
93568
+ class: "flex min-w-0 flex-wrap items-center gap-2",
93569
+ role: "group",
93570
+ "aria-label": question,
93571
+ "data-testid": `run-confirm-${kind}`,
93572
+ children: [
93573
+ /* @__PURE__ */ jsx(Text, {
93574
+ variant: "ui-caption",
93575
+ tone: "muted",
93576
+ class: "me-auto",
93577
+ children: question
93578
+ }),
93579
+ /* @__PURE__ */ jsx(Button, {
93580
+ variant: "ghost",
93581
+ size: "small",
93582
+ disabled: acting !== null,
93583
+ mix: on("click", () => {
93584
+ confirming = null;
93585
+ update();
93586
+ }),
93587
+ children: t$2("tasks.taskRunPanel.cancel")
93588
+ }),
93589
+ button(`${kind}-confirmed`, label, kind === "approve" ? handle.props.onApprove : handle.props.onDiscard, "primary")
93590
+ ]
93591
+ });
93592
+ let ask = (kind, label, variant) => /* @__PURE__ */ jsx(Button, {
93593
+ variant,
93594
+ size: "small",
93595
+ disabled: acting !== null,
93596
+ "data-testid": `run-${kind}`,
93597
+ mix: on("click", () => {
93598
+ confirming = kind;
93599
+ requesting = false;
93600
+ update();
93601
+ }),
93602
+ children: label
93603
+ });
93604
+ return () => {
93605
+ let { run, blocked, preview, now = Date.now() } = handle.props;
93606
+ let state = run?.state;
93607
+ let fresh = !run || state === "discarded";
93608
+ let working = state === "provisioning" || state === "working" || state === "changes" || state === "approved";
93609
+ let line = (icon, text, tone = "") => /* @__PURE__ */ jsxs("div", {
93610
+ class: `flex min-w-0 items-center gap-2 ${tone}`,
93611
+ "data-testid": "run-state",
93612
+ children: [
93613
+ icon,
93614
+ /* @__PURE__ */ jsx(Text, {
93615
+ variant: "ui",
93616
+ class: "min-w-0 [overflow-wrap:anywhere]",
93617
+ children: text
93618
+ }),
93619
+ run && working ? /* @__PURE__ */ jsx(Text, {
93620
+ variant: "ui-caption",
93621
+ tone: "muted",
93622
+ class: "ms-auto shrink-0 tabular-nums",
93623
+ children: elapsed(run.activity.findLast((entry) => entry.kind === "status")?.at ?? run.createdAt, now)
93624
+ }) : null
93625
+ ]
93626
+ });
93627
+ let activity = (run?.activity ?? []).filter((entry) => entry.kind !== "status").slice(-6);
93628
+ return /* @__PURE__ */ jsxs("section", {
93629
+ class: "flex min-w-0 flex-col gap-3",
93630
+ "aria-label": t$2("tasks.taskRunPanel.agent"),
93631
+ "data-testid": "task-run-panel",
93632
+ "data-state": state ?? (run === null ? "none" : "loading"),
93633
+ children: [/* @__PURE__ */ jsxs("div", {
93634
+ class: "flex items-center gap-2",
93635
+ children: [/* @__PURE__ */ jsx(Text, {
93636
+ as: "h3",
93637
+ variant: "ui",
93638
+ weight: "medium",
93639
+ children: t$2("tasks.taskRunPanel.agent")
93640
+ }), run && !fresh ? /* @__PURE__ */ jsx(Text, {
93641
+ variant: "ui-caption",
93642
+ tone: "muted",
93643
+ class: "min-w-0 truncate font-mono",
93644
+ children: run.branch
93645
+ }) : null]
93646
+ }), /* @__PURE__ */ jsx("div", {
93647
+ class: "flex min-w-0 flex-col gap-3 rounded-lg bg-[var(--bud-card)] p-3 ring-1 ring-[var(--bud-card-border)]",
93648
+ children: run === void 0 ? line(/* @__PURE__ */ jsx(Spinner, { size: 14 }), t$2("tasks.taskRunPanel.loading"), "text-muted") : fresh ? /* @__PURE__ */ jsxs("div", {
93649
+ class: "flex min-w-0 flex-wrap items-center gap-3",
93650
+ children: [/* @__PURE__ */ jsx(Text, {
93651
+ variant: "ui-caption",
93652
+ tone: "muted",
93653
+ class: "min-w-0 flex-1",
93654
+ children: blocked ?? t$2("tasks.taskRunPanel.startHint")
93655
+ }), blocked ? null : button("start", t$2("tasks.taskRunPanel.start"), handle.props.onStart, "primary")]
93656
+ }) : /* @__PURE__ */ jsxs(Fragment, { children: [
93657
+ state === "provisioning" ? line(/* @__PURE__ */ jsx(Spinner, { size: 14 }), t$2("tasks.taskRunPanel.settingUp")) : state === "working" || state === "changes" ? line(/* @__PURE__ */ jsx(Spinner, { size: 14 }), t$2("tasks.taskRunPanel.working")) : state === "approved" || state === "pushing" ? line(/* @__PURE__ */ jsx(Spinner, { size: 14 }), t$2("tasks.taskRunPanel.pushing", { branch: run.branch })) : state === "review" ? line(/* @__PURE__ */ jsx(Icon$1, {
93658
+ name: "circle-dot",
93659
+ size: 14
93660
+ }), t$2("tasks.taskRunPanel.review"), "text-amber-600 dark:text-amber-400") : state === "needs_context" ? line(/* @__PURE__ */ jsx(Icon$1, {
93661
+ name: "message",
93662
+ size: 14
93663
+ }), t$2("tasks.taskRunPanel.needsContext"), "text-violet-600 dark:text-violet-400") : state === "merged" ? line(/* @__PURE__ */ jsx(Icon$1, {
93664
+ name: "circle-check",
93665
+ size: 14
93666
+ }), t$2("tasks.taskRunPanel.merged", { branch: run.branch }), "text-emerald-600 dark:text-emerald-400") : state === "pushed" ? line(/* @__PURE__ */ jsx(Icon$1, {
93667
+ name: "push",
93668
+ size: 14
93669
+ }), t$2("tasks.taskRunPanel.pushed", {
93670
+ branch: run.branch,
93671
+ commit: (run.pushed ?? "").slice(0, 7)
93672
+ }), "text-emerald-600 dark:text-emerald-400") : line(/* @__PURE__ */ jsx(Icon$1, {
93673
+ name: "circle-alert",
93674
+ size: 14
93675
+ }), run.error?.message ?? t$2("tasks.taskRunPanel.failed"), "text-red-600 dark:text-red-400"),
93676
+ run.asleep && (state === "review" || state === "needs_context" || state === "failed") ? /* @__PURE__ */ jsxs("div", {
93677
+ class: "flex min-w-0 items-center gap-2 text-muted",
93678
+ "data-testid": "run-asleep",
93679
+ children: [/* @__PURE__ */ jsx(Icon$1, {
93680
+ name: "moon",
93681
+ size: 13,
93682
+ class: "shrink-0"
93683
+ }), /* @__PURE__ */ jsx(Text, {
93684
+ variant: "ui-caption",
93685
+ tone: "muted",
93686
+ class: "min-w-0",
93687
+ children: t$2("tasks.taskRunPanel.asleep")
93688
+ })]
93689
+ }) : null,
93690
+ state === "needs_context" && run.question ? /* @__PURE__ */ jsx("div", {
93691
+ class: "min-w-0 rounded-md bg-[var(--bud-control)] px-3 py-2",
93692
+ "data-testid": "run-question",
93693
+ children: /* @__PURE__ */ jsx(TaskMarkdown, { children: run.question })
93694
+ }) : null,
93695
+ state === "review" && run.summary ? /* @__PURE__ */ jsx("div", {
93696
+ class: "min-w-0",
93697
+ "data-testid": "run-summary",
93698
+ children: /* @__PURE__ */ jsx(TaskMarkdown, { children: run.summary })
93699
+ }) : null,
93700
+ activity.length && state !== "pushed" && state !== "merged" ? /* @__PURE__ */ jsx("ol", {
93701
+ class: "flex min-w-0 flex-col gap-1",
93702
+ "aria-label": t$2("tasks.taskRunPanel.activity"),
93703
+ children: activity.map((entry, index) => /* @__PURE__ */ jsxs("li", {
93704
+ class: "flex min-w-0 items-baseline gap-2",
93705
+ children: [/* @__PURE__ */ jsx(Icon$1, {
93706
+ name: entry.kind === "tool" ? "code" : entry.kind === "error" ? "warning" : "circle",
93707
+ size: 11,
93708
+ class: "shrink-0 translate-y-px text-muted"
93709
+ }), /* @__PURE__ */ jsx(Text, {
93710
+ variant: "ui-caption",
93711
+ tone: "muted",
93712
+ class: "min-w-0 truncate font-mono",
93713
+ children: entry.text
93714
+ })]
93715
+ }, `${entry.at}-${index}`))
93716
+ }) : null,
93717
+ confirming === "approve" ? confirm("approve", t$2("tasks.taskRunPanel.confirmApprove", { branch: run.branch }), t$2("tasks.taskRunPanel.approve")) : confirming === "discard" ? confirm("discard", t$2("tasks.taskRunPanel.confirmDiscard"), t$2("tasks.taskRunPanel.discard")) : state === "needs_context" && handle.props.onAnswer ? /* @__PURE__ */ jsxs("div", {
93718
+ class: "flex min-w-0 flex-col gap-2",
93719
+ children: [/* @__PURE__ */ jsx(CommentComposer, {
93720
+ label: t$2("tasks.taskRunPanel.answer"),
93721
+ placeholder: t$2("tasks.taskRunPanel.answerPlaceholder"),
93722
+ busy: acting !== null,
93723
+ onSubmit: async (message) => {
93724
+ await handle.props.onAnswer(message);
93725
+ }
93726
+ }), /* @__PURE__ */ jsx("span", {
93727
+ class: "ms-auto",
93728
+ children: ask("discard", t$2("tasks.taskRunPanel.discard"), "ghost")
93729
+ })]
93730
+ }) : requesting && state === "review" ? /* @__PURE__ */ jsx(CommentComposer, {
93731
+ label: t$2("tasks.taskRunPanel.requestChanges"),
93732
+ placeholder: t$2("tasks.taskRunPanel.changesPlaceholder"),
93733
+ autoFocus: true,
93734
+ busy: acting !== null,
93735
+ onSubmit: async (message) => {
93736
+ await handle.props.onChanges(message);
93737
+ requesting = false;
93738
+ update();
93739
+ },
93740
+ footer: /* @__PURE__ */ jsx(Button, {
93741
+ variant: "ghost",
93742
+ size: "small",
93743
+ mix: on("click", () => {
93744
+ requesting = false;
93745
+ update();
93746
+ }),
93747
+ children: t$2("tasks.taskRunPanel.cancel")
93748
+ })
93749
+ }) : /* @__PURE__ */ jsxs("div", {
93750
+ class: "flex min-w-0 flex-wrap items-center gap-2",
93751
+ children: [
93752
+ state === "review" ? ask("approve", t$2("tasks.taskRunPanel.approve"), "primary") : null,
93753
+ state === "review" ? /* @__PURE__ */ jsx(Button, {
93754
+ variant: "secondary",
93755
+ size: "small",
93756
+ disabled: acting !== null,
93757
+ "data-testid": "run-changes",
93758
+ mix: on("click", () => {
93759
+ requesting = true;
93760
+ update();
93761
+ }),
93762
+ children: t$2("tasks.taskRunPanel.requestChanges")
93763
+ }) : null,
93764
+ state === "failed" && run.error?.retryable && run.failedIn ? button("retry", t$2("tasks.taskRunPanel.retry"), handle.props.onRetry, "primary") : null,
93765
+ preview && (state === "working" || state === "changes" || state === "review" || state === "needs_context") ? button("preview", t$2("tasks.taskRunPanel.preview"), handle.props.onPreview) : null,
93766
+ state === "pushed" && handle.props.onCanvas ? /* @__PURE__ */ jsx(Button, {
93767
+ variant: "secondary",
93768
+ size: "small",
93769
+ "data-testid": "run-canvas",
93770
+ mix: on("click", () => handle.props.onCanvas?.()),
93771
+ children: t$2("tasks.taskRunPanel.showOnCanvas")
93772
+ }) : null,
93773
+ state === "pushed" || state === "merged" ? button("start", t$2("tasks.taskRunPanel.startAgain"), handle.props.onStart, "ghost") : null,
93774
+ state !== "pushed" && state !== "merged" && state !== "pushing" && state !== "approved" ? /* @__PURE__ */ jsx("span", {
93775
+ class: "ms-auto",
93776
+ children: ask("discard", t$2("tasks.taskRunPanel.discard"), "ghost")
93777
+ }) : null
93778
+ ]
93779
+ })
93780
+ ] })
93781
+ })]
93782
+ });
92130
93783
  };
92131
93784
  }
92132
93785
  //#endregion
@@ -97857,7 +99510,7 @@ function ItemDiscussion(handle) {
97857
99510
  */
97858
99511
  function ThreadTaskLinks(handle) {
97859
99512
  return () => {
97860
- let { itemIds, items, href, onEdit, busy } = handle.props;
99513
+ let { itemIds, items, href, onEdit, busy, schema, runs } = handle.props;
97861
99514
  if (!itemIds.length && !onEdit) return null;
97862
99515
  let names = new Map(items.map((item) => [item.id, item]));
97863
99516
  return /* @__PURE__ */ jsxs("div", {
@@ -97869,15 +99522,33 @@ function ThreadTaskLinks(handle) {
97869
99522
  href: href(id),
97870
99523
  title: item?.title ?? id,
97871
99524
  class: "bud-interaction bud-control inline-flex min-h-6 max-w-full items-center gap-1.5 rounded-md px-2 py-0.5",
97872
- children: [/* @__PURE__ */ jsx(Text, {
97873
- variant: "code",
97874
- class: "shrink-0",
97875
- children: id
97876
- }), item?.title ? /* @__PURE__ */ jsx(Text, {
97877
- variant: "ui-caption",
97878
- class: "truncate",
97879
- children: item.title
97880
- }) : null]
99525
+ children: [
99526
+ /* @__PURE__ */ jsx(Text, {
99527
+ variant: "code",
99528
+ class: "shrink-0",
99529
+ children: id
99530
+ }),
99531
+ item?.title ? /* @__PURE__ */ jsx(Text, {
99532
+ variant: "ui-caption",
99533
+ class: "truncate",
99534
+ children: item.title
99535
+ }) : null,
99536
+ item?.status && schema ? /* @__PURE__ */ jsxs("span", {
99537
+ class: "flex shrink-0 items-center gap-1 text-muted",
99538
+ "data-task-status": true,
99539
+ children: [/* @__PURE__ */ jsx(StatusDot, {
99540
+ status: item.status,
99541
+ schema
99542
+ }), /* @__PURE__ */ jsx(Text, {
99543
+ variant: "ui-caption",
99544
+ children: schema.statuses.find((status) => status.value === item.status)?.label ?? taskLabel(item.status)
99545
+ })]
99546
+ }) : null,
99547
+ runs?.[id] && taskRunBadge(runs[id]) ? /* @__PURE__ */ jsx("span", {
99548
+ class: "shrink-0",
99549
+ children: /* @__PURE__ */ jsx(TaskRunBadge, { run: runs[id] })
99550
+ }) : null
99551
+ ]
97881
99552
  }, id);
97882
99553
  }), onEdit ? /* @__PURE__ */ jsx(IconButton, {
97883
99554
  icon: "tasks",
@@ -98201,78 +99872,6 @@ function equal(left, right) {
98201
99872
  return JSON.stringify(left) === JSON.stringify(right);
98202
99873
  }
98203
99874
  //#endregion
98204
- //#region app/routes.ts
98205
- var routes = route({
98206
- screen: get("/(:screen)(/*rest)"),
98207
- screenModule: get("/__bud/screens/:name.js"),
98208
- logo: get("/__bud/logo/:theme"),
98209
- health: get("/health"),
98210
- conversation: conversationRoutes.show,
98211
- tasksApi: {
98212
- index: get("/api/tasks"),
98213
- schema: get("/api/tasks/schema"),
98214
- workspace: get("/api/tasks/workspace"),
98215
- show: get("/api/tasks/items/:id"),
98216
- section: get("/api/tasks/items/:id/sections/:section"),
98217
- create: post("/api/tasks"),
98218
- update: post("/api/tasks/items/:id"),
98219
- mutate: post("/api/tasks/items/:id/actions"),
98220
- sync: post("/api/tasks/sync")
98221
- },
98222
- filesApi: {
98223
- index: get("/api/files"),
98224
- entry: get("/api/files/entry"),
98225
- read: get("/api/files/read"),
98226
- refresh: post("/api/files/refresh")
98227
- },
98228
- fileSearchApi: { search: get("/api/files/search") },
98229
- fileReviewApi: {
98230
- repository: get("/api/files/repository"),
98231
- compare: get("/api/files/compare"),
98232
- diff: get("/api/files/diff"),
98233
- source: get("/api/files/source"),
98234
- history: get("/api/files/history")
98235
- },
98236
- fileMutationsApi: {
98237
- prepare: post("/api/files/mutations/prepare"),
98238
- apply: post("/api/files/mutations/apply"),
98239
- recoveries: get("/api/files/mutations/recoveries")
98240
- },
98241
- fileSavesApi: { save: post("/api/files/save") },
98242
- fileReviewActionsApi: {
98243
- prepare: post("/api/files/review-actions/prepare"),
98244
- apply: post("/api/files/review-actions/apply"),
98245
- recoveries: get("/api/files/review-actions/recoveries")
98246
- },
98247
- liveApi: { stream: get("/api/live") },
98248
- previewsApi: {
98249
- show: get("/api/previews/items/*id"),
98250
- image: get("/api/previews/images/:hash.jpg"),
98251
- refresh: post("/api/previews/refresh/*id"),
98252
- describe: post("/api/previews/describe/*id"),
98253
- locate: post("/api/previews/locate/*id")
98254
- },
98255
- branchesApi: {
98256
- list: get("/api/branches"),
98257
- activate: post("/api/branches/activate/*name"),
98258
- deactivate: post("/api/branches/deactivate/*name"),
98259
- capture: post("/api/branches/capture/*name")
98260
- },
98261
- comments: {
98262
- list: get("/api/comments"),
98263
- get: get("/api/comments/:id"),
98264
- create: post("/api/comments"),
98265
- update: post("/api/comments/:id"),
98266
- reply: post("/api/comments/:id/replies"),
98267
- status: post("/api/comments/:id/status"),
98268
- link: post("/api/comments/:id/links"),
98269
- unlink: post("/api/comments/:id/links/remove"),
98270
- deleteMessage: post("/api/comments/:id/messages/remove"),
98271
- sync: post("/api/comments/sync"),
98272
- viewer: get("/api/viewer")
98273
- }
98274
- });
98275
- //#endregion
98276
99875
  //#region ../live/src/lib/sse.ts
98277
99876
  /**
98278
99877
  * Reads Server-Sent Events from a response body, following the HTML event-stream format.
@@ -98496,6 +100095,11 @@ var endpoints = [
98496
100095
  write: true,
98497
100096
  list: false
98498
100097
  },
100098
+ {
100099
+ route: routes.comments.makeTask,
100100
+ write: true,
100101
+ list: false
100102
+ },
98499
100103
  {
98500
100104
  route: routes.comments.deleteMessage,
98501
100105
  write: true,
@@ -99129,4 +100733,4 @@ function unavailableComments(message = commentsUnavailable) {
99129
100733
  };
99130
100734
  }
99131
100735
  //#endregion
99132
- export { FileSearchPanel as $, markWorkerErrorReported as $n, valueByRole as $r, Button as $t, parseEditorPreferences as A, parseThread as An, parseFileSearchResult as Ar, defaultReviewView as At, TaskWorkspace as B, parseThreadStatusInput as Bn, parseWorkActivity as Br, fileHref as Bt, ThreadTaskLinks as C, parsePreviewViewport as Ci, predictThreadStatus as Cn, parseRecoveries as Cr, legacyConversationHref as Ct, ReviewActionDialog as D, parseWorkChange as Dn, parseReviewSnapshot as Dr, taskHref as Dt, FileConflictPanel as E, predictWorkUpdate as En, parseReviewRepository as Er, selectedTask as Et, FileWorkspace as F, parseThreadInput as Fn, MAX_CANVAS_Y as Fr, reviewComparison as Ft, mergeThreads as G, renderDiffWithHighlighter as Gn, parseWorkItemRef as Gr, fileRoutes as Gt, CanvasWorkspace as H, parseFileUpdate as Hn, parseWorkCreate as Hr, readFileLocation as Ht, defaultFileDestination as I, parseThreadLinkInput as In, parseElementAnchor as Ir, reviewContextKey as It, conversationId as J, areDiffTargetsEqual as Jn, parseWorkSnapshot as Jr, CommentThreadDetail as Jt, stableJson as K, areDiffRenderOptionsEqual as Kn, parseWorkMutationResult as Kr, pageRoutes as Kt, fileActionIntent as L, parseThreadReplyInput as Ln, parseWorkWorkspace as Lr, reviewHref as Lt, FileMutationDialog as M, parseThreadDeleteInput as Mn, parseFileDocument as Mr, parseReviewSession as Mt, FileReviewPanel as N, parseThreadFilter as Nn, parseFileIndex as Nr, readReviewLocation as Nt, FileEditorPanel as O, MAX_THREADS as On, parseReviewSource as Or, taskRole as Ot, codeThemes as P, parseThreadId as Pn, parseFilePath as Pr, rememberReviewPosition as Pt, text$4 as Q, isHandledWorkerPoolError as Qn, parseWorkValue as Qr, Spinner as Qt, mutationFileView as R, parseThreadSnapshot as Rn, parseSectionData as Rr, closeFileTab as Rt, writeRows as S, parsePreviewPins as Si, predictThreadReply as Sn, parseMutationResult as Sr, isCodeConversation as St, ItemDiscussion as T, predictWorkCreate as Tn, parseReviewHistory as Tr, readConversationLocation as Tt, captureCanvasPoint as U, reviewConflictIdentity as Un, parseWorkDetail as Ur, reconcileFileView as Ut, parseTaskDesign as V, createCodeAnchor as Vn, parseWorkConnection as Vr, parseFileView as Vt, CommentMergeError as W, isDiffPlainText as Wn, parseWorkItem as Wr, rememberFile as Wt, parseCommentThread as X, WorkerPoolTerminatedError as Xn, parseWorkSyncResult as Xr, CommentComposer as Xt, object$1 as Y, WorkerPoolTaskCanceledError as Yn, parseWorkSync as Yr, CommentThreadItem as Yt, revision as Z, WorkerPoolWorkerError as Zn, parseWorkUpdate as Zr, Loader as Zt, requestComments as _, parsePreview as _i, Icon$1 as _n, parseReviewActionResult as _r, PagesWorkspace as _t, saveThreads as a, fieldByRole as ai, LiveStatus as an, getSharedHighlighter as ar, FieldCardHeader as at, plainRow as b, parsePreviewHash as bi, predictThreadCreate as bn, maxFileSaveBytes as br, conversationHref as bt, previewKey as c, WorkValidationError as ci, toast as cn, attachResolvedThemes as cr, initialShellTabs as ct, saveWorkspace as d, parseWork as di, hasMessage as dn, getResolvedOrResolveLanguage as dr, readTabsCookie as dt, messageDeletionRefusal as ei, ToolbarSeparator as en, isFilePlainText as er, BranchSidebar as et, storeDocument as f, record$1 as fi, isLocale as fn, resolveLanguage as fr, stepShellTab as ft, CommentsRequestError as g, PREVIEW_TILE_HEIGHT as gi, Text as gn, parseReviewActionRecoveries as gr, visitShellTab as gt, storedWorkspace as h, PREVIEW_THUMBNAIL_WIDTHS as hi, useLocaleSource as hn, parseReviewActionPlan as hr, tabsCookieValue as ht, saveThread as i, withoutMessages as ii, IconButton as in, areThemesEqual as ir, FieldCardContent as it, FileRecoveryDialog as j, parseThreadCapabilities as jn, parseFileChange as jr, legacyFileHref as jt, defaultEditorPreferences as k, parseAnchor as kn, parseFileSearchQuery as kr, defaultReviewPosition as kt, projectStore as l, identifier$1 as li, readPreference as ln, themeResolver as lr, openShellTab as lt, storedFiles as m, MAX_PREVIEW_HEIGHT as mi, t$2 as mn, ResolvedLanguages as mr, tabsCookieName as mt, unavailableComments as n, parseMessage as ni, ShellTabBar as nn, areFileRenderOptionsEqual as nr, CommentThreadHeading as nt, threadMatches as o, parseWorkSchema as oi, Tooltip as on, prepareThemeResolution as or, activeTab as ot, storedDocument as p, strict$1 as pi, locale as pn, areLanguagesAttached as pr, tabHref as pt, parseCommentInput as q, areFilesEqual as qn, parseWorkQuery as qr, taskRoutes as qt, followThreads as r, parseMessageAuthor as ri, Select as rn, hasResolvedThemes as rr, FieldCard as rt, applyFileUpdate as s, statusCategory as si, AppShell as sn, validateResolvedThemeName as sr, closeShellTab as st, commentsUnavailable as t, messageDeletionRefusals as ti, WorkspaceLayout as tn, renderFileWithHighlighter as tr, ConversationSidebar as tt, saveFiles as u, nonempty as ui, writePreference as un, getThemes as ur, parseShellTabs as ut, projectLive as v, parsePreviewBranch as vi, RESYNC as vn, parseFileSaveRequest as vr, codeCommentCounts as vt, ThreadTaskPicker as w, predictWorkAction as wn, parseReviewDiff as wr, locateCodeConversations as wt, writeOptimistically as x, parsePreviewId as xi, predictThreadDelete as xn, parseMutationPlan as xr, conversationLabel as xt, routes as y, parsePreviewCapture as yi, parseLiveId as yn, parseFileSaveResult as yr, conversationDestination as yt, remainingMutationIntent as z, parseThreadStatus as zn, parseWorkActionInput as zr, defaultFileView as zt };
100736
+ export { Dialog as $, areFileRenderOptionsEqual as $n, parseMessage as $r, LiveStatus as $t, FileRecoveryDialog as A, parseThreadFilter as An, parseFileIndex as Ar, readReviewLocation as At, AgentBrowser as B, reviewConflictIdentity as Bn, parseWorkDetail as Br, reconcileFileView as Bt, ThreadTaskPicker as C, predictWorkCreate as Cn, parseReviewRepository as Cr, taskHref as Ct, FileEditorPanel as D, parseAnchor as Dn, parseFileSearchResult as Dr, defaultReviewView as Dt, ReviewActionDialog as E, MAX_THREADS as En, parseFileSearchQuery as Er, defaultReviewPosition as Et, defaultFileDestination as F, parseThreadSnapshot as Fn, parseSectionData as Fr, closeFileTab as Ft, FileSearchPanel as G, areDiffTargetsEqual as Gn, parseWorkSnapshot as Gr, Loader as Gt, parseTaskDesign as H, renderDiffWithHighlighter as Hn, parseWorkItemRef as Hr, CommentThreadDetail as Ht, fileActionIntent as I, parseThreadStatus as In, parseWorkActionInput as Ir, defaultFileView as It, CommentThreadHeading as J, WorkerPoolWorkerError as Jn, parseWorkUpdate as Jr, ToolbarSeparator as Jt, BranchSidebar as K, WorkerPoolTaskCanceledError as Kn, parseWorkSync as Kr, Spinner as Kt, mutationFileView as L, parseThreadStatusInput as Ln, parseWorkActivity as Lr, fileHref as Lt, FileReviewPanel as M, parseThreadInput as Mn, MAX_CANVAS_Y as Mr, reviewComparison as Mt, codeThemes as N, parseThreadLinkInput as Nn, parseElementAnchor as Nr, reviewContextKey as Nt, defaultEditorPreferences as O, parseThread as On, parseFileChange as Or, legacyFileHref as Ot, FileWorkspace as P, parseThreadReplyInput as Pn, parseWorkWorkspace as Pr, reviewHref as Pt, FieldCardHeader as Q, renderFileWithHighlighter as Qn, messageDeletionRefusals as Qr, IconButton as Qt, remainingMutationIntent as R, createCodeAnchor as Rn, parseWorkConnection as Rr, parseFileView as Rt, ThreadTaskLinks as S, predictWorkAction as Sn, parseReviewHistory as Sr, taskAgentHref as St, FileConflictPanel as T, parseWorkChange as Tn, parseReviewSource as Tr, taskRole as Tt, CanvasWorkspace as U, areDiffRenderOptionsEqual as Un, parseWorkMutationResult as Ur, CommentThreadItem as Ut, TaskWorkspace as V, isDiffPlainText as Vn, parseWorkItem as Vr, rememberFile as Vt, captureCanvasPoint as W, areFilesEqual as Wn, parseWorkQuery as Wr, CommentComposer as Wt, FieldCardContent as X, markWorkerErrorReported as Xn, workRunSummary as Xr, ShellTabBar as Xt, FieldCard as Y, isHandledWorkerPoolError as Yn, valueByRole as Yr, WorkspaceLayout as Yt, FieldCardFooter as Z, isFilePlainText as Zn, messageDeletionRefusal as Zr, Select as Zt, requestComments as _, parsePreviewId as _i, parseLiveId as _n, maxFileSaveBytes as _r, legacyConversationHref as _t, saveThreads as a, identifier$1 as ai, hasMessage as an, attachResolvedThemes as ar, readTabsCookie as at, writeOptimistically as b, predictThreadReply as bn, parseRecoveries as br, agentViewOpen as bt, previewKey as c, record$1 as ci, t$2 as cn, getResolvedOrResolveLanguage as cr, tabsCookieName as ct, saveWorkspace as d, PREVIEW_THUMBNAIL_WIDTHS as di, Icon$1 as dn, ResolvedLanguages as dr, PagesWorkspace as dt, parseMessageAuthor as ei, Tooltip as en, hasResolvedThemes as er, activeTab as et, storeDocument as f, PREVIEW_TILE_HEIGHT as fi, routes as fn, parseReviewActionPlan as fr, codeCommentCounts as ft, CommentsRequestError as g, parsePreviewHash as gi, RESYNC as gn, parseFileSaveResult as gr, isCodeConversation as gt, storedWorkspace as h, parsePreviewCapture as hi, taskRoutes as hn, parseFileSaveRequest as hr, conversationLabel as ht, saveThread as i, WorkValidationError as ii, writePreference as in, validateResolvedThemeName as ir, parseShellTabs as it, FileMutationDialog as j, parseThreadId as jn, parseFilePath as jr, rememberReviewPosition as jt, parseEditorPreferences as k, parseThreadDeleteInput as kn, parseFileDocument as kr, parseReviewSession as kt, projectStore as l, strict$1 as li, useLocaleSource as ln, resolveLanguage as lr, tabsCookieValue as lt, storedFiles as m, parsePreviewBranch as mi, pageRoutes as mn, parseReviewActionResult as mr, conversationHref as mt, unavailableComments as n, fieldByRole as ni, toast as nn, getSharedHighlighter as nr, initialShellTabs as nt, threadMatches as o, nonempty as oi, isLocale as on, themeResolver as or, stepShellTab as ot, storedDocument as p, parsePreview as pi, fileRoutes as pn, parseReviewActionRecoveries as pr, conversationDestination as pt, ConversationSidebar as q, WorkerPoolTerminatedError as qn, parseWorkSyncResult as qr, Button as qt, followThreads as r, parseWorkSchema as ri, readPreference as rn, prepareThemeResolution as rr, openShellTab as rt, applyFileUpdate as s, parseWork as si, locale as sn, getThemes as sr, tabHref as st, commentsUnavailable as t, withoutMessages as ti, AppShell as tn, areThemesEqual as tr, closeShellTab as tt, saveFiles as u, MAX_PREVIEW_HEIGHT as ui, Text as un, areLanguagesAttached as ur, visitShellTab as ut, projectLive as v, parsePreviewPins as vi, predictThreadCreate as vn, parseMutationPlan as vr, locateCodeConversations as vt, ItemDiscussion as w, predictWorkUpdate as wn, parseReviewSnapshot as wr, taskLabel as wt, writeRows as x, predictThreadStatus as xn, parseReviewDiff as xr, selectedTask as xt, plainRow as y, parsePreviewViewport as yi, predictThreadDelete as yn, parseMutationResult as yr, readConversationLocation as yt, TaskRunPanel as z, parseFileUpdate as zn, parseWorkCreate as zr, readFileLocation as zt };