poe-code 3.0.336 → 3.0.338

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 CHANGED
@@ -53828,6 +53828,8 @@ function parseReviewDiff(diffText) {
53828
53828
  status: "modified",
53829
53829
  hunks: [],
53830
53830
  reviewableLines: [],
53831
+ leftLineSet: /* @__PURE__ */ new Set(),
53832
+ rightContextLineSet: /* @__PURE__ */ new Set(),
53831
53833
  reviewableLineSet: /* @__PURE__ */ new Set()
53832
53834
  };
53833
53835
  continue;
@@ -53880,11 +53882,13 @@ function parseReviewDiff(diffText) {
53880
53882
  }
53881
53883
  if (line.startsWith("-") && !line.startsWith("---")) {
53882
53884
  currentHunk.lines.push({ side: "LEFT", line: oldLine, text: line });
53885
+ currentFile.leftLineSet.add(oldLine);
53883
53886
  oldLine += 1;
53884
53887
  continue;
53885
53888
  }
53886
53889
  if (line.startsWith(" ")) {
53887
53890
  currentHunk.lines.push({ side: "RIGHT", line: newLine, text: line });
53891
+ currentFile.rightContextLineSet.add(newLine);
53888
53892
  currentFile.reviewableLineSet.add(newLine);
53889
53893
  oldLine += 1;
53890
53894
  newLine += 1;
@@ -53902,6 +53906,8 @@ function parseReviewDiff(diffText) {
53902
53906
  files: publicFiles,
53903
53907
  fileOrder: new Map(publicFiles.map((file, index) => [file.path, index])),
53904
53908
  reviewableLinesByPath: new Map(files.map((file) => [file.path, file.reviewableLineSet])),
53909
+ leftLinesByPath: new Map(files.map((file) => [file.path, file.leftLineSet])),
53910
+ rightContextLinesByPath: new Map(files.map((file) => [file.path, file.rightContextLineSet])),
53905
53911
  rendered: publicFiles.map(renderReviewFile).join("\n\n")
53906
53912
  };
53907
53913
  }
