arc-1 1.0.2 → 1.1.0

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.
Files changed (166) hide show
  1. package/bin/arc1-cli.js +3 -7
  2. package/bin/arc1.js +4 -9
  3. package/dist/adt/abapgit.d.ts +10 -5
  4. package/dist/adt/abapgit.d.ts.map +1 -1
  5. package/dist/adt/abapgit.js +357 -76
  6. package/dist/adt/abapgit.js.map +1 -1
  7. package/dist/adt/atc.d.ts +49 -0
  8. package/dist/adt/atc.d.ts.map +1 -0
  9. package/dist/adt/atc.js +294 -0
  10. package/dist/adt/atc.js.map +1 -0
  11. package/dist/adt/aunit-package.d.ts +22 -0
  12. package/dist/adt/aunit-package.d.ts.map +1 -0
  13. package/dist/adt/aunit-package.js +78 -0
  14. package/dist/adt/aunit-package.js.map +1 -0
  15. package/dist/adt/aunit.d.ts +143 -0
  16. package/dist/adt/aunit.d.ts.map +1 -0
  17. package/dist/adt/aunit.js +987 -0
  18. package/dist/adt/aunit.js.map +1 -0
  19. package/dist/adt/client.d.ts +9 -7
  20. package/dist/adt/client.d.ts.map +1 -1
  21. package/dist/adt/client.js +55 -64
  22. package/dist/adt/client.js.map +1 -1
  23. package/dist/adt/config.d.ts +2 -0
  24. package/dist/adt/config.d.ts.map +1 -1
  25. package/dist/adt/config.js +1 -0
  26. package/dist/adt/config.js.map +1 -1
  27. package/dist/adt/devtools.d.ts +8 -30
  28. package/dist/adt/devtools.d.ts.map +1 -1
  29. package/dist/adt/devtools.js +41 -218
  30. package/dist/adt/devtools.js.map +1 -1
  31. package/dist/adt/diagnostics.d.ts +1 -1
  32. package/dist/adt/diagnostics.d.ts.map +1 -1
  33. package/dist/adt/diagnostics.js +12 -12
  34. package/dist/adt/diagnostics.js.map +1 -1
  35. package/dist/adt/errors.d.ts +7 -0
  36. package/dist/adt/errors.d.ts.map +1 -1
  37. package/dist/adt/errors.js +7 -0
  38. package/dist/adt/errors.js.map +1 -1
  39. package/dist/adt/features.d.ts +9 -3
  40. package/dist/adt/features.d.ts.map +1 -1
  41. package/dist/adt/features.js +40 -8
  42. package/dist/adt/features.js.map +1 -1
  43. package/dist/adt/gcts.d.ts +12 -45
  44. package/dist/adt/gcts.d.ts.map +1 -1
  45. package/dist/adt/gcts.js +299 -171
  46. package/dist/adt/gcts.js.map +1 -1
  47. package/dist/adt/http-deadline.d.ts +23 -0
  48. package/dist/adt/http-deadline.d.ts.map +1 -0
  49. package/dist/adt/http-deadline.js +106 -0
  50. package/dist/adt/http-deadline.js.map +1 -0
  51. package/dist/adt/http-wire-body.d.ts +2 -0
  52. package/dist/adt/http-wire-body.d.ts.map +1 -0
  53. package/dist/adt/http-wire-body.js +14 -0
  54. package/dist/adt/http-wire-body.js.map +1 -0
  55. package/dist/adt/http.d.ts +10 -24
  56. package/dist/adt/http.d.ts.map +1 -1
  57. package/dist/adt/http.js +89 -53
  58. package/dist/adt/http.js.map +1 -1
  59. package/dist/adt/path-safety.d.ts +16 -0
  60. package/dist/adt/path-safety.d.ts.map +1 -0
  61. package/dist/adt/path-safety.js +101 -0
  62. package/dist/adt/path-safety.js.map +1 -0
  63. package/dist/adt/semaphore.d.ts +2 -2
  64. package/dist/adt/semaphore.d.ts.map +1 -1
  65. package/dist/adt/semaphore.js +26 -9
  66. package/dist/adt/semaphore.js.map +1 -1
  67. package/dist/adt/source-diff.d.ts +10 -1
  68. package/dist/adt/source-diff.d.ts.map +1 -1
  69. package/dist/adt/source-diff.js +33 -7
  70. package/dist/adt/source-diff.js.map +1 -1
  71. package/dist/adt/text-search.d.ts +25 -0
  72. package/dist/adt/text-search.d.ts.map +1 -0
  73. package/dist/adt/text-search.js +152 -0
  74. package/dist/adt/text-search.js.map +1 -0
  75. package/dist/adt/transport-diff.d.ts +128 -0
  76. package/dist/adt/transport-diff.d.ts.map +1 -0
  77. package/dist/adt/transport-diff.js +524 -0
  78. package/dist/adt/transport-diff.js.map +1 -0
  79. package/dist/adt/transport.d.ts +78 -13
  80. package/dist/adt/transport.d.ts.map +1 -1
  81. package/dist/adt/transport.js +443 -41
  82. package/dist/adt/transport.js.map +1 -1
  83. package/dist/adt/types.d.ts +23 -12
  84. package/dist/adt/types.d.ts.map +1 -1
  85. package/dist/adt/xml-parser.d.ts +1 -8
  86. package/dist/adt/xml-parser.d.ts.map +1 -1
  87. package/dist/adt/xml-parser.js +54 -60
  88. package/dist/adt/xml-parser.js.map +1 -1
  89. package/dist/authz/policy.d.ts.map +1 -1
  90. package/dist/authz/policy.js +5 -2
  91. package/dist/authz/policy.js.map +1 -1
  92. package/dist/cli-args.d.ts +2 -2
  93. package/dist/cli-args.js +2 -2
  94. package/dist/cli-checks.d.ts +56 -0
  95. package/dist/cli-checks.d.ts.map +1 -0
  96. package/dist/cli-checks.js +368 -0
  97. package/dist/cli-checks.js.map +1 -0
  98. package/dist/cli.d.ts +68 -15
  99. package/dist/cli.d.ts.map +1 -1
  100. package/dist/cli.js +677 -297
  101. package/dist/cli.js.map +1 -1
  102. package/dist/handlers/cds-hints.d.ts.map +1 -1
  103. package/dist/handlers/cds-hints.js +1 -10
  104. package/dist/handlers/cds-hints.js.map +1 -1
  105. package/dist/handlers/diagnose.d.ts +4 -0
  106. package/dist/handlers/diagnose.d.ts.map +1 -1
  107. package/dist/handlers/diagnose.js +616 -9
  108. package/dist/handlers/diagnose.js.map +1 -1
  109. package/dist/handlers/dispatch.d.ts.map +1 -1
  110. package/dist/handlers/dispatch.js +40 -1
  111. package/dist/handlers/dispatch.js.map +1 -1
  112. package/dist/handlers/git.d.ts.map +1 -1
  113. package/dist/handlers/git.js +165 -84
  114. package/dist/handlers/git.js.map +1 -1
  115. package/dist/handlers/read.d.ts.map +1 -1
  116. package/dist/handlers/read.js +15 -0
  117. package/dist/handlers/read.js.map +1 -1
  118. package/dist/handlers/schemas.d.ts +15 -2
  119. package/dist/handlers/schemas.d.ts.map +1 -1
  120. package/dist/handlers/schemas.js +75 -6
  121. package/dist/handlers/schemas.js.map +1 -1
  122. package/dist/handlers/search.js +1 -1
  123. package/dist/handlers/search.js.map +1 -1
  124. package/dist/handlers/tools.d.ts.map +1 -1
  125. package/dist/handlers/tools.js +51 -42
  126. package/dist/handlers/tools.js.map +1 -1
  127. package/dist/handlers/transport.d.ts +2 -1
  128. package/dist/handlers/transport.d.ts.map +1 -1
  129. package/dist/handlers/transport.js +128 -27
  130. package/dist/handlers/transport.js.map +1 -1
  131. package/dist/handlers/write/create.d.ts.map +1 -1
  132. package/dist/handlers/write/create.js +11 -0
  133. package/dist/handlers/write/create.js.map +1 -1
  134. package/dist/handlers/write/update-delete.d.ts.map +1 -1
  135. package/dist/handlers/write/update-delete.js +33 -10
  136. package/dist/handlers/write/update-delete.js.map +1 -1
  137. package/dist/handlers/write-helpers.d.ts.map +1 -1
  138. package/dist/handlers/write-helpers.js +3 -2
  139. package/dist/handlers/write-helpers.js.map +1 -1
  140. package/dist/server/audit.d.ts +1 -1
  141. package/dist/server/audit.d.ts.map +1 -1
  142. package/dist/server/audit.js +228 -21
  143. package/dist/server/audit.js.map +1 -1
  144. package/dist/server/config.d.ts +16 -0
  145. package/dist/server/config.d.ts.map +1 -1
  146. package/dist/server/config.js +145 -17
  147. package/dist/server/config.js.map +1 -1
  148. package/dist/server/effective-policy-log.d.ts +2 -1
  149. package/dist/server/effective-policy-log.d.ts.map +1 -1
  150. package/dist/server/effective-policy-log.js +8 -2
  151. package/dist/server/effective-policy-log.js.map +1 -1
  152. package/dist/server/multi-target-runtime.d.ts.map +1 -1
  153. package/dist/server/multi-target-runtime.js +3 -0
  154. package/dist/server/multi-target-runtime.js.map +1 -1
  155. package/dist/server/multi-target-tools.d.ts.map +1 -1
  156. package/dist/server/multi-target-tools.js +5 -0
  157. package/dist/server/multi-target-tools.js.map +1 -1
  158. package/dist/server/server.d.ts +15 -13
  159. package/dist/server/server.d.ts.map +1 -1
  160. package/dist/server/server.js +36 -26
  161. package/dist/server/server.js.map +1 -1
  162. package/dist/server/types.d.ts +2 -0
  163. package/dist/server/types.d.ts.map +1 -1
  164. package/dist/server/types.js +1 -0
  165. package/dist/server/types.js.map +1 -1
  166. package/package.json +13 -13
