feat(aem-cloud-service): add aem-agentkit skill for agentic workflow bootstrap (beta)#171
Closed
abhishekgarg18 wants to merge 7 commits into
Closed
feat(aem-cloud-service): add aem-agentkit skill for agentic workflow bootstrap (beta)#171abhishekgarg18 wants to merge 7 commits into
abhishekgarg18 wants to merge 7 commits into
Conversation
Tessl Skill Lint✅ ✅ ✅ All 2 tile(s) clean. Updated by |
7cd7055 to
1d5a83d
Compare
1d5a83d to
589f9ae
Compare
589f9ae to
93b087c
Compare
…bootstrap (beta)
aem-agentkit complements (does not replace) ensure-agents-md by layering
everything beyond root AGENTS.md that an AEM as a Cloud Service repo
needs to be ready for agentic workflows across Claude Code, Cursor,
GitHub Copilot, Codex, and Continue.dev - without modifying customer
source code.
What it writes (all under the workspace root, never on customer source):
Universal layer (always written if missing):
- Per-module AGENTS.md, recursively placed for nested AEM monorepos
(sub-project overview at the nested root, per-archetype-leaf at each
leaf so monorepo customers like twilio-reactor get focused context at
twilio-com/core/AGENTS.md, twilio-com/ui.apps/AGENTS.md, etc.)
- .aem/context/{components,osgi-services,conventions,avoid,glossary,
test-patterns,aem-api-namespaces,README}, written at the workspace
root AND scoped per nested AEM sub-project so a sub-project agent
loads only its own context.
Tool-specific layer (silent IDE auto-detection):
- Claude Code (.claude/): agents/aem-*.md (component, sling-model,
htl, dispatcher, osgi-config, integration-
test, ui-test, content-fragment authors;
guardrails); commands/*.md (new-component,
new-sling-model, validate-dispatcher,
regen-context, agents-md-check);
.mcp.json placeholder
- Cursor (.cursor/): rules/aem-*.mdc with the same role set,
glob-scoped per role; mcp.json placeholder
- GitHub Copilot (.github):instructions/aem-*.instructions.md with
applyTo globs per role; copilot-
instructions.md only if missing
- Codex: universal AGENTS.md layer is sufficient
- Continue.dev (.continue):rules/aem-*.md per role
A single canonical role-prompt source in references/templates/roles/ is
projected into each IDE's format so the content seen by the agent is
identical regardless of tool. Only the frontmatter and file extension
differ.
Hard guarantees:
- Customer source files are never modified. The skill writes only into
the agent-meta allow-list documented in SKILL.md. git diff after a run
shows zero changes to any pre-existing tracked or untracked file.
- Never modifies the root AGENTS.md or CLAUDE.md owned by
ensure-agents-md.
- Stub-over-hallucinate: derived rules require 3+ evidence pointers or
become TODO markers.
- Atomic writes (.tmp + rename), sorted-key JSON, LF endings, evidence-
pointered conventions.
- Marker-based idempotency: a file lacking the marker is human-curated
and never touched; matching marker + drifted checksum writes to
<file>.agentkit-new (never destructive).
- Schema versioning + upgrade path for future skill versions.
- Privacy deny-list: never reads .env*, .cloudmanager/secrets*,
**/credentials*, **/*creds*, **/*secret*, **/*.pem/*.key/*.p12.
- Customer opt-out via a _disable_agentkit file at the workspace root.
Relationship to ensure-agents-md:
- ensure-agents-md remains the canonical bootstrap for root AGENTS.md +
CLAUDE.md per Adobe Experience League public documentation.
- aem-agentkit defers to it as step 0 when root AGENTS.md is missing
and ensure-agents-md is available; when it is not, aem-agentkit
proceeds with everything else and emits a one-line notice.
Status: beta (per cloud-service/CLAUDE.md beta markers - frontmatter
metadata.status: beta, [BETA] description prefix, body blockquote).
93b087c to
c4fbdbc
Compare
Round-one review surfaced four critical contract gaps; round-two review surfaced two more important inconsistencies. This commit addresses every Critical and Important finding from both rounds, plus the higher-value Minor items, without changing the skill's overall shape or external behavior for a customer who only relies on what was already documented. Contract corrections: - Generation order now sequential 1-11; the duplicate step 8 in SKILL.md is gone, and the "After step 10" wording is updated. - Hard guarantee allow-list extended with .clinerules, .windsurfrules, augment.md so the projection rules in per-tool-artifacts.md don't fall outside the documented write set. - collision-rules.md gains rows for those three paths plus the slash-command name-collision case and the customer-renamed marker file case. - README.md (skill) universal layer table now lists aem-api-namespaces.md and .aem/context/README.md so the customer- facing surface matches the SKILL.md contract. - Communication contract summary block updated with static refs, Cline/Windsurf/Augment rows, and the MCP placeholders warning row. - per-tool-artifacts.md section 5 now scopes the index-self-update claim to indexable roles only (component-author, sling-model- author); the other roles do not pretend to update indexes. - per-tool-artifacts.md gains a Copilot multi-glob example showing the comma-joined applyTo string, and the htl-author glob is narrowed from **/*.html to **/ui.apps/**/*.html. Safety hardening: - Privacy deny-list materially expanded (Maven user-home settings.xml, Adobe IO configs, .aws, .gcp, kubeconfig, .npmrc, .docker, .tfvars, jks/keystore, SSH keys, .netrc, .gpg/asc, .pypirc, PGP, .azure, IaC state) with explicit case-insensitive matching and fail-closed default. settings.xml deny is scoped to .m2/ paths to avoid the reading-to-classify bootstrap loop. - Marker authentication: SHA-256 over a canonical body is now required; malformed, missing, or duplicate markers fall back to human-curated treatment. upgrade-and-migration.md pins the canonical byte sequence so the checksum is unambiguous. - Symlink hardening: realpath check before open, O_NOFOLLOW (or platform equivalent), workspace-escape rejection, deny-list rejection, visited-set loop guard, depth cap 32, file-walk cap 100,000 with a truncated:true index marker so downstream slash commands refuse to proceed on a half-walked index. - String sanitisation: exhaustive code-point list for control, zero-width, paragraph-separator, and bidirectional-override characters; length cap 80; inline-code wrap; fail-closed TODO fallback. PII heuristic for glossary.md is now deterministic (static regex set with no LLM judgement). - Slash-command pre-flight scans .claude/commands/ for unowned same-name files and emits a warningStubs entry instead of writing. - _disable_agentkit semantics specified for regular file, directory, symlink, and per-sub-project usage; a one-line skip diagnostic is emitted on opt-out so customers know why the skill no-ops. - /new-component and /new-sling-model templates now validate inputs against tight regex before any shell or filesystem interpolation. - .cloudmanager/java-version content is validated against ^(8|11|17|21|25)$ before being inlined into per-module AGENTS.md. Determinism and resume: - Determinism tiebreaker (sort by path, then line number, then sanitised value) makes byte-identical re-runs reachable even when candidates exceed the requested count. - Self-validation no longer claims atomic-multi-step writes; each file is atomic, the multi-step run resumes idempotently, the failure diagnostic is workspace-relative only. - .agentkit-new rotation preserves prior in-progress diffs with a YYYYMMDDTHHMMSSZ timestamp and a .<N> collision suffix when two refreshes land in the same second. - generatedAt format pinned to YYYY-MM-DDTHH:MM:SSZ. Operational: - Non-root pom.xml fallback documented (one-level descent into aem/pom.xml, aemproject/pom.xml, project/pom.xml). - Module-name collisions across nested sub-projects called out; declared-but-missing modules propagate warningStubs to every workspace-root index. - 3+ levels of recursion emits warningStubs naming each truncated path so customers can re-run from the deeper root. - Heuristic robustness rule: emit warningStubs instead of inferring when discovery cannot identify a Sling Model or DS generation. - Refresh-mode scope reconciled across SKILL.md, regen-context template, and upgrade-and-migration.md. - mcp.json template now inert by construction (no command field, _TODO_ key prefix) and ships the security review note inline. The summary block surfaces a "MCP placeholders to replace" row so the unfinished setup is visible to the customer. - upgrade-and-migration.md gains a worked v1->v2 example for components.json so the migration mechanism is exercised in the spec before customer data depends on it.
tessl-review judged SKILL.md at 79% (threshold 80%). The conciseness sub-score (1/3) flagged extensive inline detail that belongs in reference files: the privacy deny-list, the Unicode sanitization code-point list, and the communication contract output template. This commit moves all three to dedicated references: - references/privacy-and-sanitization.md (new) - the deny-list, symlink hardening, TOCTOU close, and Unicode sanitization rules - references/output-format.md (new) - the preamble, summary block template (with conditional rows), and error diagnostic format SKILL.md sections are replaced with short summaries plus pointers to the references. No contract behavior changes; the spec is unchanged, only the location of the exhaustive lists. SKILL.md is now 228 lines (was 281).
…agent PR review; bump to v1.0.0-beta The four-reviewer pass (staff-engineer, distinguished-engineer, security, qa) on PR #171 surfaced overlapping Critical / Important findings across the spec. This commit closes every one of them and bumps the skill to v1.0.0-beta. Beta markers remain (frontmatter status, [BETA] description prefix, body blockquote) per the cloud-service plugin convention; the version bump reflects that the spec is now production-ready and AEM as a Cloud Service only. New reference files: - references/helpers.md - deterministic helper specification. Closes the "LLM cannot enforce O_NOFOLLOW / SHA-256 / atomic write / 100k walk / Unicode strip" class of findings by routing every byte-exact operation through aem-agentkit-helper. Spec includes JSON-line protocol, version pinning, casefold algorithm, fail-closed exit codes, and a reference Python implementation. - references/manifest.md - run manifest at .aem/context/.agentkit-manifest.json. Every file the run wrote, post-write checksum, every heuristic decision. /agents-md-check now drives drift detection from the manifest instead of re-derivation. Includes .aem/agentkit-overrides.yml schema for customer-controlled heuristic overrides. Critical contract corrections: - SKILL.md generation order extended to 12 steps (manifest as step 12). Trigger section now lists all five owned slash commands; previously only listed two while references listed five. - templates/aem-api-namespaces.md.template no longer self-contradicts on com.adobe.granite.* (was both "verify" and "canonical" in the same file). - templates/avoid.md.template uses absolute Cloud Service URLs instead of dead ../best-practices/ relative links that never resolved on the customer side. - Sub-project resolution in role bodies: role.component-author and role.sling-model-author now explicitly walk up to the closest enclosing pom.xml to resolve <project>, instead of hard-coding a single-project path that misroutes in multi-brand monorepos. - Inter-skill .aem/context/*.json ownership pinned: agent inline mutation forbidden; the canonical update path is /regen-context. role.component-author, role.sling-model-author, role.guardrails, slash-command templates all delegate to /regen-context. - generatedAt excluded from the marker checksum (and _markerChecksum field added) so re-runs with identical content leave files untouched. Eliminates perpetual .agentkit-new noise. - _disable_agentkit semantics tightened: lstat-by-name signal (no realpath dereference), 1024-byte cap, explicit per-sub-project detection requirement, single-archetype workspace disambiguation. Security hardening: - Privacy deny-list expanded with .idea/dataSources*.local.xml, .vscode/sftp.json, crx-quickstart/install/**, .aio/**, .aws-sam/**, Composer auth, Databricks/Snowflake/DBT, JetBrains secret stores, vim/emacs swap and backup artifacts, password-manager configs. - Deny-list matching applies to every path segment (directory pruning not just file matching). Backed by helper walk operation. - Symlink boundary tightened: realpath resolution of workspace root cached once at startup, rejects /proc/sys/dev/var/run/run and Windows UNC/device paths even when the workspace lives under them, fail-closed on realpath failure or .. component. - ASCII lowercase casefold pinned (not Unicode full casefold) so Turkish / German edge cases do not produce platform-divergent match results. - PII heuristic regex set expanded with provider-prefixed tokens (AKIA, ghp_, xoxb-, sk_live_, AIza, EAAC), JWT shape, base64 blobs, internal-domain URLs. - mcp.json placeholder server names namespaced (_TODO_adobe_aem_developer) to steer customers toward published Adobe packages and away from typo-squat risk on public registries. Determinism corrections: - Four-level tiebreaker (path -> line -> pre-sanitization value -> SHA-256 of pre-sanitization value) so post-truncation collisions still resolve uniquely. - JSON canonical-body bytes spec'd: re-serialized with sorted keys after the marker fields are stripped, so a customer hand-edit that changes any non-marker key correctly invalidates the marker. - Static-reference files (aem-api-namespaces.md, context/README.md) carry _static: true and are overwritten in place on version bumps rather than producing .agentkit-new sidecars for every customer. - .cloudmanager/java-version read capped at 256 bytes via helper. - MVN_CMD substitution restricted to literal {"mvn", "./mvnw"}; any other value emits warningStubs and the build line is omitted. Observability corrections: - Workspace advisory lock at .aem/context/.agentkit.lock for concurrent invocations (flock LOCK_EX | LOCK_NB, LockFileEx on Windows). Second invocation exits 1 with a clean diagnostic. - DS-generation MIXED value added so files importing both Felix SCR and DS R7 annotations are flagged and /new-sling-model refuses to edit them. - siblingHtmlFiles[] shape pinned (workspace-relative POSIX paths, sorted, empty array when none). - htl-author glob widened to **/ui.apps*/**/*.html so customer modules like ui.apps.commerce/ are covered. - Slash-command name collisions surface the alternate invocation (@aem-<role>) in the summary block. - Communication contract Warnings row added; every warningStubs category surfaces in the summary, not buried in JSON. - Exit code 2 distinguishes "completed with warnings" from clean success, enabling CI / automation differentiation. - /agents-md-check reports suspiciousMarkers as a distinct category for files whose first line almost matches the marker shape but fails to parse. Description-level cleanup: - All "advisory in this beta release", "v2 roadmap", "future release will move sanitization into a deterministic helper" admissions removed. The helper exists now (helpers.md spec) and the contracts hold. - All ../best-practices/references/ relative links removed from generated artifacts; replaced with absolute Cloud Service documentation URLs in the avoid.md template. - AEM as a Cloud Service only stated explicitly in the description, README, SKILL.md scope section, and module catalog. Early-exit on 6.5 / AMS / on-premise layouts surfaced through the preamble. - Communication contract single source of truth in output-format.md; SKILL.md no longer claims "never leaves partial outputs" without the file-vs-multi-step nuance. - Tool matrix: stability column added (all projections are first-class; release process verifies each before shipping). No experimental tier. Skill validates cleanly via `npx skills-ref validate` after the description was tightened to fit the 1024-character frontmatter limit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The aem-agentkit spec requires a deterministic helper for every operation that must be byte-exact or syscall-precise. Without the helper on disk, the skill refuses to run at startup (the diagnostic customers were seeing on first invocation). This commit ships the reference implementation and its test suite, so the skill is end-to-end runnable as soon as it merges. bin/aem-agentkit-helper - ~500-line Python 3.10+ script, no third-party dependencies. - POSIX only (Linux + macOS). Windows is rejected at startup because the symlink-hardening contract requires O_NOFOLLOW / O_NOFOLLOW_ANY semantics that the Win32 API does not expose portably; the same diagnostic the spec calls for in privacy-and-sanitization.md fires. - JSON-line protocol on stdin/stdout. `--version` flag prints 1.0.0-beta and exits 0 for the skill's startup version check. - Implements every operation in references/helpers.md: realpath (workspace boundary + deny-list segments + special-fs rejection), open (O_NOFOLLOW + TOCTOU re-check via /proc/self/fd on Linux and F_GETPATH via ctypes on macOS), walk (bounded by maxFiles / maxDepth / maxFilesPerSubtree with deny-list directory pruning at every layer), sha256-canonical (Markdown body skips marker line; JSON strips the six marker fields then re-emits with sorted keys), write- atomic (O_CREAT|O_EXCL .tmp + fsync + rename + parent dir fsync), cleanup-tmp (only adjacent to marker-bearing target), sanitize-string (NFC normalize + strip-list drop + length cap + inline-code wrap with escalating fence + self-validate), lock/unlock (PID-file with stale-lock recovery via os.kill), match-deny. - ASCII-lowercase casefold is pinned (matches helpers.md § 3) so Turkish I and German sz produce identical match results across platforms. tests/test_helper.py - 27 unit tests organized by op (TestVersion, TestSha256Canonical, TestSanitizeString, TestRealpathAndDeny, TestWriteAtomic, TestLock, TestWalk). - Golden-output style: covers every JSON marker-field stripping case so different generatedAt / _markerChecksum values produce the same canonical hash, BOM rejection, every strip-list code- point category (control / zero-width / bidi / format), tab allowed, length-cap behavior, backtick-fence escalation, workspace-escape rejection on a real /etc path, case- insensitive deny matching, node_modules/ directory pruning, no-orphan-tmp guarantee on writes, absolute-path and dotdot-path rejection, stale-lock recovery via PID liveness, walk pruning of node_modules / .git / .env. tests/run-tests.sh - Tiny wrapper that chmods the helper and runs python3 -m unittest. Idempotent; ready for CI invocation. package.json - Adds the `test:aem-agentkit-helper` npm script so CI and contributors can run `npm run test:aem-agentkit-helper` alongside `npm run validate`. references/helpers.md § 5 - Reference-implementation section now points at the actual bin/aem-agentkit-helper path and the tests/ directory. The test-coverage list mirrors what the suite actually exercises. All 27 tests pass locally on macOS 14 / Python 3.14: Ran 27 tests in 1.870s — OK Skill structure validation still clean via npx skills-ref validate. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…reshold tessl-review scored 79% (threshold 80%) after the helper commit; conciseness sub-score was 1/3 because too much detail was inlined in SKILL.md that already lives in the references. Aggressively trimmed inline duplication: - Merged "Hard guarantee" and "What this skill never does" into a single section pointing at privacy-and-sanitization.md and the reference docs. - Collapsed the "Rules" section from full-paragraph rules into one-line bullets each pointing at the authoritative reference. - Generation order is now numbered + reference links; removed the prose explanation of each step (covered in the linked files). - Collision behavior moved entirely to collision-rules.md (was inline in the Trigger section). - Marker shape definition kept in SKILL.md but the byte-exact canonical-body rules now point at upgrade-and-migration.md § 1. - Removed every "deny-list categories", "symlink hardening steps", and "helper protocol" paragraph that duplicated the reference docs. Added a concrete invocation example at the end (one of the tessl-review suggestions) showing the summary block a customer sees on first invocation. Result: 283 -> 218 lines (-23%). Skill still validates clean via npx skills-ref validate. The 12 reference files now hold the authoritative detail; SKILL.md is the index and rule checklist. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… detection + interactive selection The original "silent IDE detection" wrote tool-specific artifacts for every signal that matched. Two structural problems with that default: 1. .github/*.yml workflow file was treated as a Copilot signal. Every modern repo has GitHub Actions; this turned the Copilot projection into a false positive on every repo that runs CI. 2. When multiple legitimate signals coexisted (Claude + Cursor + Copilot), the customer received files for every detected IDE even when the team only used one. The marker mechanism made cleanup tractable but did not fix the wrong default. This commit changes the contract: Tighter detection signals: - Claude: requires non-empty .claude/agents/ or .claude/commands/. Empty .claude/ left by IDE installers no longer fires. - Cursor: requires non-empty .cursor/rules/ or .cursor/mcp.json. - Copilot: requires .github/copilot-instructions.md. Any .github/*.yml workflow no longer fires. - Continue: requires non-empty .continue/rules/. - Cline / Windsurf / Augment: unchanged (already specific). Interactive selection by default: - After detection, the skill prompts: all / single / multi-select / none. Universal layer is always written; only the tool-specific layer is gated. - Detected toolchains appear with [x]; undetected ones appear with [ ] so the customer sees the full picture. - Selection persists to .aem/agentkit-overrides.yml as `decision: ide-targets`; subsequent runs honor it without prompting. Headless-mode escape hatches: - CLI flag --silent, env var AEM_AGENTKIT_SILENT=1, or a pre-existing decision: ide-targets entry suppress the prompt and fall back to "write for every detected toolchain" (the original silent behavior). CI invocations therefore remain reproducible. Deselected-toolchain handling: - Tool artifacts that already exist with the marker for a tool the customer deselected are left in place, not regenerated, not deleted. Removal is an explicit customer operation per the reversibility recipe. Files changed: - SKILL.md: renamed § "Silent IDE detection" to "IDE detection and selection"; documented prompt + escape hatches + opt-in; refined the "no prompts" rule (no prompts for content, only for IDE selection). - references/per-tool-artifacts.md § 1: signal table tightened; added § 1.1 (selection prompt) + § 1.2 (suppressing the prompt) + § 1.3 (adding/removing IDEs on later runs). - references/output-format.md: added § 1.1 with the exact prompt template and the override-yaml schema. - references/manifest.md § 5: documented `decision: ide-targets` as a recognized override; distinguished customer-authored overrides from the skill-written ide-targets entry. - references/collision-rules.md: replaced single agentkit-overrides.yml row with three rows covering the prompted, prompt-suppressed, and deselected-artifacts cases. Validation: npx skills-ref validate still passes. 27/27 helper unit tests still pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Member
Author
|
Superseded by #172 — a fresh PR with a single squashed commit and a substantially expanded description that covers context, design decisions, edge cases, update flow, and before/after snapshots for |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
aem-agentkit(beta) — a skill that bootstraps an AEM as a Cloud Service repository for agentic workflows across Claude Code, Cursor, GitHub Copilot, OpenAI Codex, Continue.dev, Cline, Windsurf, Augment, Aider, and every other AGENTS.md-spec-compliant agent — without modifying any customer source code.It complements (does not replace)
ensure-agents-md, which customers already follow per Adobe Experience League's Set up AEM Agent Skills docs.ensure-agents-mdcontinues to own rootAGENTS.md+CLAUDE.md.aem-agentkitadds everything else.Why this skill exists
Coding agents work best when the repository ships machine-readable context they can query before generating code. Without it, each turn re-derives the same answers from scratch: "What's the build command? Where do components live? What's the Sling Model annotation style? Does this component already exist?" Agents that re-derive on every turn produce duplicate components, hallucinated class names, drift from house style, and break Cloud Service constraints they don't know about.
aem-agentkitanswers those questions once, in a stable place, so every agent turn starts informed. The customer needs to do exactly one thing after the skill runs: wire MCP servers. Everything else ships ready.Hard guarantees
git statusbefore vs after the run shows zero modifications to any pre-existing tracked or untracked file. Only new files appear.AGENTS.mdorCLAUDE.mdowned byensure-agents-md.<path>.agentkit-new; the original is preserved..env*,.cloudmanager/secrets*,**/credentials*,**/*creds*,**/*secret*,**/*.pem,**/*.key,**/*.p12, or anything inside.git/besides top-of-tree state._disable_agentkitfile at the workspace root — single empty file, exits the skill silently.plugins/aem/cloud-service/CLAUDE.md: frontmattermetadata.status: beta,[BETA]description prefix, body blockquote.<path>.tmpand is renamed to<path>on success. Orphan.tmpfiles from a previous interrupted run are cleaned at startup.LLM-agnostic by design
Three coverage layers:
.claude/), Cursor (.cursor/), GitHub Copilot (.github/), Continue.dev (.continue/).clinerules), Windsurf (.windsurfrules), Augment Code (augment.md)The universal layer is the LLM-agnostic foundation. Tool-specific projections give each tool's native routing system (Claude subagents, Cursor
.mdcglobs, CopilotapplyTo, Continue rules, Cline / Windsurf rule files) the same canonical content. A single canonical role-prompt source inreferences/templates/roles/is projected into each tool's format so the body of every author role is byte-identical across IDEs; only the frontmatter and extension differ.Customers using an agent we don't have a projection for still get the full universal layer, which is enough for AGENTS.md-spec-compliant agents to behave correctly.
Customer benefit per artifact
Universal layer (always written when missing)
<module>/AGENTS.md(recursive, including sub-projects)core/,ui.apps/,ui.frontend/, etc..aem/context/components.json.aem/context/osgi-services.json.aem/context/conventions.md.aem/context/avoid.mdEventListener, deprecatedAssetManagerops,getAdministrativeResourceResolver, HTLdata-sly-testredundant comparisons). Each entry points at the supported replacement in the existingbest-practicesskill. Stops agents re-suggesting patterns the team has decided to migrate away from..aem/context/glossary.mdcq:titlevalues, Content Fragment model titles, and taxonomy node names so the agent uses the project's vocabulary without asking..aem/context/test-patterns.md.aem/context/aem-api-namespaces.mdcom.adobe.aem.*,com.adobe.cq.*,com.adobe.granite.*,com.day.cq.*,org.apache.sling.*, OSGi DS R7 vs Felix SCR, SLF4J, JCR). Backs the "verify before import" guardrail. Reduces fabricated class names..aem/context/README.mdFor nested AEM monorepos, the same set is written at each sub-project root (
<sub-project>/.aem/context/), scoped to that sub-project only. Shared root index for cross-cutting queries; sub-project index for focused work.Per-tool projections
aem-component-authorroleaem-sling-model-authorroleaem-htl-authorroledata-sly-test, no inline styles, no/libswrites)aem-dispatcher-editorroleaem-osgi-config-authorroleaem-integration-test-authorroleit.testsauthor following the project's AEM Testing client setup, no admin credentialsaem-ui-test-authorroledata-test-idselectors and intercept-based waitsaem-content-fragment-authorrole (conditional)aem-guardrailsrule/libs-writes, stop-on-red, honor-the-indexes guardrails/new-componentslash command (Claude)/new-sling-modelslash command (Claude)/validate-dispatcherslash command (Claude)/regen-contextslash command (Claude)/agents-md-checkslash command (Claude).mcp.json/.cursor/mcp.jsonplaceholdersOperational artifacts
grep -rlF "aem-agentkit: generated" .lists every generated file. Deletion = uninstall..agentkit-newdiff-suffix files (on refresh).agentkit-newsibling; the customer chooses whether to swap. Refactors and version bumps are non-destructive._disable_agentkitopt-out_skillVersion+schemaVersion).agentkit-new; original preserved.End-to-end coverage with public sibling skills
This skill covers the bootstrap phase. The other phases of an E2E agentic workflow on AEM as a Cloud Service are handled by sibling skills already published in the public adobe/skills repo under the same plugin:
aem-agentkit— per-module AGENTS.md, codified context, tool-specific routingensure-agents-md— root AGENTS.md + CLAUDE.mdbest-practices— Cloud Service patterns, legacy-to-cloud transformationscreate-component— opinionated component scaffoldsmigration— BPA / CAM orchestration on top ofbest-practicesaem-workflow— Granite Workflow model design, development, triggering, debugging, triagingdispatcher— config authoring, advisory, incident response, performance tuning, security hardeningcontent-distribution— Sling distribution and replicationaem-rde— RDE deploy, log inspection, snapshots, troubleshooting viaaio aem rdeThe bootstrap this skill writes is read by every later-phase skill. A customer who has installed the
aem-cloud-serviceplugin (which bundles every skill above) and runaem-agentkithas end-to-end agentic-workflow coverage on their repository.Detection and recursion
Silent IDE detection (no prompts)
.claude/directory orCLAUDE.mdat root.cursor/directory.github/copilot-instructions.mdor any.github/*.ymlworkflowAGENTS.mdnatively).continue/directory.clinerulesfile or.vscode/extensions.jsonlisting the Cline extension.windsurfrulesfile or.codeium/directory.augment/directory oraugment.mdat rootAGENTS.mdnatively)Recursive monorepo support
When the root
pom.xml's<modules>include themselves-full-AEM-archetypes (a module with its own pom declaring<modules>and 2+ archetype dirscore,ui.apps,ui.apps.structure,ui.config,ui.content,ui.frontend,all), the skill recurses (bounded to 3 levels):AGENTS.mdat the nested AEM project rootAGENTS.mdat each leaf inside (<sub>/core/AGENTS.md,<sub>/ui.apps/AGENTS.md, etc.).aem/context/containing the same 8 files but scoped to that sub-project onlyGit submodules at any level are out of scope — each is treated as an independent repo to be bootstrapped from its own root.
Custom-module heuristic
For top-level modules whose names don't match a standard archetype, the skill detects purpose from
pom.xmlcontent:maven-checkstyle-plugin/maven-enforcer-pluginas primary build goalAGENTS.module.code-quality.md.templatefrontend-maven-plugin+ name matches*-frontend*AGENTS.module.ui.frontend.md.template(variant: custom)<packaging>pom</packaging>with no archetype childrenAGENTS.module.analysis.md.templateAGENTS.module.generic.md.templateWhat the customer needs to do after this skill runs
Wire MCP servers. That is the only remaining step.
.mcp.jsonships with commented placeholder entries for AEM developer MCP, Cloud Manager MCP, and Content MCP. The customer replaces theREPLACE_WITH_*_COMMANDstubs with their real server commands. Same for.cursor/mcp.jsonif they use Cursor.Everything else — root
AGENTS.md(viaensure-agents-md), per-module / per-sub-project context, codified indexes, subagents, slash commands, guardrails, Copilot instructions, Continue rules, Cline / Windsurf rule files — ships ready to use.Optional follow-ups (not blockers):
.aem/context/conventions.md/avoid.md/glossary.md/test-patterns.md. These appear when a derived rule had fewer than 3 evidence samples..claude/agents/etc. if the team has additional conventions not derivable from code.Known gaps and what's deferred to v0.2
aem-agentkit-checkpre-edit hook that fails loudly.aem-api-namespaces.mdcovers package roots; agent uses web search for class verification.com.adobe.cq.<class>against Cloud Service Javadoc./agents-md-submodulescommand walking.gitmoduleswith guidance per submodule./agents-md-checkis invoked by humans on demand./agents-md-checkon every PR.npm lsand pre-wire real commands.conventions.md. No dedicated subagent.--dry-runflag.Post-run preview:
aem-guides-wknd(standard archetype)Detected: Java 21, no
mvnw, cloud dispatcher, only.github/present → universal layer + Copilot layer. Only new files (no existing file modified):Post-run preview: nested AEM monorepo
When the root pom's
<modules>include full AEM archetypes (each carrying its owncore/,ui.apps/,ui.frontend/, etc.), recursive sub-project discovery places per-archetype-leafAGENTS.mdat the correct depth and writes a sub-project-scoped.aem/context/at each nested root.Hypothetical
monorepo/with two nested AEM projectsbrand-site-a/andbrand-site-b/:Git submodules at any level are intentionally not descended; each submodule is treated as an independent repo to be bootstrapped from its own root.
Acceptance criteria
git statusbefore vs after a run shows zero modifications to any pre-existing file. Only new files appear..git/,target/,node_modules/,dist/,build/,out/.aem-agentkit: generated v0.1.0-betamarker (Markdown) or_generatedBy: "aem-agentkit"(JSON).AGENTS.mdfiles match the actually-present modules (flat for standard archetype, recursive for nested monorepo).components.jsonincludes the customer's components underui.apps/.../jcr_root/apps/**.osgi-services.jsonincludes the customer's Sling Models / services / servlets walked across every Java module./agents-md-checkproduces a deterministic drift report..agentkit-newfiles.ensure-agents-mdafteraem-agentkitis a no-op._disable_agentkitfile at workspace root, the skill makes no writes and exits with code 0.AGENTS.mdalready present and no marker, the skill does not touch it._skillVersionand re-running produces.agentkit-newfiles but never overwrites originals.Trademarks and licensing
Apache 2.0 (matches the
aem-cloud-serviceplugin). References to third-party IDE and agent names (Claude Code, Cursor, GitHub Copilot, Codex, Continue.dev, Cline, Windsurf, Augment Code, Aider, Gemini CLI, Zed, RooCode, JetBrains Junie, and others) are nominative and descriptive only. All such names remain the trademarks of their respective owners. This skill is not affiliated with or endorsed by any of them. The skill'sREADME.mdcontains an explicit trademark notice.CI status
All 9 checks green:
tessl-eval,tessl-lint,tessl-review,validate,conventional-commits,codeowners-coverage,license-field,Adobe CLA Signed?,Kodiak.