@mastra/factory 0.8.0-alpha.13 → 0.8.0-alpha.15

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 (148) hide show
  1. package/CHANGELOG.md +215 -0
  2. package/dist/factory.d.ts.map +1 -1
  3. package/dist/factory.js +41 -3
  4. package/dist/factory.js.map +1 -1
  5. package/dist/integrations/base.d.ts +8 -0
  6. package/dist/integrations/base.d.ts.map +1 -1
  7. package/dist/integrations/github/app-identity.d.ts +43 -0
  8. package/dist/integrations/github/app-identity.d.ts.map +1 -0
  9. package/dist/integrations/github/app-identity.js +62 -0
  10. package/dist/integrations/github/app-identity.js.map +1 -0
  11. package/dist/integrations/github/integration.d.ts.map +1 -1
  12. package/dist/integrations/github/integration.js +3 -1
  13. package/dist/integrations/github/integration.js.map +1 -1
  14. package/dist/integrations/github/reconcile-worker.d.ts +5 -0
  15. package/dist/integrations/github/reconcile-worker.d.ts.map +1 -1
  16. package/dist/integrations/github/reconcile-worker.js +7 -0
  17. package/dist/integrations/github/reconcile-worker.js.map +1 -1
  18. package/dist/integrations/github/routes.d.ts.map +1 -1
  19. package/dist/integrations/github/routes.js +7 -3
  20. package/dist/integrations/github/routes.js.map +1 -1
  21. package/dist/integrations/github/rules.d.ts +8 -0
  22. package/dist/integrations/github/rules.d.ts.map +1 -1
  23. package/dist/integrations/github/rules.js +30 -8
  24. package/dist/integrations/github/rules.js.map +1 -1
  25. package/dist/integrations/github/sandbox.d.ts +39 -6
  26. package/dist/integrations/github/sandbox.d.ts.map +1 -1
  27. package/dist/integrations/github/sandbox.js +48 -14
  28. package/dist/integrations/github/sandbox.js.map +1 -1
  29. package/dist/integrations/github/webhook.d.ts +20 -0
  30. package/dist/integrations/github/webhook.d.ts.map +1 -1
  31. package/dist/integrations/github/webhook.js +32 -5
  32. package/dist/integrations/github/webhook.js.map +1 -1
  33. package/dist/integrations/linear/rules.d.ts.map +1 -1
  34. package/dist/integrations/linear/rules.js +2 -1
  35. package/dist/integrations/linear/rules.js.map +1 -1
  36. package/dist/integrations/platform/github/event-worker.d.ts +2 -0
  37. package/dist/integrations/platform/github/event-worker.d.ts.map +1 -1
  38. package/dist/integrations/platform/github/event-worker.js +29 -7
  39. package/dist/integrations/platform/github/event-worker.js.map +1 -1
  40. package/dist/integrations/platform/github/integration.d.ts +7 -0
  41. package/dist/integrations/platform/github/integration.d.ts.map +1 -1
  42. package/dist/integrations/platform/github/integration.js +39 -4
  43. package/dist/integrations/platform/github/integration.js.map +1 -1
  44. package/dist/routes/config.d.ts +12 -6
  45. package/dist/routes/config.d.ts.map +1 -1
  46. package/dist/routes/config.js +97 -56
  47. package/dist/routes/config.js.map +1 -1
  48. package/dist/routes/knowledge.d.ts +152 -0
  49. package/dist/routes/knowledge.d.ts.map +1 -0
  50. package/dist/routes/knowledge.js +442 -0
  51. package/dist/routes/knowledge.js.map +1 -0
  52. package/dist/routes/projects.d.ts +9 -1
  53. package/dist/routes/projects.d.ts.map +1 -1
  54. package/dist/routes/projects.js +8 -0
  55. package/dist/routes/projects.js.map +1 -1
  56. package/dist/routes/surface.d.ts +6 -0
  57. package/dist/routes/surface.d.ts.map +1 -1
  58. package/dist/routes/surface.js +9 -0
  59. package/dist/routes/surface.js.map +1 -1
  60. package/dist/routes/work-items.d.ts.map +1 -1
  61. package/dist/routes/work-items.js +3 -1
  62. package/dist/routes/work-items.js.map +1 -1
  63. package/dist/rules/binding-context.d.ts.map +1 -1
  64. package/dist/rules/binding-context.js +4 -1
  65. package/dist/rules/binding-context.js.map +1 -1
  66. package/dist/rules/defaults.d.ts.map +1 -1
  67. package/dist/rules/defaults.js +87 -4
  68. package/dist/rules/defaults.js.map +1 -1
  69. package/dist/rules/dispatcher.d.ts +6 -0
  70. package/dist/rules/dispatcher.d.ts.map +1 -1
  71. package/dist/rules/dispatcher.js +118 -16
  72. package/dist/rules/dispatcher.js.map +1 -1
  73. package/dist/rules/processor.d.ts.map +1 -1
  74. package/dist/rules/processor.js +20 -7
  75. package/dist/rules/processor.js.map +1 -1
  76. package/dist/rules/resolve.d.ts +1 -0
  77. package/dist/rules/resolve.d.ts.map +1 -1
  78. package/dist/rules/resolve.js +3 -2
  79. package/dist/rules/resolve.js.map +1 -1
  80. package/dist/rules/start-coordinator.d.ts +2 -0
  81. package/dist/rules/start-coordinator.d.ts.map +1 -1
  82. package/dist/rules/start-coordinator.js +3 -1
  83. package/dist/rules/start-coordinator.js.map +1 -1
  84. package/dist/rules/terminal-cleanup.d.ts +23 -0
  85. package/dist/rules/terminal-cleanup.d.ts.map +1 -0
  86. package/dist/rules/terminal-cleanup.js +43 -0
  87. package/dist/rules/terminal-cleanup.js.map +1 -0
  88. package/dist/rules/tools.d.ts.map +1 -1
  89. package/dist/rules/tools.js +24 -2
  90. package/dist/rules/tools.js.map +1 -1
  91. package/dist/rules/transition-service.d.ts +3 -0
  92. package/dist/rules/transition-service.d.ts.map +1 -1
  93. package/dist/rules/transition-service.js +10 -6
  94. package/dist/rules/transition-service.js.map +1 -1
  95. package/dist/rules/types.d.ts +32 -3
  96. package/dist/rules/types.d.ts.map +1 -1
  97. package/dist/rules/types.js +2 -0
  98. package/dist/rules/types.js.map +1 -1
  99. package/dist/rules/validation.d.ts.map +1 -1
  100. package/dist/rules/validation.js +8 -3
  101. package/dist/rules/validation.js.map +1 -1
  102. package/dist/sandbox/base-checkpoint-triggers.d.ts +77 -0
  103. package/dist/sandbox/base-checkpoint-triggers.d.ts.map +1 -0
  104. package/dist/sandbox/base-checkpoint-triggers.js +137 -0
  105. package/dist/sandbox/base-checkpoint-triggers.js.map +1 -0
  106. package/dist/sandbox/base-checkpoint.d.ts +59 -0
  107. package/dist/sandbox/base-checkpoint.d.ts.map +1 -0
  108. package/dist/sandbox/base-checkpoint.js +145 -0
  109. package/dist/sandbox/base-checkpoint.js.map +1 -0
  110. package/dist/sandbox/fleet.d.ts +32 -0
  111. package/dist/sandbox/fleet.d.ts.map +1 -1
  112. package/dist/sandbox/fleet.js +39 -10
  113. package/dist/sandbox/fleet.js.map +1 -1
  114. package/dist/session/checkpoint-capture.d.ts +3 -2
  115. package/dist/session/checkpoint-capture.d.ts.map +1 -1
  116. package/dist/session/checkpoint-capture.js +3 -3
  117. package/dist/session/checkpoint-capture.js.map +1 -1
  118. package/dist/session/model-pack-hydration.d.ts +55 -0
  119. package/dist/session/model-pack-hydration.d.ts.map +1 -0
  120. package/dist/session/model-pack-hydration.js +56 -0
  121. package/dist/session/model-pack-hydration.js.map +1 -0
  122. package/dist/skills/service.d.ts +9 -0
  123. package/dist/skills/service.d.ts.map +1 -1
  124. package/dist/skills/service.js +10 -1
  125. package/dist/skills/service.js.map +1 -1
  126. package/dist/storage/domains/model-packs/base.d.ts +26 -0
  127. package/dist/storage/domains/model-packs/base.d.ts.map +1 -1
  128. package/dist/storage/domains/model-packs/base.js +102 -13
  129. package/dist/storage/domains/model-packs/base.js.map +1 -1
  130. package/dist/storage/domains/source-control/base.d.ts +28 -0
  131. package/dist/storage/domains/source-control/base.d.ts.map +1 -1
  132. package/dist/storage/domains/source-control/base.js +70 -14
  133. package/dist/storage/domains/source-control/base.js.map +1 -1
  134. package/dist/storage/domains/source-control/inmemory.d.ts +9 -1
  135. package/dist/storage/domains/source-control/inmemory.d.ts.map +1 -1
  136. package/dist/storage/domains/source-control/inmemory.js +8 -0
  137. package/dist/storage/domains/source-control/inmemory.js.map +1 -1
  138. package/dist/storage/domains/work-items/base.d.ts +67 -1
  139. package/dist/storage/domains/work-items/base.d.ts.map +1 -1
  140. package/dist/storage/domains/work-items/base.js +140 -12
  141. package/dist/storage/domains/work-items/base.js.map +1 -1
  142. package/dist/workspace.d.ts +31 -2
  143. package/dist/workspace.d.ts.map +1 -1
  144. package/dist/workspace.js +224 -53
  145. package/dist/workspace.js.map +1 -1
  146. package/factory-skills/factory-rereview/SKILL.md +1 -1
  147. package/factory-skills/factory-review/SKILL.md +1 -1
  148. package/package.json +7 -7