@@ -0,0 +1,524 @@
1
+ /**
2
+ * Transport-scoped review diffs — backs `SAPTransport action="diff"`.
3
+ *
4
+ * Answers "what did this transport change?" by picking, per object, the revision written
5
+ * under the transport and the one immediately before it, then diffing those two sources.
6
+ *
7
+ * The selection mirrors SAP's own ADT MCP tool
8
+ * (`com.sap.adt.tm.backend.diff.TransportDiffService`, ADT 3.60.1) with four corrections
9
+ * proven necessary against live feeds — see docs/plans/2026-08-03-transport-diff.md:
10
+ *
11
+ * 1. match the request AND its tasks (SAP matches one exact correction number);
12
+ * 2. break timestamp ties on the version number — the feed is returned in neither
13
+ * version nor date order (a4h returns `00002, 00000, 00001`);
14
+ * 3. skip every same-transport sibling when walking back, not just one active entry,
15
+ * so two saves under one transport still diff against the pre-transport state;
16
+ * 4. never require the predecessor to carry a CTS id — released revisions with a blank
17
+ * transport exist and are valid baselines.
18
+ *
19
+ * `selectionMethod` and `baselineStatus` ride the result so a reviewer can tell exact
20
+ * evidence from a fallback guess; SAP's tool reports neither.
21
+ */
22
+ import { CLASS_REVISION_INCLUDES, REVISION_TYPES } from './client.js';
23
+ import { AdtApiError, isNotFoundError } from './errors.js';
24
+ import { unifiedDiff } from './source-diff.js';
25
+ /**
26
+ * Error text for a result NOTE (not a thrown error).
27
+ *
28
+ * These notes ride a SUCCESS payload, so they never reach dispatch's `formatMinimalAdtError`.
29
+ * Under `ARC1_MINIMAL_ERRORS` the SAP diagnostic and the ADT path must still be withheld —
30
+ * the status code alone is enough for a reviewer to see that something failed.
31
+ */
32
+ function describeError(err, minimalErrors) {
33
+ if (!minimalErrors)
34
+ return err instanceof Error ? err.message : String(err);
35
+ if (err instanceof AdtApiError)
36
+ return `SAP request failed (status ${err.statusCode})`;
37
+ return 'request failed';
38
+ }
39
+ /**
40
+ * The two pseudo-versions SAP's `IRevision` maps to UI text rather than a number: `00000` is the
41
+ * ACTIVE work state and `99999` the INACTIVE draft. Either can legitimately be the *current* side
42
+ * of a review — that is the change being shipped — but neither is ever a transported baseline.
43
+ */
44
+ const ACTIVE_VERSION = '00000';
45
+ const INACTIVE_VERSION = '99999';
46
+ const WORK_STATE_VERSIONS = new Set([ACTIVE_VERSION, INACTIVE_VERSION]);
47
+ /**
48
+ * The 5-digit ADT version number of a revision.
49
+ *
50
+ * On 7.58 the atom `<id>` is the bare number (`00001`). Some releases use a URN there, so
51
+ * fall back to the number segment of the content URI (`…/versions/<ts>/00001/content`).
52
+ */
53
+ export function revisionNumber(revision) {
54
+ for (const value of [revision.id, revision.uri]) {
55
+ const match = String(value ?? '').match(/(?:^|\/)(\d{5})(?:$|[/?#])/);
56
+ if (match)
57
+ return match[1];
58
+ }
59
+ return '';
60
+ }
61
+ /**
62
+ * Newest first: timestamp desc, then version number desc, then original order (stable).
63
+ *
64
+ * A revision may carry NO `<atom:updated>` at all (live: CERTRULE_DYNP version 00001 on
65
+ * a4h). Such entries rank AFTER every dated one — a high-numbered undated revision must not
66
+ * outrank a genuinely newer dated one and become the baseline — and are then ordered among
67
+ * themselves by version number.
68
+ */
69
+ function sortNewestFirst(revisions) {
70
+ return revisions
71
+ .map((revision, index) => {
72
+ const parsed = Date.parse(String(revision.timestamp ?? ''));
73
+ // revisionNumber() returns '' when no digit run is present, and Number('') is 0 — which
74
+ // would rank an unparseable revision alongside ACTIVE (00000). Test the digits instead.
75
+ const raw = revisionNumber(revision);
76
+ return {
77
+ revision,
78
+ index,
79
+ time: Number.isFinite(parsed) ? parsed : Number.NEGATIVE_INFINITY,
80
+ num: /^\d+$/.test(raw) ? Number(raw) : Number.NEGATIVE_INFINITY,
81
+ };
82
+ })
83
+ .sort(
84
+ // Subtracting two -Infinity values yields NaN, so compare the keys instead of
85
+ // differencing them — the ordering must not depend on NaN happening to be falsy.
86
+ (a, b) => compareDesc(a.time, b.time) || compareDesc(a.num, b.num) || a.index - b.index)
87
+ .map((e) => e.revision);
88
+ }
89
+ /** Descending compare that is total for ±Infinity (a - b would be NaN for equal infinities). */
90
+ function compareDesc(a, b) {
91
+ if (a === b)
92
+ return 0;
93
+ return a > b ? -1 : 1;
94
+ }
95
+ /**
96
+ * Pick the revision written under `transportIds` and the one immediately preceding it.
97
+ *
98
+ * `transportIds` should hold the request id AND every task id: version records reference
99
+ * the request on the systems verified so far, but matching both is a superset that can
100
+ * only add correct matches.
101
+ */
102
+ export function selectTransportRevisionPair(revisions, transportIds) {
103
+ const sorted = sortNewestFirst(revisions);
104
+ const wanted = new Set([...transportIds].map((id) => String(id).trim().toUpperCase()).filter(Boolean));
105
+ const belongsToTransport = (r) => {
106
+ const id = String(r.transport ?? '')
107
+ .trim()
108
+ .toUpperCase();
109
+ return id !== '' && wanted.has(id);
110
+ };
111
+ if (!sorted.length) {
112
+ return { current: null, previous: null, selectionMethod: 'no-revisions', skipped: [] };
113
+ }
114
+ // An UNRELEASED transport has no snapshot of its own — but while its objects are locked,
115
+ // the active entry (00000) carries the transport link, so it matches here and the walk
116
+ // back lands on the last released state. That makes "what am I about to ship" the same
117
+ // code path as "what did this transport ship", with the same evidence labels.
118
+ let currentIndex = sorted.findIndex(belongsToTransport);
119
+ let selectionMethod = 'exact-transport';
120
+ if (currentIndex === -1) {
121
+ // No revision names this transport. Prefer the newest real snapshot over a work state,
122
+ // so the diff is still between two transported versions.
123
+ currentIndex = sorted.findIndex((r) => !WORK_STATE_VERSIONS.has(revisionNumber(r)));
124
+ selectionMethod = 'latest-revision-fallback';
125
+ }
126
+ if (currentIndex === -1) {
127
+ currentIndex = 0;
128
+ selectionMethod = 'active-only-fallback';
129
+ }
130
+ const skipped = [];
131
+ let previousIndex = currentIndex + 1;
132
+ while (previousIndex < sorted.length) {
133
+ const candidate = sorted[previousIndex];
134
+ const num = revisionNumber(candidate);
135
+ if (WORK_STATE_VERSIONS.has(num)) {
136
+ const kind = num === ACTIVE_VERSION ? 'active work state' : 'inactive draft';
137
+ skipped.push({ revision: candidate, reason: `${kind} (version ${num}), not a transported predecessor` });
138
+ }
139
+ else if (belongsToTransport(candidate)) {
140
+ skipped.push({ revision: candidate, reason: 'belongs to the same transport — baseline must predate it' });
141
+ }
142
+ else {
143
+ break;
144
+ }
145
+ previousIndex += 1;
146
+ }
147
+ return {
148
+ current: sorted[currentIndex],
149
+ previous: previousIndex < sorted.length ? sorted[previousIndex] : null,
150
+ selectionMethod,
151
+ skipped,
152
+ };
153
+ }
154
+ /**
155
+ * Classify the "before" side.
156
+ *
157
+ * Creation is asserted ONLY when the current revision was matched to the transport and has
158
+ * no predecessor. A missing predecessor under a fallback selection is ambiguous — it may
159
+ * simply mean the object's history was never snapshotted.
160
+ */
161
+ export function baselineStatusFor(pair, allRevisions = []) {
162
+ if (!pair.current)
163
+ return 'baseline-unavailable';
164
+ const matched = pair.selectionMethod === 'exact-transport';
165
+ if (pair.previous)
166
+ return matched ? 'prior-revision' : 'prior-revision-unverified';
167
+ if (!matched)
168
+ return 'baseline-ambiguous';
169
+ // "Matched with no predecessor" normally means created here — but for an OPEN transport the
170
+ // active row carries the transport link, so `matched` is trivially true, and SAP only writes
171
+ // versions on release. If any revision has a strictly lower version number, the object plainly
172
+ // pre-existed and the walk-back simply failed to reach it (e.g. the transport's own revision
173
+ // is undated and sorts last). Creation is asserted only when nothing older exists.
174
+ const currentNum = Number(revisionNumber(pair.current));
175
+ const hasOlder = allRevisions.some((r) => {
176
+ const raw = revisionNumber(r);
177
+ return /^\d+$/.test(raw) && !WORK_STATE_VERSIONS.has(raw) && Number(raw) < currentNum;
178
+ });
179
+ return hasOlder ? 'baseline-ambiguous' : 'no-prior-snapshot';
180
+ }
181
+ // ─── Logical object rollup ──────────────────────────────────────────
182
+ /**
183
+ * LIMU component types that belong to a class.
184
+ *
185
+ * `REPT` (text pool) deliberately is NOT here: it exists for BOTH classes (the `====CP` class
186
+ * pool) and programs, and claiming it for classes turned every report with text symbols into a
187
+ * phantom class. It is resolved by `wbtype`/name shape below instead.
188
+ */
189
+ const CLASS_COMPONENT_TYPES = new Set(['CINC', 'CPRI', 'CPRO', 'CPUB', 'CLSD', 'METH']);
190
+ /** LIMU source types that roll up to a program (or, by `wbtype`, an include). */
191
+ const PROGRAM_COMPONENT_TYPES = new Set(['REPS', 'REPT']);
192
+ /**
193
+ * The owning class of a LIMU class component, or '' when the entry is not one.
194
+ *
195
+ * CTS pads the class name to 30 characters and appends the component:
196
+ * `ZCL_ARC1_DEMO_CALC SUBTRACT` (METH — space padded)
197
+ * `ZCL_ARC1_DEMO_CALC============CCIMP` (CINC — '=' padded)
198
+ * Both live shapes verified on a4h. Taking the first 30 chars and cutting at the first
199
+ * '=' handles both, where SAP's own `^([^\s]+)` leaves `====CCIMP` attached.
200
+ *
201
+ * `REPT` is ambiguous (class pool vs program text pool), so it counts as a class component
202
+ * only when `wbtype` says CLAS or the name carries the `=`-padded class-pool shape.
203
+ */
204
+ function classOwnerName(pgmid, type, wbtype, name) {
205
+ if (pgmid !== 'LIMU')
206
+ return '';
207
+ const wb = wbtype.toUpperCase();
208
+ const isClassComponent = CLASS_COMPONENT_TYPES.has(type) || wb.startsWith('CLAS/') || (type === 'REPT' && name.includes('='));
209
+ if (!isClassComponent)
210
+ return '';
211
+ return name.slice(0, 30).replace(/=+.*$/, '').trimEnd();
212
+ }
213
+ /**
214
+ * ADT splits programs and includes across two endpoints (`/programs/programs/` vs
215
+ * `/programs/includes/`) although CTS types both as `R3TR PROG` / `LIMU REPS`. Only `wbtype`
216
+ * carries the distinction, so an include typed as PROG would 404 on every revision lookup.
217
+ */
218
+ function isIncludeWbtype(wbtype) {
219
+ return wbtype.toUpperCase().startsWith('PROG/I');
220
+ }
221
+ /**
222
+ * A FUNCTION-GROUP *source* entry: the group container (`FUGR/F`), its main program
223
+ * (`FUGR/PX`) or a structural include (`FUGR/I`, live-verified on 7.50 and 7.58 — see
224
+ * `src/handlers/read.ts`). These live under `/functions/groups/{group}/...`, which has no
225
+ * revisions feed here, so they are reported as inventory rather than 404'd elsewhere.
226
+ *
227
+ * `FUGR/FF` is deliberately EXCLUDED: it is a function MODULE (`LIMU FUNC`), which
228
+ * `SLASH_TYPE_MAP` maps to the fully supported `FUNC` type. Matching the bare `FUGR/`
229
+ * prefix would send every changed function module to inventory instead of diffing it.
230
+ */
231
+ function isFunctionGroupSource(wbtype) {
232
+ const wb = wbtype.toUpperCase();
233
+ return wb.startsWith('FUGR/') && !wb.startsWith('FUGR/FF');
234
+ }
235
+ /** Marker type for a function-group part, so `diffTransportObject` can explain it. */
236
+ const FUGR_INCLUDE_TYPE = 'FUGR_INCLUDE';
237
+ /**
238
+ * Collapse a transport's raw entries into reviewable objects.
239
+ *
240
+ * `parseTransportList` already yields task-level entries only, so request-level and
241
+ * `<tm:all_objects>` duplicates never arrive here — but the same object under two tasks
242
+ * does, and LIMU names are unusable as ADT object names either way.
243
+ */
244
+ export function rollupTransportObjects(tasks) {
245
+ const byKey = new Map();
246
+ for (const task of tasks) {
247
+ for (const object of task.objects) {
248
+ const pgmid = String(object.pgmid ?? '').toUpperCase();
249
+ // Release comments ("Comment Entry: Released") are bookkeeping, not repository objects.
250
+ if (pgmid === 'CORR')
251
+ continue;
252
+ const rawType = String(object.type ?? '').toUpperCase();
253
+ const wbtype = String(object.wbtype ?? '');
254
+ const rawName = String(object.name ?? '').toUpperCase();
255
+ const owner = classOwnerName(pgmid, rawType, wbtype, rawName);
256
+ let type = rawType;
257
+ let name = rawName;
258
+ let logicalPgmid = pgmid;
259
+ if (owner) {
260
+ logicalPgmid = 'R3TR';
261
+ type = 'CLAS';
262
+ name = owner;
263
+ }
264
+ else if (isFunctionGroupSource(wbtype)) {
265
+ // FUGR sources are not addressable via the program/include endpoints — keep the entry
266
+ // visible as inventory instead of routing it somewhere that 404s.
267
+ logicalPgmid = 'R3TR';
268
+ type = FUGR_INCLUDE_TYPE;
269
+ }
270
+ else if (pgmid === 'LIMU' && PROGRAM_COMPONENT_TYPES.has(rawType)) {
271
+ logicalPgmid = 'R3TR';
272
+ type = isIncludeWbtype(wbtype) ? 'INCL' : 'PROG';
273
+ }
274
+ else if (type === 'PROG' && isIncludeWbtype(wbtype)) {
275
+ // R3TR PROG with wbtype PROG/I is a standalone include, not a program.
276
+ type = 'INCL';
277
+ }
278
+ if (!type || !name)
279
+ continue;
280
+ const key = `${logicalPgmid}:${type}:${name}`;
281
+ const component = { pgmid, type: rawType, name: object.name, wbtype, taskId: task.id };
282
+ const existing = byKey.get(key);
283
+ if (!existing) {
284
+ byKey.set(key, {
285
+ pgmid: logicalPgmid,
286
+ type,
287
+ name,
288
+ description: String(object.description ?? ''),
289
+ taskIds: [task.id],
290
+ components: [component],
291
+ });
292
+ continue;
293
+ }
294
+ existing.description ||= String(object.description ?? '');
295
+ if (!existing.taskIds.includes(task.id))
296
+ existing.taskIds.push(task.id);
297
+ existing.components.push(component);
298
+ }
299
+ }
300
+ return [...byKey.values()];
301
+ }
302
+ // ─── Per-object diffing ─────────────────────────────────────────────
303
+ /** Class-pool suffix → the ADT include that holds it. */
304
+ const CLASS_POOL_INCLUDES = {
305
+ CCDEF: 'definitions',
306
+ CCIMP: 'implementations',
307
+ CCMAC: 'macros',
308
+ CCAU: 'testclasses',
309
+ };
310
+ /**
311
+ * Which class includes this transport actually touched.
312
+ *
313
+ * CTS already states it: a `CINC ZCL_X============CCIMP` entry names the include, and
314
+ * `METH`/`CPUB`/`CPRI`/`CPRO`/`CLSD` mean the main source. Reading that is strictly better
315
+ * than diffing all five and guessing afterwards which were untouched — it cannot mislabel a
316
+ * changed include as unchanged, and it drops ~4/5 of the SAP round trips for a typical class.
317
+ * A bare `R3TR CLAS` entry carries no component detail, so fall back to all five.
318
+ */
319
+ export function classIncludesFor(object) {
320
+ const includes = new Set();
321
+ for (const c of object.components) {
322
+ // A whole-class R3TR entry is exactly the case where CTS records NO component detail
323
+ // (`R3TR CLAS X` and `LIMU <sub> X` are mutually exclusive per request — measured across
324
+ // ~640k LIMU rows on 758, zero counterexamples), so fall back to every include.
325
+ if (c.pgmid !== 'LIMU')
326
+ return { includes: [...CLASS_REVISION_INCLUDES], fromComponents: false };
327
+ // The suffix starts at a FIXED offset: CTS pads the class name into a 30-char field. It
328
+ // pads with '=' only when the name is shorter — 6.6% of live CINC rows are 30-char names
329
+ // with no padding at all, where splitting on '=' returns the whole string and silently
330
+ // resolves to `main`. Positions 31+ hold only CCAU/CCIMP/CCDEF/CCMAC (census-verified);
331
+ // for METH/CLSD/CPUB/CPRI/CPRO they hold a method name or '', which correctly means main.
332
+ const suffix = c.name.slice(30).trim().toUpperCase();
333
+ includes.add(CLASS_POOL_INCLUDES[suffix] ?? 'main');
334
+ }
335
+ return includes.size
336
+ ? { includes: [...includes], fromComponents: true }
337
+ : { includes: [...CLASS_REVISION_INCLUDES], fromComponents: false };
338
+ }
339
+ /**
340
+ * Per-part diff cap. A created object renders its ENTIRE source as an addition, so a page of
341
+ * 20 such objects is otherwise unbounded — `MAX_DIFF_OBJECTS` limits the object count, never
342
+ * the bytes. `added`/`removed` are counted before truncation, so the totals stay honest.
343
+ */
344
+ const MAX_DIFF_LINES = 400;
345
+ /** Trim a unified diff to `MAX_DIFF_LINES` body lines, keeping the header. */
346
+ function capDiff(diff) {
347
+ const lines = diff.split('\n');
348
+ if (lines.length <= MAX_DIFF_LINES)
349
+ return { diff, truncated: false };
350
+ return {
351
+ diff: `${lines.slice(0, MAX_DIFF_LINES).join('\n')}\n… diff truncated at ${MAX_DIFF_LINES} lines`,
352
+ truncated: true,
353
+ };
354
+ }
355
+ /** Short evidence label for a revision, e.g. `00001 (A4HK906289)`. */
356
+ function revisionLabel(revision) {
357
+ const num = revisionNumber(revision) || revision.id || '?';
358
+ return revision.transport ? `${num} (${revision.transport})` : num;
359
+ }
360
+ /**
361
+ * Build the "we could not read this" part row. Message text is sanitized by the caller.
362
+ *
363
+ * `resolved` carries whatever evidence was already established. A failure AFTER pair selection
364
+ * (a flaky source GET) must keep its `selectionMethod`/`from`/`to` — claiming "no revisions"
365
+ * for an object whose pair WAS identified is a false signal in the field a reviewer uses to
366
+ * judge evidence quality.
367
+ */
368
+ function unavailablePart(part, note, resolved) {
369
+ return {
370
+ part,
371
+ baselineStatus: 'baseline-unavailable',
372
+ selectionMethod: resolved?.selectionMethod ?? 'no-revisions',
373
+ from: resolved?.from ?? null,
374
+ to: resolved?.to ?? null,
375
+ added: 0,
376
+ removed: 0,
377
+ diff: '',
378
+ note,
379
+ };
380
+ }
381
+ /**
382
+ * Diff one source part of one object across the transport boundary.
383
+ *
384
+ * Returns null ONLY for a class include that genuinely does not exist (most classes have no
385
+ * CCAU test include) — every other failure becomes a visible `baseline-unavailable` row, so a
386
+ * read error can never masquerade as "unchanged".
387
+ */
388
+ async function diffPart(client, type, name, part, transportIds, opts) {
389
+ const include = type === 'CLAS' ? part : undefined;
390
+ let revisions;
391
+ try {
392
+ revisions = (await client.getRevisions(type, name, { include, group: opts.group })).revisions;
393
+ }
394
+ catch (err) {
395
+ if (type === 'CLAS' && part !== 'main' && isNotFoundError(err))
396
+ return null;
397
+ return unavailablePart(part, `revision history unavailable: ${describeError(err, opts.minimalErrors)}`);
398
+ }
399
+ const pair = selectTransportRevisionPair(revisions, transportIds);
400
+ const base = {
401
+ part,
402
+ baselineStatus: baselineStatusFor(pair, revisions),
403
+ selectionMethod: pair.selectionMethod,
404
+ from: pair.previous ? revisionLabel(pair.previous) : null,
405
+ to: pair.current ? revisionLabel(pair.current) : null,
406
+ };
407
+ if (!pair.current) {
408
+ return { ...base, added: 0, removed: 0, diff: '', note: 'no revision history for this part' };
409
+ }
410
+ let after;
411
+ let before;
412
+ try {
413
+ // No predecessor: render the whole thing as an addition so a created object is still
414
+ // reviewable. `baselineStatus` says whether that is proven creation or a missing base.
415
+ [after, before] = await Promise.all([
416
+ client.getRevisionSource(pair.current.uri),
417
+ pair.previous ? client.getRevisionSource(pair.previous.uri) : Promise.resolve(''),
418
+ ]);
419
+ }
420
+ catch (err) {
421
+ return unavailablePart(part, `source read failed: ${describeError(err, opts.minimalErrors)}`, base);
422
+ }
423
+ const result = unifiedDiff(before, after, `${name} (${base.from ?? 'none'})`, `${name} (${base.to})`, 3, true);
424
+ const capped = capDiff(result.diff);
425
+ const note = result.cosmeticOnly
426
+ ? 'whitespace-only change (trailing blanks / final newline)'
427
+ : result.identical
428
+ ? 'no source change between the selected revisions'
429
+ : undefined;
430
+ return {
431
+ ...base,
432
+ added: result.added,
433
+ removed: result.removed,
434
+ diff: capped.diff,
435
+ ...(capped.truncated ? { diffTruncated: true } : {}),
436
+ ...(note ? { note } : {}),
437
+ };
438
+ }
439
+ /** Diff every source part of one logical object. Never throws — failures become visible rows. */
440
+ export async function diffTransportObject(client, object, transportIds, opts = {}) {
441
+ const { type, name, taskIds } = object;
442
+ const head = { type, name, taskIds };
443
+ if (type === FUGR_INCLUDE_TYPE) {
444
+ return {
445
+ ...head,
446
+ parts: [],
447
+ inventoryReason: 'function-group source (wbtype FUGR/*) — in scope, but its includes live under /functions/groups and have no revisions feed here',
448
+ };
449
+ }
450
+ if (!REVISION_TYPES.has(type)) {
451
+ return {
452
+ ...head,
453
+ parts: [],
454
+ inventoryReason: `type ${type} has no ADT source revision feed — in scope, but no source diff available`,
455
+ };
456
+ }
457
+ // FUNC revisions are addressed under their group. A lookup failure must not abort the whole
458
+ // review, so it degrades to an inventory row like any other per-object problem.
459
+ let group;
460
+ if (type === 'FUNC') {
461
+ try {
462
+ group = (await client.resolveFunctionGroup(name)) ?? undefined;
463
+ }
464
+ catch (err) {
465
+ return {
466
+ ...head,
467
+ parts: [],
468
+ inventoryReason: `function group lookup failed: ${describeError(err, opts.minimalErrors)}`,
469
+ };
470
+ }
471
+ if (!group) {
472
+ return { ...head, parts: [], inventoryReason: `cannot resolve the function group for FUNC ${name}` };
473
+ }
474
+ }
475
+ // Parts are independent reads; http.ts funnels every request through the shared Semaphore
476
+ // (ARC1_MAX_CONCURRENT), so fanning out here is bounded without extra bookkeeping.
477
+ const selection = type === 'CLAS' ? classIncludesFor(object) : { includes: ['main'], fromComponents: true };
478
+ const wanted = selection.includes;
479
+ const settled = await Promise.all(wanted.map(async (part) => {
480
+ try {
481
+ return await diffPart(client, type, name, part, transportIds, { group, minimalErrors: opts.minimalErrors });
482
+ }
483
+ catch (err) {
484
+ if (type === 'CLAS' && part !== 'main' && isNotFoundError(err))
485
+ return null;
486
+ return unavailablePart(part, `source read failed: ${describeError(err, opts.minimalErrors)}`);
487
+ }
488
+ }));
489
+ const parts = settled.filter((p) => p !== null);
490
+ // Every selected part turned out not to exist. Dropping them all would emit an object with
491
+ // no rows and no reason — indistinguishable from "nothing changed", which is the one thing
492
+ // this tool must never say by accident.
493
+ if (!parts.length) {
494
+ return {
495
+ ...head,
496
+ parts: [],
497
+ inventoryReason: `no readable source for ${wanted.join(', ')} — the object or its includes could not be found`,
498
+ };
499
+ }
500
+ return { ...head, parts: selection.fromComponents ? parts : suppressUntouchedParts(parts) };
501
+ }
502
+ /**
503
+ * Blank the DIFF of parts this transport did not touch, keeping the row for coverage.
504
+ *
505
+ * ONLY valid for a SPECULATIVE part list. When the includes came from the transport's own
506
+ * components, every selected part was named by CTS and therefore WAS changed — suppressing
507
+ * one because its revision happens to carry no CTS id (a live-verified shape) would erase a
508
+ * real diff and report it clean. The caller enforces that; this function assumes the parts
509
+ * were probed blindly.
510
+ *
511
+ * Without it, the whole-class (`R3TR CLAS`) shape renders SAP's boilerplate headers in the
512
+ * four untouched includes as fresh additions — noise around one real change.
513
+ *
514
+ * Two further guards: suppress only when a sibling part DID match the transport (so
515
+ * attribution demonstrably works for this object), and NEVER touch a row whose read failed.
516
+ */
517
+ function suppressUntouchedParts(parts) {
518
+ if (!parts.some((p) => p.selectionMethod === 'exact-transport'))
519
+ return parts;
520
+ return parts.map((p) => p.selectionMethod === 'exact-transport' || p.baselineStatus === 'baseline-unavailable'
521
+ ? p
522
+ : { ...p, added: 0, removed: 0, diff: '', note: 'not changed by this transport' });
523
+ }
524
+ //# sourceMappingURL=transport-diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport-diff.js","sourceRoot":"","sources":["../../src/adt/transport-diff.ts"],"names":[],"mappings":"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"}