arc-1 0.9.2 → 0.9.4

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 (60) hide show
  1. package/README.md +4 -4
  2. package/dist/adt/client.d.ts +12 -1
  3. package/dist/adt/client.d.ts.map +1 -1
  4. package/dist/adt/client.js +56 -1
  5. package/dist/adt/client.js.map +1 -1
  6. package/dist/adt/devtools.d.ts.map +1 -1
  7. package/dist/adt/devtools.js +191 -51
  8. package/dist/adt/devtools.js.map +1 -1
  9. package/dist/adt/diagnostics.d.ts +21 -1
  10. package/dist/adt/diagnostics.d.ts.map +1 -1
  11. package/dist/adt/diagnostics.js +72 -0
  12. package/dist/adt/diagnostics.js.map +1 -1
  13. package/dist/adt/fm-signature.d.ts +77 -0
  14. package/dist/adt/fm-signature.d.ts.map +1 -0
  15. package/dist/adt/fm-signature.js +343 -0
  16. package/dist/adt/fm-signature.js.map +1 -0
  17. package/dist/adt/http.d.ts +9 -1
  18. package/dist/adt/http.d.ts.map +1 -1
  19. package/dist/adt/http.js +8 -7
  20. package/dist/adt/http.js.map +1 -1
  21. package/dist/adt/rap-generate.d.ts +110 -0
  22. package/dist/adt/rap-generate.d.ts.map +1 -0
  23. package/dist/adt/rap-generate.js +262 -0
  24. package/dist/adt/rap-generate.js.map +1 -0
  25. package/dist/adt/rap-handlers.d.ts +14 -0
  26. package/dist/adt/rap-handlers.d.ts.map +1 -1
  27. package/dist/adt/rap-handlers.js +96 -9
  28. package/dist/adt/rap-handlers.js.map +1 -1
  29. package/dist/adt/types.d.ts +73 -1
  30. package/dist/adt/types.d.ts.map +1 -1
  31. package/dist/adt/xml-parser.d.ts.map +1 -1
  32. package/dist/adt/xml-parser.js +14 -0
  33. package/dist/adt/xml-parser.js.map +1 -1
  34. package/dist/authz/policy.d.ts.map +1 -1
  35. package/dist/authz/policy.js +9 -0
  36. package/dist/authz/policy.js.map +1 -1
  37. package/dist/context/method-surgery.d.ts +27 -0
  38. package/dist/context/method-surgery.d.ts.map +1 -1
  39. package/dist/context/method-surgery.js +104 -7
  40. package/dist/context/method-surgery.js.map +1 -1
  41. package/dist/handlers/intent.d.ts +20 -0
  42. package/dist/handlers/intent.d.ts.map +1 -1
  43. package/dist/handlers/intent.js +729 -71
  44. package/dist/handlers/intent.js.map +1 -1
  45. package/dist/handlers/schemas.d.ts +111 -3
  46. package/dist/handlers/schemas.d.ts.map +1 -1
  47. package/dist/handlers/schemas.js +163 -11
  48. package/dist/handlers/schemas.js.map +1 -1
  49. package/dist/handlers/tools.d.ts.map +1 -1
  50. package/dist/handlers/tools.js +152 -33
  51. package/dist/handlers/tools.js.map +1 -1
  52. package/dist/server/config.d.ts.map +1 -1
  53. package/dist/server/config.js +1 -0
  54. package/dist/server/config.js.map +1 -1
  55. package/dist/server/server.d.ts +1 -1
  56. package/dist/server/server.js +1 -1
  57. package/dist/server/types.d.ts +2 -0
  58. package/dist/server/types.d.ts.map +1 -1
  59. package/dist/server/types.js.map +1 -1
  60. package/package.json +1 -2
