@mastra/factory 0.26.0-alpha.1 → 0.26.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 (180) hide show
  1. package/README.md +74 -7
  2. package/dist/boards/define-board.d.ts +19 -0
  3. package/dist/boards/define-board.d.ts.map +1 -1
  4. package/dist/boards/define-board.js +41 -9
  5. package/dist/boards/define-board.js.map +1 -1
  6. package/dist/boards/project-boards.d.ts +78 -0
  7. package/dist/boards/project-boards.d.ts.map +1 -0
  8. package/dist/boards/project-boards.js +194 -0
  9. package/dist/boards/project-boards.js.map +1 -0
  10. package/dist/boards/review.js +2 -2
  11. package/dist/boards/review.js.map +1 -1
  12. package/dist/boards/stored-board.d.ts +101 -0
  13. package/dist/boards/stored-board.d.ts.map +1 -0
  14. package/dist/boards/stored-board.js +139 -0
  15. package/dist/boards/stored-board.js.map +1 -0
  16. package/dist/boards/work.d.ts.map +1 -1
  17. package/dist/boards/work.js +6 -3
  18. package/dist/boards/work.js.map +1 -1
  19. package/dist/capabilities/intake.d.ts +6 -0
  20. package/dist/capabilities/intake.d.ts.map +1 -1
  21. package/dist/environment/build.d.ts +1 -1
  22. package/dist/environment/build.d.ts.map +1 -1
  23. package/dist/environment/build.js +2 -0
  24. package/dist/environment/build.js.map +1 -1
  25. package/dist/factory.d.ts +15 -2
  26. package/dist/factory.d.ts.map +1 -1
  27. package/dist/factory.js +51 -12
  28. package/dist/factory.js.map +1 -1
  29. package/dist/integrations/github/integration.d.ts +5 -4
  30. package/dist/integrations/github/integration.d.ts.map +1 -1
  31. package/dist/integrations/github/integration.js +10 -8
  32. package/dist/integrations/github/integration.js.map +1 -1
  33. package/dist/integrations/github/sandbox.d.ts +2 -2
  34. package/dist/integrations/github/sandbox.d.ts.map +1 -1
  35. package/dist/integrations/github/sandbox.js +6 -1
  36. package/dist/integrations/github/sandbox.js.map +1 -1
  37. package/dist/integrations/jira/binding-scope.d.ts +30 -0
  38. package/dist/integrations/jira/binding-scope.d.ts.map +1 -0
  39. package/dist/integrations/jira/binding-scope.js +50 -0
  40. package/dist/integrations/jira/binding-scope.js.map +1 -0
  41. package/dist/integrations/jira/claim.d.ts +12 -0
  42. package/dist/integrations/jira/claim.d.ts.map +1 -1
  43. package/dist/integrations/jira/claim.js +24 -1
  44. package/dist/integrations/jira/claim.js.map +1 -1
  45. package/dist/integrations/jira/intake-jql.d.ts +32 -0
  46. package/dist/integrations/jira/intake-jql.d.ts.map +1 -0
  47. package/dist/integrations/jira/intake-jql.js +57 -0
  48. package/dist/integrations/jira/intake-jql.js.map +1 -0
  49. package/dist/integrations/jira/integration.d.ts +4 -3
  50. package/dist/integrations/jira/integration.d.ts.map +1 -1
  51. package/dist/integrations/jira/integration.js +14 -21
  52. package/dist/integrations/jira/integration.js.map +1 -1
  53. package/dist/integrations/jira/routes.d.ts +3 -0
  54. package/dist/integrations/jira/routes.d.ts.map +1 -1
  55. package/dist/integrations/jira/routes.js +16 -29
  56. package/dist/integrations/jira/routes.js.map +1 -1
  57. package/dist/integrations/jira/rules.d.ts.map +1 -1
  58. package/dist/integrations/jira/rules.js +8 -13
  59. package/dist/integrations/jira/rules.js.map +1 -1
  60. package/dist/integrations/platform/github/integration.d.ts +5 -0
  61. package/dist/integrations/platform/github/integration.d.ts.map +1 -1
  62. package/dist/integrations/platform/github/integration.js +7 -0
  63. package/dist/integrations/platform/github/integration.js.map +1 -1
  64. package/dist/integrations/platform/jira/integration.d.ts +7 -1
  65. package/dist/integrations/platform/jira/integration.d.ts.map +1 -1
  66. package/dist/integrations/platform/jira/integration.js +26 -24
  67. package/dist/integrations/platform/jira/integration.js.map +1 -1
  68. package/dist/integrations/platform/jira/routes.d.ts +3 -0
  69. package/dist/integrations/platform/jira/routes.d.ts.map +1 -1
  70. package/dist/integrations/platform/jira/routes.js +17 -28
  71. package/dist/integrations/platform/jira/routes.js.map +1 -1
  72. package/dist/routes/attention-providers.d.ts +2 -1
  73. package/dist/routes/attention-providers.d.ts.map +1 -1
  74. package/dist/routes/attention-providers.js +3 -2
  75. package/dist/routes/attention-providers.js.map +1 -1
  76. package/dist/routes/attention.d.ts +2 -1
  77. package/dist/routes/attention.d.ts.map +1 -1
  78. package/dist/routes/attention.js.map +1 -1
  79. package/dist/routes/boards.d.ts +30 -0
  80. package/dist/routes/boards.d.ts.map +1 -0
  81. package/dist/routes/boards.js +272 -0
  82. package/dist/routes/boards.js.map +1 -0
  83. package/dist/routes/contracts.d.ts +249 -0
  84. package/dist/routes/contracts.d.ts.map +1 -1
  85. package/dist/routes/contracts.js +107 -35
  86. package/dist/routes/contracts.js.map +1 -1
  87. package/dist/routes/intake.d.ts +15 -10
  88. package/dist/routes/intake.d.ts.map +1 -1
  89. package/dist/routes/intake.js +109 -22
  90. package/dist/routes/intake.js.map +1 -1
  91. package/dist/routes/projects.d.ts +3 -0
  92. package/dist/routes/projects.d.ts.map +1 -1
  93. package/dist/routes/projects.js +10 -1
  94. package/dist/routes/projects.js.map +1 -1
  95. package/dist/routes/surface.d.ts +10 -3
  96. package/dist/routes/surface.d.ts.map +1 -1
  97. package/dist/routes/surface.js +13 -1
  98. package/dist/routes/surface.js.map +1 -1
  99. package/dist/routes/tenant-credentials.d.ts +9 -0
  100. package/dist/routes/tenant-credentials.d.ts.map +1 -1
  101. package/dist/routes/tenant-credentials.js +24 -2
  102. package/dist/routes/tenant-credentials.js.map +1 -1
  103. package/dist/routes/work-items.d.ts +3 -1
  104. package/dist/routes/work-items.d.ts.map +1 -1
  105. package/dist/routes/work-items.js +64 -42
  106. package/dist/routes/work-items.js.map +1 -1
  107. package/dist/rules/dispatch-errors.d.ts.map +1 -1
  108. package/dist/rules/dispatch-errors.js +4 -0
  109. package/dist/rules/dispatch-errors.js.map +1 -1
  110. package/dist/rules/dispatcher.d.ts +7 -1
  111. package/dist/rules/dispatcher.d.ts.map +1 -1
  112. package/dist/rules/dispatcher.js +70 -34
  113. package/dist/rules/dispatcher.js.map +1 -1
  114. package/dist/rules/processor.d.ts +3 -1
  115. package/dist/rules/processor.d.ts.map +1 -1
  116. package/dist/rules/processor.js +11 -6
  117. package/dist/rules/processor.js.map +1 -1
  118. package/dist/rules/tools.d.ts +2 -1
  119. package/dist/rules/tools.d.ts.map +1 -1
  120. package/dist/rules/tools.js +2 -1
  121. package/dist/rules/tools.js.map +1 -1
  122. package/dist/rules/transition-service.d.ts +3 -1
  123. package/dist/rules/transition-service.d.ts.map +1 -1
  124. package/dist/rules/transition-service.js +12 -12
  125. package/dist/rules/transition-service.js.map +1 -1
  126. package/dist/sandbox/local-factory-sandbox.d.ts +4 -1
  127. package/dist/sandbox/local-factory-sandbox.d.ts.map +1 -1
  128. package/dist/sandbox/local-factory-sandbox.js +1 -1
  129. package/dist/sandbox/local-factory-sandbox.js.map +1 -1
  130. package/dist/storage/domains/audit/actions.d.ts +1 -0
  131. package/dist/storage/domains/audit/actions.d.ts.map +1 -1
  132. package/dist/storage/domains/audit/actions.js +6 -1
  133. package/dist/storage/domains/audit/actions.js.map +1 -1
  134. package/dist/storage/domains/boards/base.d.ts +110 -0
  135. package/dist/storage/domains/boards/base.d.ts.map +1 -0
  136. package/dist/storage/domains/boards/base.js +292 -0
  137. package/dist/storage/domains/boards/base.js.map +1 -0
  138. package/dist/storage/domains/boards/schemas.d.ts +11 -0
  139. package/dist/storage/domains/boards/schemas.d.ts.map +1 -0
  140. package/dist/storage/domains/boards/schemas.js +106 -0
  141. package/dist/storage/domains/boards/schemas.js.map +1 -0
  142. package/dist/storage/domains/credentials/base.d.ts +4 -1
  143. package/dist/storage/domains/credentials/base.d.ts.map +1 -1
  144. package/dist/storage/domains/credentials/base.js +5 -2
  145. package/dist/storage/domains/credentials/base.js.map +1 -1
  146. package/dist/storage/domains/intake/base.d.ts +86 -5
  147. package/dist/storage/domains/intake/base.d.ts.map +1 -1
  148. package/dist/storage/domains/intake/base.js +298 -59
  149. package/dist/storage/domains/intake/base.js.map +1 -1
  150. package/dist/storage/domains/projects/base.d.ts +2 -1
  151. package/dist/storage/domains/projects/base.d.ts.map +1 -1
  152. package/dist/storage/domains/projects/base.js +15 -10
  153. package/dist/storage/domains/projects/base.js.map +1 -1
  154. package/dist/storage/domains/work-items/base.d.ts +16 -2
  155. package/dist/storage/domains/work-items/base.d.ts.map +1 -1
  156. package/dist/storage/domains/work-items/base.js +40 -11
  157. package/dist/storage/domains/work-items/base.js.map +1 -1
  158. package/dist/tools/read-tools.d.ts +3 -1
  159. package/dist/tools/read-tools.d.ts.map +1 -1
  160. package/dist/tools/read-tools.js +3 -2
  161. package/dist/tools/read-tools.js.map +1 -1
  162. package/dist/tools/session-tools.d.ts +3 -1
  163. package/dist/tools/session-tools.d.ts.map +1 -1
  164. package/dist/tools/session-tools.js +2 -1
  165. package/dist/tools/session-tools.js.map +1 -1
  166. package/dist/tools/sessions-state-processor.d.ts +3 -1
  167. package/dist/tools/sessions-state-processor.d.ts.map +1 -1
  168. package/dist/tools/sessions-state-processor.js +2 -1
  169. package/dist/tools/sessions-state-processor.js.map +1 -1
  170. package/dist/tools/work-item-tools.d.ts +3 -1
  171. package/dist/tools/work-item-tools.d.ts.map +1 -1
  172. package/dist/tools/work-item-tools.js +3 -2
  173. package/dist/tools/work-item-tools.js.map +1 -1
  174. package/dist/workspace.d.ts +2 -0
  175. package/dist/workspace.d.ts.map +1 -1
  176. package/dist/workspace.js +14 -5
  177. package/dist/workspace.js.map +1 -1
  178. package/factory-skills/factory-plan/SKILL.md +1 -1
  179. package/factory-skills/factory-triage/SKILL.md +18 -7
  180. package/package.json +9 -9
