@mastra/factory 0.6.0-alpha.1 → 0.6.0-alpha.4
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.
- package/CHANGELOG.md +126 -0
- package/dist/capabilities/version-control.d.ts +1 -0
- package/dist/capabilities/version-control.d.ts.map +1 -1
- package/dist/factory.d.ts +10 -0
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +13 -1
- package/dist/factory.js.map +1 -1
- package/dist/integrations/github/integration.d.ts +13 -1
- package/dist/integrations/github/integration.d.ts.map +1 -1
- package/dist/integrations/github/integration.js +50 -2
- package/dist/integrations/github/integration.js.map +1 -1
- package/dist/integrations/github/issue-reconciler.d.ts +24 -0
- package/dist/integrations/github/issue-reconciler.d.ts.map +1 -0
- package/dist/integrations/github/issue-reconciler.js +104 -0
- package/dist/integrations/github/issue-reconciler.js.map +1 -0
- package/dist/integrations/github/reconcile-worker.d.ts +8 -0
- package/dist/integrations/github/reconcile-worker.d.ts.map +1 -1
- package/dist/integrations/github/reconcile-worker.js +38 -1
- package/dist/integrations/github/reconcile-worker.js.map +1 -1
- package/dist/integrations/github/routes.d.ts.map +1 -1
- package/dist/integrations/github/routes.js +45 -6
- package/dist/integrations/github/routes.js.map +1 -1
- package/dist/integrations/github/rules.d.ts +33 -2
- package/dist/integrations/github/rules.d.ts.map +1 -1
- package/dist/integrations/github/rules.js +89 -11
- package/dist/integrations/github/rules.js.map +1 -1
- package/dist/integrations/github/sandbox.d.ts.map +1 -1
- package/dist/integrations/github/sandbox.js +74 -8
- package/dist/integrations/github/sandbox.js.map +1 -1
- package/dist/integrations/issue-reconcile-worker.d.ts +19 -0
- package/dist/integrations/issue-reconcile-worker.d.ts.map +1 -0
- package/dist/integrations/issue-reconcile-worker.js +98 -0
- package/dist/integrations/issue-reconcile-worker.js.map +1 -0
- package/dist/integrations/issue-reconciler.d.ts +47 -0
- package/dist/integrations/issue-reconciler.d.ts.map +1 -0
- package/dist/integrations/issue-reconciler.js +104 -0
- package/dist/integrations/issue-reconciler.js.map +1 -0
- package/dist/integrations/linear/integration.d.ts +2 -0
- package/dist/integrations/linear/integration.d.ts.map +1 -1
- package/dist/integrations/linear/integration.js +14 -1
- package/dist/integrations/linear/integration.js.map +1 -1
- package/dist/integrations/linear/issue-reconciler.d.ts +6 -0
- package/dist/integrations/linear/issue-reconciler.d.ts.map +1 -0
- package/dist/integrations/linear/issue-reconciler.js +64 -0
- package/dist/integrations/linear/issue-reconciler.js.map +1 -0
- package/dist/integrations/linear/rules.d.ts.map +1 -1
- package/dist/integrations/linear/rules.js +5 -2
- package/dist/integrations/linear/rules.js.map +1 -1
- package/dist/integrations/platform/github/event-worker.d.ts +7 -0
- package/dist/integrations/platform/github/event-worker.d.ts.map +1 -1
- package/dist/integrations/platform/github/event-worker.js +24 -0
- package/dist/integrations/platform/github/event-worker.js.map +1 -1
- package/dist/integrations/platform/github/integration.d.ts +13 -3
- package/dist/integrations/platform/github/integration.d.ts.map +1 -1
- package/dist/integrations/platform/github/integration.js +35 -1
- package/dist/integrations/platform/github/integration.js.map +1 -1
- package/dist/integrations/platform/linear/event-worker.d.ts +105 -0
- package/dist/integrations/platform/linear/event-worker.d.ts.map +1 -0
- package/dist/integrations/platform/linear/event-worker.js +380 -0
- package/dist/integrations/platform/linear/event-worker.js.map +1 -0
- package/dist/integrations/platform/linear/integration.d.ts +9 -0
- package/dist/integrations/platform/linear/integration.d.ts.map +1 -1
- package/dist/integrations/platform/linear/integration.js +37 -1
- package/dist/integrations/platform/linear/integration.js.map +1 -1
- package/dist/routes/config.d.ts +25 -0
- package/dist/routes/config.d.ts.map +1 -1
- package/dist/routes/config.js +63 -1
- package/dist/routes/config.js.map +1 -1
- package/dist/routes/fs.d.ts +16 -2
- package/dist/routes/fs.d.ts.map +1 -1
- package/dist/routes/fs.js +47 -5
- package/dist/routes/fs.js.map +1 -1
- package/dist/routes/surface.d.ts +2 -0
- package/dist/routes/surface.d.ts.map +1 -1
- package/dist/routes/surface.js +2 -1
- package/dist/routes/surface.js.map +1 -1
- package/dist/rules/binding-context.d.ts +28 -1
- package/dist/rules/binding-context.d.ts.map +1 -1
- package/dist/rules/binding-context.js +66 -1
- package/dist/rules/binding-context.js.map +1 -1
- package/dist/rules/defaults.d.ts.map +1 -1
- package/dist/rules/defaults.js +37 -2
- package/dist/rules/defaults.js.map +1 -1
- package/dist/rules/tools.d.ts +2 -0
- package/dist/rules/tools.d.ts.map +1 -1
- package/dist/rules/tools.js +15 -6
- package/dist/rules/tools.js.map +1 -1
- package/dist/rules/types.d.ts +7 -2
- package/dist/rules/types.d.ts.map +1 -1
- package/dist/rules/types.js +2 -1
- package/dist/rules/types.js.map +1 -1
- package/dist/session/filesystem-capture.d.ts +26 -0
- package/dist/session/filesystem-capture.d.ts.map +1 -0
- package/dist/session/filesystem-capture.js +75 -0
- package/dist/session/filesystem-capture.js.map +1 -0
- package/dist/storage/domains/filesystem/base.d.ts +26 -0
- package/dist/storage/domains/filesystem/base.d.ts.map +1 -0
- package/dist/storage/domains/filesystem/base.js +74 -0
- package/dist/storage/domains/filesystem/base.js.map +1 -0
- package/dist/storage/domains/projects/base.d.ts +1 -0
- package/dist/storage/domains/projects/base.d.ts.map +1 -1
- package/dist/storage/domains/projects/base.js +3 -0
- package/dist/storage/domains/projects/base.js.map +1 -1
- package/dist/storage/domains/source-control/base.d.ts +2 -0
- package/dist/storage/domains/source-control/base.d.ts.map +1 -1
- package/dist/storage/domains/source-control/base.js +6 -0
- package/dist/storage/domains/source-control/base.js.map +1 -1
- package/dist/storage/domains/source-control/inmemory.d.ts.map +1 -1
- package/dist/storage/domains/source-control/inmemory.js +3 -0
- package/dist/storage/domains/source-control/inmemory.js.map +1 -1
- package/dist/storage/domains/work-items/base.d.ts +11 -0
- package/dist/storage/domains/work-items/base.d.ts.map +1 -1
- package/dist/storage/domains/work-items/base.js +17 -0
- package/dist/storage/domains/work-items/base.js.map +1 -1
- package/factory-skills/factory-triage/SKILL.md +45 -12
- package/package.json +7 -7
package/dist/rules/defaults.js
CHANGED
|
@@ -96,10 +96,24 @@ function issueOpened(context) {
|
|
|
96
96
|
githubRepositoryId: context.repository.id,
|
|
97
97
|
githubIssueNumber: context.issue.number,
|
|
98
98
|
...githubActorLogin(context) ? { author: githubActorLogin(context) } : {},
|
|
99
|
-
assignees: context.issue.assignees ?? []
|
|
99
|
+
assignees: context.issue.assignees ?? [],
|
|
100
|
+
labels: context.issue.labels ?? []
|
|
100
101
|
}
|
|
101
102
|
};
|
|
102
103
|
}
|
|
104
|
+
function issueClosed(context) {
|
|
105
|
+
if (!context.item || context.item.source !== "github-issue" || !context.issue) return;
|
|
106
|
+
if (context.board !== "work") return;
|
|
107
|
+
if (context.item.stages.some((stage) => stage === "done" || stage === "canceled")) return;
|
|
108
|
+
const canceled = context.issue.stateReason === "not_planned" || context.issue.stateReason === "duplicate";
|
|
109
|
+
return {
|
|
110
|
+
type: "transition",
|
|
111
|
+
idempotencyKey: `${context.ingress.id}:issue-closed`,
|
|
112
|
+
board: "work",
|
|
113
|
+
stage: canceled ? "canceled" : "done",
|
|
114
|
+
message: { text: `GitHub issue #${context.issue.number} was closed${context.issue.stateReason ? ` (${context.issue.stateReason})` : ""}; this Work card was moved to ${canceled ? "Canceled" : "Done"}.` }
|
|
115
|
+
};
|
|
116
|
+
}
|
|
103
117
|
function pullRequestOpened(context) {
|
|
104
118
|
if (!context.pullRequest) return;
|
|
105
119
|
return {
|
|
@@ -120,6 +134,7 @@ function pullRequestOpened(context) {
|
|
|
120
134
|
merged: context.pullRequest.merged,
|
|
121
135
|
assignees: context.pullRequest.assignees ?? [],
|
|
122
136
|
requestedReviewers: context.pullRequest.requestedReviewers ?? [],
|
|
137
|
+
labels: context.pullRequest.labels ?? [],
|
|
123
138
|
headBranch: context.pullRequest.headBranch,
|
|
124
139
|
baseBranch: context.pullRequest.baseBranch,
|
|
125
140
|
...githubActorLogin(context) ? { author: githubActorLogin(context) } : {}
|
|
@@ -186,6 +201,7 @@ function linearIssueObserved(context) {
|
|
|
186
201
|
linearAssignee: context.issue.assignee,
|
|
187
202
|
linearCreator: context.issue.creator,
|
|
188
203
|
linearTeam: context.issue.team,
|
|
204
|
+
labels: [...context.issue.labels],
|
|
189
205
|
...context.issue.assignee ? { assignee: context.issue.assignee } : {},
|
|
190
206
|
...context.issue.creator ? {
|
|
191
207
|
creator: context.issue.creator,
|
|
@@ -194,6 +210,21 @@ function linearIssueObserved(context) {
|
|
|
194
210
|
}
|
|
195
211
|
};
|
|
196
212
|
}
|
|
213
|
+
function linearIssueClosed(context) {
|
|
214
|
+
if (!context.item || context.item.source !== "linear-issue") return;
|
|
215
|
+
if (context.board !== "work") return;
|
|
216
|
+
if (context.item.stages.some((stage) => stage === "done" || stage === "canceled")) return;
|
|
217
|
+
const stateType = context.issue.stateType;
|
|
218
|
+
if (stateType !== "completed" && stateType !== "canceled") return;
|
|
219
|
+
const canceled = stateType === "canceled";
|
|
220
|
+
return {
|
|
221
|
+
type: "transition",
|
|
222
|
+
idempotencyKey: `${context.ingress.id}:issue-closed`,
|
|
223
|
+
board: "work",
|
|
224
|
+
stage: canceled ? "canceled" : "done",
|
|
225
|
+
message: { text: `Linear issue ${context.issue.identifier} was ${canceled ? "canceled" : "completed"}; this Work card was moved to ${canceled ? "Canceled" : "Done"}.` }
|
|
226
|
+
};
|
|
227
|
+
}
|
|
197
228
|
const BUILT_IN_DEFAULTS = {
|
|
198
229
|
work: {
|
|
199
230
|
triage: {
|
|
@@ -211,6 +242,7 @@ const BUILT_IN_DEFAULTS = {
|
|
|
211
242
|
github: {
|
|
212
243
|
issueOpened: { onEvent: issueOpened },
|
|
213
244
|
issueEdited: { onEvent: retriageGithubIssue },
|
|
245
|
+
issueClosed: { onEvent: issueClosed },
|
|
214
246
|
issueCommentCreated: { onEvent: retriageGithubIssue },
|
|
215
247
|
issueCommentEdited: { onEvent: retriageGithubIssue },
|
|
216
248
|
issueCommentDeleted: { onEvent: retriageGithubIssue },
|
|
@@ -219,7 +251,10 @@ const BUILT_IN_DEFAULTS = {
|
|
|
219
251
|
pullRequestMerged: { onEvent: pullRequestMerged },
|
|
220
252
|
pullRequestClosed: { onEvent: pullRequestClosed }
|
|
221
253
|
},
|
|
222
|
-
linear: {
|
|
254
|
+
linear: {
|
|
255
|
+
issueObserved: { onEvent: linearIssueObserved },
|
|
256
|
+
issueClosed: { onEvent: linearIssueClosed }
|
|
257
|
+
}
|
|
223
258
|
};
|
|
224
259
|
function mergeBoardRules(base, overrides) {
|
|
225
260
|
const result = {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaults.js","names":[],"sources":["../../src/rules/defaults.ts"],"sourcesContent":["import type {\n FactoryBoardRuleLeaf,\n FactoryBoardRules,\n FactoryGithubRuleLeaf,\n FactoryGithubEventName,\n FactoryGithubRuleContext,\n FactoryLinearEventName,\n FactoryLinearRuleContext,\n FactoryLinearRuleLeaf,\n FactoryRules,\n FactoryRulesOverrides,\n FactoryRuleSource,\n FactoryRuleStage,\n FactoryStageRuleContext,\n FactoryToolResultRuleContext,\n FactoryToolRuleLeaf,\n} from './types.js';\nimport { assertFactoryRules, FactoryRuleValidationError } from './validation.js';\n\nexport const DEFAULT_FACTORY_RULE_VERSION = 'factory-default-v1';\n\nfunction trustedGithubActor(context: Pick<FactoryStageRuleContext, 'actor'>): boolean {\n return context.actor.type === 'github' && context.actor.trusted;\n}\n\nfunction githubActorLogin(context: Pick<FactoryStageRuleContext, 'actor'>): string | undefined {\n return context.actor.type === 'github' ? context.actor.login : undefined;\n}\n\nfunction invokeIssueInvestigation(context: FactoryStageRuleContext) {\n return {\n type: 'invokeSkill',\n idempotencyKey: `${context.ingress.id}:factory-triage`,\n role: 'triage',\n skillName: 'factory-triage',\n arguments: context.item.url ? `GitHub issue (${context.item.url})` : context.item.title,\n } as const;\n}\n\nfunction investigateTriagedIssue(context: FactoryStageRuleContext) {\n if (context.cause === 'linked_item_materialized' && context.fromStage === 'intake' && context.toStage === 'triage') {\n return;\n }\n return invokeIssueInvestigation(context);\n}\n\nfunction retriageGithubIssue(context: FactoryGithubRuleContext) {\n if (!context.item || context.item.source !== 'github-issue' || !context.item.url) return;\n if (context.actor.type === 'github' && context.actor.factoryAuthored) return;\n\n const reason =\n context.event === 'issueEdited'\n ? context.issueChange?.title && context.issueChange.body\n ? 'issue title and body edited'\n : context.issueChange?.title\n ? 'issue title edited'\n : 'issue body edited'\n : context.event === 'issueCommentDeleted'\n ? 'comment deleted'\n : context.event === 'issueCommentEdited'\n ? 'comment edited'\n : 'comment created';\n return {\n type: 'invokeSkill',\n idempotencyKey: `${context.ingress.id}:factory-triage`,\n role: 'triage',\n skillName: 'factory-triage',\n arguments: `Re-triage GitHub issue (${context.item.url}) after ${reason}.`,\n } as const;\n}\n\nfunction investigateTriagedLinearIssue(context: FactoryStageRuleContext) {\n const identifier = context.item.sourceKey?.startsWith('linear:')\n ? context.item.sourceKey.slice('linear:'.length)\n : context.item.title;\n return {\n type: 'invokeSkill',\n idempotencyKey: `${context.ingress.id}:factory-triage-linear`,\n role: 'triage',\n skillName: 'factory-triage',\n arguments: `Linear issue ${identifier}${context.item.url ? ` (${context.item.url})` : ''}`,\n } as const;\n}\n\nfunction planWorkItem(context: FactoryStageRuleContext) {\n return {\n type: 'invokeSkill',\n idempotencyKey: `${context.ingress.id}:factory-plan`,\n role: 'plan',\n skillName: 'factory-plan',\n arguments: context.item.url ? `Work item (${context.item.url})` : context.item.title,\n } as const;\n}\n\nfunction reviewPullRequest(context: FactoryStageRuleContext) {\n return {\n type: 'invokeSkill',\n idempotencyKey: `${context.ingress.id}:factory-review`,\n role: 'review',\n skillName: 'factory-review',\n arguments: context.item.url ? `GitHub pull request (${context.item.url})` : context.item.title,\n } as const;\n}\n\nfunction resultContent(value: unknown): string | undefined {\n if (typeof value === 'string') return value;\n if (!value || typeof value !== 'object' || Array.isArray(value)) return;\n const content = (value as { content?: unknown }).content;\n return typeof content === 'string' ? content : undefined;\n}\n\n// Interactive-session path only: factory-plan never calls submit_plan — it\n// advances planning → execute via factory_transition_work_item directly.\nfunction advanceApprovedPlan(context: FactoryToolResultRuleContext) {\n if (\n context.result.status !== 'success' ||\n context.board !== 'work' ||\n context.item.stages.length !== 1 ||\n context.item.stages[0] !== 'planning' ||\n context.actor.type !== 'agent' ||\n context.actor.role !== 'plan' ||\n !resultContent(context.result.value)?.startsWith('Plan approved.')\n ) {\n return;\n }\n return {\n type: 'transition',\n idempotencyKey: `${context.ingress.id}:approved-plan`,\n board: 'work',\n stage: 'execute',\n } as const;\n}\n\nfunction createdAfterFactory(createdAt: string | undefined, factoryCreatedAt: string): boolean {\n if (!createdAt) return false;\n const sourceCreatedAt = Date.parse(createdAt);\n const projectCreatedAt = Date.parse(factoryCreatedAt);\n return Number.isFinite(sourceCreatedAt) && Number.isFinite(projectCreatedAt) && sourceCreatedAt > projectCreatedAt;\n}\n\nfunction issueOpened(context: FactoryGithubRuleContext) {\n if (!context.issue) return;\n return {\n type: 'upsertLinkedWorkItem',\n idempotencyKey: `${context.ingress.id}:issue-intake`,\n board: 'work',\n source: 'github-issue',\n sourceKey: `github-issue:${context.issue.number}`,\n title: context.issue.title,\n url: context.issue.url,\n stage:\n trustedGithubActor(context) && createdAfterFactory(context.issue.createdAt, context.factory.createdAt)\n ? 'triage'\n : 'intake',\n metadata: {\n githubRepositoryId: context.repository.id,\n githubIssueNumber: context.issue.number,\n ...(githubActorLogin(context) ? { author: githubActorLogin(context) } : {}),\n assignees: context.issue.assignees ?? [],\n },\n } as const;\n}\n\nfunction pullRequestOpened(context: FactoryGithubRuleContext) {\n if (!context.pullRequest) return;\n return {\n type: 'upsertLinkedWorkItem',\n idempotencyKey: `${context.ingress.id}:pull-request-intake`,\n board: 'review',\n source: 'github-pr',\n sourceKey: `github-pr:${context.pullRequest.number}`,\n title: context.pullRequest.title,\n url: context.pullRequest.url,\n stage:\n trustedGithubActor(context) && createdAfterFactory(context.pullRequest.createdAt, context.factory.createdAt)\n ? 'review'\n : 'intake',\n metadata: {\n githubRepositoryId: context.repository.id,\n githubPullRequestNumber: context.pullRequest.number,\n factoryAuthored: context.actor.type === 'github' && context.actor.factoryAuthored,\n state: context.pullRequest.state,\n draft: context.pullRequest.draft,\n merged: context.pullRequest.merged,\n assignees: context.pullRequest.assignees ?? [],\n requestedReviewers: context.pullRequest.requestedReviewers ?? [],\n headBranch: context.pullRequest.headBranch,\n baseBranch: context.pullRequest.baseBranch,\n ...(githubActorLogin(context) ? { author: githubActorLogin(context) } : {}),\n },\n } as const;\n}\n\nfunction pullRequestMerged(context: FactoryGithubRuleContext) {\n if (!context.item || !context.pullRequest?.merged) return;\n if (context.board === 'review') {\n // The event is bound to the PR's own Review card: a merged PR is finished\n // review work, so always move the card to Done. The message only reaches\n // an active session (if any) — cards without one just move, instead of\n // failing retries against a binding that never existed.\n return {\n type: 'transition',\n idempotencyKey: `${context.ingress.id}:pull-request-merged`,\n board: 'review',\n stage: 'done',\n message: {\n text:\n `Pull request #${context.pullRequest.number} merged; this Review card was moved to Done. ` +\n 'No further review is needed unless follow-up work was requested.',\n },\n } as const;\n }\n // Provenance bound the event to the originating Work item instead: remind\n // its agent to assess completion — never auto-complete the Work item.\n return {\n type: 'sendMessage',\n idempotencyKey: `${context.ingress.id}:assess-work-completion`,\n role: 'work',\n message:\n `Pull request #${context.pullRequest.number} merged. Assess whether the linked Work item is complete. ` +\n 'Do not mark it Done solely because this PR merged; use factory_transition_work_item only after verifying the work.',\n } as const;\n}\n\nfunction pullRequestClosed(context: FactoryGithubRuleContext) {\n if (!context.item || !context.pullRequest || context.pullRequest.merged) return;\n if (context.board !== 'review') return;\n // A PR closed without merging is abandoned review work: clear the card off\n // the board instead of leaving it in Reviewing forever.\n return {\n type: 'transition',\n idempotencyKey: `${context.ingress.id}:pull-request-closed`,\n board: 'review',\n stage: 'canceled',\n message: {\n text:\n `Pull request #${context.pullRequest.number} was closed without merging; ` +\n 'this Review card was moved to Canceled.',\n },\n } as const;\n}\n\nfunction reReviewRequestedPullRequest(context: FactoryGithubRuleContext) {\n // Only a review re-requested *from Factory's own bot* restarts the review —\n // requesting a human reviewer is not Factory's signal.\n if (!context.item || context.board !== 'review' || !context.reviewRequest?.factoryReviewer) return;\n if (!context.pullRequest || context.pullRequest.state !== 'open' || context.pullRequest.merged) return;\n // Trusted (write/admin) requesters only: re-entering review checks out and\n // executes PR code, the same bar pullRequestOpened applies to auto-review.\n if (!trustedGithubActor(context)) return;\n if (context.actor.type === 'github' && context.actor.factoryAuthored) return;\n // Already in Reviewing: a review pass is pending or running; re-entering\n // would be a same-stage no-op anyway (stage rules only fire on change).\n if (context.item.stages.length === 1 && context.item.stages[0] === 'review') return;\n return {\n type: 'transition',\n idempotencyKey: `${context.ingress.id}:re-review-requested`,\n board: 'review',\n stage: 'review',\n } as const;\n}\n\nfunction linearIssueObserved(context: FactoryLinearRuleContext) {\n if (context.item) return;\n return {\n type: 'upsertLinkedWorkItem',\n idempotencyKey: `${context.ingress.id}:issue-triage`,\n board: 'work',\n source: 'linear-issue',\n sourceKey: `linear:${context.issue.identifier}`,\n title: `${context.issue.identifier}: ${context.issue.title}`,\n url: context.issue.url,\n stage: 'triage',\n metadata: {\n linearIssueId: context.issue.id,\n identifier: context.issue.identifier,\n linearState: context.issue.state,\n linearStateType: context.issue.stateType,\n linearPriority: context.issue.priorityLabel,\n linearAssignee: context.issue.assignee,\n linearCreator: context.issue.creator,\n linearTeam: context.issue.team,\n ...(context.issue.assignee ? { assignee: context.issue.assignee } : {}),\n ...(context.issue.creator ? { creator: context.issue.creator, author: context.issue.creator } : {}),\n },\n } as const;\n}\n\nconst BUILT_IN_DEFAULTS: FactoryRulesOverrides = {\n work: {\n triage: {\n issue: { onEnter: investigateTriagedIssue },\n linearIssue: { onEnter: investigateTriagedLinearIssue },\n },\n planning: {\n issue: { onEnter: planWorkItem },\n linearIssue: { onEnter: planWorkItem },\n manual: { onEnter: planWorkItem },\n },\n },\n review: { review: { pullRequest: { onEnter: reviewPullRequest } } },\n tools: { submit_plan: { onResult: advanceApprovedPlan } },\n github: {\n issueOpened: { onEvent: issueOpened },\n issueEdited: { onEvent: retriageGithubIssue },\n issueCommentCreated: { onEvent: retriageGithubIssue },\n issueCommentEdited: { onEvent: retriageGithubIssue },\n issueCommentDeleted: { onEvent: retriageGithubIssue },\n pullRequestOpened: { onEvent: pullRequestOpened },\n pullRequestReviewRequested: { onEvent: reReviewRequestedPullRequest },\n pullRequestMerged: { onEvent: pullRequestMerged },\n pullRequestClosed: { onEvent: pullRequestClosed },\n },\n linear: { issueObserved: { onEvent: linearIssueObserved } },\n};\n\nfunction mergeBoardRules(\n base: FactoryBoardRules | undefined,\n overrides: FactoryBoardRules | undefined,\n): FactoryBoardRules {\n const result: FactoryBoardRules = {};\n const stages = new Set([...Object.keys(base ?? {}), ...Object.keys(overrides ?? {})]) as Set<FactoryRuleStage>;\n for (const stage of stages) {\n const baseSources = base?.[stage];\n const overrideSources = overrides?.[stage];\n const sources = new Set([\n ...Object.keys(baseSources ?? {}),\n ...Object.keys(overrideSources ?? {}),\n ]) as Set<FactoryRuleSource>;\n const mergedSources: Partial<Record<FactoryRuleSource, FactoryBoardRuleLeaf>> = {};\n for (const source of sources) {\n const baseLeaf = baseSources?.[source];\n const overrideLeaf = overrideSources?.[source];\n mergedSources[source] = {\n ...(baseLeaf?.onEnter ? { onEnter: baseLeaf.onEnter } : {}),\n ...(baseLeaf?.onExit ? { onExit: baseLeaf.onExit } : {}),\n ...(overrideLeaf && 'onEnter' in overrideLeaf ? { onEnter: overrideLeaf.onEnter } : {}),\n ...(overrideLeaf && 'onExit' in overrideLeaf ? { onExit: overrideLeaf.onExit } : {}),\n };\n }\n result[stage] = mergedSources;\n }\n return result;\n}\n\nfunction mergeToolRules(\n base: Record<string, FactoryToolRuleLeaf> | undefined,\n overrides: Record<string, FactoryToolRuleLeaf> | undefined,\n): Record<string, FactoryToolRuleLeaf> {\n const result: Record<string, FactoryToolRuleLeaf> = {};\n for (const name of new Set([...Object.keys(base ?? {}), ...Object.keys(overrides ?? {})])) {\n const baseLeaf = base?.[name];\n const overrideLeaf = overrides?.[name];\n result[name] = {\n ...(baseLeaf?.onResult ? { onResult: baseLeaf.onResult } : {}),\n ...(overrideLeaf && 'onResult' in overrideLeaf ? { onResult: overrideLeaf.onResult } : {}),\n };\n }\n return result;\n}\n\nfunction mergeGithubRules(\n base: FactoryRulesOverrides['github'],\n overrides: FactoryRulesOverrides['github'],\n): NonNullable<FactoryRulesOverrides['github']> {\n const result: Partial<Record<FactoryGithubEventName, FactoryGithubRuleLeaf>> = {};\n const events = new Set([...Object.keys(base ?? {}), ...Object.keys(overrides ?? {})]) as Set<FactoryGithubEventName>;\n for (const event of events) {\n const baseLeaf = base?.[event];\n const overrideLeaf = overrides?.[event];\n result[event] = {\n ...(baseLeaf?.onEvent ? { onEvent: baseLeaf.onEvent } : {}),\n ...(overrideLeaf && 'onEvent' in overrideLeaf ? { onEvent: overrideLeaf.onEvent } : {}),\n };\n }\n return result;\n}\n\nfunction mergeLinearRules(\n base: FactoryRulesOverrides['linear'],\n overrides: FactoryRulesOverrides['linear'],\n): NonNullable<FactoryRulesOverrides['linear']> {\n const result: Partial<Record<FactoryLinearEventName, FactoryLinearRuleLeaf>> = {};\n const events = new Set([...Object.keys(base ?? {}), ...Object.keys(overrides ?? {})]) as Set<FactoryLinearEventName>;\n for (const event of events) {\n const baseLeaf = base?.[event];\n const overrideLeaf = overrides?.[event];\n result[event] = {\n ...(baseLeaf?.onEvent ? { onEvent: baseLeaf.onEvent } : {}),\n ...(overrideLeaf && 'onEvent' in overrideLeaf ? { onEvent: overrideLeaf.onEvent } : {}),\n };\n }\n return result;\n}\n\nexport function mergeFactoryRuleOverrides(\n base: FactoryRulesOverrides,\n overrides: FactoryRulesOverrides = {},\n): Omit<FactoryRules, 'version'> {\n return {\n work: mergeBoardRules(base.work, overrides.work),\n review: mergeBoardRules(base.review, overrides.review),\n tools: mergeToolRules(base.tools, overrides.tools),\n github: mergeGithubRules(base.github, overrides.github),\n linear: mergeLinearRules(base.linear, overrides.linear),\n };\n}\n\nexport function defaultFactoryRules(input: { version: string; overrides?: FactoryRulesOverrides }): FactoryRules {\n if (typeof input?.version !== 'string' || input.version.trim().length === 0) {\n throw new FactoryRuleValidationError('Factory rule version is required.');\n }\n\n const rules: FactoryRules = {\n version: input.version.trim(),\n ...mergeFactoryRuleOverrides(BUILT_IN_DEFAULTS, input.overrides),\n };\n assertFactoryRules(rules);\n return rules;\n}\n\nexport function builtInFactoryRules(): FactoryRules {\n return defaultFactoryRules({ version: DEFAULT_FACTORY_RULE_VERSION });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"defaults.js","names":[],"sources":["../../src/rules/defaults.ts"],"sourcesContent":["import type {\n FactoryBoardRuleLeaf,\n FactoryBoardRules,\n FactoryGithubRuleLeaf,\n FactoryGithubEventName,\n FactoryGithubRuleContext,\n FactoryLinearEventName,\n FactoryLinearRuleContext,\n FactoryLinearRuleLeaf,\n FactoryRules,\n FactoryRulesOverrides,\n FactoryRuleSource,\n FactoryRuleStage,\n FactoryStageRuleContext,\n FactoryToolResultRuleContext,\n FactoryToolRuleLeaf,\n} from './types.js';\nimport { assertFactoryRules, FactoryRuleValidationError } from './validation.js';\n\nexport const DEFAULT_FACTORY_RULE_VERSION = 'factory-default-v1';\n\nfunction trustedGithubActor(context: Pick<FactoryStageRuleContext, 'actor'>): boolean {\n return context.actor.type === 'github' && context.actor.trusted;\n}\n\nfunction githubActorLogin(context: Pick<FactoryStageRuleContext, 'actor'>): string | undefined {\n return context.actor.type === 'github' ? context.actor.login : undefined;\n}\n\nfunction invokeIssueInvestigation(context: FactoryStageRuleContext) {\n return {\n type: 'invokeSkill',\n idempotencyKey: `${context.ingress.id}:factory-triage`,\n role: 'triage',\n skillName: 'factory-triage',\n arguments: context.item.url ? `GitHub issue (${context.item.url})` : context.item.title,\n } as const;\n}\n\nfunction investigateTriagedIssue(context: FactoryStageRuleContext) {\n if (context.cause === 'linked_item_materialized' && context.fromStage === 'intake' && context.toStage === 'triage') {\n return;\n }\n return invokeIssueInvestigation(context);\n}\n\nfunction retriageGithubIssue(context: FactoryGithubRuleContext) {\n if (!context.item || context.item.source !== 'github-issue' || !context.item.url) return;\n if (context.actor.type === 'github' && context.actor.factoryAuthored) return;\n\n const reason =\n context.event === 'issueEdited'\n ? context.issueChange?.title && context.issueChange.body\n ? 'issue title and body edited'\n : context.issueChange?.title\n ? 'issue title edited'\n : 'issue body edited'\n : context.event === 'issueCommentDeleted'\n ? 'comment deleted'\n : context.event === 'issueCommentEdited'\n ? 'comment edited'\n : 'comment created';\n return {\n type: 'invokeSkill',\n idempotencyKey: `${context.ingress.id}:factory-triage`,\n role: 'triage',\n skillName: 'factory-triage',\n arguments: `Re-triage GitHub issue (${context.item.url}) after ${reason}.`,\n } as const;\n}\n\nfunction investigateTriagedLinearIssue(context: FactoryStageRuleContext) {\n const identifier = context.item.sourceKey?.startsWith('linear:')\n ? context.item.sourceKey.slice('linear:'.length)\n : context.item.title;\n return {\n type: 'invokeSkill',\n idempotencyKey: `${context.ingress.id}:factory-triage-linear`,\n role: 'triage',\n skillName: 'factory-triage',\n arguments: `Linear issue ${identifier}${context.item.url ? ` (${context.item.url})` : ''}`,\n } as const;\n}\n\nfunction planWorkItem(context: FactoryStageRuleContext) {\n return {\n type: 'invokeSkill',\n idempotencyKey: `${context.ingress.id}:factory-plan`,\n role: 'plan',\n skillName: 'factory-plan',\n arguments: context.item.url ? `Work item (${context.item.url})` : context.item.title,\n } as const;\n}\n\nfunction reviewPullRequest(context: FactoryStageRuleContext) {\n return {\n type: 'invokeSkill',\n idempotencyKey: `${context.ingress.id}:factory-review`,\n role: 'review',\n skillName: 'factory-review',\n arguments: context.item.url ? `GitHub pull request (${context.item.url})` : context.item.title,\n } as const;\n}\n\nfunction resultContent(value: unknown): string | undefined {\n if (typeof value === 'string') return value;\n if (!value || typeof value !== 'object' || Array.isArray(value)) return;\n const content = (value as { content?: unknown }).content;\n return typeof content === 'string' ? content : undefined;\n}\n\n// Interactive-session path only: factory-plan never calls submit_plan — it\n// advances planning → execute via factory_transition_work_item directly.\nfunction advanceApprovedPlan(context: FactoryToolResultRuleContext) {\n if (\n context.result.status !== 'success' ||\n context.board !== 'work' ||\n context.item.stages.length !== 1 ||\n context.item.stages[0] !== 'planning' ||\n context.actor.type !== 'agent' ||\n context.actor.role !== 'plan' ||\n !resultContent(context.result.value)?.startsWith('Plan approved.')\n ) {\n return;\n }\n return {\n type: 'transition',\n idempotencyKey: `${context.ingress.id}:approved-plan`,\n board: 'work',\n stage: 'execute',\n } as const;\n}\n\nfunction createdAfterFactory(createdAt: string | undefined, factoryCreatedAt: string): boolean {\n if (!createdAt) return false;\n const sourceCreatedAt = Date.parse(createdAt);\n const projectCreatedAt = Date.parse(factoryCreatedAt);\n return Number.isFinite(sourceCreatedAt) && Number.isFinite(projectCreatedAt) && sourceCreatedAt > projectCreatedAt;\n}\n\nfunction issueOpened(context: FactoryGithubRuleContext) {\n if (!context.issue) return;\n return {\n type: 'upsertLinkedWorkItem',\n idempotencyKey: `${context.ingress.id}:issue-intake`,\n board: 'work',\n source: 'github-issue',\n sourceKey: `github-issue:${context.issue.number}`,\n title: context.issue.title,\n url: context.issue.url,\n stage:\n trustedGithubActor(context) && createdAfterFactory(context.issue.createdAt, context.factory.createdAt)\n ? 'triage'\n : 'intake',\n metadata: {\n githubRepositoryId: context.repository.id,\n githubIssueNumber: context.issue.number,\n ...(githubActorLogin(context) ? { author: githubActorLogin(context) } : {}),\n assignees: context.issue.assignees ?? [],\n labels: context.issue.labels ?? [],\n },\n } as const;\n}\n\nfunction issueClosed(context: FactoryGithubRuleContext) {\n if (!context.item || context.item.source !== 'github-issue' || !context.issue) return;\n if (context.board !== 'work') return;\n // Already off the board: nothing to reconcile.\n if (context.item.stages.some(stage => stage === 'done' || stage === 'canceled')) return;\n // Issue closure is a repository fact, not third-party input — no actor trust\n // gate. `not_planned` (and `duplicate`) means abandoned, everything else is\n // completed work.\n const canceled = context.issue.stateReason === 'not_planned' || context.issue.stateReason === 'duplicate';\n return {\n type: 'transition',\n idempotencyKey: `${context.ingress.id}:issue-closed`,\n board: 'work',\n stage: canceled ? 'canceled' : 'done',\n message: {\n text:\n `GitHub issue #${context.issue.number} was closed` +\n `${context.issue.stateReason ? ` (${context.issue.stateReason})` : ''}; ` +\n `this Work card was moved to ${canceled ? 'Canceled' : 'Done'}.`,\n },\n } as const;\n}\n\nfunction pullRequestOpened(context: FactoryGithubRuleContext) {\n if (!context.pullRequest) return;\n return {\n type: 'upsertLinkedWorkItem',\n idempotencyKey: `${context.ingress.id}:pull-request-intake`,\n board: 'review',\n source: 'github-pr',\n sourceKey: `github-pr:${context.pullRequest.number}`,\n title: context.pullRequest.title,\n url: context.pullRequest.url,\n stage:\n trustedGithubActor(context) && createdAfterFactory(context.pullRequest.createdAt, context.factory.createdAt)\n ? 'review'\n : 'intake',\n metadata: {\n githubRepositoryId: context.repository.id,\n githubPullRequestNumber: context.pullRequest.number,\n factoryAuthored: context.actor.type === 'github' && context.actor.factoryAuthored,\n state: context.pullRequest.state,\n draft: context.pullRequest.draft,\n merged: context.pullRequest.merged,\n assignees: context.pullRequest.assignees ?? [],\n requestedReviewers: context.pullRequest.requestedReviewers ?? [],\n labels: context.pullRequest.labels ?? [],\n headBranch: context.pullRequest.headBranch,\n baseBranch: context.pullRequest.baseBranch,\n ...(githubActorLogin(context) ? { author: githubActorLogin(context) } : {}),\n },\n } as const;\n}\n\nfunction pullRequestMerged(context: FactoryGithubRuleContext) {\n if (!context.item || !context.pullRequest?.merged) return;\n if (context.board === 'review') {\n // The event is bound to the PR's own Review card: a merged PR is finished\n // review work, so always move the card to Done. The message only reaches\n // an active session (if any) — cards without one just move, instead of\n // failing retries against a binding that never existed.\n return {\n type: 'transition',\n idempotencyKey: `${context.ingress.id}:pull-request-merged`,\n board: 'review',\n stage: 'done',\n message: {\n text:\n `Pull request #${context.pullRequest.number} merged; this Review card was moved to Done. ` +\n 'No further review is needed unless follow-up work was requested.',\n },\n } as const;\n }\n // Provenance bound the event to the originating Work item instead: remind\n // its agent to assess completion — never auto-complete the Work item.\n return {\n type: 'sendMessage',\n idempotencyKey: `${context.ingress.id}:assess-work-completion`,\n role: 'work',\n message:\n `Pull request #${context.pullRequest.number} merged. Assess whether the linked Work item is complete. ` +\n 'Do not mark it Done solely because this PR merged; use factory_transition_work_item only after verifying the work.',\n } as const;\n}\n\nfunction pullRequestClosed(context: FactoryGithubRuleContext) {\n if (!context.item || !context.pullRequest || context.pullRequest.merged) return;\n if (context.board !== 'review') return;\n // A PR closed without merging is abandoned review work: clear the card off\n // the board instead of leaving it in Reviewing forever.\n return {\n type: 'transition',\n idempotencyKey: `${context.ingress.id}:pull-request-closed`,\n board: 'review',\n stage: 'canceled',\n message: {\n text:\n `Pull request #${context.pullRequest.number} was closed without merging; ` +\n 'this Review card was moved to Canceled.',\n },\n } as const;\n}\n\nfunction reReviewRequestedPullRequest(context: FactoryGithubRuleContext) {\n // Only a review re-requested *from Factory's own bot* restarts the review —\n // requesting a human reviewer is not Factory's signal.\n if (!context.item || context.board !== 'review' || !context.reviewRequest?.factoryReviewer) return;\n if (!context.pullRequest || context.pullRequest.state !== 'open' || context.pullRequest.merged) return;\n // Trusted (write/admin) requesters only: re-entering review checks out and\n // executes PR code, the same bar pullRequestOpened applies to auto-review.\n if (!trustedGithubActor(context)) return;\n if (context.actor.type === 'github' && context.actor.factoryAuthored) return;\n // Already in Reviewing: a review pass is pending or running; re-entering\n // would be a same-stage no-op anyway (stage rules only fire on change).\n if (context.item.stages.length === 1 && context.item.stages[0] === 'review') return;\n return {\n type: 'transition',\n idempotencyKey: `${context.ingress.id}:re-review-requested`,\n board: 'review',\n stage: 'review',\n } as const;\n}\n\nfunction linearIssueObserved(context: FactoryLinearRuleContext) {\n if (context.item) return;\n return {\n type: 'upsertLinkedWorkItem',\n idempotencyKey: `${context.ingress.id}:issue-triage`,\n board: 'work',\n source: 'linear-issue',\n sourceKey: `linear:${context.issue.identifier}`,\n title: `${context.issue.identifier}: ${context.issue.title}`,\n url: context.issue.url,\n stage: 'triage',\n metadata: {\n linearIssueId: context.issue.id,\n identifier: context.issue.identifier,\n linearState: context.issue.state,\n linearStateType: context.issue.stateType,\n linearPriority: context.issue.priorityLabel,\n linearAssignee: context.issue.assignee,\n linearCreator: context.issue.creator,\n linearTeam: context.issue.team,\n labels: [...context.issue.labels] as string[],\n ...(context.issue.assignee ? { assignee: context.issue.assignee } : {}),\n ...(context.issue.creator ? { creator: context.issue.creator, author: context.issue.creator } : {}),\n },\n } as const;\n}\n\nfunction linearIssueClosed(context: FactoryLinearRuleContext) {\n if (!context.item || context.item.source !== 'linear-issue') return;\n if (context.board !== 'work') return;\n // Already off the board: nothing to reconcile.\n if (context.item.stages.some(stage => stage === 'done' || stage === 'canceled')) return;\n // Only terminal state types trigger close.\n const stateType = context.issue.stateType;\n if (stateType !== 'completed' && stateType !== 'canceled') return;\n const canceled = stateType === 'canceled';\n return {\n type: 'transition',\n idempotencyKey: `${context.ingress.id}:issue-closed`,\n board: 'work',\n stage: canceled ? 'canceled' : 'done',\n message: {\n text: `Linear issue ${context.issue.identifier} was ${canceled ? 'canceled' : 'completed'}; this Work card was moved to ${canceled ? 'Canceled' : 'Done'}.`,\n },\n } as const;\n}\n\nconst BUILT_IN_DEFAULTS: FactoryRulesOverrides = {\n work: {\n triage: {\n issue: { onEnter: investigateTriagedIssue },\n linearIssue: { onEnter: investigateTriagedLinearIssue },\n },\n planning: {\n issue: { onEnter: planWorkItem },\n linearIssue: { onEnter: planWorkItem },\n manual: { onEnter: planWorkItem },\n },\n },\n review: { review: { pullRequest: { onEnter: reviewPullRequest } } },\n tools: { submit_plan: { onResult: advanceApprovedPlan } },\n github: {\n issueOpened: { onEvent: issueOpened },\n issueEdited: { onEvent: retriageGithubIssue },\n issueClosed: { onEvent: issueClosed },\n issueCommentCreated: { onEvent: retriageGithubIssue },\n issueCommentEdited: { onEvent: retriageGithubIssue },\n issueCommentDeleted: { onEvent: retriageGithubIssue },\n pullRequestOpened: { onEvent: pullRequestOpened },\n pullRequestReviewRequested: { onEvent: reReviewRequestedPullRequest },\n pullRequestMerged: { onEvent: pullRequestMerged },\n pullRequestClosed: { onEvent: pullRequestClosed },\n },\n linear: { issueObserved: { onEvent: linearIssueObserved }, issueClosed: { onEvent: linearIssueClosed } },\n};\n\nfunction mergeBoardRules(\n base: FactoryBoardRules | undefined,\n overrides: FactoryBoardRules | undefined,\n): FactoryBoardRules {\n const result: FactoryBoardRules = {};\n const stages = new Set([...Object.keys(base ?? {}), ...Object.keys(overrides ?? {})]) as Set<FactoryRuleStage>;\n for (const stage of stages) {\n const baseSources = base?.[stage];\n const overrideSources = overrides?.[stage];\n const sources = new Set([\n ...Object.keys(baseSources ?? {}),\n ...Object.keys(overrideSources ?? {}),\n ]) as Set<FactoryRuleSource>;\n const mergedSources: Partial<Record<FactoryRuleSource, FactoryBoardRuleLeaf>> = {};\n for (const source of sources) {\n const baseLeaf = baseSources?.[source];\n const overrideLeaf = overrideSources?.[source];\n mergedSources[source] = {\n ...(baseLeaf?.onEnter ? { onEnter: baseLeaf.onEnter } : {}),\n ...(baseLeaf?.onExit ? { onExit: baseLeaf.onExit } : {}),\n ...(overrideLeaf && 'onEnter' in overrideLeaf ? { onEnter: overrideLeaf.onEnter } : {}),\n ...(overrideLeaf && 'onExit' in overrideLeaf ? { onExit: overrideLeaf.onExit } : {}),\n };\n }\n result[stage] = mergedSources;\n }\n return result;\n}\n\nfunction mergeToolRules(\n base: Record<string, FactoryToolRuleLeaf> | undefined,\n overrides: Record<string, FactoryToolRuleLeaf> | undefined,\n): Record<string, FactoryToolRuleLeaf> {\n const result: Record<string, FactoryToolRuleLeaf> = {};\n for (const name of new Set([...Object.keys(base ?? {}), ...Object.keys(overrides ?? {})])) {\n const baseLeaf = base?.[name];\n const overrideLeaf = overrides?.[name];\n result[name] = {\n ...(baseLeaf?.onResult ? { onResult: baseLeaf.onResult } : {}),\n ...(overrideLeaf && 'onResult' in overrideLeaf ? { onResult: overrideLeaf.onResult } : {}),\n };\n }\n return result;\n}\n\nfunction mergeGithubRules(\n base: FactoryRulesOverrides['github'],\n overrides: FactoryRulesOverrides['github'],\n): NonNullable<FactoryRulesOverrides['github']> {\n const result: Partial<Record<FactoryGithubEventName, FactoryGithubRuleLeaf>> = {};\n const events = new Set([...Object.keys(base ?? {}), ...Object.keys(overrides ?? {})]) as Set<FactoryGithubEventName>;\n for (const event of events) {\n const baseLeaf = base?.[event];\n const overrideLeaf = overrides?.[event];\n result[event] = {\n ...(baseLeaf?.onEvent ? { onEvent: baseLeaf.onEvent } : {}),\n ...(overrideLeaf && 'onEvent' in overrideLeaf ? { onEvent: overrideLeaf.onEvent } : {}),\n };\n }\n return result;\n}\n\nfunction mergeLinearRules(\n base: FactoryRulesOverrides['linear'],\n overrides: FactoryRulesOverrides['linear'],\n): NonNullable<FactoryRulesOverrides['linear']> {\n const result: Partial<Record<FactoryLinearEventName, FactoryLinearRuleLeaf>> = {};\n const events = new Set([...Object.keys(base ?? {}), ...Object.keys(overrides ?? {})]) as Set<FactoryLinearEventName>;\n for (const event of events) {\n const baseLeaf = base?.[event];\n const overrideLeaf = overrides?.[event];\n result[event] = {\n ...(baseLeaf?.onEvent ? { onEvent: baseLeaf.onEvent } : {}),\n ...(overrideLeaf && 'onEvent' in overrideLeaf ? { onEvent: overrideLeaf.onEvent } : {}),\n };\n }\n return result;\n}\n\nexport function mergeFactoryRuleOverrides(\n base: FactoryRulesOverrides,\n overrides: FactoryRulesOverrides = {},\n): Omit<FactoryRules, 'version'> {\n return {\n work: mergeBoardRules(base.work, overrides.work),\n review: mergeBoardRules(base.review, overrides.review),\n tools: mergeToolRules(base.tools, overrides.tools),\n github: mergeGithubRules(base.github, overrides.github),\n linear: mergeLinearRules(base.linear, overrides.linear),\n };\n}\n\nexport function defaultFactoryRules(input: { version: string; overrides?: FactoryRulesOverrides }): FactoryRules {\n if (typeof input?.version !== 'string' || input.version.trim().length === 0) {\n throw new FactoryRuleValidationError('Factory rule version is required.');\n }\n\n const rules: FactoryRules = {\n version: input.version.trim(),\n ...mergeFactoryRuleOverrides(BUILT_IN_DEFAULTS, input.overrides),\n };\n assertFactoryRules(rules);\n return rules;\n}\n\nexport function builtInFactoryRules(): FactoryRules {\n return defaultFactoryRules({ version: DEFAULT_FACTORY_RULE_VERSION });\n}\n"],"mappings":"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"}
|
package/dist/rules/tools.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import type { RequestContext } from '@mastra/core/request-context';
|
|
2
2
|
import type { IntegrationTools } from '../integrations/base.js';
|
|
3
3
|
import type { WorkItemsStorage } from '../storage/domains/work-items/base.js';
|
|
4
|
+
import type { FactorySessionSourceLookup } from './binding-context.js';
|
|
4
5
|
import type { FactoryTransitionService } from './transition-service.js';
|
|
5
6
|
export declare function createFactoryTransitionTools(options: {
|
|
6
7
|
requestContext: RequestContext;
|
|
7
8
|
storage: WorkItemsStorage;
|
|
8
9
|
transitionService: Pick<FactoryTransitionService, 'transition'>;
|
|
10
|
+
sessions?: FactorySessionSourceLookup;
|
|
9
11
|
}): Promise<IntegrationTools>;
|
|
10
12
|
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/rules/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAInE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/rules/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAInE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AAC9E,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAEvE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AA0BxE,wBAAsB,4BAA4B,CAAC,OAAO,EAAE;IAC1D,cAAc,EAAE,cAAc,CAAC;IAC/B,OAAO,EAAE,gBAAgB,CAAC;IAC1B,iBAAiB,EAAE,IAAI,CAAC,wBAAwB,EAAE,YAAY,CAAC,CAAC;IAChE,QAAQ,CAAC,EAAE,0BAA0B,CAAC;CACvC,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAiD5B"}
|
package/dist/rules/tools.js
CHANGED
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
import { FACTORY_RULE_STAGES } from "./types.js";
|
|
2
|
-
import {
|
|
2
|
+
import { resolveFactorySessionAddress } from "./binding-context.js";
|
|
3
3
|
import { createTool } from "@mastra/core/tools";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
//#region src/rules/tools.ts
|
|
6
|
+
const MAX_RATIONALE_LENGTH = 1e3;
|
|
6
7
|
const transitionInputSchema = z.object({
|
|
7
8
|
stage: z.enum(FACTORY_RULE_STAGES),
|
|
8
9
|
expectedRevision: z.number().int().positive(),
|
|
9
|
-
rationale: z.string().trim().min(1).
|
|
10
|
+
rationale: z.string().trim().min(1).transform((value) => value.length <= MAX_RATIONALE_LENGTH ? value : `${value.slice(0, MAX_RATIONALE_LENGTH - 1)}…`)
|
|
10
11
|
}).strict();
|
|
11
12
|
function boardForSource(type) {
|
|
12
13
|
return type === "pull-request" ? "review" : "work";
|
|
13
14
|
}
|
|
14
15
|
async function createFactoryTransitionTools(options) {
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
const resolution = await resolveFactorySessionAddress({
|
|
17
|
+
requestContext: options.requestContext,
|
|
18
|
+
storage: options.storage,
|
|
19
|
+
sessions: options.sessions
|
|
20
|
+
});
|
|
21
|
+
if (!resolution) return {};
|
|
22
|
+
const availableBinding = resolution.binding ?? await options.storage.findActiveRunBinding(resolution.address);
|
|
18
23
|
if (!availableBinding) return {};
|
|
19
24
|
return { factory_transition_work_item: createTool({
|
|
20
25
|
id: "factory_transition_work_item",
|
|
@@ -22,7 +27,11 @@ async function createFactoryTransitionTools(options) {
|
|
|
22
27
|
inputSchema: transitionInputSchema,
|
|
23
28
|
requireApproval: true,
|
|
24
29
|
execute: async ({ stage, expectedRevision, rationale }, execution) => {
|
|
25
|
-
const currentAddress =
|
|
30
|
+
const currentAddress = (await resolveFactorySessionAddress({
|
|
31
|
+
requestContext: execution.requestContext,
|
|
32
|
+
storage: options.storage,
|
|
33
|
+
sessions: options.sessions
|
|
34
|
+
}))?.address ?? null;
|
|
26
35
|
const toolCallId = execution.agent?.toolCallId;
|
|
27
36
|
if (!currentAddress || !toolCallId) throw new Error("Factory transitions require an authenticated bound agent tool call.");
|
|
28
37
|
const binding = await options.storage.findActiveRunBinding(currentAddress);
|
package/dist/rules/tools.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.js","names":[],"sources":["../../src/rules/tools.ts"],"sourcesContent":["import type { RequestContext } from '@mastra/core/request-context';\nimport { createTool } from '@mastra/core/tools';\nimport { z } from 'zod';\n\nimport type { IntegrationTools } from '../integrations/base.js';\nimport type { WorkItemsStorage } from '../storage/domains/work-items/base.js';\nimport {
|
|
1
|
+
{"version":3,"file":"tools.js","names":[],"sources":["../../src/rules/tools.ts"],"sourcesContent":["import type { RequestContext } from '@mastra/core/request-context';\nimport { createTool } from '@mastra/core/tools';\nimport { z } from 'zod';\n\nimport type { IntegrationTools } from '../integrations/base.js';\nimport type { WorkItemsStorage } from '../storage/domains/work-items/base.js';\nimport type { FactorySessionSourceLookup } from './binding-context.js';\nimport { resolveFactorySessionAddress } from './binding-context.js';\nimport type { FactoryTransitionService } from './transition-service.js';\nimport { FACTORY_RULE_STAGES } from './types.js';\nimport type { FactoryRuleBoard } from './types.js';\n\nconst MAX_RATIONALE_LENGTH = 1_000;\n\nconst transitionInputSchema = z\n .object({\n stage: z.enum(FACTORY_RULE_STAGES),\n expectedRevision: z.number().int().positive(),\n // Providers strip maxLength from the JSON schema and models can't count characters, so a\n // hard cap invites overshoot-retry loops at the end of every run. Accept and clamp instead.\n rationale: z\n .string()\n .trim()\n .min(1)\n .transform(value =>\n value.length <= MAX_RATIONALE_LENGTH ? value : `${value.slice(0, MAX_RATIONALE_LENGTH - 1)}…`,\n ),\n })\n .strict();\n\nfunction boardForSource(type: string | undefined): FactoryRuleBoard {\n return type === 'pull-request' ? 'review' : 'work';\n}\n\nexport async function createFactoryTransitionTools(options: {\n requestContext: RequestContext;\n storage: WorkItemsStorage;\n transitionService: Pick<FactoryTransitionService, 'transition'>;\n sessions?: FactorySessionSourceLookup;\n}): Promise<IntegrationTools> {\n const resolution = await resolveFactorySessionAddress({\n requestContext: options.requestContext,\n storage: options.storage,\n sessions: options.sessions,\n });\n if (!resolution) return {};\n const availableBinding = resolution.binding ?? (await options.storage.findActiveRunBinding(resolution.address));\n if (!availableBinding) return {};\n\n return {\n factory_transition_work_item: createTool({\n id: 'factory_transition_work_item',\n description:\n 'Request a governed stage transition for the Factory work item exactly bound to this thread. Use the current revision from the factory-phase signal and explain why the transition is appropriate.',\n inputSchema: transitionInputSchema,\n requireApproval: true,\n execute: async ({ stage, expectedRevision, rationale }, execution) => {\n const currentResolution = await resolveFactorySessionAddress({\n requestContext: execution.requestContext,\n storage: options.storage,\n sessions: options.sessions,\n });\n const currentAddress = currentResolution?.address ?? null;\n const toolCallId = execution.agent?.toolCallId;\n if (!currentAddress || !toolCallId) {\n throw new Error('Factory transitions require an authenticated bound agent tool call.');\n }\n const binding = await options.storage.findActiveRunBinding(currentAddress);\n if (!binding || binding.id !== availableBinding.id) {\n throw new Error('Factory agent binding is unavailable, revoked, or no longer matches this session.');\n }\n const item = await options.storage.get({ orgId: binding.orgId, id: binding.workItemId });\n if (!item) throw new Error('Bound Factory work item not found.');\n\n return options.transitionService.transition({\n orgId: binding.orgId,\n factoryProjectId: binding.factoryProjectId,\n workItemId: binding.workItemId,\n board: boardForSource(item.externalSource?.type),\n stage,\n expectedRevision,\n actor: { type: 'agent', bindingId: binding.id, role: binding.role },\n ingress: { type: 'agent', identity: `${binding.id}:${toolCallId}` },\n cause: rationale,\n });\n },\n }),\n };\n}\n"],"mappings":";;;;;AAYA,MAAM,uBAAuB;AAE7B,MAAM,wBAAwB,EAC3B,OAAO;CACN,OAAO,EAAE,KAAK,mBAAmB;CACjC,kBAAkB,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS;CAG5C,WAAW,EACR,OAAO,CAAC,CACR,KAAK,CAAC,CACN,IAAI,CAAC,CAAC,CACN,WAAU,UACT,MAAM,UAAU,uBAAuB,QAAQ,GAAG,MAAM,MAAM,GAAG,uBAAuB,CAAC,EAAE,EAC7F;AACJ,CAAC,CAAC,CACD,OAAO;AAEV,SAAS,eAAe,MAA4C;CAClE,OAAO,SAAS,iBAAiB,WAAW;AAC9C;AAEA,eAAsB,6BAA6B,SAKrB;CAC5B,MAAM,aAAa,MAAM,6BAA6B;EACpD,gBAAgB,QAAQ;EACxB,SAAS,QAAQ;EACjB,UAAU,QAAQ;CACpB,CAAC;CACD,IAAI,CAAC,YAAY,OAAO,CAAC;CACzB,MAAM,mBAAmB,WAAW,WAAY,MAAM,QAAQ,QAAQ,qBAAqB,WAAW,OAAO;CAC7G,IAAI,CAAC,kBAAkB,OAAO,CAAC;CAE/B,OAAO,EACL,8BAA8B,WAAW;EACvC,IAAI;EACJ,aACE;EACF,aAAa;EACb,iBAAiB;EACjB,SAAS,OAAO,EAAE,OAAO,kBAAkB,aAAa,cAAc;GAMpE,MAAM,kBAAiB,MALS,6BAA6B;IAC3D,gBAAgB,UAAU;IAC1B,SAAS,QAAQ;IACjB,UAAU,QAAQ;GACpB,CAAC,EAAA,EACyC,WAAW;GACrD,MAAM,aAAa,UAAU,OAAO;GACpC,IAAI,CAAC,kBAAkB,CAAC,YACtB,MAAM,IAAI,MAAM,qEAAqE;GAEvF,MAAM,UAAU,MAAM,QAAQ,QAAQ,qBAAqB,cAAc;GACzE,IAAI,CAAC,WAAW,QAAQ,OAAO,iBAAiB,IAC9C,MAAM,IAAI,MAAM,mFAAmF;GAErG,MAAM,OAAO,MAAM,QAAQ,QAAQ,IAAI;IAAE,OAAO,QAAQ;IAAO,IAAI,QAAQ;GAAW,CAAC;GACvF,IAAI,CAAC,MAAM,MAAM,IAAI,MAAM,oCAAoC;GAE/D,OAAO,QAAQ,kBAAkB,WAAW;IAC1C,OAAO,QAAQ;IACf,kBAAkB,QAAQ;IAC1B,YAAY,QAAQ;IACpB,OAAO,eAAe,KAAK,gBAAgB,IAAI;IAC/C;IACA;IACA,OAAO;KAAE,MAAM;KAAS,WAAW,QAAQ;KAAI,MAAM,QAAQ;IAAK;IAClE,SAAS;KAAE,MAAM;KAAS,UAAU,GAAG,QAAQ,GAAG,GAAG;IAAa;IAClE,OAAO;GACT,CAAC;EACH;CACF,CAAC,EACH;AACF"}
|
package/dist/rules/types.d.ts
CHANGED
|
@@ -5,9 +5,9 @@ export declare const FACTORY_RULE_BOARDS: readonly ["work", "review"];
|
|
|
5
5
|
export type FactoryRuleBoard = (typeof FACTORY_RULE_BOARDS)[number];
|
|
6
6
|
export declare const FACTORY_RULE_SOURCES: readonly ["issue", "pullRequest", "linearIssue", "manual"];
|
|
7
7
|
export type FactoryRuleSource = (typeof FACTORY_RULE_SOURCES)[number];
|
|
8
|
-
export declare const FACTORY_GITHUB_EVENTS: readonly ["issueOpened", "issueEdited", "issueCommentCreated", "issueCommentEdited", "issueCommentDeleted", "pullRequestOpened", "pullRequestUpdated", "pullRequestReviewRequested", "pullRequestMerged", "pullRequestClosed"];
|
|
8
|
+
export declare const FACTORY_GITHUB_EVENTS: readonly ["issueOpened", "issueEdited", "issueClosed", "issueCommentCreated", "issueCommentEdited", "issueCommentDeleted", "pullRequestOpened", "pullRequestUpdated", "pullRequestReviewRequested", "pullRequestMerged", "pullRequestClosed"];
|
|
9
9
|
export type FactoryGithubEventName = (typeof FACTORY_GITHUB_EVENTS)[number];
|
|
10
|
-
export declare const FACTORY_LINEAR_EVENTS: readonly ["issueObserved"];
|
|
10
|
+
export declare const FACTORY_LINEAR_EVENTS: readonly ["issueObserved", "issueClosed"];
|
|
11
11
|
export type FactoryLinearEventName = (typeof FACTORY_LINEAR_EVENTS)[number];
|
|
12
12
|
export type FactoryRuleJsonValue = null | boolean | number | string | FactoryRuleJsonValue[] | {
|
|
13
13
|
[key: string]: FactoryRuleJsonValue;
|
|
@@ -97,6 +97,10 @@ export interface FactoryGithubRuleContext extends FactoryRuleContextBase {
|
|
|
97
97
|
createdAt?: string;
|
|
98
98
|
updatedAt?: string;
|
|
99
99
|
assignees?: string[];
|
|
100
|
+
labels?: string[];
|
|
101
|
+
state?: 'open' | 'closed';
|
|
102
|
+
/** GitHub close reason: `completed`, `not_planned`, or `duplicate`. */
|
|
103
|
+
stateReason?: string;
|
|
100
104
|
};
|
|
101
105
|
issueChange?: {
|
|
102
106
|
title: boolean;
|
|
@@ -121,6 +125,7 @@ export interface FactoryGithubRuleContext extends FactoryRuleContextBase {
|
|
|
121
125
|
merged: boolean;
|
|
122
126
|
assignees?: string[];
|
|
123
127
|
requestedReviewers?: string[];
|
|
128
|
+
labels?: string[];
|
|
124
129
|
headBranch: string;
|
|
125
130
|
baseBranch: string;
|
|
126
131
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/rules/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG,cAAc,GAAG,WAAW,GAAG,cAAc,GAAG,QAAQ,CAAC;AAEtF,eAAO,MAAM,mBAAmB,oFAAqF,CAAC;AACtH,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE,eAAO,MAAM,mBAAmB,6BAA8B,CAAC;AAC/D,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE,eAAO,MAAM,oBAAoB,4DAA6D,CAAC;AAC/F,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE,eAAO,MAAM,qBAAqB,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/rules/types.ts"],"names":[],"mappings":"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"}
|
package/dist/rules/types.js
CHANGED
|
@@ -18,6 +18,7 @@ const FACTORY_RULE_SOURCES = [
|
|
|
18
18
|
const FACTORY_GITHUB_EVENTS = [
|
|
19
19
|
"issueOpened",
|
|
20
20
|
"issueEdited",
|
|
21
|
+
"issueClosed",
|
|
21
22
|
"issueCommentCreated",
|
|
22
23
|
"issueCommentEdited",
|
|
23
24
|
"issueCommentDeleted",
|
|
@@ -27,7 +28,7 @@ const FACTORY_GITHUB_EVENTS = [
|
|
|
27
28
|
"pullRequestMerged",
|
|
28
29
|
"pullRequestClosed"
|
|
29
30
|
];
|
|
30
|
-
const FACTORY_LINEAR_EVENTS = ["issueObserved"];
|
|
31
|
+
const FACTORY_LINEAR_EVENTS = ["issueObserved", "issueClosed"];
|
|
31
32
|
function factoryRuleSourceForWorkItem(source) {
|
|
32
33
|
switch (source) {
|
|
33
34
|
case "github-issue": return "issue";
|
package/dist/rules/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","names":[],"sources":["../../src/rules/types.ts"],"sourcesContent":["export type WorkItemSource = 'github-issue' | 'github-pr' | 'linear-issue' | 'manual';\n\nexport const FACTORY_RULE_STAGES = ['intake', 'triage', 'planning', 'execute', 'review', 'done', 'canceled'] as const;\nexport type FactoryRuleStage = (typeof FACTORY_RULE_STAGES)[number];\n\nexport const FACTORY_RULE_BOARDS = ['work', 'review'] as const;\nexport type FactoryRuleBoard = (typeof FACTORY_RULE_BOARDS)[number];\n\nexport const FACTORY_RULE_SOURCES = ['issue', 'pullRequest', 'linearIssue', 'manual'] as const;\nexport type FactoryRuleSource = (typeof FACTORY_RULE_SOURCES)[number];\n\nexport const FACTORY_GITHUB_EVENTS = [\n 'issueOpened',\n 'issueEdited',\n 'issueCommentCreated',\n 'issueCommentEdited',\n 'issueCommentDeleted',\n 'pullRequestOpened',\n 'pullRequestUpdated',\n 'pullRequestReviewRequested',\n 'pullRequestMerged',\n 'pullRequestClosed',\n] as const;\nexport type FactoryGithubEventName = (typeof FACTORY_GITHUB_EVENTS)[number];\n\nexport const FACTORY_LINEAR_EVENTS = ['issueObserved'] as const;\nexport type FactoryLinearEventName = (typeof FACTORY_LINEAR_EVENTS)[number];\n\nexport type FactoryRuleJsonValue =\n | null\n | boolean\n | number\n | string\n | FactoryRuleJsonValue[]\n | { [key: string]: FactoryRuleJsonValue };\n\nexport interface FactoryRuleItemContext {\n id: string;\n source: WorkItemSource;\n sourceKey: string | null;\n parentWorkItemId: string | null;\n title: string;\n url: string | null;\n stages: readonly string[];\n}\n\nexport type FactoryRuleActor =\n | { type: 'human'; id: string }\n | { type: 'agent'; bindingId: string; role: string }\n | { type: 'github'; login: string; trusted: boolean; factoryAuthored: boolean }\n | { type: 'system'; id: string };\n\nexport interface FactoryRuleIngressIdentity {\n type: 'human' | 'agent' | 'toolResult' | 'github' | 'linear' | 'rule';\n id: string;\n}\n\nexport interface FactoryRuleCausalEntry {\n ingressId: string;\n decisionType: FactoryCommitDecision['type'];\n}\n\nexport interface FactoryRuleContextBase {\n tenant: { orgId: string; projectId: string };\n actor: FactoryRuleActor;\n ingress: FactoryRuleIngressIdentity;\n cause: string;\n causalChain: readonly FactoryRuleCausalEntry[];\n ruleSetVersion: string;\n}\n\nexport interface FactoryBoundRuleContext extends FactoryRuleContextBase {\n item: FactoryRuleItemContext;\n board: FactoryRuleBoard;\n itemRevision: number;\n}\n\nexport interface FactoryStageRuleContext extends FactoryBoundRuleContext {\n source: FactoryRuleSource;\n stage: FactoryRuleStage;\n fromStage: FactoryRuleStage;\n toStage: FactoryRuleStage;\n}\n\nexport interface FactoryToolResultRuleContext extends FactoryBoundRuleContext {\n toolName: string;\n threadId: string;\n assistantMessageId: string;\n toolCallId: string;\n result: {\n status: 'success' | 'error';\n value: FactoryRuleJsonValue;\n };\n}\n\nexport interface FactoryGithubRuleContext extends FactoryRuleContextBase {\n item?: FactoryRuleItemContext;\n board?: FactoryRuleBoard;\n itemRevision?: number;\n event: FactoryGithubEventName;\n deliveryId: string;\n factory: { createdAt: string };\n repository: { id: number; fullName: string };\n issue?: {\n number: number;\n title: string;\n url: string;\n createdAt?: string;\n updatedAt?: string;\n assignees?: string[];\n };\n issueChange?: { title: boolean; body: boolean };\n issueComment?: {\n id: number;\n body?: string;\n url?: string;\n author?: string;\n authorType?: string;\n createdAt?: string;\n updatedAt?: string;\n };\n pullRequest?: {\n number: number;\n title: string;\n url: string;\n createdAt?: string;\n state: 'open' | 'closed';\n draft: boolean;\n merged: boolean;\n assignees?: string[];\n requestedReviewers?: string[];\n headBranch: string;\n baseBranch: string;\n };\n /** Present on `pullRequestReviewRequested`: who review was (re-)requested from. */\n reviewRequest?: { reviewer: string; factoryReviewer: boolean };\n}\n\nexport interface FactoryLinearRuleContext extends FactoryRuleContextBase {\n item?: FactoryRuleItemContext;\n board?: FactoryRuleBoard;\n itemRevision?: number;\n event: FactoryLinearEventName;\n issue: {\n id: string;\n identifier: string;\n title: string;\n url: string;\n state: string;\n stateType: string;\n priorityLabel: string;\n assignee: string | null;\n creator: string | null;\n team: string | null;\n labels: readonly string[];\n createdAt: string;\n updatedAt: string;\n };\n}\n\nexport type FactoryRuleHandler<TContext> = (\n context: Readonly<TContext>,\n) => FactoryRuleDecision | void | Promise<FactoryRuleDecision | void>;\n\nexport interface FactoryBoardRuleLeaf {\n onEnter?: FactoryRuleHandler<FactoryStageRuleContext>;\n onExit?: FactoryRuleHandler<FactoryStageRuleContext>;\n}\n\nexport interface FactoryToolRuleLeaf {\n onResult?: FactoryRuleHandler<FactoryToolResultRuleContext>;\n}\n\nexport interface FactoryGithubRuleLeaf {\n onEvent?: FactoryRuleHandler<FactoryGithubRuleContext>;\n}\n\nexport interface FactoryLinearRuleLeaf {\n onEvent?: FactoryRuleHandler<FactoryLinearRuleContext>;\n}\n\nexport type FactoryBoardRules = Partial<\n Record<FactoryRuleStage, Partial<Record<FactoryRuleSource, FactoryBoardRuleLeaf>>>\n>;\n\nexport interface FactoryRules {\n version: string;\n work: FactoryBoardRules;\n review: FactoryBoardRules;\n tools: Record<string, FactoryToolRuleLeaf>;\n github: Partial<Record<FactoryGithubEventName, FactoryGithubRuleLeaf>>;\n linear: Partial<Record<FactoryLinearEventName, FactoryLinearRuleLeaf>>;\n}\n\nexport interface FactoryRulesOverrides {\n work?: FactoryBoardRules;\n review?: FactoryBoardRules;\n tools?: Record<string, FactoryToolRuleLeaf>;\n github?: Partial<Record<FactoryGithubEventName, FactoryGithubRuleLeaf>>;\n linear?: Partial<Record<FactoryLinearEventName, FactoryLinearRuleLeaf>>;\n}\n\nexport type FactoryRuleRejectionCode =\n | 'forbidden'\n | 'invalid_transition'\n | 'missing_binding'\n | 'stale'\n | 'timeout'\n | 'rule_error'\n | 'causal_depth_exceeded'\n | 'repeated_transition';\n\nexport interface FactoryRuleRejectDecision {\n type: 'reject';\n code: FactoryRuleRejectionCode;\n reason: string;\n}\n\ninterface FactoryCommitDecisionBase {\n idempotencyKey: string;\n}\n\nexport interface FactoryTransitionDecision extends FactoryCommitDecisionBase {\n type: 'transition';\n board: FactoryRuleBoard;\n stage: FactoryRuleStage;\n /**\n * Delivered to the item's active session (waking it if idle) after the\n * transition commits. Skipped when the item has no active run binding, so\n * informational messages never fail the transition.\n */\n message?: { text: string; role?: string };\n}\n\nexport interface FactoryUpsertLinkedWorkItemDecision extends FactoryCommitDecisionBase {\n type: 'upsertLinkedWorkItem';\n board: FactoryRuleBoard;\n source: WorkItemSource;\n sourceKey: string;\n title: string;\n url: string | null;\n stage: FactoryRuleStage;\n metadata?: Record<string, FactoryRuleJsonValue>;\n}\n\nexport interface FactoryInvokeSkillDecision extends FactoryCommitDecisionBase {\n type: 'invokeSkill';\n role: string;\n skillName: string;\n arguments?: string;\n precedingMessage?: string;\n}\n\nexport interface FactorySendMessageDecision extends FactoryCommitDecisionBase {\n type: 'sendMessage';\n role: string;\n message: string;\n priority?: 'medium' | 'high' | 'urgent';\n idleBehavior?: 'persist' | 'wake';\n prepareBinding?: boolean;\n}\n\nexport interface FactoryNotifyDecision extends FactoryCommitDecisionBase {\n type: 'notify';\n title: string;\n body?: string;\n level?: 'info' | 'warning' | 'error';\n}\n\nexport type FactoryCommitDecision =\n | FactoryTransitionDecision\n | FactoryUpsertLinkedWorkItemDecision\n | FactoryInvokeSkillDecision\n | FactorySendMessageDecision\n | FactoryNotifyDecision;\n\nexport type FactoryRuleDecision = FactoryRuleRejectDecision | FactoryCommitDecision;\n\nexport interface FactoryTransitionResultAccepted {\n status: 'accepted';\n transitionId: string;\n itemId: string;\n revision: number;\n stage: FactoryRuleStage;\n decisions: FactoryCommitDecision[];\n}\n\nexport interface FactoryTransitionResultRejected {\n status: 'rejected';\n transitionId: string;\n itemId: string;\n code: FactoryRuleRejectionCode;\n reason: string;\n}\n\nexport type FactoryTransitionResult = FactoryTransitionResultAccepted | FactoryTransitionResultRejected;\n\nexport function factoryRuleSourceForWorkItem(source: WorkItemSource): FactoryRuleSource {\n switch (source) {\n case 'github-issue':\n return 'issue';\n case 'github-pr':\n return 'pullRequest';\n case 'linear-issue':\n return 'linearIssue';\n case 'manual':\n return 'manual';\n }\n}\n"],"mappings":";AAEA,MAAa,sBAAsB;CAAC;CAAU;CAAU;CAAY;CAAW;CAAU;CAAQ;AAAU;AAG3G,MAAa,sBAAsB,CAAC,QAAQ,QAAQ;AAGpD,MAAa,uBAAuB;CAAC;CAAS;CAAe;CAAe;AAAQ;AAGpF,MAAa,wBAAwB;CACnC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAGA,MAAa,wBAAwB,CAAC,
|
|
1
|
+
{"version":3,"file":"types.js","names":[],"sources":["../../src/rules/types.ts"],"sourcesContent":["export type WorkItemSource = 'github-issue' | 'github-pr' | 'linear-issue' | 'manual';\n\nexport const FACTORY_RULE_STAGES = ['intake', 'triage', 'planning', 'execute', 'review', 'done', 'canceled'] as const;\nexport type FactoryRuleStage = (typeof FACTORY_RULE_STAGES)[number];\n\nexport const FACTORY_RULE_BOARDS = ['work', 'review'] as const;\nexport type FactoryRuleBoard = (typeof FACTORY_RULE_BOARDS)[number];\n\nexport const FACTORY_RULE_SOURCES = ['issue', 'pullRequest', 'linearIssue', 'manual'] as const;\nexport type FactoryRuleSource = (typeof FACTORY_RULE_SOURCES)[number];\n\nexport const FACTORY_GITHUB_EVENTS = [\n 'issueOpened',\n 'issueEdited',\n 'issueClosed',\n 'issueCommentCreated',\n 'issueCommentEdited',\n 'issueCommentDeleted',\n 'pullRequestOpened',\n 'pullRequestUpdated',\n 'pullRequestReviewRequested',\n 'pullRequestMerged',\n 'pullRequestClosed',\n] as const;\nexport type FactoryGithubEventName = (typeof FACTORY_GITHUB_EVENTS)[number];\n\nexport const FACTORY_LINEAR_EVENTS = ['issueObserved', 'issueClosed'] as const;\nexport type FactoryLinearEventName = (typeof FACTORY_LINEAR_EVENTS)[number];\n\nexport type FactoryRuleJsonValue =\n | null\n | boolean\n | number\n | string\n | FactoryRuleJsonValue[]\n | { [key: string]: FactoryRuleJsonValue };\n\nexport interface FactoryRuleItemContext {\n id: string;\n source: WorkItemSource;\n sourceKey: string | null;\n parentWorkItemId: string | null;\n title: string;\n url: string | null;\n stages: readonly string[];\n}\n\nexport type FactoryRuleActor =\n | { type: 'human'; id: string }\n | { type: 'agent'; bindingId: string; role: string }\n | { type: 'github'; login: string; trusted: boolean; factoryAuthored: boolean }\n | { type: 'system'; id: string };\n\nexport interface FactoryRuleIngressIdentity {\n type: 'human' | 'agent' | 'toolResult' | 'github' | 'linear' | 'rule';\n id: string;\n}\n\nexport interface FactoryRuleCausalEntry {\n ingressId: string;\n decisionType: FactoryCommitDecision['type'];\n}\n\nexport interface FactoryRuleContextBase {\n tenant: { orgId: string; projectId: string };\n actor: FactoryRuleActor;\n ingress: FactoryRuleIngressIdentity;\n cause: string;\n causalChain: readonly FactoryRuleCausalEntry[];\n ruleSetVersion: string;\n}\n\nexport interface FactoryBoundRuleContext extends FactoryRuleContextBase {\n item: FactoryRuleItemContext;\n board: FactoryRuleBoard;\n itemRevision: number;\n}\n\nexport interface FactoryStageRuleContext extends FactoryBoundRuleContext {\n source: FactoryRuleSource;\n stage: FactoryRuleStage;\n fromStage: FactoryRuleStage;\n toStage: FactoryRuleStage;\n}\n\nexport interface FactoryToolResultRuleContext extends FactoryBoundRuleContext {\n toolName: string;\n threadId: string;\n assistantMessageId: string;\n toolCallId: string;\n result: {\n status: 'success' | 'error';\n value: FactoryRuleJsonValue;\n };\n}\n\nexport interface FactoryGithubRuleContext extends FactoryRuleContextBase {\n item?: FactoryRuleItemContext;\n board?: FactoryRuleBoard;\n itemRevision?: number;\n event: FactoryGithubEventName;\n deliveryId: string;\n factory: { createdAt: string };\n repository: { id: number; fullName: string };\n issue?: {\n number: number;\n title: string;\n url: string;\n createdAt?: string;\n updatedAt?: string;\n assignees?: string[];\n labels?: string[];\n state?: 'open' | 'closed';\n /** GitHub close reason: `completed`, `not_planned`, or `duplicate`. */\n stateReason?: string;\n };\n issueChange?: { title: boolean; body: boolean };\n issueComment?: {\n id: number;\n body?: string;\n url?: string;\n author?: string;\n authorType?: string;\n createdAt?: string;\n updatedAt?: string;\n };\n pullRequest?: {\n number: number;\n title: string;\n url: string;\n createdAt?: string;\n state: 'open' | 'closed';\n draft: boolean;\n merged: boolean;\n assignees?: string[];\n requestedReviewers?: string[];\n labels?: string[];\n headBranch: string;\n baseBranch: string;\n };\n /** Present on `pullRequestReviewRequested`: who review was (re-)requested from. */\n reviewRequest?: { reviewer: string; factoryReviewer: boolean };\n}\n\nexport interface FactoryLinearRuleContext extends FactoryRuleContextBase {\n item?: FactoryRuleItemContext;\n board?: FactoryRuleBoard;\n itemRevision?: number;\n event: FactoryLinearEventName;\n issue: {\n id: string;\n identifier: string;\n title: string;\n url: string;\n state: string;\n stateType: string;\n priorityLabel: string;\n assignee: string | null;\n creator: string | null;\n team: string | null;\n labels: readonly string[];\n createdAt: string;\n updatedAt: string;\n };\n}\n\nexport type FactoryRuleHandler<TContext> = (\n context: Readonly<TContext>,\n) => FactoryRuleDecision | void | Promise<FactoryRuleDecision | void>;\n\nexport interface FactoryBoardRuleLeaf {\n onEnter?: FactoryRuleHandler<FactoryStageRuleContext>;\n onExit?: FactoryRuleHandler<FactoryStageRuleContext>;\n}\n\nexport interface FactoryToolRuleLeaf {\n onResult?: FactoryRuleHandler<FactoryToolResultRuleContext>;\n}\n\nexport interface FactoryGithubRuleLeaf {\n onEvent?: FactoryRuleHandler<FactoryGithubRuleContext>;\n}\n\nexport interface FactoryLinearRuleLeaf {\n onEvent?: FactoryRuleHandler<FactoryLinearRuleContext>;\n}\n\nexport type FactoryBoardRules = Partial<\n Record<FactoryRuleStage, Partial<Record<FactoryRuleSource, FactoryBoardRuleLeaf>>>\n>;\n\nexport interface FactoryRules {\n version: string;\n work: FactoryBoardRules;\n review: FactoryBoardRules;\n tools: Record<string, FactoryToolRuleLeaf>;\n github: Partial<Record<FactoryGithubEventName, FactoryGithubRuleLeaf>>;\n linear: Partial<Record<FactoryLinearEventName, FactoryLinearRuleLeaf>>;\n}\n\nexport interface FactoryRulesOverrides {\n work?: FactoryBoardRules;\n review?: FactoryBoardRules;\n tools?: Record<string, FactoryToolRuleLeaf>;\n github?: Partial<Record<FactoryGithubEventName, FactoryGithubRuleLeaf>>;\n linear?: Partial<Record<FactoryLinearEventName, FactoryLinearRuleLeaf>>;\n}\n\nexport type FactoryRuleRejectionCode =\n | 'forbidden'\n | 'invalid_transition'\n | 'missing_binding'\n | 'stale'\n | 'timeout'\n | 'rule_error'\n | 'causal_depth_exceeded'\n | 'repeated_transition';\n\nexport interface FactoryRuleRejectDecision {\n type: 'reject';\n code: FactoryRuleRejectionCode;\n reason: string;\n}\n\ninterface FactoryCommitDecisionBase {\n idempotencyKey: string;\n}\n\nexport interface FactoryTransitionDecision extends FactoryCommitDecisionBase {\n type: 'transition';\n board: FactoryRuleBoard;\n stage: FactoryRuleStage;\n /**\n * Delivered to the item's active session (waking it if idle) after the\n * transition commits. Skipped when the item has no active run binding, so\n * informational messages never fail the transition.\n */\n message?: { text: string; role?: string };\n}\n\nexport interface FactoryUpsertLinkedWorkItemDecision extends FactoryCommitDecisionBase {\n type: 'upsertLinkedWorkItem';\n board: FactoryRuleBoard;\n source: WorkItemSource;\n sourceKey: string;\n title: string;\n url: string | null;\n stage: FactoryRuleStage;\n metadata?: Record<string, FactoryRuleJsonValue>;\n}\n\nexport interface FactoryInvokeSkillDecision extends FactoryCommitDecisionBase {\n type: 'invokeSkill';\n role: string;\n skillName: string;\n arguments?: string;\n precedingMessage?: string;\n}\n\nexport interface FactorySendMessageDecision extends FactoryCommitDecisionBase {\n type: 'sendMessage';\n role: string;\n message: string;\n priority?: 'medium' | 'high' | 'urgent';\n idleBehavior?: 'persist' | 'wake';\n prepareBinding?: boolean;\n}\n\nexport interface FactoryNotifyDecision extends FactoryCommitDecisionBase {\n type: 'notify';\n title: string;\n body?: string;\n level?: 'info' | 'warning' | 'error';\n}\n\nexport type FactoryCommitDecision =\n | FactoryTransitionDecision\n | FactoryUpsertLinkedWorkItemDecision\n | FactoryInvokeSkillDecision\n | FactorySendMessageDecision\n | FactoryNotifyDecision;\n\nexport type FactoryRuleDecision = FactoryRuleRejectDecision | FactoryCommitDecision;\n\nexport interface FactoryTransitionResultAccepted {\n status: 'accepted';\n transitionId: string;\n itemId: string;\n revision: number;\n stage: FactoryRuleStage;\n decisions: FactoryCommitDecision[];\n}\n\nexport interface FactoryTransitionResultRejected {\n status: 'rejected';\n transitionId: string;\n itemId: string;\n code: FactoryRuleRejectionCode;\n reason: string;\n}\n\nexport type FactoryTransitionResult = FactoryTransitionResultAccepted | FactoryTransitionResultRejected;\n\nexport function factoryRuleSourceForWorkItem(source: WorkItemSource): FactoryRuleSource {\n switch (source) {\n case 'github-issue':\n return 'issue';\n case 'github-pr':\n return 'pullRequest';\n case 'linear-issue':\n return 'linearIssue';\n case 'manual':\n return 'manual';\n }\n}\n"],"mappings":";AAEA,MAAa,sBAAsB;CAAC;CAAU;CAAU;CAAY;CAAW;CAAU;CAAQ;AAAU;AAG3G,MAAa,sBAAsB,CAAC,QAAQ,QAAQ;AAGpD,MAAa,uBAAuB;CAAC;CAAS;CAAe;CAAe;AAAQ;AAGpF,MAAa,wBAAwB;CACnC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAGA,MAAa,wBAAwB,CAAC,iBAAiB,aAAa;AAqRpE,SAAgB,6BAA6B,QAA2C;CACtF,QAAQ,QAAR;EACE,KAAK,gBACH,OAAO;EACT,KAAK,aACH,OAAO;EACT,KAAK,gBACH,OAAO;EACT,KAAK,UACH,OAAO;CACX;AACF"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { SessionBeforeAgentEndListener } from '@mastra/core/agent-controller';
|
|
2
|
+
import type { WorkspaceSandbox } from '@mastra/core/workspace';
|
|
3
|
+
import type { FilesystemFile, FilesystemStorage } from '../storage/domains/filesystem/base.js';
|
|
4
|
+
import type { SourceControlStorageHandle } from '../storage/domains/source-control/base.js';
|
|
5
|
+
export interface FilesystemCaptureSession {
|
|
6
|
+
readonly identity: {
|
|
7
|
+
getResourceId(): string;
|
|
8
|
+
};
|
|
9
|
+
readonly thread: {
|
|
10
|
+
requireId(): string;
|
|
11
|
+
};
|
|
12
|
+
getWorkspace(): {
|
|
13
|
+
sandbox?: Pick<WorkspaceSandbox, 'executeCommand'>;
|
|
14
|
+
};
|
|
15
|
+
onBeforeAgentEnd(listener: SessionBeforeAgentEndListener): () => void;
|
|
16
|
+
}
|
|
17
|
+
export interface FilesystemCaptureDependencies {
|
|
18
|
+
filesystem: Pick<FilesystemStorage, 'replaceFiles'>;
|
|
19
|
+
sourceControl: {
|
|
20
|
+
sessions: Pick<SourceControlStorageHandle['sessions'], 'getBySessionId'>;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export declare function parseFilesystemCaptureFiles(output: string): FilesystemFile[];
|
|
24
|
+
export declare function captureSessionFilesystem(session: FilesystemCaptureSession, { filesystem, sourceControl }: FilesystemCaptureDependencies): Promise<void>;
|
|
25
|
+
export declare function observeSessionFilesystem(session: FilesystemCaptureSession, dependencies: FilesystemCaptureDependencies): () => void;
|
|
26
|
+
//# sourceMappingURL=filesystem-capture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filesystem-capture.d.ts","sourceRoot":"","sources":["../../src/session/filesystem-capture.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,+BAA+B,CAAC;AACnF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC/F,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,2CAA2C,CAAC;AAK5F,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,QAAQ,EAAE;QAAE,aAAa,IAAI,MAAM,CAAA;KAAE,CAAC;IAC/C,QAAQ,CAAC,MAAM,EAAE;QAAE,SAAS,IAAI,MAAM,CAAA;KAAE,CAAC;IACzC,YAAY,IAAI;QAAE,OAAO,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,CAAA;KAAE,CAAC;IACvE,gBAAgB,CAAC,QAAQ,EAAE,6BAA6B,GAAG,MAAM,IAAI,CAAC;CACvE;AAED,MAAM,WAAW,6BAA6B;IAC5C,UAAU,EAAE,IAAI,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAC;IACpD,aAAa,EAAE;QACb,QAAQ,EAAE,IAAI,CAAC,0BAA0B,CAAC,UAAU,CAAC,EAAE,gBAAgB,CAAC,CAAC;KAC1E,CAAC;CACH;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,EAAE,CAmB5E;AAED,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,wBAAwB,EACjC,EAAE,UAAU,EAAE,aAAa,EAAE,EAAE,6BAA6B,GAC3D,OAAO,CAAC,IAAI,CAAC,CA0Cf;AAED,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,wBAAwB,EACjC,YAAY,EAAE,6BAA6B,GAC1C,MAAM,IAAI,CAMZ"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
//#region src/session/filesystem-capture.ts
|
|
2
|
+
const GIT_STATUS_ARGS = [
|
|
3
|
+
"status",
|
|
4
|
+
"--porcelain=v1",
|
|
5
|
+
"-z",
|
|
6
|
+
"--untracked-files=all"
|
|
7
|
+
];
|
|
8
|
+
const ARTIFACTS_LIST_COMMAND = "cd \"$1\" && test -d .artifacts && find .artifacts -type f -print0 || true";
|
|
9
|
+
function parseFilesystemCaptureFiles(output) {
|
|
10
|
+
const files = /* @__PURE__ */ new Map();
|
|
11
|
+
const records = output.split("\0");
|
|
12
|
+
for (let index = 0; index < records.length; index += 1) {
|
|
13
|
+
const record = records[index];
|
|
14
|
+
if (!record || record.length < 4) continue;
|
|
15
|
+
const code = record.slice(0, 2);
|
|
16
|
+
let path = record.slice(3);
|
|
17
|
+
const moved = code.includes("R") || code.includes("C");
|
|
18
|
+
if (moved) index += 1;
|
|
19
|
+
if (path.startsWith("./")) path = path.slice(2);
|
|
20
|
+
if (!path || !code.includes("U") && code.includes("D") && !moved) continue;
|
|
21
|
+
files.set(path, { path });
|
|
22
|
+
}
|
|
23
|
+
return [...files.values()].toSorted((a, b) => a.path.localeCompare(b.path));
|
|
24
|
+
}
|
|
25
|
+
async function captureSessionFilesystem(session, { filesystem, sourceControl }) {
|
|
26
|
+
try {
|
|
27
|
+
const resourceId = session.identity.getResourceId();
|
|
28
|
+
const threadId = session.thread.requireId();
|
|
29
|
+
const sourceSession = await sourceControl.sessions.getBySessionId(resourceId);
|
|
30
|
+
const sandbox = session.getWorkspace().sandbox;
|
|
31
|
+
if (!sourceSession?.sandboxWorkdir || !sandbox?.executeCommand) return;
|
|
32
|
+
const result = await sandbox.executeCommand("git", [
|
|
33
|
+
"-C",
|
|
34
|
+
sourceSession.sandboxWorkdir,
|
|
35
|
+
...GIT_STATUS_ARGS
|
|
36
|
+
], { timeout: 3e4 });
|
|
37
|
+
if (result.exitCode !== 0) {
|
|
38
|
+
console.warn("[Factory filesystem capture] Unable to inspect Git status.", result.stderr);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const artifacts = await sandbox.executeCommand("sh", [
|
|
42
|
+
"-c",
|
|
43
|
+
ARTIFACTS_LIST_COMMAND,
|
|
44
|
+
"sh",
|
|
45
|
+
sourceSession.sandboxWorkdir
|
|
46
|
+
], { timeout: 3e4 });
|
|
47
|
+
if (artifacts.exitCode !== 0) {
|
|
48
|
+
console.warn("[Factory filesystem capture] Unable to list workspace artifacts.", artifacts.stderr);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const files = new Map(parseFilesystemCaptureFiles(result.stdout).map((file) => [file.path, file]));
|
|
52
|
+
for (const path of artifacts.stdout.split("\0")) {
|
|
53
|
+
const normalizedPath = path.replace(/^\.\//, "");
|
|
54
|
+
if (normalizedPath) files.set(normalizedPath, { path: normalizedPath });
|
|
55
|
+
}
|
|
56
|
+
await filesystem.replaceFiles({
|
|
57
|
+
resourceId,
|
|
58
|
+
threadId,
|
|
59
|
+
files: [...files.values()].toSorted((a, b) => a.path.localeCompare(b.path))
|
|
60
|
+
});
|
|
61
|
+
} catch (error) {
|
|
62
|
+
console.warn("[Factory filesystem capture] Unable to persist files.", error);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function observeSessionFilesystem(session, dependencies) {
|
|
66
|
+
let capture = Promise.resolve();
|
|
67
|
+
return session.onBeforeAgentEnd(() => {
|
|
68
|
+
capture = capture.then(() => captureSessionFilesystem(session, dependencies));
|
|
69
|
+
return capture;
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
//#endregion
|
|
73
|
+
export { captureSessionFilesystem, observeSessionFilesystem, parseFilesystemCaptureFiles };
|
|
74
|
+
|
|
75
|
+
//# sourceMappingURL=filesystem-capture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filesystem-capture.js","names":[],"sources":["../../src/session/filesystem-capture.ts"],"sourcesContent":["import type { SessionBeforeAgentEndListener } from '@mastra/core/agent-controller';\nimport type { WorkspaceSandbox } from '@mastra/core/workspace';\n\nimport type { FilesystemFile, FilesystemStorage } from '../storage/domains/filesystem/base.js';\nimport type { SourceControlStorageHandle } from '../storage/domains/source-control/base.js';\n\nconst GIT_STATUS_ARGS = ['status', '--porcelain=v1', '-z', '--untracked-files=all'];\nconst ARTIFACTS_LIST_COMMAND = 'cd \"$1\" && test -d .artifacts && find .artifacts -type f -print0 || true';\n\nexport interface FilesystemCaptureSession {\n readonly identity: { getResourceId(): string };\n readonly thread: { requireId(): string };\n getWorkspace(): { sandbox?: Pick<WorkspaceSandbox, 'executeCommand'> };\n onBeforeAgentEnd(listener: SessionBeforeAgentEndListener): () => void;\n}\n\nexport interface FilesystemCaptureDependencies {\n filesystem: Pick<FilesystemStorage, 'replaceFiles'>;\n sourceControl: {\n sessions: Pick<SourceControlStorageHandle['sessions'], 'getBySessionId'>;\n };\n}\n\nexport function parseFilesystemCaptureFiles(output: string): FilesystemFile[] {\n const files = new Map<string, FilesystemFile>();\n const records = output.split('\\0');\n\n for (let index = 0; index < records.length; index += 1) {\n const record = records[index];\n if (!record || record.length < 4) continue;\n\n const code = record.slice(0, 2);\n let path = record.slice(3);\n const moved = code.includes('R') || code.includes('C');\n if (moved) index += 1;\n if (path.startsWith('./')) path = path.slice(2);\n if (!path || (!code.includes('U') && code.includes('D') && !moved)) continue;\n\n files.set(path, { path });\n }\n\n return [...files.values()].toSorted((a, b) => a.path.localeCompare(b.path));\n}\n\nexport async function captureSessionFilesystem(\n session: FilesystemCaptureSession,\n { filesystem, sourceControl }: FilesystemCaptureDependencies,\n): Promise<void> {\n try {\n const resourceId = session.identity.getResourceId();\n const threadId = session.thread.requireId();\n const sourceSession = await sourceControl.sessions.getBySessionId(resourceId);\n const sandbox = session.getWorkspace().sandbox;\n if (!sourceSession?.sandboxWorkdir || !sandbox?.executeCommand) return;\n\n const result = await sandbox.executeCommand('git', ['-C', sourceSession.sandboxWorkdir, ...GIT_STATUS_ARGS], {\n timeout: 30_000,\n });\n if (result.exitCode !== 0) {\n console.warn('[Factory filesystem capture] Unable to inspect Git status.', result.stderr);\n return;\n }\n\n const artifacts = await sandbox.executeCommand(\n 'sh',\n ['-c', ARTIFACTS_LIST_COMMAND, 'sh', sourceSession.sandboxWorkdir],\n { timeout: 30_000 },\n );\n if (artifacts.exitCode !== 0) {\n console.warn('[Factory filesystem capture] Unable to list workspace artifacts.', artifacts.stderr);\n return;\n }\n\n const files = new Map(parseFilesystemCaptureFiles(result.stdout).map(file => [file.path, file]));\n for (const path of artifacts.stdout.split('\\0')) {\n const normalizedPath = path.replace(/^\\.\\//, '');\n if (normalizedPath) {\n files.set(normalizedPath, { path: normalizedPath });\n }\n }\n\n await filesystem.replaceFiles({\n resourceId,\n threadId,\n files: [...files.values()].toSorted((a, b) => a.path.localeCompare(b.path)),\n });\n } catch (error) {\n console.warn('[Factory filesystem capture] Unable to persist files.', error);\n }\n}\n\nexport function observeSessionFilesystem(\n session: FilesystemCaptureSession,\n dependencies: FilesystemCaptureDependencies,\n): () => void {\n let capture = Promise.resolve();\n return session.onBeforeAgentEnd(() => {\n capture = capture.then(() => captureSessionFilesystem(session, dependencies));\n return capture;\n });\n}\n"],"mappings":";AAMA,MAAM,kBAAkB;CAAC;CAAU;CAAkB;CAAM;AAAuB;AAClF,MAAM,yBAAyB;AAgB/B,SAAgB,4BAA4B,QAAkC;CAC5E,MAAM,wBAAQ,IAAI,IAA4B;CAC9C,MAAM,UAAU,OAAO,MAAM,IAAI;CAEjC,KAAK,IAAI,QAAQ,GAAG,QAAQ,QAAQ,QAAQ,SAAS,GAAG;EACtD,MAAM,SAAS,QAAQ;EACvB,IAAI,CAAC,UAAU,OAAO,SAAS,GAAG;EAElC,MAAM,OAAO,OAAO,MAAM,GAAG,CAAC;EAC9B,IAAI,OAAO,OAAO,MAAM,CAAC;EACzB,MAAM,QAAQ,KAAK,SAAS,GAAG,KAAK,KAAK,SAAS,GAAG;EACrD,IAAI,OAAO,SAAS;EACpB,IAAI,KAAK,WAAW,IAAI,GAAG,OAAO,KAAK,MAAM,CAAC;EAC9C,IAAI,CAAC,QAAS,CAAC,KAAK,SAAS,GAAG,KAAK,KAAK,SAAS,GAAG,KAAK,CAAC,OAAQ;EAEpE,MAAM,IAAI,MAAM,EAAE,KAAK,CAAC;CAC1B;CAEA,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,CAAC,CAAC,UAAU,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AAC5E;AAEA,eAAsB,yBACpB,SACA,EAAE,YAAY,iBACC;CACf,IAAI;EACF,MAAM,aAAa,QAAQ,SAAS,cAAc;EAClD,MAAM,WAAW,QAAQ,OAAO,UAAU;EAC1C,MAAM,gBAAgB,MAAM,cAAc,SAAS,eAAe,UAAU;EAC5E,MAAM,UAAU,QAAQ,aAAa,CAAC,CAAC;EACvC,IAAI,CAAC,eAAe,kBAAkB,CAAC,SAAS,gBAAgB;EAEhE,MAAM,SAAS,MAAM,QAAQ,eAAe,OAAO;GAAC;GAAM,cAAc;GAAgB,GAAG;EAAe,GAAG,EAC3G,SAAS,IACX,CAAC;EACD,IAAI,OAAO,aAAa,GAAG;GACzB,QAAQ,KAAK,8DAA8D,OAAO,MAAM;GACxF;EACF;EAEA,MAAM,YAAY,MAAM,QAAQ,eAC9B,MACA;GAAC;GAAM;GAAwB;GAAM,cAAc;EAAc,GACjE,EAAE,SAAS,IAAO,CACpB;EACA,IAAI,UAAU,aAAa,GAAG;GAC5B,QAAQ,KAAK,oEAAoE,UAAU,MAAM;GACjG;EACF;EAEA,MAAM,QAAQ,IAAI,IAAI,4BAA4B,OAAO,MAAM,CAAC,CAAC,KAAI,SAAQ,CAAC,KAAK,MAAM,IAAI,CAAC,CAAC;EAC/F,KAAK,MAAM,QAAQ,UAAU,OAAO,MAAM,IAAI,GAAG;GAC/C,MAAM,iBAAiB,KAAK,QAAQ,SAAS,EAAE;GAC/C,IAAI,gBACF,MAAM,IAAI,gBAAgB,EAAE,MAAM,eAAe,CAAC;EAEtD;EAEA,MAAM,WAAW,aAAa;GAC5B;GACA;GACA,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,CAAC,CAAC,UAAU,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;EAC5E,CAAC;CACH,SAAS,OAAO;EACd,QAAQ,KAAK,yDAAyD,KAAK;CAC7E;AACF;AAEA,SAAgB,yBACd,SACA,cACY;CACZ,IAAI,UAAU,QAAQ,QAAQ;CAC9B,OAAO,QAAQ,uBAAuB;EACpC,UAAU,QAAQ,WAAW,yBAAyB,SAAS,YAAY,CAAC;EAC5E,OAAO;CACT,CAAC;AACH"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { FactoryStorageDomain } from '@mastra/core/storage';
|
|
2
|
+
import type { CollectionSchema } from '@mastra/core/storage';
|
|
3
|
+
export interface FilesystemFile {
|
|
4
|
+
path: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ReplaceFilesystemFilesInput {
|
|
7
|
+
resourceId: string;
|
|
8
|
+
threadId: string;
|
|
9
|
+
files: FilesystemFile[];
|
|
10
|
+
}
|
|
11
|
+
export declare const FILESYSTEM_SCHEMAS: CollectionSchema[];
|
|
12
|
+
export declare class FilesystemStorage extends FactoryStorageDomain {
|
|
13
|
+
constructor();
|
|
14
|
+
init(): Promise<void>;
|
|
15
|
+
dangerouslyClearAll(): Promise<void>;
|
|
16
|
+
replaceFiles(input: ReplaceFilesystemFilesInput): Promise<void>;
|
|
17
|
+
listFiles(args: {
|
|
18
|
+
resourceId: string;
|
|
19
|
+
threadId: string;
|
|
20
|
+
}): Promise<FilesystemFile[]>;
|
|
21
|
+
deleteFiles(args: {
|
|
22
|
+
resourceId: string;
|
|
23
|
+
threadId: string;
|
|
24
|
+
}): Promise<number>;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/storage/domains/filesystem/base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAI7D,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,2BAA2B;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,cAAc,EAAE,CAAC;CACzB;AAED,eAAO,MAAM,kBAAkB,EAAE,gBAAgB,EAiBhD,CAAC;AAuCF,qBAAa,iBAAkB,SAAQ,oBAAoB;;IAKnD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIpC,YAAY,CAAC,KAAK,EAAE,2BAA2B,GAAG,OAAO,CAAC,IAAI,CAAC;IAY/D,SAAS,CAAC,IAAI,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IASpF,WAAW,CAAC,IAAI,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;CAInF"}
|