abapgit-agent 1.13.3 → 1.13.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.
package/abap/CLAUDE.md CHANGED
@@ -70,24 +70,93 @@ abapgit-agent ref --list-topics
70
70
  ```
71
71
 
72
72
  The folder is configured in `.abapGitAgent` (property: `folder`):
73
- - If `folder` is `/src/` → files go in `src/` (e.g., `src/zcl_my_class.clas.abap`)
74
- - If `folder` is `/abap/` → files go in `abap/` (e.g., `abap/zcl_my_class.clas.abap`)
73
+ - If `folder` is `/src/` → files go in `src/`
74
+ - If `folder` is `/abap/` → files go in `abap/`
75
75
 
76
76
  **Also check naming conventions before creating any new object:**
77
77
 
78
78
  ```
79
- 1. Check guidelines/objects.local.md ← project-specific overrides (if file exists)
80
- 2. Fall back to guidelines/objects.md default Z/Y prefix conventions
79
+ 1. Check guidelines/objects.local.md ← this project's actual conventions (if file exists)
80
+ 2. No objects.local.md? customer namespace project, use Z/Y defaults
81
81
  ```
82
82
 
83
- `objects.local.md` is created by `abapgit-agent init` and is never overwritten by updates it holds project-specific prefixes (e.g. `YCL_` instead of `ZCL_`).
83
+ `objects.local.md` is never overwritten by updates. It specifies the production naming
84
+ pattern — which may be customer namespace (`ZCL_*`, `YCL_*`), SAP namespace (`CL_*`),
85
+ or SAP registered namespace (`/NAMESPACE/CL_*` — also SAP namespace, not customer).
86
+ Never assume Z/Y prefix without checking.
87
+
88
+ **SAP namespace vs customer namespace:**
89
+ - **Customer namespace**: `Z*`, `Y*` objects; `Z*`, `Y*`, `$*` packages — owned by the customer
90
+ - **SAP namespace**: everything else (`CL_*`, `IF_*`, `/NAMESPACE/*`) — delivered by SAP
84
91
 
85
92
  ---
86
93
 
87
- ### 3. Create XML Metadata / Local Classes
94
+ ### 3. Creating a New ABAP Object — Files to Write and Package Assignment
88
95
 
89
- Each ABAP object needs an XML metadata file. Local helper/test-double classes use separate `.locals_def.abap` / `.locals_imp.abap` files.
90
- See `guidelines/object-creation.md` run: `abapgit-agent ref --topic object-creation`
96
+ ```
97
+ WRONG: Only write the .abap source file
98
+ ✅ CORRECT: Every object needs both a source file AND an XML metadata file
99
+ XML-only objects (TABL, STRU, DTEL, TTYP) need ONLY the XML file
100
+ ```
101
+
102
+ Use the object name from `objects.local.md` (or `objects.md` as fallback) in place of `<name>`:
103
+
104
+ | Object Type | Source File | XML File |
105
+ |-------------|-------------|----------|
106
+ | Class (CLAS) | `<name>.clas.abap` | `<name>.clas.xml` |
107
+ | Interface (INTF) | `<name>.intf.abap` | `<name>.intf.xml` |
108
+ | Program (PROG) | `<name>.prog.abap` | `<name>.prog.xml` |
109
+ | CDS View (DDLS) | `<name>.ddls.asddls` | `<name>.ddls.xml` |
110
+ | Table (TABL) | *(none)* | `<name>.tabl.xml` |
111
+ | Structure (STRU) | *(none)* | `<name>.stru.xml` |
112
+ | Data Element (DTEL) | *(none)* | `<name>.dtel.xml` |
113
+ | Table Type (TTYP) | *(none)* | `<name>.ttyp.xml` |
114
+
115
+ **Package assignment — determine the package, then follow the confirmation rule below:**
116
+
117
+ ```
118
+ 1. Check objects.local.md for package rules ← use them directly
119
+ 2. No package rules in objects.local.md?
120
+ └── Read .abapGitAgent → get the package property → use as root
121
+ Run: abapgit-agent tree --package <root>
122
+ ├── Only one package found → use it directly
123
+ └── Multiple packages found → present options, ask user to choose
124
+ 3. No package in .abapGitAgent?
125
+ └── Ask the user for the root package
126
+ ```
127
+
128
+ **Confirmation before writing files — depends on namespace:**
129
+
130
+ ```
131
+ Object name starts with Z* or Y* AND package starts with Z*, Y*, or $*?
132
+ └── Customer namespace object in customer package
133
+ → Write files directly. No confirmation needed.
134
+
135
+ Anything else (SAP namespace object, or SAP-delivered package)?
136
+ └── Show a creation summary and wait for explicit confirmation:
137
+
138
+ "I'm going to create the following:
139
+
140
+ Object: <NAME> (<Type>)
141
+ Package: <PACKAGE>
142
+ Files: <folder>/<name>.<ext>.abap
143
+ <folder>/<name>.<ext>.xml
144
+
145
+ Shall I proceed?"
146
+ ```
147
+
148
+ ```
149
+ ❌ WRONG: Write files without showing the summary for SAP namespace objects
150
+ ❌ WRONG: Run abapgit-agent tree and pick a package yourself
151
+ ✅ CORRECT: Customer namespace → write directly
152
+ ✅ CORRECT: SAP namespace → always show summary, wait for confirmation
153
+ ```
154
+
155
+ > **Tip for project setup**: Add package rules to `objects.local.md` so Claude never
156
+ > needs to ask. See `guidelines/objects.md` for examples.
157
+
158
+ → For exact XML templates: `abapgit-agent ref --topic abapgit`
159
+ → For local helper/test-double class files: `abapgit-agent ref --topic object-creation`
91
160
 
92
161
  ---
93
162
 
@@ -102,14 +171,15 @@ Each ABAP object needs an XML metadata file. Local helper/test-double classes us
102
171
 
103
172
  ```bash
104
173
  # Check syntax of local code (no commit/push needed)
105
- abapgit-agent syntax --files src/zcl_my_class.clas.abap
106
- abapgit-agent syntax --files src/zc_my_view.ddls.asddls
174
+ # Use the actual filename from your project (name comes from objects.local.md)
175
+ abapgit-agent syntax --files src/<name>.clas.abap
176
+ abapgit-agent syntax --files src/<name>.ddls.asddls
107
177
 
108
178
  # Check multiple INDEPENDENT files
109
- abapgit-agent syntax --files src/zcl_utils.clas.abap,src/zcl_logger.clas.abap
179
+ abapgit-agent syntax --files src/<name1>.clas.abap,src/<name2>.clas.abap
110
180
  ```
111
181
 
112
- **For other types (DDLS, FUGR, TABL, etc.)**: Skip syntax, proceed to commit/push/pull.
182
+ **For other types (FUGR, TABL, etc.)**: Skip syntax, proceed to commit/push/pull.
113
183
 
114
184
  **Why use syntax command?**
115
185
  - Catches syntax errors BEFORE polluting git history with fix commits
@@ -126,11 +196,11 @@ When checking multiple files, each is validated in isolation:
126
196
  **For dependent files, skip `syntax` and use `pull` instead:**
127
197
  ```bash
128
198
  # ❌ BAD - Interface and implementing class (may show false errors)
129
- abapgit-agent syntax --files src/zif_my_intf.intf.abap,src/zcl_my_class.clas.abap
199
+ abapgit-agent syntax --files src/<intf_name>.intf.abap,src/<class_name>.clas.abap
130
200
 
131
201
  # ✅ GOOD - Use pull instead for dependent files
132
202
  git add . && git commit && git push
133
- abapgit-agent pull --files src/zif_my_intf.intf.abap,src/zcl_my_class.clas.abap
203
+ abapgit-agent pull --files src/<intf_name>.intf.abap,src/<class_name>.clas.abap
134
204
  ```
135
205
 
136
206
  **Note**: `inspect` still runs against ABAP system (requires pull first). Use `syntax` for pre-commit checking.
@@ -256,11 +326,29 @@ After activating a class, stop and tell the user: `"Class is activated. Run with
256
326
 
257
327
  ---
258
328
 
259
- ### 10. Probe ClassesUse `scratchWorkspace` When Required
329
+ ### 10. Probe and PoC Objects Always Z/Y, Never in SAP Packages
330
+
331
+ ```
332
+ ❌ WRONG: Create a probe/PoC object with the project's SAP namespace prefix
333
+ ❌ WRONG: Assign a probe/PoC object to an SAP-delivered package
334
+ ✅ CORRECT: Probe/PoC objects always use Z* or Y* prefix
335
+ ✅ CORRECT: Always assign to a customer namespace package (Z*, Y*, or $*)
336
+ ```
337
+
338
+ This rule applies even on projects where production objects use SAP namespace (`CL_*`, `/NAMESPACE/*`).
339
+
340
+ **Trigger — when `objects.local.md` shows a SAP namespace prefix (`CL_*`, `IF_*`, `/NAMESPACE/*`)
341
+ and the user asks to create a new object, always ask first:**
260
342
 
261
- By default, probe/throwaway classes may be created in the current project. When `disableProbeClasses: true` is set in `.abapgit-agent.json`, they must go to `scratchWorkspace` instead. If `scratchWorkspace` is also not configured, refuse and guide the user to set it up.
343
+ ```
344
+ "Is this a production object, a PoC (will persist, needs its own package/repo),
345
+ or a probe (throwaway, run once)?"
346
+ ```
262
347
 
263
- See `guidelines/run-probe-classes.md` run: `abapgit-agent ref --topic run-probe-classes`
348
+ Never assumewait for the user's answer before proceeding.
349
+
350
+ → For full decision flow (how to determine namespace, probe vs PoC, scratchWorkspace,
351
+ pocWorkspace, setup instructions): `abapgit-agent ref --topic probe-poc`
264
352
 
265
353
  ---
266
354
 
@@ -355,11 +443,11 @@ If workflow mode is `"trunk"` or not set, commit directly to the default branch:
355
443
  ```bash
356
444
  git checkout main # or master/develop (auto-detected)
357
445
  git pull origin main
358
- edit src/zcl_auth_handler.clas.abap
359
- abapgit-agent syntax --files src/zcl_auth_handler.clas.abap
360
- git add . && git commit -m "feat: add authentication handler"
446
+ # edit your ABAP file (name from objects.local.md)
447
+ abapgit-agent syntax --files src/<name>.clas.abap
448
+ git add . && git commit -m "feat: description"
361
449
  git push origin main
362
- abapgit-agent pull --files src/zcl_auth_handler.clas.abap --sync-xml
450
+ abapgit-agent pull --files src/<name>.clas.abap --sync-xml
363
451
  ```
364
452
 
365
453
  ### AI Tool Guidelines
@@ -400,7 +488,14 @@ abapgit-agent pull --files src/zcl_auth_handler.clas.abap --sync-xml
400
488
  2. ✓ Inform the user that run is disabled for this project
401
489
 
402
490
  **When `safeguards.disableProbeClasses = true`:**
403
- 1. ✗ Do not create probe classes in the current project — see Rule 10 and `guidelines/run-command.md`
491
+ 1. ✗ Do not create probe classes in the current project
492
+ 2. ✓ If `scratchWorkspace` is configured → create probe class there (see Rule 10)
493
+ 3. ✗ If `scratchWorkspace` is NOT configured → refuse, tell user to configure it in `.abapGitAgent`
494
+
495
+ **When user requests a PoC object:**
496
+ 1. ✓ Read `pocWorkspace.path` from `.abapGitAgent`
497
+ 2. ✓ If configured → read `{path}/.abapGitAgent` for package, show confirmation summary, wait for user
498
+ 3. ✗ If NOT configured → refuse, tell user to set up a PoC repo and configure `pocWorkspace.path`
404
499
 
405
500
  **When `conflictDetection.mode = "ignore"` or not set:**
406
501
  1. ✓ Run `pull` normally — no conflict flags needed
@@ -443,10 +538,14 @@ Modified ABAP files?
443
538
  │ │ └─ ✅ Use: syntax → commit → push → pull --sync-xml
444
539
  │ └─ Dependent files (interface + class, class uses class)?
445
540
  │ └─ ✅ Use: skip syntax → commit → push → pull --sync-xml
446
- └─ Other types (DDLS, FUGR, TABL, etc.)?
447
- └─ ✅ Use: skip syntax → commit → push → pull --sync-xml (if errors: inspect)
541
+ └─ Other types (FUGR, TABL, STRU, DTEL, TTYP, etc.)?
542
+ ├─ XML-only objects (TABL, STRU, DTEL, TTYP)?
543
+ │ └─ ✅ Use: skip syntax → commit → push → pull --files abap/ztable.tabl.xml --sync-xml
544
+ └─ FUGR and other complex objects?
545
+ └─ ✅ Use: skip syntax → commit → push → pull --sync-xml → (if errors: inspect)
448
546
  ```
449
547
 
548
+ → For creating new objects (what files to write): `abapgit-agent ref --topic object-creation`
450
549
  → See `guidelines/workflow-detailed.md` — run: `abapgit-agent ref --topic workflow-detailed`
451
550
 
452
551
  ---
@@ -479,6 +578,7 @@ Detailed guidelines are available in the `guidelines/` folder:
479
578
  | `guidelines/debug-session.md` | Debug Session Guide |
480
579
  | `guidelines/debug-dump.md` | Dump Analysis Guide |
481
580
  | `guidelines/run-probe-classes.md` | run Command — AI Guidelines (probe classes, scratchWorkspace) |
581
+ | `guidelines/probe-poc.md` | Probe and PoC — Full Decision Flow |
482
582
  | `guidelines/branch-workflow.md` | Branch Workflow |
483
583
  | `guidelines/workflow-detailed.md` | Development Workflow (Detailed) |
484
584
  | `guidelines/object-creation.md` | Object Creation (XML metadata, local classes) |
@@ -19,13 +19,17 @@ Class | zcl_*.clas.abap | zcl_*.clas.xml
19
19
  Test Class | zcl_*.clas.testclasses.abap | zcl_*.clas.xml
20
20
  Interface | zif_*.intf.abap | zif_*.intf.xml
21
21
  Program | z*.prog.abap | z*.prog.xml
22
- Table | z*.tabl.abap | z*.tabl.xml
23
22
  CDS View (DDLS) | zc_*.ddls.asddls | zc_*.ddls.xml
24
- Data Element | z*.dtel.abap | z*.dtel.xml
25
- Structure | z*.stru.abap | z*.stru.xml
26
- Table Type | z*.ttyp.abap | z*.ttyp.xml
23
+ Table (TABL) | (no .abap file) | z*.tabl.xml
24
+ Structure (STRU) | (no .abap file) | z*.stru.xml
25
+ Data Element (DTEL)| (no .abap file) | z*.dtel.xml
26
+ Table Type (TTYP) | (no .abap file) | z*.ttyp.xml
27
27
  ```
28
28
 
29
+ > **XML-only objects (TABL, STRU, DTEL, TTYP)** have **no ABAP source file**. abapGit serializes
30
+ > them as XML metadata only. When using `--files`, pass the `.xml` file directly:
31
+ > `abapgit-agent pull --files abap/zmy_table.tabl.xml --sync-xml`
32
+
29
33
  > **CRITICAL: Always write XML files with a UTF-8 BOM (`\ufeff`) as the very first character**, before `<?xml ...`.
30
34
  > Without the BOM, abapGit shows the object as **"M" (modified)** after every pull because the
31
35
  > serializer always produces XML with BOM — and every byte matters.
@@ -244,6 +248,8 @@ abapGit's serializer **omits fields that have their default value**. Writing ext
244
248
 
245
249
  **Filename**: `src/zmy_table.tabl.xml`
246
250
 
251
+ > **XML-only object** — no `.abap` source file. Pull with: `pull --files src/zmy_table.tabl.xml`
252
+
247
253
  ```xml
248
254
  <?xml version="1.0" encoding="utf-8"?>
249
255
  <abapGit version="v1.0.0" serializer="LCL_OBJECT_TABL" serializer_version="v1.0.0">
@@ -313,6 +319,8 @@ The XML format is identical for both types — only `SOURCE_TYPE` differs:
313
319
 
314
320
  **Filename**: `src/zmy_dtel.dtel.xml`
315
321
 
322
+ > **XML-only object** — no `.abap` source file. Pull with: `pull --files src/zmy_dtel.dtel.xml`
323
+
316
324
  ```xml
317
325
  <?xml version="1.0" encoding="utf-8"?>
318
326
  <abapGit version="v1.0.0" serializer="LCL_OBJECT_DTEL" serializer_version="v1.0.0">
@@ -323,9 +331,9 @@ The XML format is identical for both types — only `SOURCE_TYPE` differs:
323
331
  <DDLANGUAGE>E</DDLANGUAGE>
324
332
  <DDTEXT>Description of data element</DDTEXT>
325
333
  <REPTEXT>Description</REPTEXT>
326
- <SCRTEXT_S>Short</SCRTEXT_S>
327
- <SCRTEXT_M>Medium</SCRTEXT_M>
328
- <SCRTEXT_L>Long Description</SCRTEXT_L>
334
+ <SCRTEXT_S>Short text</SCRTEXT_S>
335
+ <SCRTEXT_M>Medium text</SCRTEXT_M>
336
+ <SCRTEXT_L>Long description text</SCRTEXT_L>
329
337
  <DTELMASTER>E</DTELMASTER>
330
338
  <DATATYPE>CHAR</DATATYPE>
331
339
  <LENG>000010</LENG>
@@ -338,9 +346,84 @@ The XML format is identical for both types — only `SOURCE_TYPE` differs:
338
346
  **Key Fields**:
339
347
  - `ROLLNAME`: Data element name
340
348
  - `DDTEXT`: Description (**not** `DESCRIPT`)
349
+ - `REPTEXT` / `SCRTEXT_S` / `SCRTEXT_M` / `SCRTEXT_L`: Field labels (report heading, short, medium, long)
350
+ - `DTELMASTER`: Language key for label master (`E` for English)
341
351
  - `DATATYPE`: Data type (`CHAR`, `NUMC`, `DATS`, `TIMS`, `INT4`, etc.)
342
352
  - `LENG`: Length padded to 6 digits (e.g. `000010` for 10 characters)
343
353
 
354
+ **Omit `<PARAMID>`** unless you specifically need a SET/GET parameter ID — the serializer omits it when empty, so including an empty tag causes a permanent diff.
355
+
356
+ ---
357
+
358
+ ### Structure (STRU)
359
+
360
+ **Filename**: `src/zmy_struct.stru.xml`
361
+
362
+ > **XML-only object** — no `.abap` source file. abapGit uses the same TABL serializer for STRU.
363
+ > Pull with: `pull --files src/zmy_struct.stru.xml`
364
+
365
+ ```xml
366
+ <?xml version="1.0" encoding="utf-8"?>
367
+ <abapGit version="v1.0.0" serializer="LCL_OBJECT_TABL" serializer_version="v1.0.0">
368
+ <asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
369
+ <asx:values>
370
+ <DD02V>
371
+ <TABNAME>ZMY_STRUCT</TABNAME>
372
+ <DDLANGUAGE>E</DDLANGUAGE>
373
+ <TABCLASS>INTTAB</TABCLASS>
374
+ <DDTEXT>Description of the structure</DDTEXT>
375
+ <CONTFLAG>A</CONTFLAG>
376
+ </DD02V>
377
+ </asx:values>
378
+ </asx:abap>
379
+ </abapGit>
380
+ ```
381
+
382
+ **Key difference from TABL**: `TABCLASS` is `INTTAB` (internal table / structure) instead of `TRANSP`.
383
+
384
+ **Note**: Like TABL, after the first pull abapGit expands the XML with `<DD03P_TABLE>` field definitions. When creating a new structure you only need the `<DD02V>` header.
385
+
386
+ ---
387
+
388
+ ### Table Type (TTYP)
389
+
390
+ **Filename**: `src/zmy_ttyp.ttyp.xml`
391
+
392
+ > **XML-only object** — no `.abap` source file.
393
+ > Pull with: `pull --files src/zmy_ttyp.ttyp.xml`
394
+
395
+ ```xml
396
+ <?xml version="1.0" encoding="utf-8"?>
397
+ <abapGit version="v1.0.0" serializer="LCL_OBJECT_TTYP" serializer_version="v1.0.0">
398
+ <asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
399
+ <asx:values>
400
+ <DD40V>
401
+ <TYPENAME>ZMY_TTYP</TYPENAME>
402
+ <DDLANGUAGE>E</DDLANGUAGE>
403
+ <DDTEXT>Description of table type</DDTEXT>
404
+ <ROWTYPE>ZMY_STRUCT</ROWTYPE>
405
+ <ROWKIND>S</ROWKIND>
406
+ <DATATYPE>TABLE_T</DATATYPE>
407
+ <ACCESSMODE>T</ACCESSMODE>
408
+ <KEYDEF>D</KEYDEF>
409
+ <KEYKIND>N</KEYKIND>
410
+ </DD40V>
411
+ </asx:values>
412
+ </asx:abap>
413
+ </abapGit>
414
+ ```
415
+
416
+ **Key Fields**:
417
+ - `TYPENAME`: Table type name
418
+ - `ROWTYPE`: Row type (a structure or data element name)
419
+ - `ROWKIND`: Row kind — `S`=Structure/Type, `D`=Data element, `R`=Reference
420
+ - `DATATYPE`: Always `TABLE_T` for table types
421
+ - `ACCESSMODE`: Table kind — `T`=Standard, `S`=Sorted, `H`=Hashed
422
+ - `KEYDEF`: Key definition — `D`=Default (standard key), `K`=User-defined
423
+ - `KEYKIND`: Key uniqueness — `N`=Non-unique, `U`=Unique
424
+
425
+ **Note**: After the first pull abapGit may expand the XML with `<DD42V>` (component definitions) if key fields are explicitly defined.
426
+
344
427
  ---
345
428
 
346
429
  ## Important Notes
@@ -12,14 +12,23 @@ grand_parent: ABAP Development
12
12
 
13
13
  **Each ABAP object requires an XML metadata file for abapGit to understand how to handle it.**
14
14
 
15
- | Object Type | ABAP File (if folder=/src/) | XML File | Details |
16
- |-------------|------------------------------|----------|---------|
17
- | Class | `src/zcl_*.clas.abap` | `src/zcl_*.clas.xml` | See `guidelines/abapgit.md` |
18
- | Interface | `src/zif_*.intf.abap` | `src/zif_*.intf.xml` | See `guidelines/abapgit.md` |
19
- | Program | `src/z*.prog.abap` | `src/z*.prog.xml` | See `guidelines/abapgit.md` |
20
- | Table | `src/z*.tabl.abap` | `src/z*.tabl.xml` | See `guidelines/abapgit.md` |
21
- | **CDS View Entity** | `src/zc_*.ddls.asddls` | `src/zc_*.ddls.xml` | **Use by default** - See `guidelines/cds.md` |
22
- | CDS View (legacy) | `src/zc_*.ddls.asddls` | `src/zc_*.ddls.xml` | Only if explicitly requested - See `guidelines/cds.md` |
15
+ Replace `<name>` with the actual object name from this project's naming conventions
16
+ (`guidelines/objects.local.md`, or `guidelines/objects.md` as fallback).
17
+
18
+ | Object Type | ABAP Source File | XML File | Details |
19
+ |-------------|-----------------|----------|---------|
20
+ | Class | `<name>.clas.abap` | `<name>.clas.xml` | See `guidelines/abapgit.md` |
21
+ | Interface | `<name>.intf.abap` | `<name>.intf.xml` | See `guidelines/abapgit.md` |
22
+ | Program | `<name>.prog.abap` | `<name>.prog.xml` | See `guidelines/abapgit.md` |
23
+ | **CDS View Entity** | `<name>.ddls.asddls` | `<name>.ddls.xml` | **Use by default** - See `guidelines/cds.md` |
24
+ | CDS View (legacy) | `<name>.ddls.asddls` | `<name>.ddls.xml` | Only if explicitly requested - See `guidelines/cds.md` |
25
+ | Table (TABL) | *(none — XML-only)* | `<name>.tabl.xml` | See `guidelines/abapgit.md` |
26
+ | Structure (STRU) | *(none — XML-only)* | `<name>.stru.xml` | See `guidelines/abapgit.md` |
27
+ | Data Element (DTEL) | *(none — XML-only)* | `<name>.dtel.xml` | See `guidelines/abapgit.md` |
28
+ | Table Type (TTYP) | *(none — XML-only)* | `<name>.ttyp.xml` | See `guidelines/abapgit.md` |
29
+
30
+ > **XML-only objects (TABL, STRU, DTEL, TTYP)**: create only the `.xml` file — there is no `.abap` source file.
31
+ > After committing and pushing, pull with: `pull --files <folder>/<name>.tabl.xml --sync-xml`
23
32
 
24
33
  **IMPORTANT: When user says "create CDS view", create CDS View Entity by default.**
25
34
 
@@ -37,14 +46,14 @@ When a class needs local helper classes or test doubles, use separate files:
37
46
 
38
47
  | File | Purpose |
39
48
  |------|---------|
40
- | `zcl_xxx.clas.locals_def.abap` | Local class definitions |
41
- | `zcl_xxx.clas.locals_imp.abap` | Local class implementations |
49
+ | `<name>.clas.locals_def.abap` | Local class definitions |
50
+ | `<name>.clas.locals_imp.abap` | Local class implementations |
42
51
 
43
52
  **XML Configuration**: Add `<CLSCCINCL>X</CLSCCINCL>` to the class XML to include local class definitions:
44
53
 
45
54
  ```xml
46
55
  <VSEOCLASS>
47
- <CLSNAME>ZCL_XXX</CLSNAME>
56
+ <CLSNAME>MY_CLASS_NAME</CLSNAME>
48
57
  ...
49
58
  <CLSCCINCL>X</CLSCCINCL>
50
59
  </VSEOCLASS>
@@ -8,67 +8,78 @@ grand_parent: ABAP Development
8
8
 
9
9
  # ABAP Object Naming Conventions
10
10
 
11
- > **Project-specific overrides**: Add your naming conventions to `guidelines/objects.local.md`.
12
- > That file is never overwritten by `abapgit-agent init --update` and is searched by the `ref` command.
11
+ **Searchable keywords**: naming convention, prefix, namespace, object type, CLAS, INTF, PROG, TABL, DDLS, SAP namespace, customer namespace, PoC, probe
13
12
 
14
- **Searchable keywords**: naming convention, Z prefix, namespace, object type, CLAS, INTF, PROG, TABL, DDLS
13
+ ## SAP Namespace vs Customer Namespace
15
14
 
16
- ## TOPICS IN THIS FILE
17
- 1. Naming Conventions
18
- 2. ABAP Object Types
19
- 3. XML Metadata (see guidelines/abapgit.md)
15
+ | | SAP Namespace | Customer Namespace |
16
+ |---|---|---|
17
+ | **Object prefix** | `CL_*`, `IF_*`, `/NAME/CL_*`, `/NAME/IF_*`, etc. | `Z*`, `Y*` |
18
+ | **Package prefix** | SAP-delivered (e.g. `SFIN`, `CA_*`, `/NAME/*`) | `Z*`, `Y*`, `$*` |
19
+ | **Ownership** | Delivered and maintained by SAP | Owned by the customer |
20
+ | **In git repo** | Objects from an SAP-delivered package | Custom development objects |
20
21
 
21
- ## Naming Conventions
22
+ > **Rule**: Never add customer-created objects (including PoC/probe classes) into SAP namespace
23
+ > packages. PoC objects always use `Z*`/`Y*` prefix and always go in a `Z*`, `Y*`, or `$*` package
24
+ > — even on a project where production objects use SAP namespace.
22
25
 
23
- Use `Z_` or `Y_` prefix for custom objects:
26
+ ## How to Determine This Project's Naming Convention
24
27
 
25
- | Object Type | Prefix | Example |
26
- |-------------|--------|---------|
27
- | Class | ZCL_ | ZCL_MY_CLASS |
28
- | Interface | ZIF_ | ZIF_MY_INTERFACE |
29
- | Program | Z | ZMY_PROGRAM |
30
- | Package | $ | $MY_PACKAGE |
31
- | Table | Z | ZMY_TABLE |
32
- | CDS View | ZC | ZC_MY_VIEW |
33
- | CDS Entity | ZE | ZE_MY_ENTITY |
34
- | Data Element | Z | ZMY_ELEMENT |
35
- | Structure | Z | ZMY_STRUCTURE |
36
- | Table Type | Z | ZMY_TABLE_TYPE |
28
+ ```
29
+ 1. Check guidelines/objects.local.md ← this project's actual conventions (always check first)
30
+ 2. No objects.local.md exists? ← assume customer namespace project, use Z/Y defaults below
31
+ ```
37
32
 
38
- ## ABAP Object Types
33
+ `objects.local.md` is never overwritten by `abapgit-agent init --update`. It specifies the
34
+ naming pattern for production objects in this project — which could be customer namespace
35
+ (`ZCL_*`, `YCL_*`) or SAP namespace (`CL_*`, `/NAMESPACE/CL_*`).
39
36
 
40
- Common object types in this project:
37
+ ## Default Naming Conventions (Z/Y customer namespace)
41
38
 
42
- | Type | Description | File Suffix |
43
- |------|-------------|-------------|
44
- | CLAS | Classes | .clas.abap |
45
- | PROG | Programs | .prog.abap |
46
- | FUGR | Function Groups | .fugr.abap |
47
- | INTF | Interfaces | .intf.abap |
48
- | TABL | Tables | .tabl.abap |
49
- | STRU | Structures | .stru.abap |
50
- | DTEL | Data Elements | .dtel.abap |
51
- | TTYP | Table Types | .ttyp.abap |
52
- | DDLS | CDS Views | .ddls.asddls |
53
- | DDLX | CDS Entities | .ddlx.asddlx |
39
+ Applied when no `objects.local.md` exists:
54
40
 
55
- ## XML Metadata
41
+ | Object Type | Default Prefix | Default Example |
42
+ |-------------|---------------|-----------------|
43
+ | Class | `ZCL_` | `ZCL_MY_CLASS` |
44
+ | Interface | `ZIF_` | `ZIF_MY_INTERFACE` |
45
+ | Program | `Z` | `ZMY_PROGRAM` |
46
+ | Package | `$` | `$MY_PACKAGE` |
47
+ | Table | `Z` | `ZMY_TABLE` |
48
+ | CDS View Entity | `ZC_` | `ZC_MY_VIEW` |
49
+ | Data Element | `Z` | `ZMY_ELEMENT` |
50
+ | Structure | `Z` | `ZMY_STRUCTURE` |
51
+ | Table Type | `Z` | `ZMY_TABLE_TYPE` |
56
52
 
57
- **See guidelines/abapgit.md for XML templates.**
53
+ ## Project-Specific Conventions (`objects.local.md`)
58
54
 
59
- Each ABAP object requires an XML metadata file for abapGit. Quick reference:
55
+ `objects.local.md` should define both the naming prefix **and the correct package(s)** for
56
+ new objects. When package rules are present, Claude uses them directly without asking. When
57
+ absent, Claude must ask the user which package to use.
58
+
59
+ Examples of what `objects.local.md` might contain:
60
60
 
61
61
  ```
62
- Class: zcl_*.clas.xml
63
- Interface: zif_*.intf.xml
64
- Table: z*.tabl.xml
65
- CDS View: zc_*.ddls.xml
66
- ```
62
+ # Customer namespace — Y prefix
63
+ Class prefix: YCL_ e.g. YCL_MY_CLASS
64
+ Interface prefix: YIF_ e.g. YIF_MY_INTERFACE
65
+ Default package: YMYPROJECT
67
66
 
68
- **Important**: Always push to git BEFORE running pull:
69
- ```bash
70
- git add .
71
- git commit -m "Changes"
72
- git push # CRITICAL: Push FIRST
73
- abapgit-agent pull --files abap/zcl_my_class.clas.abap
67
+ # SAP namespace project single package
68
+ Class prefix: CL_ e.g. CL_MY_CLASS
69
+ Interface prefix: IF_ e.g. IF_MY_INTERFACE
70
+ Default package: MY_PACKAGE
71
+
72
+ # SAP namespace project — multiple packages
73
+ Class prefix: CL_ e.g. CL_MY_CLASS
74
+ Interface prefix: IF_ e.g. IF_MY_INTERFACE
75
+ Packages:
76
+ - Feature A objects → MY_PACKAGE_A
77
+ - Feature B objects → MY_PACKAGE_B
78
+
79
+ # SAP registered namespace
80
+ Class prefix: /MYNAMESPACE/CL_
81
+ Default package: /MYNAMESPACE/MAIN
74
82
  ```
83
+
84
+ → For file structure (what files to create): `abapgit-agent ref --topic object-creation`
85
+ → For XML templates: `abapgit-agent ref --topic abapgit`
@@ -0,0 +1,146 @@
1
+ ---
2
+ layout: default
3
+ title: Probe and PoC Guide
4
+ nav_order: 19
5
+ parent: ABAP Coding Guidelines
6
+ grand_parent: ABAP Development
7
+ ---
8
+
9
+ # Probe and PoC — Full Decision Flow
10
+
11
+ **Searchable keywords**: probe, PoC, proof of concept, scratchWorkspace, pocWorkspace,
12
+ disableProbeClasses, SAP namespace, customer namespace, throwaway class
13
+
14
+ ## Probe vs PoC — Key Difference
15
+
16
+ | | Probe | PoC |
17
+ |---|---|---|
18
+ | Intent | Throwaway — run once to test something | Validate an idea — may persist, needs proper home |
19
+ | Naming | Auto-derived (`ZCL_{USER}_*`) | Developer chooses a meaningful name |
20
+ | Location | `scratchWorkspace` (separate repo) | `pocWorkspace` (separate repo, manually set up) |
21
+ | Config | `scratchWorkspace` in `.abapGitAgent` | `pocWorkspace` in `.abapGitAgent` |
22
+
23
+ Both always use `Z*`/`Y*` prefix and a customer namespace package (`Z*`, `Y*`, `$*`).
24
+ Never use SAP namespace prefix or SAP-delivered package for probe/PoC objects.
25
+
26
+ ---
27
+
28
+ ## How to Determine the Project Namespace
29
+
30
+ Before applying the decision flow, determine the project namespace from `objects.local.md`:
31
+
32
+ ```
33
+ objects.local.md shows Z*/Y* prefix OR no objects.local.md exists
34
+ → Customer namespace project
35
+
36
+ objects.local.md shows CL_*, IF_*, /NAMESPACE/* prefix
37
+ → SAP namespace project
38
+ ```
39
+
40
+ ---
41
+
42
+ ## Full Decision Flow
43
+
44
+ ```
45
+ User asks to create an object
46
+
47
+ ├── SAP namespace project AND user provides a Z*/Y* name
48
+ │ └── Ask: "Production objects here use CL_* prefix. Did you mean CL_MY_HELPER?
49
+ │ Or is this a PoC/probe object?"
50
+ │ ├── "PoC/probe" → continue as PoC or probe flow below
51
+ │ └── "Production" → correct the name to match project prefix, then proceed
52
+
53
+ ├── User confirms PROBE
54
+ │ ├── Customer namespace project
55
+ │ │ ├── disableProbeClasses = false / not set
56
+ │ │ │ └── Create in current project (Z*/Y* prefix, Z*/Y*/$* package)
57
+ │ │ └── disableProbeClasses = true
58
+ │ │ ├── scratchWorkspace configured → create there (see workflow below)
59
+ │ │ └── scratchWorkspace NOT configured
60
+ │ │ └── STOP — tell user to configure scratchWorkspace in .abapGitAgent
61
+ │ │
62
+ │ └── SAP namespace project
63
+ │ ├── scratchWorkspace configured → create there (see workflow below)
64
+ │ └── scratchWorkspace NOT configured
65
+ │ └── STOP — tell user to configure scratchWorkspace in .abapGitAgent
66
+ │ (disableProbeClasses is irrelevant for SAP namespace projects —
67
+ │ they have no customer namespace packages to host probes)
68
+
69
+ └── User confirms POC
70
+ ├── pocWorkspace.path configured in .abapGitAgent
71
+ │ └── Read {pocWorkspace.path}/.abapGitAgent → get package property
72
+ │ Show confirmation:
73
+ │ "I'll create this PoC object in:
74
+ │ Repo: {pocWorkspace.path}
75
+ │ Package: {package from that repo's .abapGitAgent}
76
+ │ Is this correct, or do you want a different PoC repo?"
77
+ │ ├── Confirmed → work in that repo using its naming/package rules
78
+ │ └── Different repo → ask user for the path, then confirm again
79
+ └── pocWorkspace.path NOT configured
80
+ └── STOP — tell user to set up a PoC repo first (see setup below)
81
+ ```
82
+
83
+ ---
84
+
85
+ ## Probe Workflow (scratchWorkspace)
86
+
87
+ **Naming** — derive from `scratchWorkspace` config in `.abapGitAgent`:
88
+ - `classPrefix` (default: `ZCL_{USER}_`) + `<PURPOSE>`, max 30 chars
89
+ - Example: user=`JOHN`, purpose=`OPEN_TRANSPORTS` → `ZCL_JOHN_OPEN_TRANSPORTS`
90
+ - If name already exists in `{path}/src/`, append `_2`, `_3`, etc.
91
+
92
+ **Workflow:**
93
+ 1. Read `{scratchWorkspace.path}/.abapGitAgent` to confirm `folder` property (e.g. `/src/`)
94
+ 2. Write class files in `{path}/src/`
95
+ 3. Commit and push from `{path}`:
96
+ ```bash
97
+ cd {path} && git add . && git commit -m "probe: <description>" && git push
98
+ ```
99
+ 4. Activate:
100
+ ```bash
101
+ cd {path} && abapgit-agent pull --files src/<classname>.clas.abap
102
+ ```
103
+ 5. Tell user (do NOT auto-run):
104
+ ```
105
+ Class activated. Run with: abapgit-agent run --class <CLASSNAME>
106
+ ```
107
+ Run the command from the original project directory, not `{path}`.
108
+
109
+ ---
110
+
111
+ ## PoC Workflow (pocWorkspace)
112
+
113
+ Once the user confirms the repo and package:
114
+
115
+ 1. Read `{pocWorkspace.path}/.abapGitAgent` → get `folder` and `package`
116
+ 2. Read `{pocWorkspace.path}/guidelines/objects.local.md` if it exists → use its naming rules
117
+ 3. Write object files in `{pocWorkspace.path}/{folder}/`
118
+ 4. Commit and push from `{pocWorkspace.path}`:
119
+ ```bash
120
+ cd {pocWorkspace.path} && git add . && git commit -m "poc: <description>" && git push
121
+ ```
122
+ 5. Activate:
123
+ ```bash
124
+ cd {pocWorkspace.path} && abapgit-agent pull --files {folder}/<name>.<ext> --sync-xml
125
+ ```
126
+
127
+ ---
128
+
129
+ ## PoC Repo Setup (one-time, manual)
130
+
131
+ When `pocWorkspace.path` is not configured, tell the user to:
132
+
133
+ ```
134
+ 1. Create a git repo for the PoC:
135
+ mkdir my-poc && cd my-poc && git init && git remote add origin <url>
136
+
137
+ 2. Link it to an ABAP package:
138
+ abapgit-agent init --package <POC_PACKAGE>
139
+
140
+ 3. Add pocWorkspace to .abapGitAgent in the main project:
141
+ "pocWorkspace": { "path": "/absolute/path/to/my-poc" }
142
+ ```
143
+
144
+ **Switching PoCs**: update `pocWorkspace.path` to point to the new PoC repo.
145
+ Claude always shows the current repo and package before creating anything —
146
+ a stale path is caught before any files are written.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "abapgit-agent",
3
- "version": "1.13.3",
3
+ "version": "1.13.4",
4
4
  "description": "ABAP Git Agent - Pull and activate ABAP code via abapGit from any git repository",
5
5
  "files": [
6
6
  "bin/",
@@ -28,6 +28,7 @@
28
28
  "test:cmd:syntax": "node tests/run-all.js --cmd --command=syntax",
29
29
  "test:cmd:pull": "node tests/run-all.js --cmd --command=pull",
30
30
  "test:sync-xml": "node tests/run-all.js --sync-xml",
31
+ "test:xml-only": "node tests/run-all.js --xml-only",
31
32
  "test:cmd:inspect": "node tests/run-all.js --cmd --command=inspect",
32
33
  "test:cmd:unit": "node tests/run-all.js --cmd --command=unit",
33
34
  "test:cmd:view": "node tests/run-all.js --cmd --command=view",
@@ -98,21 +98,31 @@ module.exports = {
98
98
  if (filesArgIndex !== -1 && filesArgIndex + 1 < args.length) {
99
99
  files = args[filesArgIndex + 1].split(',').map(f => f.trim());
100
100
 
101
- // Validate that every file has a recognised ABAP source extension
102
- // (.abap or .asddls) XML metadata files must NOT be passed here
101
+ // Validate that every file has a recognised extension:
102
+ // - .abap / .asddls ABAP source files
103
+ // - name.type.xml — XML-only objects (TABL, STRU, DTEL, TTYP, ...)
104
+ // Must have exactly 3 dot-separated parts with a non-empty name part
105
+ // to exclude .abapgit.xml, package.devc.xml, plain .xml, etc.
103
106
  const ABAP_SOURCE_EXTS = new Set(['abap', 'asddls']);
107
+ const isXmlOnlyObject = (f) => {
108
+ const base = f.split('/').pop();
109
+ const parts = base.split('.');
110
+ return parts.length === 3 && parts[0].length > 0 && parts[2].toLowerCase() === 'xml';
111
+ };
104
112
  const nonSourceFiles = files.filter(f => {
105
113
  const base = f.split('/').pop(); // strip directory
106
114
  const parts = base.split('.');
107
115
  const ext = parts[parts.length - 1].toLowerCase();
108
- return parts.length < 3 || !ABAP_SOURCE_EXTS.has(ext);
116
+ if (ABAP_SOURCE_EXTS.has(ext)) return false; // .abap / .asddls — valid
117
+ if (isXmlOnlyObject(f)) return false; // name.type.xml — valid
118
+ return true; // everything else — invalid
109
119
  });
110
120
  if (nonSourceFiles.length > 0) {
111
- console.error('❌ Error: --files only accepts ABAP source files (.abap, .asddls).');
112
- console.error(' The following file(s) are not ABAP source files:');
121
+ console.error('❌ Error: --files only accepts ABAP source files (.abap, .asddls) or XML-only object files (name.type.xml).');
122
+ console.error(' The following file(s) are not recognised:');
113
123
  nonSourceFiles.forEach(f => console.error(` ${f}`));
114
- console.error(' Tip: pass the source file, not the XML metadata file.');
115
- console.error(' Example: --files src/zcl_my_class.clas.abap');
124
+ console.error(' Tip: for source objects pass the .abap file; for XML-only objects (TABL, STRU, DTEL, TTYP)');
125
+ console.error(' pass the .xml file, e.g. --files abap/ztable.tabl.xml');
116
126
  process.exit(1);
117
127
  }
118
128