@sideboard-ai/core 0.1.151 → 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-JAOMXDXN.js → agents-V24DYZI4.js} +8 -9
  5. package/dist/{agents-U2JCFXW4.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-GCWAAPJ5.js → chunk-2NRNP7QP.js} +432 -239
  12. package/dist/{chunk-4XNSGDXE.js → chunk-3BWVOUQG.js} +244 -1
  13. package/dist/{chunk-LZAOX76N.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-6H4TJ5TA.js → chunk-KMNODRWF.js} +481 -212
  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-UIS7BVCX.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-LWYUZAXR.js → coordinator-prompt-7FHKCWXB.js} +5 -5
  34. package/dist/{coordinator-prompt-ZK5MII7W.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-IB2CCEJF.js → global-workspace-2BRRKSDN.js} +5 -6
  38. package/dist/{global-workspace-T7RL3XEC.js → global-workspace-4LHCZ2DC.js} +5 -6
  39. package/dist/index.cjs +1961 -786
  40. package/dist/index.d.cts +228 -30
  41. package/dist/index.d.ts +228 -30
  42. package/dist/index.js +322 -110
  43. package/dist/mcp/run-stdio.cjs +1817 -1264
  44. package/dist/mcp/run-stdio.js +250 -82
  45. package/dist/{orchestrator-DPTRBKEH.js → orchestrator-5PSHBLP6.js} +10 -12
  46. package/dist/{orchestrator-Y5MWUU7C.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-ZXCUVCZC.js → workspaces-5UNDTN4G.js} +5 -7
  52. package/dist/{workspaces-VICQYI2N.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-77MP647F.js +0 -210
  57. package/dist/chunk-ADCEGG4A.js +0 -592
  58. package/dist/chunk-HWZWBJWL.js +0 -120
  59. package/dist/chunk-OXOU2FRS.js +0 -212
  60. package/dist/chunk-TSCWSAQL.js +0 -122
  61. package/dist/chunk-Y2FNDKHF.js +0 -538
@@ -10,7 +10,7 @@ import {
10
10
  } from "./chunk-77WWLBCI.js";
11
11
  import {
12
12
  appDataDir
13
- } from "./chunk-QZQEXME2.js";
13
+ } from "./chunk-EFVFB2AH.js";
14
14
 
15
15
  // src/store/app-settings.ts
16
16
  import { randomUUID } from "crypto";
@@ -18,6 +18,145 @@ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
18
18
  import { homedir, hostname } from "os";
19
19
  import { join as join2 } from "path";
20
20
 