package/CHANGELOG.md CHANGED
@@ -1,5 +1,220 @@
1
1
  # @mastra/factory
2
2
 
3
+ ## 0.8.0-alpha.15
4
+
5
+ ### Patch Changes
6
+
7
+ - Fixed model packs so each user can set a default for new interactive Factory chats while preserving thread-specific pack and model choices, refreshing edited packs, and leaving Factory work runs unaffected. ([#21762](https://github.com/mastra-ai/mastra/pull/21762))
8
+
9
+ ## 0.8.0-alpha.14
10
+
11
+ ### Minor Changes
12
+
13
+ - Added foundational support for an upcoming experimental memory capability across storage, runtime, and developer tooling. ([#19538](https://github.com/mastra-ai/mastra/pull/19538))
14
+
15
+ ### Patch Changes
16
+
17
+ - Resume a skill run that was aborted out from under it. ([#21802](https://github.com/mastra-ai/mastra/pull/21802))
18
+
19
+ An aborted run was recorded as a terminal failure on the assumption that an
20
+ abort is deliberate. In practice the dominant cause is the process going away
21
+ underneath the run — an operator restarting the server — and the run stream does
22
+ not say which happened. Cards were dead-ending at attempt 1 with nothing on the
23
+ board to press, needing a human to nudge each one by hand after every restart.
24
+
25
+ Aborted runs are now retried like any other interrupted work, still bounded by
26
+ the existing attempt cap.
27
+
28
+ - Stop Factory from waking itself on its own GitHub comments. ([#21800](https://github.com/mastra-ai/mastra/pull/21800))
29
+
30
+ Factory recognised its own writes by comparing the event sender against
31
+ `GITHUB_APP_SLUG`. That variable names the deployment's own self-hosted GitHub
32
+ App, which is a different App than the one a Platform deployment posts as — and
33
+ on such a deployment it is legitimately unset, so the check compared against
34
+ `undefined[bot]` and never matched. Every self-loop guard silently failed open.
35
+
36
+ The visible result: triage published its handoff comment, that comment came back
37
+ through ingress, re-invoked triage, and cancelled the run that had written it —
38
+ leaving the public verdict stuck at "Pending" while both runs reported success.
39
+
40
+ The Platform integration now names the App it actually posts as, overridable
41
+ with `MASTRA_PLATFORM_GITHUB_APP_SLUG`, and identity resolution is centralised so
42
+ an unresolved identity is reported as _unknown_ rather than collapsing into
43
+ "not Factory".
44
+
45
+ - Let a Factory run finish its stage when the previous role handed off in the same ([#21802](https://github.com/mastra-ai/mastra/pull/21802))
46
+ session.
47
+
48
+ `factory_transition_work_item` re-checked its authority at execution time by
49
+ comparing the live run binding against the binding row that existed when the
50
+ tool was built, requiring the same row id. But handing the next role its turn in
51
+ an existing session legitimately rotates that row: the previous role's binding is
52
+ revoked and a new one is issued for the same session and the same work item.
53
+ Tools built for the earlier role stay live across that rotation, so they were
54
+ keyed to a row that the handoff itself had just replaced.
55
+
56
+ The visible result: planning produced a complete plan, called its terminal
57
+ transition to `execute`, and was refused with "Factory agent binding is
58
+ unavailable, revoked, or no longer matches this session." The item stopped in
59
+ Planning with the plan written but never advanced, and the decision that carried
60
+ it reported success. Every leg that continues an item in an existing session —
61
+ planning after triage, and the review-feedback wakes — failed the same way.
62
+
63
+ Authority is now the work item the session is bound to rather than the
64
+ individual binding row, so a rotation no longer strands the run it exists to
65
+ start. Re-pointing a session at a _different_ work item is still refused.
66
+
67
+ - Start the implementation run when a work item enters Building. ([#21802](https://github.com/mastra-ai/mastra/pull/21802))
68
+
69
+ Building was the one stage on the Work board with no entry rule, so an item
70
+ arriving there stopped: the plan was approved and nothing picked it up until
71
+ somebody pressed Build by hand. Every other stage advances itself, which made
72
+ Building the single manual step in an otherwise continuous path from intake to
73
+ review.
74
+
75
+ The run it starts carries a prompt rather than activating a skill. Skills exist
76
+ here to define a handoff — a terminal message later rules match on to decide
77
+ what happens next — and Building already has one: it ends by opening a pull
78
+ request, which arrives as its own event and raises the Review card. Rules could
79
+ previously only express "invoke this skill", so the decision vocabulary now
80
+ accepts a prompt as the alternative to a skill name.
81
+
82
+ - Credit the reporter as a co-author on work their issue caused ([#21802](https://github.com/mastra-ai/mastra/pull/21802))
83
+
84
+ When Factory builds a fix for a GitHub issue, the build prompt now asks for a
85
+ `Co-Authored-By` trailer naming the person who reported it, so the reporter shows
86
+ up as a contributor on the pull request rather than only in the issue thread.
87
+
88
+ Only GitHub issues qualify. A Linear card stamps a display name and a manual card
89
+ stamps nothing, and neither resolves to the GitHub account a trailer needs, so
90
+ those are left uncredited rather than credited to nobody. Issues Factory filed
91
+ itself are skipped.
92
+
93
+ Intake already stamped the reporter's login but the stage rules could not see it;
94
+ the intake-stamped metadata now reaches rules that run on a stage.
95
+
96
+ - Stop reporting a skill kickoff as successful when it was queued onto a run that was already ending. ([#21802](https://github.com/mastra-ai/mastra/pull/21802))
97
+
98
+ Signals sent into an active session settle as `deliver`, which acknowledges routing but promises nothing about execution. If the in-flight run finished before draining its queue, the prompt was dropped: no turn started, no error surfaced, and the decision was marked succeeded while the work item sat in its new stage with nobody working on it. The dispatcher now confirms the signal actually landed in the thread and retries the decision when it did not, so the next attempt finds the session idle and takes the instrumented wake path.
99
+
100
+ - Dismiss runs still parked on a work item when it reaches a terminal stage. A merged or closed pull request cannot answer a suggested run, so the card no longer keeps asking. ([#21802](https://github.com/mastra-ai/mastra/pull/21802))
101
+
102
+ - Check who sent a GitHub comment or review before letting it wake an agent, and ingest default-branch `push` events. ([#21800](https://github.com/mastra-ai/mastra/pull/21800))
103
+
104
+ The sender gate listed event kinds under names the webhook classifier never produces, so the identity check that keeps untrusted commenters from waking Factory agents was skipped for every comment and review event. The gate now names the kinds the classifier actually emits. Separately, `push` events were dropped by the event filter before ingestion; they are now ingested and forwarded to Factory's event pipeline so downstream consumers (such as the upcoming warm base-checkpoint refresh) can observe default-branch pushes.
105
+
106
+ - Ingest `pull_request.opened` from the Platform event poller so a newly opened pull request mints its Review card. The poller forwards an allow-list of events to the rules engine, and `opened` was missing from it — so on deployments without a direct webhook (the only path a local deployment has), a pull request the factory authored itself was never reviewed. ([#21802](https://github.com/mastra-ai/mastra/pull/21802))
107
+
108
+ - Keep kickoff skill resolution off the sandbox so clicking Review on a board card no longer blocks on full sandbox provisioning. Project skill roots (`.claude/skills`, `.agents/skills`, `<configDir>/skills`) are guarded while the session sandbox is unmaterialized — discovery reports them empty instead of forcing materialization — and a skills rescan fires automatically once materialization completes so repo-local skills become visible. Bundled Factory skills (e.g. factory-review) resolve from local disk in milliseconds. ([#21802](https://github.com/mastra-ai/mastra/pull/21802))
109
+
110
+ - Stop the GitHub event worker from crashing when it is constructed before source-control storage is initialized. ([#21801](https://github.com/mastra-ai/mastra/pull/21801))
111
+
112
+ `workers()` dereferenced the integration's source-control storage eagerly while building the reconcile worker, but that storage is only attached later by `versionControl.initialize`. A deployment that constructs workers first crashed with "source-control storage has not been initialized". The worker now receives a lazy handle that resolves the storage slices at call time, once the worker is actually running.
113
+
114
+ - Deliver GitHub review feedback to the factory rules on the polling path. Submitted reviews and new pull request comments were dropped before the rules engine ran, so the agent that authored a branch was never woken when a reviewer asked for changes. ([#21802](https://github.com/mastra-ai/mastra/pull/21802))
115
+
116
+ - Route pull request comments to the agent that authored the pull request, and stop provenance from branding commenters as Factory. ([#21802](https://github.com/mastra-ai/mastra/pull/21802))
117
+
118
+ Comments on a PR arrive as `issue_comment` with `issue.pull_request` set, and the ingress explicitly dropped them. That closed the most common feedback path of all: on a Factory-authored PR, GitHub refuses a formal `--approve`/`--request-changes` verdict from the account that opened it, so the review skill falls back to `gh pr comment` — which was discarded. External review bots leaving plain comments were dropped for the same reason.
119
+
120
+ A new `pullRequestCommentCreated` rule event now carries those comments, reading the pull request from the `issue` payload so provenance binds the comment to the authoring Work item rather than mistaking the number for an issue's. The default rule sends a high-priority `sendMessage` to the `work` role, which wakes an idle session. Factory's own comments are ignored, because `factoryAuthored` cannot distinguish the Work role from the Review role and reacting to them would let an agent wake itself in a loop.
121
+
122
+ Separately, `factoryAuthored` was derived from PR provenance for every event, which proves the _pull request_ came from Factory, not the sender of the event. Any human or review bot commenting on a Factory-authored PR was therefore marked as Factory. Provenance-based attribution is now skipped for events whose sender is responding to the PR — comments, submitted reviews, and re-requested reviews — where only the app login identifies Factory.
123
+
124
+ - Wait for the run that swallowed a kickoff, instead of racing it. ([#21802](https://github.com/mastra-ai/mastra/pull/21802))
125
+
126
+ A signal queued onto an already-running turn can be dropped when that turn ends
127
+ before draining its queue. That case was detected correctly and then handed to
128
+ the generic exponential backoff, which spends all five attempts inside about
129
+ thirty seconds — while the run it is waiting on takes minutes. Every attempt
130
+ landed on the same busy session and the card gave up roughly ten times too early.
131
+
132
+ The dispatcher now waits for the in-flight run to end and redelivers into the
133
+ freed session, which is the event that actually resolves the condition. The
134
+ decision settles within its original lease without spending the retry budget, and
135
+ a redelivery that is dropped again still goes back on the queue.
136
+
137
+ - Only credit reporters who are real GitHub accounts ([#21802](https://github.com/mastra-ai/mastra/pull/21802))
138
+
139
+ The issue poller stamps a placeholder login when GitHub returns no author, which
140
+ would have become a `Co-Authored-By` trailer crediting an account nobody owns.
141
+ Reporter credit now requires a login that matches GitHub's grammar.
142
+
143
+ - Re-review a pull request when a push lands while its card is still in Reviewing. ([#21802](https://github.com/mastra-ai/mastra/pull/21802))
144
+
145
+ A push to a card already sitting in Reviewing was dropped rather than deferred:
146
+ the rule returned nothing, and once the in-flight pass finished it transitioned
147
+ to Done having reviewed code that was no longer current, with no record that
148
+ newer commits had arrived. That is the exact ordering the review loop produces —
149
+ a review asks for changes, the authoring agent pushes a fix, and the fix lands
150
+ before the card finishes leaving Reviewing.
151
+
152
+ Only Intake now suppresses the re-review. A push during Reviewing re-enters the
153
+ stage, which supersedes the stale pass: the stage rule already cancels the run
154
+ in flight and selects the right skill for the entry it sees.
155
+
156
+ Transition decisions carry a `reenter` flag for this, since a transition to the
157
+ stage an item already holds is otherwise inert — the common case is a board
158
+ being corrected into a state it already has, not work that needs restarting.
159
+
160
+ - Credit the author on review follow-up pull requests ([#21802](https://github.com/mastra-ai/mastra/pull/21802))
161
+
162
+ When a review pass ships mechanical fixes as a follow-up pull request, those
163
+ commits now carry a `Co-Authored-By` trailer for the human whose work they build
164
+ on — the reviewed pull request's author, or, when that author is a bot, the
165
+ reporter of the issue the pull request closes.
166
+
167
+ - Carry pull request review feedback back to the agent that wrote the code. ([#21802](https://github.com/mastra-ai/mastra/pull/21802))
168
+
169
+ A `changes_requested` review is meant to wake the authoring work session, but
170
+ when the pull request carried no provenance the event resolved to the pull
171
+ request's own Review card. `addressReviewFeedback` deliberately refuses to act
172
+ on the review board — a Review card reacting to its own posted review would loop
173
+ the reviewer against itself — so the wake was dropped and the author never heard
174
+ about the feedback.
175
+
176
+ Review and pull request comment events now follow the linked card's
177
+ `parentWorkItemId` back to the item that authored the pull request, so the
178
+ existing guard becomes true for the right item instead of never. A pull request
179
+ card with no authoring item still emits nothing.
180
+
181
+ - Close the work/review loop: a review that requests changes now wakes the agent that authored the pull request. ([#21802](https://github.com/mastra-ai/mastra/pull/21802))
182
+
183
+ `pull_request_review` webhooks were accepted and classified urgent, but no matching rule event existed, so the delivery was dropped after classification and the authoring agent was never told. PR subscriptions did not cover this — they sync PR activity into a thread's notification inbox for the agent to read on its _next_ turn, but nothing starts that turn.
184
+
185
+ A new `pullRequestReviewSubmitted` rule event maps `pull_request_review`/`submitted`, and the default rule sends a high-priority `sendMessage` to the `work` role, which wakes an idle session. Only `changes_requested` fires; `approved` and `commented` stay quiet, and the Review card that posted the review never reacts to its own output.
186
+
187
+ - Send Factory's own pull requests straight to Review. ([#21802](https://github.com/mastra-ai/mastra/pull/21802))
188
+
189
+ A pull request entered Review only when its author passed a repository-collaborator
190
+ permission check. A GitHub App bot is never a collaborator, so every pull request
191
+ Factory opened itself scored as untrusted and parked in Intake, waiting on a human
192
+ click — the exact opposite of the intent, since those are the pull requests whose
193
+ provenance Factory knows best.
194
+
195
+ Factory authorship is now its own trust signal for pull requests: the branch came
196
+ from a Work run this Factory dispatched. Issues are deliberately unchanged, because
197
+ auto-triaging an issue Factory opened is a self-loop with no upside.
198
+
199
+ - Report what actually happened to a Factory run. A human dragging a card on the board now arms the item, so the run it asks for starts instead of parking for approval, and a run that dies mid-flight — a provider error, or a cancellation by the next decision — is recorded as failed on the decision instead of reported as a success. ([#21802](https://github.com/mastra-ai/mastra/pull/21802))
200
+
201
+ - Retire a parked proposal when the run it asked for starts anyway. Approving a ([#21802](https://github.com/mastra-ai/mastra/pull/21802))
202
+ proposal mints a fresh decision rather than dispatching the parked one, so the
203
+ original stayed `proposed` forever and the card kept asking to start a run that
204
+ had already finished. The dispatcher now dismisses proposals for the same work
205
+ item and role as any `invokeSkill` it dispatches, so the waiting badge only ever
206
+ marks a loop that is genuinely stopped.
207
+
208
+ - Deliver GitHub pull request signals to the session that actually owns the subscribed thread, and skip subscriptions whose thread this deployment does not hold. ([#21800](https://github.com/mastra-ai/mastra/pull/21800))
209
+
210
+ A subscription records the Factory project as its resource, but an unscoped session registers under its own id, so delivery looked for the thread under a resource that did not own it and failed with "Thread not found" on every matching event. Delivery now reads the thread from storage to find its owning resource. A subscription naming a thread that is absent is skipped rather than failed, so a pull request's events reaching a deployment that never owned the thread no longer fabricate a session or retry in a loop.
211
+
212
+ - Fixed restarting a review after deleting its thread. It no longer fails with "git clone failed: a branch named ... already exists". Reused Platform sandboxes now delete the previous session's local branches when they are recycled. A new session for the same branch starts fresh from the base branch. Branch checkout also recovers from leftover or broken branch refs instead of failing the workspace. ([#21268](https://github.com/mastra-ai/mastra/pull/21268))
213
+
214
+ - Updated dependencies [[`566e080`](https://github.com/mastra-ai/mastra/commit/566e080ac4296ef2ba84a99c496a1c19706fa2df), [`c549e2f`](https://github.com/mastra-ai/mastra/commit/c549e2f40edc1cac5d9e74e82f90da22b48df084), [`c549e2f`](https://github.com/mastra-ai/mastra/commit/c549e2f40edc1cac5d9e74e82f90da22b48df084), [`2ef2f23`](https://github.com/mastra-ai/mastra/commit/2ef2f230a7aed342e7dc3b2000cd42e4c43e08a7), [`5740ec6`](https://github.com/mastra-ai/mastra/commit/5740ec60c760ffdfbfaa59d603d03b847c864e05)]:
215
+ - @mastra/code-sdk@1.3.0-alpha.13
216
+ - @mastra/core@1.60.0-alpha.13
217
+
3
218
  ## 0.8.0-alpha.13
4
219
 
5
220
  ### Minor Changes
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAGlD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAS/D,OAAO,KAAK,EAAE,kBAAkB,EAAgD,MAAM,wBAAwB,CAAC;AAmB/G,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAiCrD,8EAA8E;AAC9E,MAAM,MAAM,UAAU,GAAG,WAAW,CAAC,qBAAqB,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAE9E,MAAM,WAAW,mBAAmB;IAClC;;;;;;;;;;;;;;OAcG;IACH,IAAI,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAClC;;;;;;;OAOG;IACH,OAAO,EAAE,cAAc,CAAC;IACxB;;;;OAIG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,0EAA0E;IAC1E,OAAO,CAAC,EAAE,0BAA0B,CAAC;IACrC,mDAAmD;IACnD,UAAU,CAAC,EAAE,6BAA6B,CAAC;IAC3C;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,kBAAkB,EAAE,CAAC;IACpC;;;;;OAKG;IACH,KAAK,CAAC,EAAE,YAAY,CAAC;IAErB;;;OAGG;IACH,QAAQ,CAAC,EAAE;QACT,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;CACH;AAED,MAAM,WAAW,0BAA0B;IACzC;;;;;;OAMG;IACH,OAAO,EAAE,gBAAgB,CAAC;IAC1B;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,MAAM,WAAW,6BAA6B;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAwFD,qBAAa,aAAa;;gBAOZ,MAAM,EAAE,mBAAmB;IAWvC;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC;IAgmBpC;;;;OAIG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAY/B,iFAAiF;IAC3E,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAGhC"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAGlD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAS/D,OAAO,KAAK,EAAE,kBAAkB,EAAgD,MAAM,wBAAwB,CAAC;AAoB/G,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAqCrD,8EAA8E;AAC9E,MAAM,MAAM,UAAU,GAAG,WAAW,CAAC,qBAAqB,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAE9E,MAAM,WAAW,mBAAmB;IAClC;;;;;;;;;;;;;;OAcG;IACH,IAAI,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAClC;;;;;;;OAOG;IACH,OAAO,EAAE,cAAc,CAAC;IACxB;;;;OAIG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,0EAA0E;IAC1E,OAAO,CAAC,EAAE,0BAA0B,CAAC;IACrC,mDAAmD;IACnD,UAAU,CAAC,EAAE,6BAA6B,CAAC;IAC3C;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,kBAAkB,EAAE,CAAC;IACpC;;;;;OAKG;IACH,KAAK,CAAC,EAAE,YAAY,CAAC;IAErB;;;OAGG;IACH,QAAQ,CAAC,EAAE;QACT,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;CACH;AAED,MAAM,WAAW,0BAA0B;IACzC;;;;;;OAMG;IACH,OAAO,EAAE,gBAAgB,CAAC;IAC1B;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,MAAM,WAAW,6BAA6B;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAwFD,qBAAa,aAAa;;gBAOZ,MAAM,EAAE,mBAAmB;IAWvC;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC;IAypBpC;;;;OAIG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAY/B,iFAAiF;IAC3E,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAGhC"}
package/dist/factory.js CHANGED
@@ -1,14 +1,17 @@
1
1
  import { timedPhase } from "./timing.js";
2
2
  import { buildAuthRoutes, createFactoryAuthGate, createFactoryRouteAuth, getFactoryAuthOrgId, getFactoryAuthUserFromContext, getFactoryAuthUserId } from "./auth.js";
3
3
  import { recordFactoryPullRequestProvenance } from "./integrations/github/provenance.js";
4
- import { assertFactoryRules } from "./rules/validation.js";
5
4
  import { SandboxFleet } from "./sandbox/fleet.js";
5
+ import { BaseCheckpointBuilder } from "./sandbox/base-checkpoint.js";
6
+ import { createBaseCheckpointTriggers } from "./sandbox/base-checkpoint-triggers.js";
7
+ import { assertFactoryRules } from "./rules/validation.js";
6
8
  import { PlatformGithubIntegration } from "./integrations/platform/github/integration.js";
7
9
  import { PlatformLinearIntegration } from "./integrations/platform/linear/integration.js";
8
10
  import { createCustomProvidersPrimer, registerCustomProvidersSource } from "./routes/custom-provider-source.js";
9
11
  import { ProjectRoutes } from "./routes/projects.js";
10
12
  import { hydrateSessionMemorySettings } from "./session/memory-settings-hydration.js";
11
13
  import { FactoryTransitionService } from "./rules/transition-service.js";
14
+ import { hydrateSessionModelPack } from "./session/model-pack-hydration.js";
12
15
  import { observeSessionFilesystem } from "./session/filesystem-capture.js";
13
16
  import { ModelCredentialsStorage } from "./storage/domains/credentials/base.js";
14
17
  import { FactoryWorkspaceRegistry, createWorkspaceFactory } from "./workspace.js";
@@ -19,6 +22,7 @@ import { assembleFactoryApiRoutes, buildIntegrationContext } from "./routes/surf
19
22
  import { builtInFactoryRules } from "./rules/defaults.js";
20
23
  import { FactoryDecisionDispatcher } from "./rules/dispatcher.js";
21
24
  import { FactoryPhaseStateProcessor } from "./rules/processor.js";
25
+ import { createTerminalStageCleanup } from "./rules/terminal-cleanup.js";
22
26
  import { createFactoryTransitionTools } from "./rules/tools.js";
23
27
  import { registerSandboxReattach } from "./sandbox/reattach.js";
24
28
  import { SessionRetirementCoordinator } from "./sandbox/session-retirement.js";
@@ -194,6 +198,7 @@ var MastraFactory = class {
194
198
  workItems: workItemsStorage,
195
199
  channelIdentity: storage.registerDomain(new ChannelIdentityStorage())
196
200
  };
201
+ let baseCheckpoints;
197
202
  const auditDomain = new AuditDomain({
198
203
  auth: routeAuth,
199
204
  audit: auditStorage,
@@ -254,7 +259,23 @@ var MastraFactory = class {
254
259
  });
255
260
  const intakeReady = integrations.some((integration) => integration.intake !== void 0) && storage.isDomainReady("intake");
256
261
  const factoryReady = storage.isDomainReady("projects") && storage.isDomainReady("work-items");
262
+ const knowledgeEnabled = process.env.MASTRACODE_EXPERIMENTAL_SUBCONSCIOUS === "1";
257
263
  const githubIntegration = integrations.find((integration) => integration.id === "github");
264
+ if (githubIntegration && fleet.enabled && storage.isDomainReady("source-control")) {
265
+ const checkpointLogger = { warn: (message) => console.warn(`[factory] ${message}`) };
266
+ baseCheckpoints = createBaseCheckpointTriggers({
267
+ builder: new BaseCheckpointBuilder({
268
+ fleet,
269
+ logger: checkpointLogger
270
+ }),
271
+ fleet,
272
+ github: {
273
+ sourceControlStorage: sourceControlStorage.forIntegration("github"),
274
+ ...githubIntegration.versionControl ? { versionControl: githubIntegration.versionControl } : {}
275
+ },
276
+ logger: checkpointLogger
277
+ });
278
+ }
258
279
  const workItemsReady = storage.isDomainReady("work-items");
259
280
  const sessionRetirement = machine && storage.isDomainReady("source-control") ? new SessionRetirementCoordinator({
260
281
  fleet,
@@ -266,17 +287,25 @@ var MastraFactory = class {
266
287
  orgId,
267
288
  workItemId
268
289
  }) : void 0;
290
+ const onTerminalStage = workItemsReady ? createTerminalStageCleanup({
291
+ workItems: workItemsStorage,
292
+ reconcileBinding: async (binding) => {
293
+ await factoryProcessor?.reconcileBinding(binding);
294
+ },
295
+ ...retireTerminalSessions ? { releaseSandboxes: retireTerminalSessions } : {}
296
+ }) : retireTerminalSessions;
269
297
  const transitionService = workItemsReady ? new FactoryTransitionService({
270
298
  rules,
271
299
  storage: workItemsStorage,
272
- ...retireTerminalSessions ? { onTerminalStage: retireTerminalSessions } : {}
300
+ ...onTerminalStage ? { onTerminalStage } : {}
273
301
  }) : void 0;
274
302
  const projectRoutes = new ProjectRoutes({
275
303
  auth: routeAuth,
276
304
  projects: factoryProjectsStorage,
277
305
  sourceControl: sourceControlStorage,
278
306
  versionControlIntegrationIds: integrations.filter((integration) => integration.versionControl).map((integration) => integration.id),
279
- ...sessionRetirement ? { sessionRetirement } : {}
307
+ ...sessionRetirement ? { sessionRetirement } : {},
308
+ onProjectRepositoryLinked: (args) => baseCheckpoints?.onProjectRepositoryLinked(args)
280
309
  });
281
310
  const factoryProcessor = workItemsReady ? new FactoryPhaseStateProcessor({
282
311
  rules,
@@ -379,6 +408,7 @@ var MastraFactory = class {
379
408
  publicOrigin,
380
409
  stateSigner,
381
410
  fleet,
411
+ ...baseCheckpoints ? { baseCheckpoints } : {},
382
412
  sessionRetirement,
383
413
  factoryStorage: storage,
384
414
  integrationStorage,
@@ -387,6 +417,7 @@ var MastraFactory = class {
387
417
  integrations: integrationRegistrations,
388
418
  intakeReady,
389
419
  factoryReady,
420
+ knowledgeEnabled,
390
421
  rules,
391
422
  factoryTransitionService: transitionService,
392
423
  onFactoryRuntime: ({ transitionService: runtimeTransitionService, prepareBinding }) => {
@@ -464,6 +495,11 @@ var MastraFactory = class {
464
495
  sourceControl: sourceControlStorage.forIntegration("github"),
465
496
  memorySettings: memorySettingsStorage
466
497
  }), { blocking: true });
498
+ prepared.base.controller.onSessionCreated((session) => hydrateSessionModelPack(session, {
499
+ sourceControl: sourceControlStorage.forIntegration("github"),
500
+ workItems: workItemsStorage,
501
+ modelPacks: modelPacksStorage
502
+ }), { blocking: true });
467
503
  this.#prepared = prepared;
468
504
  this.#factoryProcessor = factoryProcessor;
469
505
  const channelRegistrations = integrationRegistrations.filter(({ integration, ready }) => ready && integration.channels);
@@ -474,6 +510,7 @@ var MastraFactory = class {
474
510
  auth: routeAuth,
475
511
  stateSigner,
476
512
  fleet,
513
+ ...baseCheckpoints ? { baseCheckpoints } : {},
477
514
  factoryStorage: storage,
478
515
  integrationStorage,
479
516
  sourceControlStorage,
@@ -488,6 +525,7 @@ var MastraFactory = class {
488
525
  auth: routeAuth,
489
526
  stateSigner,
490
527
  fleet,
528
+ ...baseCheckpoints ? { baseCheckpoints } : {},
491
529
  factoryStorage: storage,
492
530
  integrationStorage,
493
531
  sourceControlStorage,