@mastra/factory 0.10.0-alpha.14 → 0.10.0-alpha.3

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 (123) hide show
  1. package/CHANGELOG.md +0 -180
  2. package/dist/auth.d.ts.map +1 -1
  3. package/dist/auth.js +0 -1
  4. package/dist/auth.js.map +1 -1
  5. package/dist/factory.d.ts +0 -8
  6. package/dist/factory.d.ts.map +1 -1
  7. package/dist/factory.js +6 -23
  8. package/dist/factory.js.map +1 -1
  9. package/dist/index.d.ts +0 -2
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +1 -2
  12. package/dist/integrations/base.d.ts +1 -3
  13. package/dist/integrations/base.d.ts.map +1 -1
  14. package/dist/integrations/github/integration.d.ts +0 -14
  15. package/dist/integrations/github/integration.d.ts.map +1 -1
  16. package/dist/integrations/github/integration.js +1 -48
  17. package/dist/integrations/github/integration.js.map +1 -1
  18. package/dist/integrations/github/provenance.d.ts +2 -7
  19. package/dist/integrations/github/provenance.d.ts.map +1 -1
  20. package/dist/integrations/github/provenance.js +2 -16
  21. package/dist/integrations/github/provenance.js.map +1 -1
  22. package/dist/integrations/github/routes.d.ts +1 -8
  23. package/dist/integrations/github/routes.d.ts.map +1 -1
  24. package/dist/integrations/github/routes.js +7 -228
  25. package/dist/integrations/github/routes.js.map +1 -1
  26. package/dist/integrations/github/session-subscriptions.d.ts +0 -9
  27. package/dist/integrations/github/session-subscriptions.d.ts.map +1 -1
  28. package/dist/integrations/github/session-subscriptions.js +1 -39
  29. package/dist/integrations/github/session-subscriptions.js.map +1 -1
  30. package/dist/integrations/linear/routes.d.ts.map +1 -1
  31. package/dist/integrations/linear/routes.js +0 -50
  32. package/dist/integrations/linear/routes.js.map +1 -1
  33. package/dist/integrations/platform/github/integration.d.ts +1 -3
  34. package/dist/integrations/platform/github/integration.d.ts.map +1 -1
  35. package/dist/integrations/platform/github/integration.js +0 -33
  36. package/dist/integrations/platform/github/integration.js.map +1 -1
  37. package/dist/routes/intake.d.ts +0 -5
  38. package/dist/routes/intake.d.ts.map +1 -1
  39. package/dist/routes/intake.js +19 -70
  40. package/dist/routes/intake.js.map +1 -1
  41. package/dist/routes/surface.d.ts +3 -4
  42. package/dist/routes/surface.d.ts.map +1 -1
  43. package/dist/routes/surface.js +12 -10
  44. package/dist/routes/surface.js.map +1 -1
  45. package/dist/routes/work-items.d.ts.map +1 -1
  46. package/dist/routes/work-items.js +1 -1
  47. package/dist/routes/work-items.js.map +1 -1
  48. package/dist/rules/defaults.js +5 -5
  49. package/dist/rules/defaults.js.map +1 -1
  50. package/dist/rules/dispatcher.d.ts +0 -9
  51. package/dist/rules/dispatcher.d.ts.map +1 -1
  52. package/dist/rules/dispatcher.js +17 -69
  53. package/dist/rules/dispatcher.js.map +1 -1
  54. package/dist/rules/processor.d.ts.map +1 -1
  55. package/dist/rules/processor.js +11 -28
  56. package/dist/rules/processor.js.map +1 -1
  57. package/dist/rules/tools.d.ts.map +1 -1
  58. package/dist/rules/tools.js +5 -9
  59. package/dist/rules/tools.js.map +1 -1
  60. package/dist/rules/transition-service.d.ts +2 -5
  61. package/dist/rules/transition-service.d.ts.map +1 -1
  62. package/dist/rules/transition-service.js +2 -15
  63. package/dist/rules/transition-service.js.map +1 -1
  64. package/dist/rules/types.d.ts +1 -4
  65. package/dist/rules/types.d.ts.map +1 -1
  66. package/dist/rules/types.js +1 -17
  67. package/dist/rules/types.js.map +1 -1
  68. package/dist/session/factory-session.d.ts +3 -9
  69. package/dist/session/factory-session.d.ts.map +1 -1
  70. package/dist/session/factory-session.js +4 -5
  71. package/dist/session/factory-session.js.map +1 -1
  72. package/dist/session/first-exec-capture.d.ts +10 -16
  73. package/dist/session/first-exec-capture.d.ts.map +1 -1
  74. package/dist/session/first-exec-capture.js +14 -74
  75. package/dist/session/first-exec-capture.js.map +1 -1
  76. package/dist/session/first-message-capture.d.ts +10 -14
  77. package/dist/session/first-message-capture.d.ts.map +1 -1
  78. package/dist/session/first-message-capture.js +11 -17
  79. package/dist/session/first-message-capture.js.map +1 -1
  80. package/dist/storage/domains/credentials/base.d.ts +1 -3
  81. package/dist/storage/domains/credentials/base.d.ts.map +1 -1
  82. package/dist/storage/domains/credentials/base.js +15 -33
  83. package/dist/storage/domains/credentials/base.js.map +1 -1
  84. package/dist/storage/domains/custom-providers/base.d.ts +1 -3
  85. package/dist/storage/domains/custom-providers/base.d.ts.map +1 -1
  86. package/dist/storage/domains/custom-providers/base.js +25 -45
  87. package/dist/storage/domains/custom-providers/base.js.map +1 -1
  88. package/dist/storage/domains/integrations/base.d.ts +1 -3
  89. package/dist/storage/domains/integrations/base.d.ts.map +1 -1
  90. package/dist/storage/domains/integrations/base.js +12 -28
  91. package/dist/storage/domains/integrations/base.js.map +1 -1
  92. package/dist/storage/domains/source-control/base.d.ts +0 -5
  93. package/dist/storage/domains/source-control/base.d.ts.map +1 -1
  94. package/dist/storage/domains/source-control/base.js +0 -6
  95. package/dist/storage/domains/source-control/base.js.map +1 -1
  96. package/dist/storage/domains/source-control/inmemory.d.ts +0 -4
  97. package/dist/storage/domains/source-control/inmemory.d.ts.map +1 -1
  98. package/dist/storage/domains/source-control/inmemory.js +0 -7
  99. package/dist/storage/domains/source-control/inmemory.js.map +1 -1
  100. package/dist/storage/domains/work-items/base.d.ts +2 -21
  101. package/dist/storage/domains/work-items/base.d.ts.map +1 -1
  102. package/dist/storage/domains/work-items/base.js +9 -65
  103. package/dist/storage/domains/work-items/base.js.map +1 -1
  104. package/factory-skills/factory-rereview/SKILL.md +0 -2
  105. package/factory-skills/factory-review/SKILL.md +0 -2
  106. package/factory-skills/factory-triage/SKILL.md +17 -7
  107. package/package.json +9 -9
  108. package/dist/secret-encryption.d.ts +0 -25
  109. package/dist/secret-encryption.d.ts.map +0 -1
  110. package/dist/secret-encryption.js +0 -96
  111. package/dist/secret-encryption.js.map +0 -1
  112. package/dist/session/session-title.d.ts +0 -7
  113. package/dist/session/session-title.d.ts.map +0 -1
  114. package/dist/session/session-title.js +0 -14
  115. package/dist/session/session-title.js.map +0 -1
  116. package/dist/session/thread-title-mirror.d.ts +0 -35
  117. package/dist/session/thread-title-mirror.d.ts.map +0 -1
  118. package/dist/session/thread-title-mirror.js +0 -51
  119. package/dist/session/thread-title-mirror.js.map +0 -1
  120. package/dist/work-item-branch.d.ts +0 -23
  121. package/dist/work-item-branch.d.ts.map +0 -1
  122. package/dist/work-item-branch.js +0 -39
  123. package/dist/work-item-branch.js.map +0 -1
