Skip to content

Commit af67578

Browse files
betegonclaude
andcommitted
fix(init): restore production API URL and validate-all-then-execute for patchsets
Restore MASTRA_API_URL to production Cloudflare Worker with env var override (was hardcoded to localhost:8787). Add upfront safePath() validation in applyPatchset() so no files are written if any patch targets an unsafe path. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 914995f commit af67578

File tree

4 files changed

+32
-2
lines changed

4 files changed

+32
-2
lines changed

src/lib/init/constants.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
export const MASTRA_API_URL = "http://localhost:8787";
1+
export const MASTRA_API_URL =
2+
process.env.MASTRA_API_URL ??
3+
"https://sentry-init-agent.getsentry.workers.dev";
24

35
export const WORKFLOW_ID = "sentry-wizard";
46

src/lib/init/local-ops.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,13 @@ function applyPatchset(
488488
}
489489

490490
const { cwd, params } = payload;
491+
492+
// Phase 1: Validate all paths before writing anything
493+
for (const patch of params.patches) {
494+
safePath(cwd, patch.path);
495+
}
496+
497+
// Phase 2: Apply patches
491498
const applied: Array<{ path: string; action: string }> = [];
492499

493500
for (const patch of params.patches) {

test/init-eval/helpers/run-wizard.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export async function runWizard(
6969
env: {
7070
...process.env,
7171
// Override the hardcoded Mastra URL to point at local/test server
72-
SENTRY_WIZARD_API_URL: mastraUrl,
72+
MASTRA_API_URL: mastraUrl,
7373
// Disable telemetry
7474
SENTRY_CLI_NO_TELEMETRY: "1",
7575
},

test/lib/init/local-ops.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -857,6 +857,27 @@ describe("handleLocalOp", () => {
857857
expect(fs.existsSync(join(testDir, "phantom.txt"))).toBe(false);
858858
});
859859

860+
test("rejects entire patchset if any path is unsafe (no partial writes)", async () => {
861+
const payload: ApplyPatchsetPayload = {
862+
type: "local-op",
863+
operation: "apply-patchset",
864+
cwd: testDir,
865+
params: {
866+
patches: [
867+
{ path: "safe.txt", action: "create", patch: "good content" },
868+
{ path: "../../evil.txt", action: "create", patch: "bad" },
869+
],
870+
},
871+
};
872+
873+
const result = await handleLocalOp(payload, options);
874+
expect(result.ok).toBe(false);
875+
expect(result.error).toContain("outside project directory");
876+
877+
// First patch must NOT have been written
878+
expect(fs.existsSync(join(testDir, "safe.txt"))).toBe(false);
879+
});
880+
860881
test("dry-run still validates path safety", async () => {
861882
const payload: ApplyPatchsetPayload = {
862883
type: "local-op",

0 commit comments

Comments
 (0)