@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 +42 -6
- package/dist/prompts.js +8 -1
- package/package.json +2 -2
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
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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.
|
|
4
|
-
"description": "PAPI MCP server
|
|
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",
|