@@ -3,15 +3,12 @@ import { listPullRequestSubscriptionsForThread, subscribeToPullRequest } from ".
3
3
  import { SandboxBudgetError } from "../../sandbox/fleet.js";
4
4
  import { MaterializeError, WorktreeError, commitAll, ensureProjectSandbox, isValidGitRef as isValidGitRef$1, materializeRepo, pushBranch, teardownProjectSandbox } from "./sandbox.js";
5
5
  import { baseCheckpointIsStale } from "../../sandbox/base-checkpoint-triggers.js";
6
- import { normalizeSessionTitle } from "../../session/session-title.js";
7
6
  import { getGithubFeatureDiagnostics, isGithubFeatureEnabled } from "./config.js";
8
7
  import { reclaimDeletedSessionSandbox } from "./sandbox-release.js";
9
8
  import { handleGithubWebhook } from "./webhook.js";
10
9
  import { registerApiRoute } from "@mastra/core/server";
11
10
  import { randomUUID } from "crypto";
12
11
  import { UniqueViolationError } from "@mastra/core/storage";
13
- import { resolveModel } from "@mastra/code-sdk/agents/model";
14
- import { RequestContext } from "@mastra/core/request-context";
15
12
  import { streamSSE } from "hono/streaming";
16
13
  //#region src/integrations/github/routes.ts
