abapgit-agent 1.11.3 → 1.12.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.
@@ -25,13 +25,6 @@ You are working on an ABAP project using abapGit for version control.
25
25
  | CDS views | "How to define CDS view with associations?" |
26
26
  | Getting syntax errors | Check reference before trying approaches |
27
27
 
28
- ```bash
29
- # For CDS topics
30
- abapgit-agent ref --topic cds
31
- abapgit-agent ref "CDS view"
32
- abapgit-agent ref "association"
33
- ```
34
-
35
28
  ```bash
36
29
  # Search for a pattern
37
30
  abapgit-agent ref "CORRESPONDING"
@@ -45,7 +38,7 @@ abapgit-agent ref --topic sql
45
38
  abapgit-agent ref --list-topics
46
39
  ```
47
40
 
48
- ### 2. Read `.abapGitAgent` for Folder Location
41
+ ### 2. Read `.abapGitAgent` for Folder Location and Naming Conventions
49
42
 
50
43
  **Before creating ANY ABAP object file, you MUST read `.abapGitAgent` to determine the correct folder.**
51
44
 
@@ -58,171 +51,182 @@ The folder is configured in `.abapGitAgent` (property: `folder`):
58
51
  - If `folder` is `/src/` → files go in `src/` (e.g., `src/zcl_my_class.clas.abap`)
59
52
  - If `folder` is `/abap/` → files go in `abap/` (e.g., `abap/zcl_my_class.clas.abap`)
60
53
 
61
- ### 3. Create XML Metadata for Each ABAP Object
54
+ **Also check naming conventions before creating any new object:**
62
55
 
63
- **Each ABAP object requires an XML metadata file for abapGit to understand how to handle it.**
56
+ ```
57
+ 1. Check guidelines/objects.local.md ← project-specific overrides (if file exists)
58
+ 2. Fall back to guidelines/objects.md ← default Z/Y prefix conventions
59
+ ```
64
60
 
65
- | Object Type | ABAP File (if folder=/src/) | XML File |
66
- |-------------|------------------------------|----------|
67
- | Class | `src/zcl_*.clas.abap` | `src/zcl_*.clas.xml` |
68
- | Interface | `src/zif_*.intf.abap` | `src/zif_*.intf.xml` |
69
- | Program | `src/z*.prog.abap` | `src/z*.prog.xml` |
70
- | Table | `src/z*.tabl.abap` | `src/z*.tabl.xml` |
71
- | CDS View | `src/zc_*.ddls.asddls` | `src/zc_*.ddls.xml` |
61
+ `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_`).
72
62
 
73
- **Use `ref --topic abapgit` for complete XML templates.**
63
+ ### 3. Create XML Metadata / Local Classes
74
64
 
75
- ### 4. Use `unit` Command for Unit Tests
65
+ Each ABAP object needs an XML metadata file. Local helper/test-double classes use separate `.locals_def.abap` / `.locals_imp.abap` files.
66
+ → See `guidelines/object-creation.md` for XML templates and local class setup
76
67
 
77
- **Use `abapgit-agent unit` to run ABAP unit tests (AUnit).**
68
+ ### 4. Use Syntax Command Before Commit (for CLAS, INTF, PROG, DDLS)
78
69
 
79
70
  ```
80
- ❌ WRONG: Try to use SE24 or other transaction codes
81
- ✅ CORRECT: Use abapgit-agent unit --files src/zcl_test.clas.testclasses.abap
71
+ ❌ WRONG: Make changes Commit Push Pull → Find errors → Fix → Repeat
72
+ ✅ CORRECT: Make changes Run syntax → Fix locally → Commit → Push → Pull → Done
82
73
  ```
83
74
 
75
+ **For CLAS, INTF, PROG, DDLS files**: Run `syntax` command BEFORE commit to catch errors early.
76
+
84
77
  ```bash
85
- # Run unit tests (after pulling to ABAP)
86
- abapgit-agent unit --files src/zcl_test.clas.testclasses.abap
78
+ # Check syntax of local code (no commit/push needed)
79
+ abapgit-agent syntax --files src/zcl_my_class.clas.abap
80
+
81
+ # Check multiple INDEPENDENT files
82
+ abapgit-agent syntax --files src/zcl_utils.clas.abap,src/zcl_logger.clas.abap
87
83
  ```
88
84
 