@@ -0,0 +1,110 @@
1
+ /**
2
+ * High-level RAP behavior pool generator (PR-C / SAPWrite generate_behavior_implementation).
3
+ *
4
+ * One-shot equivalent of Eclipse ADT's "Generate Behavior Implementation"
5
+ * Cmd+1 quickfix on a behavior pool class. Composes existing capabilities:
6
+ *
7
+ * 1. parseClassMetadata.rootEntityRef — auto-discover the bound BDEF
8
+ * 2. extractRapHandlerRequirements — derive every required handler method
9
+ * 3. applyRapHandlerScaffold — auto-create lhc_<alias> skeletons,
10
+ * inject signatures + empty stubs
11
+ * 4. updateSource (per include URL) — write CCDEF + CCIMP under one lock
12
+ * 5. activateBatch — optional final activation
13
+ *
14
+ * This avoids the broken `/sap/bc/adt/quickfixes/proposals/.../create_class_implementation`
15
+ * server endpoint (HTTP 500 on a4h regardless of payload — verified live during research).
16
+ * Local generation is deterministic, fully unit-testable, and reuses the proven PR #257
17
+ * include-write path.
18
+ *
19
+ * Inputs:
20
+ * className — the behavior pool class (e.g. "ZBP_DM_PROJECT")
21
+ * options.bdefName — explicit BDEF override; default is auto-discovery from rootEntityRef
22
+ * options.targetAlias — restrict scaffold to one entity alias (case-insensitive)
23
+ * options.activate — also run SAPActivate after writing (default true)
24
+ * options.dryRun — preview without writing/activating (default false)
25
+ *
26
+ * Output:
27
+ * `RapGenerateResult` carries the discovery, validation, scaffold, and activation
28
+ * outcomes. Activation failures matching the "stale active CCDEF/CCIMP placeholder
29
+ * + new inactive content" coupling DO NOT throw — they return `activation.success=false`
30
+ * with a guided `hint` so the caller can surface the recovery path. Other activation
31
+ * failures rethrow.
32
+ */
33
+ import type { AdtClient } from './client.js';
34
+ import { type RapHandlerRequirement } from './rap-handlers.js';
35
+ /** Options for `generateBehaviorImplementation`. */
36
+ export interface RapGenerateOptions {
37
+ /** Explicit BDEF name (overrides rootEntityRef auto-discovery). */
38
+ bdefName?: string;
39
+ /** Restrict scaffold to a single entity alias (case-insensitive). */
40
+ targetAlias?: string;
41
+ /** Also run `SAPActivate` on the class after writing (default `true`). */
42
+ activate?: boolean;
43
+ /** Preview the plan without writing or activating (default `false`). */
44
+ dryRun?: boolean;
45
+ /** Optional transport request to attribute writes to. */
46
+ transport?: string;
47
+ }
48
+ /** Discovery + validation diagnostics. */
49
+ export interface RapGenerateDiscovery {
50
+ className: string;
51
+ bdefName: string;
52
+ /** Where the BDEF name came from. */
53
+ source: 'rootEntityRef' | 'explicit';
54
+ /** Class metadata category (must be `behaviorPool`). */
55
+ classCategory: string;
56
+ }
57
+ export interface RapGenerateValidation {
58
+ /** MAIN source contains a `FOR BEHAVIOR OF <bdef>` clause that points at the discovered BDEF. */
59
+ mainHasForBehaviorOf: boolean;
60
+ /** BDEF source contains `managed implementation in class <className>` (or `unmanaged …`) bound to the class. */
61
+ bdefBindsClass: boolean;
62
+ /** Free-text reason when one of the cross-references doesn't match. */
63
+ mismatchReason?: string;
64
+ }
65
+ export interface RapGenerateActivation {
66
+ success: boolean;
67
+ /** Human-friendly recovery hint when `success === false` for a known soft-failure mode. */
68
+ hint?: string;
69
+ /** Activation messages from SAP (errors + warnings + info). */
70
+ messages?: string[];
71
+ }
72
+ export interface RapGenerateResult {
73
+ discovery: RapGenerateDiscovery;
74
+ validation: RapGenerateValidation;
75
+ /** Whether any include source actually changed during scaffolding. */
76
+ scaffoldChanged: boolean;
77
+ /** Sections updated by the scaffold (e.g. ['definitions', 'implementations']). */
78
+ changedSections: Array<'main' | 'definitions' | 'implementations'>;
79
+ /** Counts by category for telemetry / talk demos. */
80
+ inserted: {
81
+ signatures: number;
82
+ stubs: number;
83
+ autoCreatedSkeletons: number;
84
+ };
85
+ /** Required handlers parsed out of the BDEF (post `targetAlias` filter). */
86
+ required: RapHandlerRequirement[];
87
+ /** Activation report; absent when `activate=false` or when scaffold made no changes. */
88
+ activation?: RapGenerateActivation;
89
+ /** Echoes the `dryRun` request flag for caller convenience. */
90
+ dryRun: boolean;
91
+ }
92
+ /**
93
+ * Classify a `generate_behavior_implementation` outcome as MCP success vs error.
94
+ *
95
+ * The orchestrator never throws on activation failure — it returns a structured
96
+ * result so the caller can see what was scaffolded. The handler then decides
97
+ * which MCP result code to surface. See Codex review on PR #260 (P1):
98
+ * - activation absent (dryRun / activate=false / no scaffold change + no activation) → success
99
+ * - activation.success === true → success
100
+ * - activation.success === false WITH hint (e.g. stale-active CCDEF coupling) → success
101
+ * (the source is correct; the user follows the recovery path)
102
+ * - activation.success === false WITHOUT hint → error (real compile failure)
103
+ */
104
+ export declare function isRapGenerateResultSuccess(result: RapGenerateResult): boolean;
105
+ /**
106
+ * Run the high-level "Generate Behavior Implementation" flow against a
107
+ * behavior pool class. See module-level docs for the contract.
108
+ */
109
+ export declare function generateBehaviorImplementation(client: AdtClient, className: string, options?: RapGenerateOptions): Promise<RapGenerateResult>;
110
+ //# sourceMappingURL=rap-generate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rap-generate.d.ts","sourceRoot":"","sources":["../../src/adt/rap-generate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAI7C,OAAO,EAKL,KAAK,qBAAqB,EAC3B,MAAM,mBAAmB,CAAC;AAE3B,oDAAoD;AACpD,MAAM,WAAW,kBAAkB;IACjC,mEAAmE;IACnE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,wEAAwE;IACxE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,0CAA0C;AAC1C,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,qCAAqC;IACrC,MAAM,EAAE,eAAe,GAAG,UAAU,CAAC;IACrC,wDAAwD;IACxD,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,qBAAqB;IACpC,iGAAiG;IACjG,oBAAoB,EAAE,OAAO,CAAC;IAC9B,gHAAgH;IAChH,cAAc,EAAE,OAAO,CAAC;IACxB,uEAAuE;IACvE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,2FAA2F;IAC3F,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,oBAAoB,CAAC;IAChC,UAAU,EAAE,qBAAqB,CAAC;IAClC,sEAAsE;IACtE,eAAe,EAAE,OAAO,CAAC;IACzB,kFAAkF;IAClF,eAAe,EAAE,KAAK,CAAC,MAAM,GAAG,aAAa,GAAG,iBAAiB,CAAC,CAAC;IACnE,qDAAqD;IACrD,QAAQ,EAAE;QACR,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,oBAAoB,EAAE,MAAM,CAAC;KAC9B,CAAC;IACF,4EAA4E;IAC5E,QAAQ,EAAE,qBAAqB,EAAE,CAAC;IAClC,wFAAwF;IACxF,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,+DAA+D;IAC/D,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAI7E;AA8CD;;;GAGG;AACH,wBAAsB,8BAA8B,CAClD,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,iBAAiB,CAAC,CAiN5B"}
@@ -0,0 +1,262 @@
1
+ /**
2
+ * High-level RAP behavior pool generator (PR-C / SAPWrite generate_behavior_implementation).
3
+ *
4
+ * One-shot equivalent of Eclipse ADT's "Generate Behavior Implementation"
5
+ * Cmd+1 quickfix on a behavior pool class. Composes existing capabilities:
6
+ *
7
+ * 1. parseClassMetadata.rootEntityRef — auto-discover the bound BDEF
8
+ * 2. extractRapHandlerRequirements — derive every required handler method
9
+ * 3. applyRapHandlerScaffold — auto-create lhc_<alias> skeletons,
10
+ * inject signatures + empty stubs
11
+ * 4. updateSource (per include URL) — write CCDEF + CCIMP under one lock
12
+ * 5. activateBatch — optional final activation
13
+ *
14
+ * This avoids the broken `/sap/bc/adt/quickfixes/proposals/.../create_class_implementation`
15
+ * server endpoint (HTTP 500 on a4h regardless of payload — verified live during research).
16
+ * Local generation is deterministic, fully unit-testable, and reuses the proven PR #257
17
+ * include-write path.
18
+ *
19
+ * Inputs:
20
+ * className — the behavior pool class (e.g. "ZBP_DM_PROJECT")
21
+ * options.bdefName — explicit BDEF override; default is auto-discovery from rootEntityRef
22
+ * options.targetAlias — restrict scaffold to one entity alias (case-insensitive)
23
+ * options.activate — also run SAPActivate after writing (default true)
24
+ * options.dryRun — preview without writing/activating (default false)
25
+ *
26
+ * Output:
27
+ * `RapGenerateResult` carries the discovery, validation, scaffold, and activation
28
+ * outcomes. Activation failures matching the "stale active CCDEF/CCIMP placeholder
29
+ * + new inactive content" coupling DO NOT throw — they return `activation.success=false`
30
+ * with a guided `hint` so the caller can surface the recovery path. Other activation
31
+ * failures rethrow.
32
+ */
33
+ import { lockObject, unlockObject, updateSource } from './crud.js';
34
+ import { activateBatch } from './devtools.js';
35
+ import { AdtApiError, AdtSafetyError } from './errors.js';
36
+ import { applyRapHandlerScaffold, extractRapHandlerRequirements, findMissingRapHandlerImplementationStubs, findMissingRapHandlerRequirements, } from './rap-handlers.js';
37
+ /**
38
+ * Classify a `generate_behavior_implementation` outcome as MCP success vs error.
39
+ *
40
+ * The orchestrator never throws on activation failure — it returns a structured
41
+ * result so the caller can see what was scaffolded. The handler then decides
42
+ * which MCP result code to surface. See Codex review on PR #260 (P1):
43
+ * - activation absent (dryRun / activate=false / no scaffold change + no activation) → success
44
+ * - activation.success === true → success
45
+ * - activation.success === false WITH hint (e.g. stale-active CCDEF coupling) → success
46
+ * (the source is correct; the user follows the recovery path)
47
+ * - activation.success === false WITHOUT hint → error (real compile failure)
48
+ */
49
+ export function isRapGenerateResultSuccess(result) {
50
+ if (!result.activation)
51
+ return true;
52
+ if (result.activation.success)
53
+ return true;
54
+ return Boolean(result.activation.hint);
55
+ }
56
+ /**
57
+ * Recovery hint for the well-known "stale active CCDEF/CCIMP placeholder + new
58
+ * inactive handlers" activation rejection. Surfaced verbatim when SAP returns
59
+ * `Local classes of "CL_ABAP_BEHAVIOR_HANDLER" can only be derived in the
60
+ * "Local Definitions/Implementations" of a global BEHAVIOR class`. The hint is
61
+ * intentionally specific — generic "try Eclipse" advice would not unblock the
62
+ * SEGW→RAP migration skill.
63
+ */
64
+ const STALE_ACTIVE_HINT = 'Activation rejected with the well-known "Local classes of CL_ABAP_BEHAVIOR_HANDLER…" error. ' +
65
+ 'This typically means the active CCDEF/CCIMP for this class are still SAP placeholder comments ' +
66
+ 'while the inactive copies now contain real handlers, and RAP refuses the inactive→active transition. ' +
67
+ 'Recovery options: (a) activate the class once via Eclipse "Generate Behavior Implementation" wizard ' +
68
+ '(it bypasses this coupling), or (b) delete and recreate the class via SAPWrite(action="delete", type="CLAS") ' +
69
+ 'followed by SAPWrite(action="create", type="CLAS", …) and rerun generate_behavior_implementation against ' +
70
+ 'the freshly created class. The just-written CCDEF/CCIMP source is correct and reusable in both recovery paths.';
71
+ /** Build the include URL for CCDEF/CCIMP/macros/testclasses (mirror of intent.ts:classIncludeUrl). */
72
+ function classIncludeUrlFor(name, include) {
73
+ return `/sap/bc/adt/oo/classes/${encodeURIComponent(name)}/includes/${include}`;
74
+ }
75
+ function classObjectUrl(name) {
76
+ return `/sap/bc/adt/oo/classes/${encodeURIComponent(name)}`;
77
+ }
78
+ function classMainSourceUrl(name) {
79
+ return `${classObjectUrl(name)}/source/main`;
80
+ }
81
+ const FOR_BEHAVIOR_OF_RE = /\bfor\s+behavior\s+of\s+(\w+)/i;
82
+ const MANAGED_IMPL_RE = /\b(?:managed|unmanaged|projection)\s+implementation\s+in\s+class\s+(\w+)\s+unique\b/i;
83
+ /**
84
+ * "Local classes of CL_ABAP_BEHAVIOR_HANDLER…" is the activation rejection that
85
+ * happens when the active CCDEF/CCIMP placeholders are out of sync with the new
86
+ * inactive content. We recognize it by the stable English fragment SAP emits in
87
+ * the activation message body — the message text is identical across 7.50 and
88
+ * 7.58 (verified live during PR-C research, 2026-05-10).
89
+ */
90
+ const STALE_ACTIVE_RE = /local classes of\s+["']?cl_abap_behavior_handler["']?\s+can\s+only\s+be\s+derived/i;
91
+ /**
92
+ * Run the high-level "Generate Behavior Implementation" flow against a
93
+ * behavior pool class. See module-level docs for the contract.
94
+ */
95
+ export async function generateBehaviorImplementation(client, className, options = {}) {
96
+ const dryRun = options.dryRun === true;
97
+ const activateRequested = options.activate !== false; // default true
98
+ const targetAlias = (options.targetAlias ?? '').trim().toLowerCase();
99
+ const transport = options.transport;
100
+ if (!className?.trim()) {
101
+ throw new AdtSafetyError('generate_behavior_implementation: className is required.');
102
+ }
103
+ const cleanClassName = className.trim();
104
+ // ── Phase 1: discovery ────────────────────────────────────────────────
105
+ const metadata = await client.getClassMetadata(cleanClassName);
106
+ if (metadata.category !== 'behaviorPool') {
107
+ throw new AdtSafetyError(`generate_behavior_implementation: class ${cleanClassName} is not a RAP behavior pool ` +
108
+ `(class:category=${metadata.category || '<empty>'}). The action only operates on classes ` +
109
+ `marked behaviorPool. Create the class via SAPWrite(action="create", type="CLAS") with a ` +
110
+ `'CLASS … FOR BEHAVIOR OF <bdef>' DEFINITION header and ensure the BDEF is active first.`);
111
+ }
112
+ const explicitBdef = options.bdefName?.trim();
113
+ let bdefName = explicitBdef ?? metadata.rootEntityRef?.name ?? '';
114
+ const discoverySource = explicitBdef ? 'explicit' : 'rootEntityRef';
115
+ if (!bdefName) {
116
+ throw new AdtSafetyError(`generate_behavior_implementation: cannot auto-discover BDEF for ${cleanClassName} — ` +
117
+ `class metadata has no rootEntityRef. Pass an explicit "bdefName" parameter to override.`);
118
+ }
119
+ bdefName = bdefName.toUpperCase();
120
+ // ── Phase 2: read sources + cross-validate ────────────────────────────
121
+ const structured = await client.getClassStructured(cleanClassName);
122
+ const mainSource = structured.main ?? '';
123
+ const definitionsSource = structured.definitions ?? '';
124
+ const implementationsSource = structured.implementations ?? '';
125
+ const bdefRead = await client.getBdef(bdefName);
126
+ const bdefSource = bdefRead.source;
127
+ const mainBdefMatch = FOR_BEHAVIOR_OF_RE.exec(mainSource);
128
+ const bdefClassMatch = MANAGED_IMPL_RE.exec(bdefSource);
129
+ const mainBdefRef = mainBdefMatch?.[1]?.toUpperCase();
130
+ const bdefClassRef = bdefClassMatch?.[1]?.toUpperCase();
131
+ const validation = {
132
+ mainHasForBehaviorOf: Boolean(mainBdefRef),
133
+ bdefBindsClass: Boolean(bdefClassRef),
134
+ };
135
+ const mismatches = [];
136
+ if (!mainBdefRef) {
137
+ mismatches.push(`MAIN source for ${cleanClassName} does not contain "FOR BEHAVIOR OF <bdef>"`);
138
+ }
139
+ else if (mainBdefRef !== bdefName) {
140
+ mismatches.push(`MAIN binds BDEF ${mainBdefRef} but discovery resolved to ${bdefName}`);
141
+ }
142
+ if (!bdefClassRef) {
143
+ mismatches.push(`BDEF ${bdefName} does not contain "managed implementation in class <class> unique"`);
144
+ }
145
+ else if (bdefClassRef !== cleanClassName.toUpperCase()) {
146
+ mismatches.push(`BDEF ${bdefName} binds class ${bdefClassRef} but we are generating for ${cleanClassName}`);
147
+ }
148
+ if (mismatches.length > 0) {
149
+ validation.mismatchReason = mismatches.join('; ');
150
+ }
151
+ if (validation.mismatchReason && !dryRun) {
152
+ throw new AdtSafetyError(`generate_behavior_implementation: cross-reference validation failed (${validation.mismatchReason}). ` +
153
+ `Refusing to mutate. Re-run with dryRun=true to inspect the report and fix the source files first.`);
154
+ }
155
+ // ── Phase 3: scaffold plan ────────────────────────────────────────────
156
+ let requirements = extractRapHandlerRequirements(bdefSource);
157
+ if (targetAlias) {
158
+ requirements = requirements.filter((req) => req.entityAlias.toLowerCase() === targetAlias);
159
+ }
160
+ const combinedSource = [mainSource, definitionsSource, implementationsSource].filter(Boolean).join('\n\n');
161
+ const missingSignatures = findMissingRapHandlerRequirements(requirements, combinedSource);
162
+ const missingStubs = findMissingRapHandlerImplementationStubs(requirements, combinedSource);
163
+ const scaffoldPlan = applyRapHandlerScaffold({
164
+ main: mainSource,
165
+ definitions: definitionsSource || undefined,
166
+ implementations: implementationsSource || undefined,
167
+ }, missingSignatures, missingStubs);
168
+ const result = {
169
+ discovery: {
170
+ className: cleanClassName,
171
+ bdefName,
172
+ source: discoverySource,
173
+ classCategory: metadata.category,
174
+ },
175
+ validation,
176
+ scaffoldChanged: scaffoldPlan.changedSections.length > 0,
177
+ changedSections: scaffoldPlan.changedSections.filter((section) => section === 'main' || section === 'definitions' || section === 'implementations'),
178
+ inserted: {
179
+ signatures: scaffoldPlan.insertedSignatureCount,
180
+ stubs: scaffoldPlan.insertedImplementationStubCount,
181
+ autoCreatedSkeletons: (scaffoldPlan.skeletons?.createdDefinitions.length ?? 0) +
182
+ (scaffoldPlan.skeletons?.createdImplementations.length ?? 0),
183
+ },
184
+ required: requirements,
185
+ dryRun,
186
+ };
187
+ // Dry-run short-circuits before any side effects.
188
+ if (dryRun) {
189
+ return result;
190
+ }
191
+ const objectUrl = classObjectUrl(cleanClassName);
192
+ // ── Phase 4: write (only when scaffold has changes) ───────────────────
193
+ // When scaffoldChanged=false, all handlers are already in place — skip the
194
+ // lock+write cycle entirely. Activation still runs below if requested, because
195
+ // a populated-but-inactive class is a realistic rerun/recovery state after
196
+ // earlier manual include writes (Codex review note on PR #260).
197
+ if (result.scaffoldChanged) {
198
+ await client.http.withStatefulSession(async (session) => {
199
+ const lock = await lockObject(session, client.safety, objectUrl, 'MODIFY');
200
+ const effectiveTransport = transport ?? (lock.corrNr || undefined);
201
+ try {
202
+ if (scaffoldPlan.changed.main && scaffoldPlan.sections.main !== mainSource) {
203
+ await updateSource(session, client.safety, classMainSourceUrl(cleanClassName), scaffoldPlan.sections.main, lock.lockHandle, effectiveTransport);
204
+ }
205
+ if (scaffoldPlan.changed.definitions && scaffoldPlan.sections.definitions) {
206
+ await updateSource(session, client.safety, classIncludeUrlFor(cleanClassName, 'definitions'), scaffoldPlan.sections.definitions, lock.lockHandle, effectiveTransport);
207
+ }
208
+ if (scaffoldPlan.changed.implementations && scaffoldPlan.sections.implementations) {
209
+ await updateSource(session, client.safety, classIncludeUrlFor(cleanClassName, 'implementations'), scaffoldPlan.sections.implementations, lock.lockHandle, effectiveTransport);
210
+ }
211
+ }
212
+ finally {
213
+ try {
214
+ await unlockObject(session, objectUrl, lock.lockHandle);
215
+ }
216
+ catch {
217
+ // best-effort-cleanup: surface the original error, not an unlock failure
218
+ }
219
+ }
220
+ });
221
+ }
222
+ // ── Phase 5: optional activation ──────────────────────────────────────
223
+ if (activateRequested) {
224
+ try {
225
+ const activationOutcome = await activateBatch(client.http, client.safety, [
226
+ { url: objectUrl, name: cleanClassName },
227
+ ]);
228
+ const detailMessages = (activationOutcome.details ?? []).map((d) => d.text).filter(Boolean);
229
+ const allMessages = [...(activationOutcome.messages ?? []), ...detailMessages];
230
+ if (activationOutcome.success) {
231
+ result.activation = { success: true, messages: allMessages };
232
+ }
233
+ else {
234
+ const matchedStaleActive = allMessages.some((msg) => STALE_ACTIVE_RE.test(msg));
235
+ result.activation = {
236
+ success: false,
237
+ messages: allMessages,
238
+ hint: matchedStaleActive ? STALE_ACTIVE_HINT : undefined,
239
+ };
240
+ }
241
+ }
242
+ catch (err) {
243
+ // The activateBatch path normally returns a result rather than throwing,
244
+ // but RAP-not-available / network errors / safety errors propagate. The
245
+ // stale-active soft-failure is detected via message inspection above.
246
+ // For unrecognised errors we attach the source-of-truth error message but
247
+ // keep the result structure so callers can still see the scaffold report.
248
+ if (err instanceof AdtApiError && STALE_ACTIVE_RE.test(err.message)) {
249
+ result.activation = {
250
+ success: false,
251
+ messages: [err.message],
252
+ hint: STALE_ACTIVE_HINT,
253
+ };
254
+ }
255
+ else {
256
+ throw err;
257
+ }
258
+ }
259
+ }
260
+ return result;
261
+ }
262
+ //# sourceMappingURL=rap-generate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rap-generate.js","sourceRoot":"","sources":["../../src/adt/rap-generate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAGH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EACL,uBAAuB,EACvB,6BAA6B,EAC7B,wCAAwC,EACxC,iCAAiC,GAElC,MAAM,mBAAmB,CAAC;AAgE3B;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,0BAA0B,CAAC,MAAyB;IAClE,IAAI,CAAC,MAAM,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IACpC,IAAI,MAAM,CAAC,UAAU,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC3C,OAAO,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,iBAAiB,GACrB,8FAA8F;IAC9F,gGAAgG;IAChG,uGAAuG;IACvG,sGAAsG;IACtG,+GAA+G;IAC/G,2GAA2G;IAC3G,gHAAgH,CAAC;AAEnH,sGAAsG;AACtG,SAAS,kBAAkB,CACzB,IAAY,EACZ,OAAqE;IAErE,OAAO,0BAA0B,kBAAkB,CAAC,IAAI,CAAC,aAAa,OAAO,EAAE,CAAC;AAClF,CAAC;AAED,SAAS,cAAc,CAAC,IAAY;IAClC,OAAO,0BAA0B,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;AAC9D,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAY;IACtC,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,cAAc,CAAC;AAC/C,CAAC;AAED,MAAM,kBAAkB,GAAG,gCAAgC,CAAC;AAC5D,MAAM,eAAe,GAAG,sFAAsF,CAAC;AAC/G;;;;;;GAMG;AACH,MAAM,eAAe,GAAG,oFAAoF,CAAC;AAE7G;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAClD,MAAiB,EACjB,SAAiB,EACjB,UAA8B,EAAE;IAEhC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,KAAK,IAAI,CAAC;IACvC,MAAM,iBAAiB,GAAG,OAAO,CAAC,QAAQ,KAAK,KAAK,CAAC,CAAC,eAAe;IACrE,MAAM,WAAW,GAAG,CAAC,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrE,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IAEpC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC;QACvB,MAAM,IAAI,cAAc,CAAC,0DAA0D,CAAC,CAAC;IACvF,CAAC;IACD,MAAM,cAAc,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;IAExC,yEAAyE;IACzE,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC;IAC/D,IAAI,QAAQ,CAAC,QAAQ,KAAK,cAAc,EAAE,CAAC;QACzC,MAAM,IAAI,cAAc,CACtB,2CAA2C,cAAc,8BAA8B;YACrF,mBAAmB,QAAQ,CAAC,QAAQ,IAAI,SAAS,yCAAyC;YAC1F,0FAA0F;YAC1F,yFAAyF,CAC5F,CAAC;IACJ,CAAC;IAED,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC9C,IAAI,QAAQ,GAAG,YAAY,IAAI,QAAQ,CAAC,aAAa,EAAE,IAAI,IAAI,EAAE,CAAC;IAClE,MAAM,eAAe,GAAiC,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC;IAClG,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,cAAc,CACtB,mEAAmE,cAAc,KAAK;YACpF,yFAAyF,CAC5F,CAAC;IACJ,CAAC;IACD,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IAElC,yEAAyE;IACzE,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC;IACnE,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,IAAI,EAAE,CAAC;IACzC,MAAM,iBAAiB,GAAG,UAAU,CAAC,WAAW,IAAI,EAAE,CAAC;IACvD,MAAM,qBAAqB,GAAG,UAAU,CAAC,eAAe,IAAI,EAAE,CAAC;IAC/D,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAChD,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC;IAEnC,MAAM,aAAa,GAAG,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC1D,MAAM,cAAc,GAAG,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACxD,MAAM,WAAW,GAAG,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;IACtD,MAAM,YAAY,GAAG,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;IAExD,MAAM,UAAU,GAA0B;QACxC,oBAAoB,EAAE,OAAO,CAAC,WAAW,CAAC;QAC1C,cAAc,EAAE,OAAO,CAAC,YAAY,CAAC;KACtC,CAAC;IACF,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,UAAU,CAAC,IAAI,CAAC,mBAAmB,cAAc,4CAA4C,CAAC,CAAC;IACjG,CAAC;SAAM,IAAI,WAAW,KAAK,QAAQ,EAAE,CAAC;QACpC,UAAU,CAAC,IAAI,CAAC,mBAAmB,WAAW,8BAA8B,QAAQ,EAAE,CAAC,CAAC;IAC1F,CAAC;IACD,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,UAAU,CAAC,IAAI,CAAC,QAAQ,QAAQ,oEAAoE,CAAC,CAAC;IACxG,CAAC;SAAM,IAAI,YAAY,KAAK,cAAc,CAAC,WAAW,EAAE,EAAE,CAAC;QACzD,UAAU,CAAC,IAAI,CAAC,QAAQ,QAAQ,gBAAgB,YAAY,8BAA8B,cAAc,EAAE,CAAC,CAAC;IAC9G,CAAC;IACD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,UAAU,CAAC,cAAc,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpD,CAAC;IACD,IAAI,UAAU,CAAC,cAAc,IAAI,CAAC,MAAM,EAAE,CAAC;QACzC,MAAM,IAAI,cAAc,CACtB,wEAAwE,UAAU,CAAC,cAAc,KAAK;YACpG,mGAAmG,CACtG,CAAC;IACJ,CAAC;IAED,yEAAyE;IACzE,IAAI,YAAY,GAAG,6BAA6B,CAAC,UAAU,CAAC,CAAC;IAC7D,IAAI,WAAW,EAAE,CAAC;QAChB,YAAY,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,WAAW,EAAE,KAAK,WAAW,CAAC,CAAC;IAC7F,CAAC;IAED,MAAM,cAAc,GAAG,CAAC,UAAU,EAAE,iBAAiB,EAAE,qBAAqB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3G,MAAM,iBAAiB,GAAG,iCAAiC,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;IAC1F,MAAM,YAAY,GAAG,wCAAwC,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;IAE5F,MAAM,YAAY,GAAG,uBAAuB,CAC1C;QACE,IAAI,EAAE,UAAU;QAChB,WAAW,EAAE,iBAAiB,IAAI,SAAS;QAC3C,eAAe,EAAE,qBAAqB,IAAI,SAAS;KACpD,EACD,iBAAiB,EACjB,YAAY,CACb,CAAC;IAEF,MAAM,MAAM,GAAsB;QAChC,SAAS,EAAE;YACT,SAAS,EAAE,cAAc;YACzB,QAAQ;YACR,MAAM,EAAE,eAAe;YACvB,aAAa,EAAE,QAAQ,CAAC,QAAQ;SACjC;QACD,UAAU;QACV,eAAe,EAAE,YAAY,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC;QACxD,eAAe,EAAE,YAAY,CAAC,eAAe,CAAC,MAAM,CAClD,CAAC,OAAO,EAAyD,EAAE,CACjE,OAAO,KAAK,MAAM,IAAI,OAAO,KAAK,aAAa,IAAI,OAAO,KAAK,iBAAiB,CACnF;QACD,QAAQ,EAAE;YACR,UAAU,EAAE,YAAY,CAAC,sBAAsB;YAC/C,KAAK,EAAE,YAAY,CAAC,+BAA+B;YACnD,oBAAoB,EAClB,CAAC,YAAY,CAAC,SAAS,EAAE,kBAAkB,CAAC,MAAM,IAAI,CAAC,CAAC;gBACxD,CAAC,YAAY,CAAC,SAAS,EAAE,sBAAsB,CAAC,MAAM,IAAI,CAAC,CAAC;SAC/D;QACD,QAAQ,EAAE,YAAY;QACtB,MAAM;KACP,CAAC;IAEF,kDAAkD;IAClD,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,SAAS,GAAG,cAAc,CAAC,cAAc,CAAC,CAAC;IAEjD,yEAAyE;IACzE,2EAA2E;IAC3E,+EAA+E;IAC/E,2EAA2E;IAC3E,gEAAgE;IAChE,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;QAC3B,MAAM,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;YACtD,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;YAC3E,MAAM,kBAAkB,GAAG,SAAS,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,SAAS,CAAC,CAAC;YACnE,IAAI,CAAC;gBACH,IAAI,YAAY,CAAC,OAAO,CAAC,IAAI,IAAI,YAAY,CAAC,QAAQ,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;oBAC3E,MAAM,YAAY,CAChB,OAAO,EACP,MAAM,CAAC,MAAM,EACb,kBAAkB,CAAC,cAAc,CAAC,EAClC,YAAY,CAAC,QAAQ,CAAC,IAAI,EAC1B,IAAI,CAAC,UAAU,EACf,kBAAkB,CACnB,CAAC;gBACJ,CAAC;gBACD,IAAI,YAAY,CAAC,OAAO,CAAC,WAAW,IAAI,YAAY,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;oBAC1E,MAAM,YAAY,CAChB,OAAO,EACP,MAAM,CAAC,MAAM,EACb,kBAAkB,CAAC,cAAc,EAAE,aAAa,CAAC,EACjD,YAAY,CAAC,QAAQ,CAAC,WAAW,EACjC,IAAI,CAAC,UAAU,EACf,kBAAkB,CACnB,CAAC;gBACJ,CAAC;gBACD,IAAI,YAAY,CAAC,OAAO,CAAC,eAAe,IAAI,YAAY,CAAC,QAAQ,CAAC,eAAe,EAAE,CAAC;oBAClF,MAAM,YAAY,CAChB,OAAO,EACP,MAAM,CAAC,MAAM,EACb,kBAAkB,CAAC,cAAc,EAAE,iBAAiB,CAAC,EACrD,YAAY,CAAC,QAAQ,CAAC,eAAe,EACrC,IAAI,CAAC,UAAU,EACf,kBAAkB,CACnB,CAAC;gBACJ,CAAC;YACH,CAAC;oBAAS,CAAC;gBACT,IAAI,CAAC;oBACH,MAAM,YAAY,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;gBAC1D,CAAC;gBAAC,MAAM,CAAC;oBACP,yEAAyE;gBAC3E,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,yEAAyE;IACzE,IAAI,iBAAiB,EAAE,CAAC;QACtB,IAAI,CAAC;YACH,MAAM,iBAAiB,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE;gBACxE,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,cAAc,EAAE;aACzC,CAAC,CAAC;YACH,MAAM,cAAc,GAAG,CAAC,iBAAiB,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAC5F,MAAM,WAAW,GAAG,CAAC,GAAG,CAAC,iBAAiB,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,GAAG,cAAc,CAAC,CAAC;YAC/E,IAAI,iBAAiB,CAAC,OAAO,EAAE,CAAC;gBAC9B,MAAM,CAAC,UAAU,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;YAC/D,CAAC;iBAAM,CAAC;gBACN,MAAM,kBAAkB,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;gBAChF,MAAM,CAAC,UAAU,GAAG;oBAClB,OAAO,EAAE,KAAK;oBACd,QAAQ,EAAE,WAAW;oBACrB,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,SAAS;iBACzD,CAAC;YACJ,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,yEAAyE;YACzE,wEAAwE;YACxE,sEAAsE;YACtE,0EAA0E;YAC1E,0EAA0E;YAC1E,IAAI,GAAG,YAAY,WAAW,IAAI,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBACpE,MAAM,CAAC,UAAU,GAAG;oBAClB,OAAO,EAAE,KAAK;oBACd,QAAQ,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC;oBACvB,IAAI,EAAE,iBAAiB;iBACxB,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -60,6 +60,12 @@ export interface RapHandlerSectionApplyResults {
60
60
  }