17
14
  /**
@@ -27,6 +24,7 @@ import { streamSSE } from "hono/streaming";
27
24
  * so the SPA can cleanly hide all GitHub UI.
28
25
  */
29
26
  const sessionOperationLocks = /* @__PURE__ */ new Map();
27
+ const MAX_SESSION_TITLE_LENGTH = 80;
30
28
  const USER_SESSION_BRANCH_PREFIX = "user/session-";
31
29
  const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
32
30
  /**
@@ -71,6 +69,9 @@ function isValidGitRef(value) {
71
69
  function isJsonObject(value) {
72
70
  return typeof value === "object" && value !== null && !Array.isArray(value);
73
71
  }
72
+ function normalizeSessionTitle(title) {
73
+ return [...title.replace(/\s+/g, " ").trim()].slice(0, MAX_SESSION_TITLE_LENGTH).join("").trimEnd() || null;
74
+ }
74
75
  /**
75
76
  * Resolve the org-scoped tenant for a GitHub request. GitHub project features
76
77
  * are org-owned, so they require both a signed-in user and a WorkOS
@@ -107,11 +108,6 @@ function parseListPage(raw) {
107
108
  const page = Number(raw);
108
109
  return page >= 1 ? page : null;
109
110
  }
110
- function parseResourceNumber(raw) {
111
- if (raw === void 0 || !/^\d{1,10}$/.test(raw)) return null;
112
- const parsed = Number(raw);
113
- return parsed > 0 ? parsed : null;
114
- }
115
111
  const VALID_ISSUE_LABEL_FILTERS = /* @__PURE__ */ new Set(["status: auto-triaged", "status: needs approval"]);
