小橘 57c740cdde Revert "chore(workflow): auto-generated commit"
This reverts commit 75f2768a8c7713879bb2ab564f42f24bc609338e.
2026-04-28 15:49:22 +00:00

68 lines
1.7 KiB
TypeScript

import type { Role, RoleResult, StartStep } from "@uncaged/nerve-core";
export type IntakeMeta = {
issueUrl: string;
host: string | null;
owner: string | null;
repo: string | null;
issueNumber: number | null;
valid: boolean;
failureKind: "none" | "invalid_input";
failureReason: string | null;
};
function parseIssueUrl(raw: string): IntakeMeta {
const issueUrl = raw.trim();
const match = issueUrl.match(/^https?:\/\/([^/\s]+)\/([^/\s]+)\/([^/\s]+)\/issues\/(\d+)(?:[/?#].*)?$/i);
if (match === null) {
return {
issueUrl,
host: null,
owner: null,
repo: null,
issueNumber: null,
valid: false,
failureKind: "invalid_input",
failureReason: `invalid issue URL: ${issueUrl}`,
};
}
const issueNumber = Number(match[4]);
if (!Number.isInteger(issueNumber) || issueNumber <= 0) {
return {
issueUrl,
host: null,
owner: null,
repo: null,
issueNumber: null,
valid: false,
failureKind: "invalid_input",
failureReason: `invalid issue number: ${match[4]}`,
};
}
return {
issueUrl,
host: match[1],
owner: match[2],
repo: match[3],
issueNumber,
valid: true,
failureKind: "none",
failureReason: null,
};
}
export function buildIntakeRole(): Role<IntakeMeta> {
return async (start: StartStep): Promise<RoleResult<IntakeMeta>> => {
const parsed = parseIssueUrl(start.content);
if (!parsed.valid) {
return { content: parsed.failureReason ?? "invalid issue URL", meta: parsed };
}
return {
content: `parsed issue URL: ${parsed.owner}/${parsed.repo}#${parsed.issueNumber} @ ${parsed.host}`,
meta: parsed,
};
};
}