89
- ### 5. Use CDS Test Double Framework for CDS View Tests
85
+ **For dependent files, skip `syntax` and use `pull` instead:**
86
+ ```bash
87
+ # ❌ BAD - Interface and implementing class (may show false errors)
88
+ abapgit-agent syntax --files src/zif_my_intf.intf.abap,src/zcl_my_class.clas.abap
90
89
 
91
- **When creating unit tests for CDS views, use the CDS Test Double Framework (`CL_CDS_TEST_ENVIRONMENT`).**
90
+ # GOOD - Use pull instead for dependent files
91
+ git add . && git commit && git push
92
+ abapgit-agent pull --files src/zif_my_intf.intf.abap,src/zcl_my_class.clas.abap
93
+ ```
94
+
95
+ ### 5. Local Helper / Test-Double Classes
96
+
97
+ → See `guidelines/object-creation.md` for local class setup (`locals_def.abap` / `locals_imp.abap`)
98
+
99
+ ### 6. Use `ref`, `view` and `where` Commands to Learn About Unknown Classes/Methods
100
+
101
+ **When working with unfamiliar ABAP classes or methods, follow this priority:**
92
102
 
93
103
  ```
94
- WRONG: Use regular AUnit test class without test doubles
95
- CORRECT: Use CL_CDS_TEST_ENVIRONMENT to create test doubles for CDS views
104
+ 1. First: Check local git repo for usage examples
105
+ 2. Second: Check ABAP reference/cheat sheets
106
+ 3. Third: Use view/where commands to query ABAP system (if needed)
96
107
  ```
97
108
 
98
- **Why**: CDS views read from database tables. Using test doubles allows:
99
- - Injecting test data without affecting production data
100
- - Testing specific scenarios that may not exist in production
101
- - Fast, isolated tests that don't depend on database state
109
+ ```bash
110
+ # Find where a class/interface is USED
111
+ abapgit-agent where --objects ZIF_UNKNOWN_INTERFACE
102
112
 
103
- See `../guidelines/testing.md` for code examples.
113
+ # View CLASS DEFINITION
114
+ abapgit-agent view --objects ZCL_UNKNOWN_CLASS
115
+ ```
104
116
 
105
- ---
117
+ ### 7. CDS Unit Tests
106
118
 
107
- ## Development Workflow
119
+ Use `CL_CDS_TEST_ENVIRONMENT` for unit tests that read CDS views.
120
+ → See `guidelines/cds-testing.md` for code examples
121
+
122
+ ### 8. Use `unit` Command for Unit Tests
108
123
 
124
+ **Use `abapgit-agent unit` to run ABAP unit tests (AUnit).**
125
+
126
+ ```
127
+ ❌ WRONG: Try to use SE24, SE37, or other transaction codes
128
+ ✅ CORRECT: Use abapgit-agent unit --files src/zcl_test.clas.testclasses.abap
109
129
  ```
110
- 1. Read .abapGitAgent → get folder value
111
-
112
-
113
- 2. Research → use ref command for unfamiliar topics
114
-
115
-
116
- 3. Write code → place in correct folder (e.g., src/zcl_*.clas.abap)
117
-
118
-
119
- 4. Commit and push → git add . && git commit && git push
120
-
121
-
122
- 5. Activate → abapgit-agent pull --files src/file.clas.abap
123
-
124
-
125
- 6. Verify → Check pull output
126
- - **Do NOT run inspect before commit/push/pull** - ABAP validates on pull
127
- - **Do NOT run unit before pull** - Tests run against ABAP system, code must be activated first
128
- - Objects NOT in "Activated Objects" but in "Failed Objects Log" → Syntax error (check inspect)
129
- - Objects NOT appearing at all → XML metadata issue
130
-
131
-
132
- 7. (Optional) Run unit tests → abapgit-agent unit --files src/zcl_test.clas.testclasses.abap (ONLY if test file exists, AFTER successful pull)
133
-
134
-
135
- 8. If needed → Use inspect to check syntax (runs against ABAP system)
136
- ```
137
-
138
- **IMPORTANT**:
139
- - **ALWAYS push to git BEFORE running pull** - abapGit reads from git
140
- - **Use inspect AFTER pull** to check syntax on objects already in ABAP
141
- - **Check pull output**:
142
- - In "Failed Objects Log" → Syntax error (use inspect for details)
143
- - Not appearing at all → XML metadata is wrong
144
-
145
- **When to use inspect vs view**:
146
- - **inspect**: Use when there are SYNTAX ERRORS (to find line numbers and details)
147
- - **view**: Use when you need to understand an object STRUCTURE (table fields, class methods)
148
- - Do NOT use view to debug syntax errors - view shows definitions, not errors
149
-
150
- ### Commands
151
130
 
152
131
  ```bash
153
- # 1. Pull/activate after pushing to git (abapGit reads from git!)
154
- abapgit-agent pull --files src/zcl_class1.clas.abap,src/zcl_class2.clas.abap
155
-
156
- # 2. Inspect AFTER pull to check syntax (runs against ABAP system)
157
- abapgit-agent inspect --files src/zcl_class1.clas.abap,src/zif_interface1.intf.abap
132
+ # Run unit tests (after pulling to ABAP)
133
+ abapgit-agent unit --files src/zcl_test.clas.testclasses.abap
158
134
 
