Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
0da189a
feat: abapGit roundtrip - export, deploy, and structure support
ThePlenkov Mar 17, 2026
66a6348
chore: update abapgit-examples submodule to c1980b0
ThePlenkov Mar 17, 2026
130168d
feat: add adt diff command and fix CDS-to-abapGit serialization
ThePlenkov Mar 17, 2026
a8198fa
feat: resolve DDIC metadata via ADT for zero-diff TABL serialization
ThePlenkov Mar 17, 2026
5ba5e65
feat(adt-diff): add --format ddl option and fix CDS DDL generation
ThePlenkov Mar 18, 2026
0d06b3c
fix(cds-to-abapgit): stop emitting LANGDEP, CLIDEP, POSITION from CDS…
ThePlenkov Mar 18, 2026
b1357ac
fix(adt-diff): use .acds extension for CDS DDL diff display
ThePlenkov Mar 18, 2026
ff711e8
feat(cds-to-abapgit): detect LANGDEP from spras/lang fields in CDS
ThePlenkov Mar 18, 2026
20a4ac7
fix(cds-to-abapgit): correct DD03P field ordering to match SAP
ThePlenkov Mar 18, 2026
61ce2ba
Revert "fix(cds-to-abapgit): correct DD03P field ordering to match SAP"
ThePlenkov Mar 18, 2026
d7578d3
fix(abapgit): align dd02v and dd03p field order
ThePlenkov Mar 18, 2026
50e1200
fix(cds-to-abapgit): detect CLIDEP for client-dependent tables
ThePlenkov Mar 18, 2026
c0c3128
feat(adt-diff): support multi-file and glob patterns in diff command
ThePlenkov Mar 18, 2026
591ea22
fix(adt-diff): align zage_tabl test expectations with fixture
ThePlenkov Mar 18, 2026
83e8684
chore: unify AI agent rules under .agents/rules/
ThePlenkov Mar 18, 2026
d7ba7b9
chore: add Windsurf frontmatter triggers to all agent rules
ThePlenkov Mar 18, 2026
1bf9751
chore: remove redundant agent rules, consolidate into AGENTS.md
ThePlenkov Mar 18, 2026
877475c
docs: cross-link agent rules and skills, standardize tool references
ThePlenkov Mar 18, 2026
07a59da
feat(adt-diff): rename --format to --source, add annotation filtering…
ThePlenkov Mar 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .agents/rules/adt/adk-save-logic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
trigger: model_decision
description: Complex logic handling for ADK object save, upsert, and locking.
---

# ADK Save and Upsert Logic

## Upsert Fallback Handling
`AdkObject.save()` upsert fallback has **TWO** catch paths that both need `422 "already exists"` handling to correctly mark objects as unchanged instead of failing.

1. **Lock Catch:**
- If Lock fails -> `shouldFallbackToCreate(e)` -> try create.
- Catch `422 "already exists"` -> mark unchanged.

2. **Outer saveViaContract Catch:**
- If Lock succeeds but PUT fails (e.g. `405 Method Not Allowed`) -> `shouldFallbackToCreate(e)` -> try create.
- Catch `422 "already exists"` -> mark unchanged.

**Note:** Both paths must wrap their `save({ mode: 'create' })` calls in try/catch blocks that check `isAlreadyExistsError(e)`.

## Endpoint Behaviors
- **TABL Lock:** Can succeed for existing objects, but subsequent metadata PUT returns `405 Method Not Allowed`.
- **TTYP Lock:** Returns `405` when object doesn't exist (instead of `404`).
- **Create (POST):** Returns `422` (or "Unprocessable") with "already exists" message if object exists.
39 changes: 39 additions & 0 deletions .agents/rules/adt/adt-ddic-mapping.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
trigger: model_decision
description: Mapping of SAP ADT DDIC objects to their root elements and schemas.
---

# SAP ADT DDIC Object Mapping

SAP ADT wraps DDIC object responses in different root elements depending on the object type.

## Mappings

### DOMA (Domain)
- **Root Element:** `domain`
- **Namespace:** `http://www.sap.com/adt/dictionary/domains`
- **Schema:** `sap/domain.xsd`
- **Notes:** Direct extension of `adtcore:AdtMainObject`. Works out of the box.