61
61
  export interface RapHandlerScaffoldPlan {
62
62
  sections: RapHandlerSourceSections;
63
+ skeletons: {
64
+ createdDefinitions: string[];
65
+ createdImplementations: string[];
66
+ changed: Record<RapHandlerSectionName, boolean>;
67
+ changedSections: RapHandlerSectionName[];
68
+ };
63
69
  signatures: RapHandlerSectionApplyResults;
64
70
  implementationStubs: RapHandlerSectionApplyResults;
65
71
  unresolved: RapHandlerRequirement[];
@@ -68,6 +74,13 @@ export interface RapHandlerScaffoldPlan {
68
74
  insertedSignatureCount: number;
69
75
  insertedImplementationStubCount: number;
70
76
  }
77
+ export interface RapHandlerSkeletonResult {
78
+ sections: RapHandlerSourceSections;
79
+ createdDefinitions: string[];
80
+ createdImplementations: string[];
81
+ changed: Record<RapHandlerSectionName, boolean>;
82
+ changedSections: RapHandlerSectionName[];
83
+ }
71
84
  export declare function rapHandlerRequirementKey(requirement: RapHandlerRequirement): string;
72
85
  /**
73
86
  * Extract RAP behavior-pool handler method requirements from interface BDEF source.
@@ -145,6 +158,7 @@ export declare function applyRapHandlerImplementationStubs(classSource: string,
145
158
  createImplementationBlocks?: boolean;
146
159
  definitionSource?: string;
147
160
  }): RapHandlerApplyResult;
161
+ export declare function ensureRapHandlerSkeletons(sections: RapHandlerSourceSections, requirements: RapHandlerRequirement[]): RapHandlerSkeletonResult;
148
162
  /**
149
163
  * Build the complete auto-apply plan for a behavior pool without doing I/O.
150
164
  *
@@ -1 +1 @@
1
- {"version":3,"file":"rap-handlers.d.ts","sourceRoot":"","sources":["../../src/adt/rap-handlers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rap-handlers.d.ts","sourceRoot":"","sources":["../../src/adt/rap-handlers.ts"],"names":[],"mappings":"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"}
@@ -718,6 +718,82 @@ function countInserted(results) {
718
718
  function changedSectionsFrom(changed) {
719
719
  return Object.keys(changed).filter((section) => changed[section]);
720
720
  }
721
+ function uniqueRequirementsByTargetClass(requirements) {
722
+ const seen = new Set();
723
+ const out = [];
724
+ for (const requirement of requirements) {
725
+ const key = requirement.targetHandlerClass.toLowerCase();
726
+ if (seen.has(key))
727
+ continue;
728
+ seen.add(key);
729
+ out.push(requirement);
730
+ }
731
+ return out;
732
+ }
733
+ function hasClassDefinition(sections, targetHandlerClass) {
734
+ const target = targetHandlerClass.toLowerCase();
735
+ return [sections.main, sections.definitions, sections.implementations]
736
+ .filter(Boolean)
737
+ .some((source) => parseClassDefinitionRanges(source ?? '').some((range) => range.name.toLowerCase() === target));
738
+ }
739
+ function hasClassImplementation(sections, targetHandlerClass) {
740
+ const target = targetHandlerClass.toLowerCase();
741
+ return [sections.main, sections.definitions, sections.implementations]
742
+ .filter(Boolean)
743
+ .some((source) => parseClassImplementationRanges(source ?? '').some((range) => range.name.toLowerCase() === target));
744
+ }
745
+ function appendBlocksToSection(source, blocks) {
746
+ if (blocks.length === 0)
747
+ return source;
748
+ const blockText = blocks.join('\n\n');
749
+ if (!source || source.trim().length === 0)
750
+ return `${blockText}\n`;
751
+ const separator = source.endsWith('\n') ? (source.endsWith('\n\n') ? '' : '\n') : '\n\n';
752
+ return `${source}${separator}${blockText}\n`;
753
+ }
754
+ function handlerDefinitionSkeleton(targetHandlerClass) {
755
+ return `CLASS ${targetHandlerClass} DEFINITION INHERITING FROM cl_abap_behavior_handler.
756
+ PRIVATE SECTION.
757
+ ENDCLASS.`;
758
+ }
759
+ function handlerImplementationSkeleton(targetHandlerClass) {
760
+ return `CLASS ${targetHandlerClass} IMPLEMENTATION.
761
+ ENDCLASS.`;
762
+ }
763
+ export function ensureRapHandlerSkeletons(sections, requirements) {
764
+ const targetRequirements = uniqueRequirementsByTargetClass(requirements);
765
+ const definitionBlocks = [];
766
+ const implementationBlocks = [];
767
+ const createdDefinitions = [];
768
+ const createdImplementations = [];
769
+ for (const requirement of targetRequirements) {
770
+ const targetHandlerClass = requirement.targetHandlerClass;
771
+ if (!hasClassDefinition(sections, targetHandlerClass)) {
772
+ definitionBlocks.push(handlerDefinitionSkeleton(targetHandlerClass));
773
+ createdDefinitions.push(targetHandlerClass);
774
+ }
775
+ if (!hasClassImplementation(sections, targetHandlerClass)) {
776
+ implementationBlocks.push(handlerImplementationSkeleton(targetHandlerClass));
777
+ createdImplementations.push(targetHandlerClass);
778
+ }
779
+ }
780
+ const changed = {
781
+ main: false,
782
+ definitions: createdDefinitions.length > 0,
783
+ implementations: createdImplementations.length > 0,
784
+ };
785
+ return {
786
+ sections: {
787
+ main: sections.main,
788
+ definitions: appendBlocksToSection(sections.definitions, definitionBlocks),
789
+ implementations: appendBlocksToSection(sections.implementations, implementationBlocks),
790
+ },
791
+ createdDefinitions,
792
+ createdImplementations,
793
+ changed,
794
+ changedSections: changedSectionsFrom(changed),
795
+ };
796
+ }
721
797
  /**
722
798
  * Build the source used to resolve semantic method names while creating stubs.
723
799
  *
@@ -783,30 +859,35 @@ function applySignaturesAcrossSections(sections, missingSignatures) {
783
859
  * names come from declarations, not necessarily from BDEF action names".
784
860
  */
785
861
  export function applyRapHandlerScaffold(sections, missingSignatures, missingImplementationStubs) {
786
- const signaturePlan = applySignaturesAcrossSections(sections, missingSignatures);
862
+ const skeletonPlan = ensureRapHandlerSkeletons(sections, [...missingSignatures, ...missingImplementationStubs]);
863
+ const signaturePlan = applySignaturesAcrossSections(skeletonPlan.sections, missingSignatures);
787
864
  // A METHOD stub is only useful after its declaration exists. If the target
788
865
  // `lhc_*` class was not found anywhere, suppress the stub for that unresolved
789
866
  // declaration rather than creating an implementation block with no matching
790
867
  // RAP handler signature.
791
868
  const unresolvedDeclarationKeys = new Set(signaturePlan.unresolved.map(rapHandlerRequirementKey));
792
869
  const stubRequirements = missingImplementationStubs.filter((req) => !unresolvedDeclarationKeys.has(rapHandlerRequirementKey(req)));
793
- const definitionLookupSource = buildDefinitionLookupSource(sections, signaturePlan);
870
+ const definitionLookupSource = buildDefinitionLookupSource(skeletonPlan.sections, signaturePlan);
794
871
  const stubMain = applyRapHandlerImplementationStubs(signaturePlan.updatedSections.main, stubRequirements, {
795
872
  createImplementationBlocks: true,
796
873
  definitionSource: definitionLookupSource,
797
874
  });
798
- const stubDefinitions = sections.definitions
799
- ? applyRapHandlerImplementationStubs(signaturePlan.updatedSections.definitions ?? sections.definitions, stubRequirements, {
875
+ const stubDefinitions = skeletonPlan.sections.definitions
876
+ ? applyRapHandlerImplementationStubs(signaturePlan.updatedSections.definitions ?? skeletonPlan.sections.definitions, stubRequirements, {
800
877
  definitionSource: definitionLookupSource,
801
878
  })
802
879
  : undefined;
803
- const stubImplementations = sections.implementations
804
- ? applyRapHandlerImplementationStubs(signaturePlan.updatedSections.implementations ?? sections.implementations, stubRequirements, { createImplementationBlocks: true, definitionSource: definitionLookupSource })
880
+ const stubImplementations = skeletonPlan.sections.implementations
881
+ ? applyRapHandlerImplementationStubs(signaturePlan.updatedSections.implementations ?? skeletonPlan.sections.implementations, stubRequirements, { createImplementationBlocks: true, definitionSource: definitionLookupSource })
805
882
  : undefined;
806
883
  const changed = {
807
- main: signaturePlan.signatures.main.changed || stubMain.changed,
808
- definitions: (signaturePlan.signatures.definitions?.changed ?? false) || (stubDefinitions?.changed ?? false),
809
- implementations: (signaturePlan.signatures.implementations?.changed ?? false) || (stubImplementations?.changed ?? false),
884
+ main: skeletonPlan.changed.main || signaturePlan.signatures.main.changed || stubMain.changed,
885
+ definitions: skeletonPlan.changed.definitions ||
886
+ (signaturePlan.signatures.definitions?.changed ?? false) ||
887
+ (stubDefinitions?.changed ?? false),
888
+ implementations: skeletonPlan.changed.implementations ||
889
+ (signaturePlan.signatures.implementations?.changed ?? false) ||
890
+ (stubImplementations?.changed ?? false),
810
891
  };
811
892
  const changedSections = changedSectionsFrom(changed);
812
893
  return {
@@ -815,6 +896,12 @@ export function applyRapHandlerScaffold(sections, missingSignatures, missingImpl
815
896
  definitions: stubDefinitions?.updatedSource ?? signaturePlan.updatedSections.definitions,
816
897
  implementations: stubImplementations?.updatedSource ?? signaturePlan.updatedSections.implementations,
817
898
  },
899
+ skeletons: {
900
+ createdDefinitions: skeletonPlan.createdDefinitions,
901
+ createdImplementations: skeletonPlan.createdImplementations,
902
+ changed: skeletonPlan.changed,
903
+ changedSections: skeletonPlan.changedSections,
904
+ },
818
905
  signatures: signaturePlan.signatures,
819
906
  implementationStubs: {
820
907
  main: stubMain,