@papi-ai/server 0.7.70 → 0.7.71

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.
@@ -1865,9 +1865,12 @@ Check PAPI_PROJECT_ID in your .mcp.json config. Find your project ID in the PAPI
1865
1865
  return this.invoke("getOwnerIdentity", []);
1866
1866
  }
1867
1867
  // --- Contributor cohort (task-2029, C288) ---
1868
- // Owner-only enforcement is BOTH tool-layer (resolveOwnerGate) and
1869
- // server-side in the edge function (auth-derived caller vs project owner)
1870
- // defence in depth, since this client runs on the user's machine.
1868
+ // Owner-only enforcement is BOTH tool-layer (resolveOwnerGate) and server-side
1869
+ // in the edge function (auth-derived caller vs project owner). task-2442 (C351)
1870
+ // added addContributorByEmail/removeContributorByEmail to the proxy WRITE_METHODS
1871
+ // set too, so a viewer is now rejected at the role-gate wall before the handler —
1872
+ // three layers of defence, since this client runs on the user's machine.
1873
+ // listContributors stays a member-open read (task-2377).
1871
1874
  async listContributors() {
1872
1875
  return this.invoke("listContributors", []);
1873
1876
  }
package/dist/index.js CHANGED
@@ -1982,9 +1982,12 @@ Check PAPI_PROJECT_ID in your .mcp.json config. Find your project ID in the PAPI
1982
1982
  return this.invoke("getOwnerIdentity", []);
1983
1983
  }
1984
1984
  // --- Contributor cohort (task-2029, C288) ---
1985
- // Owner-only enforcement is BOTH tool-layer (resolveOwnerGate) and
1986
- // server-side in the edge function (auth-derived caller vs project owner)
1987
- // defence in depth, since this client runs on the user's machine.
1985
+ // Owner-only enforcement is BOTH tool-layer (resolveOwnerGate) and server-side
1986
+ // in the edge function (auth-derived caller vs project owner). task-2442 (C351)
1987
+ // added addContributorByEmail/removeContributorByEmail to the proxy WRITE_METHODS
1988
+ // set too, so a viewer is now rejected at the role-gate wall before the handler —
1989
+ // three layers of defence, since this client runs on the user's machine.
1990
+ // listContributors stays a member-open read (task-2377).
1988
1991
  async listContributors() {
1989
1992
  return this.invoke("listContributors", []);
1990
1993
  }
@@ -21089,6 +21092,18 @@ function clearBuildCheckpoint(key) {
21089
21092
  } catch {
21090
21093
  }
21091
21094
  }
