@unbrained/pm-cli 2026.8.8 → 2026.8.10
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 +59 -0
- package/dist/cli/commander-usage.js +17 -12
- package/dist/cli/help-json-payload.js +51 -16
- package/dist/cli/main.js +7 -6
- package/dist/cli-bundle/bundle-manifest.json +162 -162
- package/dist/cli-bundle/chunks/chunk-2QYH4QMI.js +30 -0
- package/dist/cli-bundle/chunks/{chunk-2ZMXX3Q6.js → chunk-EBO7OUUE.js} +70 -70
- package/dist/cli-bundle/chunks/{chunk-NUXRRNAB.js → chunk-ETML5C6H.js} +48 -48
- package/dist/cli-bundle/chunks/chunk-JUDU4RO4.js +194 -0
- package/dist/cli-bundle/chunks/chunk-JZSNADRR.js +5 -0
- package/dist/cli-bundle/chunks/chunk-MENWVGJW.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-ALDHXLPS.js → chunk-S4EITGLA.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-TIGKWVLA.js +13 -0
- package/dist/cli-bundle/chunks/{chunk-CBLA33YK.js → chunk-TRWXF476.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-TSLDTJLQ.js +2 -0
- package/dist/cli-bundle/chunks/{register-list-query-WFZAMJHZ.js → register-list-query-OJ6ZXKV4.js} +2 -2
- package/dist/cli-bundle/chunks/{register-mutation-SOKKOTHQ.js → register-mutation-DKI7QC7O.js} +2 -2
- package/dist/cli-bundle/chunks/register-operations-P5OGMT6I.js +2 -0
- package/dist/cli-bundle/chunks/{register-setup-2HL5ZHMK.js → register-setup-S3KT2LTH.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-ANTMGYLI.js → chunk-2COZ67XT.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-2EXI2DKR.js +4 -0
- package/dist/cli-bundle/focused-chunks/{chunk-YSAHYUXX.js → chunk-34SX654S.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-36FTZ2NT.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-3CQECMKR.js +16 -0
- package/dist/cli-bundle/focused-chunks/chunk-75774JWP.js +6 -0
- package/dist/cli-bundle/focused-chunks/chunk-7UN6BHHO.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-TCSAPH33.js → chunk-CHIBMEZR.js} +6 -6
- package/dist/cli-bundle/focused-chunks/chunk-DZGAHZZV.js +3 -0
- package/dist/cli-bundle/focused-chunks/chunk-FF4MNAYB.js +153 -0
- package/dist/cli-bundle/focused-chunks/chunk-GHTN2ILR.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-I4YM2I7S.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-IMDTEN7K.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-IW43E4XL.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-JMVA4HKR.js +5 -0
- package/dist/cli-bundle/focused-chunks/{chunk-PL2EYDJK.js → chunk-KR5RVXLQ.js} +31 -29
- package/dist/cli-bundle/focused-chunks/chunk-KSNJG4KI.js +16 -0
- package/dist/cli-bundle/focused-chunks/chunk-M6RPIXKC.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-MXYSIQ56.js +18 -0
- package/dist/cli-bundle/focused-chunks/chunk-RIIN5V4N.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-RKWSCYYN.js +2 -0
- package/dist/cli-bundle/main.js +13 -13
- 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 +38 -38
- 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 +1 -1
- 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 +2 -2
- package/dist/core/diagnostics/remediation.js +19 -9
- package/dist/core/fs/fs-utils.d.ts +10 -0
- package/dist/core/fs/fs-utils.js +16 -4
- package/dist/core/history/history.js +13 -4
- package/dist/core/item/actionability.d.ts +7 -1
- package/dist/core/item/actionability.js +71 -15
- package/dist/core/item/item-format.js +3 -32
- package/dist/core/schema/fields-file.d.ts +1 -2
- package/dist/core/schema/fields-file.js +4 -11
- package/dist/core/schema/runtime-schema.js +3 -10
- package/dist/core/schema/status-defs-file.d.ts +1 -2
- package/dist/core/schema/status-defs-file.js +4 -32
- package/dist/core/schema/status-token.d.ts +2 -0
- package/dist/core/schema/status-token.js +32 -0
- package/dist/core/schema/type-workflows.d.ts +1 -2
- package/dist/core/schema/type-workflows.js +4 -11
- package/dist/core/shared/author.d.ts +25 -0
- package/dist/core/shared/author.js +128 -10
- package/dist/core/shared/errors.d.ts +4 -0
- package/dist/core/shared/errors.js +2 -2
- package/dist/core/shared/text-normalization.d.ts +1 -1
- package/dist/core/shared/text-normalization.js +2 -2
- package/dist/sdk/actionability.d.ts +1 -1
- package/dist/sdk/actionability.js +3 -3
- package/dist/sdk/agent/command-recovery.d.ts +4 -0
- package/dist/sdk/agent/command-recovery.js +52 -0
- package/dist/sdk/agent/command-suggestions.d.ts +4 -0
- package/dist/sdk/agent/command-suggestions.js +67 -0
- package/dist/sdk/agent/create-option-policy.d.ts +12 -0
- package/dist/sdk/agent/create-option-policy.js +32 -0
- package/dist/sdk/agent/item-addressing.d.ts +19 -0
- package/dist/sdk/agent/item-addressing.js +208 -0
- package/dist/sdk/cli-bootstrap.d.ts +1 -1
- package/dist/sdk/cli-bootstrap.js +20 -5
- package/dist/sdk/cli-contracts/commander-mutation-options.js +16 -4
- package/dist/sdk/cli-contracts/flag-contracts.js +62 -21
- package/dist/sdk/cli-contracts/registration-helpers.js +10 -2
- package/dist/sdk/cli-contracts/runtime-contracts.d.ts +8 -0
- package/dist/sdk/cli-contracts/runtime-contracts.js +20 -3
- package/dist/sdk/cli-contracts/tool-option-contracts.d.ts +6 -0
- package/dist/sdk/cli-contracts/tool-option-contracts.js +4 -2
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +19 -4
- package/dist/sdk/cli-contracts/tool-schema.js +17 -4
- package/dist/sdk/context-intent-runtime.js +8 -5
- package/dist/sdk/context-signal-store.d.ts +34 -0
- package/dist/sdk/context-signal-store.js +24 -2
- package/dist/sdk/core-governance.d.ts +1 -1
- package/dist/sdk/core-governance.js +3 -3
- package/dist/sdk/dependencies.d.ts +2 -0
- package/dist/sdk/dependencies.js +7 -6
- package/dist/sdk/dependency-flag-validation.d.ts +15 -1
- package/dist/sdk/dependency-flag-validation.js +54 -2
- package/dist/sdk/extension/bundled-catalog.js +19 -6
- package/dist/sdk/generated-error-code-catalog.js +110 -2
- package/dist/sdk/governance/health.js +38 -12
- package/dist/sdk/governance/provenance-health.d.ts +39 -0
- package/dist/sdk/governance/provenance-health.js +185 -0
- package/dist/sdk/governance/validate-item-reader.d.ts +13 -0
- package/dist/sdk/governance/validate-item-reader.js +18 -0
- package/dist/sdk/governance/validate.d.ts +2 -2
- package/dist/sdk/governance/validate.js +25 -11
- package/dist/sdk/governance.d.ts +1 -0
- package/dist/sdk/governance.js +3 -2
- package/dist/sdk/graph/assembly.d.ts +4 -0
- package/dist/sdk/graph/assembly.js +22 -2
- package/dist/sdk/graph/run.d.ts +2 -0
- package/dist/sdk/graph/run.js +3 -2
- package/dist/sdk/index.d.ts +4 -0
- package/dist/sdk/index.js +6 -2
- package/dist/sdk/lifecycle/close.js +27 -19
- package/dist/sdk/lifecycle/create.d.ts +2 -0
- package/dist/sdk/lifecycle/create.js +66 -19
- package/dist/sdk/lifecycle/plan.js +6 -3
- package/dist/sdk/lifecycle/update-many.js +39 -27
- package/dist/sdk/lifecycle/update.d.ts +6 -1
- package/dist/sdk/lifecycle/update.js +51 -28
- package/dist/sdk/merge/driver.d.ts +2 -1
- package/dist/sdk/merge/driver.js +7 -4
- package/dist/sdk/merge/index.d.ts +1 -1
- package/dist/sdk/merge/index.js +3 -3
- package/dist/sdk/merge/install.d.ts +4 -0
- package/dist/sdk/merge/install.js +29 -17
- package/dist/sdk/merge/receipts.d.ts +17 -1
- package/dist/sdk/merge/receipts.js +112 -20
- package/dist/sdk/merge/reconcile.js +21 -4
- package/dist/sdk/merge/three-way.d.ts +6 -2
- package/dist/sdk/merge/three-way.js +24 -10
- package/dist/sdk/output-projection.js +24 -4
- package/dist/sdk/query/context.d.ts +2 -0
- package/dist/sdk/query/context.js +7 -4
- package/dist/sdk/query/get.d.ts +11 -0
- package/dist/sdk/query/get.js +37 -3
- package/dist/sdk/query/light-metadata.d.ts +3 -0
- package/dist/sdk/query/light-metadata.js +19 -0
- package/dist/sdk/read-output-contracts.d.ts +1 -1
- package/dist/sdk/read-output-contracts.js +23 -4
- package/dist/sdk/relationship-kinds/contract.d.ts +48 -0
- package/dist/sdk/relationship-kinds/contract.js +22 -0
- package/dist/sdk/relationships.d.ts +6 -41
- package/dist/sdk/relationships.js +12 -126
- package/dist/sdk/runtime-primitives.d.ts +1 -1
- package/dist/sdk/runtime-primitives.js +3 -3
- package/dist/sdk/runtime.d.ts +4 -1
- package/dist/sdk/runtime.js +8 -3
- package/dist/sdk/schema-migration.js +7 -9
- package/dist/sdk/similarity-scoring.d.ts +1 -2
- package/dist/sdk/similarity-scoring.js +4 -16
- package/dist/sdk/similarity.d.ts +5 -0
- package/dist/sdk/similarity.js +40 -10
- package/dist/sdk/structured-mutations.js +5 -2
- package/dist/sdk/test/linked-command-detection.d.ts +2 -7
- package/dist/sdk/test/linked-command-detection.js +22 -9
- package/dist/sdk/workspace-snapshot.d.ts +4 -0
- package/dist/sdk/workspace-snapshot.js +24 -11
- package/docs/AGENT_GUIDE.md +5 -2
- package/docs/COMMANDS.md +27 -6
- package/docs/DEPENDENCY_KIND_CONTRACT.md +29 -0
- package/docs/ITEM_READ_PROJECTIONS.md +26 -0
- package/docs/MERGE_SAFETY.md +17 -8
- package/docs/README.md +2 -5
- package/docs/READ_OUTPUT_CONTRACTS.md +2 -2
- package/docs/RELATIONSHIP_GRAPH.md +1 -1
- package/docs/SDK.md +33 -8
- package/docs/SDK_AGENT_SESSION_CONTEXT.md +36 -2
- package/docs/SDK_CONTEXT.md +97 -0
- package/docs/SDK_CONTEXT_INTEGRITY.md +33 -3
- package/docs/SENTRY_CONTRACT_EPOCHS.md +20 -0
- package/docs/agent-task-token-baseline.json +2 -2
- package/marketplace.json +2 -2
- package/package.json +5 -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 +415 -43
- package/dist/cli-bundle/chunks/chunk-GKA54IJM.js +0 -5
- package/dist/cli-bundle/chunks/chunk-KRY7SRUO.js +0 -2
- package/dist/cli-bundle/chunks/chunk-MNJ4NNSY.js +0 -26
- package/dist/cli-bundle/chunks/chunk-OJPCFDDY.js +0 -13
- package/dist/cli-bundle/chunks/chunk-PFSD3DAN.js +0 -194
- package/dist/cli-bundle/chunks/chunk-SQ7QZFQ6.js +0 -2
- package/dist/cli-bundle/chunks/register-operations-5XQETS6E.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-54EU2UVO.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-5FLBTZJQ.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-5GJ57YKN.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-CMDS3KYT.js +0 -14
- package/dist/cli-bundle/focused-chunks/chunk-DMKOMTTY.js +0 -6
- package/dist/cli-bundle/focused-chunks/chunk-F5B3HBEZ.js +0 -5
- package/dist/cli-bundle/focused-chunks/chunk-FI6DWU2M.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-FNOKJG6N.js +0 -16
- package/dist/cli-bundle/focused-chunks/chunk-FPDYXZBK.js +0 -4
- package/dist/cli-bundle/focused-chunks/chunk-GWI6YIKJ.js +0 -3
- package/dist/cli-bundle/focused-chunks/chunk-HCUC62AB.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-HGNKPSCB.js +0 -153
- package/dist/cli-bundle/focused-chunks/chunk-IAS7PMLG.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-SM2PJGP3.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-U646T7Z6.js +0 -18
- package/dist/cli-bundle/focused-chunks/chunk-YKPE4PPY.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-ZOLDTUU7.js +0 -2
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* value for the coordinator that performed the merge.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
!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]="
|
|
10
|
+
!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]="59863597-bf57-5d96-9cba-983443e5b209")}catch(e){}}();
|
|
11
11
|
import { execFile } from "node:child_process";
|
|
12
12
|
import { randomUUID } from "node:crypto";
|
|
13
13
|
import { readdir, readFile } from "node:fs/promises";
|
|
@@ -19,13 +19,33 @@ import { nowIso } from "../../core/shared/time.js";
|
|
|
19
19
|
const execFileAsync = promisify(execFile);
|
|
20
20
|
async function resolveReceiptDirectory(cwd) {
|
|
21
21
|
try {
|
|
22
|
-
const { stdout } = await execFileAsync("git", [
|
|
22
|
+
const { stdout } = await execFileAsync("git", [
|
|
23
|
+
"rev-parse",
|
|
24
|
+
"--path-format=absolute",
|
|
25
|
+
"--git-path",
|
|
26
|
+
"pm-merge-receipts",
|
|
27
|
+
], { cwd, encoding: "utf8", windowsHide: true, timeout: 10_000 });
|
|
23
28
|
return stdout.trim();
|
|
24
29
|
}
|
|
25
30
|
catch {
|
|
26
31
|
return null;
|
|
27
32
|
}
|
|
28
33
|
}
|
|
34
|
+
async function resolveTrackerRootFromItemPath(cwd, itemPath) {
|
|
35
|
+
let directory = path.dirname(path.resolve(cwd, itemPath));
|
|
36
|
+
for (let depth = 0; depth < 12; depth += 1) {
|
|
37
|
+
if (await pathExists(path.join(directory, "settings.json")))
|
|
38
|
+
return directory;
|
|
39
|
+
const parent = path.dirname(directory);
|
|
40
|
+
if (parent === directory)
|
|
41
|
+
break;
|
|
42
|
+
directory = parent;
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
function durableReceiptDirectory(pmRoot) {
|
|
47
|
+
return path.join(pmRoot, "merge-receipts");
|
|
48
|
+
}
|
|
29
49
|
function receiptFileName(id) {
|
|
30
50
|
return `${id}.json`;
|
|
31
51
|
}
|
|
@@ -39,13 +59,28 @@ export function summarizeMergeReceipt(receipt) {
|
|
|
39
59
|
fields_from_theirs: receipt.fields_from_theirs,
|
|
40
60
|
union_fields: receipt.union_fields,
|
|
41
61
|
preferred: receipt.preferred,
|
|
62
|
+
conflict_resolution: receipt.conflict_resolution,
|
|
42
63
|
decisions: receipt.decisions.map((decision) => ({
|
|
43
64
|
field: decision.field,
|
|
44
|
-
retained_hash:
|
|
45
|
-
|
|
65
|
+
retained_hash: isPrehashedValue(decision.retained) ??
|
|
66
|
+
sha256Hex(stableStringify(decision.retained)),
|
|
67
|
+
discarded_hash: isPrehashedValue(decision.discarded) ??
|
|
68
|
+
sha256Hex(stableStringify(decision.discarded)),
|
|
46
69
|
})),
|
|
47
70
|
};
|
|
48
71
|
}
|
|
72
|
+
function isPrehashedValue(value) {
|
|
73
|
+
if (typeof value !== "object" ||
|
|
74
|
+
value === null ||
|
|
75
|
+
Array.isArray(value) ||
|
|
76
|
+
!("pm_value_hash" in value)) {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
const hash = value.pm_value_hash;
|
|
80
|
+
return typeof hash === "string" && /^[a-f0-9]{64}$/u.test(hash)
|
|
81
|
+
? hash
|
|
82
|
+
: undefined;
|
|
83
|
+
}
|
|
49
84
|
/** Persist one item-driver outcome in the clone-local Git directory. */
|
|
50
85
|
export async function writeMergeReceipt(params) {
|
|
51
86
|
const directory = await resolveReceiptDirectory(params.cwd);
|
|
@@ -65,23 +100,40 @@ export async function writeMergeReceipt(params) {
|
|
|
65
100
|
item_path: itemPath.replaceAll("\\", "/"),
|
|
66
101
|
item_id: itemId,
|
|
67
102
|
preferred: params.preferred,
|
|
103
|
+
conflict_resolution: params.conflictResolution ?? "preferred_side",
|
|
68
104
|
fields_from_theirs: [...params.fieldsFromTheirs],
|
|
69
105
|
union_fields: [...params.unionFields],
|
|
70
106
|
decisions: structuredClone(params.decisions),
|
|
71
107
|
state: "pending",
|
|
72
108
|
created_at: nowIso(),
|
|
109
|
+
value_availability: "clone_local",
|
|
73
110
|
};
|
|
74
111
|
await ensureDir(directory);
|
|
75
112
|
await writeFileAtomic(path.join(directory, receiptFileName(receipt.id)), `${JSON.stringify(receipt, null, 2)}\n`);
|
|
113
|
+
const trackerRoot = await resolveTrackerRootFromItemPath(params.cwd, receipt.item_path);
|
|
114
|
+
if (trackerRoot !== null) {
|
|
115
|
+
const durableDirectory = durableReceiptDirectory(trackerRoot);
|
|
116
|
+
const summary = summarizeMergeReceipt(receipt);
|
|
117
|
+
const durableReceipt = {
|
|
118
|
+
...receipt,
|
|
119
|
+
decisions: summary.decisions.map((decision) => ({
|
|
120
|
+
field: decision.field,
|
|
121
|
+
base: null,
|
|
122
|
+
ours: null,
|
|
123
|
+
theirs: null,
|
|
124
|
+
retained: { pm_value_hash: decision.retained_hash },
|
|
125
|
+
discarded: { pm_value_hash: decision.discarded_hash },
|
|
126
|
+
})),
|
|
127
|
+
value_availability: "hash_only",
|
|
128
|
+
};
|
|
129
|
+
await ensureDir(durableDirectory);
|
|
130
|
+
await writeFileAtomic(path.join(durableDirectory, receiptFileName(receipt.id)), `${JSON.stringify(durableReceipt, null, 2)}\n`);
|
|
131
|
+
}
|
|
76
132
|
return receipt;
|
|
77
133
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const directory = await resolveReceiptDirectory(cwd);
|
|
81
|
-
if (directory === null || !(await pathExists(directory))) {
|
|
134
|
+
async function readReceiptsFromDirectory(directory, options) {
|
|
135
|
+
if (!(await pathExists(directory)))
|
|
82
136
|
return [];
|
|
83
|
-
}
|
|
84
|
-
const receipts = [];
|
|
85
137
|
let names;
|
|
86
138
|
try {
|
|
87
139
|
names = await readdir(directory);
|
|
@@ -89,23 +141,52 @@ export async function listMergeReceipts(cwd, options = {}) {
|
|
|
89
141
|
catch {
|
|
90
142
|
return [];
|
|
91
143
|
}
|
|
144
|
+
const receipts = [];
|
|
92
145
|
for (const name of names.sort((left, right) => left.localeCompare(right))) {
|
|
93
|
-
if (!name.endsWith(".json"))
|
|
146
|
+
if (!name.endsWith(".json"))
|
|
94
147
|
continue;
|
|
95
|
-
}
|
|
96
148
|
try {
|
|
97
149
|
const parsed = JSON.parse(await readFile(path.join(directory, name), "utf8"));
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
150
|
+
const normalizedReceipt = {
|
|
151
|
+
...parsed,
|
|
152
|
+
conflict_resolution: parsed.conflict_resolution ?? "preferred_side",
|
|
153
|
+
};
|
|
154
|
+
if (normalizedReceipt.version === 1 &&
|
|
155
|
+
(options.includeReconciled || normalizedReceipt.state === "pending") &&
|
|
156
|
+
(options.includeLossless !== false ||
|
|
157
|
+
normalizedReceipt.decisions.length > 0)) {
|
|
158
|
+
receipts.push(normalizedReceipt);
|
|
101
159
|
}
|
|
102
160
|
}
|
|
103
161
|
catch {
|
|
104
|
-
//
|
|
105
|
-
// omitted count once a future schema version adds richer diagnostics.
|
|
162
|
+
// Malformed evidence remains an integrity concern for a future schema.
|
|
106
163
|
}
|
|
107
164
|
}
|
|
108
|
-
return receipts
|
|
165
|
+
return receipts;
|
|
166
|
+
}
|
|
167
|
+
/** Read clone-local receipts with explicit reconciled/lossless classification controls. */
|
|
168
|
+
export async function listMergeReceipts(cwd, options = {}) {
|
|
169
|
+
const directory = await resolveReceiptDirectory(cwd);
|
|
170
|
+
const local = directory === null
|
|
171
|
+
? []
|
|
172
|
+
: await readReceiptsFromDirectory(directory, options);
|
|
173
|
+
const trackerRoot = options.pmRoot ?? path.join(cwd, ".agents", "pm");
|
|
174
|
+
const durable = await readReceiptsFromDirectory(durableReceiptDirectory(trackerRoot), options);
|
|
175
|
+
const receipts = new Map(durable.map((receipt) => [receipt.id, receipt]));
|
|
176
|
+
for (const receipt of local)
|
|
177
|
+
receipts.set(receipt.id, receipt);
|
|
178
|
+
return [...receipts.values()].sort((left, right) => left.created_at.localeCompare(right.created_at));
|
|
179
|
+
}
|
|
180
|
+
/** Split merge provenance into receipts with discarded values and receipts whose composition was lossless. */
|
|
181
|
+
export function partitionMergeReceipts(receipts) {
|
|
182
|
+
const pendingDecisions = [];
|
|
183
|
+
const lossless = [];
|
|
184
|
+
for (const receipt of receipts) {
|
|
185
|
+
(Array.isArray(receipt.decisions) && receipt.decisions.length > 0
|
|
186
|
+
? pendingDecisions
|
|
187
|
+
: lossless).push(receipt);
|
|
188
|
+
}
|
|
189
|
+
return { pendingDecisions, lossless };
|
|
109
190
|
}
|
|
110
191
|
/** Mark a receipt as represented by a committed merge history event. */
|
|
111
192
|
export async function markMergeReceiptReconciled(cwd, receipt) {
|
|
@@ -114,10 +195,21 @@ export async function markMergeReceiptReconciled(cwd, receipt) {
|
|
|
114
195
|
return;
|
|
115
196
|
}
|
|
116
197
|
await writeFileAtomic(path.join(directory, receiptFileName(receipt.id)), `${JSON.stringify({ ...receipt, state: "reconciled", reconciled_at: nowIso() }, null, 2)}\n`);
|
|
198
|
+
const trackerRoot = await resolveTrackerRootFromItemPath(cwd, receipt.item_path);
|
|
199
|
+
if (trackerRoot !== null) {
|
|
200
|
+
const durablePath = path.join(durableReceiptDirectory(trackerRoot), receiptFileName(receipt.id));
|
|
201
|
+
if (await pathExists(durablePath)) {
|
|
202
|
+
const durable = JSON.parse(await readFile(durablePath, "utf8"));
|
|
203
|
+
await writeFileAtomic(durablePath, `${JSON.stringify({ ...durable, state: "reconciled", reconciled_at: nowIso() }, null, 2)}\n`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
117
206
|
}
|
|
118
207
|
/** Report pending or historical clone-local merge decisions. */
|
|
119
208
|
export async function runMergeReceiptReport(options) {
|
|
120
|
-
const receipts = await listMergeReceipts(options.cwd ?? process.cwd(),
|
|
209
|
+
const receipts = await listMergeReceipts(options.cwd ?? process.cwd(), {
|
|
210
|
+
...options,
|
|
211
|
+
includeLossless: true,
|
|
212
|
+
});
|
|
121
213
|
return {
|
|
122
214
|
ok: true,
|
|
123
215
|
count: receipts.length,
|
|
@@ -126,4 +218,4 @@ export async function runMergeReceiptReport(options) {
|
|
|
126
218
|
};
|
|
127
219
|
}
|
|
128
220
|
//# sourceMappingURL=receipts.js.map
|
|
129
|
-
//# debugId=
|
|
221
|
+
//# debugId=59863597-bf57-5d96-9cba-983443e5b209
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
|
|
2
|
-
!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]="
|
|
2
|
+
!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]="c5620467-6c8c-5702-b742-57fba9e302c5")}catch(e){}}();
|
|
3
|
+
import { EXIT_CODE } from "../../core/shared/constants.js";
|
|
4
|
+
import { PmCliError } from "../../core/shared/errors.js";
|
|
3
5
|
import { runHistoryRepair, runHistoryRepairAll, } from "../history-repair.js";
|
|
4
6
|
import { runValidate } from "../governance/validate.js";
|
|
5
|
-
import { listMergeReceipts, markMergeReceiptReconciled, summarizeMergeReceipt, } from "./receipts.js";
|
|
7
|
+
import { listMergeReceipts, markMergeReceiptReconciled, partitionMergeReceipts, summarizeMergeReceipt, } from "./receipts.js";
|
|
6
8
|
/**
|
|
7
9
|
* Preview or apply post-merge history reconciliation and immediately validate
|
|
8
10
|
* the two merge-critical invariants. The default remains explicit and safe:
|
|
@@ -11,7 +13,22 @@ import { listMergeReceipts, markMergeReceiptReconciled, summarizeMergeReceipt, }
|
|
|
11
13
|
*/
|
|
12
14
|
export async function runMergeReconcile(options, global) {
|
|
13
15
|
const dryRun = options.dryRun === true;
|
|
14
|
-
const pendingReceipts = await listMergeReceipts(process.cwd()
|
|
16
|
+
const pendingReceipts = await listMergeReceipts(process.cwd(), {
|
|
17
|
+
includeLossless: true,
|
|
18
|
+
});
|
|
19
|
+
const { pendingDecisions: discardedReceipts } = partitionMergeReceipts(pendingReceipts);
|
|
20
|
+
if (!dryRun && options.force !== true && discardedReceipts.length > 0) {
|
|
21
|
+
throw new PmCliError(`Merge reconciliation would accept ${discardedReceipts.length} receipt(s) containing discarded scalar values. Review pm merge report and rerun with --force only after deciding which values to retain or re-apply.`, EXIT_CODE.CONFLICT, {
|
|
22
|
+
code: "merge_reconcile_discards_require_acceptance",
|
|
23
|
+
required: "Explicitly review every discarded field before accepting reconciliation.",
|
|
24
|
+
nextSteps: discardedReceipts.map((receipt) => `Review receipt ${receipt.id} for ${receipt.item_id}: ${receipt.decisions
|
|
25
|
+
.map((decision) => decision.field)
|
|
26
|
+
.join(", ")}.`),
|
|
27
|
+
recovery: {
|
|
28
|
+
suggested_retry: "pm merge reconcile --dry-run",
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
}
|
|
15
32
|
const receiptsByItem = pendingReceipts.reduce((groups, receipt) => {
|
|
16
33
|
(groups[receipt.item_id] ??= []).push(receipt);
|
|
17
34
|
return groups;
|
|
@@ -106,4 +123,4 @@ export async function runMergeReconcile(options, global) {
|
|
|
106
123
|
};
|
|
107
124
|
}
|
|
108
125
|
//# sourceMappingURL=reconcile.js.map
|
|
109
|
-
//# debugId=
|
|
126
|
+
//# debugId=c5620467-6c8c-5702-b742-57fba9e302c5
|
|
@@ -100,6 +100,8 @@ export interface ItemDocumentMergeResult {
|
|
|
100
100
|
conflict_decisions: ItemMergeConflictDecision[];
|
|
101
101
|
/** Which side unresolvable conflicts were resolved toward. */
|
|
102
102
|
preferred: MergePreferredSide;
|
|
103
|
+
/** Scalar-conflict selection contract used for this merge. */
|
|
104
|
+
conflict_resolution: "preferred_side" | "stable_value_order";
|
|
103
105
|
}
|
|
104
106
|
/**
|
|
105
107
|
* Field-aware three-way merge of one tracker item document. Commutative
|
|
@@ -107,8 +109,8 @@ export interface ItemDocumentMergeResult {
|
|
|
107
109
|
* concurrent appends never conflict; `updated_at` resolves to the latest
|
|
108
110
|
* timestamp so disjoint-field edits never collide on the shared freshness
|
|
109
111
|
* scalar; every other metadata field and the body use classic three-way
|
|
110
|
-
* resolution. Unresolvable both-sides-changed conflicts
|
|
111
|
-
*
|
|
112
|
+
* resolution. Unresolvable both-sides-changed conflicts use the configured
|
|
113
|
+
* scalar policy but remain reported in `conflict_fields`, and the merged output
|
|
112
114
|
* is always canonically serialized — count-prefixed TOON array headers are
|
|
113
115
|
* recomputed, so the hand-resolution corruption class (stale `notes[N]`
|
|
114
116
|
* headers) cannot be produced by this merge.
|
|
@@ -116,6 +118,8 @@ export interface ItemDocumentMergeResult {
|
|
|
116
118
|
export declare function mergeItemDocuments(baseRaw: string, oursRaw: string, theirsRaw: string, options?: ItemDocumentFormatOptions & {
|
|
117
119
|
/** Side that wins unresolvable conflicts (default "ours"). */
|
|
118
120
|
preferred?: MergePreferredSide;
|
|
121
|
+
/** Direction-independent scalar selection used by the Git driver. */
|
|
122
|
+
conflictResolution?: "preferred_side" | "stable_value_order";
|
|
119
123
|
}): ItemDocumentMergeResult;
|
|
120
124
|
/** Documents the JSON document merge result payload exchanged by command, SDK, and package integrations. */
|
|
121
125
|
export interface JsonDocumentMergeResult {
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* definition for multi-branch agent workflows.
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
!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]="
|
|
12
|
+
!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]="f6f04eec-0698-5e5b-a40e-de3a4be89f95")}catch(e){}}();
|
|
13
13
|
import { historyEntriesToRaw, reanchorHistoryEntries, } from "../../core/history/replay.js";
|
|
14
14
|
import { canonicalDocument, parseItemDocument, serializeItemDocument, } from "../../core/item/item-format.js";
|
|
15
15
|
import { EXIT_CODE } from "../../core/shared/constants.js";
|
|
@@ -339,6 +339,18 @@ function mergeScalarThreeWay(base, ours, theirs, preferred) {
|
|
|
339
339
|
conflict: true,
|
|
340
340
|
};
|
|
341
341
|
}
|
|
342
|
+
function mergeItemScalarThreeWay(base, ours, theirs, preferred, conflictResolution) {
|
|
343
|
+
const outcome = mergeScalarThreeWay(base, ours, theirs, preferred);
|
|
344
|
+
if (!outcome.conflict || conflictResolution === "preferred_side") {
|
|
345
|
+
return outcome;
|
|
346
|
+
}
|
|
347
|
+
const retainTheirs = stableStringify(theirs).localeCompare(stableStringify(ours)) < 0;
|
|
348
|
+
return {
|
|
349
|
+
value: retainTheirs ? theirs : ours,
|
|
350
|
+
from_theirs: retainTheirs,
|
|
351
|
+
conflict: true,
|
|
352
|
+
};
|
|
353
|
+
}
|
|
342
354
|
function toMetadataRecord(document) {
|
|
343
355
|
return { ...document.metadata };
|
|
344
356
|
}
|
|
@@ -350,7 +362,7 @@ function parseItemMergeSide(raw, label, options) {
|
|
|
350
362
|
throw new PmCliError(`Item merge input (${label}) is not a readable item document: ${String(error)}`, EXIT_CODE.GENERIC_FAILURE);
|
|
351
363
|
}
|
|
352
364
|
}
|
|
353
|
-
function mergeItemMetadataRecords(baseRecord, oursRecord, theirsRecord, preferred) {
|
|
365
|
+
function mergeItemMetadataRecords(baseRecord, oursRecord, theirsRecord, preferred, conflictResolution) {
|
|
354
366
|
const unionFieldSet = new Set(ITEM_UNION_COLLECTION_FIELDS);
|
|
355
367
|
const latestFieldSet = new Set(ITEM_LATEST_TIMESTAMP_FIELDS);
|
|
356
368
|
const fieldNames = [
|
|
@@ -382,7 +394,7 @@ function mergeItemMetadataRecords(baseRecord, oursRecord, theirsRecord, preferre
|
|
|
382
394
|
accumulator.merged[field] = latestTimestamp(oursValue, theirsValue);
|
|
383
395
|
continue;
|
|
384
396
|
}
|
|
385
|
-
const outcome =
|
|
397
|
+
const outcome = mergeItemScalarThreeWay(baseValue, oursValue, theirsValue, preferred, conflictResolution);
|
|
386
398
|
if (outcome.value !== undefined) {
|
|
387
399
|
accumulator.merged[field] = outcome.value;
|
|
388
400
|
}
|
|
@@ -394,7 +406,7 @@ function mergeItemMetadataRecords(baseRecord, oursRecord, theirsRecord, preferre
|
|
|
394
406
|
ours: oursValue,
|
|
395
407
|
theirs: theirsValue,
|
|
396
408
|
retained: outcome.value,
|
|
397
|
-
discarded:
|
|
409
|
+
discarded: outcome.from_theirs ? oursValue : theirsValue,
|
|
398
410
|
});
|
|
399
411
|
}
|
|
400
412
|
else if (outcome.from_theirs) {
|
|
@@ -409,14 +421,15 @@ function mergeItemMetadataRecords(baseRecord, oursRecord, theirsRecord, preferre
|
|
|
409
421
|
* concurrent appends never conflict; `updated_at` resolves to the latest
|
|
410
422
|
* timestamp so disjoint-field edits never collide on the shared freshness
|
|
411
423
|
* scalar; every other metadata field and the body use classic three-way
|
|
412
|
-
* resolution. Unresolvable both-sides-changed conflicts
|
|
413
|
-
*
|
|
424
|
+
* resolution. Unresolvable both-sides-changed conflicts use the configured
|
|
425
|
+
* scalar policy but remain reported in `conflict_fields`, and the merged output
|
|
414
426
|
* is always canonically serialized — count-prefixed TOON array headers are
|
|
415
427
|
* recomputed, so the hand-resolution corruption class (stale `notes[N]`
|
|
416
428
|
* headers) cannot be produced by this merge.
|
|
417
429
|
*/
|
|
418
430
|
export function mergeItemDocuments(baseRaw, oursRaw, theirsRaw, options = {}) {
|
|
419
431
|
const preferred = options.preferred ?? "ours";
|
|
432
|
+
const conflictResolution = options.conflictResolution ?? "preferred_side";
|
|
420
433
|
// An empty base means both branches created the file independently
|
|
421
434
|
// (add/add); three-way falls back to treating every differing field as an
|
|
422
435
|
// ours/theirs decision, which the scalar resolver already models.
|
|
@@ -429,8 +442,8 @@ export function mergeItemDocuments(baseRaw, oursRaw, theirsRaw, options = {}) {
|
|
|
429
442
|
: {};
|
|
430
443
|
const oursRecord = toMetadataRecord(ours);
|
|
431
444
|
const theirsRecord = toMetadataRecord(theirs);
|
|
432
|
-
const { merged, conflictFields, fieldsFromTheirs, unionFields, conflictDecisions, } = mergeItemMetadataRecords(baseRecord, oursRecord, theirsRecord, preferred);
|
|
433
|
-
const bodyOutcome =
|
|
445
|
+
const { merged, conflictFields, fieldsFromTheirs, unionFields, conflictDecisions, } = mergeItemMetadataRecords(baseRecord, oursRecord, theirsRecord, preferred, conflictResolution);
|
|
446
|
+
const bodyOutcome = mergeItemScalarThreeWay(hasBase ? base.body : "", ours.body, theirs.body, preferred, conflictResolution);
|
|
434
447
|
if (bodyOutcome.conflict) {
|
|
435
448
|
conflictFields.push("body");
|
|
436
449
|
conflictDecisions.push({
|
|
@@ -439,7 +452,7 @@ export function mergeItemDocuments(baseRaw, oursRaw, theirsRaw, options = {}) {
|
|
|
439
452
|
ours: ours.body,
|
|
440
453
|
theirs: theirs.body,
|
|
441
454
|
retained: bodyOutcome.value,
|
|
442
|
-
discarded:
|
|
455
|
+
discarded: bodyOutcome.from_theirs ? ours.body : theirs.body,
|
|
443
456
|
});
|
|
444
457
|
}
|
|
445
458
|
else if (bodyOutcome.from_theirs) {
|
|
@@ -456,6 +469,7 @@ export function mergeItemDocuments(baseRaw, oursRaw, theirsRaw, options = {}) {
|
|
|
456
469
|
union_fields: unionFields,
|
|
457
470
|
conflict_decisions: conflictDecisions,
|
|
458
471
|
preferred,
|
|
472
|
+
conflict_resolution: conflictResolution,
|
|
459
473
|
};
|
|
460
474
|
}
|
|
461
475
|
function isPlainObject(value) {
|
|
@@ -611,4 +625,4 @@ export function mergeJsonDocuments(baseRaw, oursRaw, theirsRaw, options = {}) {
|
|
|
611
625
|
};
|
|
612
626
|
}
|
|
613
627
|
//# sourceMappingURL=three-way.js.map
|
|
614
|
-
//# debugId=
|
|
628
|
+
//# debugId=f6f04eec-0698-5e5b-a40e-de3a4be89f95
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Declares machine-readable field-group omissions for bounded command results.
|
|
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]="630b48a7-aa38-529c-a272-14b7c748101c")}catch(e){}}();
|
|
8
8
|
import { EXIT_CODE } from "../core/shared/constants.js";
|
|
9
9
|
import { PmCliError } from "../core/shared/errors.js";
|
|
10
10
|
/** Universal selector for results carrying a {@link ReadRowContract}. */
|
|
@@ -283,11 +283,31 @@ function resolveContextReceipt(result) {
|
|
|
283
283
|
function resolveGetReceipt(result) {
|
|
284
284
|
if (!isRecord(result.item))
|
|
285
285
|
return undefined;
|
|
286
|
-
const
|
|
286
|
+
const item = result.item;
|
|
287
|
+
const itemGroups = [
|
|
288
|
+
"comments",
|
|
289
|
+
"notes",
|
|
290
|
+
"learnings",
|
|
291
|
+
"files",
|
|
292
|
+
"tests",
|
|
293
|
+
"docs",
|
|
294
|
+
"reminders",
|
|
295
|
+
"events",
|
|
296
|
+
];
|
|
297
|
+
const resultGroups = [
|
|
298
|
+
"body",
|
|
299
|
+
"children",
|
|
300
|
+
"claim_state",
|
|
301
|
+
"linked",
|
|
302
|
+
"schedule",
|
|
303
|
+
];
|
|
304
|
+
const groups = ["body", ...itemGroups, ...resultGroups.slice(1)].map((name) => ({
|
|
287
305
|
name,
|
|
288
306
|
restore_with: `--fields ${name}`,
|
|
289
307
|
}));
|
|
290
|
-
return createOutputOmissionReceipt(groups, new Set(groups.flatMap(({ name }) => (
|
|
308
|
+
return createOutputOmissionReceipt(groups, new Set(groups.flatMap(({ name }) => !Object.hasOwn(itemGroups.includes(name) ? item : result, name)
|
|
309
|
+
? []
|
|
310
|
+
: [name])));
|
|
291
311
|
}
|
|
292
312
|
function resolveListOrSearchReceipt(result) {
|
|
293
313
|
if (!isRecord(result.projection))
|
|
@@ -358,4 +378,4 @@ export function attachOutputOmissionReceipt(command, result) {
|
|
|
358
378
|
: { ...disclosedResult, omission_receipt: receipt };
|
|
359
379
|
}
|
|
360
380
|
//# sourceMappingURL=output-projection.js.map
|
|
361
|
-
//# debugId=
|
|
381
|
+
//# debugId=630b48a7-aa38-529c-a272-14b7c748101c
|
|
@@ -362,6 +362,8 @@ export interface ContextResult {
|
|
|
362
362
|
focus_fields?: string[];
|
|
363
363
|
/** Value that configures or reports warnings for this contract. */
|
|
364
364
|
warnings?: string[];
|
|
365
|
+
/** Actionable recovery contracts for context signal-store warnings. */
|
|
366
|
+
warning_details?: ContextSignalStoreReadResult["warning_details"];
|
|
365
367
|
/** Value that configures or reports ranking for this contract. */
|
|
366
368
|
ranking?: ContextRankingSummary;
|
|
367
369
|
/** Token-budget selection and projection accounting for ranked focus rows. */
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Implements the pm context 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]="161507f0-b1a7-59a6-9a60-d8f09806ed3f")}catch(e){}}();
|
|
8
8
|
import { SETTINGS_DEFAULTS, EXIT_CODE, PmCliError, compareTimestampStrings, nowIso, isTerminalStatus, normalizeStatusForRegistry, normalizeStatusInput, resolveRuntimeStatusRegistry, resolvePmRoot, readSettings, resolveAuthor, discoverExtensions, } from "../runtime-primitives.js";
|
|
9
9
|
import { collectDependencyBlockedIds, resolveItemBlockers, } from "../actionability.js";
|
|
10
10
|
import { CONTEXT_DEPTH_VALUES, CONTEXT_SECTION_VALUES, } from "../../types/index.js";
|
|
@@ -1412,7 +1412,7 @@ function buildContextSummaryExtras(needsAllItems, allItems, statusRegistry) {
|
|
|
1412
1412
|
canceledStatus).length,
|
|
1413
1413
|
};
|
|
1414
1414
|
}
|
|
1415
|
-
function attachOptionalContextSections(result, sections) {
|
|
1415
|
+
function attachOptionalContextSections(result, sections, warningDetails) {
|
|
1416
1416
|
if (sections.hierarchy)
|
|
1417
1417
|
result.hierarchy = sections.hierarchy;
|
|
1418
1418
|
if (sections.activity)
|
|
@@ -1433,6 +1433,9 @@ function attachOptionalContextSections(result, sections) {
|
|
|
1433
1433
|
result.staleness = sections.staleness;
|
|
1434
1434
|
if (sections.tests)
|
|
1435
1435
|
result.tests = sections.tests;
|
|
1436
|
+
if (warningDetails !== undefined && warningDetails.length > 0) {
|
|
1437
|
+
result.warning_details = warningDetails;
|
|
1438
|
+
}
|
|
1436
1439
|
}
|
|
1437
1440
|
function applyContextFocusProjection(result, focusFields) {
|
|
1438
1441
|
if (!focusFields) {
|
|
@@ -1642,7 +1645,7 @@ export async function runContext(options, global) {
|
|
|
1642
1645
|
};
|
|
1643
1646
|
result.workspace_memory = selectWorkspaceMemory(workspaceMemory, Math.min(800, Math.floor(runtime.tokenBudget * 0.2)));
|
|
1644
1647
|
Object.assign(result, await extensionHealthPromise);
|
|
1645
|
-
attachOptionalContextSections(result, sections);
|
|
1648
|
+
attachOptionalContextSections(result, sections, focusGroups.featureStore.warning_details);
|
|
1646
1649
|
applyContextTagProjection(result, options.noTags === true);
|
|
1647
1650
|
if (options.explainRanking === true) {
|
|
1648
1651
|
result.ranking = toContextRankingSummary(focusGroups.ranking, focusGroups.featureStore);
|
|
@@ -1656,4 +1659,4 @@ export async function runContext(options, global) {
|
|
|
1656
1659
|
return result;
|
|
1657
1660
|
}
|
|
1658
1661
|
//# sourceMappingURL=context.js.map
|
|
1659
|
-
//# debugId=
|
|
1662
|
+
//# debugId=161507f0-b1a7-59a6-9a60-d8f09806ed3f
|
package/dist/sdk/query/get.d.ts
CHANGED
|
@@ -24,6 +24,17 @@ type GetItemProjection = Partial<ItemMetadata> & {
|
|
|
24
24
|
notes_count?: number;
|
|
25
25
|
/** Number of linked tests omitted by a token-bounded projection. */
|
|
26
26
|
tests_count?: number;
|
|
27
|
+
/** Stable cardinalities for every collection mutation surface. */
|
|
28
|
+
collection_counts?: Readonly<{
|
|
29
|
+
comments: number;
|
|
30
|
+
notes: number;
|
|
31
|
+
learnings: number;
|
|
32
|
+
files: number;
|
|
33
|
+
tests: number;
|
|
34
|
+
docs: number;
|
|
35
|
+
reminders: number;
|
|
36
|
+
events: number;
|
|
37
|
+
}>;
|
|
27
38
|
};
|
|
28
39
|
/** Documents the get result payload exchanged by command, SDK, and package integrations. */
|
|
29
40
|
export interface GetResult {
|
package/dist/sdk/query/get.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Implements the SDK-owned item query shared by every surface.
|
|
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]="f68f4074-51ba-5065-8cca-fe16acd48927")}catch(e){}}();
|
|
8
8
|
import { pathExists, getActiveExtensionRegistrations, toItemRecord, resolveItemTypeRegistry, resolveRuntimeFieldRegistry, resolveRuntimeStatusRegistry, EXIT_CODE, ITEM_METADATA_KEY_ORDER, TYPE_TO_FOLDER, PmCliError, buildItemNotFoundError, listAllItemMetadataLight, locateItem, readLocatedItem, getHistoryPath, getSettingsPath, resolvePmRoot, readSettings, resolveAuthor, } from "../runtime-primitives.js";
|
|
9
9
|
import { readHistoryEntries } from "../history-read.js";
|
|
10
10
|
import { recordContextUsageTouches } from "../context-usage.js";
|
|
@@ -21,6 +21,23 @@ const AUTOMATIC_CHILD_ROLLUP_TYPES = new Set([
|
|
|
21
21
|
"plan",
|
|
22
22
|
]);
|
|
23
23
|
const BUILTIN_ITEM_TYPES = new Set(Object.keys(TYPE_TO_FOLDER).map((type) => type.toLowerCase()));
|
|
24
|
+
function itemCollectionCounts(item) {
|
|
25
|
+
const lengths = Object.fromEntries([
|
|
26
|
+
"comments",
|
|
27
|
+
"notes",
|
|
28
|
+
"learnings",
|
|
29
|
+
"files",
|
|
30
|
+
"tests",
|
|
31
|
+
"docs",
|
|
32
|
+
"reminders",
|
|
33
|
+
"events",
|
|
34
|
+
].map((key) => [
|
|
35
|
+
key,
|
|
36
|
+
item[key]
|
|
37
|
+
?.length ?? 0,
|
|
38
|
+
]));
|
|
39
|
+
return lengths;
|
|
40
|
+
}
|
|
24
41
|
/** Decide whether a normal read should pay for a workspace-wide child projection. */
|
|
25
42
|
function shouldAutoIncludeGetChildren(itemType) {
|
|
26
43
|
const normalizedType = itemType.trim().toLowerCase();
|
|
@@ -65,14 +82,29 @@ function parseGetDepth(raw) {
|
|
|
65
82
|
throw new PmCliError("Get --depth must be one of brief|standard|deep|full", EXIT_CODE.USAGE);
|
|
66
83
|
}
|
|
67
84
|
function projectItemForDepth(item, depth) {
|
|
85
|
+
const collectionCounts = itemCollectionCounts(item);
|
|
68
86
|
if (depth === "deep") {
|
|
69
|
-
return
|
|
87
|
+
return {
|
|
88
|
+
...item,
|
|
89
|
+
comments: item.comments ?? [],
|
|
90
|
+
notes: item.notes ?? [],
|
|
91
|
+
learnings: item.learnings ?? [],
|
|
92
|
+
files: item.files ?? [],
|
|
93
|
+
tests: item.tests ?? [],
|
|
94
|
+
docs: item.docs ?? [],
|
|
95
|
+
reminders: item.reminders ?? [],
|
|
96
|
+
events: item.events ?? [],
|
|
97
|
+
notes_count: collectionCounts.notes,
|
|
98
|
+
tests_count: collectionCounts.tests,
|
|
99
|
+
collection_counts: collectionCounts,
|
|
100
|
+
};
|
|
70
101
|
}
|
|
71
102
|
const { comments: _comments, notes: _notes, learnings: _learnings, files: _files, tests: _tests, docs: _docs, reminders: _reminders, events: _events, ...projected } = item;
|
|
72
103
|
return {
|
|
73
104
|
...projected,
|
|
74
105
|
notes_count: item.notes?.length ?? 0,
|
|
75
106
|
tests_count: item.tests?.length ?? 0,
|
|
107
|
+
collection_counts: collectionCounts,
|
|
76
108
|
};
|
|
77
109
|
}
|
|
78
110
|
function parseGetFields(raw) {
|
|
@@ -100,6 +132,7 @@ function validateGetFields(fields, runtimeMetadataKeys) {
|
|
|
100
132
|
...runtimeMetadataKeys,
|
|
101
133
|
"notes_count",
|
|
102
134
|
"tests_count",
|
|
135
|
+
"collection_counts",
|
|
103
136
|
]);
|
|
104
137
|
const allowedRootFields = new Set([
|
|
105
138
|
"body",
|
|
@@ -151,6 +184,7 @@ function projectItemForFields(item, fields) {
|
|
|
151
184
|
const omittedCounts = {
|
|
152
185
|
notes_count: item.notes?.length ?? 0,
|
|
153
186
|
tests_count: item.tests?.length ?? 0,
|
|
187
|
+
collection_counts: itemCollectionCounts(item),
|
|
154
188
|
};
|
|
155
189
|
const projected = {};
|
|
156
190
|
for (const field of fields) {
|
|
@@ -387,4 +421,4 @@ export const _testOnlyGetCommand = {
|
|
|
387
421
|
shouldAutoIncludeGetChildren,
|
|
388
422
|
};
|
|
389
423
|
//# sourceMappingURL=get.js.map
|
|
390
|
-
//# debugId=
|
|
424
|
+
//# debugId=f68f4074-51ba-5065-8cca-fe16acd48927
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { ItemMetadata } from "../../types/index.js";
|
|
2
|
+
/** Read scalar-only metadata using client workspace defaults and custom type folders. */
|
|
3
|
+
export declare function listClientItemMetadataLight(pmRootOverride: string | undefined, cwdOverride: string | undefined): Promise<ItemMetadata[]>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module sdk/query/light-metadata
|
|
3
|
+
*
|
|
4
|
+
* Resolves workspace settings for the host-bound lightweight metadata reader.
|
|
5
|
+
*/
|
|
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]="6ede8efb-54ec-5b13-a1bf-216b525acc12")}catch(e){}}();
|
|
8
|
+
import { resolveItemTypeRegistry } from "../../core/item/type-registry.js";
|
|
9
|
+
import { listAllItemMetadataLight } from "../../core/store/item-store.js";
|
|
10
|
+
import { resolvePmRoot } from "../../core/store/paths.js";
|
|
11
|
+
import { readSettings } from "../../core/store/settings.js";
|
|
12
|
+
/** Read scalar-only metadata using client workspace defaults and custom type folders. */
|
|
13
|
+
export async function listClientItemMetadataLight(pmRootOverride, cwdOverride) {
|
|
14
|
+
const pmRoot = resolvePmRoot(cwdOverride ?? process.cwd(), pmRootOverride);
|
|
15
|
+
const settings = await readSettings(pmRoot);
|
|
16
|
+
return listAllItemMetadataLight(pmRoot, settings.item_format, resolveItemTypeRegistry(settings, null).type_to_folder, undefined, settings.schema);
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=light-metadata.js.map
|
|
19
|
+
//# debugId=6ede8efb-54ec-5b13-a1bf-216b525acc12
|
|
@@ -4,7 +4,7 @@ export declare const PM_READ_OUTPUT_DIMENSIONS: readonly ["include", "amount", "
|
|
|
4
4
|
/** One member of the universal read-output dimension set. */
|
|
5
5
|
export type PmReadOutputDimension = (typeof PM_READ_OUTPUT_DIMENSIONS)[number];
|
|
6
6
|
/** Built-in command roots whose primary operation is a read. */
|
|
7
|
-
export declare const PM_READ_OUTPUT_SURFACES: readonly ["list", "context", "search", "get", "next", "health", "deps", "graph", "history", "activity", "validate", "events", "contracts", "comments", "notes", "files", "docs", "stats", "aggregate"];
|
|
7
|
+
export declare const PM_READ_OUTPUT_SURFACES: readonly ["list", "context", "search", "get", "next", "health", "deps", "graph", "history", "activity", "validate", "events", "contracts", "comments", "notes", "files", "docs", "stats", "aggregate", "package-manage"];
|
|
8
8
|
/** Built-in read command supported by the universal output contract. */
|
|
9
9
|
export type PmReadOutputSurface = (typeof PM_READ_OUTPUT_SURFACES)[number];
|
|
10
10
|
/** Canonical output controls accepted by every built-in read action. */
|