159
- # Run unit tests (multiple test classes)
135
+ # Multiple test classes
160
136
  abapgit-agent unit --files src/zcl_test1.clas.testclasses.abap,src/zcl_test2.clas.testclasses.abap
137
+ ```
161
138
 
162
- # View object definitions (multiple objects)
163
- abapgit-agent view --objects ZCL_CLASS1,ZCL_CLASS2,ZIF_INTERFACE
164
-
165
- # Preview table data (multiple tables/views)
166
- abapgit-agent preview --objects ZTABLE1,ZTABLE2
139
+ ### 9. Troubleshooting ABAP Issues
167
140
 
168
- # Explore table structures
169
- abapgit-agent view --objects ZTABLE --type TABL
141
+ | Symptom | Tool | When |
142
+ |---|---|---|
143
+ | HTTP 500 / runtime crash (ST22) | `dump` | Error already occurred |
144
+ | Wrong output, no crash | `debug` | Need to trace logic |
170
145
 
171
- # Display package tree
172
- abapgit-agent tree --package \$MY_PACKAGE
146
+ Quick start:
147
+ ```bash
148
+ abapgit-agent dump --date TODAY --detail 1 # inspect last crash
149
+ abapgit-agent debug set --objects ZCL_FOO:42 # set breakpoint then attach
173
150
  ```
151
+ → See `guidelines/debug-dump.md` for dump analysis workflow
152
+ → See `guidelines/debug-session.md` for full debug session guide, breakpoint tips, and pull flow architecture
174
153
 
175
154
  ---
176
155
 
177
- ## Explore Unknown Objects
156
+ ## Development Workflow
157
+
158
+ This project's workflow mode is configured in `.abapGitAgent` under `workflow.mode`.
178
159
 
179
- **Before working with unfamiliar objects, use `view` command:**
160
+ ### Project-Level Config (`.abapgit-agent.json`)
180
161
 
181
- ```bash
182
- # Check table structure
183
- abapgit-agent view --objects ZMY_TABLE --type TABL
162
+ Checked into the repository — applies to all developers. **Read this file at the start of every session.**
184
163
 
185
- # Check class definition
186
- abapgit-agent view --objects ZCL_UNKNOWN_CLASS
164
+ | Setting | Values | Default | Effect |
165
+ |---------|--------|---------|--------|
166
+ | `safeguards.requireFilesForPull` | `true`/`false` | `false` | Requires `--files` on every pull |
167
+ | `safeguards.disablePull` | `true`/`false` | `false` | Disables pull entirely (CI/CD-only projects) |
168
+ | `conflictDetection.mode` | `"abort"`/`"ignore"` | `"abort"` | Whether to abort pull on conflict |
169
+ | `transports.allowCreate` | `true`/`false` | `true` | When `false`, `transport create` is blocked |
170
+ | `transports.allowRelease` | `true`/`false` | `true` | When `false`, `transport release` is blocked |
187
171
 
188
- # Check interface
189
- abapgit-agent view --objects ZIF_UNKNOWN_INTERFACE
172
+ ### Workflow Modes
190
173
 
191
- # Check data element
192
- abapgit-agent view --objects ZMY_DTEL --type DTEL
174
+ | Mode | Branch Strategy | Rebase Before Pull | Create PR |
175
+ |------|----------------|-------------------|-----------|
176
+ | `"branch"` | Feature branches | ✓ Always | ✓ Yes (squash merge) |
177
+ | `"trunk"` | Direct to default branch | ✗ No | ✗ No |
178
+ | (not set) | Direct to default branch | ✗ No | ✗ No |
179
+
180
+ ### Trunk Workflow (`"mode": "trunk"`)
181
+
182
+ ```bash
183
+ git checkout main
184
+ git pull origin main
185
+ edit src/zcl_auth_handler.clas.abap
186
+ abapgit-agent syntax --files src/zcl_auth_handler.clas.abap
187
+ git add . && git commit -m "feat: add authentication handler"
188
+ git push origin main
189
+ abapgit-agent pull --files src/zcl_auth_handler.clas.abap
193
190
  ```
194
191
 
195
- AI assistant SHOULD call `view` command when:
196
- - User asks to "check", "look up", or "explore" an unfamiliar object
197
- - Working with a table/structure and you don't know the fields
198
- - Calling a class/interface method and you don't know the parameters
192
+ ### Branch Workflow (`"mode": "branch"`)
199
193
 
200
- ---
194
+ → See `guidelines/branch-workflow.md` for step-by-step commands and examples
201
195
 
202
- ## Key ABAP Rules
196
+ ### AI Tool Guidelines
203
197
 
204
- 1. **Global classes MUST use `PUBLIC`**:
205
- ```abap
206
- CLASS zcl_my_class DEFINITION PUBLIC. " <- REQUIRED
207
- ```
198
+ **When `workflow.mode = "branch"`:**
199
+ 1. ✓ Create feature branches (naming: `feature/description`)
200
+ 2. Always `git fetch origin <default> && git rebase origin/<default>` before `pull` command
201
+ 3. ✓ Use `--force-with-lease` after rebase (never `--force`)
202
+ 4. ✓ Create PR with squash merge when feature complete
203
+ 5. ✗ Never commit directly to default branch
208
204
 