### DTEL (Data Element)
- **Root Element:** `blue:wbobj`
- **Namespace:** `http://www.sap.com/wbobj/dictionary/dtel`
- **Inner Content:** Wraps `dtel:dataElement`.
- **Schema:** `.xsd/custom/dataelementWrapper.xsd`
- **ADK wrapperKey:** `'wbobj'`

### TABL (Table) / Structure
- **Root Element:** `blue:blueSource`
- **Namespace:** `http://www.sap.com/wbobj/blue`
- **Schema:** `.xsd/custom/blueSource.xsd`
- **ADK wrapperKey:** `'blueSource'`
- **Notes:** Extends `abapsource:AbapSourceMainObject`. Contracts use `crud()` helper.

### TTYP (Table Type)
- **Root Element:** `tableType`
- **Namespace:** `http://www.sap.com/dictionary/tabletype`
- **Schema:** `sap/tabletype.xsd`
- **Notes:** Direct extension of `adtcore:AdtMainObject`. Works out of the box.

## Locking
- **Header:** Lock operations require `Accept: application/*,application/vnd.sap.as+xml;charset=UTF-8;dataname=com.sap.adt.lock.result`.
30 changes: 30 additions & 0 deletions .agents/rules/adt/xsd-best-practices.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
trigger: model_decision
description: Best practices for working with XSD files and XML parsing in this project.
---

# XSD and XML Best Practices

## XSD Validity
**CRITICAL:** Never create broken/invalid XSD files and then modify ts-xsd to handle them. XSDs must be valid W3C XML Schema documents FIRST.
- `xs:import` = cross-namespace. Only ONE `xs:import` per namespace per schema.
- `xs:include` = same-namespace composition/extension.
- Every `ref="prefix:name"` must resolve to an in-scope element declaration.
- Every `type="prefix:TypeName"` must resolve to an in-scope type definition.

## Custom Extensions
If SAP's XSD is missing types:
1. Create a custom extension XSD in `.xsd/custom/` with the **SAME** targetNamespace as the SAP schema.
2. Use `xs:include` to bring in the SAP schema.
3. Add new types/elements in the extension.
4. Have consumers `xs:import` the extension instead of the SAP schema directly.

## XML Parsing Gotchas
- **xmldom & Attributes:** The `@xmldom/xmldom` library returns an empty string `""` (instead of `null`) when calling `getAttribute()` for a non-existent attribute.
- **Rule:** Always use `hasAttribute()` to check for existence before reading values to avoid treating missing attributes as present empty strings.

## TS-XSD Builder Logic (Do Not Regress)
- **Qualified Attributes:** When building XML with schemas that use `attributeFormDefault="qualified"` and inherit attributes from imported schemas, the builder must collect namespace prefixes from the **ENTIRE** `$imports` chain, not just the root schema's `$xmlns`.
- *Context:* SAP ADT schemas often import `abapsource.xsd` -> `adtcore.xsd`. Attributes like `name` defined in `adtcore.xsd` need the `adtcore:` prefix even if the root schema doesn't import `adtcore` directly.
- **Inherited Child Elements:** When building XML with inherited child elements (e.g. `packageRef` defined in `adtcore.xsd` but used by `interfaces.xsd`), the builder must use the **defining schema's namespace prefix** for the element tag, not the root schema's prefix.
- *Context:* `walkElements` must return the schema where the element was defined. `buildElement` must use this schema to resolve the prefix.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
trigger: glob
description: Enforce extensionless imports for internal files in bundled TypeScript packages.
globs: *.ts
globs: '**/*.ts'
---

## Rule: Use Extensionless Imports for Internal Files
Expand Down
16 changes: 16 additions & 0 deletions .agents/rules/development/coding-conventions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
trigger: always_on
description: Core coding conventions for the abapify monorepo. TypeScript strict, ESM only, naming, formatting.
---

# Coding Conventions

- **TypeScript strict** — no `any` without a comment explaining why
- **ESM only** — no `require()`, no `__dirname` (use `import.meta.url`)
- **No decorators** except in packages that already use them
- **Async/await** over Promises `.then()` chains
- PascalCase for types/classes/interfaces; camelCase for variables/functions
- 2-space indentation (Prettier enforced)
- Cross-package imports: `@abapify/<package-name>`
- Internal file imports: extensionless relative paths — see [bundler-imports](bundler-imports.md) for details
- `workspace:*` protocol for local workspace deps — see `$link-workspace-packages` skill for setup
21 changes: 21 additions & 0 deletions .agents/rules/development/file-lifecycle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
trigger: always_on
description: Know which files are generated/downloaded before editing. Never edit codegen output or SAP XSD downloads.
---

