@agentsean/adapter-git 1.0.0

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.
@@ -0,0 +1,200 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { detectFramework, resolvePageFile } from "./resolve.js";
4
+ import { rewriteBody, rewriteTitle, titleInSource } from "./rewrite.js";
5
+ import { checkout, commitAll, createBranch, currentRemote, defaultGitRun, gitBranch, parseGithubRemote, readFile, revertCommit, unifiedDiff, writeFile, } from "./git.js";
6
+ import { openGithubPr } from "./github.js";
7
+ export function createGitAdapter(opts) {
8
+ const run = opts.gitRun ?? defaultGitRun;
9
+ const repo = path.resolve(opts.repoPath);
10
+ function fileFor(target) {
11
+ const file = resolvePageFile(repo, target.url);
12
+ if (!file) {
13
+ throw new Error(`no source file for ${target.url} in ${repo} (${detectFramework(repo)})`);
14
+ }
15
+ return file;
16
+ }
17
+ function newPageFile(pagePath) {
18
+ const rel = pagePath.replace(/^\//, "").replace(/\/$/, "") || "index";
19
+ return path.join(repo, "content", `${rel}.md`);
20
+ }
21
+ function plan(action) {
22
+ if (action.kind === "create_page" && "path" in action.payload) {
23
+ const file = newPageFile(action.payload.path);
24
+ const before = fs.existsSync(file) ? readFile(file) : "";
25
+ const after = `# ${action.payload.title}\n\n${action.payload.body}\n`;
26
+ return { file, before, after, summary: `create ${path.relative(repo, file)}` };
27
+ }
28
+ const file = fileFor(action.target);
29
+ const before = readFile(file);
30
+ if ("title" in action.payload &&
31
+ (action.kind === "rewrite_title" || action.kind === "fix_title_length")) {
32
+ const rewritten = rewriteTitle(before, action.payload.title);
33
+ if (!rewritten.ok)
34
+ throw new Error(rewritten.error);
35
+ return {
36
+ file,
37
+ before,
38
+ after: rewritten.after,
39
+ summary: `rewrite title on ${path.relative(repo, file)}`,
40
+ };
41
+ }
42
+ if ("body" in action.payload && action.kind === "refresh_content") {
43
+ const rewritten = rewriteBody(before, action.payload.body);
44
+ if (!rewritten.ok)
45
+ throw new Error(rewritten.error);
46
+ return {
47
+ file,
48
+ before,
49
+ after: rewritten.after,
50
+ summary: `refresh content on ${path.relative(repo, file)}`,
51
+ };
52
+ }
53
+ throw new Error(`git adapter does not apply ${action.kind}`);
54
+ }
55
+ const adapter = {
56
+ kind: "git",
57
+ capabilities() {
58
+ return {
59
+ kind: "git",
60
+ reads: true,
61
+ writes: true,
62
+ pullRequests: true,
63
+ rollback: true,
64
+ };
65
+ },
66
+ async read(target) {
67
+ const file = fileFor(target);
68
+ return {
69
+ targetRef: path.relative(repo, file),
70
+ body: readFile(file),
71
+ contentType: "text/plain",
72
+ };
73
+ },
74
+ async dryRun(action) {
75
+ const planned = plan(action);
76
+ return {
77
+ targetRef: path.relative(repo, planned.file).replaceAll("\\", "/"),
78
+ before: planned.before,
79
+ after: planned.after,
80
+ summary: planned.summary,
81
+ };
82
+ },
83
+ async apply(action) {
84
+ const planned = plan(action);
85
+ const file = planned.file;
86
+ const rel = path.relative(repo, file).replaceAll("\\", "/");
87
+ const base = opts.defaultBranch ?? gitBranch(run, repo);
88
+ const branch = action.kind === "rewrite_title" || action.kind === "fix_title_length"
89
+ ? `sean/title-${action.id.slice(0, 8)}`
90
+ : `sean/${action.kind}-${action.id.slice(0, 8)}`;
91
+ try {
92
+ createBranch(run, repo, branch);
93
+ }
94
+ catch {
95
+ checkout(run, repo, branch);
96
+ }
97
+ fs.mkdirSync(path.dirname(file), { recursive: true });
98
+ writeFile(file, planned.after);
99
+ const sha = commitAll(run, repo, `seo: ${planned.summary}\n\nAction ${action.id}`);
100
+ const diff = unifiedDiff(planned.before, planned.after, rel);
101
+ let prUrl;
102
+ const remote = currentRemote(run, repo);
103
+ const parsed = remote ? parseGithubRemote(remote) : null;
104
+ if (opts.token && parsed) {
105
+ if (!opts.skipPush) {
106
+ try {
107
+ run(["push", "-u", "origin", branch], repo);
108
+ }
109
+ catch {
110
+ /* local-only is still a valid apply */
111
+ }
112
+ }
113
+ try {
114
+ prUrl = await openGithubPr({
115
+ owner: parsed.owner,
116
+ repo: parsed.repo,
117
+ title: `seo: ${planned.summary}`,
118
+ body: action.rationale.join("\n"),
119
+ head: branch,
120
+ base,
121
+ token: opts.token,
122
+ ...(opts.fetch ? { fetch: opts.fetch } : {}),
123
+ ...(opts.apiBase ? { apiBase: opts.apiBase } : {}),
124
+ });
125
+ }
126
+ catch {
127
+ prUrl = undefined;
128
+ }
129
+ }
130
+ const result = {
131
+ targetRef: rel,
132
+ before: planned.before,
133
+ after: planned.after,
134
+ summary: prUrl
135
+ ? `Opened PR ${prUrl} (branch ${branch}, ${sha.slice(0, 7)})`
136
+ : `Committed ${sha.slice(0, 7)} on ${branch}`,
137
+ branch,
138
+ commitSha: sha,
139
+ diff,
140
+ };
141
+ if (prUrl)
142
+ result.prUrl = prUrl;
143
+ return result;
144
+ },
145
+ async verify(change) {
146
+ const file = path.join(repo, change.targetRef);
147
+ let live;
148
+ try {
149
+ live = readFile(file);
150
+ }
151
+ catch (e) {
152
+ return { ok: false, detail: e instanceof Error ? e.message : String(e) };
153
+ }
154
+ if (live === change.after)
155
+ return { ok: true, detail: "file matches after snapshot" };
156
+ const expected = titleInSource(change.after);
157
+ const got = titleInSource(live);
158
+ if (expected && got === expected) {
159
+ return { ok: true, detail: "title landed in source" };
160
+ }
161
+ return {
162
+ ok: false,
163
+ detail: `live file does not match after snapshot (expected title ${expected ?? "?"}, got ${got ?? "?"})`,
164
+ };
165
+ },
166
+ async rollback(change) {
167
+ const file = path.join(repo, change.targetRef);
168
+ const liveBefore = readFile(file);
169
+ if (change.commitSha) {
170
+ try {
171
+ const sha = revertCommit(run, repo, change.commitSha);
172
+ const after = readFile(file);
173
+ return {
174
+ targetRef: change.targetRef,
175
+ before: liveBefore,
176
+ after,
177
+ summary: `git revert ${change.commitSha.slice(0, 7)} → ${sha.slice(0, 7)}`,
178
+ commitSha: sha,
179
+ branch: change.branch,
180
+ };
181
+ }
182
+ catch {
183
+ /* fall through to snapshot restore */
184
+ }
185
+ }
186
+ writeFile(file, change.before);
187
+ const sha = commitAll(run, repo, `seo: revert ${change.targetRef}\n\nChange ${change.id}`);
188
+ return {
189
+ targetRef: change.targetRef,
190
+ before: liveBefore,
191
+ after: change.before,
192
+ summary: `Restored shadow-ledger snapshot (${sha.slice(0, 7)})`,
193
+ commitSha: sha,
194
+ branch: change.branch,
195
+ };
196
+ },
197
+ };
198
+ return adapter;
199
+ }
200
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /** Highest-ROI migration feature: catch preview hosts that index. */
2
+ export declare const VERCEL_BYPASS_HEADER = "x-vercel-protection-bypass";
3
+ export declare const CF_ACCESS_CLIENT_ID = "CF-Access-Client-Id";
4
+ export declare const CF_ACCESS_CLIENT_SECRET = "CF-Access-Client-Secret";
5
+ export type PreviewIndexationInput = {
6
+ host: string;
7
+ productionHost?: string | undefined;
8
+ isProduction?: boolean | undefined;
9
+ headers: Record<string, string>;
10
+ html?: string | undefined;
11
+ };
12
+ export type PreviewIndexationResult = {
13
+ ok: boolean;
14
+ leaks: string[];
15
+ note: string;
16
+ };
17
+ /**
18
+ * Vercel silently omits X-Robots-Tag: noindex when a custom domain is assigned
19
+ * to a non-production branch. Nobody else checks for this.
20
+ */
21
+ export declare function assertPreviewNotIndexed(input: PreviewIndexationInput): PreviewIndexationResult;
22
+ export declare const CRAWLER_BYPASS: {
23
+ readonly vercel: "x-vercel-protection-bypass";
24
+ readonly cloudflareAccessId: "CF-Access-Client-Id";
25
+ readonly cloudflareAccessSecret: "CF-Access-Client-Secret";
26
+ };
27
+ //# sourceMappingURL=ci-gate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ci-gate.d.ts","sourceRoot":"","sources":["../src/ci-gate.ts"],"names":[],"mappings":"AAAA,qEAAqE;AAErE,eAAO,MAAM,oBAAoB,+BAA+B,CAAC;AACjE,eAAO,MAAM,mBAAmB,wBAAwB,CAAC;AACzD,eAAO,MAAM,uBAAuB,4BAA4B,CAAC;AAEjE,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,YAAY,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACnC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAUF;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,sBAAsB,GAC5B,uBAAuB,CA4BzB;AAED,eAAO,MAAM,cAAc;;;;CAIjB,CAAC"}
@@ -0,0 +1,48 @@
1
+ /** Highest-ROI migration feature: catch preview hosts that index. */
2
+ export const VERCEL_BYPASS_HEADER = "x-vercel-protection-bypass";
3
+ export const CF_ACCESS_CLIENT_ID = "CF-Access-Client-Id";
4
+ export const CF_ACCESS_CLIENT_SECRET = "CF-Access-Client-Secret";
5
+ function header(headers, name) {
6
+ const want = name.toLowerCase();
7
+ for (const [k, v] of Object.entries(headers)) {
8
+ if (k.toLowerCase() === want)
9
+ return v;
10
+ }
11
+ return undefined;
12
+ }
13
+ /**
14
+ * Vercel silently omits X-Robots-Tag: noindex when a custom domain is assigned
15
+ * to a non-production branch. Nobody else checks for this.
16
+ */
17
+ export function assertPreviewNotIndexed(input) {
18
+ const leaks = [];
19
+ const production = input.isProduction ??
20
+ (input.productionHost ? input.host === input.productionHost : false);
21
+ if (production) {
22
+ return {
23
+ ok: true,
24
+ leaks,
25
+ note: "Production host — indexation expected.",
26
+ };
27
+ }
28
+ const xrobots = header(input.headers, "x-robots-tag") ?? "";
29
+ const meta = input.html
30
+ ? (/<meta\s+name=["']robots["'][^>]*content=["']([^"']+)/i.exec(input.html)?.[1] ??
31
+ "")
32
+ : "";
33
+ const noindex = /noindex/i.test(xrobots) || /noindex/i.test(meta);
34
+ if (!noindex) {
35
+ leaks.push(`${input.host} is a non-production host without X-Robots-Tag: noindex (Vercel drops this header when a custom domain is assigned to a preview branch).`);
36
+ }
37
+ return {
38
+ ok: leaks.length === 0,
39
+ leaks,
40
+ note: leaks.length ? leaks[0] : "Preview is noindexed.",
41
+ };
42
+ }
43
+ export const CRAWLER_BYPASS = {
44
+ vercel: VERCEL_BYPASS_HEADER,
45
+ cloudflareAccessId: CF_ACCESS_CLIENT_ID,
46
+ cloudflareAccessSecret: CF_ACCESS_CLIENT_SECRET,
47
+ };
48
+ //# sourceMappingURL=ci-gate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ci-gate.js","sourceRoot":"","sources":["../src/ci-gate.ts"],"names":[],"mappings":"AAAA,qEAAqE;AAErE,MAAM,CAAC,MAAM,oBAAoB,GAAG,4BAA4B,CAAC;AACjE,MAAM,CAAC,MAAM,mBAAmB,GAAG,qBAAqB,CAAC;AACzD,MAAM,CAAC,MAAM,uBAAuB,GAAG,yBAAyB,CAAC;AAgBjE,SAAS,MAAM,CAAC,OAA+B,EAAE,IAAY;IAC3D,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAChC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7C,IAAI,CAAC,CAAC,WAAW,EAAE,KAAK,IAAI;YAAE,OAAO,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CACrC,KAA6B;IAE7B,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,UAAU,GACd,KAAK,CAAC,YAAY;QAClB,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACvE,IAAI,UAAU,EAAE,CAAC;QACf,OAAO;YACL,EAAE,EAAE,IAAI;YACR,KAAK;YACL,IAAI,EAAE,wCAAwC;SAC/C,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,cAAc,CAAC,IAAI,EAAE,CAAC;IAC5D,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI;QACrB,CAAC,CAAC,CAAC,uDAAuD,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YAC9E,EAAE,CAAC;QACL,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,KAAK,CAAC,IAAI,CACR,GAAG,KAAK,CAAC,IAAI,0IAA0I,CACxJ,CAAC;IACJ,CAAC;IACD,OAAO;QACL,EAAE,EAAE,KAAK,CAAC,MAAM,KAAK,CAAC;QACtB,KAAK;QACL,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,uBAAuB;KACzD,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,MAAM,EAAE,oBAAoB;IAC5B,kBAAkB,EAAE,mBAAmB;IACvC,sBAAsB,EAAE,uBAAuB;CACvC,CAAC"}
package/dist/git.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ export type GitRun = (args: string[], cwd: string) => string;
2
+ export declare function defaultGitRun(args: string[], cwd: string): string;
3
+ export declare function ensureGitIdentity(run: GitRun, cwd: string): void;
4
+ export declare function gitHead(run: GitRun, cwd: string): string;
5
+ export declare function gitBranch(run: GitRun, cwd: string): string;
6
+ export declare function createBranch(run: GitRun, cwd: string, name: string): void;
7
+ export declare function checkout(run: GitRun, cwd: string, name: string): void;
8
+ export declare function commitAll(run: GitRun, cwd: string, message: string): string;
9
+ export declare function revertCommit(run: GitRun, cwd: string, sha: string): string;
10
+ export declare function writeFile(filePath: string, body: string): void;
11
+ export declare function readFile(filePath: string): string;
12
+ export declare function parseGithubRemote(remote: string): {
13
+ owner: string;
14
+ repo: string;
15
+ } | null;
16
+ export declare function currentRemote(run: GitRun, cwd: string): string | null;
17
+ export declare function unifiedDiff(before: string, after: string, file: string): string;
18
+ //# sourceMappingURL=git.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,MAAM,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;AAE7D,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAMjE;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAMhE;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAEzE;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAErE;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAe3E;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAc1E;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAG9D;AAED,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,GACb;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAMxC;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMrE;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAa/E"}
package/dist/git.js ADDED
@@ -0,0 +1,97 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ export function defaultGitRun(args, cwd) {
5
+ return execFileSync("git", args, {
6
+ cwd,
7
+ encoding: "utf8",
8
+ stdio: ["ignore", "pipe", "pipe"],
9
+ }).trim();
10
+ }
11
+ export function ensureGitIdentity(run, cwd) {
12
+ try {
13
+ run(["config", "user.email"], cwd);
14
+ }
15
+ catch {
16
+ run(["-c", "user.email=sean@local", "-c", "user.name=Agent Sean", "status"], cwd);
17
+ }
18
+ }
19
+ export function gitHead(run, cwd) {
20
+ return run(["rev-parse", "HEAD"], cwd);
21
+ }
22
+ export function gitBranch(run, cwd) {
23
+ return run(["rev-parse", "--abbrev-ref", "HEAD"], cwd);
24
+ }
25
+ export function createBranch(run, cwd, name) {
26
+ run(["checkout", "-b", name], cwd);
27
+ }
28
+ export function checkout(run, cwd, name) {
29
+ run(["checkout", name], cwd);
30
+ }
31
+ export function commitAll(run, cwd, message) {
32
+ run(["add", "-A"], cwd);
33
+ run([
34
+ "-c",
35
+ "user.email=sean@agentsean.local",
36
+ "-c",
37
+ "user.name=Agent Sean",
38
+ "commit",
39
+ "-m",
40
+ message,
41
+ ], cwd);
42
+ return gitHead(run, cwd);
43
+ }
44
+ export function revertCommit(run, cwd, sha) {
45
+ run([
46
+ "-c",
47
+ "user.email=sean@agentsean.local",
48
+ "-c",
49
+ "user.name=Agent Sean",
50
+ "revert",
51
+ "--no-edit",
52
+ sha,
53
+ ], cwd);
54
+ return gitHead(run, cwd);
55
+ }
56
+ export function writeFile(filePath, body) {
57
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
58
+ fs.writeFileSync(filePath, body, "utf8");
59
+ }
60
+ export function readFile(filePath) {
61
+ return fs.readFileSync(filePath, "utf8");
62
+ }
63
+ export function parseGithubRemote(remote) {
64
+ const ssh = /^git@github\.com:([^/]+)\/(.+?)(?:\.git)?$/.exec(remote);
65
+ if (ssh)
66
+ return { owner: ssh[1], repo: ssh[2] };
67
+ const https = /^https:\/\/github\.com\/([^/]+)\/(.+?)(?:\.git)?$/.exec(remote);
68
+ if (https)
69
+ return { owner: https[1], repo: https[2] };
70
+ return null;
71
+ }
72
+ export function currentRemote(run, cwd) {
73
+ try {
74
+ return run(["remote", "get-url", "origin"], cwd);
75
+ }
76
+ catch {
77
+ return null;
78
+ }
79
+ }
80
+ export function unifiedDiff(before, after, file) {
81
+ const a = before.split("\n");
82
+ const b = after.split("\n");
83
+ const lines = [`--- a/${file}`, `+++ b/${file}`];
84
+ const max = Math.max(a.length, b.length);
85
+ for (let i = 0; i < max; i++) {
86
+ const left = a[i];
87
+ const right = b[i];
88
+ if (left === right)
89
+ continue;
90
+ if (left !== undefined)
91
+ lines.push(`-${left}`);
92
+ if (right !== undefined)
93
+ lines.push(`+${right}`);
94
+ }
95
+ return lines.join("\n");
96
+ }
97
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAI7B,MAAM,UAAU,aAAa,CAAC,IAAc,EAAE,GAAW;IACvD,OAAO,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE;QAC/B,GAAG;QACH,QAAQ,EAAE,MAAM;QAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;KAClC,CAAC,CAAC,IAAI,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,GAAW,EAAE,GAAW;IACxD,IAAI,CAAC;QACH,GAAG,CAAC,CAAC,QAAQ,EAAE,YAAY,CAAC,EAAE,GAAG,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,GAAG,CAAC,CAAC,IAAI,EAAE,uBAAuB,EAAE,IAAI,EAAE,sBAAsB,EAAE,QAAQ,CAAC,EAAE,GAAG,CAAC,CAAC;IACpF,CAAC;AACH,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,GAAW,EAAE,GAAW;IAC9C,OAAO,GAAG,CAAC,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,GAAW,EAAE,GAAW;IAChD,OAAO,GAAG,CAAC,CAAC,WAAW,EAAE,cAAc,EAAE,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,GAAW,EAAE,IAAY;IACjE,GAAG,CAAC,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,GAAW,EAAE,GAAW,EAAE,IAAY;IAC7D,GAAG,CAAC,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,GAAW,EAAE,GAAW,EAAE,OAAe;IACjE,GAAG,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;IACxB,GAAG,CACD;QACE,IAAI;QACJ,iCAAiC;QACjC,IAAI;QACJ,sBAAsB;QACtB,QAAQ;QACR,IAAI;QACJ,OAAO;KACR,EACD,GAAG,CACJ,CAAC;IACF,OAAO,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,GAAW,EAAE,GAAW;IAChE,GAAG,CACD;QACE,IAAI;QACJ,iCAAiC;QACjC,IAAI;QACJ,sBAAsB;QACtB,QAAQ;QACR,WAAW;QACX,GAAG;KACJ,EACD,GAAG,CACJ,CAAC;IACF,OAAO,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,QAAgB,EAAE,IAAY;IACtD,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,QAAgB;IACvC,OAAO,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,MAAc;IAEd,MAAM,GAAG,GAAG,4CAA4C,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtE,IAAI,GAAG;QAAE,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,CAAE,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,CAAE,EAAE,CAAC;IAClD,MAAM,KAAK,GAAG,mDAAmD,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC/E,IAAI,KAAK;QAAE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAE,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAE,EAAE,CAAC;IACxD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAW,EAAE,GAAW;IACpD,IAAI,CAAC;QACH,OAAO,GAAG,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,GAAG,CAAC,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAc,EAAE,KAAa,EAAE,IAAY;IACrE,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7B,MAAM,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,MAAM,KAAK,GAAG,CAAC,SAAS,IAAI,EAAE,EAAE,SAAS,IAAI,EAAE,CAAC,CAAC;IACjD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;IACzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAClB,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACnB,IAAI,IAAI,KAAK,KAAK;YAAE,SAAS;QAC7B,IAAI,IAAI,KAAK,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QAC/C,IAAI,KAAK,KAAK,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,13 @@
1
+ export type OpenPrInput = {
2
+ owner: string;
3
+ repo: string;
4
+ title: string;
5
+ body: string;
6
+ head: string;
7
+ base: string;
8
+ token: string;
9
+ apiBase?: string | undefined;
10
+ fetch?: typeof fetch | undefined;
11
+ };
12
+ export declare function openGithubPr(input: OpenPrInput): Promise<string>;
13
+ //# sourceMappingURL=github.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../src/github.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,KAAK,CAAC,EAAE,OAAO,KAAK,GAAG,SAAS,CAAC;CAClC,CAAC;AAEF,wBAAsB,YAAY,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAwBtE"}
package/dist/github.js ADDED
@@ -0,0 +1,27 @@
1
+ export async function openGithubPr(input) {
2
+ const api = input.apiBase ?? "https://api.github.com";
3
+ const fetchFn = input.fetch ?? fetch;
4
+ const res = await fetchFn(`${api}/repos/${input.owner}/${input.repo}/pulls`, {
5
+ method: "POST",
6
+ headers: {
7
+ accept: "application/vnd.github+json",
8
+ authorization: `Bearer ${input.token}`,
9
+ "content-type": "application/json",
10
+ },
11
+ body: JSON.stringify({
12
+ title: input.title,
13
+ body: input.body,
14
+ head: input.head,
15
+ base: input.base,
16
+ }),
17
+ });
18
+ const text = await res.text();
19
+ if (!res.ok) {
20
+ throw new Error(`github pr failed ${res.status}: ${text.slice(0, 400)}`);
21
+ }
22
+ const json = JSON.parse(text);
23
+ if (!json.html_url)
24
+ throw new Error("github pr response missing html_url");
25
+ return json.html_url;
26
+ }
27
+ //# sourceMappingURL=github.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.js","sourceRoot":"","sources":["../src/github.ts"],"names":[],"mappings":"AAYA,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,KAAkB;IACnD,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,IAAI,wBAAwB,CAAC;IACtD,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC;IACrC,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,GAAG,UAAU,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,QAAQ,EAAE;QAC3E,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,MAAM,EAAE,6BAA6B;YACrC,aAAa,EAAE,UAAU,KAAK,CAAC,KAAK,EAAE;YACtC,cAAc,EAAE,kBAAkB;SACnC;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,IAAI,EAAE,KAAK,CAAC,IAAI;SACjB,CAAC;KACH,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAC9B,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,oBAAoB,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAA0B,CAAC;IACvD,IAAI,CAAC,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IAC3E,OAAO,IAAI,CAAC,QAAQ,CAAC;AACvB,CAAC"}
@@ -0,0 +1,7 @@
1
+ export { createGitAdapter, type GitAdapterOptions } from "./adapter.js";
2
+ export { resolvePageFile, detectFramework } from "./resolve.js";
3
+ export { rewriteTitle, rewriteBody, titleInSource } from "./rewrite.js";
4
+ export { parseGithubRemote, unifiedDiff } from "./git.js";
5
+ export { openGithubPr } from "./github.js";
6
+ export { assertPreviewNotIndexed, CRAWLER_BYPASS, VERCEL_BYPASS_HEADER, CF_ACCESS_CLIENT_ID, CF_ACCESS_CLIENT_SECRET, } from "./ci-gate.js";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EACL,uBAAuB,EACvB,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export { createGitAdapter } from "./adapter.js";
2
+ export { resolvePageFile, detectFramework } from "./resolve.js";
3
+ export { rewriteTitle, rewriteBody, titleInSource } from "./rewrite.js";
4
+ export { parseGithubRemote, unifiedDiff } from "./git.js";
5
+ export { openGithubPr } from "./github.js";
6
+ export { assertPreviewNotIndexed, CRAWLER_BYPASS, VERCEL_BYPASS_HEADER, CF_ACCESS_CLIENT_ID, CF_ACCESS_CLIENT_SECRET, } from "./ci-gate.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAA0B,MAAM,cAAc,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EACL,uBAAuB,EACvB,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,cAAc,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function resolvePageFile(repoRoot: string, pageUrl: string): string | null;
2
+ export declare function detectFramework(repoRoot: string): "next" | "astro" | "hugo" | "jekyll" | "docusaurus" | "unknown";
3
+ //# sourceMappingURL=resolve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"AAyEA,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMhF;AAED,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,GACf,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,YAAY,GAAG,SAAS,CA8BjE"}
@@ -0,0 +1,108 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ const PAGE_FILES = [
4
+ "page.tsx",
5
+ "page.jsx",
6
+ "page.ts",
7
+ "page.js",
8
+ "index.tsx",
9
+ "index.jsx",
10
+ "index.ts",
11
+ "index.js",
12
+ "index.mdx",
13
+ "index.md",
14
+ "index.astro",
15
+ "index.html",
16
+ ];
17
+ function exists(file) {
18
+ try {
19
+ return fs.statSync(file).isFile();
20
+ }
21
+ catch {
22
+ return false;
23
+ }
24
+ }
25
+ function urlPath(pageUrl) {
26
+ const u = new URL(pageUrl);
27
+ return u.pathname.replace(/\/+$/, "") || "/";
28
+ }
29
+ function candidatesFor(repoRoot, pathname) {
30
+ const rel = pathname === "/" ? "" : pathname.replace(/^\//, "");
31
+ const segs = rel ? rel.split("/") : [];
32
+ const out = [];
33
+ const roots = ["", "src"];
34
+ for (const src of roots) {
35
+ const app = src ? path.join(repoRoot, src, "app") : path.join(repoRoot, "app");
36
+ const pages = src
37
+ ? path.join(repoRoot, src, "pages")
38
+ : path.join(repoRoot, "pages");
39
+ if (pathname === "/") {
40
+ for (const f of PAGE_FILES) {
41
+ out.push(path.join(app, f));
42
+ out.push(path.join(pages, f));
43
+ }
44
+ out.push(path.join(repoRoot, "src/pages/index.astro"));
45
+ out.push(path.join(repoRoot, "content/_index.md"));
46
+ out.push(path.join(repoRoot, "index.md"));
47
+ out.push(path.join(repoRoot, "index.html"));
48
+ }
49
+ else {
50
+ for (const f of PAGE_FILES) {
51
+ out.push(path.join(app, ...segs, f));
52
+ out.push(path.join(pages, ...segs) + path.extname(f === "page.tsx" ? "" : ""));
53
+ out.push(path.join(pages, `${rel}.tsx`));
54
+ out.push(path.join(pages, `${rel}.jsx`));
55
+ out.push(path.join(pages, `${rel}.mdx`));
56
+ out.push(path.join(pages, `${rel}.md`));
57
+ out.push(path.join(pages, ...segs, "index.tsx"));
58
+ }
59
+ out.push(path.join(repoRoot, "src/pages", `${rel}.astro`));
60
+ out.push(path.join(repoRoot, "src/pages", rel, "index.astro"));
61
+ out.push(path.join(repoRoot, "content", `${rel}.md`));
62
+ out.push(path.join(repoRoot, "content", rel, "_index.md"));
63
+ out.push(path.join(repoRoot, "docs", `${rel}.md`));
64
+ out.push(path.join(repoRoot, "blog", `${rel}.md`));
65
+ out.push(path.join(repoRoot, "_posts", `${rel}.md`));
66
+ out.push(path.join(repoRoot, `${rel}.md`));
67
+ }
68
+ }
69
+ return out;
70
+ }
71
+ export function resolvePageFile(repoRoot, pageUrl) {
72
+ const pathname = urlPath(pageUrl);
73
+ for (const file of candidatesFor(repoRoot, pathname)) {
74
+ if (exists(file))
75
+ return file;
76
+ }
77
+ return null;
78
+ }
79
+ export function detectFramework(repoRoot) {
80
+ const pkgPath = path.join(repoRoot, "package.json");
81
+ if (exists(pkgPath)) {
82
+ try {
83
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
84
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
85
+ if (deps["next"])
86
+ return "next";
87
+ if (deps["astro"])
88
+ return "astro";
89
+ if (deps["@docusaurus/core"])
90
+ return "docusaurus";
91
+ }
92
+ catch {
93
+ /* ignore */
94
+ }
95
+ }
96
+ if (exists(path.join(repoRoot, "hugo.toml")) ||
97
+ exists(path.join(repoRoot, "config.toml"))) {
98
+ return "hugo";
99
+ }
100
+ if (exists(path.join(repoRoot, "_config.yml")))
101
+ return "jekyll";
102
+ if (fs.existsSync(path.join(repoRoot, "app")) ||
103
+ fs.existsSync(path.join(repoRoot, "src/app"))) {
104
+ return "next";
105
+ }
106
+ return "unknown";
107
+ }
108
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"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"}