21
+ // src/store/account-profile.ts
22
+ var ACCOUNT_ROLE_PRESETS = ["engineering", "design", "product"];
23
+ var ACCOUNT_ROLES = ACCOUNT_ROLE_PRESETS;
24
+ var ACCOUNT_ROLE_MAX = 16;
25
+ var PROFILE_NOTES_MAX = 2e3;
26
+ var ACCOUNT_ROLE_LABELS = {
27
+ engineering: "Engineering",
28
+ design: "Design",
29
+ product: "Product",
30
+ qa: "QA"
31
+ };
32
+ var ROLE_TEAM_HINTS = {
33
+ engineering: ["engineering-team", "engineering", "eng-team"],
34
+ design: ["design-team", "design"],
35
+ product: ["product-team", "product"]
36
+ };
37
+ function accountRoleLabel(role) {
38
+ const known = ACCOUNT_ROLE_LABELS[role];
39
+ if (known) return known;
40
+ return role.split("-").filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
41
+ }
42
+ function normalizeAccountRole(value) {
43
+ const key = (value ?? "").trim().toLowerCase().replace(/[_\s]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
44
+ if (key === "both") return void 0;
45
+ if (key.length < 2 || key.length > 40) return void 0;
46
+ if (!/^[a-z][a-z0-9-]*$/.test(key)) return void 0;
47
+ return key;
48
+ }
49
+ function normalizeAccountRoles(roles, legacyRole) {
50
+ const raw = Array.isArray(roles) ? roles : [];
51
+ const out = [];
52
+ const seen = /* @__PURE__ */ new Set();
53
+ const push = (value) => {
54
+ const role = normalizeAccountRole(typeof value === "string" ? value : "");
55
+ if (!role || seen.has(role) || out.length >= ACCOUNT_ROLE_MAX) return;
56
+ seen.add(role);
57
+ out.push(role);
58
+ };
59
+ for (const item of raw) push(item);
60
+ if (out.length === 0) push(legacyRole);
61
+ return out;
62
+ }
63
+ function normalizeProfileNotes(value) {
64
+ if (typeof value !== "string") return "";
65
+ return value.replace(/\r\n/g, "\n").trim().slice(0, PROFILE_NOTES_MAX);
66
+ }
67
+ function reviewTeamHintsForRoles(roles) {
68
+ const seen = /* @__PURE__ */ new Set();
69
+ const out = [];
70
+ for (const role of roles) {
71
+ const hints = ROLE_TEAM_HINTS[role] ?? teamHintsForCustomRole(role);
72
+ for (const hint of hints) {
73
+ const key = hint.toLowerCase();
74
+ if (seen.has(key)) continue;
75
+ seen.add(key);
76
+ out.push(hint);
77
+ }
78
+ }
79
+ return out;
80
+ }
81
+ function teamHintsForCustomRole(role) {
82
+ const slug = role.trim().toLowerCase();
83
+ if (!slug) return [];
84
+ if (slug.endsWith("-team") || slug.endsWith("-squad")) return [slug];
85
+ return [`${slug}-team`, slug];
86
+ }
87
+ function resolveAccountProfile(input) {
88
+ return resolveViewerProfile(input);
89
+ }
90
+ function resolveViewerProfile(account, project) {
91
+ const accountRoles = normalizeAccountRoles(account?.roles, account?.role);
92
+ const projectRoles = normalizeAccountRoles(project?.roles, project?.role);
93
+ const rolesFromProject = projectRoles.length > 0;
94
+ const roles = rolesFromProject ? projectRoles : accountRoles;
95
+ const accountNotes = normalizeProfileNotes(account?.notes);
96
+ const projectNotes = normalizeProfileNotes(project?.notes);
97
+ const notes = [accountNotes, projectNotes].filter(Boolean).join("\n");
98
+ return {
99
+ roles,
100
+ roleLabels: roles.map((role) => accountRoleLabel(role)),
101
+ reviewTeamHints: reviewTeamHintsForRoles(roles),
102
+ notes,
103
+ accountNotes,
104
+ projectNotes,
105
+ rolesFromProject
106
+ };
107
+ }
108
+ function preferTeamsForRole(viewerTeams, hints) {
109
+ const teams = viewerTeams.map((t) => t.trim()).filter(Boolean);
110
+ const want = hints.map((t) => t.trim()).filter(Boolean);
111
+ if (!want.length) return teams;
112
+ if (!teams.length) return want;
113
+ const hintKeys = want.map((t) => t.toLowerCase());
114
+ const matched = teams.filter((team) => {
115
+ const key = team.toLowerCase();
116
+ return hintKeys.some((hint) => key === hint || key.includes(hint) || hint.includes(key));
117
+ });
118
+ return matched.length ? matched : teams;
119
+ }
120
+ function compactNotes(notes, max = 160) {
121
+ const oneLine = notes.replace(/\s+/g, " ").trim();
122
+ if (oneLine.length <= max) return oneLine;
123
+ return `${oneLine.slice(0, max - 1).trimEnd()}\u2026`;
124
+ }
125
+ function formatAccountProfilePlaybookLine(profile) {
126
+ if (profile.roleLabels.length === 0 && !profile.notes) return "";
127
+ const parts = [];
128
+ if (profile.roleLabels.length) {
129
+ parts.push(
130
+ `roles ${profile.roleLabels.join(", ")} (tickets to work on / PRs to review; prefer those teams)`
131
+ );
132
+ }
133
+ if (profile.notes) {
134
+ parts.push(`notes: ${compactNotes(profile.notes)}`);
135
+ }
136
+ 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.`;
137
+ }
138
+ function formatProjectProfilePlaybookLines(projects) {
139
+ const lines = projects.map((project) => {
140
+ const roles = (project.roleLabels ?? []).filter(Boolean);
141
+ const notes = normalizeProfileNotes(project.notes);
142
+ if (!roles.length && !notes) return "";
143
+ const bits = [];
144
+ if (roles.length) bits.push(`roles ${roles.join(", ")}`);
145
+ if (notes) bits.push(compactNotes(notes, 120));
146
+ return `- ${project.name}: ${bits.join(". ")}`;
147
+ }).filter(Boolean);
148
+ if (!lines.length) return "";
149
+ return ["Project overrides (Settings \u2192 Projects; empty roles inherit account):", ...lines].join(
150
+ "\n"
151
+ );
152
+ }
153
+ function formatWorkspaceProfileSuffix(profile) {
154
+ const bits = [];
155
+ if (profile.roles.length) bits.push(`roles:${profile.roles.join(",")}`);
156
+ if (profile.projectNotes) bits.push(`notes:${compactNotes(profile.projectNotes, 80)}`);
157
+ return bits.length ? ` ${bits.join(" ")}` : "";
158
+ }
159
+
21
160
  // src/store/secret-vault.ts
22
161
  import { join } from "path";
23
162
 
@@ -515,8 +654,49 @@ function normalizeDefaults(raw) {
515
654
  if (typeof source.fast === "boolean") {
516
655
  out.fast = source.fast;
517
656
  }
657
+ const roles = normalizeAccountRoles(source.roles, source.role);
658
+ if (roles.length) out.roles = roles;
659
+ const notes = normalizeProfileNotes(source.notes);
660
+ if (notes) out.notes = notes;
661
+ return out;
662
+ }
663
+ function profileRepoKey(path) {
664
+ return path.trim().replace(/\/+$/, "");
665
+ }
666
+ function normalizeProjectProfile(raw) {
667
+ if (!raw || typeof raw !== "object") return void 0;
668
+ const source = raw;
669
+ const out = {};
670
+ const roles = normalizeAccountRoles(source.roles, source.role);
671
+ if (roles.length) out.roles = roles;
672
+ const notes = normalizeProfileNotes(source.notes);
673
+ if (notes) out.notes = notes;
674
+ return out.roles || out.notes ? out : void 0;
675
+ }
676
+ function normalizeProjects(raw) {
677
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return {};
678
+ const out = {};
679
+ for (const [path, value] of Object.entries(raw)) {
680
+ const key = profileRepoKey(path);
681
+ if (!key) continue;
682
+ const profile = normalizeProjectProfile(value);
683
+ if (profile) out[key] = profile;
684
+ }
518
685
  return out;
519
686
  }
687
+ function findProjectProfileKey(projects, repoPath) {
688
+ const want = profileRepoKey(repoPath ?? "");
689
+ if (!want) return void 0;
690
+ if (projects[want]) return want;
691
+ for (const key of Object.keys(projects)) {
692
+ const stored = profileRepoKey(key);
693
+ if (!stored) continue;
694
+ if (stored === want || want.startsWith(`${stored}/`) || stored.startsWith(`${want}/`)) {
695
+ return key;
696
+ }
697
+ }
698
+ return void 0;
699
+ }
520
700
  function normalizeAdvanced(raw) {
521
701
  if (!raw || typeof raw !== "object") return {};
522
702
  const source = raw;
@@ -587,6 +767,7 @@ function normalizeSettings(raw) {
587
767
  let brightsy = {};
588
768
  let integrations = {};
589
769
  let defaults = {};
770
+ let projects = {};
590
771
  let advanced = {};
591
772
  if (raw && typeof raw === "object") {
592
773
  if ("environment" in raw) {
@@ -619,6 +800,9 @@ function normalizeSettings(raw) {
619
800
  if ("defaults" in raw) {
620
801
  defaults = normalizeDefaults(raw.defaults);
621
802
  }
803
+ if ("projects" in raw) {
804
+ projects = normalizeProjects(raw.projects);
805
+ }
622
806
  if ("advanced" in raw) {
623
807
  advanced = normalizeAdvanced(raw.advanced);
624
808
  }
@@ -631,6 +815,7 @@ function normalizeSettings(raw) {
631
815
  brightsy,
632
816
  integrations,
633
817
  defaults,
818
+ projects,
634
819
  advanced
635
820
  };
636
821
  }
@@ -642,6 +827,7 @@ var EMPTY_SETTINGS = {
642
827
  brightsy: {},
643
828
  integrations: {},
644
829
  defaults: {},
830
+ projects: {},
645
831
  advanced: {}
646
832
  };
647
833
  function readSettingsFile() {
@@ -1055,8 +1241,40 @@ function updateDefaultsSettings(patch) {
1055
1241
  defaults.fast = Boolean(patch.fast);
1056
1242
  }
1057
1243
  }
1244
+ if ("roles" in patch) {
1245
+ const roles = normalizeAccountRoles(patch.roles);
1246
+ if (!roles.length) delete defaults.roles;
1247
+ else defaults.roles = roles;
1248
+ delete defaults.role;
1249
+ }
1250
+ if ("notes" in patch) {
1251
+ const notes = normalizeProfileNotes(patch.notes);
1252
+ if (!notes) delete defaults.notes;
1253
+ else defaults.notes = notes;
1254
+ }
1058
1255
  return saveAppSettings({ ...current, defaults });
1059
1256
  }
1257
+ function updateProjectProfileSettings(repoPath, patch) {
1258
+ const current = loadAppSettings();
1259
+ const key = profileRepoKey(repoPath);
1260
+ if (!key) return current;
1261
+ const projects = { ...current.projects };
1262
+ const existing = projects[key] ?? {};
1263
+ const next = { ...existing };
1264
+ if ("roles" in patch) {
1265
+ const roles = normalizeAccountRoles(patch.roles);
1266
+ if (!roles.length) delete next.roles;
1267
+ else next.roles = roles;
1268
+ }
1269
+ if ("notes" in patch) {
1270
+ const notes = normalizeProfileNotes(patch.notes);
1271
+ if (!notes) delete next.notes;
1272
+ else next.notes = notes;
1273
+ }
1274
+ if (!next.roles?.length && !next.notes) delete projects[key];
1275
+ else projects[key] = next;
1276
+ return saveAppSettings({ ...current, projects });
1277
+ }
1060
1278
  function getDefaultAgent(settings = loadAppSettings()) {
1061
1279
  return settings.defaults.agent ?? "claude";
1062
1280
  }
@@ -1070,6 +1288,14 @@ function getDefaultEffort(settings = loadAppSettings()) {
1070
1288
  function getDefaultFast(settings = loadAppSettings()) {
1071
1289
  return settings.defaults.fast === true;
1072
1290
  }
1291
+ function resolveAccountProfileFromSettings(settings = loadAppSettings()) {
1292
+ return resolveViewerProfile(settings.defaults);
1293
+ }
1294
+ function resolveViewerProfileForRepo(repoPath, settings = loadAppSettings()) {
1295
+ const key = findProjectProfileKey(settings.projects, repoPath);
1296
+ const project = key ? settings.projects[key] : void 0;
1297
+ return resolveViewerProfile(settings.defaults, project);
1298
+ }
1073
1299
  function resolveThreadDefaults(settings = loadAppSettings()) {
1074
1300
  return {
1075
1301
  agent: getDefaultAgent(settings),
@@ -1424,6 +1650,19 @@ function harnessEnvKey(harness) {
1424
1650
  }
1425
1651
 
1426
1652
  export {
1653
+ ACCOUNT_ROLE_PRESETS,
1654
+ ACCOUNT_ROLES,
1655
+ ACCOUNT_ROLE_MAX,
1656
+ PROFILE_NOTES_MAX,
1657
+ ACCOUNT_ROLE_LABELS,
1658
+ accountRoleLabel,
1659
+ reviewTeamHintsForRoles,
1660
+ resolveAccountProfile,
1661
+ resolveViewerProfile,
1662
+ preferTeamsForRole,
1663
+ formatAccountProfilePlaybookLine,
1664
+ formatProjectProfilePlaybookLines,
1665
+ formatWorkspaceProfileSuffix,
1427
1666
  setVaultMasterKey,
1428
1667
  persistVaultKeyInKeychain,
1429
1668
  readKeychainVaultKey,
@@ -1441,6 +1680,7 @@ export {
1441
1680
  toPublicAppSettings,
1442
1681
  appSettingsPath,
1443
1682
  claudeUserSettingsPath,
1683
+ findProjectProfileKey,
1444
1684
  loadAppSettings,
1445
1685
  saveAppSettings,
1446
1686
  updateAppEnvironment,
@@ -1450,10 +1690,13 @@ export {
1450
1690
  updateOpencodeSettings,
1451
1691
  updateIntegrationsSettings,
1452
1692
  updateDefaultsSettings,
1693
+ updateProjectProfileSettings,
1453
1694
  getDefaultAgent,
1454
1695
  getDefaultModel,
1455
1696
  getDefaultEffort,
1456
1697
  getDefaultFast,
1698
+ resolveAccountProfileFromSettings,
1699
+ resolveViewerProfileForRepo,
1457
1700
  resolveThreadDefaults,
1458
1701
  resolveNewThreadOptions,
1459
1702
  isLinearConnected,
@@ -5,19 +5,19 @@ import {
5
5
  brightsyMcpServerName,
6
6
  ensureCliTeamTracked,
7
7
  ensureConnectedBrightsyTeamTokens
8
- } from "./chunk-G7SIQFBQ.js";
8
+ } from "./chunk-LZ6QMEQC.js";
9
9
  import {
10
10
  loadBrightsyConfig
11
11
  } from "./chunk-S42XV45P.js";
12
12
  import {
13
13
  isOrchestratorThread
14
- } from "./chunk-Y2FNDKHF.js";
14
+ } from "./chunk-RNC3GR6L.js";
15
15
  import {
16
16
  codexUnattendedGitConfigArgs,
17
17
  mergeAgentGitAuthEnv,
18
18
  resolveAgentGitAuthEnv,
19
19
  resolveCodexGitWritableRoots
20
- } from "./chunk-3JBMACYX.js";
20
+ } from "./chunk-CJQLPPEJ.js";
21
21
  import {
22
22
  enrichPathWithNpmGlobalBin,
23
23
  isConductorBundledCli,
@@ -33,10 +33,10 @@ import {
33
33
  resolveClaudeExecutable,
34
34
  unwrapStrippedElectronLaunch,
35
35
  wrapElectronAsNodeLaunch
36
- } from "./chunk-CZD4NRDZ.js";
36
+ } from "./chunk-D7EGJ3EI.js";
37
37
  import {
38
38
  appDataDir
39
- } from "./chunk-BD2ICC4D.js";
39
+ } from "./chunk-JTJHOYCU.js";
40
40
 
41
41
  // src/agents/brightsy.ts
42
42
  import { existsSync } from "fs";
@@ -2098,7 +2098,7 @@ var claudeAdapter = {
2098
2098
  );
2099
2099
  }
2100
2100
  const mode = permissionMode(thread);
2101
- const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-T7RL3XEC.js");
2101
+ const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-4LHCZ2DC.js");
2102
2102
  const isOrchestrator = isOrchestratorThread2(thread);
2103
2103
  const injectedServers = await buildInjectedMcpServers({
2104
2104
  includeSideboard: true,
@@ -5,7 +5,7 @@ import {
5
5
  threadFilePath,
6
6
  threadLockPath,
7
7
  threadsDir
8
- } from "./chunk-QZQEXME2.js";
8
+ } from "./chunk-EFVFB2AH.js";
9
9
 
10
10
  // src/store/thread-store.ts
11
11
  import { randomUUID } from "crypto";
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-JT7R45JB.js";
4
4
  import {
5
5
  appDataDir
6
- } from "./chunk-QZQEXME2.js";
6
+ } from "./chunk-EFVFB2AH.js";
7
7
 
8
8
  // src/store/caffeinate-hold.ts
9
9
  import { spawn } from "child_process";