# File Lifecycle — Know Before You Edit

**Before editing ANY file**, check whether it's generated/downloaded:

```bash
bunx nx show project <package> --json | grep -i "xsd\|generated\|download"
```

| Pattern | Lifecycle | Rule |
| ------------------------------------- | ------------------- | ------------------------------------------------------ |
| `packages/*/src/schemas/generated/**` | Codegen output | Never edit — fix the generator or XSD source |
| `packages/adt-schemas/.xsd/sap/**` | Downloaded from SAP | Never edit — create custom extension in `.xsd/custom/` |
| `packages/adt-schemas/.xsd/custom/**` | Hand-maintained | Safe to edit |
| `packages/*/dist/**` | Build output | Never edit |

If an edit keeps "reverting": **stop**. Something is regenerating the file. Check Nx targets before using `sed`/force-writes.
5 changes: 5 additions & 0 deletions .agents/rules/development/package-versions.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
---
trigger: model_decision
description: Always install latest package versions when adding dependencies. Never hardcode specific versions.
---

# Package Versions: Always Install Latest

## Rule
Expand Down
40 changes: 40 additions & 0 deletions .agents/rules/git/no-auto-commit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
trigger: always_on
description: Never commit or push without explicit user approval.
---

# No Auto-Commit Rule

## Rule

**NEVER run `git commit` or `git push` without explicit user approval.**

Before committing:

1. Show the planned commit(s): message, staged files, diff summary
2. Wait for the user to confirm
3. Only then execute `git commit`

## Exception: `$monitor-ci` Skill

When the `$monitor-ci` skill is active (CI self-healing workflow), autonomous commits and pushes are permitted for:

- Applying self-healing fixes
- Retrying CI with empty commits
- Updating lockfiles for pre-CI failures

The skill has its own git safety rules (never `git add -A`, stage only fix-related files).

## Applies To

- All AI assistants (Devin, Windsurf, Claude, etc.)
- Both interactive and background/subagent sessions

## Why

Commits are permanent project history. The user must review and approve:

- What files are staged
- The commit message
- Whether changes should be split into multiple commits
- Whether to push after committing
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
---
trigger: model_decision
description: Fix false circular dependencies in Nx caused by config files. Use .nxignore and ESLint ignores.
---

# Nx Circular Dependencies: Config File Exclusions

## Problem
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Nx Monorepo Setup Rules
---
trigger: model_decision
description: Nx monorepo setup rules - package creation workflow, config templates, plugin inference, import conventions.
---

> **See**: [`.agents/rules/development/tooling/nx-monorepo.md`](../../../.agents/rules/development/tooling/nx-monorepo.md) for complete Nx plugin inference system documentation.
# Nx Monorepo Setup Rules

## Quick Reference

