@papi-ai/server 0.7.84 → 0.7.85
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/backfill-cycle-metrics.js +80 -9
- package/dist/index.js +562 -77
- package/dist/prompts.js +7 -3
- package/package.json +4 -4
|
@@ -135,7 +135,21 @@ var init_dist = __esm({
|
|
|
135
135
|
{ key: "autoBranch", label: "Auto branch", description: "Creates a feature branch per task/cycle at build start.", step: "build" },
|
|
136
136
|
{ key: "autoCommit", label: "Auto commit", description: "Commits your work automatically when a build completes.", step: "build" },
|
|
137
137
|
{ key: "autoPush", label: "Auto push & PR", description: "Pushes the branch and opens a pull request on build complete.", step: "build" },
|
|
138
|
-
{ key: "papiMetaFraming", label: "PAPI self-referential framing", description: "Includes PAPI-meta build-discipline framing in handoff output.", step: "build" }
|
|
138
|
+
{ key: "papiMetaFraming", label: "PAPI self-referential framing", description: "Includes PAPI-meta build-discipline framing in handoff output.", step: "build" },
|
|
139
|
+
// Editor-equal release. Two legitimate team shapes need opposite answers, so
|
|
140
|
+
// this is a PROJECT policy rather than a global rule:
|
|
141
|
+
//
|
|
142
|
+
// OFF (default) — an editor's release opens a CONTRIBUTOR PR and PAPI records
|
|
143
|
+
// the release when GitHub merges it. Right for an open//multi-contributor
|
|
144
|
+
// product where the project owner is the last gate before production.
|
|
145
|
+
// ON — an editor releases on exactly the owner's path. Right for a small team
|
|
146
|
+
// of trusted peers who each run whole cycles end to end, where routing every
|
|
147
|
+
// close back through one person is the bottleneck, not the safeguard.
|
|
148
|
+
//
|
|
149
|
+
// Defaults OFF so existing projects are byte-identical, and because widening who
|
|
150
|
+
// can ship to production must be a deliberate choice, never a silent upgrade.
|
|
151
|
+
// A VIEWER is denied either way — this moves the editor line only.
|
|
152
|
+
{ key: "editorRelease", label: "Editors release like the owner", description: "Lets editors run a full release instead of opening a contributor PR.", step: "release", defaultEnabled: false }
|
|
139
153
|
];
|
|
140
154
|
CAPABILITY_KEYS = CAPABILITY_REGISTRY.map((c) => c.key);
|
|
141
155
|
HOSTED_APP_URL = "https://getpapi.ai";
|
|
@@ -171,6 +185,7 @@ __export(git_exports, {
|
|
|
171
185
|
detectUnrecordedCommits: () => detectUnrecordedCommits,
|
|
172
186
|
ensureLatestDevelop: () => ensureLatestDevelop,
|
|
173
187
|
ensureTagAtHead: () => ensureTagAtHead,
|
|
188
|
+
findContributorReleasePullRequests: () => findContributorReleasePullRequests,
|
|
174
189
|
findTaskCommitsOnBase: () => findTaskCommitsOnBase,
|
|
175
190
|
getBranchDiff: () => getBranchDiff,
|
|
176
191
|
getCommitFiles: () => getCommitFiles,
|
|
@@ -188,6 +203,7 @@ __export(git_exports, {
|
|
|
188
203
|
getOriginRepoSlug: () => getOriginRepoSlug,
|
|
189
204
|
getOriginUrl: () => getOriginUrl,
|
|
190
205
|
getPathsDifferingFrom: () => getPathsDifferingFrom,
|
|
206
|
+
getPullRequestState: () => getPullRequestState,
|
|
191
207
|
getPullRequestUrl: () => getPullRequestUrl,
|
|
192
208
|
getRemoteBranchFiles: () => getRemoteBranchFiles,
|
|
193
209
|
getRootCommitHash: () => getRootCommitHash,
|
|
@@ -1151,6 +1167,56 @@ function getPullRequestUrl(cwd, branch) {
|
|
|
1151
1167
|
return null;
|
|
1152
1168
|
}
|
|
1153
1169
|
}
|
|
1170
|
+
function getPullRequestState(cwd, prUrl) {
|
|
1171
|
+
try {
|
|
1172
|
+
const output = execFileSync(
|
|
1173
|
+
"gh",
|
|
1174
|
+
["pr", "view", prUrl, "--json", "url,state,mergedAt"],
|
|
1175
|
+
{ cwd, encoding: "utf-8" }
|
|
1176
|
+
).trim();
|
|
1177
|
+
if (!output) return null;
|
|
1178
|
+
const parsed = JSON.parse(output);
|
|
1179
|
+
if (!parsed.url || !["OPEN", "CLOSED", "MERGED"].includes(parsed.state ?? "")) return null;
|
|
1180
|
+
return {
|
|
1181
|
+
url: parsed.url,
|
|
1182
|
+
state: parsed.state,
|
|
1183
|
+
mergedAt: parsed.mergedAt ?? null
|
|
1184
|
+
};
|
|
1185
|
+
} catch {
|
|
1186
|
+
return null;
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
function findContributorReleasePullRequests(cwd, cycle) {
|
|
1190
|
+
if (!Number.isInteger(cycle) || cycle <= 0) return [];
|
|
1191
|
+
try {
|
|
1192
|
+
const output = execFileSync(
|
|
1193
|
+
"gh",
|
|
1194
|
+
[
|
|
1195
|
+
"pr",
|
|
1196
|
+
"list",
|
|
1197
|
+
"--state",
|
|
1198
|
+
"all",
|
|
1199
|
+
"--limit",
|
|
1200
|
+
"20",
|
|
1201
|
+
"--search",
|
|
1202
|
+
`"Contributor release PR for cycle ${cycle}" in:body`,
|
|
1203
|
+
"--json",
|
|
1204
|
+
"url,state,mergedAt,headRefName"
|
|
1205
|
+
],
|
|
1206
|
+
{ cwd, encoding: "utf-8" }
|
|
1207
|
+
).trim();
|
|
1208
|
+
if (!output) return [];
|
|
1209
|
+
const parsed = JSON.parse(output);
|
|
1210
|
+
return parsed.flatMap((pr) => pr.url && pr.headRefName && ["OPEN", "CLOSED", "MERGED"].includes(pr.state ?? "") ? [{
|
|
1211
|
+
url: pr.url,
|
|
1212
|
+
state: pr.state,
|
|
1213
|
+
mergedAt: pr.mergedAt ?? null,
|
|
1214
|
+
branch: pr.headRefName
|
|
1215
|
+
}] : []);
|
|
1216
|
+
} catch {
|
|
1217
|
+
return [];
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1154
1220
|
function squashMergePullRequest(cwd, branch) {
|
|
1155
1221
|
const repo = getOriginRepoSlug(cwd);
|
|
1156
1222
|
const baseArgs = ["pr", "merge", branch, "--squash", "--delete-branch"];
|
|
@@ -1518,6 +1584,10 @@ var init_proxy_adapter = __esm({
|
|
|
1518
1584
|
"dismissRecommendation",
|
|
1519
1585
|
"findPendingDocActionsForTask",
|
|
1520
1586
|
"getActiveDecisions",
|
|
1587
|
+
"getContributorRole",
|
|
1588
|
+
"listContributorReleasePrs",
|
|
1589
|
+
"recordContributorReleasePr",
|
|
1590
|
+
"setContributorReleasePrStatus",
|
|
1521
1591
|
"getActiveStage",
|
|
1522
1592
|
"getBuildReportCountForTask",
|
|
1523
1593
|
"getBuildReportsSince",
|
|
@@ -1657,7 +1727,7 @@ var init_proxy_adapter = __esm({
|
|
|
1657
1727
|
"applyActiveDecisionUpdates",
|
|
1658
1728
|
// getToolCallCount + updatePhaseStatus are ABSENT: they now have edge handlers and
|
|
1659
1729
|
// are served through the forwarder (getToolCallCount = SUP-2026-026 handler #1).
|
|
1660
|
-
|
|
1730
|
+
// getContributorRole is edge-wired and binds identity from the bearer.
|
|
1661
1731
|
// task-3018 (C356): storeDocBody + getDocBodyUsage are now WIRED — edge case
|
|
1662
1732
|
// handlers + ALLOWED_METHODS/WRITE_METHODS entries exist, so they forward and
|
|
1663
1733
|
// hosted callers get body storage. Removed from this list, as task-3017 required.
|
|
@@ -1665,9 +1735,6 @@ var init_proxy_adapter = __esm({
|
|
|
1665
1735
|
// of the owner-action queue. Six readers were wired C329 (task-2412) but the
|
|
1666
1736
|
// producer stayed here, so the hosted Owner Action Queue was structurally empty
|
|
1667
1737
|
// (AD-74 inverted). Now forwards; the edge binds user_id to the bearer ([C]).
|
|
1668
|
-
"recordContributorReleasePr",
|
|
1669
|
-
"setContributorReleasePrStatus",
|
|
1670
|
-
"listContributorReleasePrs",
|
|
1671
1738
|
"claimReview",
|
|
1672
1739
|
"getSiblingAds",
|
|
1673
1740
|
"getSiblingRepoTasks",
|
|
@@ -2383,8 +2450,8 @@ Check PAPI_PROJECT_ID in your .mcp.json config. Find your project ID in the PAPI
|
|
|
2383
2450
|
getCycleLearningPatterns() {
|
|
2384
2451
|
return this.invoke("getCycleLearningPatterns", []);
|
|
2385
2452
|
}
|
|
2386
|
-
updateCycleLearningActionRef(learningId, taskDisplayId) {
|
|
2387
|
-
return this.invoke("updateCycleLearningActionRef", [learningId, taskDisplayId]);
|
|
2453
|
+
updateCycleLearningActionRef(learningId, taskDisplayId, opts) {
|
|
2454
|
+
return this.invoke("updateCycleLearningActionRef", [learningId, taskDisplayId, opts ?? {}]);
|
|
2388
2455
|
}
|
|
2389
2456
|
// --- Strategy Review Drafts ---
|
|
2390
2457
|
savePendingReviewResponse(cycleNumber, rawResponse) {
|
|
@@ -2490,7 +2557,11 @@ Check PAPI_PROJECT_ID in your .mcp.json config. Find your project ID in the PAPI
|
|
|
2490
2557
|
*/
|
|
2491
2558
|
async getMeteredUsage() {
|
|
2492
2559
|
const body = await this.postRoute("metering", {});
|
|
2493
|
-
return {
|
|
2560
|
+
return {
|
|
2561
|
+
tier: body.tier ?? "free",
|
|
2562
|
+
monthlyToolCalls: body.monthlyToolCalls ?? 0,
|
|
2563
|
+
projectLimitOverride: body.projectLimitOverride ?? null
|
|
2564
|
+
};
|
|
2494
2565
|
}
|
|
2495
2566
|
async listUserProjects() {
|
|
2496
2567
|
const body = await this.postRoute("project-list", {});
|
|
@@ -2871,7 +2942,7 @@ Fix the PAPI_PROJECT_ID in your .mcp.json (or unset it and let PAPI resolve the
|
|
|
2871
2942
|
Get started in 3 steps:
|
|
2872
2943
|
1. Sign up at ${dashboardUrl ? `${dashboardUrl}/login` : "your configured PAPI dashboard"}
|
|
2873
2944
|
2. Complete the onboarding wizard \u2014 it generates your .mcp.json config
|
|
2874
|
-
3. Download the config, place it in your project root, and restart
|
|
2945
|
+
3. Download the config, place it in your project root, and restart your AI client
|
|
2875
2946
|
|
|
2876
2947
|
Already have an account? Make sure PAPI_DATA_API_KEY is set in your .mcp.json env config.`
|
|
2877
2948
|
);
|