@papi-ai/server 0.7.23 → 0.7.24

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.
Files changed (2) hide show
  1. package/dist/index.js +34 -1
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -9346,6 +9346,7 @@ __export(git_exports, {
9346
9346
  getStagedFiles: () => getStagedFiles,
9347
9347
  getTaskIdsOnBranch: () => getTaskIdsOnBranch,
9348
9348
  getUnmergedBranches: () => getUnmergedBranches,
9349
+ getUntrackedFiles: () => getUntrackedFiles,
9349
9350
  gitPull: () => gitPull,
9350
9351
  gitPush: () => gitPush,
9351
9352
  hasRemote: () => hasRemote,
@@ -9473,6 +9474,18 @@ function getModifiedFiles(cwd) {
9473
9474
  return [];
9474
9475
  }
9475
9476
  }
9477
+ function getUntrackedFiles(cwd) {
9478
+ try {
9479
+ const out = execFileSync("git", ["ls-files", "--others", "--exclude-standard"], {
9480
+ cwd,
9481
+ encoding: "utf-8"
9482
+ }).replace(/\n+$/, "");
9483
+ if (!out) return [];
9484
+ return out.split("\n").map((l) => l.trim()).filter(Boolean);
9485
+ } catch {
9486
+ return [];
9487
+ }
9488
+ }
9476
9489
  function getBranchDiff(cwd, base = "origin/main", maxBytes = 2e5) {
9477
9490
  const refs = [`${base}...HEAD`, "main...HEAD"];
9478
9491
  for (const ref of refs) {
@@ -19526,6 +19539,10 @@ function autoCommit(config2, taskId, taskTitle, predictedFiles) {
19526
19539
  const parts = p.split(/[\\/]/);
19527
19540
  return parts[parts.length - 1] ?? p;
19528
19541
  };
19542
+ const dirname6 = (p) => {
19543
+ const idx = Math.max(p.lastIndexOf("/"), p.lastIndexOf("\\"));
19544
+ return idx > 0 ? p.slice(0, idx) : "";
19545
+ };
19529
19546
  const predictedNames = new Set(predictedFiles.map(basename2).filter(Boolean));
19530
19547
  const scoped = modified.filter((p) => predictedNames.has(basename2(p)));
19531
19548
  if (scoped.length === 0) {
@@ -19533,7 +19550,23 @@ function autoCommit(config2, taskId, taskTitle, predictedFiles) {
19533
19550
  const predSample = predictedFiles.slice(0, 5).join(", ");
19534
19551
  return `Auto-commit: refused \u2014 none of the ${modified.length} modified file(s) intersect FILES LIKELY TOUCHED. Modified: ${modSample}. Expected: ${predSample}. Stage the intended files manually (\`git add <paths>\`) then re-run, or set PAPI_AUTO_COMMIT=false.`;
19535
19552
  }
19536
- return safeRun(() => stagePathsAndCommit(cwd, scoped, message)) + ` (scoped to ${scoped.length}/${modified.length} files via FILES LIKELY TOUCHED).`;
19553
+ const untracked = getUntrackedFiles(cwd);
19554
+ const scopedDirs = [...new Set(scoped.map(dirname6).filter((d) => d.length > 0))];
19555
+ const isUnderScopedDir = (p) => scopedDirs.some((d) => p === d || p.startsWith(`${d}/`) || p.startsWith(`${d}\\`));
19556
+ const scopedSet = new Set(scoped);
19557
+ const adjacentUntracked = untracked.filter(
19558
+ (p) => !scopedSet.has(p) && isUnderScopedDir(p)
19559
+ );
19560
+ const toStage = [...scoped, ...adjacentUntracked];
19561
+ const toStageSet = new Set(toStage);
19562
+ const droppedUntracked = untracked.filter((p) => !toStageSet.has(p));
19563
+ let line = safeRun(() => stagePathsAndCommit(cwd, toStage, message)) + ` (scoped to ${scoped.length}/${modified.length} files via FILES LIKELY TOUCHED` + (adjacentUntracked.length > 0 ? ` + ${adjacentUntracked.length} untracked under scoped dir(s)` : "") + `).`;
19564
+ if (droppedUntracked.length > 0) {
19565
+ const sample = droppedUntracked.slice(0, 10).join(", ");
19566
+ const more = droppedUntracked.length > 10 ? ` (+${droppedUntracked.length - 10} more)` : "";
19567
+ line += ` \u26A0\uFE0F ${droppedUntracked.length} untracked file(s) were NOT committed: ${sample}${more}. If they belong to this task, run \`git add <paths> && git commit --amend --no-edit\` before pushing \u2014 otherwise the committed tree may not build on checkout/CI.`;
19568
+ }
19569
+ return line;
19537
19570
  }
19538
19571
  return safeRun(() => stageAllAndCommit(cwd, message));
19539
19572
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@papi-ai/server",
3
- "version": "0.7.23",
3
+ "version": "0.7.24",
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
  "type": "module",