@sideboard-ai/core 0.1.152 → 0.1.153

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 (61) hide show
  1. package/dist/{abletime-223A3LY6.js → abletime-H7LPGIP2.js} +3 -3
  2. package/dist/{abletime-CLC5UJC2.js → abletime-JSTJLXAW.js} +3 -3
  3. package/dist/agents/cursor-runner.js +2 -2
  4. package/dist/{agents-CUKWIM34.js → agents-V24DYZI4.js} +8 -9
  5. package/dist/{agents-VHXCBBBD.js → agents-YVW75KBO.js} +8 -9
  6. package/dist/{app-settings-3CHCNIMD.js → app-settings-H3INSR67.js} +38 -4
  7. package/dist/{app-settings-J3JBCUOT.js → app-settings-VRQI3FIE.js} +38 -4
  8. package/dist/{caffeinate-hold-NBRUWYXO.js → caffeinate-hold-DBKMRZZO.js} +2 -2
  9. package/dist/{caffeinate-hold-X3JNPR42.js → caffeinate-hold-SK2QISPE.js} +2 -2
  10. package/dist/chunk-2F63IMCL.js +959 -0
  11. package/dist/{chunk-7BQNSUR2.js → chunk-2NRNP7QP.js} +357 -185
  12. package/dist/{chunk-4XNSGDXE.js → chunk-3BWVOUQG.js} +244 -1
  13. package/dist/{chunk-EY6QXPPO.js → chunk-4THE3EY7.js} +6 -6
  14. package/dist/{chunk-TUGKX5BD.js → chunk-7UURXPKD.js} +1 -1
  15. package/dist/{chunk-DCOZABNT.js → chunk-AO35MGOE.js} +1 -1
  16. package/dist/{chunk-3JBMACYX.js → chunk-CJQLPPEJ.js} +387 -15
  17. package/dist/{chunk-CZD4NRDZ.js → chunk-D7EGJ3EI.js} +244 -1
  18. package/dist/{chunk-QZQEXME2.js → chunk-EFVFB2AH.js} +1 -1
  19. package/dist/{chunk-B7XK37WZ.js → chunk-FDCFXMDG.js} +1 -1
  20. package/dist/{chunk-WLV7TRMR.js → chunk-JOK4XWBG.js} +1 -1
  21. package/dist/{chunk-BD2ICC4D.js → chunk-JTJHOYCU.js} +1 -1
  22. package/dist/{chunk-6X7Z34XE.js → chunk-KMNODRWF.js} +397 -173
  23. package/dist/{chunk-GE7M3QTE.js → chunk-LQMFCS54.js} +387 -15
  24. package/dist/{chunk-G7SIQFBQ.js → chunk-LZ6QMEQC.js} +1 -1
  25. package/dist/{chunk-EUXOHTUK.js → chunk-LZQULFIT.js} +1 -1
  26. package/dist/{chunk-KLBOWJ74.js → chunk-OCQPTUR7.js} +1 -1
  27. package/dist/{chunk-GFQ57XAX.js → chunk-QZEZXYVV.js} +13 -13
  28. package/dist/chunk-RNC3GR6L.js +905 -0
  29. package/dist/{chunk-VHX673DI.js → chunk-WLPXZFRE.js} +1 -1
  30. package/dist/{chunk-7F4XE6UG.js → chunk-XD2BAANL.js} +5 -5
  31. package/dist/{connected-teams-XO766HB4.js → connected-teams-DBWAMP7G.js} +2 -2
  32. package/dist/{connected-teams-I2WZZZFA.js → connected-teams-WGONUQOF.js} +2 -2
  33. package/dist/{coordinator-prompt-WGFRYCHE.js → coordinator-prompt-7FHKCWXB.js} +5 -5
  34. package/dist/{coordinator-prompt-TBX4MOFM.js → coordinator-prompt-KX2FVVYT.js} +5 -5
  35. package/dist/{cursor-recover-NOQYOFRF.js → cursor-recover-L5MD6MBO.js} +1 -1
  36. package/dist/{cursor-recover-QSLWEZNA.js → cursor-recover-NDMLLNYX.js} +2 -2
  37. package/dist/{global-workspace-IY5QAV5C.js → global-workspace-2BRRKSDN.js} +5 -6
  38. package/dist/{global-workspace-BHLUJ46D.js → global-workspace-4LHCZ2DC.js} +5 -6
  39. package/dist/index.cjs +1875 -765
  40. package/dist/index.d.cts +195 -11
  41. package/dist/index.d.ts +195 -11
  42. package/dist/index.js +298 -108
  43. package/dist/mcp/run-stdio.cjs +1743 -1228
  44. package/dist/mcp/run-stdio.js +232 -80
  45. package/dist/{orchestrator-NUA6SEV7.js → orchestrator-5PSHBLP6.js} +10 -12
  46. package/dist/{orchestrator-256DFPSX.js → orchestrator-ZSSU3FKW.js} +9 -11
  47. package/dist/{paths-UMEDHOS5.js → paths-53TLA7VQ.js} +1 -1
  48. package/dist/{paths-QCI3MTO5.js → paths-RRCLNSJB.js} +1 -1
  49. package/dist/{thread-store-WGASXXXR.js → thread-store-KBFBHT5G.js} +2 -2
  50. package/dist/{thread-store-57ZLHR3A.js → thread-store-MVQU6HPJ.js} +2 -2
  51. package/dist/{workspaces-4FSXVIZM.js → workspaces-5UNDTN4G.js} +5 -7
  52. package/dist/{workspaces-NECIQTAO.js → workspaces-MQYNZXUK.js} +5 -7
  53. package/dist/{worktree-HTUM35NT.js → worktree-PEWDAX5O.js} +4 -4
  54. package/dist/{worktree-DPIREDFR.js → worktree-T4SWFSTT.js} +4 -4
  55. package/package.json +1 -1
  56. package/dist/chunk-2U6QF3PT.js +0 -211
  57. package/dist/chunk-67TIJ7S5.js +0 -122
  58. package/dist/chunk-7TIUOYBK.js +0 -213
  59. package/dist/chunk-G4MTYUWS.js +0 -592
  60. package/dist/chunk-K2ANSHUO.js +0 -120
  61. package/dist/chunk-SN6CMKF6.js +0 -538
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-KGZBYWZ3.js";
10
10
  import {
11
11
  appDataDir
12
- } from "./chunk-BD2ICC4D.js";
12
+ } from "./chunk-JTJHOYCU.js";
13
13
 
