@sideboard-ai/core 0.1.117 → 0.1.120

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.
@@ -28,7 +28,7 @@ import {
28
28
  resolveCursorModelId,
29
29
  resolveLoginCommand,
30
30
  resolveQuotaFallbackAgent
31
- } from "./chunk-YJ2WV5TZ.js";
31
+ } from "./chunk-QI7VC4EG.js";
32
32
  import "./chunk-EKIDHL2T.js";
33
33
  import {
34
34
  ORCHESTRATOR_AGENT_KINDS,
@@ -32,7 +32,7 @@ import {
32
32
  resolveCursorModelId,
33
33
  resolveLoginCommand,
34
34
  resolveQuotaFallbackAgent
35
- } from "./chunk-4CDCTYTM.js";
35
+ } from "./chunk-TDNM7QZJ.js";
36
36
  import "./chunk-YMRT2DU6.js";
37
37
  import {
38
38
  ORCHESTRATOR_AGENT_KINDS,
@@ -28,7 +28,7 @@ import {
28
28
  summarizeTurnStderr,
29
29
  toolDescription,
30
30
  turnFailChatText
31
- } from "./chunk-4CDCTYTM.js";
31
+ } from "./chunk-TDNM7QZJ.js";
32
32
  import {
33
33
  addWorkspace,
34
34
  ensureWorkspace,
@@ -2410,7 +2410,7 @@ async function createThread(input, _onSetupLine) {
2410
2410
  return readThread(thread.id) ?? thread;
2411
2411
  }
2412
2412
  async function listLinearIssues(agent, repoPath) {
2413
- const { getAdapter: getAdapter2 } = await import("./agents-OCGAZCKT.js");
2413
+ const { getAdapter: getAdapter2 } = await import("./agents-XTABRYO5.js");
2414
2414
  await requireAgent(agent, { requireLinear: true });
2415
2415
  const adapter = getAdapter2(agent);
2416
2416
  if (!adapter.listLinearIssues) {
@@ -4953,7 +4953,7 @@ function formatScheduledPrompt(name, prompt) {
4953
4953
  ${prompt}`;
4954
4954
  }
4955
4955
  async function defaultDeps() {
4956
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-4PKR6AZJ.js");
4956
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-3LJIG6XG.js");
4957
4957
  const orch = getOrchestrator2();
4958
4958
  return {
4959
4959
  findThread: (id) => findThreadByRef(id),
@@ -17,7 +17,7 @@ import {
17
17
  resolveQuotaFallbackAgent,
18
18
  stripBrightsyNdjsonNoise,
19
19
  toolDescription
20
- } from "./chunk-YJ2WV5TZ.js";
20
+ } from "./chunk-QI7VC4EG.js";
21
21
  import {
22
22
  addWorkspace,
23
23
  ensureWorkspace,
@@ -2455,7 +2455,7 @@ async function createThread(input, _onSetupLine) {
2455
2455
  return readThread(thread.id) ?? thread;
2456
2456
  }
2457
2457
  async function listLinearIssues(agent, repoPath) {
2458
- const { getAdapter: getAdapter2 } = await import("./agents-GUEKGV7V.js");
2458
+ const { getAdapter: getAdapter2 } = await import("./agents-HOIXQEP5.js");
2459
2459
  await requireAgent(agent, { requireLinear: true });
2460
2460
  const adapter = getAdapter2(agent);
2461
2461
  if (!adapter.listLinearIssues) {
@@ -5124,7 +5124,7 @@ function formatScheduledPrompt(name, prompt) {
5124
5124
  ${prompt}`;
5125
5125
  }
5126
5126
  async function defaultDeps() {
5127
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-MKTZYWTI.js");
5127
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-NWNKWZLB.js");
5128
5128
  const orch = getOrchestrator2();
5129
5129
  return {
5130
5130
  findThread: (id) => findThreadByRef(id),
@@ -815,6 +815,11 @@ function parseDiffStat(result) {
815
815
  }
816
816
  return {};
817
817
  }
818
+ function withPartTimes(next, prev) {
819
+ const now = Date.now();
820
+ const startedAt = prev && typeof prev.startedAt === "number" ? prev.startedAt : now;
821
+ return { ...next, startedAt, updatedAt: now };
822
+ }
818
823
  function applyAgentEvent(parts, event) {
819
824
  if (event.type === "stdout") {
820
825
  const data = event.data;
@@ -822,17 +827,22 @@ function applyAgentEvent(parts, event) {
822
827
  const next = [...parts];
823
828
  const last = next[next.length - 1];
824
829
  if (last?.type === "text" && sameParentId(last.parentId, event.parentId)) {
825
- next[next.length - 1] = {
826
- type: "text",
827
- text: last.text + data,
828
- ...event.parentId ? { parentId: event.parentId } : {}
829
- };
830
+ next[next.length - 1] = withPartTimes(
831
+ {
832
+ type: "text",
833
+ text: last.text + data,
834
+ ...event.parentId ? { parentId: event.parentId } : {}
835
+ },
836
+ last
837
+ );
830
838
  } else {
831
- next.push({
832
- type: "text",
833
- text: data,
834
- ...event.parentId ? { parentId: event.parentId } : {}
835
- });
839
+ next.push(
840
+ withPartTimes({
841
+ type: "text",
842
+ text: data,
843
+ ...event.parentId ? { parentId: event.parentId } : {}
844
+ })
845
+ );
836
846
  }
837
847
  return next;
838
848
  }
@@ -844,34 +854,44 @@ function applyAgentEvent(parts, event) {
844
854
  for (let i = next.length - 1; i >= 0; i--) {
845
855
  const prev = next[i];
846
856
  if (prev?.type === "thinking" && sameParentId(prev.parentId, event.parentId)) {
847
- next[i] = {
848
- type: "thinking",
849
- text: data,
850
- ...event.parentId ? { parentId: event.parentId } : {}
851
- };
857
+ next[i] = withPartTimes(
858
+ {
859
+ type: "thinking",
860
+ text: data,
861
+ ...event.parentId ? { parentId: event.parentId } : {}
862
+ },
863
+ prev
864
+ );
852
865
  return next;
853
866
  }
854
867
  }
855
- next.push({
856
- type: "thinking",
857
- text: data,
858
- ...event.parentId ? { parentId: event.parentId } : {}
859
- });
868
+ next.push(
869
+ withPartTimes({
870
+ type: "thinking",
871
+ text: data,
872
+ ...event.parentId ? { parentId: event.parentId } : {}
873
+ })
874
+ );
860
875
  return next;
861
876
  }
862
877
  const last = next[next.length - 1];
863
878
  if (last?.type === "thinking" && sameParentId(last.parentId, event.parentId)) {
864
- next[next.length - 1] = {
865
- type: "thinking",
866
- text: last.text + data,
867
- ...event.parentId ? { parentId: event.parentId } : {}
868
- };
879
+ next[next.length - 1] = withPartTimes(
880
+ {
881
+ type: "thinking",
882
+ text: last.text + data,
883
+ ...event.parentId ? { parentId: event.parentId } : {}
884
+ },
885
+ last
886
+ );
869
887
  } else {
870
- next.push({
871
- type: "thinking",
872
- text: data,
873
- ...event.parentId ? { parentId: event.parentId } : {}
874
- });
888
+ next.push(
889
+ withPartTimes({
890
+ type: "thinking",
891
+ text: data,
892
+ ...event.parentId ? { parentId: event.parentId } : {}
893
+ })
894
+ );
875
895
  }
876
896
  return next;
877
897
  }
@@ -887,22 +907,25 @@ function applyAgentEvent(parts, event) {
887
907
  ...input ?? {}
888
908
  };
889
909
  const mergedRecord = Object.keys(mergedInput).length > 0 ? mergedInput : void 0;
890
- next[existing] = {
891
- ...prev,
892
- name: event.name || prev.name,
893
- input: mergedRecord,
894
- description: toolDescription(event.name || prev.name, mergedRecord),
895
- detail: toolDetail(event.name || prev.name, mergedRecord) ?? prev.detail,
896
- filePath: toolFilePath(mergedRecord) ?? prev.filePath,
897
- additions: diff.additions ?? prev.additions,
898
- deletions: diff.deletions ?? prev.deletions,
899
- parentId: event.parentId ?? prev.parentId
900
- };
910
+ next[existing] = withPartTimes(
911
+ {
912
+ ...prev,
913
+ name: event.name || prev.name,
914
+ input: mergedRecord,
915
+ description: toolDescription(event.name || prev.name, mergedRecord),
916
+ detail: toolDetail(event.name || prev.name, mergedRecord) ?? prev.detail,
917
+ filePath: toolFilePath(mergedRecord) ?? prev.filePath,
918
+ additions: diff.additions ?? prev.additions,
919
+ deletions: diff.deletions ?? prev.deletions,
920
+ parentId: event.parentId ?? prev.parentId
921
+ },
922
+ prev
923
+ );
901
924
  return next;
902
925
  }
903
926
  return [
904
927
  ...parts,
905
- {
928
+ withPartTimes({
906
929
  type: "tool",
907
930
  id: event.id,
908
931
  name: event.name,
@@ -913,7 +936,7 @@ function applyAgentEvent(parts, event) {
913
936
  filePath: toolFilePath(input),
914
937
  ...event.parentId ? { parentId: event.parentId } : {},
915
938
  ...diff
916
- }
939
+ })
917
940
  ];
918
941
  }
919
942
  if (event.type === "tool_result") {
@@ -923,7 +946,7 @@ function applyAgentEvent(parts, event) {
923
946
  if (existing < 0) {
924
947
  return [
925
948
  ...parts,
926
- {
949
+ withPartTimes({
927
950
  type: "tool",
928
951
  id: event.id,
929
952
  name: "tool",
@@ -931,22 +954,25 @@ function applyAgentEvent(parts, event) {
931
954
  status: event.isError ? "error" : "running",
932
955
  result: event.content,
933
956
  ...event.parentId ? { parentId: event.parentId } : {}
934
- }
957
+ })
935
958
  ];
936
959
  }
937
960
  return parts.map((p, i) => {
938
961
  if (i !== existing || p.type !== "tool") return p;
939
962
  if (p.status === "done" || p.status === "error") return p;
940
- return {
941
- ...p,
942
- result: event.content ?? p.result
943
- };
963
+ return withPartTimes(
964
+ {
965
+ ...p,
966
+ result: event.content ?? p.result
967
+ },
968
+ p
969
+ );
944
970
  });
945
971
  }
946
972
  if (existing < 0) {
947
973
  return [
948
974
  ...parts,
949
- {
975
+ withPartTimes({
950
976
  type: "tool",
951
977
  id: event.id,
952
978
  name: "tool",
@@ -956,18 +982,21 @@ function applyAgentEvent(parts, event) {
956
982
  ...event.parentId ? { parentId: event.parentId } : {},
957
983
  ...fromResult.additions != null ? { additions: fromResult.additions } : {},
958
984
  ...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
959
- }
985
+ })
960
986
  ];
961
987
  }
962
988
  return parts.map((p, i) => {
963
989
  if (i !== existing || p.type !== "tool") return p;
964
- return {
965
- ...p,
966
- status: event.isError ? "error" : "done",
967
- result: event.content,
968
- ...fromResult.additions != null ? { additions: fromResult.additions } : {},
969
- ...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
970
- };
990
+ return withPartTimes(
991
+ {
992
+ ...p,
993
+ status: event.isError ? "error" : "done",
994
+ result: event.content,
995
+ ...fromResult.additions != null ? { additions: fromResult.additions } : {},
996
+ ...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
997
+ },
998
+ p
999
+ );
971
1000
  });
972
1001
  }
973
1002
  return parts;
@@ -903,6 +903,11 @@ function parseDiffStat(result) {
903
903
  }
904
904
  return {};
905
905
  }
906
+ function withPartTimes(next, prev) {
907
+ const now = Date.now();
908
+ const startedAt = prev && typeof prev.startedAt === "number" ? prev.startedAt : now;
909
+ return { ...next, startedAt, updatedAt: now };
910
+ }
906
911
  function applyAgentEvent(parts, event) {
907
912
  if (event.type === "stdout") {
908
913
  const data = event.data;
@@ -910,17 +915,22 @@ function applyAgentEvent(parts, event) {
910
915
  const next = [...parts];
911
916
  const last = next[next.length - 1];
912
917
  if (last?.type === "text" && sameParentId(last.parentId, event.parentId)) {
913
- next[next.length - 1] = {
914
- type: "text",
915
- text: last.text + data,
916
- ...event.parentId ? { parentId: event.parentId } : {}
917
- };
918
+ next[next.length - 1] = withPartTimes(
919
+ {
920
+ type: "text",
921
+ text: last.text + data,
922
+ ...event.parentId ? { parentId: event.parentId } : {}
923
+ },
924
+ last
925
+ );
918
926
  } else {
919
- next.push({
920
- type: "text",
921
- text: data,
922
- ...event.parentId ? { parentId: event.parentId } : {}
923
- });
927
+ next.push(
928
+ withPartTimes({
929
+ type: "text",
930
+ text: data,
931
+ ...event.parentId ? { parentId: event.parentId } : {}
932
+ })
933
+ );
924
934
  }
925
935
  return next;
926
936
  }
@@ -932,34 +942,44 @@ function applyAgentEvent(parts, event) {
932
942
  for (let i = next.length - 1; i >= 0; i--) {
933
943
  const prev = next[i];
934
944
  if (prev?.type === "thinking" && sameParentId(prev.parentId, event.parentId)) {
935
- next[i] = {
936
- type: "thinking",
937
- text: data,
938
- ...event.parentId ? { parentId: event.parentId } : {}
939
- };
945
+ next[i] = withPartTimes(
946
+ {
947
+ type: "thinking",
948
+ text: data,
949
+ ...event.parentId ? { parentId: event.parentId } : {}
950
+ },
951
+ prev
952
+ );
940
953
  return next;
941
954
  }
942
955
  }
943
- next.push({
944
- type: "thinking",
945
- text: data,
946
- ...event.parentId ? { parentId: event.parentId } : {}
947
- });
956
+ next.push(
957
+ withPartTimes({
958
+ type: "thinking",
959
+ text: data,
960
+ ...event.parentId ? { parentId: event.parentId } : {}
961
+ })
962
+ );
948
963
  return next;
949
964
  }
950
965
  const last = next[next.length - 1];
951
966
  if (last?.type === "thinking" && sameParentId(last.parentId, event.parentId)) {
952
- next[next.length - 1] = {
953
- type: "thinking",
954
- text: last.text + data,
955
- ...event.parentId ? { parentId: event.parentId } : {}
956
- };
967
+ next[next.length - 1] = withPartTimes(
968
+ {
969
+ type: "thinking",
970
+ text: last.text + data,
971
+ ...event.parentId ? { parentId: event.parentId } : {}
972
+ },
973
+ last
974
+ );
957
975
  } else {
958
- next.push({
959
- type: "thinking",
960
- text: data,
961
- ...event.parentId ? { parentId: event.parentId } : {}
962
- });
976
+ next.push(
977
+ withPartTimes({
978
+ type: "thinking",
979
+ text: data,
980
+ ...event.parentId ? { parentId: event.parentId } : {}
981
+ })
982
+ );
963
983
  }
964
984
  return next;
965
985
  }
@@ -975,22 +995,25 @@ function applyAgentEvent(parts, event) {
975
995
  ...input ?? {}
976
996
  };
977
997
  const mergedRecord = Object.keys(mergedInput).length > 0 ? mergedInput : void 0;
978
- next[existing] = {
979
- ...prev,
980
- name: event.name || prev.name,
981
- input: mergedRecord,
982
- description: toolDescription(event.name || prev.name, mergedRecord),
983
- detail: toolDetail(event.name || prev.name, mergedRecord) ?? prev.detail,
984
- filePath: toolFilePath(mergedRecord) ?? prev.filePath,
985
- additions: diff.additions ?? prev.additions,
986
- deletions: diff.deletions ?? prev.deletions,
987
- parentId: event.parentId ?? prev.parentId
988
- };
998
+ next[existing] = withPartTimes(
999
+ {
1000
+ ...prev,
1001
+ name: event.name || prev.name,
1002
+ input: mergedRecord,
1003
+ description: toolDescription(event.name || prev.name, mergedRecord),
1004
+ detail: toolDetail(event.name || prev.name, mergedRecord) ?? prev.detail,
1005
+ filePath: toolFilePath(mergedRecord) ?? prev.filePath,
1006
+ additions: diff.additions ?? prev.additions,
1007
+ deletions: diff.deletions ?? prev.deletions,
1008
+ parentId: event.parentId ?? prev.parentId
1009
+ },
1010
+ prev
1011
+ );
989
1012
  return next;
990
1013
  }
991
1014
  return [
992
1015
  ...parts,
993
- {
1016
+ withPartTimes({
994
1017
  type: "tool",
995
1018
  id: event.id,
996
1019
  name: event.name,
@@ -1001,7 +1024,7 @@ function applyAgentEvent(parts, event) {
1001
1024
  filePath: toolFilePath(input),
1002
1025
  ...event.parentId ? { parentId: event.parentId } : {},
1003
1026
  ...diff
1004
- }
1027
+ })
1005
1028
  ];
1006
1029
  }
1007
1030
  if (event.type === "tool_result") {
@@ -1011,7 +1034,7 @@ function applyAgentEvent(parts, event) {
1011
1034
  if (existing < 0) {
1012
1035
  return [
1013
1036
  ...parts,
1014
- {
1037
+ withPartTimes({
1015
1038
  type: "tool",
1016
1039
  id: event.id,
1017
1040
  name: "tool",
@@ -1019,22 +1042,25 @@ function applyAgentEvent(parts, event) {
1019
1042
  status: event.isError ? "error" : "running",
1020
1043
  result: event.content,
1021
1044
  ...event.parentId ? { parentId: event.parentId } : {}
1022
- }
1045
+ })
1023
1046
  ];
1024
1047
  }
1025
1048
  return parts.map((p, i) => {
1026
1049
  if (i !== existing || p.type !== "tool") return p;
1027
1050
  if (p.status === "done" || p.status === "error") return p;
1028
- return {
1029
- ...p,
1030
- result: event.content ?? p.result
1031
- };
1051
+ return withPartTimes(
1052
+ {
1053
+ ...p,
1054
+ result: event.content ?? p.result
1055
+ },
1056
+ p
1057
+ );
1032
1058
  });
1033
1059
  }
1034
1060
  if (existing < 0) {
1035
1061
  return [
1036
1062
  ...parts,
1037
- {
1063
+ withPartTimes({
1038
1064
  type: "tool",
1039
1065
  id: event.id,
1040
1066
  name: "tool",
@@ -1044,18 +1070,21 @@ function applyAgentEvent(parts, event) {
1044
1070
  ...event.parentId ? { parentId: event.parentId } : {},
1045
1071
  ...fromResult.additions != null ? { additions: fromResult.additions } : {},
1046
1072
  ...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
1047
- }
1073
+ })
1048
1074
  ];
1049
1075
  }
1050
1076
  return parts.map((p, i) => {
1051
1077
  if (i !== existing || p.type !== "tool") return p;
1052
- return {
1053
- ...p,
1054
- status: event.isError ? "error" : "done",
1055
- result: event.content,
1056
- ...fromResult.additions != null ? { additions: fromResult.additions } : {},
1057
- ...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
1058
- };
1078
+ return withPartTimes(
1079
+ {
1080
+ ...p,
1081
+ status: event.isError ? "error" : "done",
1082
+ result: event.content,
1083
+ ...fromResult.additions != null ? { additions: fromResult.additions } : {},
1084
+ ...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
1085
+ },
1086
+ p
1087
+ );
1059
1088
  });
1060
1089
  }
1061
1090
  return parts;
package/dist/index.cjs CHANGED
@@ -7915,6 +7915,11 @@ function parseDiffStat(result) {
7915
7915
  }
7916
7916
  return {};
7917
7917
  }
7918
+ function withPartTimes(next, prev) {
7919
+ const now = Date.now();
7920
+ const startedAt = prev && typeof prev.startedAt === "number" ? prev.startedAt : now;
7921
+ return { ...next, startedAt, updatedAt: now };
7922
+ }
7918
7923
  function applyAgentEvent(parts, event) {
7919
7924
  if (event.type === "stdout") {
7920
7925
  const data = event.data;
@@ -7922,17 +7927,22 @@ function applyAgentEvent(parts, event) {
7922
7927
  const next = [...parts];
7923
7928
  const last = next[next.length - 1];
7924
7929
  if (last?.type === "text" && sameParentId(last.parentId, event.parentId)) {
7925
- next[next.length - 1] = {
7926
- type: "text",
7927
- text: last.text + data,
7928
- ...event.parentId ? { parentId: event.parentId } : {}
7929
- };
7930
+ next[next.length - 1] = withPartTimes(
7931
+ {
7932
+ type: "text",
7933
+ text: last.text + data,
7934
+ ...event.parentId ? { parentId: event.parentId } : {}
7935
+ },
7936
+ last
7937
+ );
7930
7938
  } else {
7931
- next.push({
7932
- type: "text",
7933
- text: data,
7934
- ...event.parentId ? { parentId: event.parentId } : {}
7935
- });
7939
+ next.push(
7940
+ withPartTimes({
7941
+ type: "text",
7942
+ text: data,
7943
+ ...event.parentId ? { parentId: event.parentId } : {}
7944
+ })
7945
+ );
7936
7946
  }
7937
7947
  return next;
7938
7948
  }
@@ -7944,34 +7954,44 @@ function applyAgentEvent(parts, event) {
7944
7954
  for (let i = next.length - 1; i >= 0; i--) {
7945
7955
  const prev = next[i];
7946
7956
  if (prev?.type === "thinking" && sameParentId(prev.parentId, event.parentId)) {
7947
- next[i] = {
7948
- type: "thinking",
7949
- text: data,
7950
- ...event.parentId ? { parentId: event.parentId } : {}
7951
- };
7957
+ next[i] = withPartTimes(
7958
+ {
7959
+ type: "thinking",
7960
+ text: data,
7961
+ ...event.parentId ? { parentId: event.parentId } : {}
7962
+ },
7963
+ prev
7964
+ );
7952
7965
  return next;
7953
7966
  }
7954
7967
  }
7955
- next.push({
7956
- type: "thinking",
7957
- text: data,
7958
- ...event.parentId ? { parentId: event.parentId } : {}
7959
- });
7968
+ next.push(
7969
+ withPartTimes({
7970
+ type: "thinking",
7971
+ text: data,
7972
+ ...event.parentId ? { parentId: event.parentId } : {}
7973
+ })
7974
+ );
7960
7975
  return next;
7961
7976
  }
7962
7977
  const last = next[next.length - 1];
7963
7978
  if (last?.type === "thinking" && sameParentId(last.parentId, event.parentId)) {
7964
- next[next.length - 1] = {
7965
- type: "thinking",
7966
- text: last.text + data,
7967
- ...event.parentId ? { parentId: event.parentId } : {}
7968
- };
7979
+ next[next.length - 1] = withPartTimes(
7980
+ {
7981
+ type: "thinking",
7982
+ text: last.text + data,
7983
+ ...event.parentId ? { parentId: event.parentId } : {}
7984
+ },
7985
+ last
7986
+ );
7969
7987
  } else {
7970
- next.push({
7971
- type: "thinking",
7972
- text: data,
7973
- ...event.parentId ? { parentId: event.parentId } : {}
7974
- });
7988
+ next.push(
7989
+ withPartTimes({
7990
+ type: "thinking",
7991
+ text: data,
7992
+ ...event.parentId ? { parentId: event.parentId } : {}
7993
+ })
7994
+ );
7975
7995
  }
7976
7996
  return next;
7977
7997
  }
@@ -7987,22 +8007,25 @@ function applyAgentEvent(parts, event) {
7987
8007
  ...input ?? {}
7988
8008
  };
7989
8009
  const mergedRecord = Object.keys(mergedInput).length > 0 ? mergedInput : void 0;
7990
- next[existing] = {
7991
- ...prev,
7992
- name: event.name || prev.name,
7993
- input: mergedRecord,
7994
- description: toolDescription(event.name || prev.name, mergedRecord),
7995
- detail: toolDetail(event.name || prev.name, mergedRecord) ?? prev.detail,
7996
- filePath: toolFilePath(mergedRecord) ?? prev.filePath,
7997
- additions: diff.additions ?? prev.additions,
7998
- deletions: diff.deletions ?? prev.deletions,
7999
- parentId: event.parentId ?? prev.parentId
8000
- };
8010
+ next[existing] = withPartTimes(
8011
+ {
8012
+ ...prev,
8013
+ name: event.name || prev.name,
8014
+ input: mergedRecord,
8015
+ description: toolDescription(event.name || prev.name, mergedRecord),
8016
+ detail: toolDetail(event.name || prev.name, mergedRecord) ?? prev.detail,
8017
+ filePath: toolFilePath(mergedRecord) ?? prev.filePath,
8018
+ additions: diff.additions ?? prev.additions,
8019
+ deletions: diff.deletions ?? prev.deletions,
8020
+ parentId: event.parentId ?? prev.parentId
8021
+ },
8022
+ prev
8023
+ );
8001
8024
  return next;
8002
8025
  }
8003
8026
  return [
8004
8027
  ...parts,
8005
- {
8028
+ withPartTimes({
8006
8029
  type: "tool",
8007
8030
  id: event.id,
8008
8031
  name: event.name,
@@ -8013,7 +8036,7 @@ function applyAgentEvent(parts, event) {
8013
8036
  filePath: toolFilePath(input),
8014
8037
  ...event.parentId ? { parentId: event.parentId } : {},
8015
8038
  ...diff
8016
- }
8039
+ })
8017
8040
  ];
8018
8041
  }
8019
8042
  if (event.type === "tool_result") {
@@ -8023,7 +8046,7 @@ function applyAgentEvent(parts, event) {
8023
8046
  if (existing < 0) {
8024
8047
  return [
8025
8048
  ...parts,
8026
- {
8049
+ withPartTimes({
8027
8050
  type: "tool",
8028
8051
  id: event.id,
8029
8052
  name: "tool",
@@ -8031,22 +8054,25 @@ function applyAgentEvent(parts, event) {
8031
8054
  status: event.isError ? "error" : "running",
8032
8055
  result: event.content,
8033
8056
  ...event.parentId ? { parentId: event.parentId } : {}
8034
- }
8057
+ })
8035
8058
  ];
8036
8059
  }
8037
8060
  return parts.map((p, i) => {
8038
8061
  if (i !== existing || p.type !== "tool") return p;
8039
8062
  if (p.status === "done" || p.status === "error") return p;
8040
- return {
8041
- ...p,
8042
- result: event.content ?? p.result
8043
- };
8063
+ return withPartTimes(
8064
+ {
8065
+ ...p,
8066
+ result: event.content ?? p.result
8067
+ },
8068
+ p
8069
+ );
8044
8070
  });
8045
8071
  }
8046
8072
  if (existing < 0) {
8047
8073
  return [
8048
8074
  ...parts,
8049
- {
8075
+ withPartTimes({
8050
8076
  type: "tool",
8051
8077
  id: event.id,
8052
8078
  name: "tool",
@@ -8056,18 +8082,21 @@ function applyAgentEvent(parts, event) {
8056
8082
  ...event.parentId ? { parentId: event.parentId } : {},
8057
8083
  ...fromResult.additions != null ? { additions: fromResult.additions } : {},
8058
8084
  ...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
8059
- }
8085
+ })
8060
8086
  ];
8061
8087
  }
8062
8088
  return parts.map((p, i) => {
8063
8089
  if (i !== existing || p.type !== "tool") return p;
8064
- return {
8065
- ...p,
8066
- status: event.isError ? "error" : "done",
8067
- result: event.content,
8068
- ...fromResult.additions != null ? { additions: fromResult.additions } : {},
8069
- ...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
8070
- };
8090
+ return withPartTimes(
8091
+ {
8092
+ ...p,
8093
+ status: event.isError ? "error" : "done",
8094
+ result: event.content,
8095
+ ...fromResult.additions != null ? { additions: fromResult.additions } : {},
8096
+ ...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
8097
+ },
8098
+ p
8099
+ );
8071
8100
  });
8072
8101
  }
8073
8102
  return parts;
package/dist/index.d.cts CHANGED
@@ -26,10 +26,14 @@ type MessagePart = {
26
26
  type: 'text';
27
27
  text: string;
28
28
  parentId?: string;
29
+ startedAt?: number;
30
+ updatedAt?: number;
29
31
  } | {
30
32
  type: 'thinking';
31
33
  text: string;
32
34
  parentId?: string;
35
+ startedAt?: number;
36
+ updatedAt?: number;
33
37
  } | {
34
38
  type: 'tool';
35
39
  id: string;
@@ -49,6 +53,8 @@ type MessagePart = {
49
53
  * subagent stream). Omitted on top-level parts.
50
54
  */
51
55
  parentId?: string;
56
+ startedAt?: number;
57
+ updatedAt?: number;
52
58
  };
53
59
  /** Token usage for a single agent turn, aggregated across the turn's API calls. */
54
60
  interface TokenUsage {
@@ -2243,7 +2249,6 @@ declare function messagePartParentId(part: MessagePart): string | undefined;
2243
2249
  declare function withEventParentId(event: AgentEvent, parentId?: string): AgentEvent;
2244
2250
  declare function withEventsParentId(events: AgentEvent[], parentId?: string): AgentEvent[];
2245
2251
  declare function toolFilePath(input?: Record<string, unknown>): string | undefined;
2246
- /** Apply a structured agent event onto an accumulated parts list. */
2247
2252
  declare function applyAgentEvent(parts: MessagePart[], event: AgentEvent): MessagePart[];
2248
2253
  declare function partsToAssistantText(parts: MessagePart[]): string;
2249
2254
  /**
package/dist/index.d.ts CHANGED
@@ -26,10 +26,14 @@ type MessagePart = {
26
26
  type: 'text';
27
27
  text: string;
28
28
  parentId?: string;
29
+ startedAt?: number;
30
+ updatedAt?: number;
29
31
  } | {
30
32
  type: 'thinking';
31
33
  text: string;
32
34
  parentId?: string;
35
+ startedAt?: number;
36
+ updatedAt?: number;
33
37
  } | {
34
38
  type: 'tool';
35
39
  id: string;
@@ -49,6 +53,8 @@ type MessagePart = {
49
53
  * subagent stream). Omitted on top-level parts.
50
54
  */
51
55
  parentId?: string;
56
+ startedAt?: number;
57
+ updatedAt?: number;
52
58
  };
53
59
  /** Token usage for a single agent turn, aggregated across the turn's API calls. */
54
60
  interface TokenUsage {
@@ -2243,7 +2249,6 @@ declare function messagePartParentId(part: MessagePart): string | undefined;
2243
2249
  declare function withEventParentId(event: AgentEvent, parentId?: string): AgentEvent;
2244
2250
  declare function withEventsParentId(events: AgentEvent[], parentId?: string): AgentEvent[];
2245
2251
  declare function toolFilePath(input?: Record<string, unknown>): string | undefined;
2246
- /** Apply a structured agent event onto an accumulated parts list. */
2247
2252
  declare function applyAgentEvent(parts: MessagePart[], event: AgentEvent): MessagePart[];
2248
2253
  declare function partsToAssistantText(parts: MessagePart[]): string;
2249
2254
  /**
package/dist/index.js CHANGED
@@ -170,7 +170,7 @@ import {
170
170
  worktreeCleanupSettings,
171
171
  wrapReviewSkillMarkdown,
172
172
  writeWorktreeFile
173
- } from "./chunk-5X7GRP5W.js";
173
+ } from "./chunk-AFM6442E.js";
174
174
  import {
175
175
  BRIGHTSY_MCP_ALLOWED_TOOLS,
176
176
  CLAUDE_MODEL_CATALOG,
@@ -248,7 +248,7 @@ import {
248
248
  withEventParentId,
249
249
  withEventsParentId,
250
250
  writeInjectedMcpConfig
251
- } from "./chunk-YJ2WV5TZ.js";
251
+ } from "./chunk-QI7VC4EG.js";
252
252
  import {
253
253
  brightsyConfigPath,
254
254
  brightsyMcpServerName,
@@ -6987,6 +6987,11 @@ function parseDiffStat(result) {
6987
6987
  }
6988
6988
  return {};
6989
6989
  }
6990
+ function withPartTimes(next, prev) {
6991
+ const now = Date.now();
6992
+ const startedAt = prev && typeof prev.startedAt === "number" ? prev.startedAt : now;
6993
+ return { ...next, startedAt, updatedAt: now };
6994
+ }
6990
6995
  function applyAgentEvent(parts, event) {
6991
6996
  if (event.type === "stdout") {
6992
6997
  const data = event.data;
@@ -6994,17 +6999,22 @@ function applyAgentEvent(parts, event) {
6994
6999
  const next = [...parts];
6995
7000
  const last = next[next.length - 1];
6996
7001
  if (last?.type === "text" && sameParentId(last.parentId, event.parentId)) {
6997
- next[next.length - 1] = {
6998
- type: "text",
6999
- text: last.text + data,
7000
- ...event.parentId ? { parentId: event.parentId } : {}
7001
- };
7002
+ next[next.length - 1] = withPartTimes(
7003
+ {
7004
+ type: "text",
7005
+ text: last.text + data,
7006
+ ...event.parentId ? { parentId: event.parentId } : {}
7007
+ },
7008
+ last
7009
+ );
7002
7010
  } else {
7003
- next.push({
7004
- type: "text",
7005
- text: data,
7006
- ...event.parentId ? { parentId: event.parentId } : {}
7007
- });
7011
+ next.push(
7012
+ withPartTimes({
7013
+ type: "text",
7014
+ text: data,
7015
+ ...event.parentId ? { parentId: event.parentId } : {}
7016
+ })
7017
+ );
7008
7018
  }
7009
7019
  return next;
7010
7020
  }
@@ -7016,34 +7026,44 @@ function applyAgentEvent(parts, event) {
7016
7026
  for (let i = next.length - 1; i >= 0; i--) {
7017
7027
  const prev = next[i];
7018
7028
  if (prev?.type === "thinking" && sameParentId(prev.parentId, event.parentId)) {
7019
- next[i] = {
7020
- type: "thinking",
7021
- text: data,
7022
- ...event.parentId ? { parentId: event.parentId } : {}
7023
- };
7029
+ next[i] = withPartTimes(
7030
+ {
7031
+ type: "thinking",
7032
+ text: data,
7033
+ ...event.parentId ? { parentId: event.parentId } : {}
7034
+ },
7035
+ prev
7036
+ );
7024
7037
  return next;
7025
7038
  }
7026
7039
  }
7027
- next.push({
7028
- type: "thinking",
7029
- text: data,
7030
- ...event.parentId ? { parentId: event.parentId } : {}
7031
- });
7040
+ next.push(
7041
+ withPartTimes({
7042
+ type: "thinking",
7043
+ text: data,
7044
+ ...event.parentId ? { parentId: event.parentId } : {}
7045
+ })
7046
+ );
7032
7047
  return next;
7033
7048
  }
7034
7049
  const last = next[next.length - 1];
7035
7050
  if (last?.type === "thinking" && sameParentId(last.parentId, event.parentId)) {
7036
- next[next.length - 1] = {
7037
- type: "thinking",
7038
- text: last.text + data,
7039
- ...event.parentId ? { parentId: event.parentId } : {}
7040
- };
7051
+ next[next.length - 1] = withPartTimes(
7052
+ {
7053
+ type: "thinking",
7054
+ text: last.text + data,
7055
+ ...event.parentId ? { parentId: event.parentId } : {}
7056
+ },
7057
+ last
7058
+ );
7041
7059
  } else {
7042
- next.push({
7043
- type: "thinking",
7044
- text: data,
7045
- ...event.parentId ? { parentId: event.parentId } : {}
7046
- });
7060
+ next.push(
7061
+ withPartTimes({
7062
+ type: "thinking",
7063
+ text: data,
7064
+ ...event.parentId ? { parentId: event.parentId } : {}
7065
+ })
7066
+ );
7047
7067
  }
7048
7068
  return next;
7049
7069
  }
@@ -7059,22 +7079,25 @@ function applyAgentEvent(parts, event) {
7059
7079
  ...input ?? {}
7060
7080
  };
7061
7081
  const mergedRecord = Object.keys(mergedInput).length > 0 ? mergedInput : void 0;
7062
- next[existing] = {
7063
- ...prev,
7064
- name: event.name || prev.name,
7065
- input: mergedRecord,
7066
- description: toolDescription(event.name || prev.name, mergedRecord),
7067
- detail: toolDetail(event.name || prev.name, mergedRecord) ?? prev.detail,
7068
- filePath: toolFilePath(mergedRecord) ?? prev.filePath,
7069
- additions: diff.additions ?? prev.additions,
7070
- deletions: diff.deletions ?? prev.deletions,
7071
- parentId: event.parentId ?? prev.parentId
7072
- };
7082
+ next[existing] = withPartTimes(
7083
+ {
7084
+ ...prev,
7085
+ name: event.name || prev.name,
7086
+ input: mergedRecord,
7087
+ description: toolDescription(event.name || prev.name, mergedRecord),
7088
+ detail: toolDetail(event.name || prev.name, mergedRecord) ?? prev.detail,
7089
+ filePath: toolFilePath(mergedRecord) ?? prev.filePath,
7090
+ additions: diff.additions ?? prev.additions,
7091
+ deletions: diff.deletions ?? prev.deletions,
7092
+ parentId: event.parentId ?? prev.parentId
7093
+ },
7094
+ prev
7095
+ );
7073
7096
  return next;
7074
7097
  }
7075
7098
  return [
7076
7099
  ...parts,
7077
- {
7100
+ withPartTimes({
7078
7101
  type: "tool",
7079
7102
  id: event.id,
7080
7103
  name: event.name,
@@ -7085,7 +7108,7 @@ function applyAgentEvent(parts, event) {
7085
7108
  filePath: toolFilePath(input),
7086
7109
  ...event.parentId ? { parentId: event.parentId } : {},
7087
7110
  ...diff
7088
- }
7111
+ })
7089
7112
  ];
7090
7113
  }
7091
7114
  if (event.type === "tool_result") {
@@ -7095,7 +7118,7 @@ function applyAgentEvent(parts, event) {
7095
7118
  if (existing < 0) {
7096
7119
  return [
7097
7120
  ...parts,
7098
- {
7121
+ withPartTimes({
7099
7122
  type: "tool",
7100
7123
  id: event.id,
7101
7124
  name: "tool",
@@ -7103,22 +7126,25 @@ function applyAgentEvent(parts, event) {
7103
7126
  status: event.isError ? "error" : "running",
7104
7127
  result: event.content,
7105
7128
  ...event.parentId ? { parentId: event.parentId } : {}
7106
- }
7129
+ })
7107
7130
  ];
7108
7131
  }
7109
7132
  return parts.map((p, i) => {
7110
7133
  if (i !== existing || p.type !== "tool") return p;
7111
7134
  if (p.status === "done" || p.status === "error") return p;
7112
- return {
7113
- ...p,
7114
- result: event.content ?? p.result
7115
- };
7135
+ return withPartTimes(
7136
+ {
7137
+ ...p,
7138
+ result: event.content ?? p.result
7139
+ },
7140
+ p
7141
+ );
7116
7142
  });
7117
7143
  }
7118
7144
  if (existing < 0) {
7119
7145
  return [
7120
7146
  ...parts,
7121
- {
7147
+ withPartTimes({
7122
7148
  type: "tool",
7123
7149
  id: event.id,
7124
7150
  name: "tool",
@@ -7128,18 +7154,21 @@ function applyAgentEvent(parts, event) {
7128
7154
  ...event.parentId ? { parentId: event.parentId } : {},
7129
7155
  ...fromResult.additions != null ? { additions: fromResult.additions } : {},
7130
7156
  ...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
7131
- }
7157
+ })
7132
7158
  ];
7133
7159
  }
7134
7160
  return parts.map((p, i) => {
7135
7161
  if (i !== existing || p.type !== "tool") return p;
7136
- return {
7137
- ...p,
7138
- status: event.isError ? "error" : "done",
7139
- result: event.content,
7140
- ...fromResult.additions != null ? { additions: fromResult.additions } : {},
7141
- ...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
7142
- };
7162
+ return withPartTimes(
7163
+ {
7164
+ ...p,
7165
+ status: event.isError ? "error" : "done",
7166
+ result: event.content,
7167
+ ...fromResult.additions != null ? { additions: fromResult.additions } : {},
7168
+ ...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
7169
+ },
7170
+ p
7171
+ );
7143
7172
  });
7144
7173
  }
7145
7174
  return parts;
@@ -19,11 +19,11 @@ import {
19
19
  slackApi,
20
20
  slackTokenFor,
21
21
  updateSchedule
22
- } from "../chunk-74YJHND6.js";
22
+ } from "../chunk-4LRPW6QM.js";
23
23
  import {
24
24
  listModelsForAgent,
25
25
  sideboardMcpProfile
26
- } from "../chunk-4CDCTYTM.js";
26
+ } from "../chunk-TDNM7QZJ.js";
27
27
  import "../chunk-YMRT2DU6.js";
28
28
  import "../chunk-BKVDZV7X.js";
29
29
  import "../chunk-N5PM7HGQ.js";
@@ -6,8 +6,8 @@ import {
6
6
  isPidAlive,
7
7
  startOrchestration,
8
8
  waitForPidExit
9
- } from "./chunk-74YJHND6.js";
10
- import "./chunk-4CDCTYTM.js";
9
+ } from "./chunk-4LRPW6QM.js";
10
+ import "./chunk-TDNM7QZJ.js";
11
11
  import "./chunk-YMRT2DU6.js";
12
12
  import "./chunk-BKVDZV7X.js";
13
13
  import "./chunk-N5PM7HGQ.js";
@@ -4,8 +4,8 @@ import {
4
4
  isPidAlive,
5
5
  startOrchestration,
6
6
  waitForPidExit
7
- } from "./chunk-5X7GRP5W.js";
8
- import "./chunk-YJ2WV5TZ.js";
7
+ } from "./chunk-AFM6442E.js";
8
+ import "./chunk-QI7VC4EG.js";
9
9
  import "./chunk-EKIDHL2T.js";
10
10
  import "./chunk-U3IVCVLH.js";
11
11
  import "./chunk-4WV7C7WP.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sideboard-ai/core",
3
- "version": "0.1.117",
3
+ "version": "0.1.120",
4
4
  "description": "Sideboard core — orchestration, agents, git worktrees, MCP server",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",