@mastra/factory 0.1.0-alpha.6 → 0.1.0-alpha.8
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 +19 -0
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +161 -15
- package/dist/factory.js.map +1 -1
- package/dist/index.js +161 -15
- package/dist/index.js.map +1 -1
- package/dist/integrations/github/integration.js +108 -1
- package/dist/integrations/github/integration.js.map +1 -1
- package/dist/integrations/github/pat.d.ts +38 -0
- package/dist/integrations/github/pat.d.ts.map +1 -0
- package/dist/integrations/github/pat.js +48 -0
- package/dist/integrations/github/pat.js.map +1 -0
- package/dist/integrations/github/provenance.js.map +1 -1
- package/dist/integrations/github/routes.d.ts.map +1 -1
- package/dist/integrations/github/routes.js +94 -1
- package/dist/integrations/github/routes.js.map +1 -1
- package/dist/integrations/github/session-subscriptions.d.ts.map +1 -1
- package/dist/integrations/github/session-subscriptions.js +30 -0
- package/dist/integrations/github/session-subscriptions.js.map +1 -1
- package/dist/integrations/github/token-refresh.d.ts +6 -0
- package/dist/integrations/github/token-refresh.d.ts.map +1 -1
- package/dist/integrations/github/token-refresh.js +10 -0
- package/dist/integrations/github/token-refresh.js.map +1 -1
- package/dist/integrations/platform/github/integration.d.ts.map +1 -1
- package/dist/integrations/platform/github/integration.js +110 -2
- package/dist/integrations/platform/github/integration.js.map +1 -1
- package/dist/routes/surface.js +7 -1
- package/dist/routes/surface.js.map +1 -1
- package/dist/routes/work-items.js.map +1 -1
- package/dist/rules/defaults.d.ts.map +1 -1
- package/dist/rules/defaults.js +20 -6
- package/dist/rules/defaults.js.map +1 -1
- package/dist/rules/index.js +20 -6
- package/dist/rules/index.js.map +1 -1
- package/dist/rules/start-coordinator.d.ts.map +1 -1
- package/dist/rules/start-coordinator.js +7 -1
- package/dist/rules/start-coordinator.js.map +1 -1
- package/dist/workspace.d.ts +5 -0
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js +65 -6
- package/dist/workspace.js.map +1 -1
- package/factory-skills/factory-plan/SKILL.md +61 -0
- package/factory-skills/factory-review/SKILL.md +73 -0
- package/factory-skills/factory-triage/SKILL.md +77 -0
- package/package.json +6 -6
- package/factory-skills/understand-issue/SKILL.md +0 -251
- package/factory-skills/understand-pr/SKILL.md +0 -270
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @mastra/factory
|
|
2
2
|
|
|
3
|
+
## 0.1.0-alpha.8
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Added autonomous first-pass skills to the Software Factory. Work items now get an automatic investigation, planning, or review pass as soon as they enter the matching board column — no human input needed mid-run: ([#20058](https://github.com/mastra-ai/mastra/pull/20058))
|
|
8
|
+
|
|
9
|
+
- **factory-triage** runs when an issue enters triage: it investigates the issue, diagnoses the root cause, and requests a move to planning (or done if the issue should be closed).
|
|
10
|
+
- **factory-plan** runs when an item enters planning: it produces a phased implementation plan and requests a move to execute.
|
|
11
|
+
- **factory-review** runs when a pull request enters review: it reviews the changes, posts a verdict, and requests completion.
|
|
12
|
+
|
|
13
|
+
Instead of stopping to ask questions, the skills decide and record each decision as an assumption, batching assumptions and genuinely-human questions into one terminal handoff message. The superseded interactive skills (understand-issue, understand-pr) were removed.
|
|
14
|
+
|
|
15
|
+
## 0.1.0-alpha.7
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- Updated dependencies:
|
|
20
|
+
- @mastra/code-sdk@1.0.0-alpha.18
|
|
21
|
+
|
|
3
22
|
## 0.1.0-alpha.6
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
package/dist/factory.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,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;AAwBrD,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;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,kBAAkB,EAAE,CAAC;IACpC;;;;;OAKG;IACH,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;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;AAwFD,qBAAa,aAAa;;gBAOZ,MAAM,EAAE,mBAAmB;IAWvC;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,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;AAwBrD,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;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,kBAAkB,EAAE,CAAC;IACpC;;;;;OAKG;IACH,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;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;AAwFD,qBAAa,aAAa;;gBAOZ,MAAM,EAAE,mBAAmB;IAWvC;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC;IA8dpC;;;;OAIG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAS/B,iFAAiF;IAC3E,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAGhC"}
|
package/dist/factory.js
CHANGED
|
@@ -24778,6 +24778,48 @@ function createFactoryAuthGate(provider) {
|
|
|
24778
24778
|
import { createTool } from "@mastra/core/tools";
|
|
24779
24779
|
import { z } from "zod";
|
|
24780
24780
|
|
|
24781
|
+
// src/integrations/github/pat.ts
|
|
24782
|
+
var PAT_SETTINGS_USER_ID = "__github_org_settings__";
|
|
24783
|
+
var FIELD_FOR_KIND = {
|
|
24784
|
+
default: "pat",
|
|
24785
|
+
reviewer: "reviewerPat"
|
|
24786
|
+
};
|
|
24787
|
+
function asToken(value) {
|
|
24788
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
24789
|
+
}
|
|
24790
|
+
async function getGithubPat(getStorage, orgId, kind = "default") {
|
|
24791
|
+
try {
|
|
24792
|
+
const settings = await getStorage().settings.get(orgId, PAT_SETTINGS_USER_ID);
|
|
24793
|
+
if (!settings) return null;
|
|
24794
|
+
if (kind === "reviewer") return asToken(settings.reviewerPat) ?? asToken(settings.pat);
|
|
24795
|
+
return asToken(settings.pat);
|
|
24796
|
+
} catch {
|
|
24797
|
+
return null;
|
|
24798
|
+
}
|
|
24799
|
+
}
|
|
24800
|
+
async function getGithubPatStatus(getStorage, orgId) {
|
|
24801
|
+
try {
|
|
24802
|
+
const settings = await getStorage().settings.get(orgId, PAT_SETTINGS_USER_ID);
|
|
24803
|
+
return {
|
|
24804
|
+
configured: asToken(settings?.pat) !== null,
|
|
24805
|
+
reviewerConfigured: asToken(settings?.reviewerPat) !== null
|
|
24806
|
+
};
|
|
24807
|
+
} catch {
|
|
24808
|
+
return { configured: false, reviewerConfigured: false };
|
|
24809
|
+
}
|
|
24810
|
+
}
|
|
24811
|
+
async function setGithubPat(storage, orgId, pat, kind = "default") {
|
|
24812
|
+
const existing = await storage.settings.get(orgId, PAT_SETTINGS_USER_ID) ?? {};
|
|
24813
|
+
await storage.settings.save(orgId, PAT_SETTINGS_USER_ID, { ...existing, [FIELD_FOR_KIND[kind]]: pat });
|
|
24814
|
+
}
|
|
24815
|
+
async function clearGithubPat(storage, orgId, kind = "default") {
|
|
24816
|
+
const existing = await storage.settings.get(orgId, PAT_SETTINGS_USER_ID);
|
|
24817
|
+
const field = FIELD_FOR_KIND[kind];
|
|
24818
|
+
if (!existing?.[field]) return;
|
|
24819
|
+
const { [field]: _removed, ...rest } = existing;
|
|
24820
|
+
await storage.settings.save(orgId, PAT_SETTINGS_USER_ID, rest);
|
|
24821
|
+
}
|
|
24822
|
+
|
|
24781
24823
|
// src/integrations/github/subscriptions.ts
|
|
24782
24824
|
function changeRequestTargetKey(input) {
|
|
24783
24825
|
return `change-request:${input.installationExternalId}:${input.repositoryExternalId}:${input.changeRequestId}`;
|
|
@@ -24832,9 +24874,17 @@ function retirePullRequestSubscription(id, status, storage) {
|
|
|
24832
24874
|
|
|
24833
24875
|
// src/integrations/github/token-refresh.ts
|
|
24834
24876
|
var GITHUB_TOKEN_INJECTOR_CONTEXT_KEY = "factoryGithubTokenInjector";
|
|
24877
|
+
var GITHUB_PAT_KIND_CONTEXT_KEY = "factoryGithubPatKind";
|
|
24835
24878
|
function registerGithubTokenInjector(requestContext, injector) {
|
|
24836
24879
|
requestContext.set(GITHUB_TOKEN_INJECTOR_CONTEXT_KEY, injector);
|
|
24837
24880
|
}
|
|
24881
|
+
function registerGithubPatKind(requestContext, kind) {
|
|
24882
|
+
requestContext.set(GITHUB_PAT_KIND_CONTEXT_KEY, kind);
|
|
24883
|
+
}
|
|
24884
|
+
function getRegisteredGithubPatKind(requestContext) {
|
|
24885
|
+
const kind = requestContext.get(GITHUB_PAT_KIND_CONTEXT_KEY);
|
|
24886
|
+
return kind === "reviewer" ? "reviewer" : "default";
|
|
24887
|
+
}
|
|
24838
24888
|
function injectGithubToken(requestContext, token) {
|
|
24839
24889
|
const injector = requestContext.get(GITHUB_TOKEN_INJECTOR_CONTEXT_KEY);
|
|
24840
24890
|
if (!injector) {
|
|
@@ -24932,6 +24982,15 @@ async function unsubscribeCurrentSessionFromPullRequest(requestContext, pullRequ
|
|
|
24932
24982
|
}
|
|
24933
24983
|
async function refreshGithubToken(requestContext, github) {
|
|
24934
24984
|
const target = await resolveSessionTarget(requestContext, github);
|
|
24985
|
+
const pat = await getGithubPat(
|
|
24986
|
+
() => github.integrationStorage,
|
|
24987
|
+
target.orgId,
|
|
24988
|
+
getRegisteredGithubPatKind(requestContext)
|
|
24989
|
+
);
|
|
24990
|
+
if (pat) {
|
|
24991
|
+
injectGithubToken(requestContext, pat);
|
|
24992
|
+
return;
|
|
24993
|
+
}
|
|
24935
24994
|
const access = await github.versionControl.getRepositoryAccess({
|
|
24936
24995
|
orgId: target.orgId,
|
|
24937
24996
|
repositoryId: target.repository.id
|
|
@@ -26659,6 +26718,56 @@ function buildGithubRoutes(options) {
|
|
|
26659
26718
|
}
|
|
26660
26719
|
})
|
|
26661
26720
|
);
|
|
26721
|
+
const parsePatKind = (value) => {
|
|
26722
|
+
if (value === void 0 || value === null || value === "default") return "default";
|
|
26723
|
+
if (value === "reviewer") return "reviewer";
|
|
26724
|
+
return null;
|
|
26725
|
+
};
|
|
26726
|
+
routes.push(
|
|
26727
|
+
registerApiRoute2("/web/github/pat", {
|
|
26728
|
+
method: "GET",
|
|
26729
|
+
requiresAuth: false,
|
|
26730
|
+
handler: async (c) => {
|
|
26731
|
+
const resolved = await resolveOrgTenant(loose(c), auth);
|
|
26732
|
+
if ("response" in resolved) return resolved.response;
|
|
26733
|
+
return c.json(await getGithubPatStatus(() => github.integrationStorage, resolved.tenant.orgId));
|
|
26734
|
+
}
|
|
26735
|
+
}),
|
|
26736
|
+
registerApiRoute2("/web/github/pat", {
|
|
26737
|
+
method: "POST",
|
|
26738
|
+
requiresAuth: false,
|
|
26739
|
+
handler: async (c) => {
|
|
26740
|
+
const resolved = await resolveOrgTenant(loose(c), auth);
|
|
26741
|
+
if ("response" in resolved) return resolved.response;
|
|
26742
|
+
let body;
|
|
26743
|
+
try {
|
|
26744
|
+
body = await c.req.json();
|
|
26745
|
+
} catch {
|
|
26746
|
+
return c.json({ error: "Invalid JSON body" }, 400);
|
|
26747
|
+
}
|
|
26748
|
+
const kind = parsePatKind(body.kind);
|
|
26749
|
+
if (!kind) return c.json({ error: "kind must be 'default' or 'reviewer'" }, 400);
|
|
26750
|
+
const token = typeof body.token === "string" ? body.token.trim() : "";
|
|
26751
|
+
if (!token) return c.json({ error: "A token is required" }, 400);
|
|
26752
|
+
if (token.length > 500) return c.json({ error: "Token too long (max 500 characters)" }, 400);
|
|
26753
|
+
if (/\s/.test(token)) return c.json({ error: "Token must not contain whitespace" }, 400);
|
|
26754
|
+
await setGithubPat(github.integrationStorage, resolved.tenant.orgId, token, kind);
|
|
26755
|
+
return c.json(await getGithubPatStatus(() => github.integrationStorage, resolved.tenant.orgId));
|
|
26756
|
+
}
|
|
26757
|
+
}),
|
|
26758
|
+
registerApiRoute2("/web/github/pat", {
|
|
26759
|
+
method: "DELETE",
|
|
26760
|
+
requiresAuth: false,
|
|
26761
|
+
handler: async (c) => {
|
|
26762
|
+
const resolved = await resolveOrgTenant(loose(c), auth);
|
|
26763
|
+
if ("response" in resolved) return resolved.response;
|
|
26764
|
+
const kind = parsePatKind(c.req.query("kind"));
|
|
26765
|
+
if (!kind) return c.json({ error: "kind must be 'default' or 'reviewer'" }, 400);
|
|
26766
|
+
await clearGithubPat(github.integrationStorage, resolved.tenant.orgId, kind);
|
|
26767
|
+
return c.json(await getGithubPatStatus(() => github.integrationStorage, resolved.tenant.orgId));
|
|
26768
|
+
}
|
|
26769
|
+
})
|
|
26770
|
+
);
|
|
26662
26771
|
routes.push(...buildProjectGitRoutes({ github, auth, fleet, storage, emitAudit }));
|
|
26663
26772
|
return routes;
|
|
26664
26773
|
}
|
|
@@ -26701,11 +26810,12 @@ async function prepareProject(options) {
|
|
|
26701
26810
|
if (!access.authorization) {
|
|
26702
26811
|
throw new MaterializeError("Repository access did not include a bearer token.", "clone-failed");
|
|
26703
26812
|
}
|
|
26813
|
+
const ghCliToken = await getGithubPat(() => github.integrationStorage, project.installation.orgId) ?? access.authorization.token;
|
|
26704
26814
|
const sandbox = await ensureProjectSandbox({
|
|
26705
26815
|
fleet,
|
|
26706
26816
|
row: sandboxRow,
|
|
26707
26817
|
storage: github.sourceControlStorage.sandboxes,
|
|
26708
|
-
token:
|
|
26818
|
+
token: ghCliToken,
|
|
26709
26819
|
onProgress
|
|
26710
26820
|
});
|
|
26711
26821
|
const fresh = await github.sourceControlStorage.sandboxes.getById({ id: sandboxRow.id });
|
|
@@ -27739,6 +27849,7 @@ var PlatformGithubIntegration = class {
|
|
|
27739
27849
|
getRepositoryAccess: async ({ orgId, repositoryId }) => {
|
|
27740
27850
|
const repository = await this.storage.repositories.get({ orgId, id: repositoryId });
|
|
27741
27851
|
if (!repository) throw new Error("Version-control repository not found.");
|
|
27852
|
+
const cloneUrl = `https://github.com/${repository.slug}.git`;
|
|
27742
27853
|
const installation = await this.storage.installations.get({ orgId, id: repository.installationId });
|
|
27743
27854
|
if (!installation) throw new Error("Version-control installation not found.");
|
|
27744
27855
|
const installationId = parsePositiveInteger(installation.externalId);
|
|
@@ -27750,7 +27861,7 @@ var PlatformGithubIntegration = class {
|
|
|
27750
27861
|
{ repositories: [repositoryName], permissions: REPOSITORY_TOKEN_PERMISSIONS }
|
|
27751
27862
|
);
|
|
27752
27863
|
return {
|
|
27753
|
-
cloneUrl
|
|
27864
|
+
cloneUrl,
|
|
27754
27865
|
authorization: { scheme: "bearer", token: token.token }
|
|
27755
27866
|
};
|
|
27756
27867
|
},
|
|
@@ -30558,13 +30669,19 @@ var FactoryStartCoordinator = class {
|
|
|
30558
30669
|
if (!request.requestContext) {
|
|
30559
30670
|
requestContext.set("user", { workosId: request.userId, organizationId: request.orgId });
|
|
30560
30671
|
}
|
|
30672
|
+
const sessionState = {
|
|
30673
|
+
factoryProjectId: request.factoryProjectId,
|
|
30674
|
+
projectRepositoryId: sourceSession.projectRepositoryId
|
|
30675
|
+
};
|
|
30561
30676
|
const session = await this.#controller.createSession({
|
|
30562
30677
|
id: sourceSession.sessionId,
|
|
30563
30678
|
ownerId: request.userId,
|
|
30564
30679
|
resourceId: sourceSession.sessionId,
|
|
30565
30680
|
threadId: sourceSession.sessionId,
|
|
30566
|
-
requestContext
|
|
30681
|
+
requestContext,
|
|
30682
|
+
tags: sessionState
|
|
30567
30683
|
});
|
|
30684
|
+
await session.state.set(sessionState);
|
|
30568
30685
|
const threadId = await configureThread(session, request);
|
|
30569
30686
|
const kickoffMessage = await resolveKickoffMessage(session, request.invocation);
|
|
30570
30687
|
const prepared = await storage.prepareRunStart({
|
|
@@ -35306,9 +35423,9 @@ function trustedGithubActor(context) {
|
|
|
35306
35423
|
function invokeIssueInvestigation(context) {
|
|
35307
35424
|
return {
|
|
35308
35425
|
type: "invokeSkill",
|
|
35309
|
-
idempotencyKey: `${context.ingress.id}:
|
|
35426
|
+
idempotencyKey: `${context.ingress.id}:factory-triage`,
|
|
35310
35427
|
role: "triage",
|
|
35311
|
-
skillName: "
|
|
35428
|
+
skillName: "factory-triage",
|
|
35312
35429
|
arguments: context.item.url ? `GitHub issue (${context.item.url})` : context.item.title
|
|
35313
35430
|
};
|
|
35314
35431
|
}
|
|
@@ -35319,18 +35436,27 @@ function investigateTriagedLinearIssue(context) {
|
|
|
35319
35436
|
const identifier = context.item.sourceKey?.startsWith("linear:") ? context.item.sourceKey.slice("linear:".length) : context.item.title;
|
|
35320
35437
|
return {
|
|
35321
35438
|
type: "invokeSkill",
|
|
35322
|
-
idempotencyKey: `${context.ingress.id}:
|
|
35439
|
+
idempotencyKey: `${context.ingress.id}:factory-triage-linear`,
|
|
35323
35440
|
role: "triage",
|
|
35324
|
-
skillName: "
|
|
35441
|
+
skillName: "factory-triage",
|
|
35325
35442
|
arguments: `Linear issue ${identifier}${context.item.url ? ` (${context.item.url})` : ""}`
|
|
35326
35443
|
};
|
|
35327
35444
|
}
|
|
35445
|
+
function planWorkItem(context) {
|
|
35446
|
+
return {
|
|
35447
|
+
type: "invokeSkill",
|
|
35448
|
+
idempotencyKey: `${context.ingress.id}:factory-plan`,
|
|
35449
|
+
role: "plan",
|
|
35450
|
+
skillName: "factory-plan",
|
|
35451
|
+
arguments: context.item.url ? `Work item (${context.item.url})` : context.item.title
|
|
35452
|
+
};
|
|
35453
|
+
}
|
|
35328
35454
|
function reviewPullRequest(context) {
|
|
35329
35455
|
return {
|
|
35330
35456
|
type: "invokeSkill",
|
|
35331
|
-
idempotencyKey: `${context.ingress.id}:
|
|
35457
|
+
idempotencyKey: `${context.ingress.id}:factory-review`,
|
|
35332
35458
|
role: "review",
|
|
35333
|
-
skillName: "
|
|
35459
|
+
skillName: "factory-review",
|
|
35334
35460
|
arguments: context.item.url ? `GitHub pull request (${context.item.url})` : context.item.title
|
|
35335
35461
|
};
|
|
35336
35462
|
}
|
|
@@ -35428,6 +35554,11 @@ var BUILT_IN_DEFAULTS = {
|
|
|
35428
35554
|
triage: {
|
|
35429
35555
|
issue: { onEnter: investigateTriagedIssue },
|
|
35430
35556
|
linearIssue: { onEnter: investigateTriagedLinearIssue }
|
|
35557
|
+
},
|
|
35558
|
+
planning: {
|
|
35559
|
+
issue: { onEnter: planWorkItem },
|
|
35560
|
+
linearIssue: { onEnter: planWorkItem },
|
|
35561
|
+
manual: { onEnter: planWorkItem }
|
|
35431
35562
|
}
|
|
35432
35563
|
},
|
|
35433
35564
|
review: { review: { pullRequest: { onEnter: reviewPullRequest } } },
|
|
@@ -38345,7 +38476,7 @@ var FACTORY_SKILLS_SOURCE_PATH = [
|
|
|
38345
38476
|
join3(process.cwd(), "src", "mastra", "public", "factory-skills")
|
|
38346
38477
|
].find(existsSync2) ?? bundledFactorySkillsPath;
|
|
38347
38478
|
var FACTORY_SKILLS_MOUNT = path2.resolve(path2.parse(process.cwd()).root, "__mastracode_factory_skills__");
|
|
38348
|
-
var FACTORY_SKILL_NAMES = /* @__PURE__ */ new Set(["configure-factory-rules", "
|
|
38479
|
+
var FACTORY_SKILL_NAMES = /* @__PURE__ */ new Set(["configure-factory-rules", "factory-plan", "factory-review", "factory-triage"]);
|
|
38349
38480
|
var FactorySkillSource = class {
|
|
38350
38481
|
constructor(fallback, fallbackSkillRoots) {
|
|
38351
38482
|
this.fallback = fallback;
|
|
@@ -38391,7 +38522,7 @@ var factorySkillExtension = {
|
|
|
38391
38522
|
createSource: (fallback, fallbackSkillRoots) => new FactorySkillSource(fallback, fallbackSkillRoots)
|
|
38392
38523
|
};
|
|
38393
38524
|
function createWorkspaceFactory(options = {}) {
|
|
38394
|
-
const { sandbox: sandboxConfig, github, fleet } = options;
|
|
38525
|
+
const { sandbox: sandboxConfig, github, fleet, workItems } = options;
|
|
38395
38526
|
const isLocalSandbox = sandboxConfig?.machine instanceof LocalSandbox;
|
|
38396
38527
|
const githubTokenInjectors = /* @__PURE__ */ new Map();
|
|
38397
38528
|
return async ({ requestContext, mastra, skillExtension }) => {
|
|
@@ -38445,8 +38576,11 @@ function createWorkspaceFactory(options = {}) {
|
|
|
38445
38576
|
const existing = mastra?.getWorkspaceById(workspaceId);
|
|
38446
38577
|
if (existing) {
|
|
38447
38578
|
existing.setToolsConfig(MASTRACODE_WORKSPACE_TOOLS);
|
|
38448
|
-
const
|
|
38449
|
-
if (
|
|
38579
|
+
const registered = githubTokenInjectors.get(workspaceId);
|
|
38580
|
+
if (registered) {
|
|
38581
|
+
registerGithubTokenInjector(requestContext, registered.inject);
|
|
38582
|
+
registerGithubPatKind(requestContext, registered.patKind);
|
|
38583
|
+
}
|
|
38450
38584
|
return existing;
|
|
38451
38585
|
}
|
|
38452
38586
|
} catch {
|
|
@@ -38457,9 +38591,19 @@ function createWorkspaceFactory(options = {}) {
|
|
|
38457
38591
|
});
|
|
38458
38592
|
const token = access.authorization?.token;
|
|
38459
38593
|
if (!token) throw new Error("Repository access did not include a bearer token for the Factory session");
|
|
38594
|
+
let patKind = "default";
|
|
38595
|
+
if (workItems) {
|
|
38596
|
+
try {
|
|
38597
|
+
const address = getFactorySessionAddress(requestContext);
|
|
38598
|
+
const runBinding = address ? await workItems.findRunBindingBySession(address) : null;
|
|
38599
|
+
if (runBinding?.role === "review" && runBinding.orgId === session.orgId) patKind = "reviewer";
|
|
38600
|
+
} catch {
|
|
38601
|
+
}
|
|
38602
|
+
}
|
|
38603
|
+
const ghCliToken = await getGithubPat(() => github.integrationStorage, session.orgId, patKind) ?? token;
|
|
38460
38604
|
const sandbox = await fleet.ensureSandbox(
|
|
38461
38605
|
binding,
|
|
38462
|
-
{ GH_TOKEN:
|
|
38606
|
+
{ GH_TOKEN: ghCliToken },
|
|
38463
38607
|
void 0,
|
|
38464
38608
|
isLocalSandbox ? { workingDirectory: workdir } : {}
|
|
38465
38609
|
);
|
|
@@ -38483,8 +38627,9 @@ function createWorkspaceFactory(options = {}) {
|
|
|
38483
38627
|
}
|
|
38484
38628
|
sandbox.setEnvironmentVariable("GH_TOKEN", freshToken);
|
|
38485
38629
|
};
|
|
38486
|
-
githubTokenInjectors.set(workspaceId, injectGithubToken2);
|
|
38630
|
+
githubTokenInjectors.set(workspaceId, { inject: injectGithubToken2, patKind });
|
|
38487
38631
|
registerGithubTokenInjector(requestContext, injectGithubToken2);
|
|
38632
|
+
registerGithubPatKind(requestContext, patKind);
|
|
38488
38633
|
const filesystem = new SandboxFilesystem({ sandbox, workdir });
|
|
38489
38634
|
const projectSkillPaths = [path2.join(configDir, "skills"), ".claude/skills", ".agents/skills"];
|
|
38490
38635
|
const skillPaths = [...effectiveSkillExtension?.paths ?? [], ...projectSkillPaths];
|
|
@@ -38721,6 +38866,7 @@ var MastraFactory = class {
|
|
|
38721
38866
|
workspace: createWorkspaceFactory({
|
|
38722
38867
|
...this.#config.sandbox ? { sandbox: this.#config.sandbox } : {},
|
|
38723
38868
|
...githubIntegration ? { github: githubIntegration } : {},
|
|
38869
|
+
...workItemsStorage ? { workItems: workItemsStorage } : {},
|
|
38724
38870
|
fleet
|
|
38725
38871
|
}),
|
|
38726
38872
|
disableGithubSignals: true,
|