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.
- package/abap/.github/copilot-instructions.md +148 -138
- package/abap/CLAUDE.md +26 -1
- package/abap/guidelines/debug-session.md +1 -1
- package/abap/guidelines/run-probe-classes.md +67 -0
- package/bin/abapgit-agent +4 -2
- package/package.json +1 -1
- package/src/commands/init.js +40 -0
- package/src/commands/pull.js +0 -2
- package/src/commands/run.js +123 -0
- package/src/config.js +22 -1
|
@@ -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
|
-
|
|
54
|
+
**Also check naming conventions before creating any new object:**
|
|
62
55
|
|
|
63
|
-
|
|
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
|
-
|
|
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
|
-
|
|
63
|
+
### 3. Create XML Metadata / Local Classes
|
|
74
64
|
|
|
75
|
-
|
|
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
|
-
|
|
68
|
+
### 4. Use Syntax Command Before Commit (for CLAS, INTF, PROG, DDLS)
|
|
78
69
|
|
|
79
70
|
```
|
|
80
|
-
❌ WRONG:
|
|
81
|
-
✅ CORRECT:
|
|
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
|
-
#
|
|
86
|
-
abapgit-agent
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
95
|
-
|
|
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
|
-
|
|
99
|
-
|
|
100
|
-
-
|
|
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
|
-
|
|
113
|
+
# View CLASS DEFINITION
|
|
114
|
+
abapgit-agent view --objects ZCL_UNKNOWN_CLASS
|
|
115
|
+
```
|
|
104
116
|
|
|
105
|
-
|
|
117
|
+
### 7. CDS Unit Tests
|
|
106
118
|
|
|
107
|
-
|
|
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
|
-
#
|
|
154
|
-
abapgit-agent
|
|
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
|
-
#
|
|
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
|
-
|
|
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
|
-
|
|
169
|
-
|
|
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
|
-
|
|
172
|
-
|
|
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
|
-
##
|
|
156
|
+
## Development Workflow
|
|
157
|
+
|
|
158
|
+
This project's workflow mode is configured in `.abapGitAgent` under `workflow.mode`.
|
|
178
159
|
|
|
179
|
-
|
|
160
|
+
### Project-Level Config (`.abapgit-agent.json`)
|
|
180
161
|
|
|
181
|
-
|
|
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
|
-
|
|
186
|
-
|
|
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
|
-
|
|
189
|
-
abapgit-agent view --objects ZIF_UNKNOWN_INTERFACE
|
|
172
|
+
### Workflow Modes
|
|
190
173
|
|
|
191
|
-
|
|
192
|
-
|
|
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
|
-
|
|
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
|
-
|
|
196
|
+
### AI Tool Guidelines
|
|
203
197
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
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
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
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
|
-
|
|
210
|
+
**When `safeguards.requireFilesForPull = true`:** always include `--files` in every `pull` command
|
|
217
211
|
|
|
218
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
|
236
|
-
|
|
|
237
|
-
|
|
|
238
|
-
|
|
|
239
|
-
|
|
|
240
|
-
|
|
|
241
|
-
|
|
|
242
|
-
|
|
|
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
|
-
##
|
|
261
|
+
## For More Information
|
|
249
262
|
|
|
250
|
-
|
|
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.
|
|
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
|
|
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
package/src/commands/init.js
CHANGED
|
@@ -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.
|
package/src/commands/pull.js
CHANGED
|
@@ -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
|
};
|