@@ -53909,20 +53915,35 @@ function validateInlineComments(comments, context) {
53909
53915
  const accepted = [];
53910
53916
  const seen = /* @__PURE__ */ new Set();
53911
53917
  for (const comment of comments) {
53912
- const path176 = comment.path.trim();
53918
+ const path176 = comment.path;
53913
53919
  const body = comment.body.trim();
53914
- if (!path176 || !body || !Number.isInteger(comment.line) || comment.line < 1) {
53920
+ if (path176.length === 0 || !body || !Number.isInteger(comment.line) || comment.line < 1) {
53915
53921
  throw new Error("Inline review comments require path, positive line, and body.");
53916
53922
  }
53923
+ if (comment.side === "LEFT") {
53924
+ throw new Error(
53925
+ `Inline comment target ${path176}:${comment.line} is a left-side diff target; only right-side comments are supported.`
53926
+ );
53927
+ }
53917
53928
  if (!context.reviewableLinesByPath.get(path176)?.has(comment.line)) {
53918
53929
  throw new Error(
53919
53930
  `Inline comment target ${path176}:${comment.line} is not a valid right-side diff target.`
53920
53931
  );
53921
53932
  }
53933
+ if (!comment.side && context.leftLinesByPath.get(path176)?.has(comment.line) && context.rightContextLinesByPath.get(path176)?.has(comment.line)) {
53934
+ throw new Error(
53935
+ `Inline comment target ${path176}:${comment.line} is ambiguous; specify side RIGHT to target the right-side diff line.`
53936
+ );
53937
+ }
53922
53938
  const key2 = `${path176}\0${comment.line}\0${body}`;
53923
53939
  if (!seen.has(key2)) {
53924
53940
  seen.add(key2);
53925
- accepted.push({ path: path176, line: comment.line, body });
53941
+ accepted.push({
53942
+ path: path176,
53943
+ line: comment.line,
53944
+ ...comment.side ? { side: comment.side } : {},
53945
+ body
53946
+ });
53926
53947
  }
53927
53948
  }
53928
53949
  accepted.sort((left, right) => {
@@ -54101,7 +54122,7 @@ var init_github_api = __esm({
54101
54122
  // packages/github-review/src/pr-url.ts
54102
54123
  function parseUrl2(value) {
54103
54124
  try {
54104
- return new URL(value);
54125
+ return new URL(value.trim());
54105
54126
  } catch {
54106
54127
  return null;
54107
54128
  }
@@ -54121,6 +54142,9 @@ function parsePathPart(value) {
54121
54142
  return null;
54122
54143
  }
54123
54144
  }
54145
+ function formatPullRequestUrl(ref) {
54146
+ return `https://${ref.host}/${encodeURIComponent(ref.owner)}/${encodeURIComponent(ref.repo)}/pull/${ref.number}`;
54147
+ }
54124
54148
  function parseGitHubPullRequestRef(prUrl) {
54125
54149
  const parsed = parseUrl2(prUrl);
54126
54150
  if (!parsed || parsed.protocol !== "https:" || !parsed.hostname || parsed.username || parsed.password) {
@@ -54136,20 +54160,20 @@ function parseGitHubPullRequestRef(prUrl) {
54136
54160
  if (!owner || !repo || !Number.isSafeInteger(number) || number <= 0) {
54137
54161
  return null;
54138
54162
  }
54139
- return {
54163
+ const ref = {
54140
54164
  host: parsed.host.toLowerCase(),
54141
54165
  owner,
54142
54166
  repo,
54143
- number,
54144
- url: prUrl
54167
+ number
54145
54168
  };
54169
+ return { ...ref, url: formatPullRequestUrl(ref) };
54146
54170
  }
54147
54171
  function canonicalPullRequestUrl(prUrl) {
54148
54172
  const ref = parseGitHubPullRequestRef(prUrl);
54149
54173
  if (!ref) {
54150
54174
  return prUrl;
54151
54175
  }
54152
- return `https://${ref.host}/${encodeURIComponent(ref.owner)}/${encodeURIComponent(ref.repo)}/pull/${ref.number}`;
54176
+ return ref.url;
54153
54177
  }
54154
54178
  var init_pr_url = __esm({
54155
54179
  "packages/github-review/src/pr-url.ts"() {
@@ -54212,12 +54236,13 @@ function parseJson2(stdout, action) {
54212
54236
  }
54213
54237
  }
54214
54238
  function ghPrView(prUrl, fields, options = {}) {
54215
- requirePullRequestRef(prUrl);
54239
+ const ref = requirePullRequestRef(prUrl);
54240
+ const canonicalPrUrl = ref.url;
54216
54241
  const requestedFields = dedupe([...fields]);
54217
- const result = runGh(["pr", "view", prUrl, "--json", requestedFields.join(",")], options);
54242
+ const result = runGh(["pr", "view", canonicalPrUrl, "--json", requestedFields.join(",")], options);
54218
54243
  if (result.code === 0) {
54219
54244
  const parsed2 = parseJsonRecord(result.stdout, "gh pr view");
54220
- parsed2.url ??= prUrl;
54245
+ parsed2.url ??= canonicalPrUrl;
54221
54246
  return parsed2;
54222
54247
  }
54223
54248
  const availableFields = parseGhAvailableFields(result.stderr);
@@ -54225,17 +54250,20 @@ function ghPrView(prUrl, fields, options = {}) {
54225
54250
  if (fallbackFields.length === 0 || fallbackFields.length === requestedFields.length) {
54226
54251
  throw new Error(result.stderr.trim() || result.stdout.trim() || "gh pr view failed");
54227
54252
  }
54228
- const fallback = runGh(["pr", "view", prUrl, "--json", fallbackFields.join(",")], options);
54253
+ const fallback = runGh(
54254
+ ["pr", "view", canonicalPrUrl, "--json", fallbackFields.join(",")],
54255
+ options
54256
+ );
54229
54257
  if (fallback.code !== 0) {
54230
54258
  throw new Error(fallback.stderr.trim() || fallback.stdout.trim() || "gh pr view failed");
54231
54259
  }
54232
54260
  const parsed = parseJsonRecord(fallback.stdout, "gh pr view");
54233
- parsed.url ??= prUrl;
54261
+ parsed.url ??= canonicalPrUrl;
54234
54262
  return parsed;
54235
54263
  }
54236
54264
  function ghPrDiff(prUrl, options = {}) {
54237
- requirePullRequestRef(prUrl);
54238
- return runGhOrThrow(["pr", "diff", prUrl], options);
54265
+ const ref = requirePullRequestRef(prUrl);
54266
+ return runGhOrThrow(["pr", "diff", ref.url], options);
54239
54267
  }
54240
54268
  function ghApiJson(prUrl, args, payload, options = {}) {
54241
54269
  const ref = requirePullRequestRef(prUrl);
@@ -54408,18 +54436,21 @@ function reviewEndpoint(prUrl) {
54408
54436
  }
54409
54437
  return `repos/${ref.owner}/${ref.repo}/pulls/${ref.number}/reviews`;
54410
54438
  }
54411
- function validateReviewComments(comments) {
54412
- for (const comment of comments) {
54413
- if (!comment.path.trim()) {
54439
+ function normalizeReviewComments(comments) {
54440
+ return comments.map((comment) => {
54441
+ const path176 = comment.path.trim();
54442
+ const body = comment.body.trim();
54443
+ if (!path176) {
54414
54444
  throw new Error("Review comment path must be non-empty.");
54415
54445
  }
54416
54446
  if (!Number.isSafeInteger(comment.line) || comment.line <= 0) {
54417
54447
  throw new Error("Review comment line must be a positive integer.");
54418
54448
  }
54419
- if (!comment.body.trim()) {
54449
+ if (!body) {
54420
54450
  throw new Error("Review comment body must be non-empty.");
54421
54451
  }
54422
- }
54452
+ return { path: path176, line: comment.line, body };
54453
+ });
54423
54454
  }
54424
54455
  function submissionFromResponse(response) {
54425
54456
  return {
@@ -54432,8 +54463,7 @@ function submitPullRequestReview(input) {
54432
54463
  if (!REVIEW_DECISIONS.has(input.decision)) {
54433
54464
  throw new Error(`Invalid pull request review decision: ${input.decision}`);
54434
54465
  }
54435
- const comments = input.comments ?? [];
54436
- validateReviewComments(comments);
54466
+ const comments = normalizeReviewComments(input.comments ?? []);
54437
54467
  const response = ghApiJson(
54438
54468
  prUrl,
54439
54469
  ["--method", "POST", reviewEndpoint(prUrl)],
@@ -54531,9 +54561,30 @@ function isAtOrAfter(value, since) {
54531
54561
  if (!value) return false;
54532
54562
  return new Date(value).getTime() >= new Date(since).getTime();
54533
54563
  }
54534
- function createdAt(record, kind) {
54564
+ function rawCreatedAt(record, kind) {
54535
54565
  return kind === "review_body" ? text4(record, "submitted_at") ?? text4(record, "created_at") : text4(record, "created_at") ?? text4(record, "submitted_at");
54536
54566
  }
54567
+ function createdAt(record, kind) {
54568
+ const value = rawCreatedAt(record, kind);
54569
+ if (!value) {
54570
+ return null;
54571
+ }
54572
+ const timestamp = new Date(value);
54573
+ if (Number.isNaN(timestamp.getTime())) {
54574
+ throw new Error(`Invalid GitHub review-history ${kind} timestamp: ${value}`);
54575
+ }
54576
+ return timestamp.toISOString();
54577
+ }
54578
+ function dedupeRepos(repos) {
54579
+ const deduped = /* @__PURE__ */ new Map();
54580
+ for (const repo of repos) {
54581
+ const key2 = repo.toLowerCase();
54582
+ if (!deduped.has(key2)) {
54583
+ deduped.set(key2, repo);
54584
+ }
54585
+ }
54586
+ return [...deduped.values()];
54587
+ }
54537
54588
  async function* fetchReviewHistory(options) {
54538
54589
  if (!options.username.trim()) {
54539
54590
  throw new Error("GitHub review-history username is required.");
@@ -54541,7 +54592,7 @@ async function* fetchReviewHistory(options) {
54541
54592
  if (options.maxComments !== void 0 && (!Number.isInteger(options.maxComments) || options.maxComments < 1)) {
54542
54593
  throw new Error("Review-history maxComments must be a positive integer.");
54543
54594
  }
54544
- const repos = [...new Set(options.repos)];
54595
+ const repos = dedupeRepos(options.repos);
54545
54596
  for (const repo of repos) {
54546
54597
  if (!validRepo(repo)) {
54547
54598
  throw new Error(`Invalid GitHub repository name: ${repo}`);
@@ -138111,7 +138162,7 @@ var init_package2 = __esm({
138111
138162
  "package.json"() {
138112
138163
  package_default2 = {
138113
138164
  name: "poe-code",
138114
- version: "3.0.336",
138165
+ version: "3.0.338",
138115
138166
  description: "CLI tool to configure Poe API for developer workflows.",
138116
138167
  type: "module",
138117
138168
  main: "./dist/index.js",