209
- 2. **Use `/ui2/cl_json` for JSON**:
210
- ```abap
211
- DATA ls_data TYPE ty_request.
212
- ls_data = /ui2/cl_json=>deserialize( json = lv_json ).
213
- lv_json = /ui2/cl_json=>serialize( data = ls_response ).
214
- ```
205
+ **When `workflow.mode = "trunk"` or not set:**
206
+ 1. ✓ Commit directly to default branch
207
+ 2. `git pull origin <default>` before push
208
+ 3. Don't create feature branches
215
209
 
216
- 3. **Test class name max 30 chars**: `ltcl_util` (not `ltcl_abgagt_util_test`)
210
+ **When `safeguards.requireFilesForPull = true`:** always include `--files` in every `pull` command
217
211
 
218
- 4. **Interface method implementation**: Use prefix `zif_interface~method_name`
212
+ **When `safeguards.disablePull = true`:** do not run `abapgit-agent pull` at all
219
213
 
220
- ---
214
+ **When `conflictDetection.mode = "abort"`:** if pull aborts with conflict error, inform user and suggest `--conflict-mode ignore` to override for that run
215
+
216
+ ### Quick Decision Tree
221
217
 
222
- ## Error Handling
218
+ ```
219
+ Modified ABAP files?
220
+ ├─ CLAS/INTF/PROG/DDLS files?
221
+ │ ├─ Independent files (no cross-dependencies)?
222
+ │ │ └─ ✅ Use: syntax → commit → push → pull
223
+ │ └─ Dependent files (interface + class, class uses class)?
224
+ │ └─ ✅ Use: skip syntax → commit → push → pull
225
+ └─ Other types (FUGR, TABL, etc.)?
226
+ └─ ✅ Use: skip syntax → commit → push → pull → (if errors: inspect)
227
+ ```
223
228
 
224
- - **"Error updating where-used list"** This is a **SYNTAX ERROR** (not a warning!)
225
- - Use `abapgit-agent inspect --files <file>` for detailed error messages with line numbers
229
+ See `guidelines/workflow-detailed.md` for full workflow decision tree, error indicators, and complete command reference
226
230
 
227
231
  ---
228
232
 
@@ -232,23 +236,29 @@ Detailed guidelines are available in the `guidelines/` folder:
232
236
 
233
237
  | File | Topic |
234
238
  |------|-------|
235
- | `../guidelines/sql.md` | ABAP SQL Best Practices |
236
- | `../guidelines/exceptions.md` | Exception Handling |
237
- | `../guidelines/testing.md` | Unit Testing (including CDS) |
238
- | `../guidelines/cds.md` | CDS Views |
239
- | `../guidelines/classes.md` | ABAP Classes and Objects |
240
- | `../guidelines/objects.md` | Object Naming Conventions |
241
- | `../guidelines/json.md` | JSON Handling |
242
- | `../guidelines/abapgit.md` | abapGit XML Metadata Templates |
239
+ | `guidelines/sql.md` | ABAP SQL Best Practices |
240
+ | `guidelines/exceptions.md` | Exception Handling |
241
+ | `guidelines/testing.md` | Unit Testing (including CDS) |
242
+ | `guidelines/cds.md` | CDS Views |
243
+ | `guidelines/classes.md` | ABAP Classes and Objects |
244
+ | `guidelines/objects.md` | Object Naming Conventions (defaults) |
245
+ | `guidelines/objects.local.md` | **Project** Naming Conventions — overrides `objects.md` (never overwritten) |
246
+ | `guidelines/json.md` | JSON Handling |
247
+ | `guidelines/abapgit.md` | abapGit XML Metadata Templates |
248
+ | `guidelines/unit-testable-code.md` | Unit Testable Code Guidelines (Dependency Injection) |
249
+ | `guidelines/common-errors.md` | Common ABAP Errors - Quick Fixes |
250
+ | `guidelines/debug-session.md` | Debug Session Guide |
251
+ | `guidelines/debug-dump.md` | Dump Analysis Guide |
252
+ | `guidelines/branch-workflow.md` | Branch Workflow |
253
+ | `guidelines/workflow-detailed.md` | Development Workflow (Detailed) |
254
+ | `guidelines/object-creation.md` | Object Creation (XML metadata, local classes) |
255
+ | `guidelines/cds-testing.md` | CDS Testing (Test Double Framework) |
243
256
 
244
257
  These guidelines are automatically searched by the `ref` command.
245
258
 
246
259
  ---
247
260
 
248
- ## Object Naming
261
+ ## For More Information
249
262
 
