Pr-comments
Functions
postPRComment
async function postPRComment(config: PRCommentConfig, issues: DocumentationIssue[]): Promise<CommentResult>
Use postPRComment to automatically surface documentation issues as a GitHub PR review comment, so contributors see exactly what's missing before their code gets merged.
Reach for this in a CI pipeline or GitHub Action after running skrypt's analysis on a pull request. It's the last step in an automated doc-quality gate: scan the changed files, collect any DocumentationIssue objects, then call this to post them as a structured comment on the PR.
The function posts a single review comment to the GitHub Pull Requests API. If config.token is not provided, it falls back to the GITHUB_TOKEN environment variable — which is automatically available in GitHub Actions.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
config | PRCommentConfig | Yes | GitHub connection details: repo owner, repo name, PR number, and optionally a personal access token with repo scope |
config.token | string | No | GitHub personal access token — falls back to GITHUB_TOKEN env var, so you can omit this in GitHub Actions |
issues | DocumentationIssue[] | Yes | The documentation problems to report, typically the output of skrypt's analysis step. An empty array posts a ✅ all-clear comment |
Returns
Returns a Promise<CommentResult> with the outcome of the API call — including the URL of the posted comment (result.commentUrl) so you can link to it in logs or downstream steps.
Heads up
- The token needs
reposcope for private repositories. For public repos, the defaultGITHUB_TOKENin GitHub Actions is sufficient. - Calling this multiple times on the same PR creates multiple comments. If you're running this on every push, consider deleting or updating the previous comment to avoid noise.
Example:
type PRCommentConfig = {
owner: string;
repo: string;
prNumber: number;
token?: string;
};
type DocumentationIssue = {
file: string;
line: number;
element: string;
message: string;
severity: "error" | "warning";
};
type CommentResult = {
success: boolean;
commentUrl: string;
issueCount: number;
};
async function postPRComment(
config: PRCommentConfig,
issues: DocumentationIssue[]
): Promise<CommentResult> {
const token = config.token || process.env.GITHUB_TOKEN;
const body =
issues.length === 0
? "✅ **skrypt**: All public API members are documented."
: [
`## 📄 Documentation Issues (${issues.length})`,
"",
"skrypt found the following documentation problems in this PR:",
"",
...issues.map(
(i) =>
`- **${i.severity.toUpperCase()}** \`${i.file}:${i.line}\` — \`${i.element}\`: ${i.message}`
),
"",
"_Fix these before merging to keep your API docs complete._",
].join("\n");
const response = await fetch(
`https://api.github.com/repos/${config.owner}/${config.repo}/issues/${config.prNumber}/comments`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
Accept: "application/vnd.github+json",
},
body: JSON.stringify({ body }),
}
);
if (!response.ok) {
throw new Error(`GitHub API error: ${response.status} ${response.statusText}`);
}
const data = await response.json();
return {
success: true,
commentUrl: data.html_url,
issueCount: issues.length,
};
}
// Example: post doc issues found on a PR in CI
const config: PRCommentConfig = {
owner: "acme-corp",
repo: "payments-sdk",
prNumber: 142,
// token omitted — reads from GITHUB_TOKEN in CI
};
const issues: DocumentationIssue[] = [
{
file: "src/client.ts",
line: 34,
element: "PaymentsClient.charge",
message: "Missing @param description for `amount`",
severity: "error",
},
{
file: "src/webhooks.ts",
line: 89,
element: "verifySignature",
message: "No return type documented",
severity: "warning",
},
];
try {
const result = await postPRComment(config, issues);
console.log(`Posted ${result.issueCount} issue(s) → ${result.commentUrl}`);
// Posted 2 issue(s) → https://github.com/acme-corp/payments-sdk/pull/142#issuecomment-1984201337
} catch (err) {
console.error("Failed to post PR comment:", err);
process.exit(1);
}
postInlineComments
async function postInlineComments(config: PRCommentConfig, issues: DocumentationIssue[]): Promise<CommentResult[]>
Use postInlineComments to attach AI-generated documentation feedback directly to the lines of code that need it in a GitHub pull request review.
Reach for this after running skrypt's documentation analysis on a PR's changed files — it's the step that turns a list of documentation issues into actionable inline review comments that reviewers and authors see in the GitHub diff view.
Each issue in the issues array is mapped to a specific file path and line number, and posted as an inline comment on the PR. Authentication uses the token from config or falls back to the GITHUB_TOKEN environment variable, so it works out of the box in GitHub Actions.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
config | PRCommentConfig | Yes | GitHub PR context and auth — includes the repo owner, repo name, PR number, and optionally a personal access token. If token is omitted, GITHUB_TOKEN must be set in the environment. |
issues | DocumentationIssue[] | Yes | Documentation problems to post, each with a file path, line number, and message. An empty array is a no-op and returns []. |
Returns
Returns a Promise<CommentResult[]> — one result per issue, each indicating whether the comment was successfully posted and the URL of the created comment. Use the results to surface failures (e.g., permission errors or invalid line numbers) without the entire batch silently dropping.
Heads up
- Line numbers must correspond to lines in the PR diff, not the full file. Comments on lines outside the diff will fail silently or return an error result — validate line numbers against the diff before calling this.
- Requires the GitHub token to have
pull_requests: writepermission. The defaultGITHUB_TOKENin GitHub Actions has this, but fine-grained personal access tokens may not.
Example:
type PRCommentConfig = {
token?: string;
owner: string;
repo: string;
pullNumber: number;
commitSha: string;
};
type DocumentationIssue = {
path: string;
line: number;
message: string;
severity: "error" | "warning" | "info";
};
type CommentResult = {
success: boolean;
issueIndex: number;
commentUrl?: string;
error?: string;
};
// Self-contained mock of postInlineComments
async function postInlineComments(
config: PRCommentConfig,
issues: DocumentationIssue[]
): Promise<CommentResult[]> {
const token = config.token || process.env.GITHUB_TOKEN;
if (!token) throw new Error("No GitHub token provided");
const results: CommentResult[] = [];
for (let i = 0; i < issues.length; i++) {
const issue = issues[i];
// Simulate GitHub API call
const fakeCommentId = Math.floor(Math.random() * 900000000) + 100000000;
results.push({
success: true,
issueIndex: i,
commentUrl: `https://github.com/${config.owner}/${config.repo}/pull/${config.pullNumber}#discussion_r${fakeCommentId}`,
});
}
return results;
}
const config: PRCommentConfig = {
token: "ghp_A1B2C3D4E5F6G7H8I9J0K1L2M3N4O5P6Q7",
owner: "acme-corp",
repo: "payments-api",
pullNumber: 142,
commitSha: "a3f8c2e1d4b7690f2c5e8a1b3d6f9c2e4a7b0d3",
};
const issues: DocumentationIssue[] = [
{
path: "src/billing/invoice.ts",
line: 34,
message: "Missing @param documentation for `customerId` — callers won't know this expects a Stripe customer ID.",
severity: "warning",
},
{
path: "src/billing/invoice.ts",
line: 61,
message: "Return type is undocumented. Add @returns describing the shape of the invoice object.",
severity: "error",
},
{
path: "src/webhooks/handler.ts",
line: 12,
message: "Function has no JSDoc block. Add a description explaining which Stripe events this handles.",
severity: "warning",
},
];
async function main() {
try {
const results = await postInlineComments(config, issues);
const succeeded = results.filter((r) => r.success);
const failed = results.filter((r) => !r.success);
console.log(`Posted ${succeeded.length}/${results.length} inline comments successfully.`);
succeeded.forEach((r) => {
console.log(` ✓ Issue ${r.issueIndex}: ${r.commentUrl}`);
});
if (failed.length > 0) {
console.warn(` ✗ ${failed.length} comment(s) failed:`);
failed.forEach((r) => console.warn(` Issue ${r.issueIndex}: ${r.error}`));
}
} catch (err) {
console.error("Failed to post comments:", err);
process.exit(1);
}
}
main();
// Expected output:
// Posted 3/3 inline comments successfully.
// ✓ Issue 0: https://github.com/acme-corp/payments-api/pull/142#discussion_r583920471
// ✓ Issue 1: https://github.com/acme-corp/payments-api/pull/142#discussion_r294817362
// ✓ Issue 2: https://github.com/acme-corp/payments-api/pull/142#discussion_r748291053
analyzePRForDocs
async function analyzePRForDocs(config: PRCommentConfig, _options: { checkExamples?: boolean } = {}): Promise<DocumentationIssue[]>
Use analyzePRForDocs to scan a pull request and surface every function, class, or export that's missing or has incomplete documentation — before it merges.
Reach for this in a CI workflow or GitHub Action when you want to enforce documentation standards on new code. It pairs naturally with a PR comment bot: run it on each push, then post the returned issues as inline review comments so contributors know exactly what to fix.
It fetches the PR's changed files, parses the TypeScript AST, and compares exported symbols against their docstrings — flagging anything undocumented, missing parameter descriptions, or lacking a return type annotation.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
config | PRCommentConfig | Yes | GitHub connection details and PR coordinates — includes token, owner, repo, and prNumber. The token needs pull_requests: read and contents: read permissions. |
_options.checkExamples | boolean | No | When true, also flags documented symbols that have no @example block. Defaults to false, so example coverage is opt-in. |
Returns
Returns a Promise<DocumentationIssue[]> — an array of issues, each describing a specific symbol and what's wrong with its docs. An empty array means the PR is clean. Pass the array to your comment formatter or fail the CI step if issues.length > 0.
Heads up
- The
_optionsparameter is reserved for future use —checkExamplesis the only key currently respected, and behavior may expand in later versions. - The function reads from GitHub at call time, so it reflects the PR's state at that moment. Call it after the push event fires, not before the branch is updated.
Example:
type PRCommentConfig = {
token: string;
owner: string;
repo: string;
prNumber: number;
};
type DocumentationIssue = {
symbol: string;
file: string;
line: number;
issue: "missing_docstring" | "missing_param_docs" | "missing_return_doc" | "missing_example";
message: string;
};
// Inline mock — replace with real analyzePRForDocs from autodocs
async function analyzePRForDocs(
config: PRCommentConfig,
_options: { checkExamples?: boolean } = {}
): Promise<DocumentationIssue[]> {
console.log(
`Scanning PR #${config.prNumber} on ${config.owner}/${config.repo}...`
);
// Simulated response from GitHub + AST analysis
return [
{
symbol: "createPaymentIntent",
file: "src/payments/intents.ts",
line: 42,
issue: "missing_param_docs",
message: "Parameters 'amount' and 'currency' are undocumented.",
},
{
symbol: "validateWebhook",
file: "src/webhooks/validate.ts",
line: 17,
issue: "missing_return_doc",
message: "Return type is undocumented.",
},
];
}
async function main() {
const config: PRCommentConfig = {
token: "ghp_A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7",
owner: "acme-corp",
repo: "payments-sdk",
prNumber: 284,
};
try {
const issues = await analyzePRForDocs(config, { checkExamples: true });
if (issues.length === 0) {
console.log("✅ No documentation issues found.");
process.exit(0);
}
console.log(`❌ Found ${issues.length} documentation issue(s):\n`);
for (const issue of issues) {
console.log(` [${issue.symbol}] ${issue.file}:${issue.line}`);
console.log(` → ${issue.message}\n`);
}
// Fail CI if issues exist
process.exit(1);
} catch (err) {
console.error("Failed to analyze PR:", err);
process.exit(1);
}
}
main();
// Expected output:
// Scanning PR #284 on acme-corp/payments-sdk...
// ❌ Found 2 documentation issue(s):
//
// [createPaymentIntent] src/payments/intents.ts:42
// → Parameters 'amount' and 'currency' are undocumented.
//
// [validateWebhook] src/webhooks/validate.ts:17
// → Return type is undocumented.