14
14
  // src/store/app-settings.ts
15
15
  import { randomUUID } from "crypto";
@@ -63,6 +63,145 @@ function unwrapStrippedElectronLaunch(command, args) {
63
63
  return { file: args[3], args: args.slice(4) };
64
64
  }
65
65
 
66
+ // src/store/account-profile.ts
67
+ var ACCOUNT_ROLE_PRESETS = ["engineering", "design", "product"];
68
+ var ACCOUNT_ROLES = ACCOUNT_ROLE_PRESETS;
69
+ var ACCOUNT_ROLE_MAX = 16;
70
+ var PROFILE_NOTES_MAX = 2e3;
71
+ var ACCOUNT_ROLE_LABELS = {
72
+ engineering: "Engineering",
73
+ design: "Design",
74
+ product: "Product",
75
+ qa: "QA"
76
+ };
77
+ var ROLE_TEAM_HINTS = {
78
+ engineering: ["engineering-team", "engineering", "eng-team"],
79
+ design: ["design-team", "design"],
80
+ product: ["product-team", "product"]
81
+ };
82
+ function accountRoleLabel(role) {
83
+ const known = ACCOUNT_ROLE_LABELS[role];
84
+ if (known) return known;
85
+ return role.split("-").filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
86
+ }
87
+ function normalizeAccountRole(value) {
88
+ const key = (value ?? "").trim().toLowerCase().replace(/[_\s]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
89
+ if (key === "both") return void 0;
90
+ if (key.length < 2 || key.length > 40) return void 0;
91
+ if (!/^[a-z][a-z0-9-]*$/.test(key)) return void 0;
92
+ return key;
93
+ }
94
+ function normalizeAccountRoles(roles, legacyRole) {
95
+ const raw = Array.isArray(roles) ? roles : [];
96
+ const out = [];
97
+ const seen = /* @__PURE__ */ new Set();
98
+ const push = (value) => {
99
+ const role = normalizeAccountRole(typeof value === "string" ? value : "");
100
+ if (!role || seen.has(role) || out.length >= ACCOUNT_ROLE_MAX) return;
101
+ seen.add(role);
102
+ out.push(role);
103
+ };
104
+ for (const item of raw) push(item);
105
+ if (out.length === 0) push(legacyRole);
106
+ return out;
107
+ }
108
+ function normalizeProfileNotes(value) {
109
+ if (typeof value !== "string") return "";
110
+ return value.replace(/\r\n/g, "\n").trim().slice(0, PROFILE_NOTES_MAX);
111
+ }
112
+ function reviewTeamHintsForRoles(roles) {
113
+ const seen = /* @__PURE__ */ new Set();
114
+ const out = [];
115
+ for (const role of roles) {
116
+ const hints = ROLE_TEAM_HINTS[role] ?? teamHintsForCustomRole(role);
117
+ for (const hint of hints) {
118
+ const key = hint.toLowerCase();
119
+ if (seen.has(key)) continue;
120
+ seen.add(key);
121
+ out.push(hint);
122
+ }
123
+ }
124
+ return out;
125
+ }
126
+ function teamHintsForCustomRole(role) {
127
+ const slug = role.trim().toLowerCase();
128
+ if (!slug) return [];
129
+ if (slug.endsWith("-team") || slug.endsWith("-squad")) return [slug];
130
+ return [`${slug}-team`, slug];
131
+ }
132
+ function resolveAccountProfile(input) {
133
+ return resolveViewerProfile(input);
134
+ }
135
+ function resolveViewerProfile(account, project) {
136
+ const accountRoles = normalizeAccountRoles(account?.roles, account?.role);
137
+ const projectRoles = normalizeAccountRoles(project?.roles, project?.role);
138
+ const rolesFromProject = projectRoles.length > 0;
139
+ const roles = rolesFromProject ? projectRoles : accountRoles;
140
+ const accountNotes = normalizeProfileNotes(account?.notes);
141
+ const projectNotes = normalizeProfileNotes(project?.notes);
142
+ const notes = [accountNotes, projectNotes].filter(Boolean).join("\n");
143
+ return {
144
+ roles,
145
+ roleLabels: roles.map((role) => accountRoleLabel(role)),
146
+ reviewTeamHints: reviewTeamHintsForRoles(roles),
147
+ notes,
148
+ accountNotes,
149
+ projectNotes,
150
+ rolesFromProject
151
+ };
152
+ }
153
+ function preferTeamsForRole(viewerTeams, hints) {
154
+ const teams = viewerTeams.map((t) => t.trim()).filter(Boolean);
155
+ const want = hints.map((t) => t.trim()).filter(Boolean);
156
+ if (!want.length) return teams;
157
+ if (!teams.length) return want;
158
+ const hintKeys = want.map((t) => t.toLowerCase());
159
+ const matched = teams.filter((team) => {
160
+ const key = team.toLowerCase();
161
+ return hintKeys.some((hint) => key === hint || key.includes(hint) || hint.includes(key));
162
+ });
163
+ return matched.length ? matched : teams;
164
+ }
165
+ function compactNotes(notes, max = 160) {
166
+ const oneLine = notes.replace(/\s+/g, " ").trim();
167
+ if (oneLine.length <= max) return oneLine;
168
+ return `${oneLine.slice(0, max - 1).trimEnd()}\u2026`;
169
+ }
170
+ function formatAccountProfilePlaybookLine(profile) {
171
+ if (profile.roleLabels.length === 0 && !profile.notes) return "";
172
+ const parts = [];
173
+ if (profile.roleLabels.length) {
174
+ parts.push(
175
+ `roles ${profile.roleLabels.join(", ")} (tickets to work on / PRs to review; prefer those teams)`
176
+ );
177
+ }
178
+ if (profile.notes) {
179
+ parts.push(`notes: ${compactNotes(profile.notes)}`);
180
+ }
181
+ return `- Viewer profile: ${parts.join(". ")}. A team review request is not a claim \u2014 only an individual reviewer is. When they ask to find work, use these notes with list_issues (tickets) and list_prs(queue=review) (reviews) and show the options. Only create_thread and start when they also asked to start.`;
182
+ }
183
+ function formatProjectProfilePlaybookLines(projects) {
184
+ const lines = projects.map((project) => {
185
+ const roles = (project.roleLabels ?? []).filter(Boolean);
186
+ const notes = normalizeProfileNotes(project.notes);
187
+ if (!roles.length && !notes) return "";
188
+ const bits = [];
189
+ if (roles.length) bits.push(`roles ${roles.join(", ")}`);
190
+ if (notes) bits.push(compactNotes(notes, 120));
191
+ return `- ${project.name}: ${bits.join(". ")}`;
192
+ }).filter(Boolean);
193
+ if (!lines.length) return "";
194
+ return ["Project overrides (Settings \u2192 Projects; empty roles inherit account):", ...lines].join(
195
+ "\n"
196
+ );
197
+ }
198
+ function formatWorkspaceProfileSuffix(profile) {
199
+ const bits = [];
200
+ if (profile.roles.length) bits.push(`roles:${profile.roles.join(",")}`);
201
+ if (profile.projectNotes) bits.push(`notes:${compactNotes(profile.projectNotes, 80)}`);
202
+ return bits.length ? ` ${bits.join(" ")}` : "";
203
+ }
204
+
66
205
  // src/store/secret-vault.ts
67
206
  import { join } from "path";
68
207
 
@@ -543,8 +682,49 @@ function normalizeDefaults(raw) {
543
682
  if (typeof source.fast === "boolean") {
544
683
  out.fast = source.fast;
545
684
  }
685
+ const roles = normalizeAccountRoles(source.roles, source.role);
686
+ if (roles.length) out.roles = roles;
687
+ const notes = normalizeProfileNotes(source.notes);
688
+ if (notes) out.notes = notes;
689
+ return out;
690
+ }
691
+ function profileRepoKey(path) {
692
+ return path.trim().replace(/\/+$/, "");
693
+ }
694
+ function normalizeProjectProfile(raw) {
695
+ if (!raw || typeof raw !== "object") return void 0;
696
+ const source = raw;
697
+ const out = {};
698
+ const roles = normalizeAccountRoles(source.roles, source.role);
699
+ if (roles.length) out.roles = roles;
700
+ const notes = normalizeProfileNotes(source.notes);
701
+ if (notes) out.notes = notes;
702
+ return out.roles || out.notes ? out : void 0;
703
+ }
704
+ function normalizeProjects(raw) {
705
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return {};
706
+ const out = {};
707
+ for (const [path, value] of Object.entries(raw)) {
708
+ const key = profileRepoKey(path);
709
+ if (!key) continue;
710
+ const profile = normalizeProjectProfile(value);
711
+ if (profile) out[key] = profile;
712
+ }
546
713
  return out;
547
714
  }
715
+ function findProjectProfileKey(projects, repoPath) {
716
+ const want = profileRepoKey(repoPath ?? "");
717
+ if (!want) return void 0;
718
+ if (projects[want]) return want;
719
+ for (const key of Object.keys(projects)) {
720
+ const stored = profileRepoKey(key);
721
+ if (!stored) continue;
722
+ if (stored === want || want.startsWith(`${stored}/`) || stored.startsWith(`${want}/`)) {
723
+ return key;
724
+ }
725
+ }
726
+ return void 0;
727
+ }
548
728
  function normalizeAdvanced(raw) {
549
729
  if (!raw || typeof raw !== "object") return {};
550
730
  const source = raw;
@@ -615,6 +795,7 @@ function normalizeSettings(raw) {
615
795
  let brightsy = {};
616
796
  let integrations = {};
617
797
  let defaults = {};
798
+ let projects = {};
618
799
  let advanced = {};
619
800
  if (raw && typeof raw === "object") {
620
801
  if ("environment" in raw) {
@@ -647,6 +828,9 @@ function normalizeSettings(raw) {
647
828
  if ("defaults" in raw) {
648
829
  defaults = normalizeDefaults(raw.defaults);
649
830
  }
831
+ if ("projects" in raw) {
832
+ projects = normalizeProjects(raw.projects);
833
+ }
650
834
  if ("advanced" in raw) {
651
835
  advanced = normalizeAdvanced(raw.advanced);
652
836
  }
@@ -659,6 +843,7 @@ function normalizeSettings(raw) {
659
843
  brightsy,
660
844
  integrations,
661
845
  defaults,
846
+ projects,
662
847
  advanced
663
848
  };
664
849
  }
@@ -670,6 +855,7 @@ var EMPTY_SETTINGS = {
670
855
  brightsy: {},
671
856
  integrations: {},
672
857
  defaults: {},
858
+ projects: {},
673
859
  advanced: {}
674
860
  };
675
861
  function readSettingsFile() {
@@ -1083,8 +1269,40 @@ function updateDefaultsSettings(patch) {
1083
1269
  defaults.fast = Boolean(patch.fast);
1084
1270
  }
1085
1271
  }
1272
+ if ("roles" in patch) {
1273
+ const roles = normalizeAccountRoles(patch.roles);
1274
+ if (!roles.length) delete defaults.roles;
1275
+ else defaults.roles = roles;
1276
+ delete defaults.role;
1277
+ }
1278
+ if ("notes" in patch) {
1279
+ const notes = normalizeProfileNotes(patch.notes);
1280
+ if (!notes) delete defaults.notes;
1281
+ else defaults.notes = notes;
1282
+ }
1086
1283
  return saveAppSettings({ ...current, defaults });
1087
1284
  }
1285
+ function updateProjectProfileSettings(repoPath, patch) {
1286
+ const current = loadAppSettings();
1287
+ const key = profileRepoKey(repoPath);
1288
+ if (!key) return current;
1289
+ const projects = { ...current.projects };
1290
+ const existing = projects[key] ?? {};
1291
+ const next = { ...existing };
1292
+ if ("roles" in patch) {
1293
+ const roles = normalizeAccountRoles(patch.roles);
1294
+ if (!roles.length) delete next.roles;
1295
+ else next.roles = roles;
1296
+ }
1297
+ if ("notes" in patch) {
1298
+ const notes = normalizeProfileNotes(patch.notes);
1299
+ if (!notes) delete next.notes;
1300
+ else next.notes = notes;
1301
+ }
1302
+ if (!next.roles?.length && !next.notes) delete projects[key];
1303
+ else projects[key] = next;
1304
+ return saveAppSettings({ ...current, projects });
1305
+ }
1088
1306
  function getDefaultAgent(settings = loadAppSettings()) {
1089
1307
  return settings.defaults.agent ?? "claude";
1090
1308
  }
@@ -1098,6 +1316,14 @@ function getDefaultEffort(settings = loadAppSettings()) {
1098
1316
  function getDefaultFast(settings = loadAppSettings()) {
1099
1317
  return settings.defaults.fast === true;
1100
1318
  }
1319
+ function resolveAccountProfileFromSettings(settings = loadAppSettings()) {
1320
+ return resolveViewerProfile(settings.defaults);
1321
+ }
1322
+ function resolveViewerProfileForRepo(repoPath, settings = loadAppSettings()) {
1323
+ const key = findProjectProfileKey(settings.projects, repoPath);
1324
+ const project = key ? settings.projects[key] : void 0;
1325
+ return resolveViewerProfile(settings.defaults, project);
1326
+ }
1101
1327
  function resolveThreadDefaults(settings = loadAppSettings()) {
1102
1328
  return {
1103
1329
  agent: getDefaultAgent(settings),
@@ -1461,6 +1687,19 @@ export {
1461
1687
  readSecureJson,
1462
1688
  writeSecureJson,
1463
1689
  isSecureFileEncrypted,
1690
+ ACCOUNT_ROLE_PRESETS,
1691
+ ACCOUNT_ROLES,
1692
+ ACCOUNT_ROLE_MAX,
1693
+ PROFILE_NOTES_MAX,
1694
+ ACCOUNT_ROLE_LABELS,
1695
+ accountRoleLabel,
1696
+ reviewTeamHintsForRoles,
1697
+ resolveAccountProfile,
1698
+ resolveViewerProfile,
1699
+ preferTeamsForRole,
1700
+ formatAccountProfilePlaybookLine,
1701
+ formatProjectProfilePlaybookLines,
1702
+ formatWorkspaceProfileSuffix,
1464
1703
  ISSUE_SOURCE_LABELS,
1465
1704
  issueSourceLabel,
1466
1705
  HARNESS_ENV_KEYS,
@@ -1470,6 +1709,7 @@ export {
1470
1709
  toPublicAppSettings,
1471
1710
  appSettingsPath,
1472
1711
  claudeUserSettingsPath,
1712
+ findProjectProfileKey,
1473
1713
  loadAppSettings,
1474
1714
  saveAppSettings,
1475
1715
  updateAppEnvironment,
@@ -1479,10 +1719,13 @@ export {
1479
1719
  updateOpencodeSettings,
1480
1720
  updateIntegrationsSettings,
1481
1721
  updateDefaultsSettings,
1722
+ updateProjectProfileSettings,
1482
1723
  getDefaultAgent,
1483
1724
  getDefaultModel,
1484
1725
  getDefaultEffort,
1485
1726
  getDefaultFast,
1727
+ resolveAccountProfileFromSettings,
1728
+ resolveViewerProfileForRepo,
1486
1729
  resolveThreadDefaults,
1487
1730
  resolveNewThreadOptions,
1488
1731
  isLinearConnected,
@@ -291,7 +291,7 @@ function loadWorkspaceSettings(worktreePath, repoPath) {
291
291
  const repoFamily = repoPath && normPath2(repoPath) !== normPath2(worktreePath) ? detectFamily(repoPath) : null;
292
292
  const wtToml = wtFamily ? loadCommittedToml(worktreePath, wtFamily) : null;
293
293
  const repoToml = repoPath && repoFamily ? loadCommittedToml(repoPath, repoFamily) : null;
294
- let merged = wtToml ?? repoToml;
294
+ let merged = mergeSettings(repoToml, wtToml);
295
295
  if (repoPath && normPath2(repoPath) !== normPath2(worktreePath)) {
296
296
  merged = mergeSettings(merged, loadAnyLocal(repoPath));
297
297
  }
@@ -8,7 +8,7 @@ import {
8
8
  getAbleTimeHost,
9
9
  isAbleTimeConnected,
10
10
  saveAbleTimeConnection
11
- } from "./chunk-CZD4NRDZ.js";
11
+ } from "./chunk-D7EGJ3EI.js";
12
12
 
13
13
  // src/integrations/abletime-mcp.ts
14
14
  var DEFAULT_ABLETIME_HOST = "https://track.abletime.com";
@@ -6,7 +6,7 @@ import {
6
6
  getAbleTimeHost,
7
7
  isAbleTimeConnected,
8
8
  saveAbleTimeConnection
9
- } from "./chunk-4XNSGDXE.js";
9
+ } from "./chunk-3BWVOUQG.js";
10
10
 
11
11
  // src/integrations/abletime-mcp.ts
12
12
  var DEFAULT_ABLETIME_HOST = "https://track.abletime.com";
@@ -284,7 +284,7 @@ function loadWorkspaceSettings(worktreePath, repoPath) {
284
284
  const repoFamily = repoPath && normPath2(repoPath) !== normPath2(worktreePath) ? detectFamily(repoPath) : null;
285
285
  const wtToml = wtFamily ? loadCommittedToml(worktreePath, wtFamily) : null;
286
286
  const repoToml = repoPath && repoFamily ? loadCommittedToml(repoPath, repoFamily) : null;
287
- let merged = wtToml ?? repoToml;
287
+ let merged = mergeSettings(repoToml, wtToml);
288
288
  if (repoPath && normPath2(repoPath) !== normPath2(worktreePath)) {
289
289
  merged = mergeSettings(merged, loadAnyLocal(repoPath));
290
290
  }