@papi-ai/server 0.7.57 → 0.7.58

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
@@ -8081,7 +8081,9 @@ import {
8081
8081
  // src/universal-frame.ts
8082
8082
  var UNIVERSAL_FRAME = `PAPI gives this project a structured plan \u2192 build \u2192 review cycle, persisted across sessions. Follow it:
8083
8083
 
8084
- 1. ORIENT FIRST. At the start of every session, call \`orient\` (or \`papi\`) before anything else \u2014 it returns the current cycle, what's in flight, and the recommended next action. Re-run it after any context compression.
8084
+ 0. NEW HERE? If PAPI has never been set up for this project (no cycles yet, or \`orient\` says the board is empty), call \`setup\` FIRST \u2014 it generates the Product Brief and scaffolds the workflow. Then run \`plan\` to create the first cycle. This is the required first step for a brand-new project; everything below assumes setup has already run.
8085
+
8086
+ 1. ORIENT FIRST (once set up). At the start of every session, call \`orient\` (or \`papi\`) before anything else \u2014 it returns the current cycle, what's in flight, and the recommended next action. Re-run it after any context compression.
8085
8087
 
8086
8088
  2. THE CYCLE, IN ORDER: \`plan\` (once per cycle) \u2192 \`build_list\` (pick a task) \u2192 \`build_execute <task>\` to start \u2192 implement the task from its BUILD HANDOFF \u2192 \`build_execute\` again to complete with a build report \u2192 \`review_submit\` \u2192 \`release\` when every cycle task is done.
8087
8089
 
@@ -9301,7 +9303,14 @@ function buildPlanUserMessage(ctx) {
9301
9303
  parts.push("### Pre-Assigned Tasks", "", ctx.preAssignedTasks, "");
9302
9304
  }
9303
9305
  if (ctx.codebaseScan) {
9304
- parts.push("### Codebase Scan (existing implementations)", "", ctx.codebaseScan, "");
9306
+ parts.push(
9307
+ "### Codebase Scan (existing implementations)",
9308
+ "",
9309
+ "Any task tagged **PREMISE-UNVERIFIED** is a discovery/auto-triaged item whose premise references code that already exists \u2014 before scheduling it, verify the premise still holds against the live code; if it is already resolved, deprioritise or cancel it rather than spending a build slot re-verifying shipped work.",
9310
+ "",
9311
+ ctx.codebaseScan,
9312
+ ""
9313
+ );
9305
9314
  }
9306
9315
  if (ctx.buildPatterns) {
9307
9316
  parts.push("### Build Patterns", "", ctx.buildPatterns, "");
@@ -10714,6 +10723,10 @@ function extractSearchTerms(title, notes) {
10714
10723
  }
10715
10724
  return terms.slice(0, 8);
10716
10725
  }
10726
+ function isDiscoveryTask(task) {
10727
+ if (task.taskType === "discovery") return true;
10728
+ return /^\s*\[auto-triaged\]/i.test(task.title);
10729
+ }
10717
10730
  function grepForTerm(projectRoot, term) {
10718
10731
  try {
10719
10732
  const result = execSync2(
@@ -10747,19 +10760,24 @@ function scanCodebaseForTasks(projectRoot, tasks) {
10747
10760
  }
10748
10761
  }
10749
10762
  if (matches.length > 0) {
10750
- results.push({ taskId: task.id, terms, matches });
10763
+ results.push({ taskId: task.id, terms, matches, premiseUnverified: isDiscoveryTask(task) });
10751
10764
  }
10752
10765
  if (Date.now() - startTime > 5e3) break;
10753
10766
  }
10754
10767
  if (results.length === 0) return "";
10755
10768
  const elapsed = Date.now() - startTime;
10756
10769
  console.error(`[codebase-scan] scanned ${tasks.length} tasks in ${elapsed}ms \u2014 ${results.length} with matches`);
10770
+ const flaggedCount = results.filter((r) => r.premiseUnverified).length;
10771
+ const flagNote = flaggedCount > 0 ? ` \u2014 ${flaggedCount} discovery/auto-triaged task(s) flagged PREMISE-UNVERIFIED (verify before scheduling)` : "";
10757
10772
  const lines = [
10758
- `Codebase scan found existing implementations for ${results.length}/${tasks.length} candidate tasks (${elapsed}ms):`,
10773
+ `Codebase scan found existing implementations for ${results.length}/${tasks.length} candidate tasks (${elapsed}ms)${flagNote}:`,
10759
10774
  ""
10760
10775
  ];
10761
10776
  for (const result of results) {
10762
10777
  lines.push(`**${result.taskId}:**`);
10778
+ if (result.premiseUnverified) {
10779
+ lines.push(` \u26A0 PREMISE-UNVERIFIED: discovery/auto-triaged task whose premise references code already present in the repo \u2014 verify the premise still holds; it may already be resolved.`);
10780
+ }
10763
10781
  for (const match of result.matches.slice(0, 3)) {
10764
10782
  const fileList = match.files.slice(0, 3).join(", ");
10765
10783
  const moreCount = match.files.length > 3 ? ` (+${match.files.length - 3} more)` : "";
@@ -12643,7 +12661,7 @@ async function preparePlan(adapter2, config2, filters, focus, force, handoffsOnl
12643
12661
  t = startTimer();
12644
12662
  try {
12645
12663
  const scanTasks = await adapter2.queryBoard({ status: ["Backlog", "In Cycle", "Ready"], compact: true });
12646
- const candidates = scanTasks.filter((task) => task.priority !== "P3 Low" && task.scopeClass !== "brief").slice(0, 15).map((task) => ({ id: task.id, title: task.title, notes: task.notes }));
12664
+ const candidates = scanTasks.filter((task) => task.priority !== "P3 Low" && task.scopeClass !== "brief").slice(0, 15).map((task) => ({ id: task.id, title: task.title, notes: task.notes, taskType: task.taskType }));
12647
12665
  const scanResult = scanCodebaseForTasks(config2.projectRoot, candidates);
12648
12666
  if (scanResult) context.codebaseScan = scanResult;
12649
12667
  } catch (err) {
@@ -18830,6 +18848,7 @@ init_telemetry();
18830
18848
  import { writeFile as writeFile3, readFile as readFile5 } from "fs/promises";
18831
18849
  import { join as join10 } from "path";
18832
18850
  import { execFileSync as execFileSync4 } from "child_process";
18851
+ import { isSensitiveChangelogLine } from "@papi-ai/shared";
18833
18852
  init_git();
18834
18853
  var INITIAL_RELEASE_NOTES = `# Changelog
18835
18854
 
@@ -18841,7 +18860,9 @@ All notable changes to this project are documented in this file.
18841
18860
  `;
18842
18861
  function generateChangelogSection(version, commits) {
18843
18862
  const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
18844
- const filtered = commits.filter((c) => !new RegExp(`^[a-f0-9]+ release: ${version}$`).test(c));
18863
+ const filtered = commits.filter(
18864
+ (c) => !new RegExp(`^[a-f0-9]+ release: ${version}$`).test(c) && !isSensitiveChangelogLine(c)
18865
+ );
18845
18866
  const commitList = filtered.map((c) => `- ${c}`).join("\n");
18846
18867
  return `## ${version} \u2014 ${date}
18847
18868
 
@@ -29212,6 +29233,7 @@ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/
29212
29233
  var BEARER_PREFIX = "papi_";
29213
29234
  var BEARER_REGEX = /^(papi_|papi_oauth_)[a-f0-9]{64}$/;
29214
29235
  var RESOURCE_METADATA_URL = process.env["PAPI_RESOURCE_METADATA_URL"] ?? "https://getpapi.ai/.well-known/oauth-protected-resource";
29236
+ var GLAMA_MAINTAINER_EMAIL = process.env["GLAMA_MAINTAINER_EMAIL"] ?? "cathal@getpapi.ai";
29215
29237
  var DASHBOARD_ORIGIN = process.env["PAPI_DASHBOARD_URL"] ?? "https://getpapi.ai";
29216
29238
  var MCP_RESOURCE_URL = process.env["NEXT_PUBLIC_MCP_URL"] ?? "https://mcp.getpapi.ai";
29217
29239
  var FRIENDLY_GET_HTML = `<!doctype html>
@@ -29357,6 +29379,20 @@ function startHttpTransport(opts) {
29357
29379
  );
29358
29380
  return;
29359
29381
  }
29382
+ if (req.method === "GET" && req.url === "/.well-known/glama.json") {
29383
+ res.writeHead(200, {
29384
+ "Content-Type": "application/json",
29385
+ "Cache-Control": "public, max-age=3600",
29386
+ ...cors
29387
+ });
29388
+ res.end(
29389
+ JSON.stringify({
29390
+ $schema: "https://glama.ai/mcp/schemas/connector.json",
29391
+ maintainers: [{ email: GLAMA_MAINTAINER_EMAIL }]
29392
+ })
29393
+ );
29394
+ return;
29395
+ }
29360
29396
  if (req.method === "GET" && req.url === "/.well-known/oauth-authorization-server") {
29361
29397
  res.writeHead(302, {
29362
29398
  Location: `${DASHBOARD_ORIGIN}/.well-known/oauth-authorization-server`,
package/dist/prompts.js CHANGED
@@ -529,7 +529,14 @@ function buildPlanUserMessage(ctx) {
529
529
  parts.push("### Pre-Assigned Tasks", "", ctx.preAssignedTasks, "");
530
530
  }
531
531
  if (ctx.codebaseScan) {
532
- parts.push("### Codebase Scan (existing implementations)", "", ctx.codebaseScan, "");
532
+ parts.push(
533
+ "### Codebase Scan (existing implementations)",
534
+ "",
535
+ "Any task tagged **PREMISE-UNVERIFIED** is a discovery/auto-triaged item whose premise references code that already exists \u2014 before scheduling it, verify the premise still holds against the live code; if it is already resolved, deprioritise or cancel it rather than spending a build slot re-verifying shipped work.",
536
+ "",
537
+ ctx.codebaseScan,
538
+ ""
539
+ );
533
540
  }
534
541
  if (ctx.buildPatterns) {
535
542
  parts.push("### Build Patterns", "", ctx.buildPatterns, "");
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@papi-ai/server",
3
- "version": "0.7.57",
4
- "description": "PAPI MCP server \u2014 AI-powered sprint planning, build execution, and strategy review for software projects",
3
+ "version": "0.7.58",
4
+ "description": "PAPI MCP server AI-powered sprint planning, build execution, and strategy review for software projects",
5
5
  "license": "Elastic-2.0",
6
6
  "mcpName": "io.github.getpapi/papi",
7
7
  "type": "module",