@opentag/github 0.3.0 → 0.3.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/dist/index.js +204 -86
- package/dist/index.js.map +1 -1
- package/dist/ingress.d.ts +8 -0
- package/dist/ingress.d.ts.map +1 -1
- package/dist/normalize.d.ts +4 -0
- package/dist/normalize.d.ts.map +1 -1
- package/dist/render.d.ts +7 -2
- package/dist/render.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -534,7 +534,12 @@ async function applyGitHubIssueMutationIntents(input) {
|
|
|
534
534
|
import { createHmac, randomUUID, timingSafeEqual } from "crypto";
|
|
535
535
|
import { serve } from "@hono/node-server";
|
|
536
536
|
import { createOpenTagClient } from "@opentag/client";
|
|
537
|
-
import {
|
|
537
|
+
import {
|
|
538
|
+
DEFAULT_MAX_REQUEST_BODY_BYTES,
|
|
539
|
+
RequestBodyTooLargeError,
|
|
540
|
+
parseThreadActionCommand,
|
|
541
|
+
readRequestTextWithLimit
|
|
542
|
+
} from "@opentag/core";
|
|
538
543
|
import { Hono } from "hono";
|
|
539
544
|
|
|
540
545
|
// src/normalize.ts
|
|
@@ -689,6 +694,8 @@ function normalizeGitHubIssueComment(input) {
|
|
|
689
694
|
repo: input.repo,
|
|
690
695
|
issueNumber: input.issueNumber,
|
|
691
696
|
...commandMetadata(command),
|
|
697
|
+
...input.deliveryId ? { sourceDeliveryId: input.deliveryId, webhookDeliveryId: input.deliveryId } : {},
|
|
698
|
+
...typeof input.signatureVerified === "boolean" ? { webhookSignatureVerified: input.signatureVerified, signatureState: input.signatureVerified ? "verified" : "unverified" } : {},
|
|
692
699
|
...typeof input.installationId === "number" ? { installationId: input.installationId } : {}
|
|
693
700
|
}
|
|
694
701
|
};
|
|
@@ -752,6 +759,8 @@ function normalizeGitHubPullRequestReviewComment(input) {
|
|
|
752
759
|
repo: input.repo,
|
|
753
760
|
pullRequestNumber: input.pullRequestNumber,
|
|
754
761
|
...commandMetadata(command),
|
|
762
|
+
...input.deliveryId ? { sourceDeliveryId: input.deliveryId, webhookDeliveryId: input.deliveryId } : {},
|
|
763
|
+
...typeof input.signatureVerified === "boolean" ? { webhookSignatureVerified: input.signatureVerified, signatureState: input.signatureVerified ? "verified" : "unverified" } : {},
|
|
755
764
|
...typeof input.installationId === "number" ? { installationId: input.installationId } : {}
|
|
756
765
|
}
|
|
757
766
|
};
|
|
@@ -768,6 +777,42 @@ function verifyGitHubSignature(input) {
|
|
|
768
777
|
const actualBuffer = Buffer.from(input.signature);
|
|
769
778
|
return expectedBuffer.length === actualBuffer.length && timingSafeEqual(expectedBuffer, actualBuffer);
|
|
770
779
|
}
|
|
780
|
+
async function recordGitHubSignatureFailure(input) {
|
|
781
|
+
try {
|
|
782
|
+
await input.recordControlPlaneEvent?.({
|
|
783
|
+
type: "security.signature_failed",
|
|
784
|
+
severity: "warn",
|
|
785
|
+
subject: `github:POST ${input.webhookPath}`,
|
|
786
|
+
payload: {
|
|
787
|
+
provider: "github",
|
|
788
|
+
endpoint: `POST ${input.webhookPath}`,
|
|
789
|
+
reason: input.reason,
|
|
790
|
+
...input.deliveryId ? { deliveryId: input.deliveryId } : {},
|
|
791
|
+
hasSignature: input.hasSignature
|
|
792
|
+
}
|
|
793
|
+
});
|
|
794
|
+
} catch {
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
async function recordGitHubRequestBodyRejected(input) {
|
|
798
|
+
try {
|
|
799
|
+
await input.recordControlPlaneEvent?.({
|
|
800
|
+
type: "security.request_body_rejected",
|
|
801
|
+
severity: "warn",
|
|
802
|
+
subject: `github:POST ${input.webhookPath}`,
|
|
803
|
+
payload: {
|
|
804
|
+
provider: "github",
|
|
805
|
+
endpoint: `POST ${input.webhookPath}`,
|
|
806
|
+
reason: input.reason,
|
|
807
|
+
...input.maxBytes !== void 0 ? { maxBytes: input.maxBytes } : {},
|
|
808
|
+
contentLength: input.contentLength,
|
|
809
|
+
...input.deliveryId ? { deliveryId: input.deliveryId } : {},
|
|
810
|
+
...input.eventName ? { githubEvent: input.eventName } : {}
|
|
811
|
+
}
|
|
812
|
+
});
|
|
813
|
+
} catch {
|
|
814
|
+
}
|
|
815
|
+
}
|
|
771
816
|
function parseJsonPayload(rawBody) {
|
|
772
817
|
try {
|
|
773
818
|
return JSON.parse(rawBody);
|
|
@@ -775,6 +820,24 @@ function parseJsonPayload(rawBody) {
|
|
|
775
820
|
return null;
|
|
776
821
|
}
|
|
777
822
|
}
|
|
823
|
+
function isRecord(value) {
|
|
824
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
825
|
+
}
|
|
826
|
+
function hasGitHubActor(value) {
|
|
827
|
+
return isRecord(value) && typeof value.id === "number" && typeof value.login === "string";
|
|
828
|
+
}
|
|
829
|
+
function hasGitHubRepository(value) {
|
|
830
|
+
return isRecord(value) && typeof value.name === "string" && typeof value.private === "boolean" && isRecord(value.owner) && typeof value.owner.login === "string";
|
|
831
|
+
}
|
|
832
|
+
function hasGitHubInstallation(value) {
|
|
833
|
+
return isRecord(value) && typeof value.id === "number";
|
|
834
|
+
}
|
|
835
|
+
function isGitHubIssueCommentPayload(value) {
|
|
836
|
+
return isRecord(value) && (value.action === void 0 || typeof value.action === "string") && isRecord(value.comment) && typeof value.comment.id === "number" && typeof value.comment.body === "string" && typeof value.comment.html_url === "string" && isRecord(value.issue) && typeof value.issue.html_url === "string" && typeof value.issue.comments_url === "string" && typeof value.issue.number === "number" && hasGitHubRepository(value.repository) && hasGitHubActor(value.sender) && (value.installation === void 0 || hasGitHubInstallation(value.installation));
|
|
837
|
+
}
|
|
838
|
+
function isGitHubPullRequestReviewCommentPayload(value) {
|
|
839
|
+
return isRecord(value) && (value.action === void 0 || typeof value.action === "string") && isRecord(value.comment) && typeof value.comment.id === "number" && typeof value.comment.body === "string" && typeof value.comment.html_url === "string" && isRecord(value.pull_request) && typeof value.pull_request.html_url === "string" && typeof value.pull_request.number === "number" && hasGitHubRepository(value.repository) && hasGitHubActor(value.sender) && (value.installation === void 0 || hasGitHubInstallation(value.installation));
|
|
840
|
+
}
|
|
778
841
|
async function handleIssueCommentCreated(input) {
|
|
779
842
|
if (input.payload.action && input.payload.action !== "created") return;
|
|
780
843
|
if (parseThreadActionCommand(input.payload.comment.body) && input.submitThreadAction) {
|
|
@@ -796,7 +859,9 @@ async function handleIssueCommentCreated(input) {
|
|
|
796
859
|
owner: input.payload.repository.owner.login,
|
|
797
860
|
repo: input.payload.repository.name,
|
|
798
861
|
issueNumber: input.payload.issue.number,
|
|
799
|
-
commentUrl: input.payload.comment.html_url
|
|
862
|
+
commentUrl: input.payload.comment.html_url,
|
|
863
|
+
...input.deliveryId ? { sourceDeliveryId: input.deliveryId, webhookDeliveryId: input.deliveryId } : {},
|
|
864
|
+
...typeof input.signatureVerified === "boolean" ? { webhookSignatureVerified: input.signatureVerified, signatureState: input.signatureVerified ? "verified" : "unverified" } : {}
|
|
800
865
|
}
|
|
801
866
|
});
|
|
802
867
|
return;
|
|
@@ -814,6 +879,8 @@ async function handleIssueCommentCreated(input) {
|
|
|
814
879
|
actorLogin: input.payload.sender.login,
|
|
815
880
|
private: input.payload.repository.private,
|
|
816
881
|
receivedAt: input.now(),
|
|
882
|
+
...input.deliveryId ? { deliveryId: input.deliveryId } : {},
|
|
883
|
+
...typeof input.signatureVerified === "boolean" ? { signatureVerified: input.signatureVerified } : {},
|
|
817
884
|
...input.payload.installation ? { installationId: input.payload.installation.id } : {}
|
|
818
885
|
});
|
|
819
886
|
if (event) {
|
|
@@ -843,7 +910,9 @@ async function handlePullRequestReviewCommentCreated(input) {
|
|
|
843
910
|
owner,
|
|
844
911
|
repo,
|
|
845
912
|
pullRequestNumber: input.payload.pull_request.number,
|
|
846
|
-
commentUrl: input.payload.comment.html_url
|
|
913
|
+
commentUrl: input.payload.comment.html_url,
|
|
914
|
+
...input.deliveryId ? { sourceDeliveryId: input.deliveryId, webhookDeliveryId: input.deliveryId } : {},
|
|
915
|
+
...typeof input.signatureVerified === "boolean" ? { webhookSignatureVerified: input.signatureVerified, signatureState: input.signatureVerified ? "verified" : "unverified" } : {}
|
|
847
916
|
}
|
|
848
917
|
});
|
|
849
918
|
return;
|
|
@@ -861,6 +930,8 @@ async function handlePullRequestReviewCommentCreated(input) {
|
|
|
861
930
|
actorLogin: input.payload.sender.login,
|
|
862
931
|
private: input.payload.repository.private,
|
|
863
932
|
receivedAt: input.now(),
|
|
933
|
+
...input.deliveryId ? { deliveryId: input.deliveryId } : {},
|
|
934
|
+
...typeof input.signatureVerified === "boolean" ? { signatureVerified: input.signatureVerified } : {},
|
|
864
935
|
...input.payload.installation ? { installationId: input.payload.installation.id } : {}
|
|
865
936
|
});
|
|
866
937
|
if (event) {
|
|
@@ -870,41 +941,108 @@ async function handlePullRequestReviewCommentCreated(input) {
|
|
|
870
941
|
function createGitHubWebhookApp(input) {
|
|
871
942
|
const app = new Hono();
|
|
872
943
|
const webhookPath = input.webhookPath ?? "/github/webhooks";
|
|
944
|
+
const maxRequestBodyBytes = input.maxRequestBodyBytes ?? DEFAULT_MAX_REQUEST_BODY_BYTES;
|
|
873
945
|
if (!webhookPath.startsWith("/")) {
|
|
874
946
|
throw new Error("GitHub webhook path must start with /.");
|
|
875
947
|
}
|
|
876
948
|
app.post(webhookPath, async (c) => {
|
|
877
949
|
const signature = c.req.header("x-hub-signature-256");
|
|
878
950
|
if (!signature) {
|
|
951
|
+
await recordGitHubSignatureFailure({
|
|
952
|
+
recordControlPlaneEvent: input.recordControlPlaneEvent,
|
|
953
|
+
webhookPath,
|
|
954
|
+
reason: "missing_signature_header",
|
|
955
|
+
...c.req.header("x-github-delivery") ? { deliveryId: c.req.header("x-github-delivery") } : {},
|
|
956
|
+
hasSignature: false
|
|
957
|
+
});
|
|
879
958
|
return c.json({ error: "missing_signature_header" }, 401);
|
|
880
959
|
}
|
|
881
|
-
|
|
960
|
+
let rawBody;
|
|
961
|
+
try {
|
|
962
|
+
rawBody = await readRequestTextWithLimit(c.req.raw, { maxBytes: maxRequestBodyBytes });
|
|
963
|
+
} catch (error) {
|
|
964
|
+
if (error instanceof RequestBodyTooLargeError) {
|
|
965
|
+
await recordGitHubRequestBodyRejected({
|
|
966
|
+
recordControlPlaneEvent: input.recordControlPlaneEvent,
|
|
967
|
+
webhookPath,
|
|
968
|
+
reason: "request_body_too_large",
|
|
969
|
+
maxBytes: error.maxBytes,
|
|
970
|
+
contentLength: c.req.raw.headers.get("content-length"),
|
|
971
|
+
...c.req.header("x-github-delivery") ? { deliveryId: c.req.header("x-github-delivery") } : {},
|
|
972
|
+
...c.req.header("x-github-event") ? { eventName: c.req.header("x-github-event") } : {}
|
|
973
|
+
});
|
|
974
|
+
return c.json({ error: "request_body_too_large", maxBytes: error.maxBytes }, 413);
|
|
975
|
+
}
|
|
976
|
+
throw error;
|
|
977
|
+
}
|
|
882
978
|
if (!verifyGitHubSignature({ webhookSecret: input.webhookSecret, rawBody, signature })) {
|
|
979
|
+
await recordGitHubSignatureFailure({
|
|
980
|
+
recordControlPlaneEvent: input.recordControlPlaneEvent,
|
|
981
|
+
webhookPath,
|
|
982
|
+
reason: "invalid_signature",
|
|
983
|
+
...c.req.header("x-github-delivery") ? { deliveryId: c.req.header("x-github-delivery") } : {},
|
|
984
|
+
hasSignature: true
|
|
985
|
+
});
|
|
883
986
|
return c.json({ error: "invalid_signature" }, 401);
|
|
884
987
|
}
|
|
988
|
+
const deliveryId = c.req.header("x-github-delivery");
|
|
885
989
|
const eventName = c.req.header("x-github-event");
|
|
886
990
|
const payload = parseJsonPayload(rawBody);
|
|
887
991
|
if (!payload || typeof payload !== "object") {
|
|
992
|
+
await recordGitHubRequestBodyRejected({
|
|
993
|
+
recordControlPlaneEvent: input.recordControlPlaneEvent,
|
|
994
|
+
webhookPath,
|
|
995
|
+
reason: "invalid_json_body",
|
|
996
|
+
contentLength: c.req.raw.headers.get("content-length"),
|
|
997
|
+
...deliveryId ? { deliveryId } : {},
|
|
998
|
+
...eventName ? { eventName } : {}
|
|
999
|
+
});
|
|
888
1000
|
return c.json({ error: "invalid_json" }, 400);
|
|
889
1001
|
}
|
|
890
1002
|
if (eventName === "ping") {
|
|
891
1003
|
return c.json({ ok: true });
|
|
892
1004
|
}
|
|
893
1005
|
if (eventName === "issue_comment") {
|
|
1006
|
+
if (!isGitHubIssueCommentPayload(payload)) {
|
|
1007
|
+
await recordGitHubRequestBodyRejected({
|
|
1008
|
+
recordControlPlaneEvent: input.recordControlPlaneEvent,
|
|
1009
|
+
webhookPath,
|
|
1010
|
+
reason: "invalid_request_body",
|
|
1011
|
+
contentLength: c.req.raw.headers.get("content-length"),
|
|
1012
|
+
...deliveryId ? { deliveryId } : {},
|
|
1013
|
+
eventName
|
|
1014
|
+
});
|
|
1015
|
+
return c.json({ error: "invalid_request_body" }, 400);
|
|
1016
|
+
}
|
|
894
1017
|
await handleIssueCommentCreated({
|
|
895
1018
|
payload,
|
|
896
1019
|
createRun: input.createRun,
|
|
897
1020
|
...input.submitThreadAction ? { submitThreadAction: input.submitThreadAction } : {},
|
|
898
|
-
now: input.now
|
|
1021
|
+
now: input.now,
|
|
1022
|
+
...deliveryId ? { deliveryId } : {},
|
|
1023
|
+
signatureVerified: true
|
|
899
1024
|
});
|
|
900
1025
|
return c.json({ ok: true });
|
|
901
1026
|
}
|
|
902
1027
|
if (eventName === "pull_request_review_comment") {
|
|
1028
|
+
if (!isGitHubPullRequestReviewCommentPayload(payload)) {
|
|
1029
|
+
await recordGitHubRequestBodyRejected({
|
|
1030
|
+
recordControlPlaneEvent: input.recordControlPlaneEvent,
|
|
1031
|
+
webhookPath,
|
|
1032
|
+
reason: "invalid_request_body",
|
|
1033
|
+
contentLength: c.req.raw.headers.get("content-length"),
|
|
1034
|
+
...deliveryId ? { deliveryId } : {},
|
|
1035
|
+
eventName
|
|
1036
|
+
});
|
|
1037
|
+
return c.json({ error: "invalid_request_body" }, 400);
|
|
1038
|
+
}
|
|
903
1039
|
await handlePullRequestReviewCommentCreated({
|
|
904
1040
|
payload,
|
|
905
1041
|
createRun: input.createRun,
|
|
906
1042
|
...input.submitThreadAction ? { submitThreadAction: input.submitThreadAction } : {},
|
|
907
|
-
now: input.now
|
|
1043
|
+
now: input.now,
|
|
1044
|
+
...deliveryId ? { deliveryId } : {},
|
|
1045
|
+
signatureVerified: true
|
|
908
1046
|
});
|
|
909
1047
|
return c.json({ ok: true });
|
|
910
1048
|
}
|
|
@@ -924,6 +1062,7 @@ function startGitHubIngress(config) {
|
|
|
924
1062
|
fetch: createGitHubWebhookApp({
|
|
925
1063
|
webhookSecret: config.webhookSecret,
|
|
926
1064
|
webhookPath,
|
|
1065
|
+
...config.maxRequestBodyBytes ? { maxRequestBodyBytes: config.maxRequestBodyBytes } : {},
|
|
927
1066
|
async createRun(event) {
|
|
928
1067
|
const runId = `run_${randomUUID()}`;
|
|
929
1068
|
const created = await dispatcherClient.createRun({ runId, event });
|
|
@@ -932,6 +1071,9 @@ function startGitHubIngress(config) {
|
|
|
932
1071
|
async submitThreadAction(action) {
|
|
933
1072
|
await dispatcherClient.submitThreadAction(action);
|
|
934
1073
|
},
|
|
1074
|
+
async recordControlPlaneEvent(event) {
|
|
1075
|
+
await dispatcherClient.recordControlPlaneEvent(event);
|
|
1076
|
+
},
|
|
935
1077
|
now: () => (/* @__PURE__ */ new Date()).toISOString()
|
|
936
1078
|
}).fetch,
|
|
937
1079
|
port,
|
|
@@ -956,95 +1098,63 @@ function startGitHubIngress(config) {
|
|
|
956
1098
|
}
|
|
957
1099
|
|
|
958
1100
|
// src/render.ts
|
|
959
|
-
import {
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
return
|
|
1101
|
+
import {
|
|
1102
|
+
createFinalSummaryPresentation
|
|
1103
|
+
} from "@opentag/core";
|
|
1104
|
+
function tableValue(value) {
|
|
1105
|
+
return value.replace(/\|/g, "\\|").replace(/\n/g, "<br>");
|
|
964
1106
|
}
|
|
965
|
-
function
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
const value = params?.[key];
|
|
971
|
-
if (!Array.isArray(value)) return [];
|
|
972
|
-
return value.filter((item) => typeof item === "string" && item.length > 0);
|
|
1107
|
+
function decisionLabel(decision) {
|
|
1108
|
+
if (decision === "apply") return "Apply now";
|
|
1109
|
+
if (decision === "approve") return "Approve only";
|
|
1110
|
+
if (decision === "continue") return "Continue";
|
|
1111
|
+
return "Reject";
|
|
973
1112
|
}
|
|
974
|
-
function
|
|
975
|
-
|
|
976
|
-
if (
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
const command = item["command"];
|
|
980
|
-
const outcome = item["outcome"];
|
|
981
|
-
const summary = item["summary"];
|
|
982
|
-
if (typeof outcome !== "string") return void 0;
|
|
983
|
-
const prefix = typeof command === "string" && command.length > 0 ? `\`${command}\`: ${outcome}` : outcome;
|
|
984
|
-
return typeof summary === "string" && summary.length > 0 ? ` - ${prefix} - ${summary}` : ` - ${prefix}`;
|
|
985
|
-
}).filter((line) => Boolean(line));
|
|
1113
|
+
function decisionEffect(decision) {
|
|
1114
|
+
if (decision === "apply") return "Approves and applies this action to the system of record.";
|
|
1115
|
+
if (decision === "approve") return "Records approval without applying yet.";
|
|
1116
|
+
if (decision === "continue") return "Starts a follow-up run from this approved action.";
|
|
1117
|
+
return "Rejects this action.";
|
|
986
1118
|
}
|
|
987
|
-
function
|
|
988
|
-
if (action
|
|
989
|
-
const
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
const base = stringParam2(params, "base") ?? stringParam2(params, "baseBranch");
|
|
993
|
-
const changedFiles = stringArrayParam2(params, "changedFiles");
|
|
994
|
-
const risks = stringArrayParam2(params, "risks");
|
|
995
|
-
const verification = renderVerificationParams(params);
|
|
996
|
-
if (title) lines.push(`- Title: ${title}`);
|
|
997
|
-
if (head || base) lines.push(`- Branch: \`${head ?? "unknown"}\` -> \`${base ?? "main"}\``);
|
|
998
|
-
if (changedFiles.length > 0) lines.push(`- Changed files: ${changedFiles.map((file) => `\`${file}\``).join(", ")}`);
|
|
999
|
-
if (risks.length > 0) {
|
|
1000
|
-
lines.push("- Risks:");
|
|
1001
|
-
for (const risk of risks) {
|
|
1002
|
-
lines.push(` - ${risk}`);
|
|
1003
|
-
}
|
|
1004
|
-
}
|
|
1005
|
-
if (verification.length > 0) {
|
|
1006
|
-
lines.push("- Verification:");
|
|
1007
|
-
lines.push(...verification);
|
|
1008
|
-
}
|
|
1009
|
-
return lines;
|
|
1119
|
+
function actionDetailRows(action) {
|
|
1120
|
+
if (action.detailRows?.length) return action.detailRows.map((row) => [row.label, row.value]);
|
|
1121
|
+
const rows = [["Target", action.targetLabel]];
|
|
1122
|
+
if (action.setupReason) rows.push(["Status", action.setupReason]);
|
|
1123
|
+
return rows;
|
|
1010
1124
|
}
|
|
1011
|
-
function renderSuggestedActions(
|
|
1012
|
-
const
|
|
1013
|
-
if (
|
|
1125
|
+
function renderSuggestedActions(presentation) {
|
|
1126
|
+
const actions = presentation.actions ?? [];
|
|
1127
|
+
if (actions.length === 0 || !presentation.actionReceiptTitle) return [];
|
|
1014
1128
|
const lines = [
|
|
1015
|
-
|
|
1129
|
+
`### ${presentation.actionReceiptTitle}`,
|
|
1016
1130
|
"",
|
|
1017
|
-
"
|
|
1131
|
+
"OpenTag prepared a source-thread action receipt. Choose one command in this GitHub thread; full protocol lineage stays in the audit log."
|
|
1018
1132
|
];
|
|
1019
|
-
|
|
1133
|
+
if (presentation.auditRunId) {
|
|
1134
|
+
lines.push("", `Audit: run \`opentag status --run ${presentation.auditRunId}\` locally.`);
|
|
1135
|
+
}
|
|
1136
|
+
for (const action of actions) {
|
|
1020
1137
|
lines.push(
|
|
1021
1138
|
"",
|
|
1022
|
-
`####
|
|
1139
|
+
`#### ${action.index}. ${action.title}`,
|
|
1023
1140
|
"",
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
`- Intent ID: \`${candidate.intent.intentId}\``
|
|
1141
|
+
"| Field | Value |",
|
|
1142
|
+
"| --- | --- |"
|
|
1027
1143
|
);
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
lines.push("- Preconditions:");
|
|
1031
|
-
for (const precondition of candidate.proposalPreconditions) {
|
|
1032
|
-
lines.push(` - ${precondition}`);
|
|
1033
|
-
}
|
|
1144
|
+
for (const [label, value] of actionDetailRows(action)) {
|
|
1145
|
+
lines.push(`| ${label} | ${tableValue(value)} |`);
|
|
1034
1146
|
}
|
|
1035
1147
|
lines.push(
|
|
1036
1148
|
"",
|
|
1037
|
-
"**
|
|
1149
|
+
"**Choose in this thread**",
|
|
1038
1150
|
"",
|
|
1039
1151
|
`| Decision | Comment command | Effect |`,
|
|
1040
|
-
`| --- | --- | ---
|
|
1041
|
-
`| Apply now | \`apply ${candidate.index}\` | Applies this action to the system of record. |`,
|
|
1042
|
-
`| Approve only | \`approve ${candidate.index}\` | Records approval without applying yet. |`,
|
|
1043
|
-
`| Continue | \`continue ${candidate.index}\` | Starts a follow-up run from this proposal. |`,
|
|
1044
|
-
`| Reject | \`reject ${candidate.index}\` | Rejects this action. |`
|
|
1152
|
+
`| --- | --- | --- |`
|
|
1045
1153
|
);
|
|
1154
|
+
for (const decision of action.visibleDecisions) {
|
|
1155
|
+
lines.push(`| ${decisionLabel(decision)} | \`${decision} ${action.index}\` | ${decisionEffect(decision)} |`);
|
|
1156
|
+
}
|
|
1046
1157
|
}
|
|
1047
|
-
lines.push("", "Bulk shortcut: comment `apply all` to apply every supported approved action in this thread.");
|
|
1048
1158
|
return lines;
|
|
1049
1159
|
}
|
|
1050
1160
|
function renderAcknowledgement(runId) {
|
|
@@ -1053,21 +1163,28 @@ function renderAcknowledgement(runId) {
|
|
|
1053
1163
|
function renderProgress(input) {
|
|
1054
1164
|
return `OpenTag progress for \`${input.runId}\`: ${input.message}`;
|
|
1055
1165
|
}
|
|
1056
|
-
function renderFinalResult(result) {
|
|
1057
|
-
|
|
1058
|
-
|
|
1166
|
+
function renderFinalResult(result, options = {}) {
|
|
1167
|
+
return renderFinalSummaryPresentation(
|
|
1168
|
+
createFinalSummaryPresentation({
|
|
1169
|
+
result,
|
|
1170
|
+
...options.receiptContext ? { receiptContext: options.receiptContext } : {},
|
|
1171
|
+
...options.auditRunId ? { auditRunId: options.auditRunId } : {}
|
|
1172
|
+
})
|
|
1173
|
+
);
|
|
1174
|
+
}
|
|
1175
|
+
function renderFinalSummaryPresentation(presentation) {
|
|
1176
|
+
const lines = [`OpenTag finished with **${presentation.outcome}**.`, "", presentation.summary];
|
|
1177
|
+
if (presentation.verification?.length) {
|
|
1059
1178
|
lines.push("", "Verification:");
|
|
1060
|
-
for (const check of
|
|
1179
|
+
for (const check of presentation.verification) {
|
|
1061
1180
|
lines.push(`- \`${check.command}\`: ${check.outcome}`);
|
|
1062
1181
|
}
|
|
1063
1182
|
}
|
|
1064
|
-
const
|
|
1065
|
-
if (nextAction) {
|
|
1066
|
-
lines.push("", `Next action: ${nextAction}`);
|
|
1067
|
-
}
|
|
1068
|
-
const suggestedActions = renderSuggestedActions(result);
|
|
1183
|
+
const suggestedActions = renderSuggestedActions(presentation);
|
|
1069
1184
|
if (suggestedActions.length > 0) {
|
|
1070
1185
|
lines.push("", ...suggestedActions);
|
|
1186
|
+
} else if (presentation.nextActions?.length) {
|
|
1187
|
+
lines.push("", `Next action: ${presentation.nextActions[0]}`);
|
|
1071
1188
|
}
|
|
1072
1189
|
return lines.join("\n");
|
|
1073
1190
|
}
|
|
@@ -1086,6 +1203,7 @@ export {
|
|
|
1086
1203
|
normalizeGitHubPullRequestReviewComment,
|
|
1087
1204
|
renderAcknowledgement,
|
|
1088
1205
|
renderFinalResult,
|
|
1206
|
+
renderFinalSummaryPresentation,
|
|
1089
1207
|
renderProgress,
|
|
1090
1208
|
startGitHubIngress,
|
|
1091
1209
|
verifyGitHubSignature
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/pull-request.ts","../src/apply.ts","../src/ingress.ts","../src/normalize.ts","../src/render.ts"],"sourcesContent":["import type { OpenTagRunResult } from \"@opentag/core\";\n\nexport type CreatePullRequestInput = {\n token: string;\n owner: string;\n repo: string;\n title: string;\n body: string;\n head: string;\n base: string;\n};\n\nexport type FetchLike = typeof fetch;\n\nexport function buildPullRequestBody(result: OpenTagRunResult): string {\n const lines = [\"## Summary\", \"\", result.summary];\n\n if (result.changedFiles?.length) {\n lines.push(\"\", \"## Changed Files\");\n for (const file of result.changedFiles) {\n lines.push(`- \\`${file}\\``);\n }\n }\n\n if (result.verification?.length) {\n lines.push(\"\", \"## Verification\");\n for (const check of result.verification) {\n lines.push(`- \\`${check.command}\\`: ${check.outcome}`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n\nexport async function createPullRequestViaFetch(input: CreatePullRequestInput, fetchImpl: FetchLike = fetch): Promise<string> {\n const response = await fetchImpl(`https://api.github.com/repos/${input.owner}/${input.repo}/pulls`, {\n method: \"POST\",\n headers: {\n accept: \"application/vnd.github+json\",\n authorization: `Bearer ${input.token}`,\n \"content-type\": \"application/json\",\n \"x-github-api-version\": \"2022-11-28\"\n },\n body: JSON.stringify({\n title: input.title,\n body: input.body,\n head: input.head,\n base: input.base\n })\n });\n\n if (!response.ok) {\n throw new Error(`create pull request failed: ${response.status} ${await response.text()}`);\n }\n\n const body = (await response.json()) as { html_url?: string };\n if (!body.html_url) {\n throw new Error(\"create pull request response did not include html_url\");\n }\n return body.html_url;\n}\n","import type { AdapterMutationCompiler, AdapterMutationMapping, ApplyIntentOutcome, MutationIntent } from \"@opentag/core\";\nimport { createPullRequestViaFetch, type FetchLike } from \"./pull-request.js\";\n\nexport type GitHubIssueMutationTarget = {\n token: string;\n owner: string;\n repo: string;\n issueNumber?: number;\n pullRequestNumber?: number;\n};\n\nexport type GitHubIssueMutationOperation =\n | {\n kind: \"add_label\";\n intentId: string;\n label: string;\n }\n | {\n kind: \"remove_label\";\n intentId: string;\n label: string;\n }\n | {\n kind: \"replace_mapped_label\";\n intentId: string;\n label: string;\n removeLabels: string[];\n }\n | {\n kind: \"set_labels\";\n intentId: string;\n labels: string[];\n }\n | {\n kind: \"set_assignees\";\n intentId: string;\n assignees: string[];\n }\n | {\n kind: \"add_assignee\";\n intentId: string;\n assignee: string;\n }\n | {\n kind: \"remove_assignee\";\n intentId: string;\n assignee: string;\n }\n | {\n kind: \"request_review\";\n intentId: string;\n reviewers: string[];\n teamReviewers?: string[];\n }\n | {\n kind: \"create_pull_request\";\n intentId: string;\n title: string;\n body: string;\n head: string;\n base: string;\n };\n\nexport type GitHubIssueMutationCompilation =\n | {\n ok: true;\n intentId: string;\n operation: GitHubIssueMutationOperation;\n }\n | {\n ok: false;\n outcome: ApplyIntentOutcome;\n };\n\nfunction labelFromIntent(intent: MutationIntent): string | undefined {\n const value = intent.params?.[\"label\"];\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\nfunction labelsFromIntent(intent: MutationIntent): string[] | undefined {\n const value = intent.params?.[\"labels\"];\n if (!Array.isArray(value)) return undefined;\n const labels = value.filter((label): label is string => typeof label === \"string\" && label.length > 0);\n return labels.length > 0 ? labels : undefined;\n}\n\nfunction assigneeFromIntent(intent: MutationIntent): string | undefined {\n const value = intent.params?.[\"assignee\"];\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\nfunction assigneesFromIntent(intent: MutationIntent): string[] | undefined {\n const value = intent.params?.[\"assignees\"];\n if (!Array.isArray(value)) return undefined;\n const assignees = value.filter((assignee): assignee is string => typeof assignee === \"string\" && assignee.length > 0);\n return assignees.length > 0 ? assignees : undefined;\n}\n\nfunction reviewersFromIntent(intent: MutationIntent): string[] | undefined {\n const reviewer = intent.params?.[\"reviewer\"];\n const reviewers = intent.params?.[\"reviewers\"];\n const values = [\n ...(typeof reviewer === \"string\" ? [reviewer] : []),\n ...(Array.isArray(reviewers) ? reviewers : [])\n ].filter((value): value is string => typeof value === \"string\" && value.length > 0);\n return values.length > 0 ? [...new Set(values)] : undefined;\n}\n\nfunction teamReviewersFromIntent(intent: MutationIntent): string[] | undefined {\n const reviewer = intent.params?.[\"teamReviewer\"];\n const reviewers = intent.params?.[\"teamReviewers\"] ?? intent.params?.[\"team_reviewers\"];\n const values = [\n ...(typeof reviewer === \"string\" ? [reviewer] : []),\n ...(Array.isArray(reviewers) ? reviewers : [])\n ].filter((value): value is string => typeof value === \"string\" && value.length > 0);\n return values.length > 0 ? [...new Set(values)] : undefined;\n}\n\nfunction stringParam(intent: MutationIntent, ...keys: string[]): string | undefined {\n for (const key of keys) {\n const value = intent.params?.[key];\n if (typeof value === \"string\" && value.length > 0) return value;\n }\n return undefined;\n}\n\nfunction stringArrayParam(intent: MutationIntent, key: string): string[] {\n const value = intent.params?.[key];\n if (!Array.isArray(value)) return [];\n return value.filter((item): item is string => typeof item === \"string\" && item.length > 0);\n}\n\nfunction verificationLinesFromIntent(intent: MutationIntent): string[] {\n const value = intent.params?.[\"verification\"];\n if (!Array.isArray(value)) return [];\n return value\n .map((item) => {\n if (!item || typeof item !== \"object\" || Array.isArray(item)) return undefined;\n const command = (item as Record<string, unknown>)[\"command\"];\n const outcome = (item as Record<string, unknown>)[\"outcome\"];\n return typeof command === \"string\" && typeof outcome === \"string\" ? `- \\`${command}\\`: ${outcome}` : undefined;\n })\n .filter((line): line is string => Boolean(line));\n}\n\nfunction pullRequestBodyFromIntent(intent: MutationIntent): string {\n const explicitBody = stringParam(intent, \"body\");\n const changedFiles = stringArrayParam(intent, \"changedFiles\");\n const risks = stringArrayParam(intent, \"risks\");\n const verification = verificationLinesFromIntent(intent);\n const executorConditions = stringArrayParam(intent, \"executorConditions\");\n const lines = explicitBody ? [explicitBody] : [\"## Summary\", \"\", intent.summary];\n if (changedFiles.length > 0) {\n lines.push(\"\", \"## Changed Files\", ...changedFiles.map((file) => `- \\`${file}\\``));\n }\n if (risks.length > 0) {\n lines.push(\"\", \"## Risks\", ...risks.map((risk) => `- ${risk}`));\n }\n if (verification.length > 0) {\n lines.push(\"\", \"## Verification\", ...verification);\n }\n if (executorConditions.length > 0) {\n lines.push(\"\", \"## Executor Conditions\", ...executorConditions.map((condition) => `- ${condition}`));\n }\n return lines.join(\"\\n\");\n}\n\nfunction mappedValueFromIntent(intent: MutationIntent): string | undefined {\n const key = intent.domain === \"status\" ? \"status\" : \"priority\";\n const value = intent.params?.[key] ?? intent.params?.[\"value\"];\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\nfunction labelMappingForIntent(input: { intent: MutationIntent; mappings: AdapterMutationMapping[] }): { label: string; removeLabels: string[] } | undefined {\n const semanticValue = mappedValueFromIntent(input.intent);\n if (!semanticValue) return undefined;\n const mapping = input.mappings.find(\n (candidate) => candidate.adapter === \"github\" && candidate.domain === input.intent.domain && candidate.strategy === \"label\"\n );\n const label = mapping?.values[semanticValue];\n if (!label || !mapping) return undefined;\n return {\n label,\n removeLabels: Object.values(mapping.values).filter((mappedLabel) => mappedLabel !== label)\n };\n}\n\nasync function githubJson(input: {\n target: GitHubIssueMutationTarget;\n fetchImpl: FetchLike;\n method: \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\";\n path: string;\n body?: unknown;\n okStatuses?: number[];\n}): Promise<string | undefined> {\n const response = await input.fetchImpl(`https://api.github.com/repos/${input.target.owner}/${input.target.repo}${input.path}`, {\n method: input.method,\n headers: {\n accept: \"application/vnd.github+json\",\n authorization: `Bearer ${input.target.token}`,\n \"content-type\": \"application/json\",\n \"x-github-api-version\": \"2022-11-28\"\n },\n ...(input.body ? { body: JSON.stringify(input.body) } : {})\n });\n\n if (!response.ok && !(input.okStatuses ?? []).includes(response.status)) {\n throw new Error(`${input.method} ${input.path} failed: ${response.status} ${await response.text()}`);\n }\n return `https://github.com/${input.target.owner}/${input.target.repo}/issues/${input.target.issueNumber}`;\n}\n\nasync function githubJsonBody<T>(input: {\n target: GitHubIssueMutationTarget;\n fetchImpl: FetchLike;\n method: \"GET\";\n path: string;\n okStatuses?: number[];\n}): Promise<T> {\n const response = await input.fetchImpl(`https://api.github.com/repos/${input.target.owner}/${input.target.repo}${input.path}`, {\n method: input.method,\n headers: {\n accept: \"application/vnd.github+json\",\n authorization: `Bearer ${input.target.token}`,\n \"content-type\": \"application/json\",\n \"x-github-api-version\": \"2022-11-28\"\n }\n });\n\n if (!response.ok && !(input.okStatuses ?? []).includes(response.status)) {\n throw new Error(`${input.method} ${input.path} failed: ${response.status} ${await response.text()}`);\n }\n return await response.json() as T;\n}\n\ntype RequestedReviewersResponse = {\n users?: Array<{ login?: unknown }>;\n teams?: Array<{ slug?: unknown; name?: unknown }>;\n};\n\nfunction requestedReviewerLogins(response: RequestedReviewersResponse): Set<string> {\n return new Set((response.users ?? []).map((user) => user.login).filter((login): login is string => typeof login === \"string\"));\n}\n\nfunction requestedTeamReviewerNames(response: RequestedReviewersResponse): Set<string> {\n return new Set(\n (response.teams ?? [])\n .flatMap((team) => [team.slug, team.name])\n .filter((value): value is string => typeof value === \"string\" && value.length > 0)\n );\n}\n\nexport function compileGitHubIssueMutationIntent(\n intent: MutationIntent,\n options: { mappings?: AdapterMutationMapping[]; targetKind?: \"issue\" | \"pull_request\" } = {}\n): GitHubIssueMutationCompilation {\n if (intent.action === \"create_pull_request\") {\n const head = stringParam(intent, \"head\", \"branch\");\n if (!head) {\n return {\n ok: false,\n outcome: {\n intentId: intent.intentId,\n outcome: \"failed\",\n message: \"create_pull_request requires params.head or params.branch.\"\n }\n };\n }\n return {\n ok: true,\n intentId: intent.intentId,\n operation: {\n kind: \"create_pull_request\",\n intentId: intent.intentId,\n title: stringParam(intent, \"title\") ?? intent.summary,\n body: pullRequestBodyFromIntent(intent),\n head,\n base: stringParam(intent, \"base\", \"baseBranch\") ?? \"main\"\n }\n };\n }\n\n if (intent.action === \"request_review\" || intent.domain === \"review\") {\n if (options.targetKind !== \"pull_request\") {\n return {\n ok: false,\n outcome: {\n intentId: intent.intentId,\n outcome: \"unsupported\",\n message: \"GitHub review requests require a pull request target.\"\n }\n };\n }\n const reviewers = reviewersFromIntent(intent);\n const teamReviewers = teamReviewersFromIntent(intent);\n if (!reviewers?.length && !teamReviewers?.length) {\n return {\n ok: false,\n outcome: {\n intentId: intent.intentId,\n outcome: \"failed\",\n message: \"request_review requires params.reviewer, params.reviewers, or params.teamReviewers.\"\n }\n };\n }\n return {\n ok: true,\n intentId: intent.intentId,\n operation: {\n kind: \"request_review\",\n intentId: intent.intentId,\n reviewers: reviewers ?? [],\n ...(teamReviewers?.length ? { teamReviewers } : {})\n }\n };\n }\n\n if (intent.domain === \"status\") {\n const mapped = labelMappingForIntent({ intent, mappings: options.mappings ?? [] });\n if (mapped) {\n return { ok: true, intentId: intent.intentId, operation: { kind: \"replace_mapped_label\", intentId: intent.intentId, ...mapped } };\n }\n return {\n ok: false,\n outcome: {\n intentId: intent.intentId,\n outcome: \"unsupported\",\n message: \"GitHub status writes require an explicit Project field or label mapping policy.\"\n }\n };\n }\n if (intent.domain === \"priority\") {\n const mapped = labelMappingForIntent({ intent, mappings: options.mappings ?? [] });\n if (mapped) {\n return { ok: true, intentId: intent.intentId, operation: { kind: \"replace_mapped_label\", intentId: intent.intentId, ...mapped } };\n }\n return {\n ok: false,\n outcome: {\n intentId: intent.intentId,\n outcome: \"unsupported\",\n message: \"GitHub priority writes require an explicit label or Project field mapping policy.\"\n }\n };\n }\n if (intent.domain !== \"labels\" && intent.domain !== \"assignee\") {\n return {\n ok: false,\n outcome: {\n intentId: intent.intentId,\n outcome: \"unsupported\",\n message: `GitHub apply supports labels and assignee only, not ${intent.domain}.`\n }\n };\n }\n\n if (intent.domain === \"assignee\") {\n if (intent.action === \"set_assignee\") {\n const assignee = assigneeFromIntent(intent);\n return assignee\n ? { ok: true, intentId: intent.intentId, operation: { kind: \"set_assignees\", intentId: intent.intentId, assignees: [assignee] } }\n : { ok: false, outcome: { intentId: intent.intentId, outcome: \"failed\", message: \"set_assignee requires params.assignee.\" } };\n }\n if (intent.action === \"set_assignees\") {\n const assignees = assigneesFromIntent(intent);\n return assignees\n ? { ok: true, intentId: intent.intentId, operation: { kind: \"set_assignees\", intentId: intent.intentId, assignees } }\n : { ok: false, outcome: { intentId: intent.intentId, outcome: \"failed\", message: \"set_assignees requires params.assignees.\" } };\n }\n if (intent.action === \"add_assignee\") {\n const assignee = assigneeFromIntent(intent);\n return assignee\n ? { ok: true, intentId: intent.intentId, operation: { kind: \"add_assignee\", intentId: intent.intentId, assignee } }\n : { ok: false, outcome: { intentId: intent.intentId, outcome: \"failed\", message: \"add_assignee requires params.assignee.\" } };\n }\n if (intent.action === \"remove_assignee\") {\n const assignee = assigneeFromIntent(intent);\n return assignee\n ? { ok: true, intentId: intent.intentId, operation: { kind: \"remove_assignee\", intentId: intent.intentId, assignee } }\n : { ok: false, outcome: { intentId: intent.intentId, outcome: \"failed\", message: \"remove_assignee requires params.assignee.\" } };\n }\n return {\n ok: false,\n outcome: {\n intentId: intent.intentId,\n outcome: \"unsupported\",\n message: `GitHub apply does not support assignee action ${intent.action}.`\n }\n };\n }\n\n if (intent.action === \"add_label\") {\n const label = labelFromIntent(intent);\n return label\n ? { ok: true, intentId: intent.intentId, operation: { kind: \"add_label\", intentId: intent.intentId, label } }\n : { ok: false, outcome: { intentId: intent.intentId, outcome: \"failed\", message: \"add_label requires params.label.\" } };\n }\n if (intent.action === \"remove_label\") {\n const label = labelFromIntent(intent);\n return label\n ? { ok: true, intentId: intent.intentId, operation: { kind: \"remove_label\", intentId: intent.intentId, label } }\n : { ok: false, outcome: { intentId: intent.intentId, outcome: \"failed\", message: \"remove_label requires params.label.\" } };\n }\n if (intent.action === \"set_labels\") {\n const labels = labelsFromIntent(intent);\n return labels\n ? { ok: true, intentId: intent.intentId, operation: { kind: \"set_labels\", intentId: intent.intentId, labels } }\n : { ok: false, outcome: { intentId: intent.intentId, outcome: \"failed\", message: \"set_labels requires params.labels.\" } };\n }\n\n return {\n ok: false,\n outcome: {\n intentId: intent.intentId,\n outcome: \"unsupported\",\n message: `GitHub apply does not support labels action ${intent.action}.`\n }\n };\n}\n\nexport function compileGitHubIssueMutationIntents(\n intents: MutationIntent[],\n options: { mappings?: AdapterMutationMapping[]; targetKind?: \"issue\" | \"pull_request\" } = {}\n): GitHubIssueMutationCompilation[] {\n return intents.map((intent) => compileGitHubIssueMutationIntent(intent, options));\n}\n\nexport function createGitHubIssueMutationCompiler(options: {\n mappings?: AdapterMutationMapping[];\n targetKind?: \"issue\" | \"pull_request\";\n} = {}): AdapterMutationCompiler<GitHubIssueMutationOperation> {\n return {\n adapter: \"github\",\n compile(intent) {\n const compilation = compileGitHubIssueMutationIntent(intent, options);\n if (!compilation.ok) {\n return {\n ok: false,\n adapter: \"github\",\n outcome: compilation.outcome\n };\n }\n return {\n ok: true,\n adapter: \"github\",\n intentId: compilation.intentId,\n operation: compilation.operation\n };\n }\n };\n}\n\nexport async function applyGitHubIssueMutationOperation(input: {\n target: GitHubIssueMutationTarget;\n operation: GitHubIssueMutationOperation;\n fetchImpl?: FetchLike;\n}): Promise<ApplyIntentOutcome> {\n const fetchImpl = input.fetchImpl ?? fetch;\n try {\n if (input.operation.kind === \"create_pull_request\") {\n const externalUri = await createPullRequestViaFetch(\n {\n token: input.target.token,\n owner: input.target.owner,\n repo: input.target.repo,\n title: input.operation.title,\n body: input.operation.body,\n head: input.operation.head,\n base: input.operation.base\n },\n fetchImpl\n );\n return { intentId: input.operation.intentId, outcome: \"applied\", externalUri };\n }\n\n if (input.operation.kind === \"request_review\") {\n const pullRequestNumber = input.target.pullRequestNumber;\n if (typeof pullRequestNumber !== \"number\") {\n return {\n intentId: input.operation.intentId,\n outcome: \"failed\",\n message: \"request_review requires target.pullRequestNumber.\"\n };\n }\n const requested = await githubJsonBody<RequestedReviewersResponse>({\n target: input.target,\n fetchImpl,\n method: \"GET\",\n path: `/pulls/${pullRequestNumber}/requested_reviewers`\n });\n const existingReviewers = requestedReviewerLogins(requested);\n const existingTeamReviewers = requestedTeamReviewerNames(requested);\n const reviewers = input.operation.reviewers.filter((reviewer) => !existingReviewers.has(reviewer));\n const teamReviewers = input.operation.teamReviewers?.filter((reviewer) => !existingTeamReviewers.has(reviewer));\n if (reviewers.length === 0 && (!teamReviewers || teamReviewers.length === 0)) {\n return {\n intentId: input.operation.intentId,\n outcome: \"applied\",\n externalUri: `https://github.com/${input.target.owner}/${input.target.repo}/pull/${pullRequestNumber}`,\n message: \"Requested reviewers were already present; skipped GitHub notification retry.\"\n };\n }\n await githubJson({\n target: input.target,\n fetchImpl,\n method: \"POST\",\n path: `/pulls/${pullRequestNumber}/requested_reviewers`,\n body: {\n ...(reviewers.length ? { reviewers } : {}),\n ...(teamReviewers?.length ? { team_reviewers: teamReviewers } : {})\n }\n });\n return {\n intentId: input.operation.intentId,\n outcome: \"applied\",\n externalUri: `https://github.com/${input.target.owner}/${input.target.repo}/pull/${pullRequestNumber}`\n };\n }\n\n const issueNumber = input.target.issueNumber;\n if (typeof issueNumber !== \"number\") {\n return {\n intentId: input.operation.intentId,\n outcome: \"failed\",\n message: \"GitHub issue mutation requires target.issueNumber.\"\n };\n }\n\n if (input.operation.kind === \"set_assignees\") {\n const externalUri = await githubJson({\n target: input.target,\n fetchImpl,\n method: \"PATCH\",\n path: `/issues/${issueNumber}`,\n body: { assignees: input.operation.assignees }\n });\n return { intentId: input.operation.intentId, outcome: \"applied\", externalUri };\n }\n\n if (input.operation.kind === \"add_assignee\") {\n const externalUri = await githubJson({\n target: input.target,\n fetchImpl,\n method: \"POST\",\n path: `/issues/${issueNumber}/assignees`,\n body: { assignees: [input.operation.assignee] }\n });\n return { intentId: input.operation.intentId, outcome: \"applied\", externalUri };\n }\n\n if (input.operation.kind === \"remove_assignee\") {\n const externalUri = await githubJson({\n target: input.target,\n fetchImpl,\n method: \"DELETE\",\n path: `/issues/${issueNumber}/assignees`,\n body: { assignees: [input.operation.assignee] }\n });\n return { intentId: input.operation.intentId, outcome: \"applied\", externalUri };\n }\n\n if (input.operation.kind === \"replace_mapped_label\") {\n for (const label of input.operation.removeLabels) {\n await githubJson({\n target: input.target,\n fetchImpl,\n method: \"DELETE\",\n path: `/issues/${issueNumber}/labels/${encodeURIComponent(label)}`,\n okStatuses: [200, 404]\n });\n }\n const externalUri = await githubJson({\n target: input.target,\n fetchImpl,\n method: \"POST\",\n path: `/issues/${issueNumber}/labels`,\n body: { labels: [input.operation.label] }\n });\n return { intentId: input.operation.intentId, outcome: \"applied\", externalUri };\n }\n\n if (input.operation.kind === \"add_label\") {\n const externalUri = await githubJson({\n target: input.target,\n fetchImpl,\n method: \"POST\",\n path: `/issues/${issueNumber}/labels`,\n body: { labels: [input.operation.label] }\n });\n return { intentId: input.operation.intentId, outcome: \"applied\", externalUri };\n }\n\n if (input.operation.kind === \"remove_label\") {\n const externalUri = await githubJson({\n target: input.target,\n fetchImpl,\n method: \"DELETE\",\n path: `/issues/${issueNumber}/labels/${encodeURIComponent(input.operation.label)}`\n });\n return { intentId: input.operation.intentId, outcome: \"applied\", externalUri };\n }\n\n const externalUri = await githubJson({\n target: input.target,\n fetchImpl,\n method: \"PUT\",\n path: `/issues/${issueNumber}/labels`,\n body: { labels: input.operation.labels }\n });\n return { intentId: input.operation.intentId, outcome: \"applied\", externalUri };\n } catch (error) {\n return {\n intentId: input.operation.intentId,\n outcome: \"failed\",\n error: error instanceof Error ? error.message : String(error)\n };\n }\n}\n\nexport async function applyGitHubIssueMutationIntent(input: {\n target: GitHubIssueMutationTarget;\n intent: MutationIntent;\n mappings?: AdapterMutationMapping[];\n targetKind?: \"issue\" | \"pull_request\";\n fetchImpl?: FetchLike;\n}): Promise<ApplyIntentOutcome> {\n const compiled = compileGitHubIssueMutationIntent(input.intent, {\n ...(input.mappings ? { mappings: input.mappings } : {}),\n ...(input.targetKind ? { targetKind: input.targetKind } : {})\n });\n if (!compiled.ok) return compiled.outcome;\n return applyGitHubIssueMutationOperation({\n target: input.target,\n operation: compiled.operation,\n ...(input.fetchImpl ? { fetchImpl: input.fetchImpl } : {})\n });\n}\n\nexport async function applyGitHubIssueMutationIntents(input: {\n target: GitHubIssueMutationTarget;\n intents: MutationIntent[];\n mappings?: AdapterMutationMapping[];\n targetKind?: \"issue\" | \"pull_request\";\n fetchImpl?: FetchLike;\n}): Promise<ApplyIntentOutcome[]> {\n const outcomes: ApplyIntentOutcome[] = [];\n for (const intent of input.intents) {\n outcomes.push(\n await applyGitHubIssueMutationIntent({\n target: input.target,\n intent,\n ...(input.mappings ? { mappings: input.mappings } : {}),\n ...(input.targetKind ? { targetKind: input.targetKind } : {}),\n ...(input.fetchImpl ? { fetchImpl: input.fetchImpl } : {})\n })\n );\n }\n return outcomes;\n}\n","import { createHmac, randomUUID, timingSafeEqual } from \"node:crypto\";\nimport { serve } from \"@hono/node-server\";\nimport { createOpenTagClient } from \"@opentag/client\";\nimport { parseThreadActionCommand, type OpenTagEvent } from \"@opentag/core\";\nimport { Hono } from \"hono\";\nimport { normalizeGitHubIssueComment, normalizeGitHubPullRequestReviewComment } from \"./normalize.js\";\n\ntype GitHubActor = {\n id: number;\n login: string;\n};\n\ntype GitHubRepository = {\n name: string;\n private: boolean;\n owner: { login: string };\n};\n\nexport type GitHubIssueCommentPayload = {\n action?: string;\n comment: { id: number; body: string; html_url: string };\n issue: { html_url: string; comments_url: string; number: number };\n repository: GitHubRepository;\n sender: GitHubActor;\n installation?: { id: number };\n};\n\nexport type GitHubPullRequestReviewCommentPayload = {\n action?: string;\n comment: { id: number; body: string; html_url: string };\n pull_request: { html_url: string; number: number };\n repository: GitHubRepository;\n sender: GitHubActor;\n installation?: { id: number };\n};\n\nexport type GitHubThreadActionInput = {\n id: string;\n rawText: string;\n actor: {\n provider: \"github\";\n providerUserId: string;\n handle: string;\n };\n callback: {\n provider: \"github\";\n uri: string;\n threadKey: string;\n };\n metadata: Record<string, unknown>;\n};\n\nexport type GitHubWebhookAppInput = {\n webhookSecret: string;\n webhookPath?: string;\n createRun(event: OpenTagEvent): Promise<{ runId?: string }>;\n submitThreadAction?(action: GitHubThreadActionInput): Promise<unknown>;\n now(): string;\n};\n\nexport type GitHubIngressConfig = {\n webhookSecret: string;\n dispatcherUrl: string;\n dispatcherToken?: string;\n port?: number;\n hostname?: string;\n webhookPath?: string;\n};\n\nexport type GitHubIngressHandle = {\n url: string;\n webhookPath: string;\n server: ReturnType<typeof serve>;\n close(): Promise<void>;\n};\n\nexport function computeGitHubSignature(input: { webhookSecret: string; rawBody: string }): string {\n const digest = createHmac(\"sha256\", input.webhookSecret).update(input.rawBody).digest(\"hex\");\n return `sha256=${digest}`;\n}\n\nexport function verifyGitHubSignature(input: {\n webhookSecret: string;\n rawBody: string;\n signature: string;\n}): boolean {\n const expected = computeGitHubSignature(input);\n const expectedBuffer = Buffer.from(expected);\n const actualBuffer = Buffer.from(input.signature);\n return expectedBuffer.length === actualBuffer.length && timingSafeEqual(expectedBuffer, actualBuffer);\n}\n\nfunction parseJsonPayload(rawBody: string): unknown {\n try {\n return JSON.parse(rawBody);\n } catch {\n return null;\n }\n}\n\nasync function handleIssueCommentCreated(input: {\n payload: GitHubIssueCommentPayload;\n createRun(event: OpenTagEvent): Promise<{ runId?: string }>;\n submitThreadAction?(action: GitHubThreadActionInput): Promise<unknown>;\n now(): string;\n}): Promise<void> {\n if (input.payload.action && input.payload.action !== \"created\") return;\n if (parseThreadActionCommand(input.payload.comment.body) && input.submitThreadAction) {\n await input.submitThreadAction({\n id: `approval_github_comment_${input.payload.comment.id}`,\n rawText: input.payload.comment.body,\n actor: {\n provider: \"github\",\n providerUserId: String(input.payload.sender.id),\n handle: input.payload.sender.login\n },\n callback: {\n provider: \"github\",\n uri: input.payload.issue.comments_url,\n threadKey: `${input.payload.repository.owner.login}/${input.payload.repository.name}#${input.payload.issue.number}`\n },\n metadata: {\n repoProvider: \"github\",\n owner: input.payload.repository.owner.login,\n repo: input.payload.repository.name,\n issueNumber: input.payload.issue.number,\n commentUrl: input.payload.comment.html_url\n }\n });\n return;\n }\n\n const event = normalizeGitHubIssueComment({\n id: String(input.payload.comment.id),\n commentBody: input.payload.comment.body,\n commentUrl: input.payload.comment.html_url,\n apiCommentsUrl: input.payload.issue.comments_url,\n issueUrl: input.payload.issue.html_url,\n issueNumber: input.payload.issue.number,\n owner: input.payload.repository.owner.login,\n repo: input.payload.repository.name,\n actorId: input.payload.sender.id,\n actorLogin: input.payload.sender.login,\n private: input.payload.repository.private,\n receivedAt: input.now(),\n ...(input.payload.installation ? { installationId: input.payload.installation.id } : {})\n });\n\n if (event) {\n await input.createRun(event);\n }\n}\n\nasync function handlePullRequestReviewCommentCreated(input: {\n payload: GitHubPullRequestReviewCommentPayload;\n createRun(event: OpenTagEvent): Promise<{ runId?: string }>;\n submitThreadAction?(action: GitHubThreadActionInput): Promise<unknown>;\n now(): string;\n}): Promise<void> {\n if (input.payload.action && input.payload.action !== \"created\") return;\n const owner = input.payload.repository.owner.login;\n const repo = input.payload.repository.name;\n if (parseThreadActionCommand(input.payload.comment.body) && input.submitThreadAction) {\n await input.submitThreadAction({\n id: `approval_github_pr_review_comment_${input.payload.comment.id}`,\n rawText: input.payload.comment.body,\n actor: {\n provider: \"github\",\n providerUserId: String(input.payload.sender.id),\n handle: input.payload.sender.login\n },\n callback: {\n provider: \"github\",\n uri: `https://api.github.com/repos/${owner}/${repo}/issues/${input.payload.pull_request.number}/comments`,\n threadKey: `${owner}/${repo}#${input.payload.pull_request.number}`\n },\n metadata: {\n repoProvider: \"github\",\n owner,\n repo,\n pullRequestNumber: input.payload.pull_request.number,\n commentUrl: input.payload.comment.html_url\n }\n });\n return;\n }\n\n const event = normalizeGitHubPullRequestReviewComment({\n id: String(input.payload.comment.id),\n commentBody: input.payload.comment.body,\n commentUrl: input.payload.comment.html_url,\n pullRequestUrl: input.payload.pull_request.html_url,\n apiCommentsUrl: `https://api.github.com/repos/${owner}/${repo}/issues/${input.payload.pull_request.number}/comments`,\n owner,\n repo,\n pullRequestNumber: input.payload.pull_request.number,\n actorId: input.payload.sender.id,\n actorLogin: input.payload.sender.login,\n private: input.payload.repository.private,\n receivedAt: input.now(),\n ...(input.payload.installation ? { installationId: input.payload.installation.id } : {})\n });\n\n if (event) {\n await input.createRun(event);\n }\n}\n\nexport function createGitHubWebhookApp(input: GitHubWebhookAppInput) {\n const app = new Hono();\n const webhookPath = input.webhookPath ?? \"/github/webhooks\";\n if (!webhookPath.startsWith(\"/\")) {\n throw new Error(\"GitHub webhook path must start with /.\");\n }\n\n app.post(webhookPath, async (c) => {\n const signature = c.req.header(\"x-hub-signature-256\");\n if (!signature) {\n return c.json({ error: \"missing_signature_header\" }, 401);\n }\n const rawBody = await c.req.text();\n if (!verifyGitHubSignature({ webhookSecret: input.webhookSecret, rawBody, signature })) {\n return c.json({ error: \"invalid_signature\" }, 401);\n }\n\n const eventName = c.req.header(\"x-github-event\");\n const payload = parseJsonPayload(rawBody);\n if (!payload || typeof payload !== \"object\") {\n return c.json({ error: \"invalid_json\" }, 400);\n }\n\n if (eventName === \"ping\") {\n return c.json({ ok: true });\n }\n if (eventName === \"issue_comment\") {\n await handleIssueCommentCreated({\n payload: payload as GitHubIssueCommentPayload,\n createRun: input.createRun,\n ...(input.submitThreadAction ? { submitThreadAction: input.submitThreadAction } : {}),\n now: input.now\n });\n return c.json({ ok: true });\n }\n if (eventName === \"pull_request_review_comment\") {\n await handlePullRequestReviewCommentCreated({\n payload: payload as GitHubPullRequestReviewCommentPayload,\n createRun: input.createRun,\n ...(input.submitThreadAction ? { submitThreadAction: input.submitThreadAction } : {}),\n now: input.now\n });\n return c.json({ ok: true });\n }\n\n return c.json({ ok: true, ignored: \"unsupported_event\" });\n });\n\n return app;\n}\n\nexport function startGitHubIngress(config: GitHubIngressConfig): GitHubIngressHandle {\n const dispatcherClient = createOpenTagClient({\n dispatcherUrl: config.dispatcherUrl,\n ...(config.dispatcherToken ? { pairingToken: config.dispatcherToken } : {})\n });\n const port = config.port ?? 3000;\n const hostname = config.hostname ?? \"127.0.0.1\";\n const webhookPath = config.webhookPath ?? \"/github/webhooks\";\n const server = serve({\n fetch: createGitHubWebhookApp({\n webhookSecret: config.webhookSecret,\n webhookPath,\n async createRun(event) {\n const runId = `run_${randomUUID()}`;\n const created = await dispatcherClient.createRun({ runId, event });\n return created.outcome === \"run_created\" ? { runId: created.run.id } : {};\n },\n async submitThreadAction(action) {\n await dispatcherClient.submitThreadAction(action);\n },\n now: () => new Date().toISOString()\n }).fetch,\n port,\n hostname\n });\n\n return {\n url: `http://${hostname}:${port}`,\n webhookPath,\n server,\n close() {\n return new Promise((resolve, reject) => {\n server.close((error?: Error) => {\n if (error) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n }\n };\n}\n","import { parseOpenTagMention, type OpenTagEvent } from \"@opentag/core\";\nimport type { ContextPointer, OpenTagCommand, PermissionGrant, WorkItemReference } from \"@opentag/core\";\n\nexport type GitHubIssueCommentInput = {\n id: string;\n commentBody: string;\n commentUrl: string;\n apiCommentsUrl: string;\n issueUrl: string;\n issueNumber: number;\n owner: string;\n repo: string;\n actorId: number;\n actorLogin: string;\n private: boolean;\n receivedAt: string;\n installationId?: number;\n};\n\nexport type GitHubPullRequestReviewCommentInput = {\n id: string;\n commentBody: string;\n commentUrl: string;\n pullRequestUrl: string;\n apiCommentsUrl: string;\n owner: string;\n repo: string;\n pullRequestNumber: number;\n actorId: number;\n actorLogin: string;\n private: boolean;\n receivedAt: string;\n installationId?: number;\n};\n\nfunction permissionsForIntent(intent: OpenTagCommand[\"intent\"]): PermissionGrant[] {\n const permissions: PermissionGrant[] = [\n {\n scope: \"issue:comment\",\n reason: \"reply to the source GitHub thread\"\n },\n {\n scope: \"runner:local\",\n reason: \"execute the run on a paired local daemon\"\n }\n ];\n if (intent === \"fix\" || intent === \"run\") {\n permissions.push(\n {\n scope: \"repo:read\",\n reason: \"inspect the repository in the paired local checkout\"\n },\n {\n scope: \"repo:write\",\n reason: \"commit code changes on an isolated run branch\"\n },\n {\n scope: \"pr:create\",\n reason: \"open a pull request for completed code changes\"\n }\n );\n }\n return permissions;\n}\n\nfunction permissionsForPullRequestReviewCommentIntent(intent: OpenTagCommand[\"intent\"]): PermissionGrant[] {\n const permissions = permissionsForIntent(intent);\n if (intent === \"review\") {\n permissions.push({\n scope: \"pr:update\",\n reason: \"request reviewers on the source pull request after explicit approval\"\n });\n }\n return permissions;\n}\n\nfunction contextPointersForCommand(command: OpenTagCommand, privateRepo: boolean): ContextPointer[] {\n const visibility = privateRepo ? \"private\" : \"public\";\n const context: ContextPointer[] = [];\n\n for (const reference of command.parsed?.references ?? []) {\n if (reference.kind === \"url\") {\n context.push({\n kind: \"url\",\n uri: reference.uri,\n visibility,\n title: reference.title ?? \"Command URL reference\"\n });\n continue;\n }\n\n if (reference.kind === \"file\" || reference.kind === \"path\" || reference.kind === \"line\" || reference.kind === \"range\") {\n context.push({\n kind: \"file\",\n uri: reference.uri,\n ...(reference.line ? { line: reference.line } : {}),\n ...(reference.startLine ? { startLine: reference.startLine } : {}),\n ...(reference.endLine ? { endLine: reference.endLine } : {}),\n visibility,\n title: referenceTitle(reference)\n });\n }\n }\n\n return context;\n}\n\nfunction referenceTitle(reference: NonNullable<OpenTagCommand[\"parsed\"]>[\"references\"][number]): string {\n return reference.title ?? \"Command file reference\";\n}\n\nfunction githubWorkItem(input: {\n owner: string;\n repo: string;\n kind: \"issue\" | \"pull_request\";\n number: number;\n uri: string;\n}): WorkItemReference {\n return {\n provider: \"github\",\n kind: input.kind,\n externalId: `${input.owner}/${input.repo}#${input.number}`,\n uri: input.uri,\n ownerContainer: {\n provider: \"github\",\n id: `${input.owner}/${input.repo}`,\n uri: `https://github.com/${input.owner}/${input.repo}`\n }\n };\n}\n\nfunction commandMetadata(command: OpenTagCommand): Record<string, unknown> {\n if (!command.parsed) return {};\n return {\n commandParser: command.parsed.version,\n commandDiagnostics: command.parsed.diagnostics,\n ...(command.parsed.approval ? { approval: command.parsed.approval } : {}),\n ...(command.parsed.network ? { network: command.parsed.network } : {})\n };\n}\n\nexport function normalizeGitHubIssueComment(input: GitHubIssueCommentInput): OpenTagEvent | null {\n const mention = parseOpenTagMention(input.commentBody);\n if (!mention.matched) return null;\n\n const command = {\n rawText: mention.rawText,\n intent: mention.intent,\n args: mention.args,\n ...(mention.parsed ? { parsed: mention.parsed } : {})\n };\n\n return {\n id: `evt_github_comment_${input.id}`,\n source: \"github\",\n sourceEventId: input.id,\n receivedAt: input.receivedAt,\n actor: {\n provider: \"github\",\n providerUserId: String(input.actorId),\n handle: input.actorLogin\n },\n target: {\n mention: \"@opentag\",\n agentId: \"opentag\",\n ...(mention.parsed?.executorHint ? { executorHint: mention.parsed.executorHint } : {})\n },\n command,\n context: [\n {\n provider: \"github\",\n kind: \"issue\",\n uri: input.issueUrl,\n visibility: input.private ? \"private\" : \"public\"\n },\n {\n provider: \"github\",\n kind: \"comment\",\n uri: input.commentUrl,\n visibility: input.private ? \"private\" : \"public\"\n },\n ...contextPointersForCommand(command, input.private)\n ],\n workItem: githubWorkItem({\n owner: input.owner,\n repo: input.repo,\n kind: \"issue\",\n number: input.issueNumber,\n uri: input.issueUrl\n }),\n permissions: permissionsForIntent(mention.intent),\n callback: {\n provider: \"github\",\n uri: input.apiCommentsUrl,\n threadKey: `${input.owner}/${input.repo}#${input.issueNumber}`\n },\n metadata: {\n repoProvider: \"github\",\n owner: input.owner,\n repo: input.repo,\n issueNumber: input.issueNumber,\n ...commandMetadata(command),\n ...(typeof input.installationId === \"number\" ? { installationId: input.installationId } : {})\n }\n };\n}\n\nexport function normalizeGitHubPullRequestReviewComment(input: GitHubPullRequestReviewCommentInput): OpenTagEvent | null {\n const mention = parseOpenTagMention(input.commentBody);\n if (!mention.matched) return null;\n\n const command = {\n rawText: mention.rawText,\n intent: mention.intent,\n args: mention.args,\n ...(mention.parsed ? { parsed: mention.parsed } : {})\n };\n\n return {\n id: `evt_github_pr_review_comment_${input.id}`,\n source: \"github\",\n sourceEventId: input.id,\n receivedAt: input.receivedAt,\n actor: {\n provider: \"github\",\n providerUserId: String(input.actorId),\n handle: input.actorLogin\n },\n target: {\n mention: \"@opentag\",\n agentId: \"opentag\",\n ...(mention.parsed?.executorHint ? { executorHint: mention.parsed.executorHint } : {})\n },\n command,\n context: [\n {\n provider: \"github\",\n kind: \"pull_request\",\n uri: input.pullRequestUrl,\n visibility: input.private ? \"private\" : \"public\"\n },\n {\n provider: \"github\",\n kind: \"comment\",\n uri: input.commentUrl,\n visibility: input.private ? \"private\" : \"public\"\n },\n ...contextPointersForCommand(command, input.private)\n ],\n workItem: githubWorkItem({\n owner: input.owner,\n repo: input.repo,\n kind: \"pull_request\",\n number: input.pullRequestNumber,\n uri: input.pullRequestUrl\n }),\n permissions: permissionsForPullRequestReviewCommentIntent(mention.intent),\n callback: {\n provider: \"github\",\n uri: input.apiCommentsUrl,\n threadKey: `${input.owner}/${input.repo}#${input.pullRequestNumber}`\n },\n metadata: {\n repoProvider: \"github\",\n owner: input.owner,\n repo: input.repo,\n pullRequestNumber: input.pullRequestNumber,\n ...commandMetadata(command),\n ...(typeof input.installationId === \"number\" ? { installationId: input.installationId } : {})\n }\n };\n}\n","import { suggestedActionCandidatesFromResult, type OpenTagRunResult } from \"@opentag/core\";\n\nfunction nextActionSummary(result: OpenTagRunResult): string | undefined {\n if (!result.nextAction) return undefined;\n if (typeof result.nextAction === \"string\") return result.nextAction;\n return result.nextAction.summary;\n}\n\nfunction stringParam(params: Record<string, unknown> | undefined, key: string): string | undefined {\n const value = params?.[key];\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\nfunction stringArrayParam(params: Record<string, unknown> | undefined, key: string): string[] {\n const value = params?.[key];\n if (!Array.isArray(value)) return [];\n return value.filter((item): item is string => typeof item === \"string\" && item.length > 0);\n}\n\nfunction renderVerificationParams(params: Record<string, unknown> | undefined): string[] {\n const value = params?.[\"verification\"];\n if (!Array.isArray(value)) return [];\n return value\n .map((item) => {\n if (!item || typeof item !== \"object\" || Array.isArray(item)) return undefined;\n const command = (item as Record<string, unknown>)[\"command\"];\n const outcome = (item as Record<string, unknown>)[\"outcome\"];\n const summary = (item as Record<string, unknown>)[\"summary\"];\n if (typeof outcome !== \"string\") return undefined;\n const prefix = typeof command === \"string\" && command.length > 0 ? `\\`${command}\\`: ${outcome}` : outcome;\n return typeof summary === \"string\" && summary.length > 0 ? ` - ${prefix} - ${summary}` : ` - ${prefix}`;\n })\n .filter((line): line is string => Boolean(line));\n}\n\nfunction renderSuggestedActionDetails(params: Record<string, unknown> | undefined, action: string): string[] {\n if (action !== \"create_pull_request\") return [];\n const lines: string[] = [];\n const title = stringParam(params, \"title\");\n const head = stringParam(params, \"head\") ?? stringParam(params, \"branch\");\n const base = stringParam(params, \"base\") ?? stringParam(params, \"baseBranch\");\n const changedFiles = stringArrayParam(params, \"changedFiles\");\n const risks = stringArrayParam(params, \"risks\");\n const verification = renderVerificationParams(params);\n if (title) lines.push(`- Title: ${title}`);\n if (head || base) lines.push(`- Branch: \\`${head ?? \"unknown\"}\\` -> \\`${base ?? \"main\"}\\``);\n if (changedFiles.length > 0) lines.push(`- Changed files: ${changedFiles.map((file) => `\\`${file}\\``).join(\", \")}`);\n if (risks.length > 0) {\n lines.push(\"- Risks:\");\n for (const risk of risks) {\n lines.push(` - ${risk}`);\n }\n }\n if (verification.length > 0) {\n lines.push(\"- Verification:\");\n lines.push(...verification);\n }\n return lines;\n}\n\nfunction renderSuggestedActions(result: OpenTagRunResult): string[] {\n const candidates = suggestedActionCandidatesFromResult(result);\n if (candidates.length === 0) return [];\n\n const lines = [\n \"### Suggested actions:\",\n \"\",\n \"Source-thread approval: choose one command in this GitHub thread to apply a protocolized mutation or PR action to the system of record.\"\n ];\n for (const candidate of candidates) {\n lines.push(\n \"\",\n `#### Action ${candidate.index}: ${candidate.intent.summary}`,\n \"\",\n `- System-of-record action: \\`${candidate.intent.action}\\` (\\`${candidate.intent.domain}\\`)`,\n `- Proposal: \\`${candidate.proposalId}\\``,\n `- Intent ID: \\`${candidate.intent.intentId}\\``\n );\n lines.push(...renderSuggestedActionDetails(candidate.intent.params, candidate.intent.action));\n if (candidate.proposalPreconditions?.length) {\n lines.push(\"- Preconditions:\");\n for (const precondition of candidate.proposalPreconditions) {\n lines.push(` - ${precondition}`);\n }\n }\n lines.push(\n \"\",\n \"**Approve in this thread**\",\n \"\",\n `| Decision | Comment command | Effect |`,\n `| --- | --- | --- |`,\n `| Apply now | \\`apply ${candidate.index}\\` | Applies this action to the system of record. |`,\n `| Approve only | \\`approve ${candidate.index}\\` | Records approval without applying yet. |`,\n `| Continue | \\`continue ${candidate.index}\\` | Starts a follow-up run from this proposal. |`,\n `| Reject | \\`reject ${candidate.index}\\` | Rejects this action. |`\n );\n }\n\n lines.push(\"\", \"Bulk shortcut: comment `apply all` to apply every supported approved action in this thread.\");\n return lines;\n}\n\nexport function renderAcknowledgement(runId: string): string {\n return `OpenTag picked this up. Run: \\`${runId}\\``;\n}\n\nexport function renderProgress(input: { runId: string; message: string }): string {\n return `OpenTag progress for \\`${input.runId}\\`: ${input.message}`;\n}\n\nexport function renderFinalResult(result: OpenTagRunResult): string {\n const lines = [`OpenTag finished with **${result.conclusion}**.`, \"\", result.summary];\n\n if (result.verification?.length) {\n lines.push(\"\", \"Verification:\");\n for (const check of result.verification) {\n lines.push(`- \\`${check.command}\\`: ${check.outcome}`);\n }\n }\n\n const nextAction = nextActionSummary(result);\n if (nextAction) {\n lines.push(\"\", `Next action: ${nextAction}`);\n }\n\n const suggestedActions = renderSuggestedActions(result);\n if (suggestedActions.length > 0) {\n lines.push(\"\", ...suggestedActions);\n }\n\n return lines.join(\"\\n\");\n}\n"],"mappings":"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","names":["externalUri","stringParam","stringArrayParam"]}
|
|
1
|
+
{"version":3,"sources":["../src/pull-request.ts","../src/apply.ts","../src/ingress.ts","../src/normalize.ts","../src/render.ts"],"sourcesContent":["import type { OpenTagRunResult } from \"@opentag/core\";\n\nexport type CreatePullRequestInput = {\n token: string;\n owner: string;\n repo: string;\n title: string;\n body: string;\n head: string;\n base: string;\n};\n\nexport type FetchLike = typeof fetch;\n\nexport function buildPullRequestBody(result: OpenTagRunResult): string {\n const lines = [\"## Summary\", \"\", result.summary];\n\n if (result.changedFiles?.length) {\n lines.push(\"\", \"## Changed Files\");\n for (const file of result.changedFiles) {\n lines.push(`- \\`${file}\\``);\n }\n }\n\n if (result.verification?.length) {\n lines.push(\"\", \"## Verification\");\n for (const check of result.verification) {\n lines.push(`- \\`${check.command}\\`: ${check.outcome}`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n\nexport async function createPullRequestViaFetch(input: CreatePullRequestInput, fetchImpl: FetchLike = fetch): Promise<string> {\n const response = await fetchImpl(`https://api.github.com/repos/${input.owner}/${input.repo}/pulls`, {\n method: \"POST\",\n headers: {\n accept: \"application/vnd.github+json\",\n authorization: `Bearer ${input.token}`,\n \"content-type\": \"application/json\",\n \"x-github-api-version\": \"2022-11-28\"\n },\n body: JSON.stringify({\n title: input.title,\n body: input.body,\n head: input.head,\n base: input.base\n })\n });\n\n if (!response.ok) {\n throw new Error(`create pull request failed: ${response.status} ${await response.text()}`);\n }\n\n const body = (await response.json()) as { html_url?: string };\n if (!body.html_url) {\n throw new Error(\"create pull request response did not include html_url\");\n }\n return body.html_url;\n}\n","import type { AdapterMutationCompiler, AdapterMutationMapping, ApplyIntentOutcome, MutationIntent } from \"@opentag/core\";\nimport { createPullRequestViaFetch, type FetchLike } from \"./pull-request.js\";\n\nexport type GitHubIssueMutationTarget = {\n token: string;\n owner: string;\n repo: string;\n issueNumber?: number;\n pullRequestNumber?: number;\n};\n\nexport type GitHubIssueMutationOperation =\n | {\n kind: \"add_label\";\n intentId: string;\n label: string;\n }\n | {\n kind: \"remove_label\";\n intentId: string;\n label: string;\n }\n | {\n kind: \"replace_mapped_label\";\n intentId: string;\n label: string;\n removeLabels: string[];\n }\n | {\n kind: \"set_labels\";\n intentId: string;\n labels: string[];\n }\n | {\n kind: \"set_assignees\";\n intentId: string;\n assignees: string[];\n }\n | {\n kind: \"add_assignee\";\n intentId: string;\n assignee: string;\n }\n | {\n kind: \"remove_assignee\";\n intentId: string;\n assignee: string;\n }\n | {\n kind: \"request_review\";\n intentId: string;\n reviewers: string[];\n teamReviewers?: string[];\n }\n | {\n kind: \"create_pull_request\";\n intentId: string;\n title: string;\n body: string;\n head: string;\n base: string;\n };\n\nexport type GitHubIssueMutationCompilation =\n | {\n ok: true;\n intentId: string;\n operation: GitHubIssueMutationOperation;\n }\n | {\n ok: false;\n outcome: ApplyIntentOutcome;\n };\n\nfunction labelFromIntent(intent: MutationIntent): string | undefined {\n const value = intent.params?.[\"label\"];\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\nfunction labelsFromIntent(intent: MutationIntent): string[] | undefined {\n const value = intent.params?.[\"labels\"];\n if (!Array.isArray(value)) return undefined;\n const labels = value.filter((label): label is string => typeof label === \"string\" && label.length > 0);\n return labels.length > 0 ? labels : undefined;\n}\n\nfunction assigneeFromIntent(intent: MutationIntent): string | undefined {\n const value = intent.params?.[\"assignee\"];\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\nfunction assigneesFromIntent(intent: MutationIntent): string[] | undefined {\n const value = intent.params?.[\"assignees\"];\n if (!Array.isArray(value)) return undefined;\n const assignees = value.filter((assignee): assignee is string => typeof assignee === \"string\" && assignee.length > 0);\n return assignees.length > 0 ? assignees : undefined;\n}\n\nfunction reviewersFromIntent(intent: MutationIntent): string[] | undefined {\n const reviewer = intent.params?.[\"reviewer\"];\n const reviewers = intent.params?.[\"reviewers\"];\n const values = [\n ...(typeof reviewer === \"string\" ? [reviewer] : []),\n ...(Array.isArray(reviewers) ? reviewers : [])\n ].filter((value): value is string => typeof value === \"string\" && value.length > 0);\n return values.length > 0 ? [...new Set(values)] : undefined;\n}\n\nfunction teamReviewersFromIntent(intent: MutationIntent): string[] | undefined {\n const reviewer = intent.params?.[\"teamReviewer\"];\n const reviewers = intent.params?.[\"teamReviewers\"] ?? intent.params?.[\"team_reviewers\"];\n const values = [\n ...(typeof reviewer === \"string\" ? [reviewer] : []),\n ...(Array.isArray(reviewers) ? reviewers : [])\n ].filter((value): value is string => typeof value === \"string\" && value.length > 0);\n return values.length > 0 ? [...new Set(values)] : undefined;\n}\n\nfunction stringParam(intent: MutationIntent, ...keys: string[]): string | undefined {\n for (const key of keys) {\n const value = intent.params?.[key];\n if (typeof value === \"string\" && value.length > 0) return value;\n }\n return undefined;\n}\n\nfunction stringArrayParam(intent: MutationIntent, key: string): string[] {\n const value = intent.params?.[key];\n if (!Array.isArray(value)) return [];\n return value.filter((item): item is string => typeof item === \"string\" && item.length > 0);\n}\n\nfunction verificationLinesFromIntent(intent: MutationIntent): string[] {\n const value = intent.params?.[\"verification\"];\n if (!Array.isArray(value)) return [];\n return value\n .map((item) => {\n if (!item || typeof item !== \"object\" || Array.isArray(item)) return undefined;\n const command = (item as Record<string, unknown>)[\"command\"];\n const outcome = (item as Record<string, unknown>)[\"outcome\"];\n return typeof command === \"string\" && typeof outcome === \"string\" ? `- \\`${command}\\`: ${outcome}` : undefined;\n })\n .filter((line): line is string => Boolean(line));\n}\n\nfunction pullRequestBodyFromIntent(intent: MutationIntent): string {\n const explicitBody = stringParam(intent, \"body\");\n const changedFiles = stringArrayParam(intent, \"changedFiles\");\n const risks = stringArrayParam(intent, \"risks\");\n const verification = verificationLinesFromIntent(intent);\n const executorConditions = stringArrayParam(intent, \"executorConditions\");\n const lines = explicitBody ? [explicitBody] : [\"## Summary\", \"\", intent.summary];\n if (changedFiles.length > 0) {\n lines.push(\"\", \"## Changed Files\", ...changedFiles.map((file) => `- \\`${file}\\``));\n }\n if (risks.length > 0) {\n lines.push(\"\", \"## Risks\", ...risks.map((risk) => `- ${risk}`));\n }\n if (verification.length > 0) {\n lines.push(\"\", \"## Verification\", ...verification);\n }\n if (executorConditions.length > 0) {\n lines.push(\"\", \"## Executor Conditions\", ...executorConditions.map((condition) => `- ${condition}`));\n }\n return lines.join(\"\\n\");\n}\n\nfunction mappedValueFromIntent(intent: MutationIntent): string | undefined {\n const key = intent.domain === \"status\" ? \"status\" : \"priority\";\n const value = intent.params?.[key] ?? intent.params?.[\"value\"];\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\nfunction labelMappingForIntent(input: { intent: MutationIntent; mappings: AdapterMutationMapping[] }): { label: string; removeLabels: string[] } | undefined {\n const semanticValue = mappedValueFromIntent(input.intent);\n if (!semanticValue) return undefined;\n const mapping = input.mappings.find(\n (candidate) => candidate.adapter === \"github\" && candidate.domain === input.intent.domain && candidate.strategy === \"label\"\n );\n const label = mapping?.values[semanticValue];\n if (!label || !mapping) return undefined;\n return {\n label,\n removeLabels: Object.values(mapping.values).filter((mappedLabel) => mappedLabel !== label)\n };\n}\n\nasync function githubJson(input: {\n target: GitHubIssueMutationTarget;\n fetchImpl: FetchLike;\n method: \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\";\n path: string;\n body?: unknown;\n okStatuses?: number[];\n}): Promise<string | undefined> {\n const response = await input.fetchImpl(`https://api.github.com/repos/${input.target.owner}/${input.target.repo}${input.path}`, {\n method: input.method,\n headers: {\n accept: \"application/vnd.github+json\",\n authorization: `Bearer ${input.target.token}`,\n \"content-type\": \"application/json\",\n \"x-github-api-version\": \"2022-11-28\"\n },\n ...(input.body ? { body: JSON.stringify(input.body) } : {})\n });\n\n if (!response.ok && !(input.okStatuses ?? []).includes(response.status)) {\n throw new Error(`${input.method} ${input.path} failed: ${response.status} ${await response.text()}`);\n }\n return `https://github.com/${input.target.owner}/${input.target.repo}/issues/${input.target.issueNumber}`;\n}\n\nasync function githubJsonBody<T>(input: {\n target: GitHubIssueMutationTarget;\n fetchImpl: FetchLike;\n method: \"GET\";\n path: string;\n okStatuses?: number[];\n}): Promise<T> {\n const response = await input.fetchImpl(`https://api.github.com/repos/${input.target.owner}/${input.target.repo}${input.path}`, {\n method: input.method,\n headers: {\n accept: \"application/vnd.github+json\",\n authorization: `Bearer ${input.target.token}`,\n \"content-type\": \"application/json\",\n \"x-github-api-version\": \"2022-11-28\"\n }\n });\n\n if (!response.ok && !(input.okStatuses ?? []).includes(response.status)) {\n throw new Error(`${input.method} ${input.path} failed: ${response.status} ${await response.text()}`);\n }\n return await response.json() as T;\n}\n\ntype RequestedReviewersResponse = {\n users?: Array<{ login?: unknown }>;\n teams?: Array<{ slug?: unknown; name?: unknown }>;\n};\n\nfunction requestedReviewerLogins(response: RequestedReviewersResponse): Set<string> {\n return new Set((response.users ?? []).map((user) => user.login).filter((login): login is string => typeof login === \"string\"));\n}\n\nfunction requestedTeamReviewerNames(response: RequestedReviewersResponse): Set<string> {\n return new Set(\n (response.teams ?? [])\n .flatMap((team) => [team.slug, team.name])\n .filter((value): value is string => typeof value === \"string\" && value.length > 0)\n );\n}\n\nexport function compileGitHubIssueMutationIntent(\n intent: MutationIntent,\n options: { mappings?: AdapterMutationMapping[]; targetKind?: \"issue\" | \"pull_request\" } = {}\n): GitHubIssueMutationCompilation {\n if (intent.action === \"create_pull_request\") {\n const head = stringParam(intent, \"head\", \"branch\");\n if (!head) {\n return {\n ok: false,\n outcome: {\n intentId: intent.intentId,\n outcome: \"failed\",\n message: \"create_pull_request requires params.head or params.branch.\"\n }\n };\n }\n return {\n ok: true,\n intentId: intent.intentId,\n operation: {\n kind: \"create_pull_request\",\n intentId: intent.intentId,\n title: stringParam(intent, \"title\") ?? intent.summary,\n body: pullRequestBodyFromIntent(intent),\n head,\n base: stringParam(intent, \"base\", \"baseBranch\") ?? \"main\"\n }\n };\n }\n\n if (intent.action === \"request_review\" || intent.domain === \"review\") {\n if (options.targetKind !== \"pull_request\") {\n return {\n ok: false,\n outcome: {\n intentId: intent.intentId,\n outcome: \"unsupported\",\n message: \"GitHub review requests require a pull request target.\"\n }\n };\n }\n const reviewers = reviewersFromIntent(intent);\n const teamReviewers = teamReviewersFromIntent(intent);\n if (!reviewers?.length && !teamReviewers?.length) {\n return {\n ok: false,\n outcome: {\n intentId: intent.intentId,\n outcome: \"failed\",\n message: \"request_review requires params.reviewer, params.reviewers, or params.teamReviewers.\"\n }\n };\n }\n return {\n ok: true,\n intentId: intent.intentId,\n operation: {\n kind: \"request_review\",\n intentId: intent.intentId,\n reviewers: reviewers ?? [],\n ...(teamReviewers?.length ? { teamReviewers } : {})\n }\n };\n }\n\n if (intent.domain === \"status\") {\n const mapped = labelMappingForIntent({ intent, mappings: options.mappings ?? [] });\n if (mapped) {\n return { ok: true, intentId: intent.intentId, operation: { kind: \"replace_mapped_label\", intentId: intent.intentId, ...mapped } };\n }\n return {\n ok: false,\n outcome: {\n intentId: intent.intentId,\n outcome: \"unsupported\",\n message: \"GitHub status writes require an explicit Project field or label mapping policy.\"\n }\n };\n }\n if (intent.domain === \"priority\") {\n const mapped = labelMappingForIntent({ intent, mappings: options.mappings ?? [] });\n if (mapped) {\n return { ok: true, intentId: intent.intentId, operation: { kind: \"replace_mapped_label\", intentId: intent.intentId, ...mapped } };\n }\n return {\n ok: false,\n outcome: {\n intentId: intent.intentId,\n outcome: \"unsupported\",\n message: \"GitHub priority writes require an explicit label or Project field mapping policy.\"\n }\n };\n }\n if (intent.domain !== \"labels\" && intent.domain !== \"assignee\") {\n return {\n ok: false,\n outcome: {\n intentId: intent.intentId,\n outcome: \"unsupported\",\n message: `GitHub apply supports labels and assignee only, not ${intent.domain}.`\n }\n };\n }\n\n if (intent.domain === \"assignee\") {\n if (intent.action === \"set_assignee\") {\n const assignee = assigneeFromIntent(intent);\n return assignee\n ? { ok: true, intentId: intent.intentId, operation: { kind: \"set_assignees\", intentId: intent.intentId, assignees: [assignee] } }\n : { ok: false, outcome: { intentId: intent.intentId, outcome: \"failed\", message: \"set_assignee requires params.assignee.\" } };\n }\n if (intent.action === \"set_assignees\") {\n const assignees = assigneesFromIntent(intent);\n return assignees\n ? { ok: true, intentId: intent.intentId, operation: { kind: \"set_assignees\", intentId: intent.intentId, assignees } }\n : { ok: false, outcome: { intentId: intent.intentId, outcome: \"failed\", message: \"set_assignees requires params.assignees.\" } };\n }\n if (intent.action === \"add_assignee\") {\n const assignee = assigneeFromIntent(intent);\n return assignee\n ? { ok: true, intentId: intent.intentId, operation: { kind: \"add_assignee\", intentId: intent.intentId, assignee } }\n : { ok: false, outcome: { intentId: intent.intentId, outcome: \"failed\", message: \"add_assignee requires params.assignee.\" } };\n }\n if (intent.action === \"remove_assignee\") {\n const assignee = assigneeFromIntent(intent);\n return assignee\n ? { ok: true, intentId: intent.intentId, operation: { kind: \"remove_assignee\", intentId: intent.intentId, assignee } }\n : { ok: false, outcome: { intentId: intent.intentId, outcome: \"failed\", message: \"remove_assignee requires params.assignee.\" } };\n }\n return {\n ok: false,\n outcome: {\n intentId: intent.intentId,\n outcome: \"unsupported\",\n message: `GitHub apply does not support assignee action ${intent.action}.`\n }\n };\n }\n\n if (intent.action === \"add_label\") {\n const label = labelFromIntent(intent);\n return label\n ? { ok: true, intentId: intent.intentId, operation: { kind: \"add_label\", intentId: intent.intentId, label } }\n : { ok: false, outcome: { intentId: intent.intentId, outcome: \"failed\", message: \"add_label requires params.label.\" } };\n }\n if (intent.action === \"remove_label\") {\n const label = labelFromIntent(intent);\n return label\n ? { ok: true, intentId: intent.intentId, operation: { kind: \"remove_label\", intentId: intent.intentId, label } }\n : { ok: false, outcome: { intentId: intent.intentId, outcome: \"failed\", message: \"remove_label requires params.label.\" } };\n }\n if (intent.action === \"set_labels\") {\n const labels = labelsFromIntent(intent);\n return labels\n ? { ok: true, intentId: intent.intentId, operation: { kind: \"set_labels\", intentId: intent.intentId, labels } }\n : { ok: false, outcome: { intentId: intent.intentId, outcome: \"failed\", message: \"set_labels requires params.labels.\" } };\n }\n\n return {\n ok: false,\n outcome: {\n intentId: intent.intentId,\n outcome: \"unsupported\",\n message: `GitHub apply does not support labels action ${intent.action}.`\n }\n };\n}\n\nexport function compileGitHubIssueMutationIntents(\n intents: MutationIntent[],\n options: { mappings?: AdapterMutationMapping[]; targetKind?: \"issue\" | \"pull_request\" } = {}\n): GitHubIssueMutationCompilation[] {\n return intents.map((intent) => compileGitHubIssueMutationIntent(intent, options));\n}\n\nexport function createGitHubIssueMutationCompiler(options: {\n mappings?: AdapterMutationMapping[];\n targetKind?: \"issue\" | \"pull_request\";\n} = {}): AdapterMutationCompiler<GitHubIssueMutationOperation> {\n return {\n adapter: \"github\",\n compile(intent) {\n const compilation = compileGitHubIssueMutationIntent(intent, options);\n if (!compilation.ok) {\n return {\n ok: false,\n adapter: \"github\",\n outcome: compilation.outcome\n };\n }\n return {\n ok: true,\n adapter: \"github\",\n intentId: compilation.intentId,\n operation: compilation.operation\n };\n }\n };\n}\n\nexport async function applyGitHubIssueMutationOperation(input: {\n target: GitHubIssueMutationTarget;\n operation: GitHubIssueMutationOperation;\n fetchImpl?: FetchLike;\n}): Promise<ApplyIntentOutcome> {\n const fetchImpl = input.fetchImpl ?? fetch;\n try {\n if (input.operation.kind === \"create_pull_request\") {\n const externalUri = await createPullRequestViaFetch(\n {\n token: input.target.token,\n owner: input.target.owner,\n repo: input.target.repo,\n title: input.operation.title,\n body: input.operation.body,\n head: input.operation.head,\n base: input.operation.base\n },\n fetchImpl\n );\n return { intentId: input.operation.intentId, outcome: \"applied\", externalUri };\n }\n\n if (input.operation.kind === \"request_review\") {\n const pullRequestNumber = input.target.pullRequestNumber;\n if (typeof pullRequestNumber !== \"number\") {\n return {\n intentId: input.operation.intentId,\n outcome: \"failed\",\n message: \"request_review requires target.pullRequestNumber.\"\n };\n }\n const requested = await githubJsonBody<RequestedReviewersResponse>({\n target: input.target,\n fetchImpl,\n method: \"GET\",\n path: `/pulls/${pullRequestNumber}/requested_reviewers`\n });\n const existingReviewers = requestedReviewerLogins(requested);\n const existingTeamReviewers = requestedTeamReviewerNames(requested);\n const reviewers = input.operation.reviewers.filter((reviewer) => !existingReviewers.has(reviewer));\n const teamReviewers = input.operation.teamReviewers?.filter((reviewer) => !existingTeamReviewers.has(reviewer));\n if (reviewers.length === 0 && (!teamReviewers || teamReviewers.length === 0)) {\n return {\n intentId: input.operation.intentId,\n outcome: \"applied\",\n externalUri: `https://github.com/${input.target.owner}/${input.target.repo}/pull/${pullRequestNumber}`,\n message: \"Requested reviewers were already present; skipped GitHub notification retry.\"\n };\n }\n await githubJson({\n target: input.target,\n fetchImpl,\n method: \"POST\",\n path: `/pulls/${pullRequestNumber}/requested_reviewers`,\n body: {\n ...(reviewers.length ? { reviewers } : {}),\n ...(teamReviewers?.length ? { team_reviewers: teamReviewers } : {})\n }\n });\n return {\n intentId: input.operation.intentId,\n outcome: \"applied\",\n externalUri: `https://github.com/${input.target.owner}/${input.target.repo}/pull/${pullRequestNumber}`\n };\n }\n\n const issueNumber = input.target.issueNumber;\n if (typeof issueNumber !== \"number\") {\n return {\n intentId: input.operation.intentId,\n outcome: \"failed\",\n message: \"GitHub issue mutation requires target.issueNumber.\"\n };\n }\n\n if (input.operation.kind === \"set_assignees\") {\n const externalUri = await githubJson({\n target: input.target,\n fetchImpl,\n method: \"PATCH\",\n path: `/issues/${issueNumber}`,\n body: { assignees: input.operation.assignees }\n });\n return { intentId: input.operation.intentId, outcome: \"applied\", externalUri };\n }\n\n if (input.operation.kind === \"add_assignee\") {\n const externalUri = await githubJson({\n target: input.target,\n fetchImpl,\n method: \"POST\",\n path: `/issues/${issueNumber}/assignees`,\n body: { assignees: [input.operation.assignee] }\n });\n return { intentId: input.operation.intentId, outcome: \"applied\", externalUri };\n }\n\n if (input.operation.kind === \"remove_assignee\") {\n const externalUri = await githubJson({\n target: input.target,\n fetchImpl,\n method: \"DELETE\",\n path: `/issues/${issueNumber}/assignees`,\n body: { assignees: [input.operation.assignee] }\n });\n return { intentId: input.operation.intentId, outcome: \"applied\", externalUri };\n }\n\n if (input.operation.kind === \"replace_mapped_label\") {\n for (const label of input.operation.removeLabels) {\n await githubJson({\n target: input.target,\n fetchImpl,\n method: \"DELETE\",\n path: `/issues/${issueNumber}/labels/${encodeURIComponent(label)}`,\n okStatuses: [200, 404]\n });\n }\n const externalUri = await githubJson({\n target: input.target,\n fetchImpl,\n method: \"POST\",\n path: `/issues/${issueNumber}/labels`,\n body: { labels: [input.operation.label] }\n });\n return { intentId: input.operation.intentId, outcome: \"applied\", externalUri };\n }\n\n if (input.operation.kind === \"add_label\") {\n const externalUri = await githubJson({\n target: input.target,\n fetchImpl,\n method: \"POST\",\n path: `/issues/${issueNumber}/labels`,\n body: { labels: [input.operation.label] }\n });\n return { intentId: input.operation.intentId, outcome: \"applied\", externalUri };\n }\n\n if (input.operation.kind === \"remove_label\") {\n const externalUri = await githubJson({\n target: input.target,\n fetchImpl,\n method: \"DELETE\",\n path: `/issues/${issueNumber}/labels/${encodeURIComponent(input.operation.label)}`\n });\n return { intentId: input.operation.intentId, outcome: \"applied\", externalUri };\n }\n\n const externalUri = await githubJson({\n target: input.target,\n fetchImpl,\n method: \"PUT\",\n path: `/issues/${issueNumber}/labels`,\n body: { labels: input.operation.labels }\n });\n return { intentId: input.operation.intentId, outcome: \"applied\", externalUri };\n } catch (error) {\n return {\n intentId: input.operation.intentId,\n outcome: \"failed\",\n error: error instanceof Error ? error.message : String(error)\n };\n }\n}\n\nexport async function applyGitHubIssueMutationIntent(input: {\n target: GitHubIssueMutationTarget;\n intent: MutationIntent;\n mappings?: AdapterMutationMapping[];\n targetKind?: \"issue\" | \"pull_request\";\n fetchImpl?: FetchLike;\n}): Promise<ApplyIntentOutcome> {\n const compiled = compileGitHubIssueMutationIntent(input.intent, {\n ...(input.mappings ? { mappings: input.mappings } : {}),\n ...(input.targetKind ? { targetKind: input.targetKind } : {})\n });\n if (!compiled.ok) return compiled.outcome;\n return applyGitHubIssueMutationOperation({\n target: input.target,\n operation: compiled.operation,\n ...(input.fetchImpl ? { fetchImpl: input.fetchImpl } : {})\n });\n}\n\nexport async function applyGitHubIssueMutationIntents(input: {\n target: GitHubIssueMutationTarget;\n intents: MutationIntent[];\n mappings?: AdapterMutationMapping[];\n targetKind?: \"issue\" | \"pull_request\";\n fetchImpl?: FetchLike;\n}): Promise<ApplyIntentOutcome[]> {\n const outcomes: ApplyIntentOutcome[] = [];\n for (const intent of input.intents) {\n outcomes.push(\n await applyGitHubIssueMutationIntent({\n target: input.target,\n intent,\n ...(input.mappings ? { mappings: input.mappings } : {}),\n ...(input.targetKind ? { targetKind: input.targetKind } : {}),\n ...(input.fetchImpl ? { fetchImpl: input.fetchImpl } : {})\n })\n );\n }\n return outcomes;\n}\n","import { createHmac, randomUUID, timingSafeEqual } from \"node:crypto\";\nimport { serve } from \"@hono/node-server\";\nimport { createOpenTagClient } from \"@opentag/client\";\nimport {\n DEFAULT_MAX_REQUEST_BODY_BYTES,\n RequestBodyTooLargeError,\n parseThreadActionCommand,\n readRequestTextWithLimit,\n type OpenTagEvent\n} from \"@opentag/core\";\nimport { Hono } from \"hono\";\nimport { normalizeGitHubIssueComment, normalizeGitHubPullRequestReviewComment } from \"./normalize.js\";\n\ntype GitHubActor = {\n id: number;\n login: string;\n};\n\ntype GitHubRepository = {\n name: string;\n private: boolean;\n owner: { login: string };\n};\n\nexport type GitHubIssueCommentPayload = {\n action?: string;\n comment: { id: number; body: string; html_url: string };\n issue: { html_url: string; comments_url: string; number: number };\n repository: GitHubRepository;\n sender: GitHubActor;\n installation?: { id: number };\n};\n\nexport type GitHubPullRequestReviewCommentPayload = {\n action?: string;\n comment: { id: number; body: string; html_url: string };\n pull_request: { html_url: string; number: number };\n repository: GitHubRepository;\n sender: GitHubActor;\n installation?: { id: number };\n};\n\nexport type GitHubThreadActionInput = {\n id: string;\n rawText: string;\n actor: {\n provider: \"github\";\n providerUserId: string;\n handle: string;\n };\n callback: {\n provider: \"github\";\n uri: string;\n threadKey: string;\n };\n metadata: Record<string, unknown>;\n};\n\nexport type GitHubWebhookAppInput = {\n webhookSecret: string;\n webhookPath?: string;\n createRun(event: OpenTagEvent): Promise<{ runId?: string }>;\n submitThreadAction?(action: GitHubThreadActionInput): Promise<unknown>;\n recordControlPlaneEvent?(event: {\n type: string;\n severity?: \"info\" | \"warn\" | \"error\";\n subject?: string;\n payload?: Record<string, unknown>;\n }): Promise<void>;\n maxRequestBodyBytes?: number;\n now(): string;\n};\n\nexport type GitHubIngressConfig = {\n webhookSecret: string;\n dispatcherUrl: string;\n dispatcherToken?: string;\n port?: number;\n hostname?: string;\n webhookPath?: string;\n maxRequestBodyBytes?: number;\n};\n\nexport type GitHubIngressHandle = {\n url: string;\n webhookPath: string;\n server: ReturnType<typeof serve>;\n close(): Promise<void>;\n};\n\nexport function computeGitHubSignature(input: { webhookSecret: string; rawBody: string }): string {\n const digest = createHmac(\"sha256\", input.webhookSecret).update(input.rawBody).digest(\"hex\");\n return `sha256=${digest}`;\n}\n\nexport function verifyGitHubSignature(input: {\n webhookSecret: string;\n rawBody: string;\n signature: string;\n}): boolean {\n const expected = computeGitHubSignature(input);\n const expectedBuffer = Buffer.from(expected);\n const actualBuffer = Buffer.from(input.signature);\n return expectedBuffer.length === actualBuffer.length && timingSafeEqual(expectedBuffer, actualBuffer);\n}\n\nasync function recordGitHubSignatureFailure(input: {\n recordControlPlaneEvent?: GitHubWebhookAppInput[\"recordControlPlaneEvent\"];\n webhookPath: string;\n reason: \"missing_signature_header\" | \"invalid_signature\";\n deliveryId?: string;\n hasSignature: boolean;\n}): Promise<void> {\n try {\n await input.recordControlPlaneEvent?.({\n type: \"security.signature_failed\",\n severity: \"warn\",\n subject: `github:POST ${input.webhookPath}`,\n payload: {\n provider: \"github\",\n endpoint: `POST ${input.webhookPath}`,\n reason: input.reason,\n ...(input.deliveryId ? { deliveryId: input.deliveryId } : {}),\n hasSignature: input.hasSignature\n }\n });\n } catch {\n // Signature rejection should not turn into a 5xx if audit reporting is unavailable.\n }\n}\n\nasync function recordGitHubRequestBodyRejected(input: {\n recordControlPlaneEvent?: GitHubWebhookAppInput[\"recordControlPlaneEvent\"];\n webhookPath: string;\n reason: \"request_body_too_large\" | \"invalid_json_body\" | \"invalid_request_body\";\n maxBytes?: number;\n contentLength: string | null;\n deliveryId?: string;\n eventName?: string;\n}): Promise<void> {\n try {\n await input.recordControlPlaneEvent?.({\n type: \"security.request_body_rejected\",\n severity: \"warn\",\n subject: `github:POST ${input.webhookPath}`,\n payload: {\n provider: \"github\",\n endpoint: `POST ${input.webhookPath}`,\n reason: input.reason,\n ...(input.maxBytes !== undefined ? { maxBytes: input.maxBytes } : {}),\n contentLength: input.contentLength,\n ...(input.deliveryId ? { deliveryId: input.deliveryId } : {}),\n ...(input.eventName ? { githubEvent: input.eventName } : {})\n }\n });\n } catch {\n // Oversized-payload rejection should still fail closed if audit reporting is unavailable.\n }\n}\n\nfunction parseJsonPayload(rawBody: string): unknown {\n try {\n return JSON.parse(rawBody);\n } catch {\n return null;\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction hasGitHubActor(value: unknown): value is GitHubActor {\n return isRecord(value) && typeof value.id === \"number\" && typeof value.login === \"string\";\n}\n\nfunction hasGitHubRepository(value: unknown): value is GitHubRepository {\n return (\n isRecord(value) &&\n typeof value.name === \"string\" &&\n typeof value.private === \"boolean\" &&\n isRecord(value.owner) &&\n typeof value.owner.login === \"string\"\n );\n}\n\nfunction hasGitHubInstallation(value: unknown): value is { id: number } {\n return isRecord(value) && typeof value.id === \"number\";\n}\n\nfunction isGitHubIssueCommentPayload(value: unknown): value is GitHubIssueCommentPayload {\n return (\n isRecord(value) &&\n (value.action === undefined || typeof value.action === \"string\") &&\n isRecord(value.comment) &&\n typeof value.comment.id === \"number\" &&\n typeof value.comment.body === \"string\" &&\n typeof value.comment.html_url === \"string\" &&\n isRecord(value.issue) &&\n typeof value.issue.html_url === \"string\" &&\n typeof value.issue.comments_url === \"string\" &&\n typeof value.issue.number === \"number\" &&\n hasGitHubRepository(value.repository) &&\n hasGitHubActor(value.sender) &&\n (value.installation === undefined || hasGitHubInstallation(value.installation))\n );\n}\n\nfunction isGitHubPullRequestReviewCommentPayload(value: unknown): value is GitHubPullRequestReviewCommentPayload {\n return (\n isRecord(value) &&\n (value.action === undefined || typeof value.action === \"string\") &&\n isRecord(value.comment) &&\n typeof value.comment.id === \"number\" &&\n typeof value.comment.body === \"string\" &&\n typeof value.comment.html_url === \"string\" &&\n isRecord(value.pull_request) &&\n typeof value.pull_request.html_url === \"string\" &&\n typeof value.pull_request.number === \"number\" &&\n hasGitHubRepository(value.repository) &&\n hasGitHubActor(value.sender) &&\n (value.installation === undefined || hasGitHubInstallation(value.installation))\n );\n}\n\nasync function handleIssueCommentCreated(input: {\n payload: GitHubIssueCommentPayload;\n createRun(event: OpenTagEvent): Promise<{ runId?: string }>;\n submitThreadAction?(action: GitHubThreadActionInput): Promise<unknown>;\n now(): string;\n deliveryId?: string;\n signatureVerified?: boolean;\n}): Promise<void> {\n if (input.payload.action && input.payload.action !== \"created\") return;\n if (parseThreadActionCommand(input.payload.comment.body) && input.submitThreadAction) {\n await input.submitThreadAction({\n id: `approval_github_comment_${input.payload.comment.id}`,\n rawText: input.payload.comment.body,\n actor: {\n provider: \"github\",\n providerUserId: String(input.payload.sender.id),\n handle: input.payload.sender.login\n },\n callback: {\n provider: \"github\",\n uri: input.payload.issue.comments_url,\n threadKey: `${input.payload.repository.owner.login}/${input.payload.repository.name}#${input.payload.issue.number}`\n },\n metadata: {\n repoProvider: \"github\",\n owner: input.payload.repository.owner.login,\n repo: input.payload.repository.name,\n issueNumber: input.payload.issue.number,\n commentUrl: input.payload.comment.html_url,\n ...(input.deliveryId ? { sourceDeliveryId: input.deliveryId, webhookDeliveryId: input.deliveryId } : {}),\n ...(typeof input.signatureVerified === \"boolean\"\n ? { webhookSignatureVerified: input.signatureVerified, signatureState: input.signatureVerified ? \"verified\" : \"unverified\" }\n : {})\n }\n });\n return;\n }\n\n const event = normalizeGitHubIssueComment({\n id: String(input.payload.comment.id),\n commentBody: input.payload.comment.body,\n commentUrl: input.payload.comment.html_url,\n apiCommentsUrl: input.payload.issue.comments_url,\n issueUrl: input.payload.issue.html_url,\n issueNumber: input.payload.issue.number,\n owner: input.payload.repository.owner.login,\n repo: input.payload.repository.name,\n actorId: input.payload.sender.id,\n actorLogin: input.payload.sender.login,\n private: input.payload.repository.private,\n receivedAt: input.now(),\n ...(input.deliveryId ? { deliveryId: input.deliveryId } : {}),\n ...(typeof input.signatureVerified === \"boolean\" ? { signatureVerified: input.signatureVerified } : {}),\n ...(input.payload.installation ? { installationId: input.payload.installation.id } : {})\n });\n\n if (event) {\n await input.createRun(event);\n }\n}\n\nasync function handlePullRequestReviewCommentCreated(input: {\n payload: GitHubPullRequestReviewCommentPayload;\n createRun(event: OpenTagEvent): Promise<{ runId?: string }>;\n submitThreadAction?(action: GitHubThreadActionInput): Promise<unknown>;\n now(): string;\n deliveryId?: string;\n signatureVerified?: boolean;\n}): Promise<void> {\n if (input.payload.action && input.payload.action !== \"created\") return;\n const owner = input.payload.repository.owner.login;\n const repo = input.payload.repository.name;\n if (parseThreadActionCommand(input.payload.comment.body) && input.submitThreadAction) {\n await input.submitThreadAction({\n id: `approval_github_pr_review_comment_${input.payload.comment.id}`,\n rawText: input.payload.comment.body,\n actor: {\n provider: \"github\",\n providerUserId: String(input.payload.sender.id),\n handle: input.payload.sender.login\n },\n callback: {\n provider: \"github\",\n uri: `https://api.github.com/repos/${owner}/${repo}/issues/${input.payload.pull_request.number}/comments`,\n threadKey: `${owner}/${repo}#${input.payload.pull_request.number}`\n },\n metadata: {\n repoProvider: \"github\",\n owner,\n repo,\n pullRequestNumber: input.payload.pull_request.number,\n commentUrl: input.payload.comment.html_url,\n ...(input.deliveryId ? { sourceDeliveryId: input.deliveryId, webhookDeliveryId: input.deliveryId } : {}),\n ...(typeof input.signatureVerified === \"boolean\"\n ? { webhookSignatureVerified: input.signatureVerified, signatureState: input.signatureVerified ? \"verified\" : \"unverified\" }\n : {})\n }\n });\n return;\n }\n\n const event = normalizeGitHubPullRequestReviewComment({\n id: String(input.payload.comment.id),\n commentBody: input.payload.comment.body,\n commentUrl: input.payload.comment.html_url,\n pullRequestUrl: input.payload.pull_request.html_url,\n apiCommentsUrl: `https://api.github.com/repos/${owner}/${repo}/issues/${input.payload.pull_request.number}/comments`,\n owner,\n repo,\n pullRequestNumber: input.payload.pull_request.number,\n actorId: input.payload.sender.id,\n actorLogin: input.payload.sender.login,\n private: input.payload.repository.private,\n receivedAt: input.now(),\n ...(input.deliveryId ? { deliveryId: input.deliveryId } : {}),\n ...(typeof input.signatureVerified === \"boolean\" ? { signatureVerified: input.signatureVerified } : {}),\n ...(input.payload.installation ? { installationId: input.payload.installation.id } : {})\n });\n\n if (event) {\n await input.createRun(event);\n }\n}\n\nexport function createGitHubWebhookApp(input: GitHubWebhookAppInput) {\n const app = new Hono();\n const webhookPath = input.webhookPath ?? \"/github/webhooks\";\n const maxRequestBodyBytes = input.maxRequestBodyBytes ?? DEFAULT_MAX_REQUEST_BODY_BYTES;\n if (!webhookPath.startsWith(\"/\")) {\n throw new Error(\"GitHub webhook path must start with /.\");\n }\n\n app.post(webhookPath, async (c) => {\n const signature = c.req.header(\"x-hub-signature-256\");\n if (!signature) {\n await recordGitHubSignatureFailure({\n recordControlPlaneEvent: input.recordControlPlaneEvent,\n webhookPath,\n reason: \"missing_signature_header\",\n ...(c.req.header(\"x-github-delivery\") ? { deliveryId: c.req.header(\"x-github-delivery\")! } : {}),\n hasSignature: false\n });\n return c.json({ error: \"missing_signature_header\" }, 401);\n }\n let rawBody: string;\n try {\n rawBody = await readRequestTextWithLimit(c.req.raw, { maxBytes: maxRequestBodyBytes });\n } catch (error) {\n if (error instanceof RequestBodyTooLargeError) {\n await recordGitHubRequestBodyRejected({\n recordControlPlaneEvent: input.recordControlPlaneEvent,\n webhookPath,\n reason: \"request_body_too_large\",\n maxBytes: error.maxBytes,\n contentLength: c.req.raw.headers.get(\"content-length\"),\n ...(c.req.header(\"x-github-delivery\") ? { deliveryId: c.req.header(\"x-github-delivery\")! } : {}),\n ...(c.req.header(\"x-github-event\") ? { eventName: c.req.header(\"x-github-event\")! } : {})\n });\n return c.json({ error: \"request_body_too_large\", maxBytes: error.maxBytes }, 413);\n }\n throw error;\n }\n if (!verifyGitHubSignature({ webhookSecret: input.webhookSecret, rawBody, signature })) {\n await recordGitHubSignatureFailure({\n recordControlPlaneEvent: input.recordControlPlaneEvent,\n webhookPath,\n reason: \"invalid_signature\",\n ...(c.req.header(\"x-github-delivery\") ? { deliveryId: c.req.header(\"x-github-delivery\")! } : {}),\n hasSignature: true\n });\n return c.json({ error: \"invalid_signature\" }, 401);\n }\n\n const deliveryId = c.req.header(\"x-github-delivery\");\n const eventName = c.req.header(\"x-github-event\");\n const payload = parseJsonPayload(rawBody);\n if (!payload || typeof payload !== \"object\") {\n await recordGitHubRequestBodyRejected({\n recordControlPlaneEvent: input.recordControlPlaneEvent,\n webhookPath,\n reason: \"invalid_json_body\",\n contentLength: c.req.raw.headers.get(\"content-length\"),\n ...(deliveryId ? { deliveryId } : {}),\n ...(eventName ? { eventName } : {})\n });\n return c.json({ error: \"invalid_json\" }, 400);\n }\n\n if (eventName === \"ping\") {\n return c.json({ ok: true });\n }\n if (eventName === \"issue_comment\") {\n if (!isGitHubIssueCommentPayload(payload)) {\n await recordGitHubRequestBodyRejected({\n recordControlPlaneEvent: input.recordControlPlaneEvent,\n webhookPath,\n reason: \"invalid_request_body\",\n contentLength: c.req.raw.headers.get(\"content-length\"),\n ...(deliveryId ? { deliveryId } : {}),\n eventName\n });\n return c.json({ error: \"invalid_request_body\" }, 400);\n }\n await handleIssueCommentCreated({\n payload,\n createRun: input.createRun,\n ...(input.submitThreadAction ? { submitThreadAction: input.submitThreadAction } : {}),\n now: input.now,\n ...(deliveryId ? { deliveryId } : {}),\n signatureVerified: true\n });\n return c.json({ ok: true });\n }\n if (eventName === \"pull_request_review_comment\") {\n if (!isGitHubPullRequestReviewCommentPayload(payload)) {\n await recordGitHubRequestBodyRejected({\n recordControlPlaneEvent: input.recordControlPlaneEvent,\n webhookPath,\n reason: \"invalid_request_body\",\n contentLength: c.req.raw.headers.get(\"content-length\"),\n ...(deliveryId ? { deliveryId } : {}),\n eventName\n });\n return c.json({ error: \"invalid_request_body\" }, 400);\n }\n await handlePullRequestReviewCommentCreated({\n payload,\n createRun: input.createRun,\n ...(input.submitThreadAction ? { submitThreadAction: input.submitThreadAction } : {}),\n now: input.now,\n ...(deliveryId ? { deliveryId } : {}),\n signatureVerified: true\n });\n return c.json({ ok: true });\n }\n\n return c.json({ ok: true, ignored: \"unsupported_event\" });\n });\n\n return app;\n}\n\nexport function startGitHubIngress(config: GitHubIngressConfig): GitHubIngressHandle {\n const dispatcherClient = createOpenTagClient({\n dispatcherUrl: config.dispatcherUrl,\n ...(config.dispatcherToken ? { pairingToken: config.dispatcherToken } : {})\n });\n const port = config.port ?? 3000;\n const hostname = config.hostname ?? \"127.0.0.1\";\n const webhookPath = config.webhookPath ?? \"/github/webhooks\";\n const server = serve({\n fetch: createGitHubWebhookApp({\n webhookSecret: config.webhookSecret,\n webhookPath,\n ...(config.maxRequestBodyBytes ? { maxRequestBodyBytes: config.maxRequestBodyBytes } : {}),\n async createRun(event) {\n const runId = `run_${randomUUID()}`;\n const created = await dispatcherClient.createRun({ runId, event });\n return created.outcome === \"run_created\" ? { runId: created.run.id } : {};\n },\n async submitThreadAction(action) {\n await dispatcherClient.submitThreadAction(action);\n },\n async recordControlPlaneEvent(event) {\n await dispatcherClient.recordControlPlaneEvent(event);\n },\n now: () => new Date().toISOString()\n }).fetch,\n port,\n hostname\n });\n\n return {\n url: `http://${hostname}:${port}`,\n webhookPath,\n server,\n close() {\n return new Promise((resolve, reject) => {\n server.close((error?: Error) => {\n if (error) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n }\n };\n}\n","import { parseOpenTagMention, type OpenTagEvent } from \"@opentag/core\";\nimport type { ContextPointer, OpenTagCommand, PermissionGrant, WorkItemReference } from \"@opentag/core\";\n\nexport type GitHubIssueCommentInput = {\n id: string;\n commentBody: string;\n commentUrl: string;\n apiCommentsUrl: string;\n issueUrl: string;\n issueNumber: number;\n owner: string;\n repo: string;\n actorId: number;\n actorLogin: string;\n private: boolean;\n receivedAt: string;\n installationId?: number;\n deliveryId?: string;\n signatureVerified?: boolean;\n};\n\nexport type GitHubPullRequestReviewCommentInput = {\n id: string;\n commentBody: string;\n commentUrl: string;\n pullRequestUrl: string;\n apiCommentsUrl: string;\n owner: string;\n repo: string;\n pullRequestNumber: number;\n actorId: number;\n actorLogin: string;\n private: boolean;\n receivedAt: string;\n installationId?: number;\n deliveryId?: string;\n signatureVerified?: boolean;\n};\n\nfunction permissionsForIntent(intent: OpenTagCommand[\"intent\"]): PermissionGrant[] {\n const permissions: PermissionGrant[] = [\n {\n scope: \"issue:comment\",\n reason: \"reply to the source GitHub thread\"\n },\n {\n scope: \"runner:local\",\n reason: \"execute the run on a paired local daemon\"\n }\n ];\n if (intent === \"fix\" || intent === \"run\") {\n permissions.push(\n {\n scope: \"repo:read\",\n reason: \"inspect the repository in the paired local checkout\"\n },\n {\n scope: \"repo:write\",\n reason: \"commit code changes on an isolated run branch\"\n },\n {\n scope: \"pr:create\",\n reason: \"open a pull request for completed code changes\"\n }\n );\n }\n return permissions;\n}\n\nfunction permissionsForPullRequestReviewCommentIntent(intent: OpenTagCommand[\"intent\"]): PermissionGrant[] {\n const permissions = permissionsForIntent(intent);\n if (intent === \"review\") {\n permissions.push({\n scope: \"pr:update\",\n reason: \"request reviewers on the source pull request after explicit approval\"\n });\n }\n return permissions;\n}\n\nfunction contextPointersForCommand(command: OpenTagCommand, privateRepo: boolean): ContextPointer[] {\n const visibility = privateRepo ? \"private\" : \"public\";\n const context: ContextPointer[] = [];\n\n for (const reference of command.parsed?.references ?? []) {\n if (reference.kind === \"url\") {\n context.push({\n kind: \"url\",\n uri: reference.uri,\n visibility,\n title: reference.title ?? \"Command URL reference\"\n });\n continue;\n }\n\n if (reference.kind === \"file\" || reference.kind === \"path\" || reference.kind === \"line\" || reference.kind === \"range\") {\n context.push({\n kind: \"file\",\n uri: reference.uri,\n ...(reference.line ? { line: reference.line } : {}),\n ...(reference.startLine ? { startLine: reference.startLine } : {}),\n ...(reference.endLine ? { endLine: reference.endLine } : {}),\n visibility,\n title: referenceTitle(reference)\n });\n }\n }\n\n return context;\n}\n\nfunction referenceTitle(reference: NonNullable<OpenTagCommand[\"parsed\"]>[\"references\"][number]): string {\n return reference.title ?? \"Command file reference\";\n}\n\nfunction githubWorkItem(input: {\n owner: string;\n repo: string;\n kind: \"issue\" | \"pull_request\";\n number: number;\n uri: string;\n}): WorkItemReference {\n return {\n provider: \"github\",\n kind: input.kind,\n externalId: `${input.owner}/${input.repo}#${input.number}`,\n uri: input.uri,\n ownerContainer: {\n provider: \"github\",\n id: `${input.owner}/${input.repo}`,\n uri: `https://github.com/${input.owner}/${input.repo}`\n }\n };\n}\n\nfunction commandMetadata(command: OpenTagCommand): Record<string, unknown> {\n if (!command.parsed) return {};\n return {\n commandParser: command.parsed.version,\n commandDiagnostics: command.parsed.diagnostics,\n ...(command.parsed.approval ? { approval: command.parsed.approval } : {}),\n ...(command.parsed.network ? { network: command.parsed.network } : {})\n };\n}\n\nexport function normalizeGitHubIssueComment(input: GitHubIssueCommentInput): OpenTagEvent | null {\n const mention = parseOpenTagMention(input.commentBody);\n if (!mention.matched) return null;\n\n const command = {\n rawText: mention.rawText,\n intent: mention.intent,\n args: mention.args,\n ...(mention.parsed ? { parsed: mention.parsed } : {})\n };\n\n return {\n id: `evt_github_comment_${input.id}`,\n source: \"github\",\n sourceEventId: input.id,\n receivedAt: input.receivedAt,\n actor: {\n provider: \"github\",\n providerUserId: String(input.actorId),\n handle: input.actorLogin\n },\n target: {\n mention: \"@opentag\",\n agentId: \"opentag\",\n ...(mention.parsed?.executorHint ? { executorHint: mention.parsed.executorHint } : {})\n },\n command,\n context: [\n {\n provider: \"github\",\n kind: \"issue\",\n uri: input.issueUrl,\n visibility: input.private ? \"private\" : \"public\"\n },\n {\n provider: \"github\",\n kind: \"comment\",\n uri: input.commentUrl,\n visibility: input.private ? \"private\" : \"public\"\n },\n ...contextPointersForCommand(command, input.private)\n ],\n workItem: githubWorkItem({\n owner: input.owner,\n repo: input.repo,\n kind: \"issue\",\n number: input.issueNumber,\n uri: input.issueUrl\n }),\n permissions: permissionsForIntent(mention.intent),\n callback: {\n provider: \"github\",\n uri: input.apiCommentsUrl,\n threadKey: `${input.owner}/${input.repo}#${input.issueNumber}`\n },\n metadata: {\n repoProvider: \"github\",\n owner: input.owner,\n repo: input.repo,\n issueNumber: input.issueNumber,\n ...commandMetadata(command),\n ...(input.deliveryId ? { sourceDeliveryId: input.deliveryId, webhookDeliveryId: input.deliveryId } : {}),\n ...(typeof input.signatureVerified === \"boolean\"\n ? { webhookSignatureVerified: input.signatureVerified, signatureState: input.signatureVerified ? \"verified\" : \"unverified\" }\n : {}),\n ...(typeof input.installationId === \"number\" ? { installationId: input.installationId } : {})\n }\n };\n}\n\nexport function normalizeGitHubPullRequestReviewComment(input: GitHubPullRequestReviewCommentInput): OpenTagEvent | null {\n const mention = parseOpenTagMention(input.commentBody);\n if (!mention.matched) return null;\n\n const command = {\n rawText: mention.rawText,\n intent: mention.intent,\n args: mention.args,\n ...(mention.parsed ? { parsed: mention.parsed } : {})\n };\n\n return {\n id: `evt_github_pr_review_comment_${input.id}`,\n source: \"github\",\n sourceEventId: input.id,\n receivedAt: input.receivedAt,\n actor: {\n provider: \"github\",\n providerUserId: String(input.actorId),\n handle: input.actorLogin\n },\n target: {\n mention: \"@opentag\",\n agentId: \"opentag\",\n ...(mention.parsed?.executorHint ? { executorHint: mention.parsed.executorHint } : {})\n },\n command,\n context: [\n {\n provider: \"github\",\n kind: \"pull_request\",\n uri: input.pullRequestUrl,\n visibility: input.private ? \"private\" : \"public\"\n },\n {\n provider: \"github\",\n kind: \"comment\",\n uri: input.commentUrl,\n visibility: input.private ? \"private\" : \"public\"\n },\n ...contextPointersForCommand(command, input.private)\n ],\n workItem: githubWorkItem({\n owner: input.owner,\n repo: input.repo,\n kind: \"pull_request\",\n number: input.pullRequestNumber,\n uri: input.pullRequestUrl\n }),\n permissions: permissionsForPullRequestReviewCommentIntent(mention.intent),\n callback: {\n provider: \"github\",\n uri: input.apiCommentsUrl,\n threadKey: `${input.owner}/${input.repo}#${input.pullRequestNumber}`\n },\n metadata: {\n repoProvider: \"github\",\n owner: input.owner,\n repo: input.repo,\n pullRequestNumber: input.pullRequestNumber,\n ...commandMetadata(command),\n ...(input.deliveryId ? { sourceDeliveryId: input.deliveryId, webhookDeliveryId: input.deliveryId } : {}),\n ...(typeof input.signatureVerified === \"boolean\"\n ? { webhookSignatureVerified: input.signatureVerified, signatureState: input.signatureVerified ? \"verified\" : \"unverified\" }\n : {}),\n ...(typeof input.installationId === \"number\" ? { installationId: input.installationId } : {})\n }\n };\n}\n","import {\n createFinalSummaryPresentation,\n type ActionReceiptContext,\n type ActionReceiptDecision,\n type OpenTagFinalSummaryPresentation,\n type OpenTagPresentationAction,\n type OpenTagRunResult\n} from \"@opentag/core\";\n\nexport type GitHubRenderOptions = {\n receiptContext?: ActionReceiptContext;\n auditRunId?: string;\n};\n\nfunction tableValue(value: string): string {\n return value.replace(/\\|/g, \"\\\\|\").replace(/\\n/g, \"<br>\");\n}\n\nfunction decisionLabel(decision: ActionReceiptDecision): string {\n if (decision === \"apply\") return \"Apply now\";\n if (decision === \"approve\") return \"Approve only\";\n if (decision === \"continue\") return \"Continue\";\n return \"Reject\";\n}\n\nfunction decisionEffect(decision: ActionReceiptDecision): string {\n if (decision === \"apply\") return \"Approves and applies this action to the system of record.\";\n if (decision === \"approve\") return \"Records approval without applying yet.\";\n if (decision === \"continue\") return \"Starts a follow-up run from this approved action.\";\n return \"Rejects this action.\";\n}\n\nfunction actionDetailRows(action: OpenTagPresentationAction): Array<[string, string]> {\n if (action.detailRows?.length) return action.detailRows.map((row) => [row.label, row.value]);\n const rows: Array<[string, string]> = [[\"Target\", action.targetLabel]];\n if (action.setupReason) rows.push([\"Status\", action.setupReason]);\n return rows;\n}\n\nfunction renderSuggestedActions(presentation: OpenTagFinalSummaryPresentation): string[] {\n const actions = presentation.actions ?? [];\n if (actions.length === 0 || !presentation.actionReceiptTitle) return [];\n\n const lines = [\n `### ${presentation.actionReceiptTitle}`,\n \"\",\n \"OpenTag prepared a source-thread action receipt. Choose one command in this GitHub thread; full protocol lineage stays in the audit log.\"\n ];\n if (presentation.auditRunId) {\n lines.push(\"\", `Audit: run \\`opentag status --run ${presentation.auditRunId}\\` locally.`);\n }\n for (const action of actions) {\n lines.push(\n \"\",\n `#### ${action.index}. ${action.title}`,\n \"\",\n \"| Field | Value |\",\n \"| --- | --- |\"\n );\n for (const [label, value] of actionDetailRows(action)) {\n lines.push(`| ${label} | ${tableValue(value)} |`);\n }\n lines.push(\n \"\",\n \"**Choose in this thread**\",\n \"\",\n `| Decision | Comment command | Effect |`,\n `| --- | --- | --- |`\n );\n for (const decision of action.visibleDecisions) {\n lines.push(`| ${decisionLabel(decision)} | \\`${decision} ${action.index}\\` | ${decisionEffect(decision)} |`);\n }\n }\n\n return lines;\n}\n\nexport function renderAcknowledgement(runId: string): string {\n return `OpenTag picked this up. Run: \\`${runId}\\``;\n}\n\nexport function renderProgress(input: { runId: string; message: string }): string {\n return `OpenTag progress for \\`${input.runId}\\`: ${input.message}`;\n}\n\nexport function renderFinalResult(result: OpenTagRunResult, options: GitHubRenderOptions = {}): string {\n return renderFinalSummaryPresentation(\n createFinalSummaryPresentation({\n result,\n ...(options.receiptContext ? { receiptContext: options.receiptContext } : {}),\n ...(options.auditRunId ? { auditRunId: options.auditRunId } : {})\n })\n );\n}\n\nexport function renderFinalSummaryPresentation(presentation: OpenTagFinalSummaryPresentation): string {\n const lines = [`OpenTag finished with **${presentation.outcome}**.`, \"\", presentation.summary];\n\n if (presentation.verification?.length) {\n lines.push(\"\", \"Verification:\");\n for (const check of presentation.verification) {\n lines.push(`- \\`${check.command}\\`: ${check.outcome}`);\n }\n }\n\n const suggestedActions = renderSuggestedActions(presentation);\n if (suggestedActions.length > 0) {\n lines.push(\"\", ...suggestedActions);\n } else if (presentation.nextActions?.length) {\n lines.push(\"\", `Next action: ${presentation.nextActions[0]}`);\n }\n\n return lines.join(\"\\n\");\n}\n"],"mappings":"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","names":["externalUri"]}
|
package/dist/ingress.d.ts
CHANGED
|
@@ -69,6 +69,13 @@ export type GitHubWebhookAppInput = {
|
|
|
69
69
|
runId?: string;
|
|
70
70
|
}>;
|
|
71
71
|
submitThreadAction?(action: GitHubThreadActionInput): Promise<unknown>;
|
|
72
|
+
recordControlPlaneEvent?(event: {
|
|
73
|
+
type: string;
|
|
74
|
+
severity?: "info" | "warn" | "error";
|
|
75
|
+
subject?: string;
|
|
76
|
+
payload?: Record<string, unknown>;
|
|
77
|
+
}): Promise<void>;
|
|
78
|
+
maxRequestBodyBytes?: number;
|
|
72
79
|
now(): string;
|
|
73
80
|
};
|
|
74
81
|
export type GitHubIngressConfig = {
|
|
@@ -78,6 +85,7 @@ export type GitHubIngressConfig = {
|
|
|
78
85
|
port?: number;
|
|
79
86
|
hostname?: string;
|
|
80
87
|
webhookPath?: string;
|
|
88
|
+
maxRequestBodyBytes?: number;
|
|
81
89
|
};
|
|
82
90
|
export type GitHubIngressHandle = {
|
|
83
91
|
url: string;
|
package/dist/ingress.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ingress.d.ts","sourceRoot":"","sources":["../src/ingress.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C,OAAO,
|
|
1
|
+
{"version":3,"file":"ingress.d.ts","sourceRoot":"","sources":["../src/ingress.ts"],"names":[],"mappings":"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"}
|
package/dist/normalize.d.ts
CHANGED
|
@@ -13,6 +13,8 @@ export type GitHubIssueCommentInput = {
|
|
|
13
13
|
private: boolean;
|
|
14
14
|
receivedAt: string;
|
|
15
15
|
installationId?: number;
|
|
16
|
+
deliveryId?: string;
|
|
17
|
+
signatureVerified?: boolean;
|
|
16
18
|
};
|
|
17
19
|
export type GitHubPullRequestReviewCommentInput = {
|
|
18
20
|
id: string;
|
|
@@ -28,6 +30,8 @@ export type GitHubPullRequestReviewCommentInput = {
|
|
|
28
30
|
private: boolean;
|
|
29
31
|
receivedAt: string;
|
|
30
32
|
installationId?: number;
|
|
33
|
+
deliveryId?: string;
|
|
34
|
+
signatureVerified?: boolean;
|
|
31
35
|
};
|
|
32
36
|
export declare function normalizeGitHubIssueComment(input: GitHubIssueCommentInput): OpenTagEvent | null;
|
|
33
37
|
export declare function normalizeGitHubPullRequestReviewComment(input: GitHubPullRequestReviewCommentInput): OpenTagEvent | null;
|
package/dist/normalize.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../src/normalize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAGvE,MAAM,MAAM,uBAAuB,GAAG;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../src/normalize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAGvE,MAAM,MAAM,uBAAuB,GAAG;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,mCAAmC,GAAG;IAChD,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B,CAAC;AA4GF,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,uBAAuB,GAAG,YAAY,GAAG,IAAI,CAoE/F;AAED,wBAAgB,uCAAuC,CAAC,KAAK,EAAE,mCAAmC,GAAG,YAAY,GAAG,IAAI,CAoEvH"}
|
package/dist/render.d.ts
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
import { type OpenTagRunResult } from "@opentag/core";
|
|
1
|
+
import { type ActionReceiptContext, type OpenTagFinalSummaryPresentation, type OpenTagRunResult } from "@opentag/core";
|
|
2
|
+
export type GitHubRenderOptions = {
|
|
3
|
+
receiptContext?: ActionReceiptContext;
|
|
4
|
+
auditRunId?: string;
|
|
5
|
+
};
|
|
2
6
|
export declare function renderAcknowledgement(runId: string): string;
|
|
3
7
|
export declare function renderProgress(input: {
|
|
4
8
|
runId: string;
|
|
5
9
|
message: string;
|
|
6
10
|
}): string;
|
|
7
|
-
export declare function renderFinalResult(result: OpenTagRunResult): string;
|
|
11
|
+
export declare function renderFinalResult(result: OpenTagRunResult, options?: GitHubRenderOptions): string;
|
|
12
|
+
export declare function renderFinalSummaryPresentation(presentation: OpenTagFinalSummaryPresentation): string;
|
|
8
13
|
//# sourceMappingURL=render.d.ts.map
|
package/dist/render.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,oBAAoB,EAEzB,KAAK,+BAA+B,EAEpC,KAAK,gBAAgB,EACtB,MAAM,eAAe,CAAC;AAEvB,MAAM,MAAM,mBAAmB,GAAG;IAChC,cAAc,CAAC,EAAE,oBAAoB,CAAC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAiEF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAEhF;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,EAAE,OAAO,GAAE,mBAAwB,GAAG,MAAM,CAQrG;AAED,wBAAgB,8BAA8B,CAAC,YAAY,EAAE,+BAA+B,GAAG,MAAM,CAkBpG"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opentag/github",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "GitHub event normalization and callback rendering for OpenTag.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@hono/node-server": "^1.13.7",
|
|
35
35
|
"hono": "^4.6.15",
|
|
36
|
-
"@opentag/client": "0.3.
|
|
37
|
-
"@opentag/core": "0.3.
|
|
36
|
+
"@opentag/client": "0.3.1",
|
|
37
|
+
"@opentag/core": "0.3.1"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"tsup": "^8.3.5",
|