116
112
  function parseIssueLabelFilter(raw) {
117
113
  if (raw === void 0 || raw === "") return void 0;
@@ -212,7 +208,7 @@ async function ingestPolledEvents(events, ingestFactoryEvent) {
212
208
  */
213
209
  function buildGithubRoutes(options) {
214
210
  const routes = [];
215
- const { auth, users, fleet, storage, github, stateSigner, controller, memorySettings, emitAudit, sessionRetirement } = options;
211
+ const { auth, fleet, storage, github, stateSigner, controller, emitAudit, sessionRetirement } = options;
216
212
  const diagnostics = () => getGithubFeatureDiagnostics({
217
213
  github,
218
214
  auth,
@@ -535,48 +531,6 @@ function buildGithubRoutes(options) {
535
531
  }
536
532
  }
537
533
  }));
538
- routes.push(registerApiRoute("/web/github/projects/:id/issues/:number", {
539
- method: "GET",
540
- requiresAuth: false,
541
- handler: async (c) => {
542
- const loaded = await loadOrgProject({
543
- github,
544
- auth,
545
- c: loose(c)
546
- });
547
- if ("response" in loaded) return loaded.response;
548
- const number = parseResourceNumber(c.req.param("number"));
549
- if (number === null) return c.json({ error: "invalid_number" }, 400);
550
- try {
551
- const detail = await github.intake.getIssue({
552
- connection: {
553
- type: "app-installation",
554
- installationId: Number(loaded.project.installation.externalId)
555
- },
556
- sourceId: loaded.project.repository.slug,
557
- issueId: String(number)
558
- });
559
- if (detail === null) return c.json({ error: "issue_not_found" }, 404);
560
- return c.json({
561
- number: Number(detail.id),
562
- title: detail.title,
563
- url: detail.url,
564
- author: detail.author,
565
- assignee: detail.assignee,
566
- labels: detail.labels,
567
- comments: detail.commentCount ?? 0,
568
- createdAt: detail.createdAt,
569
- updatedAt: detail.updatedAt,
570
- description: detail.description
571
- });
572
- } catch (err) {
573
- return c.json({
574
- error: "github_fetch_failed",
575
- message: err instanceof Error ? err.message : String(err)
576
- }, 502);
577
- }
578
- }
579
- }));
580
534
  routes.push(registerApiRoute("/web/github/projects/:id/prs", {
581
535
  method: "GET",
582
536
  requiresAuth: false,
@@ -624,49 +578,6 @@ function buildGithubRoutes(options) {
624
578
  }
625
579
  }
626
580
  }));
