@unbrained/pm-cli 2026.9.1 → 2026.9.3
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/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +27 -0
- package/dist/cli/after-command-context-usage.js +16 -3
- package/dist/cli-bundle/bundle-manifest.json +153 -153
- package/dist/cli-bundle/chunks/{chunk-6XIIGE7U.js → chunk-34HASX3S.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-AY324UJ5.js +9 -0
- package/dist/cli-bundle/chunks/{chunk-TAG4VC22.js → chunk-DKGP3QLE.js} +27 -27
- package/dist/cli-bundle/chunks/chunk-E5RBBCXO.js +230 -0
- package/dist/cli-bundle/chunks/{chunk-DTGWEL23.js → chunk-EDPIS7EB.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-X4RCGLTX.js → chunk-IEHHE6GA.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-U45JXJCC.js → chunk-L7B7343B.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-2MC2LCXZ.js → chunk-LENC656S.js} +41 -41
- package/dist/cli-bundle/chunks/chunk-LISESA7W.js +35 -0
- package/dist/cli-bundle/chunks/{chunk-3WICXLVT.js → chunk-UPPM2FOZ.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-Y7VOMSZT.js → chunk-Y4PJ6HPK.js} +2 -2
- package/dist/cli-bundle/chunks/{register-list-query-XYNX4ASQ.js → register-list-query-W2ZTOMKP.js} +2 -2
- package/dist/cli-bundle/chunks/{register-mutation-2MVLRS3J.js → register-mutation-RVND5NCG.js} +2 -2
- package/dist/cli-bundle/chunks/{register-operations-WCIDXBU3.js → register-operations-TTROIVC4.js} +2 -2
- package/dist/cli-bundle/chunks/{register-setup-KVNC5KPL.js → register-setup-D3ZFHY3L.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-3ZBI35HU.js +176 -0
- package/dist/cli-bundle/focused-chunks/{chunk-SVXJYD6G.js → chunk-4HJFY4MB.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-4RRHC3S4.js +6 -0
- package/dist/cli-bundle/focused-chunks/chunk-4WR46RMG.js +9 -0
- package/dist/cli-bundle/focused-chunks/chunk-5RFXUPN5.js +3 -0
- package/dist/cli-bundle/focused-chunks/chunk-BWKHEIVF.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-4O4CJAR6.js → chunk-D7KXFBXV.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-MKHG3T76.js → chunk-GHCZ3YFR.js} +3 -3
- package/dist/cli-bundle/focused-chunks/{chunk-KB5OFSFD.js → chunk-GT7MXDLW.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-KBLZRU62.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-KZ2NB3ET.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-M5M6SVHS.js +3 -0
- package/dist/cli-bundle/focused-chunks/{chunk-BEVHCEWG.js → chunk-OL5EH6I3.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-MEASX544.js → chunk-Q45NHPF2.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-Y6JJIX6I.js → chunk-QKHCSUGJ.js} +48 -48
- package/dist/cli-bundle/focused-chunks/chunk-S27XMBIN.js +8 -0
- package/dist/cli-bundle/focused-chunks/chunk-TXE4TSHM.js +12 -0
- package/dist/cli-bundle/focused-chunks/chunk-UCLO3XDU.js +2 -0
- package/dist/cli-bundle/main.js +15 -15
- package/dist/cli-bundle/sdk-authoring.js +1 -1
- package/dist/cli-bundle/sdk-contracts.js +1 -1
- package/dist/cli-bundle/sdk-core.js +28 -28
- package/dist/cli-bundle/sdk-governance.js +1 -1
- package/dist/cli-bundle/sdk-graph.js +1 -1
- package/dist/cli-bundle/sdk-merge.js +35 -33
- package/dist/cli-bundle/sdk-query.js +1 -1
- package/dist/cli-bundle/sdk-runtime.js +1 -1
- package/dist/cli-bundle/sdk-testing.js +1 -1
- package/dist/cli-bundle/sdk.js +9 -9
- package/dist/core/diagnostics/remediation.js +9 -4
- package/dist/core/history/event-classification.d.ts +21 -0
- package/dist/core/history/event-classification.js +109 -0
- package/dist/core/history/event-index.d.ts +14 -3
- package/dist/core/history/event-index.js +543 -88
- package/dist/core/history/history.js +47 -18
- package/dist/core/history/workspace-history.js +7 -6
- package/dist/core/lock/lock.d.ts +22 -2
- package/dist/core/lock/lock.js +121 -19
- package/dist/core/output/output.js +31 -7
- package/dist/core/shared/time.d.ts +2 -0
- package/dist/core/shared/time.js +8 -2
- package/dist/core/store/item-metadata-query-index.js +5 -5
- package/dist/sdk/context/recency.d.ts +9 -0
- package/dist/sdk/context/recency.js +34 -0
- package/dist/sdk/context/usage-egress.d.ts +9 -0
- package/dist/sdk/context/usage-egress.js +30 -0
- package/dist/sdk/context-intent-contracts.js +7 -3
- package/dist/sdk/context-relevance.d.ts +23 -0
- package/dist/sdk/context-relevance.js +94 -23
- package/dist/sdk/context-signal-store.d.ts +7 -3
- package/dist/sdk/context-signal-store.js +155 -42
- package/dist/sdk/context-usage.d.ts +54 -0
- package/dist/sdk/context-usage.js +245 -16
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +26 -14
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +14 -2
- package/dist/sdk/governance/health.js +77 -11
- package/dist/sdk/governance/validate.js +4 -2
- package/dist/sdk/index.d.ts +2 -0
- package/dist/sdk/index.js +4 -2
- package/dist/sdk/init.d.ts +2 -0
- package/dist/sdk/init.js +18 -9
- package/dist/sdk/merge/index.d.ts +1 -1
- package/dist/sdk/merge/index.js +2 -2
- package/dist/sdk/merge/receipts.d.ts +24 -0
- package/dist/sdk/merge/receipts.js +122 -30
- package/dist/sdk/query/context.d.ts +3 -1
- package/dist/sdk/query/context.js +21 -9
- package/dist/sdk/query/next.js +18 -9
- package/dist/sdk/runtime-input.d.ts +2 -0
- package/dist/sdk/runtime-input.js +25 -2
- package/dist/sdk/runtime.d.ts +1 -0
- package/dist/sdk/runtime.js +17 -26
- package/dist/types.d.ts +2 -0
- package/dist/types.js +2 -2
- package/docs/CONTEXT_RECOVERY_PRIMITIVES.md +11 -2
- package/docs/CONTEXT_RELEVANCE.md +44 -1
- package/docs/MERGE_SAFETY.md +16 -2
- package/docs/PERFORMANCE.md +6 -3
- package/docs/READ_OUTPUT_CONTRACTS.md +9 -1
- package/docs/SDK.md +11 -8
- package/docs/SDK_CONTEXT.md +7 -0
- package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +5 -3
- package/marketplace.json +2 -2
- package/package.json +4 -4
- package/packages/pm-beads/package.json +1 -1
- package/packages/pm-calendar/package.json +1 -1
- package/packages/pm-command-kit/package.json +1 -1
- package/packages/pm-digital-twin/package.json +1 -1
- package/packages/pm-governance-audit/package.json +1 -1
- package/packages/pm-guide-shell/package.json +1 -1
- package/packages/pm-kanban/package.json +1 -1
- package/packages/pm-lifecycle-hooks/package.json +1 -1
- package/packages/pm-linked-test-adapters/package.json +1 -1
- package/packages/pm-search-advanced/package.json +1 -1
- package/packages/pm-templates/package.json +1 -1
- package/packages/pm-todos/package.json +1 -1
- package/packages/pm-vcs/package.json +1 -1
- package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
- package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
- package/sdk/public-surface.json +268 -28
- package/dist/cli-bundle/chunks/chunk-ALKKAUFN.js +0 -35
- package/dist/cli-bundle/chunks/chunk-GOACULJW.js +0 -13
- package/dist/cli-bundle/chunks/chunk-NOPL37X4.js +0 -205
- package/dist/cli-bundle/focused-chunks/chunk-2FEZ5SKM.js +0 -3
- package/dist/cli-bundle/focused-chunks/chunk-6GCRSLPG.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-7VATS5QY.js +0 -16
- package/dist/cli-bundle/focused-chunks/chunk-FWPLDEXF.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-JEFKLWMM.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-PF3E6Q36.js +0 -8
- package/dist/cli-bundle/focused-chunks/chunk-QDFJIRKN.js +0 -4
- package/dist/cli-bundle/focused-chunks/chunk-RMRCQPWU.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-S4U5CN5Q.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-T2LXXSOD.js +0 -158
- package/dist/cli-bundle/focused-chunks/chunk-Z2USIBR2.js +0 -5
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* intents; it never enters item history and is safe to delete or rebuild.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
9
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="997a09a2-cf0c-5384-b457-d9627d465b71")}catch(e){}}();
|
|
10
10
|
import { randomUUID } from "node:crypto";
|
|
11
11
|
import { appendFile, mkdir, readFile, rename, stat, writeFile, } from "node:fs/promises";
|
|
12
12
|
import path from "node:path";
|
|
@@ -16,6 +16,154 @@ const DEFAULT_RETENTION_DAYS = 30;
|
|
|
16
16
|
const DAY_MS = 86_400_000;
|
|
17
17
|
const DEFAULT_COMPACTION_BYTES = 262_144;
|
|
18
18
|
const CONTEXT_USAGE_LOCK_ID = "context-usage-ledger";
|
|
19
|
+
const CONTEXT_USAGE_SERVING_RECEIPT = Symbol.for("@unbrained/pm-cli/context-usage-serving-receipt");
|
|
20
|
+
function asObjectRecord(value) {
|
|
21
|
+
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
22
|
+
? value
|
|
23
|
+
: null;
|
|
24
|
+
}
|
|
25
|
+
/** Attach a JSON-invisible serving receipt to a result for later egress. */
|
|
26
|
+
export function attachContextUsageServingReceipt(result, receipt) {
|
|
27
|
+
const record = asObjectRecord(result);
|
|
28
|
+
if (record !== null && receipt !== null) {
|
|
29
|
+
record[CONTEXT_USAGE_SERVING_RECEIPT] = receipt;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/** Copy an attached serving receipt across a result projection boundary. */
|
|
33
|
+
export function propagateContextUsageServingReceipt(source, target) {
|
|
34
|
+
const sourceRecord = asObjectRecord(source);
|
|
35
|
+
const targetRecord = asObjectRecord(target);
|
|
36
|
+
const receipt = sourceRecord?.[CONTEXT_USAGE_SERVING_RECEIPT];
|
|
37
|
+
if (targetRecord !== null && receipt !== undefined) {
|
|
38
|
+
targetRecord[CONTEXT_USAGE_SERVING_RECEIPT] = receipt;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function receiptFromResult(result) {
|
|
42
|
+
return (asObjectRecord(result)?.[CONTEXT_USAGE_SERVING_RECEIPT] ?? null);
|
|
43
|
+
}
|
|
44
|
+
function resultReceiptSaysOmitted(result) {
|
|
45
|
+
const record = asObjectRecord(result);
|
|
46
|
+
for (const key of ["read_output", "context_intent"]) {
|
|
47
|
+
const receipt = asObjectRecord(record?.[key]);
|
|
48
|
+
if (receipt?.result_omitted === true)
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
function addContextUsageId(ids, value) {
|
|
54
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
55
|
+
ids.add(value.trim());
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function addContextUsageDirectRows(ids, value) {
|
|
59
|
+
if (!Array.isArray(value))
|
|
60
|
+
return;
|
|
61
|
+
for (const row of value) {
|
|
62
|
+
addContextUsageId(ids, asObjectRecord(row)?.id);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function addContextUsageIdList(ids, value) {
|
|
66
|
+
if (!Array.isArray(value))
|
|
67
|
+
return;
|
|
68
|
+
for (const itemId of value)
|
|
69
|
+
addContextUsageId(ids, itemId);
|
|
70
|
+
}
|
|
71
|
+
function collectNextResultItemIds(record, ids) {
|
|
72
|
+
const rows = [
|
|
73
|
+
...(asObjectRecord(record.recommended) === null
|
|
74
|
+
? []
|
|
75
|
+
: [record.recommended]),
|
|
76
|
+
...(Array.isArray(record.ready) ? record.ready : []),
|
|
77
|
+
...(Array.isArray(record.decision_needed) ? record.decision_needed : []),
|
|
78
|
+
...(Array.isArray(record.blocked) ? record.blocked : []),
|
|
79
|
+
...(Array.isArray(record.held_by_others) ? record.held_by_others : []),
|
|
80
|
+
];
|
|
81
|
+
for (const value of rows) {
|
|
82
|
+
const row = asObjectRecord(value);
|
|
83
|
+
addContextUsageId(ids, row?.id);
|
|
84
|
+
for (const blocker of Array.isArray(row?.blockers) ? row.blockers : []) {
|
|
85
|
+
addContextUsageId(ids, asObjectRecord(blocker)?.id);
|
|
86
|
+
}
|
|
87
|
+
for (const unblockedId of Array.isArray(row?.unblocks)
|
|
88
|
+
? row.unblocks
|
|
89
|
+
: []) {
|
|
90
|
+
addContextUsageId(ids, unblockedId);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function collectContextResultItemIds(record, ids) {
|
|
95
|
+
for (const key of [
|
|
96
|
+
"high_level",
|
|
97
|
+
"low_level",
|
|
98
|
+
"blocked_fallback",
|
|
99
|
+
"recently_created",
|
|
100
|
+
"unparented",
|
|
101
|
+
"activity",
|
|
102
|
+
"progress",
|
|
103
|
+
"blockers",
|
|
104
|
+
"staleness",
|
|
105
|
+
]) {
|
|
106
|
+
addContextUsageDirectRows(ids, record[key]);
|
|
107
|
+
}
|
|
108
|
+
for (const value of Array.isArray(record.blockers)
|
|
109
|
+
? record.blockers
|
|
110
|
+
: []) {
|
|
111
|
+
addContextUsageId(ids, asObjectRecord(value)?.blocked_by);
|
|
112
|
+
}
|
|
113
|
+
collectContextNestedItemIds(record, ids);
|
|
114
|
+
}
|
|
115
|
+
function collectContextNestedItemIds(record, ids) {
|
|
116
|
+
for (const value of Array.isArray(record.hierarchy)
|
|
117
|
+
? record.hierarchy
|
|
118
|
+
: []) {
|
|
119
|
+
const node = asObjectRecord(value);
|
|
120
|
+
addContextUsageId(ids, node?.id);
|
|
121
|
+
addContextUsageDirectRows(ids, node?.children);
|
|
122
|
+
}
|
|
123
|
+
for (const key of ["files", "workload"]) {
|
|
124
|
+
for (const value of Array.isArray(record[key]) ? record[key] : []) {
|
|
125
|
+
addContextUsageIdList(ids, asObjectRecord(value)?.items);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
const agenda = asObjectRecord(record.agenda);
|
|
129
|
+
for (const value of Array.isArray(agenda?.events) ? agenda.events : []) {
|
|
130
|
+
addContextUsageId(ids, asObjectRecord(value)?.item_id);
|
|
131
|
+
}
|
|
132
|
+
const tests = asObjectRecord(record.tests);
|
|
133
|
+
addContextUsageIdList(ids, tests?.items_failing);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Collect every item identifier visible in a final context or next result.
|
|
137
|
+
* The traversal is shape-aware so summary counters and unrelated identifier
|
|
138
|
+
* fields cannot enter the privacy-minimal usage ledger.
|
|
139
|
+
*/
|
|
140
|
+
export function collectContextUsageDeliveredItemIds(result, surface) {
|
|
141
|
+
const record = asObjectRecord(result);
|
|
142
|
+
if (record === null || resultReceiptSaysOmitted(result))
|
|
143
|
+
return [];
|
|
144
|
+
const ids = new Set();
|
|
145
|
+
if (surface === "next") {
|
|
146
|
+
collectNextResultItemIds(record, ids);
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
collectContextResultItemIds(record, ids);
|
|
150
|
+
}
|
|
151
|
+
return [...ids];
|
|
152
|
+
}
|
|
153
|
+
/** Resolve and append one post-egress decision carried by a context result. */
|
|
154
|
+
export async function finalizeContextUsageDelivery(options) {
|
|
155
|
+
const receipt = receiptFromResult(options.result);
|
|
156
|
+
if (receipt === null)
|
|
157
|
+
return false;
|
|
158
|
+
const resultOmitted = resultReceiptSaysOmitted(options.result);
|
|
159
|
+
await recordContextUsageDelivery({
|
|
160
|
+
pmRoot: options.pmRoot,
|
|
161
|
+
receipt,
|
|
162
|
+
deliveredItemIds: collectContextUsageDeliveredItemIds(options.result, receipt.surface),
|
|
163
|
+
resultOmitted,
|
|
164
|
+
});
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
19
167
|
/** Named validation failure emitted by context-usage SDK inputs. */
|
|
20
168
|
export class ContextUsageValidationError extends TypeError {
|
|
21
169
|
/** Stable machine-readable error code for package and CLI hosts. */
|
|
@@ -61,7 +209,7 @@ async function readEvents(options) {
|
|
|
61
209
|
return [];
|
|
62
210
|
}
|
|
63
211
|
}
|
|
64
|
-
async function appendEvents(options, events) {
|
|
212
|
+
async function appendEvents(options, events, deliveryServeId) {
|
|
65
213
|
const maxEvents = options.maxEvents ?? DEFAULT_MAX_EVENTS;
|
|
66
214
|
const retentionDays = options.retentionDays ?? DEFAULT_RETENTION_DAYS;
|
|
67
215
|
if (!Number.isInteger(maxEvents) ||
|
|
@@ -75,6 +223,10 @@ async function appendEvents(options, events) {
|
|
|
75
223
|
const releaseLock = await acquireLock(options.pmRoot, CONTEXT_USAGE_LOCK_ID, 30, `context-usage:${process.pid}`, false, false, 3_000);
|
|
76
224
|
try {
|
|
77
225
|
await mkdir(runtimeDirectory, { recursive: true });
|
|
226
|
+
if (deliveryServeId !== undefined &&
|
|
227
|
+
(await readEvents(options)).some((event) => event.kind === "delivery" && event.serve_id === deliveryServeId)) {
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
78
230
|
await appendFile(target, events.map((event) => `${JSON.stringify(event)}\n`).join(""), "utf8");
|
|
79
231
|
const customBounds = options.maxEvents !== undefined || options.retentionDays !== undefined;
|
|
80
232
|
if (!customBounds && (await stat(target)).size <= DEFAULT_COMPACTION_BYTES)
|
|
@@ -93,21 +245,70 @@ async function appendEvent(options, event) {
|
|
|
93
245
|
}
|
|
94
246
|
/** Records a propensity-complete context/next serving event. */
|
|
95
247
|
export async function recordContextUsageServing(options) {
|
|
96
|
-
if (
|
|
97
|
-
|
|
98
|
-
|
|
248
|
+
if ([
|
|
249
|
+
process.env.PM_CONTEXT_USAGE_DISABLED === "1",
|
|
250
|
+
options.enabled === false,
|
|
251
|
+
].includes(true))
|
|
252
|
+
return null;
|
|
99
253
|
if (!options.author.trim() ||
|
|
100
254
|
options.rows.some((row) => !row.id.trim() || !Number.isInteger(row.rank) || row.rank < 1)) {
|
|
101
255
|
throw new ContextUsageValidationError("Context usage serving requires an author and valid ranked rows");
|
|
102
256
|
}
|
|
257
|
+
const normalizedRows = options.rows.map((row) => ({
|
|
258
|
+
...row,
|
|
259
|
+
id: row.id.trim(),
|
|
260
|
+
}));
|
|
261
|
+
if (new Set(normalizedRows.map((row) => row.id)).size !== normalizedRows.length) {
|
|
262
|
+
throw new ContextUsageValidationError("Context usage serving requires unique normalized row ids");
|
|
263
|
+
}
|
|
264
|
+
const receipt = {
|
|
265
|
+
serve_id: randomUUID(),
|
|
266
|
+
author: options.author.trim(),
|
|
267
|
+
surface: options.surface,
|
|
268
|
+
rows: normalizedRows,
|
|
269
|
+
};
|
|
103
270
|
await appendEvent(options, {
|
|
104
271
|
kind: "serve",
|
|
272
|
+
schema_version: 2,
|
|
273
|
+
serve_id: receipt.serve_id,
|
|
105
274
|
at: resolveNow(options).iso,
|
|
106
275
|
author: options.author.trim(),
|
|
107
276
|
surface: options.surface,
|
|
108
277
|
profile: options.profile.trim() || "balanced",
|
|
109
|
-
rows:
|
|
278
|
+
rows: receipt.rows.map((row) => ({ ...row })),
|
|
279
|
+
result_omitted: false,
|
|
280
|
+
packed_item_ids: receipt.rows
|
|
281
|
+
.filter((row) => row.included)
|
|
282
|
+
.map((row) => row.id),
|
|
110
283
|
});
|
|
284
|
+
return receipt;
|
|
285
|
+
}
|
|
286
|
+
/** Append the exact post-egress delivery decision for one serving receipt. */
|
|
287
|
+
export async function recordContextUsageDelivery(options) {
|
|
288
|
+
if (options.receipt === null ||
|
|
289
|
+
process.env.PM_CONTEXT_USAGE_DISABLED === "1" ||
|
|
290
|
+
options.enabled === false) {
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
const rankedIds = new Set(options.receipt.rows.map((row) => row.id));
|
|
294
|
+
const deliveredItemIds = [
|
|
295
|
+
...new Set(options.deliveredItemIds.map((id) => id.trim())),
|
|
296
|
+
];
|
|
297
|
+
if (deliveredItemIds.some((id) => id.length === 0 || !rankedIds.has(id)) ||
|
|
298
|
+
(options.resultOmitted && deliveredItemIds.length > 0)) {
|
|
299
|
+
throw new ContextUsageValidationError("Context usage delivery requires emitted ranked ids and zero ids for an omitted result");
|
|
300
|
+
}
|
|
301
|
+
const delivery = {
|
|
302
|
+
kind: "delivery",
|
|
303
|
+
schema_version: 2,
|
|
304
|
+
serve_id: options.receipt.serve_id,
|
|
305
|
+
at: resolveNow(options).iso,
|
|
306
|
+
author: options.receipt.author,
|
|
307
|
+
surface: options.receipt.surface,
|
|
308
|
+
result_omitted: options.resultOmitted,
|
|
309
|
+
delivered_item_ids: deliveredItemIds,
|
|
310
|
+
};
|
|
311
|
+
await appendEvents(options, [delivery], delivery.serve_id);
|
|
111
312
|
}
|
|
112
313
|
/** Records one subsequent item read or mutation outcome. */
|
|
113
314
|
export async function recordContextUsageTouch(options) {
|
|
@@ -165,6 +366,18 @@ function findTouchTimeInHorizon(touches, itemId, servedAt, horizonMs) {
|
|
|
165
366
|
time >= servedAt &&
|
|
166
367
|
time - servedAt <= horizonMs)?.time;
|
|
167
368
|
}
|
|
369
|
+
function firstDeliveriesByServeId(events, author) {
|
|
370
|
+
const deliveries = new Map();
|
|
371
|
+
for (const event of events) {
|
|
372
|
+
if (event.kind === "delivery" &&
|
|
373
|
+
event.schema_version === 2 &&
|
|
374
|
+
event.author === author &&
|
|
375
|
+
!deliveries.has(event.serve_id)) {
|
|
376
|
+
deliveries.set(event.serve_id, event);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
return deliveries;
|
|
380
|
+
}
|
|
168
381
|
/**
|
|
169
382
|
* Derives decayed served-then-touched affinity. A small exploration floor keeps
|
|
170
383
|
* ignored and unseen items eligible, preventing a popularity feedback lock-in.
|
|
@@ -172,26 +385,41 @@ function findTouchTimeInHorizon(touches, itemId, servedAt, horizonMs) {
|
|
|
172
385
|
export async function readContextUsageAffinity(options) {
|
|
173
386
|
if (process.env.PM_CONTEXT_USAGE_DISABLED === "1" ||
|
|
174
387
|
options.enabled === false)
|
|
175
|
-
return {
|
|
388
|
+
return {
|
|
389
|
+
affinity: {},
|
|
390
|
+
positive_judgments: 0,
|
|
391
|
+
serving_events: 0,
|
|
392
|
+
untrusted_serving_events: 0,
|
|
393
|
+
};
|
|
176
394
|
const events = await readEvents(options);
|
|
177
395
|
const now = resolveNow(options).ms;
|
|
178
396
|
const horizonMs = (options.horizonHours ?? 24) * 3_600_000;
|
|
179
|
-
if (!Number.isFinite(horizonMs)
|
|
397
|
+
if (![Number.isFinite(horizonMs), horizonMs > 0].every(Boolean))
|
|
180
398
|
throw new ContextUsageValidationError("Context usage horizonHours must be positive");
|
|
181
399
|
const author = options.author.trim();
|
|
182
400
|
const touches = events
|
|
183
|
-
.filter((event) => event.kind === "touch"
|
|
401
|
+
.filter((event) => event.kind === "touch")
|
|
402
|
+
.filter((event) => event.author === author)
|
|
184
403
|
.map((entry) => ({ entry, time: Date.parse(entry.at) }));
|
|
185
404
|
const scores = new Map();
|
|
186
405
|
let servingEvents = 0;
|
|
406
|
+
let untrustedServingEvents = 0;
|
|
187
407
|
let positiveJudgments = 0;
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
408
|
+
const deliveries = firstDeliveriesByServeId(events, author);
|
|
409
|
+
events
|
|
410
|
+
.filter((event) => event.kind === "serve")
|
|
411
|
+
.filter((event) => event.author === author)
|
|
412
|
+
.forEach((event) => {
|
|
413
|
+
if (![event.schema_version === 2, Boolean(event.serve_id)].every(Boolean)) {
|
|
414
|
+
untrustedServingEvents += 1;
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
191
417
|
servingEvents += 1;
|
|
192
418
|
const servedAt = Date.parse(event.at);
|
|
419
|
+
const delivery = deliveries.get(event.serve_id);
|
|
420
|
+
const deliveredIds = new Set(delivery?.delivered_item_ids ?? []);
|
|
193
421
|
for (const row of event.rows) {
|
|
194
|
-
if (!row.
|
|
422
|
+
if (!deliveredIds.has(row.id))
|
|
195
423
|
continue;
|
|
196
424
|
const touchTime = findTouchTimeInHorizon(touches, row.id, servedAt, horizonMs);
|
|
197
425
|
if (touchTime === undefined)
|
|
@@ -200,17 +428,18 @@ export async function readContextUsageAffinity(options) {
|
|
|
200
428
|
const ageDays = Math.max(0, (now - touchTime) / DAY_MS);
|
|
201
429
|
scores.set(row.id, (scores.get(row.id) ?? 0) + Math.exp(-ageDays / 14));
|
|
202
430
|
}
|
|
203
|
-
}
|
|
431
|
+
});
|
|
204
432
|
const maximum = Math.max(0, ...scores.values());
|
|
205
433
|
const affinity = Object.fromEntries([...scores.entries()].map(([id, score]) => [
|
|
206
434
|
id,
|
|
207
|
-
0.05
|
|
435
|
+
maximum === 0 ? 0.05 : 0.05 + (0.95 * score) / maximum,
|
|
208
436
|
]));
|
|
209
437
|
return {
|
|
210
438
|
affinity,
|
|
211
439
|
positive_judgments: positiveJudgments,
|
|
212
440
|
serving_events: servingEvents,
|
|
441
|
+
untrusted_serving_events: untrustedServingEvents,
|
|
213
442
|
};
|
|
214
443
|
}
|
|
215
444
|
//# sourceMappingURL=context-usage.js.map
|
|
216
|
-
//# debugId=
|
|
445
|
+
//# debugId=997a09a2-cf0c-5384-b457-d9627d465b71
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Generated partition 1 of the exhaustive error-code catalog. */
|
|
2
2
|
|
|
3
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
3
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="0a4690e9-4cde-5218-81fb-5d59807fa344")}catch(e){}}();
|
|
4
4
|
export const PM_ERROR_CODE_CATALOG_PART_1 = [
|
|
5
5
|
{
|
|
6
6
|
code: "acceptance_criteria_mutation_conflict",
|
|
@@ -1271,6 +1271,18 @@ export const PM_ERROR_CODE_CATALOG_PART_1 = [
|
|
|
1271
1271
|
canonical_code: "history_target_out_of_range",
|
|
1272
1272
|
aliases: [],
|
|
1273
1273
|
},
|
|
1274
|
+
{
|
|
1275
|
+
code: "history_timestamp_invalid",
|
|
1276
|
+
meaning: "History timestamp invalid condition.",
|
|
1277
|
+
stability: "provisional",
|
|
1278
|
+
exit_code: 1,
|
|
1279
|
+
class: "generic_failure",
|
|
1280
|
+
recovery: "Inspect the structured error guidance and retry the suggested command.",
|
|
1281
|
+
sources: ["core/history/event-index.ts", "core/history/history.ts"],
|
|
1282
|
+
emitting_commands: ["*"],
|
|
1283
|
+
canonical_code: "history_timestamp_invalid",
|
|
1284
|
+
aliases: [],
|
|
1285
|
+
},
|
|
1274
1286
|
{
|
|
1275
1287
|
code: "history_unknown_author_events",
|
|
1276
1288
|
meaning: "History unknown author events condition.",
|
|
@@ -2076,6 +2088,18 @@ export const PM_ERROR_CODE_CATALOG_PART_1 = [
|
|
|
2076
2088
|
canonical_code: "merge_receipt_evidence_invalid",
|
|
2077
2089
|
aliases: [],
|
|
2078
2090
|
},
|
|
2091
|
+
{
|
|
2092
|
+
code: "merge_receipt_history_reference_missing",
|
|
2093
|
+
meaning: "Merge receipt history reference missing condition.",
|
|
2094
|
+
stability: "provisional",
|
|
2095
|
+
exit_code: 1,
|
|
2096
|
+
class: "generic_failure",
|
|
2097
|
+
recovery: "Inspect the structured error guidance and retry the suggested command.",
|
|
2098
|
+
sources: ["core/diagnostics/remediation.ts"],
|
|
2099
|
+
emitting_commands: ["*"],
|
|
2100
|
+
canonical_code: "merge_receipt_history_reference_missing",
|
|
2101
|
+
aliases: [],
|
|
2102
|
+
},
|
|
2079
2103
|
{
|
|
2080
2104
|
code: "merge_receipts_pending",
|
|
2081
2105
|
meaning: "Merge receipts pending condition.",
|
|
@@ -2136,18 +2160,6 @@ export const PM_ERROR_CODE_CATALOG_PART_1 = [
|
|
|
2136
2160
|
canonical_code: "missing_budget",
|
|
2137
2161
|
aliases: [],
|
|
2138
2162
|
},
|
|
2139
|
-
{
|
|
2140
|
-
code: "missing_cli_flag",
|
|
2141
|
-
meaning: "Missing cli flag condition.",
|
|
2142
|
-
stability: "provisional",
|
|
2143
|
-
exit_code: 1,
|
|
2144
|
-
class: "generic_failure",
|
|
2145
|
-
recovery: "Inspect the structured error guidance and retry the suggested command.",
|
|
2146
|
-
sources: ["sdk/cli-contracts/tool-option-contracts.ts"],
|
|
2147
|
-
emitting_commands: ["*"],
|
|
2148
|
-
canonical_code: "missing_cli_flag",
|
|
2149
|
-
aliases: [],
|
|
2150
|
-
},
|
|
2151
2163
|
];
|
|
2152
2164
|
//# sourceMappingURL=generated-error-code-catalog-part-1.js.map
|
|
2153
|
-
//# debugId=
|
|
2165
|
+
//# debugId=0a4690e9-4cde-5218-81fb-5d59807fa344
|
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
/** Generated partition 2 of the exhaustive error-code catalog. */
|
|
2
2
|
|
|
3
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
3
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="5d5a1c08-21ed-5823-8c1b-15f7907ab3b5")}catch(e){}}();
|
|
4
4
|
export const PM_ERROR_CODE_CATALOG_PART_2 = [
|
|
5
|
+
{
|
|
6
|
+
code: "missing_cli_flag",
|
|
7
|
+
meaning: "Missing cli flag condition.",
|
|
8
|
+
stability: "provisional",
|
|
9
|
+
exit_code: 1,
|
|
10
|
+
class: "generic_failure",
|
|
11
|
+
recovery: "Inspect the structured error guidance and retry the suggested command.",
|
|
12
|
+
sources: ["sdk/cli-contracts/tool-option-contracts.ts"],
|
|
13
|
+
emitting_commands: ["*"],
|
|
14
|
+
canonical_code: "missing_cli_flag",
|
|
15
|
+
aliases: [],
|
|
16
|
+
},
|
|
5
17
|
{
|
|
6
18
|
code: "missing_destination",
|
|
7
19
|
meaning: "Missing destination condition.",
|
|
@@ -2174,4 +2186,4 @@ export const PM_ERROR_CODE_CATALOG_PART_2 = [
|
|
|
2174
2186
|
},
|
|
2175
2187
|
];
|
|
2176
2188
|
//# sourceMappingURL=generated-error-code-catalog-part-2.js.map
|
|
2177
|
-
//# debugId=
|
|
2189
|
+
//# debugId=5d5a1c08-21ed-5823-8c1b-15f7907ab3b5
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Implements the pm health command surface and its agent-facing runtime behavior.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
7
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="f27cb24d-f2c8-5034-b655-84c577de7a16")}catch(e){}}();
|
|
8
8
|
import fs from "node:fs/promises";
|
|
9
9
|
import path from "node:path";
|
|
10
10
|
import { assertInitializedTracker } from "../environment/tracker-preflight.js";
|
|
@@ -28,6 +28,7 @@ import { EXIT_CODE, PM_CORE_REQUIRED_SUBDIRS, TYPE_TO_FOLDER, } from "../../core
|
|
|
28
28
|
import { findFirstMergeConflictMarker } from "../../core/shared/conflict-markers.js";
|
|
29
29
|
import { PmCliError } from "../../core/shared/errors.js";
|
|
30
30
|
import { toNonEmptyStringOrUndefined } from "../../core/shared/primitives.js";
|
|
31
|
+
import { sha256Hex } from "../../core/shared/serialization.js";
|
|
31
32
|
import { nowIso } from "../../core/shared/time.js";
|
|
32
33
|
import { parseItemDocument } from "../../core/item/item-format.js";
|
|
33
34
|
import { effectiveItemFormatVersion, scanItemFormatVersions, } from "../../core/item/item-format-version.js";
|
|
@@ -46,7 +47,7 @@ import { buildCapabilityContractMetadata, buildRegistrationCollisionRemediation,
|
|
|
46
47
|
import { scanStaleInProgressItems, } from "./stale-work.js";
|
|
47
48
|
import { scanTrackedRuntimeCache } from "./tracked-runtime-cache.js";
|
|
48
49
|
import { auditMergeDriverConfiguration, findGitWorkspaceRoot, } from "../merge/install.js";
|
|
49
|
-
import { inspectMergeReceiptEvidence, partitionMergeReceipts, } from "../merge/receipts.js";
|
|
50
|
+
import { inspectMergeReceiptEvidence, isSafeReceiptId, partitionMergeReceipts, } from "../merge/receipts.js";
|
|
50
51
|
import { runHistoryRepair } from "../history-repair.js";
|
|
51
52
|
import { resolveWorkspaceRelationshipKindRegistry } from "../graph/assembly.js";
|
|
52
53
|
import { analyzeHierarchyIntegrity, } from "../graph/hierarchy-integrity.js";
|
|
@@ -278,11 +279,41 @@ async function scanItemIntegrity(pmRoot, typeToFolder, schema) {
|
|
|
278
279
|
}
|
|
279
280
|
return { paths, unreadable, conflictMarkers, parseFailures, formatVersions };
|
|
280
281
|
}
|
|
282
|
+
function mergeReceiptIdsFromHistoryEntry(value) {
|
|
283
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
284
|
+
return [];
|
|
285
|
+
}
|
|
286
|
+
const context = value.context;
|
|
287
|
+
if (typeof context !== "object" ||
|
|
288
|
+
context === null ||
|
|
289
|
+
Array.isArray(context)) {
|
|
290
|
+
return [];
|
|
291
|
+
}
|
|
292
|
+
const merge = context.merge;
|
|
293
|
+
if (typeof merge !== "object" || merge === null || Array.isArray(merge)) {
|
|
294
|
+
return [];
|
|
295
|
+
}
|
|
296
|
+
const receipts = merge.receipts;
|
|
297
|
+
if (!Array.isArray(receipts))
|
|
298
|
+
return [];
|
|
299
|
+
return receipts.flatMap((receipt) => {
|
|
300
|
+
if (typeof receipt !== "object" ||
|
|
301
|
+
receipt === null ||
|
|
302
|
+
Array.isArray(receipt)) {
|
|
303
|
+
return [];
|
|
304
|
+
}
|
|
305
|
+
const receiptId = receipt.receipt_id;
|
|
306
|
+
return typeof receiptId === "string" && receiptId.length > 0
|
|
307
|
+
? [receiptId]
|
|
308
|
+
: [];
|
|
309
|
+
});
|
|
310
|
+
}
|
|
281
311
|
async function scanHistoryIntegrity(pmRoot) {
|
|
282
312
|
const historyDir = path.join(pmRoot, "history");
|
|
283
313
|
const unreadable = [];
|
|
284
314
|
const conflictMarkers = [];
|
|
285
315
|
const invalidJson = [];
|
|
316
|
+
const mergeReceiptReferences = [];
|
|
286
317
|
let files = [];
|
|
287
318
|
try {
|
|
288
319
|
files = (await fs.readdir(historyDir))
|
|
@@ -314,14 +345,25 @@ async function scanHistoryIntegrity(pmRoot) {
|
|
|
314
345
|
if (!line.trim())
|
|
315
346
|
return;
|
|
316
347
|
try {
|
|
317
|
-
JSON.parse(line);
|
|
348
|
+
const parsed = JSON.parse(line);
|
|
349
|
+
mergeReceiptReferences.push(...mergeReceiptIdsFromHistoryEntry(parsed).map((receiptId) => ({
|
|
350
|
+
itemId,
|
|
351
|
+
line: index + 1,
|
|
352
|
+
receiptId,
|
|
353
|
+
})));
|
|
318
354
|
}
|
|
319
355
|
catch {
|
|
320
356
|
invalidJson.push({ id: itemId, line: index + 1 });
|
|
321
357
|
}
|
|
322
358
|
});
|
|
323
359
|
}
|
|
324
|
-
return {
|
|
360
|
+
return {
|
|
361
|
+
files,
|
|
362
|
+
unreadable,
|
|
363
|
+
conflictMarkers,
|
|
364
|
+
invalidJson,
|
|
365
|
+
mergeReceiptReferences,
|
|
366
|
+
};
|
|
325
367
|
}
|
|
326
368
|
function buildHierarchyIntegrityWarnings(analysis) {
|
|
327
369
|
return [
|
|
@@ -336,10 +378,15 @@ function buildHierarchyIntegrityWarnings(analysis) {
|
|
|
336
378
|
: `integrity_hierarchy_divergence:${finding.child_id}`),
|
|
337
379
|
];
|
|
338
380
|
}
|
|
339
|
-
function buildMergeReceiptEvidenceWarnings(
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
381
|
+
function buildMergeReceiptEvidenceWarnings(params) {
|
|
382
|
+
const warnings = [];
|
|
383
|
+
if (params.invalidEvidenceCount > 0) {
|
|
384
|
+
warnings.push(`merge_receipt_evidence_invalid:${params.invalidEvidenceCount}`);
|
|
385
|
+
}
|
|
386
|
+
if (params.missingHistoryReferenceCount > 0) {
|
|
387
|
+
warnings.push(`merge_receipt_history_reference_missing:${params.missingHistoryReferenceCount}`);
|
|
388
|
+
}
|
|
389
|
+
return warnings;
|
|
343
390
|
}
|
|
344
391
|
async function buildIntegrityCheck(pmRoot, typeToFolder, schema, requireMergeDrivers, items) {
|
|
345
392
|
const itemScan = await scanItemIntegrity(pmRoot, typeToFolder, schema);
|
|
@@ -353,10 +400,21 @@ async function buildIntegrityCheck(pmRoot, typeToFolder, schema, requireMergeDri
|
|
|
353
400
|
? null
|
|
354
401
|
: await auditMergeDriverConfiguration(gitWorkspaceRoot);
|
|
355
402
|
const mergeReceiptEvidence = await inspectMergeReceiptEvidence(gitWorkspaceRoot ?? pmRoot, {
|
|
403
|
+
includeReconciled: true,
|
|
356
404
|
includeLossless: true,
|
|
357
405
|
pmRoot,
|
|
358
406
|
});
|
|
359
|
-
const
|
|
407
|
+
const availableMergeReceiptIds = new Set(mergeReceiptEvidence.receipts.map((receipt) => receipt.id));
|
|
408
|
+
const missingMergeReceiptReferences = historyScan.mergeReceiptReferences
|
|
409
|
+
.filter((reference) => !availableMergeReceiptIds.has(reference.receiptId))
|
|
410
|
+
.map((reference) => ({
|
|
411
|
+
item_id: reference.itemId,
|
|
412
|
+
history_line: reference.line,
|
|
413
|
+
...(isSafeReceiptId(reference.receiptId)
|
|
414
|
+
? { receipt_id: reference.receiptId }
|
|
415
|
+
: { receipt_reference_hash: sha256Hex(reference.receiptId) }),
|
|
416
|
+
}));
|
|
417
|
+
const pendingMergeReceipts = mergeReceiptEvidence.receipts.filter((receipt) => receipt.state === "pending");
|
|
360
418
|
const { pendingDecisions: pendingMergeDecisions, lossless: losslessMergeReceipts, } = partitionMergeReceipts(pendingMergeReceipts);
|
|
361
419
|
const mergeDriverInstallationMissing = mergeDriverAudit?.status === "missing" &&
|
|
362
420
|
mergeDriverAudit.missing_keys.length === 5 &&
|
|
@@ -389,7 +447,10 @@ async function buildIntegrityCheck(pmRoot, typeToFolder, schema, requireMergeDri
|
|
|
389
447
|
...(losslessMergeReceipts.length > 0
|
|
390
448
|
? [`merge_receipts_pending:${losslessMergeReceipts.length}`]
|
|
391
449
|
: []),
|
|
392
|
-
...buildMergeReceiptEvidenceWarnings(
|
|
450
|
+
...buildMergeReceiptEvidenceWarnings({
|
|
451
|
+
invalidEvidenceCount: mergeReceiptEvidence.invalid_evidence_count,
|
|
452
|
+
missingHistoryReferenceCount: missingMergeReceiptReferences.length,
|
|
453
|
+
}),
|
|
393
454
|
];
|
|
394
455
|
const normalizedWarnings = [...new Set(warnings)].sort((left, right) => left.localeCompare(right));
|
|
395
456
|
const actionableWarnings = normalizedWarnings.filter((warning) => !warning.startsWith("integrity_legacy_hierarchy_"));
|
|
@@ -421,6 +482,7 @@ async function buildIntegrityCheck(pmRoot, typeToFolder, schema, requireMergeDri
|
|
|
421
482
|
pending_merge_decisions: pendingMergeDecisions.length,
|
|
422
483
|
lossless_merge_receipts: losslessMergeReceipts.length,
|
|
423
484
|
invalid_merge_receipt_evidence: mergeReceiptEvidence.invalid_evidence_count,
|
|
485
|
+
missing_merge_receipt_history_references: missingMergeReceiptReferences.length,
|
|
424
486
|
},
|
|
425
487
|
item_unreadable: itemScan.unreadable,
|
|
426
488
|
item_conflict_markers: itemScan.conflictMarkers,
|
|
@@ -452,6 +514,10 @@ async function buildIntegrityCheck(pmRoot, typeToFolder, schema, requireMergeDri
|
|
|
452
514
|
lossless_merge_receipt_items: [
|
|
453
515
|
...new Set(losslessMergeReceipts.map((receipt) => receipt.item_id)),
|
|
454
516
|
].sort((left, right) => left.localeCompare(right)),
|
|
517
|
+
invalid_merge_receipt_evidence_details: mergeReceiptEvidence.invalid_evidence,
|
|
518
|
+
invalid_merge_receipt_evidence_details_truncated: mergeReceiptEvidence.invalid_evidence_truncated,
|
|
519
|
+
missing_merge_receipt_history_reference_details: missingMergeReceiptReferences.slice(0, HEALTH_WARNING_LIMIT),
|
|
520
|
+
missing_merge_receipt_history_reference_details_truncated: missingMergeReceiptReferences.length > HEALTH_WARNING_LIMIT,
|
|
455
521
|
},
|
|
456
522
|
},
|
|
457
523
|
warnings: normalizedWarnings,
|
|
@@ -2309,4 +2375,4 @@ export const _testOnlyHealthCommand = {
|
|
|
2309
2375
|
warningCode,
|
|
2310
2376
|
};
|
|
2311
2377
|
//# sourceMappingURL=health.js.map
|
|
2312
|
-
//# debugId=
|
|
2378
|
+
//# debugId=f27cb24d-f2c8-5034-b655-84c577de7a16
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Implements the pm validate command surface and its agent-facing runtime behavior.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
7
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="0d466293-869d-54bb-b07d-facb3be51e8c")}catch(e){}}();
|
|
8
8
|
import { assertInitializedTracker } from "../environment/tracker-preflight.js";
|
|
9
9
|
import fs from "node:fs/promises";
|
|
10
10
|
import { realpathSync } from "node:fs";
|
|
@@ -2053,6 +2053,8 @@ async function buildStorageIntegrityCheck(pmRoot, items, typeToFolder, settings)
|
|
|
2053
2053
|
].sort((left, right) => left.localeCompare(right)),
|
|
2054
2054
|
lossless_merge_receipt_count: losslessMergeReceipts.length,
|
|
2055
2055
|
invalid_merge_receipt_evidence_count: mergeReceiptEvidence.invalid_evidence_count,
|
|
2056
|
+
invalid_merge_receipt_evidence_details: mergeReceiptEvidence.invalid_evidence,
|
|
2057
|
+
invalid_merge_receipt_evidence_details_truncated: mergeReceiptEvidence.invalid_evidence_truncated,
|
|
2056
2058
|
lossless_merge_receipt_items: [
|
|
2057
2059
|
...new Set(losslessMergeReceipts.map((receipt) => receipt.item_id)),
|
|
2058
2060
|
].sort((left, right) => left.localeCompare(right)),
|
|
@@ -2273,4 +2275,4 @@ export async function runValidate(options, global, services = {}) {
|
|
|
2273
2275
|
}
|
|
2274
2276
|
/* c8 ignore stop */
|
|
2275
2277
|
//# sourceMappingURL=validate.js.map
|
|
2276
|
-
//# debugId=
|
|
2278
|
+
//# debugId=0d466293-869d-54bb-b07d-facb3be51e8c
|
package/dist/sdk/index.d.ts
CHANGED
|
@@ -81,6 +81,7 @@ export * from "./environment/source-context.js";
|
|
|
81
81
|
export * from "./environment/host-environment-errors.js";
|
|
82
82
|
export * from "./cli-contracts/command-exit-contracts.js";
|
|
83
83
|
export * from "./context-relevance.js";
|
|
84
|
+
export * from "./context/recency.js";
|
|
84
85
|
export * from "./context-intent-contracts.js";
|
|
85
86
|
export * from "./context-intent-runtime.js";
|
|
86
87
|
export * from "./context-signal-store.js";
|
|
@@ -94,6 +95,7 @@ export * from "./read-output-session.js";
|
|
|
94
95
|
export * from "./output-token-accounting.js";
|
|
95
96
|
export * from "./context-packing.js";
|
|
96
97
|
export * from "./context-usage.js";
|
|
98
|
+
export { classifyHistoryEvent, HISTORY_EVENT_CLASSIFICATION_VERSION, MAINTENANCE_HISTORY_OPERATIONS, SUBSTANTIVE_HISTORY_OPERATIONS, type HistoryEventClass, } from "../core/history/event-classification.js";
|
|
97
99
|
export * from "./dependency-provenance.js";
|
|
98
100
|
export * from "./duplicates.js";
|
|
99
101
|
export * from "./lifecycle/reopen.js";
|