250
- | Pattern | Type |
251
- |---------|------|
252
- | `ZCL_*` | Class |
253
- | `ZIF_*` | Interface |
254
- | `Z*` | Other objects |
263
+ - [SAP ABAP Cheat Sheets](https://github.com/SAP-samples/abap-cheat-sheets)
264
+ - [ABAP Keyword Documentation](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm)
package/abap/CLAUDE.md CHANGED
@@ -225,7 +225,23 @@ abapgit-agent unit --files src/zcl_test1.clas.testclasses.abap,src/zcl_test2.cla
225
225
 
226
226
  ---
227
227
 
228
- ### 9. Troubleshooting ABAP Issues
228
+ ### 9. Never Run `run` Command Proactively
229
+
230
+ **Never call `abapgit-agent run` unless the user explicitly asks.** A class implementing `IF_OO_ADT_CLASSRUN` can modify data, send emails, or trigger RFCs — running it automatically is unsafe.
231
+
232
+ After activating a class, stop and tell the user: `"Class is activated. Run with: abapgit-agent run --class ZCL_MY_CLASS"`
233
+
234
+ ---
235
+
236
+ ### 10. Probe Classes — Use `scratchWorkspace` When Required
237
+
238
+ 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.
239
+
240
+ → See `guidelines/run-probe-classes.md` for naming conventions, full workflow, and refusal guidance
241
+
242
+ ---
243
+
244
+ ### 11. Troubleshooting ABAP Issues
229
245
 
230
246
  | Symptom | Tool | When |
231
247
  |---|---|---|
@@ -236,6 +252,7 @@ Quick start:
236
252
  ```bash
237
253
  abapgit-agent dump --date TODAY --detail 1 # inspect last crash
238
254
  abapgit-agent debug set --objects ZCL_FOO:42 # set breakpoint then attach
255
+ abapgit-agent run --class ZCL_MY_RUNNER # execute and inspect output
239
256
  ```
240
257
  → See `guidelines/debug-dump.md` for dump analysis workflow
241
258
  → See `guidelines/debug-session.md` for full debug session guide, breakpoint tips, and pull flow architecture
@@ -326,6 +343,13 @@ abapgit-agent pull --files src/zcl_auth_handler.clas.abap
326
343
  1. ✗ Do not run `abapgit-agent pull` at all
327
344
  2. ✓ Inform the user that pull is disabled for this project (CI/CD only)
328
345
 
346
+ **When `safeguards.disableRun = true`:**
347
+ 1. ✗ Do not run `abapgit-agent run` at all
348
+ 2. ✓ Inform the user that run is disabled for this project
349
+
350
+ **When `safeguards.disableProbeClasses = true`:**
351
+ 1. ✗ Do not create probe classes in the current project — see Rule 10 and `guidelines/run-command.md`
352
+
329
353
  **When `conflictDetection.mode = "ignore"` or not set:**
330
354
  1. ✓ Run `pull` normally — no conflict flags needed
331
355
  2. ✗ Don't add `--conflict-mode` unless user explicitly asks
@@ -384,6 +408,7 @@ Detailed guidelines are available in the `guidelines/` folder:
384
408
  | `guidelines/common-errors.md` | Common ABAP Errors - Quick Fixes |
385
409
  | `guidelines/debug-session.md` | Debug Session Guide |
386
410
  | `guidelines/debug-dump.md` | Dump Analysis Guide |
411
+ | `guidelines/run-probe-classes.md` | run Command — AI Guidelines (probe classes, scratchWorkspace) |
387
412
  | `guidelines/branch-workflow.md` | Branch Workflow |
388
413
  | `guidelines/workflow-detailed.md` | Development Workflow (Detailed) |
389
414
  | `guidelines/object-creation.md` | Object Creation (XML metadata, local classes) |
@@ -166,7 +166,7 @@ abapgit-agent debug stack --json # call stack (shows whi
166
166
  abapgit-agent debug delete --all
167
167
  ```
168
168
 
169
- > **If the stale debug daemon holds an ABAP lock** (symptom: `Requested object EZABAPGIT is currently locked by user CAIS`):
169
+ > **If the stale debug daemon holds an ABAP lock** (symptom: `Requested object EZABAPGIT is currently locked by user <USER>`):
170
170
  > ```bash
171
171
  > pkill -f "debug-daemon" # kills daemon, SIGTERM triggers session.terminate() internally
172
172
  > ```
@@ -0,0 +1,67 @@
1
+ ---
2
+ layout: default
3
+ title: run Command Guide
4
+ nav_order: 18
5
+ parent: ABAP Coding Guidelines
6
+ grand_parent: ABAP Development
7
+ ---
8
+
9
+ # run Command — AI Guidelines
10
+
11
+ ## Never Run Proactively
12
+
13
+ `abapgit-agent run` executes live ABAP code. **Never call it unless the user explicitly asks.**
14
+
15
+ A class implementing `IF_OO_ADT_CLASSRUN` can do anything — modify database records, send emails, trigger RFCs. The interface signature gives no indication of side effects.
16
+
17
+ ```
18
+ User: "Write a class that reads flight data and prints it"
19
+ → ✓ Create the class, pull it, STOP. Do NOT run it.
20
+ → ✓ Tell the user: "Class is activated. Run with: abapgit-agent run --class ZCL_MY_CLASS"
21
+
22
+ User: "Now run it"
23
+ → ✓ Run it
24
+ ```
25
+
26
+ ---
27
+
28
+ ## Probe Classes and `scratchWorkspace`
29
+
30
+ ### Decision flow
31
+
32
+ ```
33
+ User asks to create a probe class
34
+ ├── disableProbeClasses = false / not set → create in current project (default)
35
+ └── disableProbeClasses = true
36
+ ├── scratchWorkspace configured → create there (see workflow below)
37
+ └── scratchWorkspace not configured → refuse, guide user to set it up
38
+ ```
39
+
40
+ ### When `disableProbeClasses = true` and `scratchWorkspace` is configured
41
+
42
+ **Naming** — derive from `scratchWorkspace` config in `.abapGitAgent`:
43
+ - `classPrefix` (default: `ZCL_{USER}_`) + `<PURPOSE>`, max 30 chars
44
+ - Example: user=`JOHN`, purpose=`OPEN_TRANSPORTS` → `ZCL_JOHN_OPEN_TRANSPORTS`
45
+ - If name already exists in `{path}/src/`, append `_2`, `_3`, etc.
46
+
47
+ **Workflow:**
48
+ 1. Read `{path}/.abapGitAgent` to confirm `folder` property (e.g. `/src/`)
49
+ 2. Write class files in `{path}/src/`
50
+ 3. Commit and push from `{path}`:
51
+ ```bash
52
+ cd {path} && git add . && git commit -m "probe: <description>" && git push
53
+ ```
54
+ 4. Activate:
55
+ ```bash
56
+ cd {path} && abapgit-agent pull --files src/<classname>.clas.abap
57
+ ```
58
+ 5. Tell user (do NOT auto-run):
59
+ ```
60
+ Class activated. Run with: abapgit-agent run --class <CLASSNAME>
61
+ ```
62
+ Run the command from the original project directory, not `{path}`.
63
+
64
+ ### When `disableProbeClasses = true` and `scratchWorkspace` is NOT configured
65
+
66
+ Refuse and tell the user to configure `scratchWorkspace` in `.abapGitAgent`.
67
+ → See `docs/run-command.md` (Scratch Workspace section) for setup instructions.
package/bin/abapgit-agent CHANGED
@@ -24,7 +24,7 @@ const gitUtils = require('../src/utils/git-utils');
24
24
  const versionCheck = require('../src/utils/version-check');
25
25
  const validators = require('../src/utils/validators');
26
26
  const { AbapHttp } = require('../src/utils/abap-http');
27
- const { loadConfig, getTransport, isAbapIntegrationEnabled, getSafeguards, getConflictSettings, getTransportSettings } = require('../src/config');
27
+ const { loadConfig, getTransport, isAbapIntegrationEnabled, getSafeguards, getConflictSettings, getTransportSettings, getScratchWorkspace } = require('../src/config');
28
28
 
29
29
  // Get terminal width for responsive table
30
30
  const getTermWidth = () => process.stdout.columns || 80;
@@ -52,6 +52,7 @@ async function main() {
52
52
  where: require('../src/commands/where'),
53
53
  dump: require('../src/commands/dump'),
54
54
  debug: require('../src/commands/debug'),
55
+ run: require('../src/commands/run'),
55
56
  ref: require('../src/commands/ref'),
56
57
  init: require('../src/commands/init'),
57
58
  pull: require('../src/commands/pull'),
@@ -105,7 +106,8 @@ To enable integration:
105
106
  getTransport,
106
107
  getSafeguards,
107
108
  getConflictSettings,
108
- getTransportSettings
109
+ getTransportSettings,
110
+ getScratchWorkspace
109
111
  };
110
112
 
111
113
  // Execute command
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "abapgit-agent",
3
- "version": "1.11.3",
3
+ "version": "1.12.0",
4
4
  "description": "ABAP Git Agent - Pull and activate ABAP code via abapGit from any git repository",
5
5
  "main": "src/index.js",
6
6
  "files": [
@@ -4,6 +4,7 @@
4
4
 
5
5
  const pathModule = require('path');
6
6
  const fs = require('fs');
7
+ const readline = require('readline');
7
8
 
8
9
  /**
9
10
  * Copy a file if source exists (helper for init --update)
@@ -74,6 +75,42 @@ async function copyGuidelinesFolder(srcPath, destPath, overwrite = false) {
74
75
  }
75
76
  }
76
77
 
78
+ /**
79
+ * Detect old numbered guideline files (e.g. 00_index.md, 01_sql.md) and
80
+ * prompt user to delete them if found.
81
+ */
82
+ async function cleanupOldGuidelineFiles(guidelinesPath) {
83
+ if (!fs.existsSync(guidelinesPath)) return;
84
+
85
+ const oldFiles = fs.readdirSync(guidelinesPath)
86
+ .filter(f => /^\d+_.*\.md$/.test(f));
87
+
88
+ if (oldFiles.length === 0) return;
89
+
90
+ console.log('');
91
+ console.log('⚠️ Old numbered guideline files detected (from a previous version):');
92
+ oldFiles.forEach(f => console.log(` guidelines/${f}`));
93
+ console.log(' These have been renamed and are no longer used.');
94
+
95
+ const answer = await new Promise((resolve) => {
96
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
97
+ rl.question('Delete old files? [Y/n] ', (ans) => {
98
+ rl.close();
99
+ resolve(ans.trim().toLowerCase());
100
+ });
101
+ });
102
+
103
+ if (answer === '' || answer === 'y' || answer === 'yes') {
104
+ oldFiles.forEach(f => {
105
+ fs.unlinkSync(pathModule.join(guidelinesPath, f));
106
+ console.log(` 🗑 Deleted guidelines/${f}`);
107
+ });
108
+ console.log(`✅ Old guideline files removed`);
109
+ } else {
110
+ console.log('⚠️ Old files kept — they may appear as duplicates in ref search results');
111
+ }
112
+ }
113
+
77
114
  module.exports = {
78
115
  name: 'init',
79
116
  description: 'Initialize local repository configuration',
@@ -187,6 +224,9 @@ Examples:
187
224
  true // overwrite
188
225
  );
189
226
 
227
+ // Detect and offer to remove old numbered guideline files
228
+ await cleanupOldGuidelineFiles(pathModule.join(process.cwd(), 'guidelines'));
229
+
190
230
  console.log(`
191
231
  📋 Update complete!
192
232
  Run 'abapgit-agent ref --list-topics' to see available topics.
@@ -284,11 +284,9 @@ module.exports = {
284
284
 
285
285
  if (success === 'X' || success === true) {
286
286
  console.log(`✅ Pull completed successfully!`);
287
- console.log(` Job ID: ${jobId || 'N/A'}`);
288
287
  console.log(` Message: ${message || 'N/A'}`);
289
288
  } else {
290
289
  console.error(`❌ Pull completed with errors!`);
291
- console.error(` Job ID: ${jobId || 'N/A'}`);
292
290
  console.error(` Message: ${message || 'N/A'}`);
293
291
  }
294
292
 
@@ -0,0 +1,123 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * run command — Execute an ABAP program or class and display its output.
5
+ *
6
+ * Programs (--program):
7
+ * POST /sap/bc/adt/programs/programrun/{name}
8
+ * Content-Type: application/vnd.sap.adt.programs.programRun+xml
9
+ * Accept: text/plain
10
+ * Note: SAP's ADT handler (CL_SEDI_ADT_PROGRAMRUN) calls SUBMIT with no
11
+ * WITH additions — runtime parameters cannot be passed. The program
12
+ * always runs with its coded defaults.
13
+ *
14
+ * Classes (--class):
15
+ * POST /sap/bc/adt/oo/classrun/{name}
16
+ * Accept: text/plain
17
+ * Requires the class to implement IF_OO_ADT_CLASSRUN.
18
+ * out->write() output is returned as plain text.
19
+ */
20
+
21
+ const { AdtHttp } = require('../utils/adt-http');
22
+
23
+ const PROGRAM_RUN_XML =
24
+ '<?xml version="1.0" encoding="UTF-8"?>\n' +
25
+ '<adtprog:programRun xmlns:adtprog="http://www.sap.com/adt/programs/programs"/>';
26
+
27
+ module.exports = {
28
+ name: 'run',
29
+ description: 'Execute an ABAP program or class (IF_OO_ADT_CLASSRUN) and display its output',
30
+ requiresAbapConfig: true,
31
+ requiresVersionCheck: false,
32
+
33
+ async execute(args, context) {
34
+ const { loadConfig, getSafeguards } = context;
35
+
36
+ // Check project-level safeguards
37
+ const safeguards = getSafeguards();
38
+ if (safeguards.disableRun) {
39
+ console.error('❌ Error: run command is disabled for this project\n');
40
+ if (safeguards.reason) {
41
+ console.error(`Reason: ${safeguards.reason}\n`);
42
+ }
43
+ console.error('The run command has been disabled in .abapgit-agent.json');
44
+ console.error('Please contact the project maintainer to enable it.');
45
+ process.exit(1);
46
+ }
47
+
48
+ // Parse arguments
49
+ let programName = null;
50
+ let className = null;
51
+ let jsonOutput = false;
52
+
53
+ for (let i = 0; i < args.length; i++) {
54
+ if (args[i] === '--program' && args[i + 1]) {
55
+ programName = args[++i].toUpperCase();
56
+ } else if (args[i] === '--class' && args[i + 1]) {
57
+ className = args[++i].toUpperCase();
58
+ } else if (args[i] === '--json') {
59
+ jsonOutput = true;
60
+ }
61
+ }
62
+
63
+ if (programName && className) {
64
+ console.error('Error: --program and --class are mutually exclusive');
65
+ process.exit(1);
66
+ }
67
+
68
+ if (!programName && !className) {
69
+ console.error('Error: either --program or --class is required');
70
+ console.error('Usage: abapgit-agent run --program <NAME>');
71
+ console.error(' abapgit-agent run --class <NAME>');
72
+ process.exit(1);
73
+ }
74
+
75
+ const config = loadConfig();
76
+ const adt = new AdtHttp(config);
77
+
78
+ if (!adt.csrfToken) {
79
+ await adt.fetchCsrfToken();
80
+ }
81
+
82
+ let urlPath, body, requestOptions, targetName;
83
+
84
+ if (className) {
85
+ targetName = className;
86
+ urlPath = `/sap/bc/adt/oo/classrun/${className}`;
87
+ body = '';
88
+ requestOptions = { accept: 'text/plain' };
89
+ } else {
90
+ targetName = programName;
91
+ urlPath = `/sap/bc/adt/programs/programrun/${programName}`;
92
+ body = PROGRAM_RUN_XML;
93
+ requestOptions = {
94
+ contentType: 'application/vnd.sap.adt.programs.programRun+xml',
95
+ accept: 'text/plain'
96
+ };
97
+ }
98
+
99
+ let response;
100
+ try {
101
+ response = await adt.request('POST', urlPath, body, requestOptions);
102
+ } catch (err) {
103
+ if (jsonOutput) {
104
+ console.log(JSON.stringify({ success: false, target: targetName, error: err.message || String(err) }));
105
+ } else {
106
+ console.error(`Error: ${err.message || err}`);
107
+ }
108
+ process.exit(1);
109
+ }
110
+
111
+ const output = (response.body || '').trimEnd();
112
+
113
+ if (jsonOutput) {
114
+ const key = className ? 'class' : 'program';
115
+ console.log(JSON.stringify({ success: true, [key]: targetName, output }));
116
+ } else {
117
+ console.log('\n--- Output ---');
118
+ console.log(output || '(no output)');
119
+ console.log('--------------');
120
+ console.log(`✅ Completed: ${targetName}`);
121
+ }
122
+ }
123
+ };
package/src/config.js CHANGED
@@ -122,6 +122,8 @@ function getSafeguards() {
122
122
  return {
123
123
  requireFilesForPull: projectConfig.safeguards.requireFilesForPull === true,
124
124
  disablePull: projectConfig.safeguards.disablePull === true,
125
+ disableRun: projectConfig.safeguards.disableRun === true,
126
+ disableProbeClasses: projectConfig.safeguards.disableProbeClasses === true,
125
127
  reason: projectConfig.safeguards.reason || null
126
128
  };
127
129
  }
@@ -130,6 +132,8 @@ function getSafeguards() {
130
132
  return {
131
133
  requireFilesForPull: false,
132
134
  disablePull: false,
135
+ disableRun: false,
136
+ disableProbeClasses: false,
133
137
  reason: null
134
138
  };
135
139
  }
@@ -199,6 +203,22 @@ function getTransportSettings() {
199
203
  return { allowCreate: true, allowRelease: true, reason: null };
200
204
  }
201
205
 
206
+ /**
207
+ * Get scratch workspace configuration from personal config (.abapGitAgent)
208
+ * Used by AI to create probe/throwaway ABAP classes outside the current project
209
+ * @returns {{ path: string, classPrefix: string, programPrefix: string }|null}
210
+ */
211
+ function getScratchWorkspace() {
212
+ const cfg = loadConfig();
213
+ if (!cfg.scratchWorkspace) return null;
214
+ const user = (cfg.user || 'PROBE').toUpperCase();
215
+ return {
216
+ path: cfg.scratchWorkspace.path || null,
217
+ classPrefix: cfg.scratchWorkspace.classPrefix || `ZCL_${user}_`,
218
+ programPrefix: cfg.scratchWorkspace.programPrefix || `Z${user}_`
219
+ };
220
+ }
221
+
202
222
  module.exports = {
203
223
  loadConfig,
204
224
  getAbapConfig,
@@ -211,5 +231,6 @@ module.exports = {
211
231
  getConflictSettings,
212
232
  loadProjectConfig,
213
233
  getTransportHookConfig,
214
- getTransportSettings
234
+ getTransportSettings,
235
+ getScratchWorkspace
215
236
  };