@papi-ai/server 0.7.62 → 0.7.64

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.
@@ -60,6 +60,7 @@ __export(git_exports, {
60
60
  isGitAvailable: () => isGitAvailable,
61
61
  isGitRepo: () => isGitRepo,
62
62
  listGroupedCycleBranches: () => listGroupedCycleBranches,
63
+ listOpenPullRequests: () => listOpenPullRequests,
63
64
  listOrphanFeatBranches: () => listOrphanFeatBranches,
64
65
  mergePullRequest: () => mergePullRequest,
65
66
  normalizeGitUrl: () => normalizeGitUrl,
@@ -346,6 +347,26 @@ function isGhAvailable() {
346
347
  return false;
347
348
  }
348
349
  }
350
+ function listOpenPullRequests(cwd) {
351
+ if (!isGhAvailable()) return null;
352
+ try {
353
+ const out = execFileSync(
354
+ "gh",
355
+ ["pr", "list", "--state", "open", "--limit", "100", "--json", "number,title,author,headRefName,createdAt"],
356
+ { cwd, encoding: "utf-8" }
357
+ );
358
+ const raw = JSON.parse(out);
359
+ return raw.map((p) => ({
360
+ number: p.number,
361
+ title: p.title,
362
+ author: p.author?.login ?? "unknown",
363
+ headRefName: p.headRefName,
364
+ createdAt: p.createdAt
365
+ }));
366
+ } catch {
367
+ return null;
368
+ }
369
+ }
349
370
  function getOriginRepoSlug(cwd) {
350
371
  try {
351
372
  const url = execFileSync("git", ["remote", "get-url", "origin"], {
@@ -1189,12 +1210,12 @@ var init_proxy_adapter = __esm({
1189
1210
  "listContributorReleasePrs",
1190
1211
  "claimReview",
1191
1212
  "getSiblingAds",
1192
- "getSiblingRepoTasks",
1193
- // task-2828 (C339): attributed-intelligence analytics reader — pg-only this cycle.
1194
- // Hosted forwarding needs a SECURITY DEFINER RPC + edge handler (like task-2394 did
1195
- // for getModuleEstimationStats); until then keep it here so hosted degrades to a
1196
- // safe `undefined` rather than forwarding into a 403. Wire under task-2390.
1197
- "getModelOutcomeStats"
1213
+ "getSiblingRepoTasks"
1214
+ // task-2828 (C339): attributed-intelligence analytics reader — pg-only that cycle.
1215
+ // task-2864 (C343): WIRED. getModelOutcomeStats now has an edge case handler (raw
1216
+ // SQL via postgres.js mirroring the pg query + inlined computeModelOutcomes bucketing)
1217
+ // + an ALLOWED_METHODS entry, so it forwards. countPlanRunsForCycle wired alongside it
1218
+ // (task-2860's auto-release guard reader). Both REMOVED from NO_FORWARD.
1198
1219
  // task-2394 (C329) — Batch A wired: findPendingDocActionsForTask,
1199
1220
  // getModuleEstimationStats and getDecisionScorePatterns now have edge case handlers
1200
1221
  // (each backed by a SECURITY DEFINER RPC, migration 20260714140000) plus
@@ -1327,7 +1348,8 @@ var init_proxy_adapter = __esm({
1327
1348
  if (response.status === 401) {
1328
1349
  throw new Error(
1329
1350
  `Auth: Invalid API key \u2014 PAPI_DATA_API_KEY was rejected by the proxy.
1330
- Check PAPI_DATA_API_KEY in your .mcp.json config. You can regenerate it from the PAPI dashboard.
1351
+ This usually means the key was revoked or replaced. Mint a fresh key in the Connect panel on your PAPI dashboard (https://getpapi.ai/hub), then update PAPI_DATA_API_KEY in your .mcp.json.
1352
+ Moving off a local install? Switch to the remote MCP: https://getpapi.ai/docs/install
1331
1353
  (${response.status} on ${method}: ${message})`
1332
1354
  );
1333
1355
  }
@@ -2199,6 +2221,9 @@ var SECTION_HEADERS = [
2199
2221
  "FILES LIKELY TOUCHED",
2200
2222
  "EFFORT"
2201
2223
  ];
2224
+ function normaliseHeaderLine(line) {
2225
+ return line.trim().replace(/^#{1,6}\s*/, "").replace(/^-\s+/, "").replace(/^\*\*(.*?)\*\*$/, "$1").replace(/:\s*$/, "").trim();
2226
+ }
2202
2227
  function splitSections(text) {
2203
2228
  const sections = /* @__PURE__ */ new Map();
2204
2229
  const lines = text.split("\n");
@@ -2211,8 +2236,8 @@ function splitSections(text) {
2211
2236
  }
2212
2237
  };
2213
2238
  for (const line of lines) {
2214
- const trimmed = line.trim();
2215
- const matched = SECTION_HEADERS.find((h) => trimmed === h);
2239
+ const normalised = normaliseHeaderLine(line);
2240
+ const matched = SECTION_HEADERS.find((h) => normalised === h);
2216
2241
  if (matched) {
2217
2242
  flush();
2218
2243
  currentSection = matched;
@@ -2233,7 +2258,10 @@ function parseChecklist(text) {
2233
2258
  return text.split("\n").map((l) => l.replace(/^\s*\[[ x]]\s*/, "").trim()).filter((l) => l.length > 0);
2234
2259
  }
2235
2260
  function parseBuildHandoff(markdown) {
2236
- if (!markdown.includes("BUILD HANDOFF")) return null;
2261
+ if (typeof markdown !== "string" || !markdown.trim()) return null;
2262
+ if (!markdown.includes("BUILD HANDOFF") && splitSections(markdown).size === 0) {
2263
+ return null;
2264
+ }
2237
2265
  const taskIdMatch = markdown.match(/BUILD HANDOFF\s*—\s*(task-\d+)/);
2238
2266
  const taskTitleMatch = markdown.match(/^Task:\s*(.+)$/m);
2239
2267
  const cycleMatch = markdown.match(/^Cycle:\s*(\d+)$/m);