@@ -1,5 +1,6 @@
1
1
  import { boardForWorkItem } from "../boards/semantics.js";
2
2
  import "../boards/index.js";
3
+ import { toBoardSource } from "../boards/project-boards.js";
3
4
  import { WorkItemRelationError } from "../storage/domains/work-items/base.js";
4
5
  import { requirePerson } from "./scope.js";
5
6
  import { factoryWorkItemUrl } from "../links.js";
@@ -106,7 +107,7 @@ function createFactoryWorkItemTools(scope, deps) {
106
107
  if (repository) await requireRepository(repository);
107
108
  const created = await createFactoryWorkItem({
108
109
  workItems: deps.workItems,
109
- boards: deps.boards,
110
+ boards: await toBoardSource(deps.boards).load(project),
110
111
  transitionService: deps.transitionService,
111
112
  audit,
112
113
  ...project,
@@ -269,7 +270,7 @@ function createFactoryWorkItemTools(scope, deps) {
269
270
  inputSchema: z.object({ decisionId }).strict(),
270
271
  execute: async ({ decisionId }) => settled(await retryFactoryDecision({
271
272
  workItems: deps.workItems,
272
- boards: deps.boards,
273
+ boards: await toBoardSource(deps.boards).load(project),
273
274
  ...project,
274
275
  decisionId
275
276
  }))
@@ -1 +1 @@
1
- {"version":3,"file":"work-item-tools.js","names":[],"sources":["../../src/tools/work-item-tools.ts"],"sourcesContent":["/**\n * Factory tools that change work items: file one, move it, settle its\n * decisions, and follow it. They act as the session's person (a human actor),\n * through the same code the board's routes use.\n */\n\nimport { randomUUID } from 'node:crypto';\nimport { createTool } from '@mastra/core/tools';\nimport { z } from 'zod';\n\nimport { boardForWorkItem } from '../boards/index.js';\nimport type { BoardRegistry } from '../boards/index.js';\nimport type { IntegrationTools } from '../integrations/base.js';\nimport { factoryWorkItemUrl } from '../links.js';\nimport { transitionBodySchema } from '../routes/contracts.js';\nimport type { FactoryTransitionService } from '../rules/transition-service.js';\nimport type { SourceControlSessionLookup } from '../session/factory-session.js';\nimport { resolveWorkItemRepository } from '../session/work-item-repository.js';\nimport type { AuditRecorder } from '../storage/domains/audit/domain.js';\nimport type { CommentsDomain } from '../storage/domains/comments/domain.js';\nimport { WorkItemRelationError } from '../storage/domains/work-items/base.js';\nimport type { UpdateWorkItemInput, WorkItemRow, WorkItemsStorage } from '../storage/domains/work-items/base.js';\nimport { createFactoryWorkItem } from '../work-items/create-work-item.js';\nimport type { FactoryAuditEmit } from '../work-items/create-work-item.js';\nimport {\n dismissFactoryDecision,\n resolveFactoryProposal,\n retryFactoryDecision,\n} from '../work-items/decision-actions.js';\nimport type { FactoryDecisionActionResult } from '../work-items/decision-actions.js';\nimport {\n MAX_TEXT,\n findWorkItem,\n workItemRefSchema,\n truncate,\n workItemNotFound,\n workItemNumber,\n workItemStage,\n} from './read-tools.js';\nimport { requirePerson } from './scope.js';\nimport type { FactoryToolScope } from './scope.js';\n\nexport interface FactoryWorkItemToolDependencies {\n workItems: WorkItemsStorage;\n boards: BoardRegistry;\n /** Governed stage moves; filing and moving items refuse while it is unavailable. */\n transitionService: Pick<FactoryTransitionService, 'transition'> | undefined;\n /** Writes audit rows with an explicit actor; tool calls have no HTTP request to read one from. */\n auditRecorder: AuditRecorder;\n /** The feed's front door: validates, touches open boards and mirrors to linked channels. */\n feed: Pick<CommentsDomain, 'createComment'>;\n /** Finds the caller session's source-control provider, whose linked repositories a card can name. */\n sessions: Pick<SourceControlSessionLookup, 'getSourceControlBySessionId'>;\n}\n\nconst repositorySchema = z\n .string()\n .trim()\n .min(3)\n .max(200)\n .regex(/^[^/\\s]+\\/[^/\\s]+$/, 'Use the owner/name form, e.g. \"mastra-ai/mastra\".')\n .describe('A repository linked to this Factory, as owner/name.');\n\nconst decisionId = z.string().trim().uuid().describe('Decision id, from factory_list_attention or inspect.');\n\nfunction briefItem(item: WorkItemRow) {\n return {\n id: item.id,\n number: workItemNumber(item),\n title: truncate(item.title, MAX_TEXT),\n stage: workItemStage(item),\n url:\n factoryWorkItemUrl({\n factoryProjectId: item.factoryProjectId,\n board: boardForWorkItem(item),\n workItemId: item.id,\n }) ?? null,\n };\n}\n\nfunction settled(result: FactoryDecisionActionResult) {\n if (!result.ok) throw new Error(result.message);\n const { decision } = result;\n return { decisionId: decision.id, status: decision.status, workItemId: decision.workItemId };\n}\n\n/** The work-item write and subscription tools for one user session's turn. */\nexport function createFactoryWorkItemTools(\n scope: FactoryToolScope,\n deps: FactoryWorkItemToolDependencies,\n): IntegrationTools {\n const project = { orgId: scope.orgId, factoryProjectId: scope.factoryProjectId };\n const audit: FactoryAuditEmit = async input => {\n await deps.auditRecorder.record({\n orgId: scope.orgId,\n // Turns nobody signed in started are recorded as this session's agent, as their moves are.\n actorId: scope.interactive ? scope.userId : `agent:session:${scope.sessionId}`,\n actorType: scope.interactive ? 'human' : 'agent',\n ...(scope.actorProfile ? { actorProfile: scope.actorProfile } : {}),\n ...input,\n });\n };\n const requireItem = async (ref: string) => {\n const item = await findWorkItem(deps.workItems, scope, ref);\n if (!item) throw workItemNotFound(ref);\n return item;\n };\n /**\n * Check `slug` is a repository linked to this Factory and that a card with\n * `metadata` would run in it (a card synced from an issue follows the\n * issue's repository, which a slug can't override).\n */\n const requireRepository = async (slug: string, metadata: Record<string, unknown> | null = null) => {\n const sourceControl = await deps.sessions.getSourceControlBySessionId(scope.sessionId);\n if (!sourceControl) throw new Error('This session has no source-control provider to look repositories up in.');\n const resolve = (repository?: string) =>\n resolveWorkItemRepository({\n sourceControl,\n ...project,\n item: { metadata: repository ? { ...metadata, repository } : metadata },\n });\n const resolution = await resolve(slug);\n if (resolution.status === 'resolved' && resolution.slug === slug) return;\n if (resolution.status === 'resolved') {\n throw new Error(`This card runs in ${resolution.slug}, which comes from its linked issue and can't be changed.`);\n }\n const linked = await resolve();\n const candidates =\n linked.status === 'ambiguous' ? linked.candidates : linked.status === 'resolved' ? [linked.slug] : [];\n throw new Error(\n candidates.length > 0\n ? `${slug} is not linked to this Factory. Linked repositories: ${candidates.join(', ')}.`\n : `${slug} is not linked to this Factory, and it has no linked repositories.`,\n );\n };\n const follow = (item: WorkItemRow, reason: 'created' | 'subscribed') =>\n deps.workItems.subscribeToWorkItem({\n ...project,\n workItemId: item.id,\n sessionId: scope.sessionId,\n threadId: scope.threadId,\n resourceId: scope.resourceId,\n userId: scope.userId,\n reason,\n });\n\n return {\n factory_create_work_item: createTool({\n id: 'factory_create_work_item',\n description:\n \"File a new work item on this Factory's Work board for the person you are working with. It lands in the board's first phase, exactly like pressing New card, and this session follows it. Check factory_list_work_items for an existing item first. Name the repository when the Factory links more than one; runs refuse to start on a card that doesn't say which.\",\n inputSchema: z\n .object({\n title: z.string().trim().min(1).max(512).describe('Short title, as it should read on the card.'),\n brief: z\n .string()\n .trim()\n .min(1)\n .max(8000)\n .describe('What needs doing and why; posted as the first comment on the card.'),\n repository: repositorySchema.optional(),\n })\n .strict(),\n execute: async ({ title, brief, repository }) => {\n if (repository) await requireRepository(repository);\n const created = await createFactoryWorkItem({\n workItems: deps.workItems,\n boards: deps.boards,\n transitionService: deps.transitionService,\n audit,\n ...project,\n userId: scope.userId,\n ...(scope.actorProfile ? { origin: { actorProfile: scope.actorProfile } } : {}),\n input: { title, ...(repository ? { metadata: { repository } } : {}) },\n });\n if (created.status === 'refused') throw new Error(created.message);\n if (created.status === 'rejected') throw new Error(`The board refused the new item: ${created.reason}`);\n const { item } = created;\n // The card exists from here on: report follow-up failures alongside it\n // rather than failing the call, so the agent doesn't file it twice.\n const warnings: string[] = [];\n try {\n const comment = await deps.feed.createComment({\n orgId: scope.orgId,\n workItemId: item.id,\n author: { kind: 'user', id: scope.userId },\n body: brief,\n });\n if (comment.status !== 'created') {\n warnings.push(\n `The brief was not posted (${comment.status === 'invalid' ? comment.message : comment.status}).`,\n );\n }\n } catch (error) {\n warnings.push(`The brief was not posted: ${error instanceof Error ? error.message : String(error)}`);\n }\n try {\n await follow(item, 'created');\n } catch (error) {\n warnings.push(\n `This session does not follow it yet: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n return warnings.length ? { ...briefItem(item), warnings } : briefItem(item);\n },\n }),\n\n factory_transition_work_item: createTool({\n id: 'factory_transition_work_item',\n description:\n \"Move a work item to another stage of its board, as the person you are working with. The board's rules decide whether the move is allowed and what it starts.\",\n inputSchema: z\n .object({\n workItem: workItemRefSchema,\n stage: z.string().trim().min(1).max(64).describe('Destination stage, e.g. \"planning\" or \"done\".'),\n })\n .strict(),\n execute: async ({ workItem, stage }) => {\n if (!deps.transitionService) throw new Error('Factory stage transitions are not available right now.');\n const item = await requireItem(workItem);\n const parsed = transitionBodySchema.safeParse({\n board: boardForWorkItem(item),\n stage,\n expectedRevision: item.revision,\n requestId: randomUUID(),\n cause: 'factory_tools',\n });\n if (!parsed.success) throw new Error(`\"${stage}\" is not a valid stage name.`);\n const result = await deps.transitionService.transition({\n ...parsed.data,\n ...project,\n workItemId: item.id,\n ...(scope.interactive\n ? {\n actor: { type: 'human' as const, id: scope.userId },\n ...(scope.actorProfile ? { actorProfile: scope.actorProfile } : {}),\n ingress: { ...parsed.data.ingress, identity: `human:${scope.userId}:${parsed.data.ingress.identity}` },\n }\n : {\n // Nobody signed in started this turn: move as this session's agent, so the\n // plan gate and the agent's done gates apply and the move arms no runs.\n actor: { type: 'agent' as const, bindingId: `session:${scope.sessionId}`, role: 'session' },\n ingress: {\n type: 'agent' as const,\n identity: `session:${scope.sessionId}:${parsed.data.ingress.identity}`,\n },\n }),\n });\n if (result.status === 'rejected') throw new Error(`The move was refused (${result.code}): ${result.reason}`);\n return { workItemId: item.id, stage: result.stage, revision: result.revision };\n },\n }),\n\n factory_update_work_item: createTool({\n id: 'factory_update_work_item',\n description:\n \"Edit a work item's fields as the person you are working with: its title, the repository its runs use, its parent item, or pre-approving its plans. Move stages with factory_transition_work_item and start roles with factory_start_session; post to the card's feed for anything else.\",\n inputSchema: z\n .object({\n workItem: workItemRefSchema,\n title: z.string().trim().min(1).max(500).optional().describe('New card title.'),\n repository: repositorySchema.optional(),\n parentWorkItem: workItemRefSchema\n .nullable()\n .optional()\n .describe('Parent work item (id or #number), or null to detach it from its parent.'),\n plansPreapproved: z\n .literal(true)\n .optional()\n .describe(\n \"Pre-approve the item's plans, so its runs no longer stop for plan approval. Can't be undone here.\",\n ),\n })\n .strict()\n .refine(input => Object.keys(input).some(key => key !== 'workItem'), 'Pass at least one field to change.'),\n execute: async ({ workItem, title, repository, parentWorkItem, plansPreapproved }) => {\n // Pre-approval drops the plan-approval gate for good, so it is the person's call.\n if (plansPreapproved) requirePerson(scope, 'pre-approve plans');\n const item = await requireItem(workItem);\n if (repository) await requireRepository(repository, item.metadata);\n let parentWorkItemId: string | null | undefined;\n if (parentWorkItem === null) parentWorkItemId = null;\n else if (parentWorkItem !== undefined) parentWorkItemId = (await requireItem(parentWorkItem)).id;\n const patch: UpdateWorkItemInput = {\n ...(title !== undefined ? { title } : {}),\n ...(repository ? { metadata: { repository } } : {}),\n ...(parentWorkItemId !== undefined ? { parentWorkItemId } : {}),\n ...(plansPreapproved ? { plansPreapproved } : {}),\n };\n let updated: Awaited<ReturnType<WorkItemsStorage['update']>>;\n try {\n updated = await deps.workItems.update({ orgId: scope.orgId, id: item.id, userId: scope.userId, patch });\n } catch (error) {\n if (error instanceof WorkItemRelationError) throw new Error(`The parent was refused: ${error.message}`);\n throw error;\n }\n if (!updated) throw workItemNotFound(workItem);\n const fields = [\n ...(title !== undefined ? ['title'] : []),\n ...(repository ? ['metadata'] : []),\n ...(parentWorkItemId !== undefined ? ['parentWorkItemId'] : []),\n ...(plansPreapproved ? ['plansPreapproved'] : []),\n ];\n await audit({\n action: 'factory.work_item.updated',\n factoryProjectId: scope.factoryProjectId,\n targets: [{ type: 'work_item', id: updated.item.id, name: updated.item.title }],\n metadata: { fields, cause: 'factory_tools' },\n });\n const metadata = updated.item.metadata ?? {};\n return {\n workItem: briefItem(updated.item),\n updated: fields.map(field => (field === 'metadata' ? 'repository' : field)),\n repository: typeof metadata.repository === 'string' ? metadata.repository : null,\n parentWorkItemId: updated.item.parentWorkItemId,\n plansPreapproved: updated.item.plansPreapprovedAt !== null,\n };\n },\n }),\n\n factory_retry_decision: createTool({\n id: 'factory_retry_decision',\n description:\n 'Retry one failed Factory run once its cause is fixed. Refused when the failure cannot be fixed by retrying or the item has moved on.',\n inputSchema: z.object({ decisionId }).strict(),\n execute: async ({ decisionId }) =>\n settled(await retryFactoryDecision({ workItems: deps.workItems, boards: deps.boards, ...project, decisionId })),\n }),\n\n factory_dismiss_decision: createTool({\n id: 'factory_dismiss_decision',\n description: 'Dismiss one proposed Factory run that is no longer wanted.',\n inputSchema: z.object({ decisionId }).strict(),\n execute: async ({ decisionId }) => {\n requirePerson(scope, 'dismiss a proposed run');\n return settled(\n await dismissFactoryDecision({\n workItems: deps.workItems,\n audit,\n ...project,\n userId: scope.userId,\n decisionId,\n }),\n );\n },\n }),\n\n factory_resolve_proposal: createTool({\n id: 'factory_resolve_proposal',\n description:\n \"Approve or dismiss one proposed Factory run. Approving starts the run and lets the item's later runs start without asking.\",\n inputSchema: z.object({ decisionId, action: z.enum(['approve', 'dismiss']) }).strict(),\n execute: async ({ decisionId, action }) => {\n requirePerson(scope, 'approve or dismiss a proposed run');\n return settled(\n await resolveFactoryProposal({\n workItems: deps.workItems,\n audit,\n ...project,\n userId: scope.userId,\n decisionId,\n action,\n }),\n );\n },\n }),\n\n factory_subscribe_work_item: createTool({\n id: 'factory_subscribe_work_item',\n description:\n 'Follow a work item from this session, so you hear about its progress and its sessions report to you. Items you file or start are followed already.',\n inputSchema: z.object({ workItem: workItemRefSchema }).strict(),\n execute: async ({ workItem }) => {\n const item = await requireItem(workItem);\n const subscription = await follow(item, 'subscribed');\n return { workItem: briefItem(item), subscribed: true, reason: subscription.reason };\n },\n }),\n\n factory_unsubscribe_work_item: createTool({\n id: 'factory_unsubscribe_work_item',\n description: 'Stop following a work item from this session.',\n inputSchema: z.object({ workItem: workItemRefSchema }).strict(),\n execute: async ({ workItem }) => {\n const item = await requireItem(workItem);\n const removed = await deps.workItems.unsubscribeFromWorkItem({\n orgId: scope.orgId,\n workItemId: item.id,\n sessionId: scope.sessionId,\n });\n return { workItem: briefItem(item), subscribed: false, wasSubscribed: removed };\n },\n }),\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"work-item-tools.js","names":[],"sources":["../../src/tools/work-item-tools.ts"],"sourcesContent":["/**\n * Factory tools that change work items: file one, move it, settle its\n * decisions, and follow it. They act as the session's person (a human actor),\n * through the same code the board's routes use.\n */\n\nimport { randomUUID } from 'node:crypto';\nimport { createTool } from '@mastra/core/tools';\nimport { z } from 'zod';\n\nimport { boardForWorkItem } from '../boards/index.js';\nimport type { BoardRegistry } from '../boards/index.js';\nimport { toBoardSource } from '../boards/project-boards.js';\nimport type { ProjectBoardSource } from '../boards/project-boards.js';\nimport type { IntegrationTools } from '../integrations/base.js';\nimport { factoryWorkItemUrl } from '../links.js';\nimport { transitionBodySchema } from '../routes/contracts.js';\nimport type { FactoryTransitionService } from '../rules/transition-service.js';\nimport type { SourceControlSessionLookup } from '../session/factory-session.js';\nimport { resolveWorkItemRepository } from '../session/work-item-repository.js';\nimport type { AuditRecorder } from '../storage/domains/audit/domain.js';\nimport type { CommentsDomain } from '../storage/domains/comments/domain.js';\nimport { WorkItemRelationError } from '../storage/domains/work-items/base.js';\nimport type { UpdateWorkItemInput, WorkItemRow, WorkItemsStorage } from '../storage/domains/work-items/base.js';\nimport { createFactoryWorkItem } from '../work-items/create-work-item.js';\nimport type { FactoryAuditEmit } from '../work-items/create-work-item.js';\nimport {\n dismissFactoryDecision,\n resolveFactoryProposal,\n retryFactoryDecision,\n} from '../work-items/decision-actions.js';\nimport type { FactoryDecisionActionResult } from '../work-items/decision-actions.js';\nimport {\n MAX_TEXT,\n findWorkItem,\n workItemRefSchema,\n truncate,\n workItemNotFound,\n workItemNumber,\n workItemStage,\n} from './read-tools.js';\nimport { requirePerson } from './scope.js';\nimport type { FactoryToolScope } from './scope.js';\n\nexport interface FactoryWorkItemToolDependencies {\n workItems: WorkItemsStorage;\n /** A fixed registry, or the per-project boards. */\n boards: BoardRegistry | ProjectBoardSource;\n /** Governed stage moves; filing and moving items refuse while it is unavailable. */\n transitionService: Pick<FactoryTransitionService, 'transition'> | undefined;\n /** Writes audit rows with an explicit actor; tool calls have no HTTP request to read one from. */\n auditRecorder: AuditRecorder;\n /** The feed's front door: validates, touches open boards and mirrors to linked channels. */\n feed: Pick<CommentsDomain, 'createComment'>;\n /** Finds the caller session's source-control provider, whose linked repositories a card can name. */\n sessions: Pick<SourceControlSessionLookup, 'getSourceControlBySessionId'>;\n}\n\nconst repositorySchema = z\n .string()\n .trim()\n .min(3)\n .max(200)\n .regex(/^[^/\\s]+\\/[^/\\s]+$/, 'Use the owner/name form, e.g. \"mastra-ai/mastra\".')\n .describe('A repository linked to this Factory, as owner/name.');\n\nconst decisionId = z.string().trim().uuid().describe('Decision id, from factory_list_attention or inspect.');\n\nfunction briefItem(item: WorkItemRow) {\n return {\n id: item.id,\n number: workItemNumber(item),\n title: truncate(item.title, MAX_TEXT),\n stage: workItemStage(item),\n url:\n factoryWorkItemUrl({\n factoryProjectId: item.factoryProjectId,\n board: boardForWorkItem(item),\n workItemId: item.id,\n }) ?? null,\n };\n}\n\nfunction settled(result: FactoryDecisionActionResult) {\n if (!result.ok) throw new Error(result.message);\n const { decision } = result;\n return { decisionId: decision.id, status: decision.status, workItemId: decision.workItemId };\n}\n\n/** The work-item write and subscription tools for one user session's turn. */\nexport function createFactoryWorkItemTools(\n scope: FactoryToolScope,\n deps: FactoryWorkItemToolDependencies,\n): IntegrationTools {\n const project = { orgId: scope.orgId, factoryProjectId: scope.factoryProjectId };\n const audit: FactoryAuditEmit = async input => {\n await deps.auditRecorder.record({\n orgId: scope.orgId,\n // Turns nobody signed in started are recorded as this session's agent, as their moves are.\n actorId: scope.interactive ? scope.userId : `agent:session:${scope.sessionId}`,\n actorType: scope.interactive ? 'human' : 'agent',\n ...(scope.actorProfile ? { actorProfile: scope.actorProfile } : {}),\n ...input,\n });\n };\n const requireItem = async (ref: string) => {\n const item = await findWorkItem(deps.workItems, scope, ref);\n if (!item) throw workItemNotFound(ref);\n return item;\n };\n /**\n * Check `slug` is a repository linked to this Factory and that a card with\n * `metadata` would run in it (a card synced from an issue follows the\n * issue's repository, which a slug can't override).\n */\n const requireRepository = async (slug: string, metadata: Record<string, unknown> | null = null) => {\n const sourceControl = await deps.sessions.getSourceControlBySessionId(scope.sessionId);\n if (!sourceControl) throw new Error('This session has no source-control provider to look repositories up in.');\n const resolve = (repository?: string) =>\n resolveWorkItemRepository({\n sourceControl,\n ...project,\n item: { metadata: repository ? { ...metadata, repository } : metadata },\n });\n const resolution = await resolve(slug);\n if (resolution.status === 'resolved' && resolution.slug === slug) return;\n if (resolution.status === 'resolved') {\n throw new Error(`This card runs in ${resolution.slug}, which comes from its linked issue and can't be changed.`);\n }\n const linked = await resolve();\n const candidates =\n linked.status === 'ambiguous' ? linked.candidates : linked.status === 'resolved' ? [linked.slug] : [];\n throw new Error(\n candidates.length > 0\n ? `${slug} is not linked to this Factory. Linked repositories: ${candidates.join(', ')}.`\n : `${slug} is not linked to this Factory, and it has no linked repositories.`,\n );\n };\n const follow = (item: WorkItemRow, reason: 'created' | 'subscribed') =>\n deps.workItems.subscribeToWorkItem({\n ...project,\n workItemId: item.id,\n sessionId: scope.sessionId,\n threadId: scope.threadId,\n resourceId: scope.resourceId,\n userId: scope.userId,\n reason,\n });\n\n return {\n factory_create_work_item: createTool({\n id: 'factory_create_work_item',\n description:\n \"File a new work item on this Factory's Work board for the person you are working with. It lands in the board's first phase, exactly like pressing New card, and this session follows it. Check factory_list_work_items for an existing item first. Name the repository when the Factory links more than one; runs refuse to start on a card that doesn't say which.\",\n inputSchema: z\n .object({\n title: z.string().trim().min(1).max(512).describe('Short title, as it should read on the card.'),\n brief: z\n .string()\n .trim()\n .min(1)\n .max(8000)\n .describe('What needs doing and why; posted as the first comment on the card.'),\n repository: repositorySchema.optional(),\n })\n .strict(),\n execute: async ({ title, brief, repository }) => {\n if (repository) await requireRepository(repository);\n const created = await createFactoryWorkItem({\n workItems: deps.workItems,\n boards: await toBoardSource(deps.boards).load(project),\n transitionService: deps.transitionService,\n audit,\n ...project,\n userId: scope.userId,\n ...(scope.actorProfile ? { origin: { actorProfile: scope.actorProfile } } : {}),\n input: { title, ...(repository ? { metadata: { repository } } : {}) },\n });\n if (created.status === 'refused') throw new Error(created.message);\n if (created.status === 'rejected') throw new Error(`The board refused the new item: ${created.reason}`);\n const { item } = created;\n // The card exists from here on: report follow-up failures alongside it\n // rather than failing the call, so the agent doesn't file it twice.\n const warnings: string[] = [];\n try {\n const comment = await deps.feed.createComment({\n orgId: scope.orgId,\n workItemId: item.id,\n author: { kind: 'user', id: scope.userId },\n body: brief,\n });\n if (comment.status !== 'created') {\n warnings.push(\n `The brief was not posted (${comment.status === 'invalid' ? comment.message : comment.status}).`,\n );\n }\n } catch (error) {\n warnings.push(`The brief was not posted: ${error instanceof Error ? error.message : String(error)}`);\n }\n try {\n await follow(item, 'created');\n } catch (error) {\n warnings.push(\n `This session does not follow it yet: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n return warnings.length ? { ...briefItem(item), warnings } : briefItem(item);\n },\n }),\n\n factory_transition_work_item: createTool({\n id: 'factory_transition_work_item',\n description:\n \"Move a work item to another stage of its board, as the person you are working with. The board's rules decide whether the move is allowed and what it starts.\",\n inputSchema: z\n .object({\n workItem: workItemRefSchema,\n stage: z.string().trim().min(1).max(64).describe('Destination stage, e.g. \"planning\" or \"done\".'),\n })\n .strict(),\n execute: async ({ workItem, stage }) => {\n if (!deps.transitionService) throw new Error('Factory stage transitions are not available right now.');\n const item = await requireItem(workItem);\n const parsed = transitionBodySchema.safeParse({\n board: boardForWorkItem(item),\n stage,\n expectedRevision: item.revision,\n requestId: randomUUID(),\n cause: 'factory_tools',\n });\n if (!parsed.success) throw new Error(`\"${stage}\" is not a valid stage name.`);\n const result = await deps.transitionService.transition({\n ...parsed.data,\n ...project,\n workItemId: item.id,\n ...(scope.interactive\n ? {\n actor: { type: 'human' as const, id: scope.userId },\n ...(scope.actorProfile ? { actorProfile: scope.actorProfile } : {}),\n ingress: { ...parsed.data.ingress, identity: `human:${scope.userId}:${parsed.data.ingress.identity}` },\n }\n : {\n // Nobody signed in started this turn: move as this session's agent, so the\n // plan gate and the agent's done gates apply and the move arms no runs.\n actor: { type: 'agent' as const, bindingId: `session:${scope.sessionId}`, role: 'session' },\n ingress: {\n type: 'agent' as const,\n identity: `session:${scope.sessionId}:${parsed.data.ingress.identity}`,\n },\n }),\n });\n if (result.status === 'rejected') throw new Error(`The move was refused (${result.code}): ${result.reason}`);\n return { workItemId: item.id, stage: result.stage, revision: result.revision };\n },\n }),\n\n factory_update_work_item: createTool({\n id: 'factory_update_work_item',\n description:\n \"Edit a work item's fields as the person you are working with: its title, the repository its runs use, its parent item, or pre-approving its plans. Move stages with factory_transition_work_item and start roles with factory_start_session; post to the card's feed for anything else.\",\n inputSchema: z\n .object({\n workItem: workItemRefSchema,\n title: z.string().trim().min(1).max(500).optional().describe('New card title.'),\n repository: repositorySchema.optional(),\n parentWorkItem: workItemRefSchema\n .nullable()\n .optional()\n .describe('Parent work item (id or #number), or null to detach it from its parent.'),\n plansPreapproved: z\n .literal(true)\n .optional()\n .describe(\n \"Pre-approve the item's plans, so its runs no longer stop for plan approval. Can't be undone here.\",\n ),\n })\n .strict()\n .refine(input => Object.keys(input).some(key => key !== 'workItem'), 'Pass at least one field to change.'),\n execute: async ({ workItem, title, repository, parentWorkItem, plansPreapproved }) => {\n // Pre-approval drops the plan-approval gate for good, so it is the person's call.\n if (plansPreapproved) requirePerson(scope, 'pre-approve plans');\n const item = await requireItem(workItem);\n if (repository) await requireRepository(repository, item.metadata);\n let parentWorkItemId: string | null | undefined;\n if (parentWorkItem === null) parentWorkItemId = null;\n else if (parentWorkItem !== undefined) parentWorkItemId = (await requireItem(parentWorkItem)).id;\n const patch: UpdateWorkItemInput = {\n ...(title !== undefined ? { title } : {}),\n ...(repository ? { metadata: { repository } } : {}),\n ...(parentWorkItemId !== undefined ? { parentWorkItemId } : {}),\n ...(plansPreapproved ? { plansPreapproved } : {}),\n };\n let updated: Awaited<ReturnType<WorkItemsStorage['update']>>;\n try {\n updated = await deps.workItems.update({ orgId: scope.orgId, id: item.id, userId: scope.userId, patch });\n } catch (error) {\n if (error instanceof WorkItemRelationError) throw new Error(`The parent was refused: ${error.message}`);\n throw error;\n }\n if (!updated) throw workItemNotFound(workItem);\n const fields = [\n ...(title !== undefined ? ['title'] : []),\n ...(repository ? ['metadata'] : []),\n ...(parentWorkItemId !== undefined ? ['parentWorkItemId'] : []),\n ...(plansPreapproved ? ['plansPreapproved'] : []),\n ];\n await audit({\n action: 'factory.work_item.updated',\n factoryProjectId: scope.factoryProjectId,\n targets: [{ type: 'work_item', id: updated.item.id, name: updated.item.title }],\n metadata: { fields, cause: 'factory_tools' },\n });\n const metadata = updated.item.metadata ?? {};\n return {\n workItem: briefItem(updated.item),\n updated: fields.map(field => (field === 'metadata' ? 'repository' : field)),\n repository: typeof metadata.repository === 'string' ? metadata.repository : null,\n parentWorkItemId: updated.item.parentWorkItemId,\n plansPreapproved: updated.item.plansPreapprovedAt !== null,\n };\n },\n }),\n\n factory_retry_decision: createTool({\n id: 'factory_retry_decision',\n description:\n 'Retry one failed Factory run once its cause is fixed. Refused when the failure cannot be fixed by retrying or the item has moved on.',\n inputSchema: z.object({ decisionId }).strict(),\n execute: async ({ decisionId }) =>\n settled(\n await retryFactoryDecision({\n workItems: deps.workItems,\n boards: await toBoardSource(deps.boards).load(project),\n ...project,\n decisionId,\n }),\n ),\n }),\n\n factory_dismiss_decision: createTool({\n id: 'factory_dismiss_decision',\n description: 'Dismiss one proposed Factory run that is no longer wanted.',\n inputSchema: z.object({ decisionId }).strict(),\n execute: async ({ decisionId }) => {\n requirePerson(scope, 'dismiss a proposed run');\n return settled(\n await dismissFactoryDecision({\n workItems: deps.workItems,\n audit,\n ...project,\n userId: scope.userId,\n decisionId,\n }),\n );\n },\n }),\n\n factory_resolve_proposal: createTool({\n id: 'factory_resolve_proposal',\n description:\n \"Approve or dismiss one proposed Factory run. Approving starts the run and lets the item's later runs start without asking.\",\n inputSchema: z.object({ decisionId, action: z.enum(['approve', 'dismiss']) }).strict(),\n execute: async ({ decisionId, action }) => {\n requirePerson(scope, 'approve or dismiss a proposed run');\n return settled(\n await resolveFactoryProposal({\n workItems: deps.workItems,\n audit,\n ...project,\n userId: scope.userId,\n decisionId,\n action,\n }),\n );\n },\n }),\n\n factory_subscribe_work_item: createTool({\n id: 'factory_subscribe_work_item',\n description:\n 'Follow a work item from this session, so you hear about its progress and its sessions report to you. Items you file or start are followed already.',\n inputSchema: z.object({ workItem: workItemRefSchema }).strict(),\n execute: async ({ workItem }) => {\n const item = await requireItem(workItem);\n const subscription = await follow(item, 'subscribed');\n return { workItem: briefItem(item), subscribed: true, reason: subscription.reason };\n },\n }),\n\n factory_unsubscribe_work_item: createTool({\n id: 'factory_unsubscribe_work_item',\n description: 'Stop following a work item from this session.',\n inputSchema: z.object({ workItem: workItemRefSchema }).strict(),\n execute: async ({ workItem }) => {\n const item = await requireItem(workItem);\n const removed = await deps.workItems.unsubscribeFromWorkItem({\n orgId: scope.orgId,\n workItemId: item.id,\n sessionId: scope.sessionId,\n });\n return { workItem: briefItem(item), subscribed: false, wasSubscribed: removed };\n },\n }),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AA0DA,MAAM,mBAAmB,EACtB,OAAO,CAAC,CACR,KAAK,CAAC,CACN,IAAI,CAAC,CAAC,CACN,IAAI,GAAG,CAAC,CACR,MAAM,sBAAsB,qDAAmD,CAAC,CAChF,SAAS,qDAAqD;AAEjE,MAAM,aAAa,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,sDAAsD;AAE3G,SAAS,UAAU,MAAmB;CACpC,OAAO;EACL,IAAI,KAAK;EACT,QAAQ,eAAe,IAAI;EAC3B,OAAO,SAAS,KAAK,OAAA,GAAe;EACpC,OAAO,cAAc,IAAI;EACzB,KACE,mBAAmB;GACjB,kBAAkB,KAAK;GACvB,OAAO,iBAAiB,IAAI;GAC5B,YAAY,KAAK;EACnB,CAAC,KAAK;CACV;AACF;AAEA,SAAS,QAAQ,QAAqC;CACpD,IAAI,CAAC,OAAO,IAAI,MAAM,IAAI,MAAM,OAAO,OAAO;CAC9C,MAAM,EAAE,aAAa;CACrB,OAAO;EAAE,YAAY,SAAS;EAAI,QAAQ,SAAS;EAAQ,YAAY,SAAS;CAAW;AAC7F;;AAGA,SAAgB,2BACd,OACA,MACkB;CAClB,MAAM,UAAU;EAAE,OAAO,MAAM;EAAO,kBAAkB,MAAM;CAAiB;CAC/E,MAAM,QAA0B,OAAM,UAAS;EAC7C,MAAM,KAAK,cAAc,OAAO;GAC9B,OAAO,MAAM;GAEb,SAAS,MAAM,cAAc,MAAM,SAAS,iBAAiB,MAAM;GACnE,WAAW,MAAM,cAAc,UAAU;GACzC,GAAI,MAAM,eAAe,EAAE,cAAc,MAAM,aAAa,IAAI,CAAC;GACjE,GAAG;EACL,CAAC;CACH;CACA,MAAM,cAAc,OAAO,QAAgB;EACzC,MAAM,OAAO,MAAM,aAAa,KAAK,WAAW,OAAO,GAAG;EAC1D,IAAI,CAAC,MAAM,MAAM,iBAAiB,GAAG;EACrC,OAAO;CACT;;;;;;CAMA,MAAM,oBAAoB,OAAO,MAAc,WAA2C,SAAS;EACjG,MAAM,gBAAgB,MAAM,KAAK,SAAS,4BAA4B,MAAM,SAAS;EACrF,IAAI,CAAC,eAAe,MAAM,IAAI,MAAM,yEAAyE;EAC7G,MAAM,WAAW,eACf,0BAA0B;GACxB;GACA,GAAG;GACH,MAAM,EAAE,UAAU,aAAa;IAAE,GAAG;IAAU;GAAW,IAAI,SAAS;EACxE,CAAC;EACH,MAAM,aAAa,MAAM,QAAQ,IAAI;EACrC,IAAI,WAAW,WAAW,cAAc,WAAW,SAAS,MAAM;EAClE,IAAI,WAAW,WAAW,YACxB,MAAM,IAAI,MAAM,qBAAqB,WAAW,KAAK,0DAA0D;EAEjH,MAAM,SAAS,MAAM,QAAQ;EAC7B,MAAM,aACJ,OAAO,WAAW,cAAc,OAAO,aAAa,OAAO,WAAW,aAAa,CAAC,OAAO,IAAI,IAAI,CAAC;EACtG,MAAM,IAAI,MACR,WAAW,SAAS,IAChB,GAAG,KAAK,uDAAuD,WAAW,KAAK,IAAI,EAAE,KACrF,GAAG,KAAK,mEACd;CACF;CACA,MAAM,UAAU,MAAmB,WACjC,KAAK,UAAU,oBAAoB;EACjC,GAAG;EACH,YAAY,KAAK;EACjB,WAAW,MAAM;EACjB,UAAU,MAAM;EAChB,YAAY,MAAM;EAClB,QAAQ,MAAM;EACd;CACF,CAAC;CAEH,OAAO;EACL,0BAA0B,WAAW;GACnC,IAAI;GACJ,aACE;GACF,aAAa,EACV,OAAO;IACN,OAAO,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,SAAS,6CAA6C;IAC/F,OAAO,EACJ,OAAO,CAAC,CACR,KAAK,CAAC,CACN,IAAI,CAAC,CAAC,CACN,IAAI,GAAI,CAAC,CACT,SAAS,oEAAoE;IAChF,YAAY,iBAAiB,SAAS;GACxC,CAAC,CAAC,CACD,OAAO;GACV,SAAS,OAAO,EAAE,OAAO,OAAO,iBAAiB;IAC/C,IAAI,YAAY,MAAM,kBAAkB,UAAU;IAClD,MAAM,UAAU,MAAM,sBAAsB;KAC1C,WAAW,KAAK;KAChB,QAAQ,MAAM,cAAc,KAAK,MAAM,CAAC,CAAC,KAAK,OAAO;KACrD,mBAAmB,KAAK;KACxB;KACA,GAAG;KACH,QAAQ,MAAM;KACd,GAAI,MAAM,eAAe,EAAE,QAAQ,EAAE,cAAc,MAAM,aAAa,EAAE,IAAI,CAAC;KAC7E,OAAO;MAAE;MAAO,GAAI,aAAa,EAAE,UAAU,EAAE,WAAW,EAAE,IAAI,CAAC;KAAG;IACtE,CAAC;IACD,IAAI,QAAQ,WAAW,WAAW,MAAM,IAAI,MAAM,QAAQ,OAAO;IACjE,IAAI,QAAQ,WAAW,YAAY,MAAM,IAAI,MAAM,mCAAmC,QAAQ,QAAQ;IACtG,MAAM,EAAE,SAAS;IAGjB,MAAM,WAAqB,CAAC;IAC5B,IAAI;KACF,MAAM,UAAU,MAAM,KAAK,KAAK,cAAc;MAC5C,OAAO,MAAM;MACb,YAAY,KAAK;MACjB,QAAQ;OAAE,MAAM;OAAQ,IAAI,MAAM;MAAO;MACzC,MAAM;KACR,CAAC;KACD,IAAI,QAAQ,WAAW,WACrB,SAAS,KACP,6BAA6B,QAAQ,WAAW,YAAY,QAAQ,UAAU,QAAQ,OAAO,GAC/F;IAEJ,SAAS,OAAO;KACd,SAAS,KAAK,6BAA6B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,GAAG;IACrG;IACA,IAAI;KACF,MAAM,OAAO,MAAM,SAAS;IAC9B,SAAS,OAAO;KACd,SAAS,KACP,wCAAwC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,GAC/F;IACF;IACA,OAAO,SAAS,SAAS;KAAE,GAAG,UAAU,IAAI;KAAG;IAAS,IAAI,UAAU,IAAI;GAC5E;EACF,CAAC;EAED,8BAA8B,WAAW;GACvC,IAAI;GACJ,aACE;GACF,aAAa,EACV,OAAO;IACN,UAAU;IACV,OAAO,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,SAAS,mDAA+C;GAClG,CAAC,CAAC,CACD,OAAO;GACV,SAAS,OAAO,EAAE,UAAU,YAAY;IACtC,IAAI,CAAC,KAAK,mBAAmB,MAAM,IAAI,MAAM,wDAAwD;IACrG,MAAM,OAAO,MAAM,YAAY,QAAQ;IACvC,MAAM,SAAS,qBAAqB,UAAU;KAC5C,OAAO,iBAAiB,IAAI;KAC5B;KACA,kBAAkB,KAAK;KACvB,WAAW,WAAW;KACtB,OAAO;IACT,CAAC;IACD,IAAI,CAAC,OAAO,SAAS,MAAM,IAAI,MAAM,IAAI,MAAM,6BAA6B;IAC5E,MAAM,SAAS,MAAM,KAAK,kBAAkB,WAAW;KACrD,GAAG,OAAO;KACV,GAAG;KACH,YAAY,KAAK;KACjB,GAAI,MAAM,cACN;MACE,OAAO;OAAE,MAAM;OAAkB,IAAI,MAAM;MAAO;MAClD,GAAI,MAAM,eAAe,EAAE,cAAc,MAAM,aAAa,IAAI,CAAC;MACjE,SAAS;OAAE,GAAG,OAAO,KAAK;OAAS,UAAU,SAAS,MAAM,OAAO,GAAG,OAAO,KAAK,QAAQ;MAAW;KACvG,IACA;MAGE,OAAO;OAAE,MAAM;OAAkB,WAAW,WAAW,MAAM;OAAa,MAAM;MAAU;MAC1F,SAAS;OACP,MAAM;OACN,UAAU,WAAW,MAAM,UAAU,GAAG,OAAO,KAAK,QAAQ;MAC9D;KACF;IACN,CAAC;IACD,IAAI,OAAO,WAAW,YAAY,MAAM,IAAI,MAAM,yBAAyB,OAAO,KAAK,KAAK,OAAO,QAAQ;IAC3G,OAAO;KAAE,YAAY,KAAK;KAAI,OAAO,OAAO;KAAO,UAAU,OAAO;IAAS;GAC/E;EACF,CAAC;EAED,0BAA0B,WAAW;GACnC,IAAI;GACJ,aACE;GACF,aAAa,EACV,OAAO;IACN,UAAU;IACV,OAAO,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,iBAAiB;IAC9E,YAAY,iBAAiB,SAAS;IACtC,gBAAgB,kBACb,SAAS,CAAC,CACV,SAAS,CAAC,CACV,SAAS,yEAAyE;IACrF,kBAAkB,EACf,QAAQ,IAAI,CAAC,CACb,SAAS,CAAC,CACV,SACC,mGACF;GACJ,CAAC,CAAC,CACD,OAAO,CAAC,CACR,QAAO,UAAS,OAAO,KAAK,KAAK,CAAC,CAAC,MAAK,QAAO,QAAQ,UAAU,GAAG,oCAAoC;GAC3G,SAAS,OAAO,EAAE,UAAU,OAAO,YAAY,gBAAgB,uBAAuB;IAEpF,IAAI,kBAAkB,cAAc,OAAO,mBAAmB;IAC9D,MAAM,OAAO,MAAM,YAAY,QAAQ;IACvC,IAAI,YAAY,MAAM,kBAAkB,YAAY,KAAK,QAAQ;IACjE,IAAI;IACJ,IAAI,mBAAmB,MAAM,mBAAmB;SAC3C,IAAI,mBAAmB,KAAA,GAAW,oBAAoB,MAAM,YAAY,cAAc,EAAA,CAAG;IAC9F,MAAM,QAA6B;KACjC,GAAI,UAAU,KAAA,IAAY,EAAE,MAAM,IAAI,CAAC;KACvC,GAAI,aAAa,EAAE,UAAU,EAAE,WAAW,EAAE,IAAI,CAAC;KACjD,GAAI,qBAAqB,KAAA,IAAY,EAAE,iBAAiB,IAAI,CAAC;KAC7D,GAAI,mBAAmB,EAAE,iBAAiB,IAAI,CAAC;IACjD;IACA,IAAI;IACJ,IAAI;KACF,UAAU,MAAM,KAAK,UAAU,OAAO;MAAE,OAAO,MAAM;MAAO,IAAI,KAAK;MAAI,QAAQ,MAAM;MAAQ;KAAM,CAAC;IACxG,SAAS,OAAO;KACd,IAAI,iBAAiB,uBAAuB,MAAM,IAAI,MAAM,2BAA2B,MAAM,SAAS;KACtG,MAAM;IACR;IACA,IAAI,CAAC,SAAS,MAAM,iBAAiB,QAAQ;IAC7C,MAAM,SAAS;KACb,GAAI,UAAU,KAAA,IAAY,CAAC,OAAO,IAAI,CAAC;KACvC,GAAI,aAAa,CAAC,UAAU,IAAI,CAAC;KACjC,GAAI,qBAAqB,KAAA,IAAY,CAAC,kBAAkB,IAAI,CAAC;KAC7D,GAAI,mBAAmB,CAAC,kBAAkB,IAAI,CAAC;IACjD;IACA,MAAM,MAAM;KACV,QAAQ;KACR,kBAAkB,MAAM;KACxB,SAAS,CAAC;MAAE,MAAM;MAAa,IAAI,QAAQ,KAAK;MAAI,MAAM,QAAQ,KAAK;KAAM,CAAC;KAC9E,UAAU;MAAE;MAAQ,OAAO;KAAgB;IAC7C,CAAC;IACD,MAAM,WAAW,QAAQ,KAAK,YAAY,CAAC;IAC3C,OAAO;KACL,UAAU,UAAU,QAAQ,IAAI;KAChC,SAAS,OAAO,KAAI,UAAU,UAAU,aAAa,eAAe,KAAM;KAC1E,YAAY,OAAO,SAAS,eAAe,WAAW,SAAS,aAAa;KAC5E,kBAAkB,QAAQ,KAAK;KAC/B,kBAAkB,QAAQ,KAAK,uBAAuB;IACxD;GACF;EACF,CAAC;EAED,wBAAwB,WAAW;GACjC,IAAI;GACJ,aACE;GACF,aAAa,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,OAAO;GAC7C,SAAS,OAAO,EAAE,iBAChB,QACE,MAAM,qBAAqB;IACzB,WAAW,KAAK;IAChB,QAAQ,MAAM,cAAc,KAAK,MAAM,CAAC,CAAC,KAAK,OAAO;IACrD,GAAG;IACH;GACF,CAAC,CACH;EACJ,CAAC;EAED,0BAA0B,WAAW;GACnC,IAAI;GACJ,aAAa;GACb,aAAa,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,OAAO;GAC7C,SAAS,OAAO,EAAE,iBAAiB;IACjC,cAAc,OAAO,wBAAwB;IAC7C,OAAO,QACL,MAAM,uBAAuB;KAC3B,WAAW,KAAK;KAChB;KACA,GAAG;KACH,QAAQ,MAAM;KACd;IACF,CAAC,CACH;GACF;EACF,CAAC;EAED,0BAA0B,WAAW;GACnC,IAAI;GACJ,aACE;GACF,aAAa,EAAE,OAAO;IAAE;IAAY,QAAQ,EAAE,KAAK,CAAC,WAAW,SAAS,CAAC;GAAE,CAAC,CAAC,CAAC,OAAO;GACrF,SAAS,OAAO,EAAE,YAAY,aAAa;IACzC,cAAc,OAAO,mCAAmC;IACxD,OAAO,QACL,MAAM,uBAAuB;KAC3B,WAAW,KAAK;KAChB;KACA,GAAG;KACH,QAAQ,MAAM;KACd;KACA;IACF,CAAC,CACH;GACF;EACF,CAAC;EAED,6BAA6B,WAAW;GACtC,IAAI;GACJ,aACE;GACF,aAAa,EAAE,OAAO,EAAE,UAAU,kBAAkB,CAAC,CAAC,CAAC,OAAO;GAC9D,SAAS,OAAO,EAAE,eAAe;IAC/B,MAAM,OAAO,MAAM,YAAY,QAAQ;IACvC,MAAM,eAAe,MAAM,OAAO,MAAM,YAAY;IACpD,OAAO;KAAE,UAAU,UAAU,IAAI;KAAG,YAAY;KAAM,QAAQ,aAAa;IAAO;GACpF;EACF,CAAC;EAED,+BAA+B,WAAW;GACxC,IAAI;GACJ,aAAa;GACb,aAAa,EAAE,OAAO,EAAE,UAAU,kBAAkB,CAAC,CAAC,CAAC,OAAO;GAC9D,SAAS,OAAO,EAAE,eAAe;IAC/B,MAAM,OAAO,MAAM,YAAY,QAAQ;IACvC,MAAM,UAAU,MAAM,KAAK,UAAU,wBAAwB;KAC3D,OAAO,MAAM;KACb,YAAY,KAAK;KACjB,WAAW,MAAM;IACnB,CAAC;IACD,OAAO;KAAE,UAAU,UAAU,IAAI;KAAG,YAAY;KAAO,eAAe;IAAQ;GAChF;EACF,CAAC;CACH;AACF"}
@@ -109,6 +109,8 @@ export interface SessionEnvironmentRepo {
109
109
  }
110
110
  /** The session's factory environment, resolved from the project and its `inEnvironment` links. */
111
111
  export interface SessionEnvironment {
112
+ /** The factory's display name. */
113
+ factoryName: string;
112
114
  repos: SessionEnvironmentRepo[];
113
115
  workspaceSetupCommand: string | undefined;
114
116
  /** Only an absolute root is passed on; the templates reject anything else. */
@@ -1 +1 @@
1
- {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAE,MAAM,4CAA4C,CAAC;AAE/E,OAAO,KAAK,EAAE,mBAAmB,EAA2B,MAAM,mCAAmC,CAAC;AAKtG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAoB,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,KAAK,EACV,cAAc,EAEd,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EACjB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAE1F,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AA6B9E,OAAO,KAAK,EAAE,qBAAqB,EAA4C,MAAM,8BAA8B,CAAC;AAQpH,OAAO,KAAK,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AACjG,OAAO,KAAK,EAAwB,0BAA0B,EAAE,MAAM,0CAA0C,CAAC;AACjH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAO7E,eAAO,MAAM,2BAA2B,QAQQ,CAAC;AAEjD;;;;;;;;GAQG;AACH,wBAAgB,6BAA6B,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,GAAG,SAAS,CAY7F;AACD,eAAO,MAAM,oBAAoB,QAAgF,CAAC;AAClH,eAAO,MAAM,mBAAmB,aAU9B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,0BAA0B,aAMrC,CAAC;AASH;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CASjG;AAsCD,qBAAa,kBAAmB,YAAW,WAAW;;IAOlD,QAAQ,CAAC,QAAQ,EAAE,WAAW;IAG9B,+EAA+E;IAC/E,QAAQ,CAAC,eAAe,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC;IALlD,YACW,QAAQ,EAAE,WAAW,EAC9B,kBAAkB,EAAE,MAAM,EAAE,EAC5B,eAAe,GAAE,MAAM,GAAG,SAA2C;IACrE,+EAA+E;IACtE,eAAe,GAAE,MAAM,OAAO,CAAC,OAAO,CAA+B;IAC9E,6GAA6G;IAC7G,UAAU,GAAE,SAAS,WAAW,EAAO,EAKxC;IA+BK,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOhD;IAEK,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAKtD;IAEK,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,CAK1D;IAEK,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAgC5D;IAqBD,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAG3C;CACF;AA0ED,KAAK,uBAAuB,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;AAEzE;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,OAAO,CAAC;AAEnD,MAAM,WAAW,8BAA8B;IAC7C,iFAAiF;IACjF,EAAE,EAAE,MAAM,CAAC;IACX,wEAAwE;IACxE,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE,qBAAqB,GAAG,uBAAuB,CAAC,CAAC;IACtF,sEAAsE;IACtE,OAAO,EAAE,0BAA0B,CAAC;IACpC,gFAAgF;IAChF,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC5B;AAED,MAAM,WAAW,6BAA6B;IAC5C,2EAA2E;IAC3E,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,4BAA4B;IAC5B,YAAY,CAAC,EAAE,mBAAmB,CAAC;IACnC,6EAA6E;IAC7E,cAAc,CAAC,EAAE,8BAA8B,EAAE,CAAC;IAClD,yEAAyE;IACzE,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B;;iEAE6D;IAC7D,SAAS,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,gCAAgC,GAAG,yBAAyB,CAAC,CAAC;IACjG,wEAAwE;IACxE,QAAQ,CAAC,EAAE,IAAI,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;IAC/C,gFAAgF;IAChF,iBAAiB,CAAC,EAAE,wBAAwB,CAAC;IAC7C,sFAAsF;IACtF,MAAM,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;CACjC;AAED,KAAK,mBAAmB,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAEtD,gFAAgF;AAChF,qBAAa,wBAAwB;;IAInC,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEpC;IAEK,QAAQ,CACZ,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,mBAAmB,GAC9B,OAAO,CAAC,OAAO,CAAC,CASlB;IAEK,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQxD;CACF;AAuBD,iGAAiG;AACjG,MAAM,WAAW,sBAAsB;IACrC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,0FAA0F;IAC1F,aAAa,EAAE,MAAM,CAAC;IACtB,qFAAqF;IACrF,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAED,kGAAkG;AAClG,MAAM,WAAW,kBAAkB;IACjC,kCAAkC;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,sBAAsB,EAAE,CAAC;IAChC,qBAAqB,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,8EAA8E;IAC9E,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,kFAAkF;IAClF,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAuBD;;;;GAIG;AACH,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,IAAI,CAAC,0BAA0B,EAAE,qBAAqB,GAAG,cAAc,CAAC,EACjF,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,kBAAkB,CAAC,CAsD7B;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,kBAAkB,EAC/B,OAAO,EAAE;IACP,KAAK,EAAE,MAAM,CAAC;IACd,mBAAmB,EAAE,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAClG,WAAW,CAAC,EAAE,qBAAqB,CAAC,aAAa,CAAC,CAAC;CACpD,GACA,IAAI,CAAC,qBAAqB,EAAE,WAAW,CAAC,CAe1C;AAED,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,6BAAkC,aAm/B/D,uBAAuB,2MACzC"}
package/dist/workspace.js CHANGED
@@ -13,10 +13,10 @@ import { LocalSkillSource, Workspace } from "@mastra/core/workspace";
13
13
  import { DEFAULT_CONFIG_DIR } from "@mastra/code-sdk/constants";
14
14
  import { existsSync } from "fs";
15
15
  import path, { dirname, join } from "path";
16
+ import { InlineSkillSource } from "@mastra/core/skills";
16
17
  import { fileURLToPath } from "url";
17
18
  import { SandboxFilesystem } from "@mastra/code-sdk/agents/sandbox-filesystem";
18
19
  import { MASTRACODE_WORKSPACE_TOOLS } from "@mastra/code-sdk/agents/tool-availability";
19
- import { InlineSkillSource } from "@mastra/core/skills";
20
20
  // src/workspace.ts
21
21
  const WORKSPACE_ID_PREFIX = "mfw";
22
22
  const bundleDirectory = dirname(fileURLToPath(import.meta.url));
@@ -372,6 +372,7 @@ async function resolveProjectEnvironment(storage, project) {
372
372
  }
373
373
  const workdir = project.sandboxWorkingDirectory?.trim();
374
374
  return {
375
+ factoryName: project.name,
375
376
  repos,
376
377
  workspaceSetupCommand: project.workspaceSetupCommand?.trim() || void 0,
377
378
  workingDirectory: workdir?.startsWith("/") ? workdir : void 0,
@@ -540,6 +541,8 @@ function createWorkspaceFactory(options = {}) {
540
541
  const constructSessionEntry = () => getSessionSandbox(session.id, repoFullName, () => {
541
542
  const sandbox = instrumentMethods(factorySandbox.create({
542
543
  sessionId: session.id,
544
+ ...session.factoryProjectId ? { factoryId: session.factoryProjectId } : {},
545
+ ...resolvedEnvironment ? { factoryName: resolvedEnvironment.factoryName } : {},
543
546
  sandboxId: session.sandboxId ?? void 0,
544
547
  repoFullName,
545
548
  ...environment ? environmentSandboxContext(environment, {
@@ -559,10 +562,16 @@ function createWorkspaceFactory(options = {}) {
559
562
  "reconnect"
560
563
  ]);
561
564
  sandbox.setOnStart((previous) => async (args) => {
562
- await timedPhase(`workspace.onStart(${args.outcome})`, async () => {
563
- await setupHook(args);
564
- });
565
- await previous?.(args);
565
+ try {
566
+ await timedPhase(`workspace.onStart(${args.outcome})`, async () => {
567
+ await setupHook(args);
568
+ });
569
+ await previous?.(args);
570
+ } catch (error) {
571
+ const physicalId = args.sandbox.sandboxId;
572
+ if (physicalId && error instanceof Error) error.message += ` (provider sandbox ${physicalId})`;
573
+ throw error;
574
+ }
566
575
  });
567
576
  startEagerly = eagerSandboxStart;
568
577
  return sandbox;