@papi-ai/server 0.7.75 → 0.7.77

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.
@@ -1236,10 +1236,21 @@ var init_proxy_adapter = __esm({
1236
1236
  // (1) local-only
1237
1237
  "close",
1238
1238
  "initRls",
1239
+ // task-3207 (C357): commitBuildComplete, commitReviewSubmit, commitRelease have no
1240
+ // edge case handler and no ALLOWED_METHODS entry — forwarding them 403s at the edge
1241
+ // with no try/catch at the call site, crashing build_execute/review_submit/release
1242
+ // completion for every hosted user. Restores the intended graceful degradation
1243
+ // (separate appendBuildReport + updateTaskStatus calls) until they're atomically wired.
1244
+ "commitBuildComplete",
1245
+ "commitReviewSubmit",
1246
+ "commitRelease",
1239
1247
  // (2) not-yet-wired hosted gaps — shrink as data-proxy handlers land (task-2390).
1240
1248
  // getToolCallCount + updatePhaseStatus are ABSENT: they now have edge handlers and
1241
1249
  // are served through the forwarder (getToolCallCount = SUP-2026-026 handler #1).
1242
1250
  "getContributorRole",
1251
+ // task-3018 (C356): storeDocBody + getDocBodyUsage are now WIRED — edge case
1252
+ // handlers + ALLOWED_METHODS/WRITE_METHODS entries exist, so they forward and
1253
+ // hosted callers get body storage. Removed from this list, as task-3017 required.
1243
1254
  // task-2728 (C331): createOwnerAction REMOVED from NO_FORWARD — the PRODUCER half
1244
1255
  // of the owner-action queue. Six readers were wired C329 (task-2412) but the
1245
1256
  // producer stayed here, so the hosted Owner Action Queue was structurally empty
@@ -1267,7 +1278,7 @@ var init_proxy_adapter = __esm({
1267
1278
  // now works for hosted users without exposing one member's owner actions to another.
1268
1279
  // task-2393 (C329) — Batch B wired: markCycleLearningResolved (the P1 — hosted
1269
1280
  // discovered_issue_resolve hard-errored), correctLatestBuildReportEffort,
1270
- // updateStageExitCriteria, updateDocAction, resolveLearningsForDoneTasks all have
1281
+ // updateStageExitCriteria, updateDocAction all have
1271
1282
  // edge case handlers + ALLOWED_METHODS/WRITE_METHODS entries now, so they forward.
1272
1283
  // task-2489 (C320): recordProgressStep is now wired to the edge data-proxy
1273
1284
  // (case handler + ALLOWED_METHODS/WRITE_METHODS entries), so it forwards for
@@ -1851,9 +1862,19 @@ Check PAPI_PROJECT_ID in your .mcp.json config. Find your project ID in the PAPI
1851
1862
  return this.invoke("updateDocStatus", [id, status, supersededBy]);
1852
1863
  }
1853
1864
  // --- Cycle Learnings ---
1854
- appendCycleLearnings(learnings) {
1855
- return this.invoke("appendCycleLearnings", [learnings]);
1865
+ /**
1866
+ * task-2999 / task-2998 (C356): the edge handler now calls append_cycle_learnings
1867
+ * and returns { id, findingKey, inserted } per row, so hosted callers get the same
1868
+ * per-row signal the pg path does. The [] normalisation stays as a floor for an
1869
+ * edge deployed BEFORE that change — callers must read [] as "no signal
1870
+ * available", never as "nothing was new".
1871
+ */
1872
+ async appendCycleLearnings(learnings) {
1873
+ const result = await this.invoke("appendCycleLearnings", [learnings]);
1874
+ return Array.isArray(result) ? result : [];
1856
1875
  }
1876
+ // task-2998: includeResolved was missing here, so the flag could not even be SENT
1877
+ // to the edge — the hosted caught->fixed ledger had no way to ask for history.
1857
1878
  getCycleLearnings(opts) {
1858
1879
  return this.invoke("getCycleLearnings", [opts]);
1859
1880
  }
@@ -2930,6 +2951,59 @@ var ACCURACY_HEADER = "| Cycle | Reports | Match Rate | MAE | Bias |";
2930
2951
  var ACCURACY_SEPARATOR = "|--------|---------|------------|-----|------|";
2931
2952
  var VELOCITY_HEADER = "| Cycle | Completed | Partial | Failed | Effort Points |";
2932
2953
  var VELOCITY_SEPARATOR = "|--------|-----------|---------|--------|---------------|";
2954
+ var EFFORT_SCALE = {
2955
+ XS: 1,
2956
+ S: 2,
2957
+ M: 3,
2958
+ L: 4,
2959
+ XL: 5
2960
+ };
2961
+ function effortOrdinal(effort) {
2962
+ const normalized = effort.trim().toUpperCase();
2963
+ return EFFORT_SCALE[normalized];
2964
+ }
2965
+ function calculateCycleMetrics(reports, currentCycle, window = 5) {
2966
+ const recentReports = reports.filter(
2967
+ (r) => r.cycle > currentCycle - window && r.cycle <= currentCycle
2968
+ );
2969
+ const perCycle = /* @__PURE__ */ new Map();
2970
+ for (const r of recentReports) {
2971
+ const group = perCycle.get(r.cycle) ?? [];
2972
+ group.push(r);
2973
+ perCycle.set(r.cycle, group);
2974
+ }
2975
+ const accuracy = [];
2976
+ const velocity = [];
2977
+ const sortedCycles = [...perCycle.keys()].sort((a, b) => a - b);
2978
+ for (const cycle of sortedCycles) {
2979
+ const reps = perCycle.get(cycle);
2980
+ const deltas = [];
2981
+ for (const r of reps) {
2982
+ const actual = effortOrdinal(r.actualEffort);
2983
+ const estimated = effortOrdinal(r.estimatedEffort);
2984
+ if (actual !== void 0 && estimated !== void 0) {
2985
+ deltas.push(actual - estimated);
2986
+ }
2987
+ }
2988
+ if (deltas.length > 0) {
2989
+ accuracy.push({
2990
+ cycle,
2991
+ reports: deltas.length,
2992
+ matchRate: Math.round(deltas.filter((d) => d === 0).length / deltas.length * 100),
2993
+ mae: Math.round(deltas.reduce((s, d) => s + Math.abs(d), 0) / deltas.length * 10) / 10,
2994
+ bias: Math.round(deltas.reduce((s, d) => s + d, 0) / deltas.length * 10) / 10
2995
+ });
2996
+ }
2997
+ velocity.push({
2998
+ cycle,
2999
+ completed: reps.filter((r) => r.completed === "Yes").length,
3000
+ partial: reps.filter((r) => r.completed === "Partial").length,
3001
+ failed: reps.filter((r) => r.completed === "No").length,
3002
+ effortPoints: reps.reduce((s, r) => s + (effortOrdinal(r.actualEffort) ?? 0), 0)
3003
+ });
3004
+ }
3005
+ return { accuracy, velocity };
3006
+ }
2933
3007
  function serializeAccuracyRow(a) {
2934
3008
  return `| ${a.cycle} | ${a.reports} | ${a.matchRate}% | ${a.mae} | ${a.bias >= 0 ? "+" : ""}${a.bias} |`;
2935
3009
  }
@@ -4713,13 +4787,14 @@ function computeSnapshotsFromBuildReports(reports, tasks) {
4713
4787
  const cycleReports = reportsByCycle.get(sn) ?? [];
4714
4788
  const cycleTaskRows = tasksByCycle.get(sn);
4715
4789
  const withEffort = cycleReports.filter((r) => r.estimatedEffort && r.actualEffort);
4716
- const accurate = withEffort.filter((r) => r.estimatedEffort === r.actualEffort).length;
4717
- const matchRate = withEffort.length > 0 ? Math.round(accurate / withEffort.length * 100) : 0;
4790
+ const [computedAccuracy] = calculateCycleMetrics(withEffort, sn, 1).accuracy;
4718
4791
  const { completed, total, plannedPoints, deliveredPoints } = computeCycleEffort(cycleTaskRows, cycleReports);
4719
4792
  snapshots.push({
4720
4793
  cycle: sn,
4721
4794
  date: (/* @__PURE__ */ new Date()).toISOString(),
4722
- accuracy: [{ cycle: sn, reports: cycleReports.length, matchRate, mae: 0, bias: 0 }],
4795
+ // No report in this cycle carried BOTH an estimate and an actual, so there
4796
+ // is genuinely nothing to measure. Zeros here mean "no data", not "no bias".
4797
+ accuracy: [computedAccuracy ?? { cycle: sn, reports: 0, matchRate: 0, mae: 0, bias: 0 }],
4723
4798
  velocity: [{
4724
4799
  cycle: sn,
4725
4800
  completed,