@unbrained/pm-cli 2026.8.10 → 2026.8.12
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 +153 -100
- package/dist/cli/commander-usage.js +113 -15
- package/dist/cli/error-guidance.d.ts +12 -0
- package/dist/cli/error-guidance.js +147 -29
- package/dist/cli/main.js +38 -19
- package/dist/cli/register-annotations.js +56 -3
- package/dist/cli/register-assurance.d.ts +8 -0
- package/dist/cli/register-assurance.js +52 -0
- package/dist/cli/register-files-lookup.js +14 -3
- package/dist/cli/register-list-query.js +10 -7
- package/dist/cli/register-mutation.js +30 -9
- package/dist/cli/register-operations.js +30 -15
- package/dist/cli-bundle/bundle-manifest.json +155 -155
- package/dist/cli-bundle/chunks/{chunk-TRWXF476.js → chunk-3PS7X6GS.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-7KL6KMWF.js +13 -0
- package/dist/cli-bundle/chunks/{chunk-EBO7OUUE.js → chunk-BM5YJ2UW.js} +69 -55
- package/dist/cli-bundle/chunks/chunk-D55A5AEN.js +33 -0
- package/dist/cli-bundle/chunks/chunk-KIKDWECH.js +196 -0
- package/dist/cli-bundle/chunks/{chunk-ETML5C6H.js → chunk-KOQMGCTA.js} +47 -47
- package/dist/cli-bundle/chunks/chunk-R76342NV.js +2 -0
- package/dist/cli-bundle/chunks/chunk-RBTK5EZV.js +5 -0
- package/dist/cli-bundle/chunks/chunk-VLUQOIDT.js +2 -0
- package/dist/cli-bundle/chunks/chunk-WLAHPSOX.js +3 -0
- package/dist/cli-bundle/chunks/register-list-query-XPCJRUUD.js +10 -0
- package/dist/cli-bundle/chunks/register-mutation-4RJCBKRS.js +20 -0
- package/dist/cli-bundle/chunks/register-operations-2OGISOVR.js +2 -0
- package/dist/cli-bundle/chunks/{register-setup-S3KT2LTH.js → register-setup-LLHAKP2V.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-2DALMVF7.js +5 -0
- package/dist/cli-bundle/focused-chunks/chunk-5OQIMELN.js +155 -0
- package/dist/cli-bundle/focused-chunks/chunk-5TAGTDRE.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-ECADZMVC.js +18 -0
- package/dist/cli-bundle/focused-chunks/chunk-EJGXRA6B.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-FFGSZCPK.js +16 -0
- package/dist/cli-bundle/focused-chunks/{chunk-IW43E4XL.js → chunk-GQW4BPUT.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-ISKOBJCM.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-75774JWP.js → chunk-JAFRIWVF.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-2COZ67XT.js → chunk-KHM2CS2C.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-M6RPIXKC.js → chunk-KPSXVBDV.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-34SX654S.js → chunk-KTLOKKCQ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-LGYK3NUF.js +8 -0
- package/dist/cli-bundle/focused-chunks/{chunk-2EXI2DKR.js → chunk-NBLUKITQ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-NYLOUPOB.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-Q4T463SD.js +31 -0
- package/dist/cli-bundle/focused-chunks/chunk-QVZVY53N.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-DZGAHZZV.js → chunk-RWPAWUOT.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-UTEWXDEQ.js +17 -0
- package/dist/cli-bundle/focused-chunks/{chunk-7UN6BHHO.js → chunk-YIAXMC3T.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-ZMGWAYH7.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 +41 -39
- 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/extensions/reserved-host-flags.js +3 -2
- package/dist/core/history/drift-scan.js +13 -8
- package/dist/core/history/history.d.ts +8 -0
- package/dist/core/history/history.js +57 -7
- package/dist/core/history/replay.d.ts +9 -1
- package/dist/core/history/replay.js +48 -13
- package/dist/core/output/output.d.ts +2 -0
- package/dist/core/output/output.js +46 -14
- package/dist/core/session/session-state.d.ts +47 -0
- package/dist/core/session/session-state.js +207 -6
- package/dist/core/shared/author.d.ts +7 -1
- package/dist/core/shared/author.js +66 -46
- package/dist/core/shared/command-types.d.ts +2 -0
- package/dist/core/shared/command-types.js +2 -2
- package/dist/core/shared/errors.d.ts +13 -0
- package/dist/core/shared/errors.js +2 -2
- package/dist/core/store/item-metadata-cache.d.ts +1 -1
- package/dist/core/store/item-metadata-cache.js +14 -7
- package/dist/sdk/agent/refusal-reachability.d.ts +40 -0
- package/dist/sdk/agent/refusal-reachability.js +72 -0
- package/dist/sdk/agent/subcommand-recovery.d.ts +40 -0
- package/dist/sdk/agent/subcommand-recovery.js +84 -0
- package/dist/sdk/cli-bootstrap.d.ts +10 -0
- package/dist/sdk/cli-bootstrap.js +11 -7
- package/dist/sdk/cli-contracts/completeness.js +14 -3
- package/dist/sdk/cli-contracts/enum-contracts.d.ts +1 -1
- package/dist/sdk/cli-contracts/enum-contracts.js +3 -2
- package/dist/sdk/cli-contracts/flag-contracts.d.ts +2 -0
- package/dist/sdk/cli-contracts/flag-contracts.js +20 -2
- package/dist/sdk/cli-contracts/registration-helpers.d.ts +20 -3
- package/dist/sdk/cli-contracts/registration-helpers.js +18 -12
- package/dist/sdk/cli-contracts/runtime-contracts.js +4 -3
- package/dist/sdk/cli-contracts/schemas/assurance-definition.d.ts +515 -0
- package/dist/sdk/cli-contracts/schemas/assurance-definition.js +252 -0
- package/dist/sdk/cli-contracts/tool-option-contracts.js +3 -2
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +99 -2
- package/dist/sdk/cli-contracts/tool-schema.d.ts +3 -3
- package/dist/sdk/cli-contracts/tool-schema.js +38 -5
- package/dist/sdk/cli-contracts.d.ts +1 -1
- package/dist/sdk/cli-contracts.js +3 -3
- package/dist/sdk/cli-program.js +3 -2
- package/dist/sdk/completion.js +23 -8
- package/dist/sdk/config.js +9 -3
- package/dist/sdk/context/semantic-session-attribution.d.ts +32 -0
- package/dist/sdk/context/semantic-session-attribution.js +83 -0
- package/dist/sdk/context-intent-contracts.js +45 -4
- package/dist/sdk/core-governance.d.ts +3 -1
- package/dist/sdk/core-governance.js +5 -3
- package/dist/sdk/core.d.ts +2 -1
- package/dist/sdk/core.js +3 -2
- package/dist/sdk/error-code-catalog.d.ts +13 -0
- package/dist/sdk/error-code-catalog.js +35 -2
- package/dist/sdk/extension.js +18 -17
- package/dist/sdk/files.d.ts +11 -0
- package/dist/sdk/files.js +82 -24
- package/dist/sdk/generated/generated-error-code-catalog-part-1.d.ts +8 -0
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +1585 -0
- package/dist/sdk/generated/generated-error-code-catalog-part-2.d.ts +8 -0
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +1608 -0
- package/dist/sdk/generated-error-code-catalog.js +6 -3121
- package/dist/sdk/governance/assurance-action-contracts.d.ts +7 -0
- package/dist/sdk/governance/assurance-action-contracts.js +5 -0
- package/dist/sdk/governance/assurance-action.d.ts +70 -0
- package/dist/sdk/governance/assurance-action.js +200 -0
- package/dist/sdk/governance/assurance-limits.d.ts +7 -0
- package/dist/sdk/governance/assurance-limits.js +11 -0
- package/dist/sdk/governance/assurance-mutation-error.d.ts +7 -0
- package/dist/sdk/governance/assurance-mutation-error.js +35 -0
- package/dist/sdk/governance/assurance-runtime.d.ts +20 -0
- package/dist/sdk/governance/assurance-runtime.js +134 -0
- package/dist/sdk/governance/assurance.d.ts +438 -0
- package/dist/sdk/governance/assurance.js +804 -0
- package/dist/sdk/governance/health.d.ts +3 -1
- package/dist/sdk/governance/health.js +21 -4
- package/dist/sdk/governance/validate-item-reader.js +3 -3
- package/dist/sdk/governance/validate.d.ts +2 -0
- package/dist/sdk/governance/validate.js +13 -3
- package/dist/sdk/graph/durable-cache.d.ts +1 -1
- package/dist/sdk/graph/durable-cache.js +98 -29
- package/dist/sdk/graph/governance.d.ts +14 -0
- package/dist/sdk/graph/governance.js +34 -9
- package/dist/sdk/graph/run.js +8 -3
- package/dist/sdk/index.d.ts +7 -2
- package/dist/sdk/index.js +9 -4
- package/dist/sdk/lifecycle/claim.js +26 -4
- package/dist/sdk/lifecycle/focus.js +13 -3
- package/dist/sdk/lifecycle/plan.js +8 -3
- package/dist/sdk/merge/driver.d.ts +2 -2
- package/dist/sdk/merge/driver.js +3 -3
- package/dist/sdk/merge/receipts.d.ts +6 -4
- package/dist/sdk/merge/receipts.js +7 -5
- package/dist/sdk/merge/three-way.d.ts +2 -2
- package/dist/sdk/merge/three-way.js +3 -3
- package/dist/sdk/output-projection.d.ts +9 -1
- package/dist/sdk/output-projection.js +45 -9
- package/dist/sdk/provenance.d.ts +38 -0
- package/dist/sdk/provenance.js +64 -2
- package/dist/sdk/query/activity.d.ts +49 -2
- package/dist/sdk/query/activity.js +183 -37
- package/dist/sdk/query/context.js +19 -8
- package/dist/sdk/query/get.js +19 -2
- package/dist/sdk/read-output-contracts.d.ts +5 -1
- package/dist/sdk/read-output-contracts.js +17 -2
- package/dist/sdk/read-output-session.d.ts +2 -0
- package/dist/sdk/read-output-session.js +12 -5
- package/dist/sdk/runtime-extended-actions.js +22 -5
- package/dist/sdk/runtime-primitives.d.ts +5 -3
- package/dist/sdk/runtime-primitives.js +7 -5
- package/dist/sdk/runtime-stats-options.js +3 -2
- package/dist/sdk/runtime.d.ts +4 -0
- package/dist/sdk/runtime.js +34 -34
- package/dist/sdk/stats.d.ts +36 -3
- package/dist/sdk/stats.js +55 -15
- package/dist/sdk/telemetry.js +7 -4
- package/dist/sdk/test/execution.d.ts +4 -0
- package/dist/sdk/test/execution.js +86 -21
- package/dist/sdk/traceability/runtime-files-lookup.d.ts +8 -0
- package/dist/sdk/traceability/runtime-files-lookup.js +33 -0
- package/dist/sdk/traceability/source-traceability.d.ts +102 -0
- package/dist/sdk/traceability/source-traceability.js +293 -0
- package/dist/types.d.ts +10 -2
- package/dist/types.js +2 -2
- package/docs/ASSURANCE.md +137 -0
- package/docs/COMMANDS.md +29 -8
- package/docs/CONFIGURATION.md +7 -0
- package/docs/DEPENDENCY_KIND_CONTRACT.md +10 -8
- package/docs/MERGE_SAFETY.md +3 -1
- package/docs/OUTPUT_PROJECTION_CONTRACTS.md +26 -13
- package/docs/README.md +3 -0
- package/docs/READ_OUTPUT_CONTRACTS.md +17 -2
- package/docs/RELEASING.md +9 -5
- package/docs/SDK.md +12 -1
- package/docs/SDK_AGENT_SESSION_CONTEXT.md +52 -5
- package/docs/SDK_CONTEXT_EVIDENCE_CONTRACTS.md +53 -0
- package/docs/SDK_CONTEXT_INTEGRITY.md +28 -1
- package/docs/SDK_EVIDENCE_TRACEABILITY.md +39 -1
- package/docs/SDK_RUNTIME_BOUNDARIES.md +36 -1
- package/docs/TESTING.md +12 -9
- package/docs/TRUSTWORTHY_CONTEXT_EVIDENCE.md +106 -0
- package/docs/generated/AGENT_COMMAND_SURFACE.md +1 -0
- package/docs/performance/sdk-entrypoint-import-costs.md +6 -2
- package/marketplace.json +2 -2
- package/package.json +7 -7
- 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/extensions/templates/index.ts +9 -3
- 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 +1030 -67
- package/dist/cli-bundle/chunks/chunk-2QYH4QMI.js +0 -30
- package/dist/cli-bundle/chunks/chunk-JUDU4RO4.js +0 -194
- package/dist/cli-bundle/chunks/chunk-JZSNADRR.js +0 -5
- package/dist/cli-bundle/chunks/chunk-MENWVGJW.js +0 -2
- package/dist/cli-bundle/chunks/chunk-S4EITGLA.js +0 -3
- package/dist/cli-bundle/chunks/chunk-TIGKWVLA.js +0 -13
- package/dist/cli-bundle/chunks/chunk-TSLDTJLQ.js +0 -2
- package/dist/cli-bundle/chunks/register-list-query-OJ6ZXKV4.js +0 -10
- package/dist/cli-bundle/chunks/register-mutation-DKI7QC7O.js +0 -20
- package/dist/cli-bundle/chunks/register-operations-P5OGMT6I.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-36FTZ2NT.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-3CQECMKR.js +0 -16
- package/dist/cli-bundle/focused-chunks/chunk-CHIBMEZR.js +0 -8
- package/dist/cli-bundle/focused-chunks/chunk-FF4MNAYB.js +0 -153
- package/dist/cli-bundle/focused-chunks/chunk-GHTN2ILR.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-I4YM2I7S.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-IMDTEN7K.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-JMVA4HKR.js +0 -5
- package/dist/cli-bundle/focused-chunks/chunk-KR5RVXLQ.js +0 -31
- package/dist/cli-bundle/focused-chunks/chunk-KSNJG4KI.js +0 -16
- package/dist/cli-bundle/focused-chunks/chunk-MXYSIQ56.js +0 -18
- package/dist/cli-bundle/focused-chunks/chunk-RIIN5V4N.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-RKWSCYYN.js +0 -2
package/dist/sdk/stats.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Implements the pm stats 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]="d28c7ac7-9801-5b0c-84c9-51deede398be")}catch(e){}}();
|
|
8
8
|
import fs from "node:fs/promises";
|
|
9
9
|
import path from "node:path";
|
|
10
10
|
import { getActiveExtensionRegistrations, runActiveOnReadHooks, } from "../core/extensions/index.js";
|
|
@@ -36,6 +36,53 @@ function zeroByStatus(statuses) {
|
|
|
36
36
|
return acc;
|
|
37
37
|
}, {});
|
|
38
38
|
}
|
|
39
|
+
function projectStatsDistributions(items, itemTypes, statuses, classifier, includeEmpty) {
|
|
40
|
+
const grouped = groupItemsByDimension(items, "type", classifier);
|
|
41
|
+
const presentTypes = new Set(grouped.rows.map((row) => row.key));
|
|
42
|
+
const missingTypes = itemTypes.filter((type) => !presentTypes.has(type));
|
|
43
|
+
const groupedRows = includeEmpty
|
|
44
|
+
? [
|
|
45
|
+
...grouped.rows,
|
|
46
|
+
...missingTypes.map((type) => ({
|
|
47
|
+
label: type,
|
|
48
|
+
key: type,
|
|
49
|
+
total: 0,
|
|
50
|
+
buckets: {
|
|
51
|
+
open: 0,
|
|
52
|
+
in_progress: 0,
|
|
53
|
+
blocked: 0,
|
|
54
|
+
draft: 0,
|
|
55
|
+
closed: 0,
|
|
56
|
+
canceled: 0,
|
|
57
|
+
other: 0,
|
|
58
|
+
},
|
|
59
|
+
})),
|
|
60
|
+
]
|
|
61
|
+
: grouped.rows;
|
|
62
|
+
const byType = groupedRows.map((row) => ({
|
|
63
|
+
type: row.key ?? row.label,
|
|
64
|
+
total: row.total,
|
|
65
|
+
open: row.buckets.open,
|
|
66
|
+
in_progress: row.buckets.in_progress,
|
|
67
|
+
blocked: row.buckets.blocked,
|
|
68
|
+
draft: row.buckets.draft,
|
|
69
|
+
closed: row.buckets.closed,
|
|
70
|
+
canceled: row.buckets.canceled,
|
|
71
|
+
other: row.buckets.other,
|
|
72
|
+
}));
|
|
73
|
+
const counts = zeroByStatus([...statuses]);
|
|
74
|
+
for (const item of items)
|
|
75
|
+
counts[item.status] += 1;
|
|
76
|
+
const byStatus = Object.fromEntries(Object.entries(counts).filter(([, count]) => includeEmpty || count > 0));
|
|
77
|
+
return {
|
|
78
|
+
byType,
|
|
79
|
+
byStatus,
|
|
80
|
+
omitted: includeEmpty
|
|
81
|
+
? 0
|
|
82
|
+
: missingTypes.length +
|
|
83
|
+
Object.values(counts).filter((count) => count === 0).length,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
39
86
|
function countNonEmptyLines(raw) {
|
|
40
87
|
if (raw.trim().length === 0) {
|
|
41
88
|
return 0;
|
|
@@ -75,6 +122,7 @@ export const _testOnly = {
|
|
|
75
122
|
zeroByStatus,
|
|
76
123
|
countNonEmptyLines,
|
|
77
124
|
readHistoryStreamContents,
|
|
125
|
+
projectStatsDistributions,
|
|
78
126
|
};
|
|
79
127
|
async function recordStatsObservations(global, options) {
|
|
80
128
|
const recorded = [];
|
|
@@ -129,12 +177,13 @@ async function requestedHistoryAnalytics(pmRoot, items, settings, terminalStatus
|
|
|
129
177
|
: undefined,
|
|
130
178
|
};
|
|
131
179
|
}
|
|
132
|
-
function assembleStatsResult(totals, byType, byStatus, optional) {
|
|
180
|
+
function assembleStatsResult(totals, byType, byStatus, omittedZeroBuckets, optional) {
|
|
133
181
|
const hasBreakdowns = Object.keys(optional.breakdowns).length > 0;
|
|
134
182
|
return {
|
|
135
183
|
totals,
|
|
136
184
|
by_type: byType,
|
|
137
185
|
by_status: byStatus,
|
|
186
|
+
omitted_zero_buckets: omittedZeroBuckets,
|
|
138
187
|
...(optional.metadataCoverage
|
|
139
188
|
? { metadata_coverage: optional.metadataCoverage }
|
|
140
189
|
: {}),
|
|
@@ -180,16 +229,8 @@ export async function runStats(global, options = {}) {
|
|
|
180
229
|
itemIds: items.map((item) => item.id),
|
|
181
230
|
commandLabel: "stats",
|
|
182
231
|
});
|
|
183
|
-
const
|
|
184
|
-
const
|
|
185
|
-
// zeroByType/zeroByStatus pre-seed a bucket for every registry type/status, and
|
|
186
|
-
// the light item-metadata reader drops any item whose type/status falls outside
|
|
187
|
-
// the active registry (parse rejects them) — so every item's bucket is already
|
|
188
|
-
// present here and no on-the-fly initialization is reachable.
|
|
189
|
-
for (const item of items) {
|
|
190
|
-
byType[item.type] += 1;
|
|
191
|
-
byStatus[item.status] += 1;
|
|
192
|
-
}
|
|
232
|
+
const classifier = lifecycleClassifierFromStatusRegistry(statusRegistry);
|
|
233
|
+
const distributions = projectStatsDistributions(items, typeRegistry.types, statusRegistry.definitions.map((definition) => definition.id), classifier, options.includeEmpty === true);
|
|
193
234
|
const streams = await readHistoryStreamContents(pmRoot);
|
|
194
235
|
let historyEntries = 0;
|
|
195
236
|
for (const stream of streams) {
|
|
@@ -198,7 +239,6 @@ export async function runStats(global, options = {}) {
|
|
|
198
239
|
const storage = options.storage
|
|
199
240
|
? computeHistoryStorageStats(streams)
|
|
200
241
|
: undefined;
|
|
201
|
-
const classifier = lifecycleClassifierFromStatusRegistry(statusRegistry);
|
|
202
242
|
const metadataCoverage = options.metadataCoverage
|
|
203
243
|
? computeMetadataCoverage(items, classifier)
|
|
204
244
|
: undefined;
|
|
@@ -219,7 +259,7 @@ export async function runStats(global, options = {}) {
|
|
|
219
259
|
items: items.length,
|
|
220
260
|
history_streams: streams.length,
|
|
221
261
|
history_entries: historyEntries,
|
|
222
|
-
}, byType, byStatus, {
|
|
262
|
+
}, distributions.byType, distributions.byStatus, distributions.omitted, {
|
|
223
263
|
metadataCoverage,
|
|
224
264
|
breakdowns,
|
|
225
265
|
storage,
|
|
@@ -231,4 +271,4 @@ export async function runStats(global, options = {}) {
|
|
|
231
271
|
});
|
|
232
272
|
}
|
|
233
273
|
//# sourceMappingURL=stats.js.map
|
|
234
|
-
//# debugId=
|
|
274
|
+
//# debugId=d28c7ac7-9801-5b0c-84c9-51deede398be
|
package/dist/sdk/telemetry.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Implements the pm telemetry 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]="ad3110ca-e85b-5a7e-b0a1-591796c298eb")}catch(e){}}();
|
|
8
8
|
import fs from "node:fs/promises";
|
|
9
9
|
import path from "node:path";
|
|
10
10
|
import { pathExists, readFileIfExists } from "../core/fs/fs-utils.js";
|
|
@@ -14,6 +14,7 @@ import { nowIso } from "../core/shared/time.js";
|
|
|
14
14
|
import { resolveGlobalPmRoot } from "../core/store/paths.js";
|
|
15
15
|
import { readSettings, writeSettings } from "../core/store/settings.js";
|
|
16
16
|
import { flushTelemetryQueueNow } from "../core/telemetry/runtime.js";
|
|
17
|
+
import { createUnknownSubcommandError } from "./agent/subcommand-recovery.js";
|
|
17
18
|
const TELEMETRY_QUEUE_RELATIVE_PATH = path.join("runtime", "telemetry", "events.jsonl");
|
|
18
19
|
const TELEMETRY_STATE_RELATIVE_PATH = path.join("runtime", "telemetry", "state.json");
|
|
19
20
|
const TELEMETRY_RUNTIME_RELATIVE_PATH = path.join("runtime", "telemetry");
|
|
@@ -161,8 +162,10 @@ const normalizeTelemetrySubcommand = (value) => {
|
|
|
161
162
|
}
|
|
162
163
|
// `value` is always a defined string here: an undefined subcommand normalizes
|
|
163
164
|
// to "status" above (a valid value) and never reaches this throw.
|
|
164
|
-
throw
|
|
165
|
-
|
|
165
|
+
throw createUnknownSubcommandError({
|
|
166
|
+
command_path: "telemetry",
|
|
167
|
+
token: value?.trim() || "<empty>",
|
|
168
|
+
allowed: TELEMETRY_SUBCOMMANDS,
|
|
166
169
|
examples: [
|
|
167
170
|
"pm telemetry status",
|
|
168
171
|
"pm telemetry flush",
|
|
@@ -400,4 +403,4 @@ export async function runTelemetry(options, _global) {
|
|
|
400
403
|
});
|
|
401
404
|
}
|
|
402
405
|
//# sourceMappingURL=telemetry.js.map
|
|
403
|
-
//# debugId=
|
|
406
|
+
//# debugId=ad3110ca-e85b-5a7e-b0a1-591796c298eb
|
|
@@ -35,6 +35,8 @@ export interface TestCommandOptions {
|
|
|
35
35
|
addJson?: string[];
|
|
36
36
|
/** Value that configures or reports remove for this contract. */
|
|
37
37
|
remove?: string[];
|
|
38
|
+
/** Remove linked tests by their stable 1-based list position. */
|
|
39
|
+
removeIndex?: Array<string | number>;
|
|
38
40
|
/** Value that configures or reports list for this contract. */
|
|
39
41
|
list?: boolean;
|
|
40
42
|
/** Value that configures or reports run for this contract. */
|
|
@@ -146,6 +148,8 @@ export interface TestResult {
|
|
|
146
148
|
changed: boolean;
|
|
147
149
|
/** Value that configures or reports count for this contract. */
|
|
148
150
|
count: number;
|
|
151
|
+
/** Number of linked-test entries removed by this mutation. */
|
|
152
|
+
removed?: number;
|
|
149
153
|
/** Measurements supplied for the current producing run. */
|
|
150
154
|
measurements?: TestRunMeasurement[];
|
|
151
155
|
/** Existing and current measurements below the selected threshold. */
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Implements the pm test 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]="b40f54be-2d3e-5b98-9d49-cb8608a782f5")}catch(e){}}();
|
|
8
8
|
import { spawn } from "node:child_process";
|
|
9
9
|
import { cp, mkdir, mkdtemp, open, readdir, rm } from "node:fs/promises";
|
|
10
10
|
import { tmpdir } from "node:os";
|
|
@@ -507,7 +507,6 @@ function parseAddJsonEntries(raw) {
|
|
|
507
507
|
return parsed;
|
|
508
508
|
});
|
|
509
509
|
}
|
|
510
|
-
/* c8 ignore stop */
|
|
511
510
|
function parseRemoveEntries(raw) {
|
|
512
511
|
if (!raw)
|
|
513
512
|
return [];
|
|
@@ -516,19 +515,48 @@ function parseRemoveEntries(raw) {
|
|
|
516
515
|
if (!trimmed) {
|
|
517
516
|
throw new PmCliError("--remove requires command or path value", EXIT_CODE.USAGE);
|
|
518
517
|
}
|
|
519
|
-
|
|
520
|
-
|
|
518
|
+
const identityPrefix = /^(command|path)\s*=/i.exec(trimmed);
|
|
519
|
+
if (identityPrefix) {
|
|
520
|
+
const value = trimmed.slice(identityPrefix[0].length).trim();
|
|
521
|
+
if (!value) {
|
|
522
|
+
throw new PmCliError("--remove requires a non-empty command=<value> or path=<value>", EXIT_CODE.USAGE);
|
|
523
|
+
}
|
|
524
|
+
return {
|
|
525
|
+
kind: identityPrefix[1].toLowerCase(),
|
|
526
|
+
value,
|
|
527
|
+
};
|
|
528
|
+
}
|
|
529
|
+
if (/^[A-Za-z_][\w-]*=\S+$/u.test(trimmed)) {
|
|
530
|
+
throw new PmCliError("--remove structured selectors require command=<value> or path=<value>", EXIT_CODE.USAGE);
|
|
531
|
+
}
|
|
532
|
+
if (/^(?:[-*+]\s+)?(?:path|command)\s*:/i.test(trimmed) ||
|
|
521
533
|
trimmed.startsWith("```")) {
|
|
522
534
|
const kv = parseCsvKv(trimmed, "--remove");
|
|
535
|
+
const kind = kv.path !== undefined ? "path" : "command";
|
|
523
536
|
const value = kv.path ?? kv.command;
|
|
524
537
|
if (!value?.trim()) {
|
|
525
538
|
throw new PmCliError("--remove requires command=<value> and/or path=<value>", EXIT_CODE.USAGE);
|
|
526
539
|
}
|
|
527
|
-
return value.trim();
|
|
540
|
+
return { kind, value: value.trim() };
|
|
528
541
|
}
|
|
529
|
-
return trimmed;
|
|
542
|
+
return { kind: "either", value: trimmed };
|
|
530
543
|
});
|
|
531
544
|
}
|
|
545
|
+
function parseRemoveIndexes(raw) {
|
|
546
|
+
if (!raw)
|
|
547
|
+
return [];
|
|
548
|
+
return [
|
|
549
|
+
...new Set(raw.map((value) => {
|
|
550
|
+
const parsed = typeof value === "number" ? value : Number.parseInt(value, 10);
|
|
551
|
+
if (!Number.isInteger(parsed) ||
|
|
552
|
+
parsed < 1 ||
|
|
553
|
+
String(parsed) !== String(value).trim()) {
|
|
554
|
+
throw new PmCliError("--remove-index must be a positive integer", EXIT_CODE.USAGE);
|
|
555
|
+
}
|
|
556
|
+
return parsed;
|
|
557
|
+
})),
|
|
558
|
+
];
|
|
559
|
+
}
|
|
532
560
|
function closeLinkedTestStdin(child) {
|
|
533
561
|
// Force EOF on child stdin so non-interactive runs do not wait on input.
|
|
534
562
|
try {
|
|
@@ -1383,7 +1411,10 @@ function resolveLinkedTestPreflightResult(params) {
|
|
|
1383
1411
|
}
|
|
1384
1412
|
function buildLinkedTestExecutionEnv(params) {
|
|
1385
1413
|
const effectiveDirectives = resolveEffectiveLinkedTestDirectives(params.runtimeDirectives, params.linkedTest);
|
|
1386
|
-
const executionEnv = {
|
|
1414
|
+
const executionEnv = {
|
|
1415
|
+
...process.env,
|
|
1416
|
+
SENTRY_ENVIRONMENT: "test",
|
|
1417
|
+
};
|
|
1387
1418
|
applyEnvDirectiveStage(executionEnv, params.runtimeDirectives);
|
|
1388
1419
|
applyEnvDirectiveStage(executionEnv, {
|
|
1389
1420
|
env_set: params.linkedTest.env_set ?? {},
|
|
@@ -1538,6 +1569,7 @@ async function readLinkedTestItem(params) {
|
|
|
1538
1569
|
tests: loaded.document.metadata.tests ?? [],
|
|
1539
1570
|
testRuns: loaded.document.metadata.test_runs ?? [],
|
|
1540
1571
|
changed: false,
|
|
1572
|
+
removed: 0,
|
|
1541
1573
|
};
|
|
1542
1574
|
}
|
|
1543
1575
|
function linkedTestsHaveSameIdentity(left, right) {
|
|
@@ -1555,15 +1587,26 @@ function appendMissingLinkedTests(current, additions) {
|
|
|
1555
1587
|
}
|
|
1556
1588
|
return next;
|
|
1557
1589
|
}
|
|
1558
|
-
function removeLinkedTestsBySelector(current, removals) {
|
|
1559
|
-
if (removals.length === 0) {
|
|
1560
|
-
return current;
|
|
1590
|
+
function removeLinkedTestsBySelector(current, removals, removeIndexes) {
|
|
1591
|
+
if (removals.length === 0 && removeIndexes.length === 0) {
|
|
1592
|
+
return { tests: current, removed: 0 };
|
|
1561
1593
|
}
|
|
1562
|
-
|
|
1563
|
-
|
|
1594
|
+
const indexSet = new Set(removeIndexes);
|
|
1595
|
+
const tests = current.filter((entry, index) => {
|
|
1596
|
+
if (indexSet.has(index + 1))
|
|
1597
|
+
return false;
|
|
1598
|
+
return !removals.some((selector) => {
|
|
1599
|
+
if (selector.kind === "command")
|
|
1600
|
+
return entry.command === selector.value;
|
|
1601
|
+
if (selector.kind === "path")
|
|
1602
|
+
return entry.path === selector.value;
|
|
1603
|
+
return entry.command === selector.value || entry.path === selector.value;
|
|
1604
|
+
});
|
|
1605
|
+
});
|
|
1606
|
+
return { tests, removed: current.length - tests.length };
|
|
1564
1607
|
}
|
|
1565
|
-
function applyLinkedTestMutations(previous, adds, removes) {
|
|
1566
|
-
return removeLinkedTestsBySelector(appendMissingLinkedTests(previous, adds), removes);
|
|
1608
|
+
function applyLinkedTestMutations(previous, adds, removes, removeIndexes) {
|
|
1609
|
+
return removeLinkedTestsBySelector(appendMissingLinkedTests(previous, adds), removes, removeIndexes);
|
|
1567
1610
|
}
|
|
1568
1611
|
function hasTestRuntimeDirectiveFlags(options) {
|
|
1569
1612
|
return ((options.envSet?.length ?? 0) > 0 ||
|
|
@@ -1590,25 +1633,43 @@ function assertTestRunFlagUsage(options) {
|
|
|
1590
1633
|
}
|
|
1591
1634
|
}
|
|
1592
1635
|
async function resolveLinkedTestItem(params) {
|
|
1593
|
-
const { id, options, pmRoot, settings, typeToFolder, adds, removes } = params;
|
|
1594
|
-
if (adds.length === 0 && removes.length === 0) {
|
|
1636
|
+
const { id, options, pmRoot, settings, typeToFolder, adds, removes, removeIndexes, } = params;
|
|
1637
|
+
if (adds.length === 0 && removes.length === 0 && removeIndexes.length === 0) {
|
|
1595
1638
|
return readLinkedTestItem({ id, pmRoot, settings, typeToFolder });
|
|
1596
1639
|
}
|
|
1640
|
+
let removed = 0;
|
|
1597
1641
|
const result = await mutateItem({
|
|
1598
1642
|
pmRoot,
|
|
1599
1643
|
settings,
|
|
1600
1644
|
id,
|
|
1601
|
-
op: "tests_add",
|
|
1645
|
+
op: adds.length > 0 ? "tests_add" : "tests_remove",
|
|
1602
1646
|
author: resolveAuthor(options.author, settings.author_default),
|
|
1603
1647
|
message: options.message,
|
|
1604
1648
|
force: options.force,
|
|
1605
1649
|
skipNoop: true,
|
|
1606
1650
|
mutate(document) {
|
|
1607
1651
|
const previous = document.metadata.tests ?? [];
|
|
1608
|
-
const
|
|
1609
|
-
|
|
1652
|
+
const mutation = applyLinkedTestMutations(previous, adds, removes, removeIndexes);
|
|
1653
|
+
removed = mutation.removed;
|
|
1654
|
+
if ((removes.length > 0 || removeIndexes.length > 0) && removed === 0) {
|
|
1655
|
+
throw new PmCliError("No linked tests matched the requested removal selector", EXIT_CODE.NOT_FOUND, {
|
|
1656
|
+
code: "linked_test_remove_no_match",
|
|
1657
|
+
unmatched: [
|
|
1658
|
+
...removes.map((entry) => `${entry.kind}=${entry.value}`),
|
|
1659
|
+
...removeIndexes.map((index) => `index=${index}`),
|
|
1660
|
+
],
|
|
1661
|
+
required: "List linked tests and retry with an exact command/path or a current 1-based --remove-index.",
|
|
1662
|
+
examples: [
|
|
1663
|
+
`pm test ${id} --list`,
|
|
1664
|
+
`pm test ${id} --remove-index 1`,
|
|
1665
|
+
],
|
|
1666
|
+
});
|
|
1667
|
+
}
|
|
1668
|
+
document.metadata.tests = mutation.tests;
|
|
1610
1669
|
return {
|
|
1611
|
-
changedFields: stableValueEquals(previous,
|
|
1670
|
+
changedFields: stableValueEquals(previous, mutation.tests)
|
|
1671
|
+
? []
|
|
1672
|
+
: ["tests"],
|
|
1612
1673
|
};
|
|
1613
1674
|
},
|
|
1614
1675
|
});
|
|
@@ -1617,6 +1678,7 @@ async function resolveLinkedTestItem(params) {
|
|
|
1617
1678
|
tests: result.item.tests ?? [],
|
|
1618
1679
|
testRuns: result.item.test_runs ?? [],
|
|
1619
1680
|
changed: result.changedFields.length > 0,
|
|
1681
|
+
removed,
|
|
1620
1682
|
};
|
|
1621
1683
|
}
|
|
1622
1684
|
function resolveTestRunOptions(options, tests) {
|
|
@@ -1780,6 +1842,7 @@ export async function runTest(id, options, global) {
|
|
|
1780
1842
|
...parseAddJsonEntries(resolvedAddJsons),
|
|
1781
1843
|
];
|
|
1782
1844
|
const removes = parseRemoveEntries(resolvedRemoves);
|
|
1845
|
+
const removeIndexes = parseRemoveIndexes(options.removeIndex);
|
|
1783
1846
|
const item = await resolveLinkedTestItem({
|
|
1784
1847
|
id,
|
|
1785
1848
|
options,
|
|
@@ -1788,6 +1851,7 @@ export async function runTest(id, options, global) {
|
|
|
1788
1851
|
typeToFolder: typeRegistry.type_to_folder,
|
|
1789
1852
|
adds,
|
|
1790
1853
|
removes,
|
|
1854
|
+
removeIndexes,
|
|
1791
1855
|
});
|
|
1792
1856
|
const runOptions = resolveTestRunOptions(options, item.tests);
|
|
1793
1857
|
const runStartedAt = options.run === true ? nowIso() : undefined;
|
|
@@ -1835,6 +1899,7 @@ export async function runTest(id, options, global) {
|
|
|
1835
1899
|
warnings: warnings.length > 0 ? warnings : undefined,
|
|
1836
1900
|
changed: item.changed,
|
|
1837
1901
|
count: item.tests.length,
|
|
1902
|
+
...(item.removed > 0 ? { removed: item.removed } : {}),
|
|
1838
1903
|
...measurementProjection,
|
|
1839
1904
|
};
|
|
1840
1905
|
}
|
|
@@ -1874,4 +1939,4 @@ export const _testOnlyTestCommand = {
|
|
|
1874
1939
|
summarizeRunResultStatuses,
|
|
1875
1940
|
};
|
|
1876
1941
|
//# sourceMappingURL=execution.js.map
|
|
1877
|
-
//# debugId=
|
|
1942
|
+
//# debugId=b40f54be-2d3e-5b98-9d49-cb8608a782f5
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module sdk/traceability/runtime-files-lookup
|
|
3
|
+
*
|
|
4
|
+
* Projects transport-neutral action values into reverse source lookup options.
|
|
5
|
+
*/
|
|
6
|
+
import type { FilesLookupOptions } from "../files.js";
|
|
7
|
+
/** Convert bounded MCP/action values into the public files lookup contract. */
|
|
8
|
+
export declare function runtimeFilesLookupOptions(options: Readonly<Record<string, unknown>>, paths: string[], parseInteger: (value: unknown, label: string) => number | undefined): FilesLookupOptions;
|
|
@@ -0,0 +1,33 @@
|
|
|
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]="c2ef0de1-bc44-5550-862c-f3929334fbef")}catch(e){}}();
|
|
3
|
+
import { parseSourceLineRange } from "./source-traceability.js";
|
|
4
|
+
/** Convert bounded MCP/action values into the public files lookup contract. */
|
|
5
|
+
export function runtimeFilesLookupOptions(options, paths, parseInteger) {
|
|
6
|
+
let lineRange;
|
|
7
|
+
if (typeof options.lines === "string") {
|
|
8
|
+
lineRange = parseSourceLineRange(options.lines);
|
|
9
|
+
}
|
|
10
|
+
else if (options.lineRange !== undefined) {
|
|
11
|
+
if (options.lineRange === null ||
|
|
12
|
+
typeof options.lineRange !== "object" ||
|
|
13
|
+
Array.isArray(options.lineRange)) {
|
|
14
|
+
throw new RangeError("Source line range must be an object with numeric start and end values.");
|
|
15
|
+
}
|
|
16
|
+
lineRange = parseSourceLineRange(`${String(Reflect.get(options.lineRange, "start"))}:${String(Reflect.get(options.lineRange, "end"))}`);
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
paths,
|
|
20
|
+
scope: options.scope === "project" || options.scope === "global"
|
|
21
|
+
? options.scope
|
|
22
|
+
: undefined,
|
|
23
|
+
limit: parseInteger(options.limit, "files lookup limit"),
|
|
24
|
+
offset: parseInteger(options.offset, "files lookup offset"),
|
|
25
|
+
noTruncate: options.noTruncate === true,
|
|
26
|
+
strictRead: options.strictRead === true,
|
|
27
|
+
explain: options.explain === true,
|
|
28
|
+
lineRange,
|
|
29
|
+
decisionDepth: parseInteger(options.decisionDepth, "files lookup decision depth"),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=runtime-files-lookup.js.map
|
|
33
|
+
//# debugId=c2ef0de1-bc44-5550-862c-f3929334fbef
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import type { ItemMetadata, LinkedFile } from "../../types/index.js";
|
|
2
|
+
/** Inclusive one-based source range accepted by traceability lookup. */
|
|
3
|
+
export interface SourceLineRange {
|
|
4
|
+
/** First included source line. */
|
|
5
|
+
start: number;
|
|
6
|
+
/** Last included source line. */
|
|
7
|
+
end: number;
|
|
8
|
+
}
|
|
9
|
+
/** One evidence class supporting a source-to-item association. */
|
|
10
|
+
export interface SourceTraceabilityEvidence {
|
|
11
|
+
/** Evidence producer. */
|
|
12
|
+
kind: "linked_file" | "git_commit";
|
|
13
|
+
/** Linked path or abbreviated commit identifier. */
|
|
14
|
+
reference: string;
|
|
15
|
+
/** Number of selected lines attributed to this evidence. */
|
|
16
|
+
contribution_lines?: number;
|
|
17
|
+
}
|
|
18
|
+
/** Rationale fields projected without arbitrary body or comment content. */
|
|
19
|
+
export interface SourceTraceabilityRationale {
|
|
20
|
+
/** User or project value statement. */
|
|
21
|
+
value: string | null;
|
|
22
|
+
/** Recorded timing rationale. */
|
|
23
|
+
why_now: string | null;
|
|
24
|
+
/** Recorded intended or achieved outcome. */
|
|
25
|
+
outcome: string | null;
|
|
26
|
+
/** Recorded implementation objective. */
|
|
27
|
+
objective: string | null;
|
|
28
|
+
}
|
|
29
|
+
/** Shortest typed path from source-owning work to a governing decision. */
|
|
30
|
+
export interface SourceDecisionPath {
|
|
31
|
+
/** Whether a unique decision path was found under the bound. */
|
|
32
|
+
status: "found" | "ambiguous" | "not_found";
|
|
33
|
+
/** Ordered item identifiers, including source work and decision. */
|
|
34
|
+
nodes: string[];
|
|
35
|
+
/** Relationship kinds connecting consecutive nodes. */
|
|
36
|
+
kinds: string[];
|
|
37
|
+
/** Equally short governing decision candidates. */
|
|
38
|
+
alternative_decision_ids: string[];
|
|
39
|
+
}
|
|
40
|
+
/** Explainable fields added to one reverse linked-file match. */
|
|
41
|
+
export interface SourceTraceabilityExplanation {
|
|
42
|
+
/** Higher values sort first within the original scheduling priority. */
|
|
43
|
+
score: number;
|
|
44
|
+
/** Selected source lines attributable to commits naming this item. */
|
|
45
|
+
contribution_lines: number;
|
|
46
|
+
/** Structured evidence supporting the association. */
|
|
47
|
+
evidence: SourceTraceabilityEvidence[];
|
|
48
|
+
/** Project rationale carried by the item. */
|
|
49
|
+
rationale: SourceTraceabilityRationale;
|
|
50
|
+
/** Governing decision path under the declared graph bound. */
|
|
51
|
+
decision_path: SourceDecisionPath;
|
|
52
|
+
/** Honest ambiguity codes; an empty list means no ambiguity was observed. */
|
|
53
|
+
ambiguities: string[];
|
|
54
|
+
}
|
|
55
|
+
/** Aggregate line-attribution receipt returned beside explained matches. */
|
|
56
|
+
export interface SourceTraceabilityReceipt {
|
|
57
|
+
/** Inclusive selected range, or null for path-only explanation. */
|
|
58
|
+
line_range: SourceLineRange | null;
|
|
59
|
+
/** Number of distinct blamed commits. */
|
|
60
|
+
blamed_commit_count: number;
|
|
61
|
+
/** Number of blamed commits whose message named at least one pm item. */
|
|
62
|
+
mapped_commit_count: number;
|
|
63
|
+
/** Number of blamed commits without an item reference. */
|
|
64
|
+
unmapped_commit_count: number;
|
|
65
|
+
/** Maximum relationship depth searched for a governing decision. */
|
|
66
|
+
decision_depth: number;
|
|
67
|
+
}
|
|
68
|
+
interface TraceabilityCandidate {
|
|
69
|
+
item: ItemMetadata;
|
|
70
|
+
files: LinkedFile[];
|
|
71
|
+
}
|
|
72
|
+
interface GitAttribution {
|
|
73
|
+
commitLines: Map<string, number>;
|
|
74
|
+
commitItems: Map<string, string[]>;
|
|
75
|
+
available: boolean;
|
|
76
|
+
}
|
|
77
|
+
/** Parse an inclusive `start:end` source-line selector. */
|
|
78
|
+
export declare function parseSourceLineRange(value: string): SourceLineRange;
|
|
79
|
+
declare function parseBlameCommits(output: string): Map<string, number>;
|
|
80
|
+
declare function parseCommitItemReferences(output: string): Map<string, string[]>;
|
|
81
|
+
declare function shortestDecisionPath(itemId: string, corpus: readonly ItemMetadata[], maxDepth: number): SourceDecisionPath;
|
|
82
|
+
declare function mappedBlamedCommits(attribution: GitAttribution): string[];
|
|
83
|
+
/** Enrich reverse linked-file candidates with bounded source rationale. */
|
|
84
|
+
export declare function explainSourceTraceability(params: {
|
|
85
|
+
workspaceRoot: string;
|
|
86
|
+
paths: readonly string[];
|
|
87
|
+
candidates: readonly TraceabilityCandidate[];
|
|
88
|
+
corpus: readonly ItemMetadata[];
|
|
89
|
+
lineRange?: SourceLineRange;
|
|
90
|
+
decisionDepth?: number;
|
|
91
|
+
}): Promise<{
|
|
92
|
+
explanations: Map<string, SourceTraceabilityExplanation>;
|
|
93
|
+
receipt: SourceTraceabilityReceipt;
|
|
94
|
+
}>;
|
|
95
|
+
/** Internal parser and traversal seams for deterministic boundary tests. */
|
|
96
|
+
export declare const _testOnlySourceTraceability: {
|
|
97
|
+
mappedBlamedCommits: typeof mappedBlamedCommits;
|
|
98
|
+
parseBlameCommits: typeof parseBlameCommits;
|
|
99
|
+
parseCommitItemReferences: typeof parseCommitItemReferences;
|
|
100
|
+
shortestDecisionPath: typeof shortestDecisionPath;
|
|
101
|
+
};
|
|
102
|
+
export {};
|