@mastra/platform-workspace 1.5.0-alpha.2 → 1.5.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/dist/index.cjs CHANGED
@@ -28,6 +28,7 @@ let _mastra_core_workspace = require("@mastra/core/workspace");
28
28
  let e2b = require("e2b");
29
29
  let child_process = require("child_process");
30
30
  let util = require("util");
31
+ let crypto = require("crypto");
31
32
  //#region src/client.ts
32
33
  const DEFAULT_PROXY_URL = "https://workspaces.mastra.ai";
33
34
  /**
@@ -1964,6 +1965,31 @@ var PlatformSandbox = class PlatformSandbox extends _mastra_core_workspace.Mastr
1964
1965
  }
1965
1966
  };
1966
1967
  //#endregion
1968
+ //#region ../../packages/_internals/workspace/dist/index.js
1969
+ /**
1970
+ * Setup completion marker shared by repo templates and their consumers.
1971
+ *
1972
+ * A repo template writes this file beside the checkout as its last build
1973
+ * step, so it exists only in images where every setup command succeeded. Its
1974
+ * content is a digest of the setup commands the image ran, letting a sandbox
1975
+ * booted from the image tell whether the setup it is about to run already
1976
+ * happened. Relative to the template's build cwd, which is also the runtime
1977
+ * working directory the repo was cloned into.
1978
+ */
1979
+ const SETUP_MARKER_PATH = ".mastra-sandbox/setup";
1980
+ /** Blank entries never become build steps, so they never count toward the digest either. */
1981
+ function normalizeSetupCommands(setupCommand) {
1982
+ return (setupCommand === void 0 ? [] : Array.isArray(setupCommand) ? setupCommand : [setupCommand]).filter((command) => command.trim() !== "");
1983
+ }
1984
+ /** The marker content for a setup command list: `sha256:<hex>` over the commands joined by newlines. */
1985
+ function setupMarkerContent(setupCommand) {
1986
+ return `sha256:${(0, crypto.createHash)("sha256").update(normalizeSetupCommands(setupCommand).join("\n")).digest("hex")}`;
1987
+ }
1988
+ /** Shell step that writes the marker relative to the cwd. `content` is a digest, so it is shell-safe. */
1989
+ function setupMarkerCommand(content) {
1990
+ return `mkdir -p "$(dirname "${SETUP_MARKER_PATH}")" && printf '%s' '${content}' > "${SETUP_MARKER_PATH}"`;
1991
+ }
1992
+ //#endregion
1967
1993
  //#region src/repo-template.ts
1968
1994
  const execFileAsync = (0, util.promisify)(child_process.execFile);
1969
1995
  const SHA_PATTERN = /^[0-9a-f]{7,40}$/i;
@@ -2046,6 +2072,7 @@ function createRepoTemplate(options) {
2046
2072
  if (workingDirectory) template = template.runCmd(`mkdir -p "${workingDirectory}"`).setWorkdir(workingDirectory);
2047
2073
  template = template.runCmd(`git ${auth}clone ${cloneUrl} "${repoDir}"`).runCmd(`git -C "${repoDir}" ${auth}fetch origin ${sha}`).runCmd(`git -C "${repoDir}" checkout ${sha}`);
2048
2074
  for (const command of setupCommands) template = template.runCmd(`cd "${repoDir}" && ${command}`);
2075
+ template = template.runCmd(setupMarkerCommand(setupMarkerContent(setupCommands)));
2049
2076
  return template.withFamily(family);
2050
2077
  };
2051
2078
  }
@@ -2103,7 +2130,50 @@ function redactSecrets(value) {
2103
2130
  function gitAuthFlag() {
2104
2131
  return `-c http.extraheader="AUTHORIZATION: basic $(printf 'x-access-token:%s' "$${BUILD_TOKEN_ENV}" | base64 -w0)"`;
2105
2132
  }
2106
- async function resolveDefaultBranchHead(cloneUrl, token, execute = execFileAsync) {
2133
+ /**
2134
+ * `owner/repo` for a github.com clone URL, else undefined. Only the public
2135
+ * host is API-resolvable: GitHub Enterprise and other forges keep the git
2136
+ * path below.
2137
+ */
2138
+ function parseGithubRepo(cloneUrl) {
2139
+ let url;
2140
+ try {
2141
+ url = new URL(cloneUrl);
2142
+ } catch {
2143
+ return;
2144
+ }
2145
+ if (url.hostname.toLowerCase() !== "github.com") return void 0;
2146
+ const [owner, repo, ...rest] = url.pathname.split("/").filter(Boolean);
2147
+ if (!owner || !repo || rest.length > 0) return void 0;
2148
+ return {
2149
+ owner,
2150
+ repo: repo.replace(/\.git$/i, "")
2151
+ };
2152
+ }
2153
+ /**
2154
+ * Resolve the default-branch head. github.com repositories go through the
2155
+ * REST API so resolution works wherever the host runs, including deployed
2156
+ * images without a git binary; other hosts shell out to `git ls-remote`.
2157
+ * Throws with a redaction-safe message when the head cannot be resolved.
2158
+ */
2159
+ async function resolveDefaultBranchHead(cloneUrl, token, execute = execFileAsync, fetchImpl = fetch) {
2160
+ const github = parseGithubRepo(cloneUrl);
2161
+ if (github) {
2162
+ const response = await fetchImpl(`https://api.github.com/repos/${github.owner}/${github.repo}/commits/HEAD`, {
2163
+ headers: {
2164
+ Accept: "application/vnd.github.sha",
2165
+ "X-GitHub-Api-Version": "2022-11-28",
2166
+ "User-Agent": "mastra-platform-workspace",
2167
+ ...token ? { Authorization: `Bearer ${token}` } : {}
2168
+ },
2169
+ signal: AbortSignal.timeout(1e4)
2170
+ }).catch((error) => {
2171
+ throw new Error(`GitHub head lookup failed: ${error instanceof Error ? error.message : String(error)}`);
2172
+ });
2173
+ if (!response.ok) throw new Error(`GitHub head lookup failed: ${response.status} ${response.statusText}`.trim());
2174
+ const sha = (await response.text()).trim();
2175
+ return SHA_PATTERN.test(sha) ? sha : void 0;
2176
+ }
2107
2177
  try {
2108
2178
  const env = {
2109
2179
  ...process.env,