21095
+ function writeBuildCheckpointIfLocal(input) {
21096
+ if (!hasLocalWorkspace()) return;
21097
+ writeBuildCheckpoint(input);
21098
+ }
21099
+ function readBuildCheckpointIfLocal(key) {
21100
+ if (!hasLocalWorkspace()) return null;
21101
+ return readBuildCheckpoint(key);
21102
+ }
21103
+ function clearBuildCheckpointIfLocal(key) {
21104
+ if (!hasLocalWorkspace()) return;
21105
+ clearBuildCheckpoint(key);
21106
+ }
21092
21107
  function formatResumeNote(cp) {
21093
21108
  const files = cp.modifiedFiles.filter((f) => f && f.trim());
21094
21109
  const fileList = files.length > 0 ? files.slice(0, 12).map((f) => ` - ${f}`).join("\n") + (files.length > 12 ? `
@@ -21858,7 +21873,7 @@ async function startBuild(adapter2, config2, taskId, options = {}, clientName) {
21858
21873
  );
21859
21874
  } catch {
21860
21875
  }
21861
- writeBuildCheckpoint({
21876
+ writeBuildCheckpointIfLocal({
21862
21877
  cwd: config2.projectRoot,
21863
21878
  taskId,
21864
21879
  branch: getCurrentBranch(config2.projectRoot),
@@ -22362,12 +22377,14 @@ async function completeBuild(adapter2, config2, taskId, input, options = {}, cli
22362
22377
  }
22363
22378
  } catch {
22364
22379
  }
22365
- try {
22366
- clearActiveTaskScope(config2.projectRoot);
22367
- } catch {
22380
+ if (hasLocalWorkspace()) {
22381
+ try {
22382
+ clearActiveTaskScope(config2.projectRoot);
22383
+ } catch {
22384
+ }
22368
22385
  }
22369
22386
  try {
22370
- clearBuildCheckpoint({ cwd: config2.projectRoot, taskId });
22387
+ clearBuildCheckpointIfLocal({ cwd: config2.projectRoot, taskId });
22371
22388
  } catch {
22372
22389
  }
22373
22390
  return {
@@ -22393,7 +22410,7 @@ async function completeBuild(adapter2, config2, taskId, input, options = {}, cli
22393
22410
  localPreview
22394
22411
  };
22395
22412
  }
22396
- async function cancelBuild(adapter2, taskId, reason) {
22413
+ async function cancelBuild(adapter2, taskId, reason, projectRoot) {
22397
22414
  const task = await adapter2.getTask(taskId);
22398
22415
  if (!task) {
22399
22416
  throw new Error(`Task "${taskId}" not found.`);
@@ -22402,6 +22419,18 @@ async function cancelBuild(adapter2, taskId, reason) {
22402
22419
  status: "Cancelled",
22403
22420
  closureReason: reason
22404
22421
  });
22422
+ if (projectRoot) {
22423
+ if (hasLocalWorkspace()) {
22424
+ try {
22425
+ clearActiveTaskScope(projectRoot);
22426
+ } catch {
22427
+ }
22428
+ }
22429
+ try {
22430
+ clearBuildCheckpointIfLocal({ cwd: projectRoot, taskId });
22431
+ } catch {
22432
+ }
22433
+ }
22405
22434
  return { task, reason };
22406
22435
  }
22407
22436
 
@@ -23318,7 +23347,7 @@ async function handleBuildExecute(adapter2, config2, args, clientName) {
23318
23347
  }
23319
23348
  let resumeNote = "";
23320
23349
  if (scopeTask?.status === "In Progress") {
23321
- const existing = readBuildCheckpoint({ cwd: config2.projectRoot, taskId });
23350
+ const existing = readBuildCheckpointIfLocal({ cwd: config2.projectRoot, taskId });
23322
23351
  if (existing) resumeNote = formatResumeNote(existing);
23323
23352
  }
23324
23353
  await tracker.recordStep("started");
@@ -23739,7 +23768,7 @@ function formatCompleteResult(result) {
23739
23768
  }
23740
23769
  return lines.join("\n");
23741
23770
  }
23742
- async function handleBuildCancel(adapter2, args) {
23771
+ async function handleBuildCancel(adapter2, config2, args) {
23743
23772
  const taskId = args.task_id;
23744
23773
  if (!taskId) {
23745
23774
  return errorResponse("task_id is required.");
@@ -23749,7 +23778,7 @@ async function handleBuildCancel(adapter2, args) {
23749
23778
  return errorResponse("reason is required.");
23750
23779
  }
23751
23780
  try {
23752
- const result = await cancelBuild(adapter2, taskId, reason);
23781
+ const result = await cancelBuild(adapter2, taskId, reason, config2.projectRoot);
23753
23782
  return textResponse(`Cancelled **${result.task.id}** (${result.task.title}).
23754
23783
 
23755
23784
  Reason: ${result.reason}`);
@@ -31137,7 +31166,7 @@ function createServer(adapter2, config2) {
31137
31166
  case "build_execute":
31138
31167
  return handleBuildExecute(adapter2, config2, safeArgs, server2.getClientVersion()?.name);
31139
31168
  case "build_cancel":
31140
- return handleBuildCancel(adapter2, safeArgs);
31169
+ return handleBuildCancel(adapter2, config2, safeArgs);
31141
31170
  case "idea":
31142
31171
  return handleIdea(adapter2, config2, safeArgs);
31143
31172
  case "backlog_import":
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@papi-ai/server",
3
- "version": "0.7.70",
3
+ "version": "0.7.71",
4
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",