Expand Down Expand Up @@ -153,13 +156,15 @@ You should see: `["build", "lint", "nx-release-publish", "test", "test:coverage"

## Import Rules

> See [coding-conventions](../development/coding-conventions.md) and [bundler-imports](../development/bundler-imports.md) for full details.

- **Cross-package**: `@abapify/[package-name]`
- **Internal files**: `../relative/path` (no extensions for TS files)
- **Workspace deps**: Use `workspace:*` (bun supports this protocol)
- **Internal files**: `../relative/path` (extensionless)
- **Workspace deps**: `workspace:*`

## File Organization

- **Source code**: `packages/[name]/src/`
- **Temporary files**: `tmp/` (never commit)
- **Temporary files**: `tmp/` — see [tmp-folder-testing](../development/tmp-folder-testing.md)
- **Build output**: `packages/[name]/dist/`
- **Tests**: Co-located with source (`*.test.ts`)
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
trigger: always_on
description: OpenSpec-based project planning. Check openspec/specs/ and openspec/changes/ before making changes.
---

# Project Planning and Memory Persistence Rule
Expand All @@ -17,6 +18,8 @@ This workspace uses [OpenSpec](https://openspec.dev/) for project planning and s

## AI Assistant Workflow

> For the critical review process and spec change severity rules, see [spec-first-then-code](spec-first-then-code.md).

1. **Check `openspec/specs/`** for existing specifications before making changes
2. **Check `openspec/changes/`** for active change proposals to understand context
3. **Use `/opsx:propose`** to create new change proposals with specs, design, and tasks
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ description: When making any changes for any of spec-driven packages

## Core Philosophy

> For key locations and memory persistence, see [project-planning-memory](project-planning-memory.md).

- Specifications are design contracts (stable, versioned, change-resistant)
- Documentation describes implementation (living, refactorable)
- Specs define WHAT and WHY before coding HOW
Expand Down
17 changes: 17 additions & 0 deletions .agents/rules/verification/after-changes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
trigger: always_on
description: Verification checklist after making changes. Build, typecheck, test, lint, format.
---

# After Making Changes

**NEVER tell the user to "try it" or "run it again" — verify it yourself first.**
If you changed code, YOU must build and test before declaring it done.

```bash
bunx nx build <package> # verify it compiles
bunx nx typecheck # full type check
bunx nx test <package> # run tests
bunx nx lint # fix lint issues
bunx nx format:write # REQUIRED before every commit — format all files with Prettier
```
35 changes: 17 additions & 18 deletions .agents/skills/add-endpoint/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ If you have a running SAP system connection:
# Example using curl or adt-cli:
# GET /sap/bc/adt/{path}/{objectname}
```
2. Save the raw response to `tmp/` for reference:
2. Save the raw response to `tmp/` for reference (see [tmp-folder-testing](../../rules/development/tmp-folder-testing.md)):
```bash
# adt get ZOBJECT_NAME -o tmp/response.xml
```
Expand Down Expand Up @@ -141,12 +141,14 @@ export default {

**Key rules for schema literals:**

> See [xsd-best-practices](../../rules/adt/xsd-best-practices.md) for XSD validity rules and edge cases.

- Must end with `} as const`
- One root element per schema document
- Use `$imports` for schemas you depend on (adtcore, abapoo, abapsource, etc.)
- Names follow XSD conventions: `complexType` names are PascalCase
- Look at existing schemas (e.g. `interfaces.ts`, `packagesV1.ts`) for common base types
- Existing schemas were auto-generated from XSD sources in `packages/adt-schemas/.xsd/`; manually created schemas should be documented accordingly
- Existing schemas were auto-generated from XSD sources in `packages/adt-schemas/.xsd/`; manually created schemas should be documented accordingly (see [file-lifecycle](../../rules/development/file-lifecycle.md))

### 2b: Add the typed wrapper in typed.ts

Expand Down Expand Up @@ -370,21 +372,18 @@ export const registry = {

## Step 6: Build and Verify

> Follow the verification checklist in [after-changes](../../rules/verification/after-changes.md).

```bash
# Build affected packages in dependency order
npx nx build adt-schemas
npx nx build adt-contracts
npx nx build adt-fixtures

# Type check everything
npx nx typecheck

# Run tests
npx nx test adt-schemas
npx nx test adt-contracts

# Lint
npx nx lint
bunx nx build adt-schemas
bunx nx build adt-contracts
bunx nx build adt-fixtures

# Type check, test, lint
bunx nx typecheck
bunx nx test adt-schemas adt-contracts
bunx nx lint
```

### Quick smoke test (optional)
Expand Down Expand Up @@ -467,6 +466,6 @@ application/vnd.sap.adt.{object-type}.v{version}+xml
- [ ] Module index updated (or new module registered in main `adt/index.ts`)
- [ ] Fixture XML created in `adt-fixtures/src/fixtures/{module}/`
- [ ] Fixture registered in `adt-fixtures/src/fixtures/registry.ts`
- [ ] `npx nx build adt-schemas adt-contracts adt-fixtures` passes
- [ ] `npx nx typecheck` passes
- [ ] `npx nx test adt-schemas adt-contracts` passes
- [ ] `bunx nx build adt-schemas adt-contracts adt-fixtures` passes
- [ ] `bunx nx typecheck` passes
- [ ] `bunx nx test adt-schemas adt-contracts` passes
Loading
Loading