627
- routes.push(registerApiRoute("/web/github/projects/:id/prs/:number", {
628
- method: "GET",
629
- requiresAuth: false,
630
- handler: async (c) => {
631
- const loaded = await loadOrgProject({
632
- github,
633
- auth,
634
- c: loose(c)
635
- });
636
- if ("response" in loaded) return loaded.response;
637
- const number = parseResourceNumber(c.req.param("number"));
638
- if (number === null) return c.json({ error: "invalid_number" }, 400);
639
- try {
640
- const pr = await github.versionControl.getPullRequest({
641
- connection: {
642
- type: "app-installation",
643
- installationId: Number(loaded.project.installation.externalId)
644
- },
645
- sourceId: loaded.project.repository.slug,
646
- pullRequestId: String(number)
647
- });
648
- if (pr === null) return c.json({ error: "pull_request_not_found" }, 404);
649
- return c.json({
650
- number: Number(pr.id),
651
- title: pr.title,
652
- url: pr.url,
653
- author: pr.author,
654
- assignees: pr.assignees ?? [],
655
- requestedReviewers: pr.requestedReviewers ?? [],
656
- baseBranch: pr.baseBranch,
657
- headBranch: pr.headBranch,
658
- createdAt: pr.createdAt,
659
- updatedAt: pr.updatedAt,
660
- description: pr.body
661
- });
662
- } catch (err) {
663
- return c.json({
664
- error: "github_fetch_failed",
665
- message: err instanceof Error ? err.message : String(err)
666
- }, 502);
667
- }
668
- }
669
- }));
670
581
  routes.push(registerApiRoute("/web/github/projects/:id/settings", {
671
582
  method: "GET",
672
583
  requiresAuth: false,
@@ -775,10 +686,8 @@ function buildGithubRoutes(options) {
775
686
  routes.push(...buildProjectGitRoutes({
776
687
  github,
777
688
  auth,
778
- users,
779
689
  fleet,
780
690
  controller,
781
- memorySettings,
782
691
  emitAudit,
783
692
  sessionRetirement
784
693
  }));
@@ -985,87 +894,7 @@ async function loadOwnedProject(options) {
985
894
  sandboxRow: await loadOrCreateSandboxRow(github, project, userId)
986
895
  };
987
896
  }
988
- /**
989
- * One naming per session at a time: a second caller joins the run already in
990
- * flight instead of paying for another model call and racing its rename.
991
- */
992
- function createSessionNaming() {
993
- const inFlight = /* @__PURE__ */ new Map();
994
- return (sessionId, run) => {
995
- const pending = inFlight.get(sessionId);
996
- if (pending) return pending;
997
- const started = run().finally(() => inFlight.delete(sessionId));
998
- inFlight.set(sessionId, started);
999
- return started;
1000
- };
1001
- }
1002
- /**
1003
- * Name a thread with a stored model id. Resolution has to go through
1004
- * mastracode's gateway: a bare id handed to core's model router looks for a
1005
- * process env key instead of the caller's stored provider credentials.
1006
- */
1007
- function titleModel(modelId) {
1008
- return ({ requestContext }) => resolveModel(modelId, {
1009
- remapForCodexOAuth: true,
1010
- requestContext
1011
- });
1012
- }
1013
- const MAX_SESSION_OWNER_PROFILES = 100;
1014
- const MAX_SESSION_OWNER_PROFILE_CACHE_ENTRIES = 500;
1015
- const SESSION_OWNER_PROFILE_TTL_MS = 5 * 6e4;
1016
- function createSessionOwnerProfileResolver(users) {
1017
- const cache = /* @__PURE__ */ new Map();
1018
- const cacheProfile = (userId, profile, expiresAt) => {
1019
- cache.delete(userId);
1020
- cache.set(userId, {
1021
- profile,
1022
- expiresAt
1023
- });
1024
- if (cache.size > MAX_SESSION_OWNER_PROFILE_CACHE_ENTRIES) {
1025
- const oldestUserId = cache.keys().next().value;
1026
- if (oldestUserId !== void 0) cache.delete(oldestUserId);
1027
- }
1028
- };
1029
- return async (userIds) => {
1030
- if (!users) return /* @__PURE__ */ new Map();
1031
- const requestedUserIds = [...new Set(userIds)].slice(0, MAX_SESSION_OWNER_PROFILES);
1032
- const profiles = /* @__PURE__ */ new Map();
1033
- const unresolvedUserIds = [];
1034
- const now = Date.now();
1035
- for (const userId of requestedUserIds) {
1036
- const cached = cache.get(userId);
1037
- if (!cached || cached.expiresAt <= now) {
1038
- cache.delete(userId);
1039
- unresolvedUserIds.push(userId);
1040
- } else if (cached.profile) profiles.set(userId, cached.profile);
1041
- }
1042
- if (unresolvedUserIds.length === 0) return profiles;
1043
- let resolvedUsers;
1044
- if (users.getUsers) try {
1045
- resolvedUsers = await users.getUsers(unresolvedUserIds);
1046
- } catch (error) {
1047
- console.warn("[GitHub Sessions] Bulk session owner profile lookup failed; falling back to individual lookups", { error: error instanceof Error ? error.message : String(error) });
1048
- resolvedUsers = (await Promise.allSettled(unresolvedUserIds.map((userId) => users.getUser(userId)))).filter((result) => result.status === "fulfilled").map((result) => result.value);
1049
- }
1050
- else resolvedUsers = (await Promise.allSettled(unresolvedUserIds.map((userId) => users.getUser(userId)))).filter((result) => result.status === "fulfilled").map((result) => result.value);
1051
- for (const user of resolvedUsers) {
1052
- if (!user) continue;
1053
- const name = user.name?.trim() || user.email?.trim();
1054
- if (!name) continue;
1055
- profiles.set(user.id, {
1056
- id: user.id,
1057
- name,
1058
- ...user.avatarUrl ? { avatarUrl: user.avatarUrl } : {}
1059
- });
1060
- }
1061
- const expiresAt = now + SESSION_OWNER_PROFILE_TTL_MS;
1062
- for (const userId of unresolvedUserIds) cacheProfile(userId, profiles.get(userId), expiresAt);
1063
- return profiles;
1064
- };
1065
- }
1066
- function buildProjectGitRoutes({ github, auth, users, fleet, controller, memorySettings, emitAudit, sessionRetirement }) {
1067
- const nameSession = createSessionNaming();
1068
- const resolveSessionOwnerProfiles = createSessionOwnerProfileResolver(users);
897
+ function buildProjectGitRoutes({ github, auth, fleet, controller, emitAudit, sessionRetirement }) {
1069
898
  return [
1070
899
  registerApiRoute("/web/github/projects/:id/sessions", {
1071
900
  method: "GET",
@@ -1085,14 +914,7 @@ function buildProjectGitRoutes({ github, auth, users, fleet, controller, memoryS
1085
914
  projectRepositoryId: project.id,
1086
915
  viewerUserId: userId
1087
916
  });
1088
- const owners = await resolveSessionOwnerProfiles(sessions.map((session) => session.userId));
1089
- return c.json({ sessions: sessions.map((session) => {
1090
- const owner = owners.get(session.userId);
1091
- return {
1092
- ...session,
1093
- ...owner ? { owner } : {}
1094
- };
1095
- }) });
917
+ return c.json({ sessions });
1096
918
  }
1097
919
  }),
1098
920
  registerApiRoute("/web/github/projects/:id/sessions", {
@@ -1207,49 +1029,6 @@ function buildProjectGitRoutes({ github, auth, users, fleet, controller, memoryS
1207
1029
  return c.json({ removed: true });
1208
1030
  }
1209
1031
  }),
1210
- registerApiRoute("/web/user-sessions/:sessionId/title", {
1211
- method: "POST",
1212
- requiresAuth: false,
1213
- handler: async (c) => {
1214
- const resolved = await resolveOrgTenant(loose(c), auth);
1215
- if ("response" in resolved) return resolved.response;
1216
- const sessionId = c.req.param("sessionId");
1217
- const row = await github.sourceControlStorage.sessions.getBySessionId(sessionId);
1218
- if (!row || row.orgId !== resolved.tenant.orgId || row.userId !== resolved.tenant.userId) return c.json({ error: "Session not found" }, 404);
1219
- if (!controller) return c.json({ error: "Sessions are not available on this server." }, 503);
1220
- const thread = (await controller.queryThreads({ resourceId: sessionId })).sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime())[0];
1221
- if (!thread) return c.json({ error: "This session has no conversation to name yet." }, 409);
1222
- const stored = await memorySettings.get({
1223
- orgId: row.orgId,
1224
- userId: row.userId
1225
- });
1226
- const requestContext = new RequestContext();
1227
- requestContext.set("user", {
1228
- workosId: row.userId,
1229
- organizationId: row.orgId
1230
- });
1231
- try {
1232
- const title = await nameSession(sessionId, async () => {
1233
- const generated = await controller.generateThreadTitle({
1234
- threadId: thread.id,
1235
- resourceId: sessionId,
1236
- requestContext,
1237
- ...stored?.observerModelId ? { model: titleModel(stored.observerModelId) } : {}
1238
- });
1239
- const named = generated ? normalizeSessionTitle(generated) : null;
1240
- if (named) await github.sourceControlStorage.sessions.rename({
1241
- sessionId,
1242
- title: named
1243
- });
1244
- return named;
1245
- });
1246
- if (!title) return c.json({ error: "The model returned an empty title. Try again." }, 502);
1247
- return c.json({ title });
1248
- } catch (error) {
1249
- return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);
1250
- }
1251
- }
1252
- }),
1253
1032
  registerApiRoute("/web/github/projects/:id/commit", {
1254
1033
  method: "POST",
1255
1034
  requiresAuth: false,