@papi-ai/server 0.7.55 → 0.7.57
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 +4 -1
- package/dist/index.js +128 -34
- package/dist/prompts.js +2 -2
- package/package.json +2 -2
|
@@ -1179,8 +1179,11 @@ var init_proxy_adapter = __esm({
|
|
|
1179
1179
|
// (2) not-yet-wired hosted gaps — shrink as data-proxy handlers land (task-2390).
|
|
1180
1180
|
// getToolCallCount + updatePhaseStatus are ABSENT: they now have edge handlers and
|
|
1181
1181
|
// are served through the forwarder (getToolCallCount = SUP-2026-026 handler #1).
|
|
1182
|
-
"createOwnerAction",
|
|
1183
1182
|
"getContributorRole",
|
|
1183
|
+
// task-2728 (C331): createOwnerAction REMOVED from NO_FORWARD — the PRODUCER half
|
|
1184
|
+
// of the owner-action queue. Six readers were wired C329 (task-2412) but the
|
|
1185
|
+
// producer stayed here, so the hosted Owner Action Queue was structurally empty
|
|
1186
|
+
// (AD-74 inverted). Now forwards; the edge binds user_id to the bearer ([C]).
|
|
1184
1187
|
"recordContributorReleasePr",
|
|
1185
1188
|
"setContributorReleasePrStatus",
|
|
1186
1189
|
"listContributorReleasePrs",
|
package/dist/index.js
CHANGED
|
@@ -1296,8 +1296,11 @@ var init_proxy_adapter = __esm({
|
|
|
1296
1296
|
// (2) not-yet-wired hosted gaps — shrink as data-proxy handlers land (task-2390).
|
|
1297
1297
|
// getToolCallCount + updatePhaseStatus are ABSENT: they now have edge handlers and
|
|
1298
1298
|
// are served through the forwarder (getToolCallCount = SUP-2026-026 handler #1).
|
|
1299
|
-
"createOwnerAction",
|
|
1300
1299
|
"getContributorRole",
|
|
1300
|
+
// task-2728 (C331): createOwnerAction REMOVED from NO_FORWARD — the PRODUCER half
|
|
1301
|
+
// of the owner-action queue. Six readers were wired C329 (task-2412) but the
|
|
1302
|
+
// producer stayed here, so the hosted Owner Action Queue was structurally empty
|
|
1303
|
+
// (AD-74 inverted). Now forwards; the edge binds user_id to the bearer ([C]).
|
|
1301
1304
|
"recordContributorReleasePr",
|
|
1302
1305
|
"setContributorReleasePrStatus",
|
|
1303
1306
|
"listContributorReleasePrs",
|
|
@@ -8169,20 +8172,27 @@ function formatDecisionLifecycleSummary(decisions) {
|
|
|
8169
8172
|
}
|
|
8170
8173
|
return parts.join(", ");
|
|
8171
8174
|
}
|
|
8172
|
-
function formatBuildReports(reports) {
|
|
8175
|
+
function formatBuildReports(reports, opts) {
|
|
8173
8176
|
if (reports.length === 0) return "No build reports yet.";
|
|
8174
|
-
|
|
8177
|
+
const capped = opts?.maxReports != null ? reports.slice(0, opts.maxReports) : reports;
|
|
8178
|
+
const budget = opts?.fieldBudget;
|
|
8179
|
+
const field = (v) => budget != null ? truncateNotes(v, budget) : v ?? "";
|
|
8180
|
+
const body = capped.map(
|
|
8175
8181
|
(r) => `### ${r.taskName} \u2014 ${r.date} \u2014 Cycle ${r.cycle}
|
|
8176
8182
|
|
|
8177
8183
|
- **Completed:** ${r.completed}
|
|
8178
8184
|
- **Actual Effort:** ${r.actualEffort} vs estimated ${r.estimatedEffort}
|
|
8179
8185
|
` + (r.correctionsCount ? `- **Corrections:** ${r.correctionsCount}
|
|
8180
8186
|
` : "") + (Array.isArray(r.briefImplications) && r.briefImplications.length ? `- **Brief Implications:** ${r.briefImplications.map((bi) => `[${bi.canvasSection}/${bi.type}] ${bi.detail}`).join("; ")}
|
|
8181
|
-
` : "") + `- **Surprises:** ${r.surprises}
|
|
8182
|
-
- **Discovered Issues:** ${r.discoveredIssues}
|
|
8183
|
-
- **Architecture Notes:** ${r.architectureNotes}` + (r.deadEnds ? `
|
|
8184
|
-
- **Dead Ends:** ${r.deadEnds}` : "")
|
|
8187
|
+
` : "") + `- **Surprises:** ${field(r.surprises)}
|
|
8188
|
+
- **Discovered Issues:** ${field(r.discoveredIssues)}
|
|
8189
|
+
- **Architecture Notes:** ${field(r.architectureNotes)}` + (r.deadEnds ? `
|
|
8190
|
+
- **Dead Ends:** ${field(r.deadEnds)}` : "")
|
|
8185
8191
|
).join("\n\n---\n\n");
|
|
8192
|
+
const omitted = capped.length < reports.length ? `
|
|
8193
|
+
|
|
8194
|
+
_\u2026and ${reports.length - capped.length} older build report(s) omitted to bound context size._` : "";
|
|
8195
|
+
return body + omitted;
|
|
8186
8196
|
}
|
|
8187
8197
|
function formatRecentlyShippedCapabilities(reports) {
|
|
8188
8198
|
const completed = reports.filter((r) => r.completed === "Yes" || r.completed === "Partial");
|
|
@@ -8415,6 +8425,21 @@ function computeCycleEffort(cycleTaskRows, cycleReports) {
|
|
|
8415
8425
|
function velocityPoints(v) {
|
|
8416
8426
|
return v.deliveredPoints ?? v.effortPoints;
|
|
8417
8427
|
}
|
|
8428
|
+
function resolveCompletedCycleDates(existingStart, earliestActivity, now) {
|
|
8429
|
+
const startDate = existingStart || earliestActivity || now;
|
|
8430
|
+
const startMs = Date.parse(startDate);
|
|
8431
|
+
const endMs = Date.parse(now);
|
|
8432
|
+
const known = Number.isFinite(startMs) && Number.isFinite(endMs) && startMs < endMs;
|
|
8433
|
+
return { startDate, endDate: known ? now : null };
|
|
8434
|
+
}
|
|
8435
|
+
function earliestCycleActivity(reports) {
|
|
8436
|
+
let earliest;
|
|
8437
|
+
for (const r of reports) {
|
|
8438
|
+
const ts = r.startedAt || r.createdAt || r.date;
|
|
8439
|
+
if (ts && (!earliest || Date.parse(ts) < Date.parse(earliest))) earliest = ts;
|
|
8440
|
+
}
|
|
8441
|
+
return earliest;
|
|
8442
|
+
}
|
|
8418
8443
|
function computeSnapshotsFromBuildReports(reports, tasks) {
|
|
8419
8444
|
const reportsByCycle = /* @__PURE__ */ new Map();
|
|
8420
8445
|
for (const r of reports) {
|
|
@@ -8816,7 +8841,7 @@ PRE-BUILD VERIFICATION
|
|
|
8816
8841
|
[List 2-5 specific file paths the builder should read BEFORE implementing to check if the functionality already exists. Derive these from FILES LIKELY TOUCHED \u2014 pick the files most likely to already contain the target functionality. ALSO mandate a docs sweep, not just file-existence (task-2161): name any docs the builder should check via doc_search or the docs index \u2014 a design/research/status:final doc or a prior task may already cover the work. If >80% of the scope is already implemented, the builder should report "already built" instead of re-implementing. Include this section for EVERY task \u2014 it prevents wasted build slots on already-shipped code.]
|
|
8817
8842
|
|
|
8818
8843
|
FILES LIKELY TOUCHED
|
|
8819
|
-
[files]
|
|
8844
|
+
[files \u2014 real paths only. TEST FILE LOCATIONS (task-2606): PAPI tests are NOT co-located next to source in a src/**/__tests__/ folder. Use the actual layout: server tests \u2192 packages/server/tests/<name>.test.ts; adapter-pg tests \u2192 packages/adapter-pg/src/__tests__/<name>.test.ts; dashboard/root tests \u2192 tests/<area>/<name>.test.ts. Do NOT invent packages/server/src/**/__tests__/ paths \u2014 they do not exist.]
|
|
8820
8845
|
|
|
8821
8846
|
EFFORT
|
|
8822
8847
|
[XS/S/M/L/XL]
|
|
@@ -9973,7 +9998,7 @@ REFERENCE DOCS
|
|
|
9973
9998
|
[Optional \u2014 paths to docs/ files with background context. Omit if not needed.]
|
|
9974
9999
|
|
|
9975
10000
|
FILES LIKELY TOUCHED
|
|
9976
|
-
[files]
|
|
10001
|
+
[files \u2014 real paths only. TEST FILE LOCATIONS (task-2606): PAPI tests are NOT co-located next to source in a src/**/__tests__/ folder. Use the actual layout: server tests \u2192 packages/server/tests/<name>.test.ts; adapter-pg tests \u2192 packages/adapter-pg/src/__tests__/<name>.test.ts; dashboard/root tests \u2192 tests/<area>/<name>.test.ts. Do NOT invent packages/server/src/**/__tests__/ paths \u2014 they do not exist.]
|
|
9977
10002
|
|
|
9978
10003
|
EFFORT
|
|
9979
10004
|
[XS/S/M/L/XL]`;
|
|
@@ -10425,7 +10450,9 @@ async function prepareHandoffs(adapter2, _config, taskIds, force = false) {
|
|
|
10425
10450
|
// buildHandoffsOnlyUserMessage adds +1 internally
|
|
10426
10451
|
preAssignedTasks: tasksNeedingHandoffs,
|
|
10427
10452
|
activeDecisions: formatActiveDecisionsForPlan(decisions),
|
|
10428
|
-
|
|
10453
|
+
// task-2681: truncate verbose report bodies — a couple of audit reports alone
|
|
10454
|
+
// (e.g. task-2413/2655) can push this payload past the overflow range.
|
|
10455
|
+
recentBuildReports: formatBuildReports(reports, { maxReports: 10, fieldBudget: 280 }),
|
|
10429
10456
|
productBrief: brief,
|
|
10430
10457
|
northStar
|
|
10431
10458
|
});
|
|
@@ -10946,6 +10973,7 @@ async function resolveOwnerGate(adapter2, config2) {
|
|
|
10946
10973
|
}
|
|
10947
10974
|
|
|
10948
10975
|
// src/services/plan.ts
|
|
10976
|
+
var PLAN_BUILD_REPORT_BUDGET = { maxReports: 12, fieldBudget: 280 };
|
|
10949
10977
|
async function resolvePlanScope(adapter2, config2) {
|
|
10950
10978
|
const gate = await resolveOwnerGate(adapter2, config2);
|
|
10951
10979
|
return { callerUserId: gate.callerUserId, ownerUserId: gate.ownerUserId, callerIsOwner: gate.callerIsOwner };
|
|
@@ -11794,7 +11822,7 @@ ${logLines}`);
|
|
|
11794
11822
|
cycleNumber: health.totalCycles,
|
|
11795
11823
|
productBrief,
|
|
11796
11824
|
activeDecisions: formatActiveDecisionsForPlan(decisions),
|
|
11797
|
-
recentBuildReports: formatBuildReports(cappedReports),
|
|
11825
|
+
recentBuildReports: formatBuildReports(cappedReports, PLAN_BUILD_REPORT_BUDGET),
|
|
11798
11826
|
cycleLog: formatCycleLog(log2),
|
|
11799
11827
|
board: formatBoardForPlan(plannerTasks, filters, health.totalCycles, deferredTasks),
|
|
11800
11828
|
northStar,
|
|
@@ -12580,7 +12608,7 @@ async function preparePlan(adapter2, config2, filters, focus, force, handoffsOnl
|
|
|
12580
12608
|
cycleNumber,
|
|
12581
12609
|
preAssignedTasks: preAssigned,
|
|
12582
12610
|
activeDecisions: formatActiveDecisionsForPlan(decisions),
|
|
12583
|
-
recentBuildReports: formatBuildReports(reports),
|
|
12611
|
+
recentBuildReports: formatBuildReports(reports, PLAN_BUILD_REPORT_BUDGET),
|
|
12584
12612
|
productBrief: brief,
|
|
12585
12613
|
northStar
|
|
12586
12614
|
});
|
|
@@ -19043,20 +19071,11 @@ To override, pass force=true (emits a telemetry warning).`
|
|
|
19043
19071
|
existing = (await adapter2.readCycles()).find((c) => c.number === currentCycle);
|
|
19044
19072
|
} catch {
|
|
19045
19073
|
}
|
|
19046
|
-
const completedCycle = {
|
|
19047
|
-
id: `cycle-${currentCycle}`,
|
|
19048
|
-
number: currentCycle,
|
|
19049
|
-
status: "complete",
|
|
19050
|
-
startDate: existing?.startDate ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
19051
|
-
endDate: (/* @__PURE__ */ new Date()).toISOString(),
|
|
19052
|
-
goals: existing?.goals ?? [],
|
|
19053
|
-
boardHealth: existing?.boardHealth ?? "",
|
|
19054
|
-
taskIds: existing?.taskIds ?? []
|
|
19055
|
-
};
|
|
19056
19074
|
let snapshot;
|
|
19075
|
+
let cycleReports = [];
|
|
19057
19076
|
if (adapter2.getBuildReportsSince) {
|
|
19058
19077
|
try {
|
|
19059
|
-
|
|
19078
|
+
cycleReports = (await adapter2.getBuildReportsSince(currentCycle)).filter((r) => r.cycle === currentCycle);
|
|
19060
19079
|
const cycleTasks = (await adapter2.queryBoard({ cycleSince: currentCycle, compact: true })).filter((t) => t.cycle === currentCycle);
|
|
19061
19080
|
[snapshot] = computeSnapshotsFromBuildReports(cycleReports, cycleTasks);
|
|
19062
19081
|
} catch (err) {
|
|
@@ -19065,6 +19084,22 @@ To override, pass force=true (emits a telemetry warning).`
|
|
|
19065
19084
|
);
|
|
19066
19085
|
}
|
|
19067
19086
|
}
|
|
19087
|
+
const releaseNow = (/* @__PURE__ */ new Date()).toISOString();
|
|
19088
|
+
const { startDate: resolvedStart, endDate: resolvedEnd } = resolveCompletedCycleDates(
|
|
19089
|
+
existing?.startDate,
|
|
19090
|
+
earliestCycleActivity(cycleReports),
|
|
19091
|
+
releaseNow
|
|
19092
|
+
);
|
|
19093
|
+
const completedCycle = {
|
|
19094
|
+
id: `cycle-${currentCycle}`,
|
|
19095
|
+
number: currentCycle,
|
|
19096
|
+
status: "complete",
|
|
19097
|
+
startDate: resolvedStart,
|
|
19098
|
+
endDate: resolvedEnd ?? void 0,
|
|
19099
|
+
goals: existing?.goals ?? [],
|
|
19100
|
+
boardHealth: existing?.boardHealth ?? "",
|
|
19101
|
+
taskIds: existing?.taskIds ?? []
|
|
19102
|
+
};
|
|
19068
19103
|
if (typeof adapter2.commitRelease === "function") {
|
|
19069
19104
|
try {
|
|
19070
19105
|
await adapter2.commitRelease({ cycle: completedCycle, snapshot: snapshot ?? null });
|
|
@@ -20918,7 +20953,9 @@ async function completeBuild(adapter2, config2, taskId, input, options = {}, cli
|
|
|
20918
20953
|
}
|
|
20919
20954
|
}
|
|
20920
20955
|
}
|
|
20956
|
+
const AUTO_TRIAGE_MIN_SEVERITY = /* @__PURE__ */ new Set(["P0", "P1", "P2"]);
|
|
20921
20957
|
let autoTriagedCount = 0;
|
|
20958
|
+
let autoTriagedSoftSkipped = 0;
|
|
20922
20959
|
const autoTriagedIds = [];
|
|
20923
20960
|
const autoTriagedDupes = [];
|
|
20924
20961
|
if (input.discoveredIssues && input.discoveredIssues !== "None" && typeof adapter2.createTask === "function") {
|
|
@@ -20938,6 +20975,10 @@ async function completeBuild(adapter2, config2, taskId, input, options = {}, cli
|
|
|
20938
20975
|
const sevMatch = line.match(/^(P[0-3])[\s:]+/i);
|
|
20939
20976
|
if (!sevMatch) continue;
|
|
20940
20977
|
const severityLabel = sevMatch[1].toUpperCase();
|
|
20978
|
+
if (!AUTO_TRIAGE_MIN_SEVERITY.has(severityLabel)) {
|
|
20979
|
+
autoTriagedSoftSkipped++;
|
|
20980
|
+
continue;
|
|
20981
|
+
}
|
|
20941
20982
|
const priority = severityLabel === "P0" ? "P0 Critical" : severityLabel === "P1" ? "P1 High" : severityLabel === "P2" ? "P2 Medium" : "P3 Low";
|
|
20942
20983
|
const titleRaw = line.replace(/^P[0-3][\s:]+/i, "").trim();
|
|
20943
20984
|
const title = titleRaw.length > 120 ? titleRaw.slice(0, 120) : titleRaw;
|
|
@@ -21187,6 +21228,7 @@ async function completeBuild(adapter2, config2, taskId, input, options = {}, cli
|
|
|
21187
21228
|
autoTriagedCount: autoTriagedCount > 0 ? autoTriagedCount : void 0,
|
|
21188
21229
|
autoTriagedIds: autoTriagedIds.length > 0 ? autoTriagedIds : void 0,
|
|
21189
21230
|
autoTriagedDupes: autoTriagedDupes.length > 0 ? autoTriagedDupes : void 0,
|
|
21231
|
+
autoTriagedSoftSkipped: autoTriagedSoftSkipped > 0 ? autoTriagedSoftSkipped : void 0,
|
|
21190
21232
|
reportWriteVerified,
|
|
21191
21233
|
localPreview
|
|
21192
21234
|
};
|
|
@@ -22300,7 +22342,7 @@ function formatCompleteResult(result) {
|
|
|
22300
22342
|
if (result.learningsLinkedCount) {
|
|
22301
22343
|
lines.push("", `Linked ${result.learningsLinkedCount} unactioned learning(s) to this task.`);
|
|
22302
22344
|
}
|
|
22303
|
-
if (result.autoTriagedCount || result.autoTriagedDupes?.length) {
|
|
22345
|
+
if (result.autoTriagedCount || result.autoTriagedDupes?.length || result.autoTriagedSoftSkipped) {
|
|
22304
22346
|
const parts = [];
|
|
22305
22347
|
if (result.autoTriagedCount) {
|
|
22306
22348
|
const ids = result.autoTriagedIds?.length ? ` (${result.autoTriagedIds.join(", ")})` : "";
|
|
@@ -22309,6 +22351,9 @@ function formatCompleteResult(result) {
|
|
|
22309
22351
|
if (result.autoTriagedDupes?.length) {
|
|
22310
22352
|
parts.push(`Skipped ${result.autoTriagedDupes.length} duplicate issue(s) already in Backlog: ${result.autoTriagedDupes.join(", ")}.`);
|
|
22311
22353
|
}
|
|
22354
|
+
if (result.autoTriagedSoftSkipped) {
|
|
22355
|
+
parts.push(`${result.autoTriagedSoftSkipped} low-severity (P3) observation(s) recorded to learnings, not filed as tasks.`);
|
|
22356
|
+
}
|
|
22312
22357
|
lines.push("", parts.join(" "));
|
|
22313
22358
|
}
|
|
22314
22359
|
if (result.reportWriteVerified === false) {
|
|
@@ -25759,6 +25804,50 @@ function countStalledP1(warnings) {
|
|
|
25759
25804
|
const matches = stallLine.match(/task-\d+/g);
|
|
25760
25805
|
return matches ? matches.length : 0;
|
|
25761
25806
|
}
|
|
25807
|
+
function truncateTaskTitle(title, max = 55) {
|
|
25808
|
+
const t = (title ?? "").trim();
|
|
25809
|
+
if (!t) return "untitled";
|
|
25810
|
+
if (t.length <= max) return t;
|
|
25811
|
+
return t.slice(0, max - 1).trimEnd() + "\u2026";
|
|
25812
|
+
}
|
|
25813
|
+
async function resolveCarryForwardRefs(carryForward, tasks, adapter2) {
|
|
25814
|
+
const refs = /* @__PURE__ */ new Map();
|
|
25815
|
+
const ids = carryForward?.match(/\btask-\d+\b/g);
|
|
25816
|
+
if (!ids) return refs;
|
|
25817
|
+
const unique = [...new Set(ids)];
|
|
25818
|
+
const byId = new Map(tasks.filter((t) => t.displayId).map((t) => [t.displayId, t]));
|
|
25819
|
+
const missing = [];
|
|
25820
|
+
for (const id of unique) {
|
|
25821
|
+
const t = byId.get(id);
|
|
25822
|
+
if (t) refs.set(id, { title: t.title, status: t.status });
|
|
25823
|
+
else missing.push(id);
|
|
25824
|
+
}
|
|
25825
|
+
if (missing.length > 0 && adapter2?.getTasks) {
|
|
25826
|
+
try {
|
|
25827
|
+
const fetched = await adapter2.getTasks(missing);
|
|
25828
|
+
for (const t of fetched) {
|
|
25829
|
+
if (t.displayId) refs.set(t.displayId, { title: t.title, status: t.status });
|
|
25830
|
+
}
|
|
25831
|
+
} catch {
|
|
25832
|
+
}
|
|
25833
|
+
}
|
|
25834
|
+
return refs;
|
|
25835
|
+
}
|
|
25836
|
+
function annotateTaskRefs(text, refs) {
|
|
25837
|
+
if (!text || refs.size === 0) return text;
|
|
25838
|
+
const RESOLVED = /* @__PURE__ */ new Set(["Done", "Cancelled"]);
|
|
25839
|
+
return text.replace(/\btask-\d+\b(?!\s*[(—–-])/g, (id, offset, full) => {
|
|
25840
|
+
const ref = refs.get(id);
|
|
25841
|
+
if (!ref) return id;
|
|
25842
|
+
const rest = full.slice(offset + id.length);
|
|
25843
|
+
if (/^\s*[(—–-]/.test(rest)) return id;
|
|
25844
|
+
const resolved = ref.status && RESOLVED.has(ref.status);
|
|
25845
|
+
const titlePart = ref.title ? ` \u2014 ${truncateTaskTitle(ref.title)}` : "";
|
|
25846
|
+
const statusPart = resolved ? ` [\u2713 ${ref.status}]` : "";
|
|
25847
|
+
if (!titlePart && !statusPart) return id;
|
|
25848
|
+
return `${id}${titlePart}${statusPart}`;
|
|
25849
|
+
});
|
|
25850
|
+
}
|
|
25762
25851
|
function formatSynthesisParagraph(opts) {
|
|
25763
25852
|
const parts = [];
|
|
25764
25853
|
parts.push(
|
|
@@ -25778,7 +25867,7 @@ function formatSynthesisParagraph(opts) {
|
|
|
25778
25867
|
parts.push(`Next: ${cleanMode}`);
|
|
25779
25868
|
return parts.join(" ");
|
|
25780
25869
|
}
|
|
25781
|
-
function formatOrientSummary(health, buildInfo, hierarchy, latestTag, projectRoot, environment = "unknown", subAgents = [], projectName, teamSummary, clientName) {
|
|
25870
|
+
function formatOrientSummary(health, buildInfo, hierarchy, latestTag, projectRoot, environment = "unknown", subAgents = [], projectName, teamSummary, clientName, taskRefs = /* @__PURE__ */ new Map()) {
|
|
25782
25871
|
const lines = [];
|
|
25783
25872
|
const cycleIsComplete = health.latestCycleStatus === "complete";
|
|
25784
25873
|
const tagSuffix = latestTag ? ` \u2014 ${latestTag}` : "";
|
|
@@ -25921,7 +26010,7 @@ function formatOrientSummary(health, buildInfo, hierarchy, latestTag, projectRoo
|
|
|
25921
26010
|
const hasCarryForward = health.carryForward !== "None found" && !health.carryForward.startsWith("No carry-forward");
|
|
25922
26011
|
if (hasCarryForward) {
|
|
25923
26012
|
lines.push("## Carry-Forward");
|
|
25924
|
-
lines.push(health.carryForward);
|
|
26013
|
+
lines.push(annotateTaskRefs(health.carryForward, taskRefs));
|
|
25925
26014
|
lines.push("");
|
|
25926
26015
|
}
|
|
25927
26016
|
const hasMetrics = health.metricsSection !== "Could not read methodology metrics." && !health.metricsSection.includes("undefined");
|
|
@@ -26210,7 +26299,7 @@ async function handleOrient(adapter2, config2, args = {}, clientName) {
|
|
|
26210
26299
|
(t) => t.createdCycle != null && currentCycle - t.createdCycle >= 3
|
|
26211
26300
|
);
|
|
26212
26301
|
if (stalledP1.length === 0) return void 0;
|
|
26213
|
-
const ids = stalledP1.map((t) => `${t.displayId} (${currentCycle - (t.createdCycle ?? currentCycle)}+ cycles)`).join(", ");
|
|
26302
|
+
const ids = stalledP1.map((t) => `${t.displayId} \u2014 ${truncateTaskTitle(t.title)} (${currentCycle - (t.createdCycle ?? currentCycle)}+ cycles)`).join(", ");
|
|
26214
26303
|
return `\u26A0\uFE0F P1 tasks stalled 3+ cycles: ${ids}`;
|
|
26215
26304
|
}),
|
|
26216
26305
|
// task-1917 (C280): Owner Action Queue surface. Counts the user's open
|
|
@@ -26228,10 +26317,12 @@ async function handleOrient(adapter2, config2, args = {}, clientName) {
|
|
|
26228
26317
|
let dueSuffix = "";
|
|
26229
26318
|
if (adapter2.countDueOwnerActions) {
|
|
26230
26319
|
const due = await adapter2.countDueOwnerActions(userId, projectId);
|
|
26231
|
-
|
|
26232
|
-
|
|
26233
|
-
|
|
26234
|
-
|
|
26320
|
+
if (due.urgent > 0) {
|
|
26321
|
+
const detail = [];
|
|
26322
|
+
if (due.overdue > 0) detail.push(`${due.overdue} overdue`);
|
|
26323
|
+
if (due.dueToday > 0) detail.push(`${due.dueToday} due today`);
|
|
26324
|
+
dueSuffix = detail.length > 0 ? ` (${due.urgent} need you now \u2014 ${detail.join(", ")})` : ` (${due.urgent} need you now)`;
|
|
26325
|
+
}
|
|
26235
26326
|
}
|
|
26236
26327
|
return `\u26A0\uFE0F ${count} action${count === 1 ? "" : "s"} waiting on you${dueSuffix} \u2014 open /hub to triage the Owner Action Queue.`;
|
|
26237
26328
|
} catch {
|
|
@@ -26634,7 +26725,8 @@ ${section}`;
|
|
|
26634
26725
|
]);
|
|
26635
26726
|
const teamSummary = [teamSummaryLine, releaseHistoryLine].filter(Boolean).join("\n") || void 0;
|
|
26636
26727
|
const deepHint = deepHousekeeping ? "" : "\n\n*Tip: pass `full: true` for Research Signals + version-drift, or `deep_housekeeping: true` to also check orphaned branches, merged-but-In-Progress tasks, unrecorded commits, unregistered docs, and stale skill forks (implies `full`).*";
|
|
26637
|
-
|
|
26728
|
+
const carryForwardRefs = await resolveCarryForwardRefs(healthResult.carryForward, allTasks, adapter2);
|
|
26729
|
+
return textResponse(projectBannerNote + formatOrientSummary(healthResult, buildInfo, hierarchy, latestTag, config2.projectRoot, environment, subAgents, projectName, teamSummary, clientName, carryForwardRefs) + unblockNote + deferredGateNote + feedbackResolvedNote + alertsNote + ttfvNote + reconciliationNote + mergedInProgressNote + unrecordedNote + unregisteredDocsNote + staleSkillsNote + researchSignalsNote + recsNote + pendingReviewNote + patternsNote + unactionedIssuesNote + skillProposalsNote + sessionGuidanceNote + versionNote + enrichmentNote + deliveryShapeNote + preBuildCheckNote + deepHint + enrichmentFilesSection);
|
|
26638
26730
|
} catch (err) {
|
|
26639
26731
|
const message = err instanceof Error ? err.message : String(err);
|
|
26640
26732
|
const isKnownFriendly = /^(Orient failed|Project not found|No project|Setup required)/i.test(message);
|
|
@@ -29064,9 +29156,11 @@ ${usageLine(decision.usage)}`;
|
|
|
29064
29156
|
const clientName = server2.getClientVersion()?.name;
|
|
29065
29157
|
const metric = buildMetric(name, elapsed, usage, void 0, contextBytes, contextUtilisation, clientName);
|
|
29066
29158
|
metric.success = !isError;
|
|
29067
|
-
adapter2.appendToolMetric(metric).catch(() => {
|
|
29159
|
+
adapter2.appendToolMetric(metric).catch((err) => {
|
|
29160
|
+
console.error(`[metrics] appendToolMetric failed (non-blocking): ${err instanceof Error ? err.message : String(err)}`);
|
|
29068
29161
|
});
|
|
29069
|
-
} catch {
|
|
29162
|
+
} catch (err) {
|
|
29163
|
+
console.error(`[metrics] buildMetric/appendToolMetric threw (non-blocking): ${err instanceof Error ? err.message : String(err)}`);
|
|
29070
29164
|
}
|
|
29071
29165
|
if (config2.adapterType === "md") {
|
|
29072
29166
|
const mdProjectSlug = config2.projectRoot ? config2.projectRoot.split("/").pop() : void 0;
|
package/dist/prompts.js
CHANGED
|
@@ -69,7 +69,7 @@ PRE-BUILD VERIFICATION
|
|
|
69
69
|
[List 2-5 specific file paths the builder should read BEFORE implementing to check if the functionality already exists. Derive these from FILES LIKELY TOUCHED \u2014 pick the files most likely to already contain the target functionality. ALSO mandate a docs sweep, not just file-existence (task-2161): name any docs the builder should check via doc_search or the docs index \u2014 a design/research/status:final doc or a prior task may already cover the work. If >80% of the scope is already implemented, the builder should report "already built" instead of re-implementing. Include this section for EVERY task \u2014 it prevents wasted build slots on already-shipped code.]
|
|
70
70
|
|
|
71
71
|
FILES LIKELY TOUCHED
|
|
72
|
-
[files]
|
|
72
|
+
[files \u2014 real paths only. TEST FILE LOCATIONS (task-2606): PAPI tests are NOT co-located next to source in a src/**/__tests__/ folder. Use the actual layout: server tests \u2192 packages/server/tests/<name>.test.ts; adapter-pg tests \u2192 packages/adapter-pg/src/__tests__/<name>.test.ts; dashboard/root tests \u2192 tests/<area>/<name>.test.ts. Do NOT invent packages/server/src/**/__tests__/ paths \u2014 they do not exist.]
|
|
73
73
|
|
|
74
74
|
EFFORT
|
|
75
75
|
[XS/S/M/L/XL]
|
|
@@ -1226,7 +1226,7 @@ REFERENCE DOCS
|
|
|
1226
1226
|
[Optional \u2014 paths to docs/ files with background context. Omit if not needed.]
|
|
1227
1227
|
|
|
1228
1228
|
FILES LIKELY TOUCHED
|
|
1229
|
-
[files]
|
|
1229
|
+
[files \u2014 real paths only. TEST FILE LOCATIONS (task-2606): PAPI tests are NOT co-located next to source in a src/**/__tests__/ folder. Use the actual layout: server tests \u2192 packages/server/tests/<name>.test.ts; adapter-pg tests \u2192 packages/adapter-pg/src/__tests__/<name>.test.ts; dashboard/root tests \u2192 tests/<area>/<name>.test.ts. Do NOT invent packages/server/src/**/__tests__/ paths \u2014 they do not exist.]
|
|
1230
1230
|
|
|
1231
1231
|
EFFORT
|
|
1232
1232
|
[XS/S/M/L/XL]`;
|
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.57",
|
|
4
|
+
"description": "PAPI MCP server \u2014 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",
|