@mastra/factory 0.2.2-alpha.0 → 0.2.2-alpha.1
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 +26 -0
- package/dist/auth.d.ts +2 -2
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +22 -2
- package/dist/auth.js.map +1 -1
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +411 -244
- package/dist/factory.js.map +1 -1
- package/dist/index.js +411 -244
- package/dist/index.js.map +1 -1
- package/dist/integrations/github/integration.js +85 -37
- package/dist/integrations/github/integration.js.map +1 -1
- package/dist/integrations/github/routes.d.ts.map +1 -1
- package/dist/integrations/github/routes.js +85 -37
- package/dist/integrations/github/routes.js.map +1 -1
- package/dist/integrations/github/sandbox.d.ts +2 -0
- package/dist/integrations/github/sandbox.d.ts.map +1 -1
- package/dist/integrations/github/sandbox.js +28 -8
- package/dist/integrations/github/sandbox.js.map +1 -1
- package/dist/integrations/platform/github/integration.d.ts.map +1 -1
- package/dist/integrations/platform/github/integration.js +119 -39
- package/dist/integrations/platform/github/integration.js.map +1 -1
- package/dist/routes/config.d.ts.map +1 -1
- package/dist/routes/config.js +1 -4
- package/dist/routes/config.js.map +1 -1
- package/dist/routes/surface.js +1 -4
- package/dist/routes/surface.js.map +1 -1
- package/dist/routes/work-items.js.map +1 -1
- package/dist/rules/binding-context.js.map +1 -1
- package/dist/rules/dispatcher.d.ts.map +1 -1
- package/dist/rules/dispatcher.js +7 -1
- package/dist/rules/dispatcher.js.map +1 -1
- package/dist/rules/processor.js.map +1 -1
- package/dist/rules/tools.js.map +1 -1
- package/dist/spa-static.d.ts.map +1 -1
- package/dist/spa-static.js +1 -0
- package/dist/spa-static.js.map +1 -1
- package/dist/storage/domains/source-control/base.d.ts +9 -0
- package/dist/storage/domains/source-control/base.d.ts.map +1 -1
- package/dist/storage/domains/source-control/base.js +4 -0
- package/dist/storage/domains/source-control/base.js.map +1 -1
- package/dist/storage/domains/source-control/inmemory.d.ts +4 -0
- package/dist/storage/domains/source-control/inmemory.d.ts.map +1 -1
- package/dist/storage/domains/source-control/inmemory.js +4 -0
- package/dist/storage/domains/source-control/inmemory.js.map +1 -1
- package/dist/storage/domains/work-items/base.d.ts.map +1 -1
- package/dist/storage/domains/work-items/base.js +20 -4
- package/dist/storage/domains/work-items/base.js.map +1 -1
- package/dist/storage/domains/work-items/metrics.js.map +1 -1
- package/dist/timing.d.ts +15 -0
- package/dist/timing.d.ts.map +1 -0
- package/dist/timing.js +27 -0
- package/dist/timing.js.map +1 -0
- package/dist/workspace.d.ts +2 -3
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js +104 -65
- package/dist/workspace.js.map +1 -1
- package/factory-skills/factory-review/SKILL.md +9 -2
- package/package.json +8 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../src/integrations/github/routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAEvD,OAAO,KAAK,EAAuD,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAChH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AASrF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAwC1D,OAAO,KAAK,EAAE,yBAAyB,EAAE,0BAA0B,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAgB/G,MAAM,WAAW,wBAAwB;IACvC,4EAA4E;IAC5E,IAAI,EAAE,SAAS,CAAC;IAChB;;;;OAIG;IACH,KAAK,EAAE,YAAY,CAAC;IACpB,yEAAyE;IACzE,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB;;;;OAIG;IACH,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B;;;;OAIG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4FAA4F;IAC5F,UAAU,CAAC,EAAE,iBAAiB,CAAC,YAAY,CAAC,CAAC;IAC7C,iEAAiE;IACjE,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,yBAAyB,KAAK,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAC3F,6EAA6E;IAC7E,SAAS,CAAC,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;IACjC,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,sBAAsB,CAAC;IAClC,+FAA+F;IAC/F,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACvE;AAuPD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../src/integrations/github/routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAEvD,OAAO,KAAK,EAAuD,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAChH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AASrF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAwC1D,OAAO,KAAK,EAAE,yBAAyB,EAAE,0BAA0B,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAgB/G,MAAM,WAAW,wBAAwB;IACvC,4EAA4E;IAC5E,IAAI,EAAE,SAAS,CAAC;IAChB;;;;OAIG;IACH,KAAK,EAAE,YAAY,CAAC;IACpB,yEAAyE;IACzE,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB;;;;OAIG;IACH,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B;;;;OAIG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4FAA4F;IAC5F,UAAU,CAAC,EAAE,iBAAiB,CAAC,YAAY,CAAC,CAAC;IAC7C,iEAAiE;IACjE,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,yBAAyB,KAAK,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAC3F,6EAA6E;IAC7E,SAAS,CAAC,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;IACjC,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,sBAAsB,CAAC;IAClC,+FAA+F;IAC/F,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACvE;AAuPD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,QAAQ,EAAE,CAkqB/E"}
|
|
@@ -110,8 +110,23 @@ async function teardownProjectSandbox(options) {
|
|
|
110
110
|
function shellQuote(value) {
|
|
111
111
|
return `'` + value.split(`'`).join(`'\\''`) + `'`;
|
|
112
112
|
}
|
|
113
|
-
|
|
114
|
-
|
|
113
|
+
var DEFAULT_COMMAND_TIMEOUT_MS = 15 * 6e4;
|
|
114
|
+
var CHECKOUT_COMMAND_TIMEOUT_MS = 5 * 6e4;
|
|
115
|
+
async function sh(sandbox, script, options = {}) {
|
|
116
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;
|
|
117
|
+
let timer;
|
|
118
|
+
const hangGuard = new Promise((_, reject) => {
|
|
119
|
+
timer = setTimeout(() => {
|
|
120
|
+
const phase = options.phase ? ` during ${options.phase}` : "";
|
|
121
|
+
reject(new Error(`Sandbox command timed out after ${Math.round(timeoutMs / 1e3)}s${phase}.`));
|
|
122
|
+
}, timeoutMs);
|
|
123
|
+
timer.unref?.();
|
|
124
|
+
});
|
|
125
|
+
try {
|
|
126
|
+
return await Promise.race([sandbox.executeCommand("sh", ["-c", script], { timeout: timeoutMs }), hangGuard]);
|
|
127
|
+
} finally {
|
|
128
|
+
clearTimeout(timer);
|
|
129
|
+
}
|
|
115
130
|
}
|
|
116
131
|
var MaterializeError = class extends Error {
|
|
117
132
|
constructor(message, code) {
|
|
@@ -148,7 +163,8 @@ async function materializeRepo(options) {
|
|
|
148
163
|
);
|
|
149
164
|
}
|
|
150
165
|
const authUrl = tokenUrl(repo, token);
|
|
151
|
-
const alreadyMaterialized =
|
|
166
|
+
const alreadyMaterialized = await hasExistingCheckout(sandbox, workdir, repo);
|
|
167
|
+
let succeeded = false;
|
|
152
168
|
try {
|
|
153
169
|
if (!alreadyMaterialized) {
|
|
154
170
|
reportProgress(onProgress, {
|
|
@@ -157,7 +173,8 @@ async function materializeRepo(options) {
|
|
|
157
173
|
});
|
|
158
174
|
const clone = await sh(
|
|
159
175
|
sandbox,
|
|
160
|
-
`git clone --depth=1 --single-branch --branch ${shellQuote(repoInfo.defaultBranch)} ${shellQuote(authUrl)} ${shellQuote(workdir)}
|
|
176
|
+
`git clone --depth=1 --single-branch --branch ${shellQuote(repoInfo.defaultBranch)} ${shellQuote(authUrl)} ${shellQuote(workdir)}`,
|
|
177
|
+
{ phase: "repository clone" }
|
|
161
178
|
);
|
|
162
179
|
if (clone.exitCode !== 0) {
|
|
163
180
|
throw classifyGitFailure(clone, "clone-failed");
|
|
@@ -168,13 +185,14 @@ async function materializeRepo(options) {
|
|
|
168
185
|
if (setUrl.exitCode !== 0) {
|
|
169
186
|
throw new MaterializeError(`Failed to set git remote: ${setUrl.stderr}`, "pull-failed");
|
|
170
187
|
}
|
|
171
|
-
const pull = await sh(sandbox, `git -C ${shellQuote(workdir)} pull --ff-only
|
|
188
|
+
const pull = await sh(sandbox, `git -C ${shellQuote(workdir)} pull --ff-only`, { phase: "repository pull" });
|
|
172
189
|
if (pull.exitCode !== 0) {
|
|
173
190
|
throw classifyGitFailure(pull, "pull-failed");
|
|
174
191
|
}
|
|
175
192
|
}
|
|
193
|
+
succeeded = true;
|
|
176
194
|
} finally {
|
|
177
|
-
await scrubRemote(sandbox, workdir, repo,
|
|
195
|
+
await scrubRemote(sandbox, workdir, repo, succeeded);
|
|
178
196
|
}
|
|
179
197
|
reportProgress(onProgress, { phase: "finalizing", message: "Finalizing workspace\u2026" });
|
|
180
198
|
await storage.markMaterialized({ id: sandboxRow.id });
|
|
@@ -1069,43 +1087,56 @@ function buildGithubRoutes(options) {
|
|
|
1069
1087
|
handler: async (c) => {
|
|
1070
1088
|
const resolved = await resolveOrgTenant(loose(c), auth);
|
|
1071
1089
|
if ("response" in resolved) return resolved.response;
|
|
1072
|
-
const
|
|
1090
|
+
const orgId = resolved.tenant.orgId;
|
|
1091
|
+
const installs = await github.sourceControlStorage.installations.list({ orgId });
|
|
1073
1092
|
const query = (c.req.query("q") ?? "").toLowerCase();
|
|
1074
|
-
const
|
|
1093
|
+
const listed = await Promise.all(
|
|
1094
|
+
installs.map(async (inst) => {
|
|
1095
|
+
try {
|
|
1096
|
+
return { inst, list: await github.listInstallationRepos(Number(inst.externalId)) };
|
|
1097
|
+
} catch (err) {
|
|
1098
|
+
if (err.status !== 404) throw err;
|
|
1099
|
+
console.error(`[Mastra Factory] pruning stale GitHub installation ${inst.externalId} (404 from GitHub)`);
|
|
1100
|
+
await github.sourceControlStorage.installations.delete({ orgId, id: inst.id });
|
|
1101
|
+
return { inst, list: [] };
|
|
1102
|
+
}
|
|
1103
|
+
})
|
|
1104
|
+
);
|
|
1105
|
+
const matches = [];
|
|
1075
1106
|
const seenRepositoryIds = /* @__PURE__ */ new Set();
|
|
1076
|
-
for (const inst of
|
|
1077
|
-
let list;
|
|
1078
|
-
try {
|
|
1079
|
-
list = await github.listInstallationRepos(Number(inst.externalId));
|
|
1080
|
-
} catch (err) {
|
|
1081
|
-
if (err.status !== 404) throw err;
|
|
1082
|
-
console.error(`[Mastra Factory] pruning stale GitHub installation ${inst.externalId} (404 from GitHub)`);
|
|
1083
|
-
await github.sourceControlStorage.installations.delete({ orgId: resolved.tenant.orgId, id: inst.id });
|
|
1084
|
-
continue;
|
|
1085
|
-
}
|
|
1107
|
+
for (const { inst, list } of listed) {
|
|
1086
1108
|
for (const repo of list) {
|
|
1087
1109
|
if (query && !repo.fullName.toLowerCase().includes(query)) continue;
|
|
1088
1110
|
if (seenRepositoryIds.has(repo.id)) continue;
|
|
1089
1111
|
seenRepositoryIds.add(repo.id);
|
|
1090
|
-
|
|
1091
|
-
orgId: resolved.tenant.orgId,
|
|
1092
|
-
input: {
|
|
1093
|
-
installationId: inst.id,
|
|
1094
|
-
externalId: repo.id.toString(),
|
|
1095
|
-
slug: repo.fullName,
|
|
1096
|
-
defaultBranch: isValidGitRef2(repo.defaultBranch) ? repo.defaultBranch : "main",
|
|
1097
|
-
providerMetadata: { private: repo.private, owner: repo.owner }
|
|
1098
|
-
}
|
|
1099
|
-
});
|
|
1100
|
-
repos.push({
|
|
1101
|
-
...repo,
|
|
1102
|
-
installationStorageId: inst.id,
|
|
1103
|
-
repositoryStorageId: repository.id,
|
|
1104
|
-
sandboxProvider: fleet.provider,
|
|
1105
|
-
sandboxWorkdir: fleet.computeWorkdir(repo.fullName)
|
|
1106
|
-
});
|
|
1112
|
+
matches.push({ inst, repo });
|
|
1107
1113
|
}
|
|
1108
1114
|
}
|
|
1115
|
+
const repos = new Array(matches.length);
|
|
1116
|
+
const upsertConcurrency = 10;
|
|
1117
|
+
for (let start = 0; start < matches.length; start += upsertConcurrency) {
|
|
1118
|
+
await Promise.all(
|
|
1119
|
+
matches.slice(start, start + upsertConcurrency).map(async ({ inst, repo }, offset) => {
|
|
1120
|
+
const repository = await github.sourceControlStorage.repositories.upsert({
|
|
1121
|
+
orgId,
|
|
1122
|
+
input: {
|
|
1123
|
+
installationId: inst.id,
|
|
1124
|
+
externalId: repo.id.toString(),
|
|
1125
|
+
slug: repo.fullName,
|
|
1126
|
+
defaultBranch: isValidGitRef2(repo.defaultBranch) ? repo.defaultBranch : "main",
|
|
1127
|
+
providerMetadata: { private: repo.private, owner: repo.owner }
|
|
1128
|
+
}
|
|
1129
|
+
});
|
|
1130
|
+
repos[start + offset] = {
|
|
1131
|
+
...repo,
|
|
1132
|
+
installationStorageId: inst.id,
|
|
1133
|
+
repositoryStorageId: repository.id,
|
|
1134
|
+
sandboxProvider: fleet.provider,
|
|
1135
|
+
sandboxWorkdir: fleet.computeWorkdir(repo.fullName)
|
|
1136
|
+
};
|
|
1137
|
+
})
|
|
1138
|
+
);
|
|
1139
|
+
}
|
|
1109
1140
|
return c.json({ repos });
|
|
1110
1141
|
}
|
|
1111
1142
|
})
|
|
@@ -1436,8 +1467,25 @@ async function loadOrCreateSandboxRow(github, project, userId) {
|
|
|
1436
1467
|
return github.sourceControlStorage.sandboxes.getOrCreate({ projectRepository: project, userId });
|
|
1437
1468
|
}
|
|
1438
1469
|
async function prepareProject(options) {
|
|
1439
|
-
const { github, fleet,
|
|
1440
|
-
|
|
1470
|
+
const { github, fleet, userId, onProgress } = options;
|
|
1471
|
+
let project = options.project;
|
|
1472
|
+
if (project.sandboxProvider !== fleet.provider) {
|
|
1473
|
+
const sandboxWorkdir = fleet.computeWorkdir(project.repository.slug);
|
|
1474
|
+
await github.sourceControlStorage.projectRepositories.update({
|
|
1475
|
+
orgId: project.installation.orgId,
|
|
1476
|
+
id: project.id,
|
|
1477
|
+
input: { sandboxProvider: fleet.provider, sandboxWorkdir }
|
|
1478
|
+
});
|
|
1479
|
+
project = { ...project, sandboxProvider: fleet.provider, sandboxWorkdir };
|
|
1480
|
+
}
|
|
1481
|
+
let sandboxRow = await loadOrCreateSandboxRow(github, project, userId);
|
|
1482
|
+
if (sandboxRow.sandboxWorkdir !== project.sandboxWorkdir) {
|
|
1483
|
+
await github.sourceControlStorage.sandboxes.setWorkdir({
|
|
1484
|
+
id: sandboxRow.id,
|
|
1485
|
+
sandboxWorkdir: project.sandboxWorkdir
|
|
1486
|
+
});
|
|
1487
|
+
sandboxRow = { ...sandboxRow, sandboxWorkdir: project.sandboxWorkdir, materializedAt: null };
|
|
1488
|
+
}
|
|
1441
1489
|
const access = await github.versionControl.getRepositoryAccess({
|
|
1442
1490
|
orgId: project.installation.orgId,
|
|
1443
1491
|
repositoryId: project.repository.id
|