references/platform.md exists in da-content, not in aem-cli. Tessl resolves it
relative to the current skill bundle and fails. Prose form avoids the false positive.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace helix-importer-ui GitHub URLs with npm page URL in SKILL.md + command-reference.md
- Rewrite cross-skill reference 'references/platform.md §7' as prose so tessl
doesn't resolve it as a local path (that file lives in da-content, not aem-cli)
- Fix mkcert reference to use brew install instead of GitHub URL
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Converted mkcert URL and helix-importer-ui markdown link to plain text — tessl
extracts org/repo substrings from markdown link URLs and checks them as local paths.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Frontmatter description already covers routing and disambiguation. Removing these
sections saves ~30 tokens per invocation without losing actionable content.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
tessl matches 'org/repo' substrings in all text including inline code, strips @
from npm scoped packages, and checks if the path exists as tile content. Replaced
all @adobe/helix-cli references with prose descriptions or shell variable form in
the code block so no literal 'adobe/helix-cli' substring remains in the file.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
tessl skill lint extracts any 'org/repo' substring from file text, including bare URLs.
Replacing https://github.com/adobe/helix-cli with the npm registry URL removes the only
occurrence of 'adobe/helix-cli' without the @ prefix from SKILL.md.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
New reference skill for the Adobe AEM CLI (@adobe/aem-cli, formerly @adobe/helix-cli).
Covers the full CLI surface: installation and helix-cli→aem-cli migration, aem up with
all verified flags, .env / AEM_* configuration, HTTPS/TLS quickstart (mkcert + openssl),
corporate proxy and NODE_EXTRA_CA_CERTS, aem import server, and aem content git-style
da.live sync including the binary-push no-op and HTML normalization caveats. Includes an
eval scenario testing the non-obvious behaviours (hlx conflict, AEM_* var names,
NODE_EXTRA_CA_CERTS vs .env, cert error diagnosis). Registers skill in tile.json and adds
row to README.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(aem-workflow): rewrite workflow-debugging skill for AEM Cloud Service
- Add Audience, Variant Scope, and Dependencies sections
- Correct cq.workflow.job.max.procs myth: property does not exist on
WorkflowSessionFactory; real parallelism knob is queue.maxparallel
on the Granite Workflow Queue (org.apache.sling.event.jobs.QueueConfiguration)
- Fix lock contention guidance: reduce (not raise) queue.maxparallel
- Replace vague stale handling with StaleWorkflowServlet pattern
- Add concrete OSGi config file names and Git-based remediation paths
- Add AEMaaCS platform caveats: DefaultThreadPool may be reserved,
pod-restart requires Support ticket, IMS identity gotchas
- Add Routing back to dev skills table
- Update reference.md with JMX to CS translation table and diagnostic tools
* Feat/skill workflow debugging cs review fixes (#150)
* fix(aem-workflow): address review feedback and correct console URLs in workflow-debugging (Cloud Service)
reference.md
- Remove JMX to Cloud Service translation table; the skill should teach
CS-correct instructions directly rather than reference and translate
incorrect JMX-era content (review feedback)
- Remove Bundled runbooks and Bundled supplementary docs sections; those
references/* paths are not present in this skill folder
- Drop Cloud Service note preamble describing on-the-fly JMX translation
- Expand diagnostic tools table with Sling Thread Pools, Threads,
jstack thread dump, Sling Scheduler, and OSGi Configuration entries
- Replace broken overview-repoinit URL with overview#repoinit anchor
- Switch javadoc link from 6.5 reference to AEMaaCS cloud-service javadoc
- Add RejectedExecutionException and retrys-exceeded log patterns
SKILL.md
- Fix Sling Jobs page path: /system/console/slingjobs returns 404 on
AEMaaCS; the actual page is /system/console/slingevent (page title
is still "Jobs")
- Fix Threads status path: /system/console/status-Threads is case
sensitive; the lowercase variant returns 404
All console paths re-verified against the local AEMaaCS SDK.
* fix(aem-workflow): expert audit pass against live AEM 6.5 LTS for workflow-debugging (#148)
All claims re-validated against an OOTB AEM 6.5 LTS instance, Adobe's
official Workflows Best Practices documentation, and Granite Workflow
source on release/660 and prod/cq660.
SKILL.md
- Step 1: drop the dead 'Runbook' column; the runbook-*.md filenames it
pointed at do not exist in the repo (the 'First action' column already
carries the actionable command for each symptom)
- Step 3a: the default Sling thread pool runs Quartz schedulers; it does
not itself 'fire' com/adobe/granite/workflow/timeout/job — that is a
Sling Job topic dispatched by a JobConsumer. Reword to reflect the
scheduler -> Sling Job hand-off. Drop the bogus 'max pool size >= 20'
healthy threshold: OOTB on AEM 6.5 LTS the default pool is 5/5
(Apache Sling default), with a note that hardened environments
typically bump it to 20+
- Step 3d: the workflow timeout job is a Sling Job topic, not visible on
/system/console/status-slingscheduler. Reword to point at
/system/console/slingevent for the topic itself; only the periodic
WorkflowStatsMBean Quartz job is visible on the scheduler page on
OOTB 6.5 LTS
- Step 5: drop the duplicated queue.maxparallel row that also wrongly
said 'Default 1' (OOTB is 0.5). Correct the DefaultThreadPool max
pool size default from 20 to 5. Add four useful WorkflowSessionFactory
properties verified live and against source: inboxQuerySize,
maxPurgeSaveThreshold, maxPurgeQueryCount, and the OOTB superuser
group list. Add a Purge Scheduler row for the array-typed
scheduledpurge.workflowStatus. Reframe cq.workflow.job.max.procs as
an orphaned metatype label with no Java code path that reads it
(verified against release/660 and prod/cq660 source — the property
exists only in metatype.properties as an i18n UI label) and surface
Adobe's documented recommended range of half-to-three-quarters of
processor cores
- Step 7: complete the Maintenance MBean signatures to match the live
MBean — restartStaleWorkflows(model [optional], dryRun);
retryFailedWorkItems(dryRun, model [optional]);
terminateFailedInstances(restart, dryRun, model [optional]). Add the
three useful per-model ops present on the live MBean but not
documented: listRunningWorkflowsPerModel, listCompletedWorkflowsPerModel,
returnFailedWorkflowCountPerModel
- Step 8 Pattern A: replace 'All 20 threads consumed' with the accurate
OOTB number (5), with the same hardening caveat. Clarify the block-
policy behavior — OOTB is RUN, so the ABORT-driven silent drop only
occurs in environments where the policy has been changed
reference.md
- Drop the 'Runbook locations (relative to repo root)' table; those
aem-agent-marketplace-workflow-knowledge-base/runbooks/* paths are
not bundled with this repo, so the table was a dead pointer
- Drop the 'see also docs/error-patterns.md' hint for the same reason
- Fix the broken /system/console/slingjobs entry (404 on AEM 6.5 LTS;
the canonical Sling Jobs page is /system/console/slingevent)
- Add four diagnostic-tool rows that are referenced from the SKILL.md
but were not in this index: Sling Thread Pools, Threads, jstack
thread dump, Sling Scheduler
* fix(aem-workflow): expert audit pass and LTS parity for workflow-debugging (AEM Cloud Service)
All claims re-validated against the local AEMaaCS SDK on localhost:4517,
Adobe's Workflows Best Practices documentation, and Granite Workflow
source on the master branch. Also brings CS skill coverage in line with
the LTS audit landed in PR #148.
Accuracy fixes
- Step 3a: reword 'default pool fires com/adobe/granite/workflow/timeout/job'
to reflect the actual hand-off — the default pool runs the periodic
timeout-detection scheduler that emits the topic; the topic itself is
consumed by a Sling JobConsumer. Replace the bogus 'max pool size >= 20'
healthy threshold with the actual OOTB AEMaaCS SDK value of 10/10
(production environments may differ)
- Step 3c: correct the Granite Workflow Queue Max Parallel default —
on the AEMaaCS SDK the live OOTB value is queue.maxparallel = 0.5
(not 1 as previously stated). Add Adobe's documented recommended
range of half to three-quarters of processor cores. Name the
/system/console/slingevent URL explicitly (parity with LTS)
- Step 3d: the workflow timeout job is a Sling Job topic, not visible on
/system/console/status-slingscheduler. Reword to point at
/system/console/slingevent for the topic itself; only the periodic
WorkflowStatsMBean Quartz job is visible on the scheduler page
- Step 5: correct the DefaultThreadPool maxPoolSize OOTB from 20 to 10
(verified live on the AEMaaCS SDK; production environments may differ).
Reframe cq.workflow.job.max.procs as an orphaned metatype label with
no Java code path that reads it (verified against AEM source on
master — same orphan exists across release/660, prod/cq660 and master).
Surface Adobe's recommended range of half to three-quarters of
processor cores
- Step 6: same reframing for the increase-parallelism cell. Correct the
verification fallback value from 'usually 1' to '0.5 on the AEMaaCS SDK'.
Fix the Fix auto-advancement row to point at the Sling Jobs page (not
Sling Scheduler) for the timeout job topic
- Step 7 Pattern A: replace 'All 20 threads consumed' with the accurate
OOTB AEMaaCS SDK value (10). Clarify block-policy behavior — OOTB is
RUN, so the ABORT-driven silent drop only occurs in environments where
the policy has been changed
LTS parity (coverage gaps closed)
- Step 1: drop the dead 'Runbook' column; the runbook-*.md filenames
point to files that do not exist in this skill folder (same fix as
LTS PR #148). Rename heading to 'Map symptom to first action'
- Step 5: add three useful WorkflowSessionFactory properties documented
in the LTS skill and verified live on the CS SDK with the same OOTB
values — granite.workflow.inboxQuerySize (2000),
granite.workflow.maxPurgeSaveThreshold (20), and
granite.workflow.maxPurgeQueryCount (1000)
Integrates upstream changes from the snowflake-demos test worktree.
Adds a second conversion level alongside the original page-level
(overlay) path.
SKILL.md:
- Two modes documented: page-level (overlay template + [data-slot]
markers) and block-level (each section becomes an independent
EDS block with its own decorate() + CSS).
- New `level` parameter: auto | check | block | page.
- auto: feasibility runs, recommendation surfaced, user confirms
- check: feasibility scan only, stops before Phase 3 (batch scan)
- block / page: explicit override, analysis runs as validation
- Description updated to mention both modes; trigger terms expanded.
- Version bump 1.0.0 → 1.1.0.
phases/2-analyze.md:
- Adds block-level feasibility assessment (5 checks per section:
structure, CSS scope, content model, JS independence, visual
independence).
- decisions.json gains levelParam, conversionLevel, feasibility
fields with per-section pass/fail tables.
- Level-driven transition rules at the end (auto/check/block/page).
knowledge/block-level-feasibility.md (new):
- 301-line reference: the 5 checks in detail, hybrid option, source
signals (BEM/section-scoped → block; Tailwind/utility-first →
page), worked Frescopa example showing all 9 sections passing.
phases/3-generate.md:
- Adds a "Note on conversionLevel" callout explaining that this
phase currently implements only the page-level path. block-level
and hybrid are documented in SKILL.md and block-level-feasibility.md
but Phase 3 generation for them is a future enhancement. Until
then, fall back to page-level and surface a note to the user
rather than silently producing wrong output.
skills-ref validates clean. No XML tags in description.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tessl review feedback after the trim: actionability stayed at 2/3
because the Quick start showed how to read phase files, not the
actual conversion shape. Replaces it with a single compressed
end-to-end example walking all seven phases with real bash commands
(playwright-cli, curl to admin.da.live, curl to admin.hlx.page, git
push to the snowflake-NNN branch). Also collapses "What this skill
does NOT do" from 8 lines to 1.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Addresses Tessl review feedback (Content score 55% → targeting 90%+):
- conciseness 1/3: SKILL.md was 333 lines of host adapter details,
path resolution mechanics, config schemas, and directory conventions
that belong in HOST-NOTES.md. Cut to 156 lines.
- actionability 2/3: entry point had no copy-paste-ready commands.
Added a Quick start section with the Phase 0 substrate-install
invocation and the phase walk-through pattern.
Moves to HOST-NOTES.md (in addition to what was already there):
- "Resolving paths inside this bundle" — per-host SKILL_DIR mapping
Removes from SKILL.md (was duplicative of HOST-NOTES.md or maintainer-
only):
- "How to invoke (host adapters)" section
- "Bundle assets" file tree (now just prose in Quick start)
- "The .snowflake/ directory convention" full section + JSON schema
- "Host-portable constraints (for skill maintainers)" — already in
HOST-NOTES.md
- "Loading knowledge in each phase" — collapsed into a 3-line note
on the seven-phases section
Preserves all 14 markdown links (orphan check stays green).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tessl deterministic validation rejects literal XML tags in the
description field. Reword `<div class="…">` and `<table>` as
"div-class" and "table" — the body of SKILL.md still uses the
literal tags in code-fenced examples, where they belong.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
After moving fixtures/ → references/fixtures/, the link to
references/media.md needs to be ../media.md, not ../references/media.md.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Move snowflake/substrate/* → snowflake/assets/substrate/* and
snowflake/install-substrate.mjs → snowflake/scripts/install-substrate.mjs
so the bundle layout matches Tessl's expected spec dirs
(references/, assets/, scripts/). Updates the installer's path
resolution accordingly (SUBSTRATE_DIR derived via dirname(SCRIPT_DIR)).
- Move da-content/fixtures/* → da-content/references/fixtures/* for
the same reason.
- Add explicit markdown links in snowflake/SKILL.md to phases/*.md,
knowledge/*.md, HOST-NOTES.md, README.md, examples/README.md so
Tessl's orphan check finds them all. da-content/SKILL.md links to
references/fixtures/README.md.
- Rename plugin's .tileignore → .tesslignore (legacy filename
deprecated).
Updates every path mention in SKILL.md, HOST-NOTES.md, README.md,
phases/0-prereq.md to reflect the new layout. Smoke-tested the
installer against a vanilla temp repo — substrate self-locates
correctly.
The remaining "code-review SKILL.md too large" warning is on a
pre-existing skill not touched by this branch.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Imports two skills from aemcoder/skills and wires them into the
plugin's release machinery.
- da-content (renamed from source eds-da-content): reference for DA +
EDS content rules — block HTML format, metadata, media handling, DA
Source API contract, IMS auth, and the 11 silent-failure rules.
Trimmed description from 922 → 709 chars and added a Related Skills
section pointing at da-auth, generate-import-html, page-import,
snowflake.
- snowflake: static-to-EDS overlay conversion that preserves the
original DOM byte-for-byte while making text and image content
authorable in DA. Description leads with the DOM-preservation
property and explicitly defers canonical block-rewrite migrations
to page-import. All internal references updated from eds-da-content
to da-content. SKILL_DIR resolution table rewritten for Claude Code
plugin distribution. DA token reads now consume $DA_TOKEN (set by
da-auth) with ~/.aem/da-token.json fallback.
Cross-skill integration:
- da-auth Related Skills now lists snowflake + da-content
- page-import description disambiguates against snowflake; "Do NOT
use" list points to snowflake for DOM-preservation use cases
- tile.json registers both new skills
- README.md adds a snowflake row to Migrating Content and a new
Content & Platform Reference subsection for da-content
- Each new skill ships package.json + .releaserc.json for
semantic-release
Evals:
- da-content-block-html-generation: 10-item weighted checklist on
silent-failure rule compliance when generating block HTML
- snowflake-overlay-vs-page-import-selection: 7-item checklist on
description-driven skill disambiguation given DOM-preservation
vocabulary
skills-ref validates all 94 skills in the repo.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tokens are now stored at ~/.aem/ims-token.json, not in
.claude-plugin/project-config.json. Update the gitignore comment
in all guide skills to say "contains project config" and update
admin skill auth reads to use the new path.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- da.md: destination field is site-relative, not full /{org}/{site}/ path
- snapshots.md: add 3-step confirmation for publish-entire and approve
- config-api.md: close missing ** in "Fails if org already exists"
- SKILL.md: add publish/approve snapshot to destructive ops table (HIGH)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
All skills now read the IMS token from a single user-level file (~/.aem/ims-token.json)
instead of per-project project-config.json. The ops skill uses ~/.aem/ops-config.json
for org/site context so it works from any directory. Other skills (handover, authoring,
development, admin) retain .claude-plugin/project-config.json for project-level context.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a Sensitive Data Handling section to the ops skill covering
redaction defaults, memory rules, and POST safety on credential
endpoints. The redaction default applies uniformly across all org
types (personal/dev/stage/prod) — customer dev environments hold
real PII just like prod.
secrets.md gets the same empty-POST warning and create-confirmation
gate already present in apikeys.md and tokens.md, since POST to
secrets.json with an empty body creates a real secret on the server.
Verified behavioral compliance in a fresh session: redaction holds
on "list users" prompts and credential values are not re-echoed
after creation.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Three changes bundled together, all driven by live testing against a
non-production org:
1. Drop `--connect-timeout 15 --max-time 120` from every curl example
(22 files). The Bash tool harness already enforces a 120s default
timeout, and the explicit cap was silently failing legitimate slow
operations like bulk publishes and large media uploads.
2. Fix the auto-track polling loop in jobs.md. Progress fields are nested
under `progress` in the API response, not at the top level, so the loop
was always reporting 0/0. Updated the loop and the API reference note.
3. Document accurate response shapes for endpoints that return data:
- apikeys.md / tokens.md: response is keyed-object / array; add
critical warning that empty POST creates a credential with default
role and 1-year expiry, with the secret value returned exactly once.
- logs.md: actual response wraps entries in `{from, to, entries[]}`
with `route` / `method` fields, not flat "Operation".
- snapshots.md: response is `{snapshots: [...], links: {...}}`.
Also drops the leftover doc note in SKILL.md that referenced the removed
curl flags.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Apply a consistent 3-step gate (state impact → ask yes/no → only execute on
yes) across all destructive operations: cache wildcard purge, code delete,
content delete preview, jobs stop, snapshots remove resource, tokens revoke,
users remove org user, versioning delete/restore, and config-api updates.
DA copy gains the same gate as the existing move flow, and stop job is
upgraded from a one-liner warning. SKILL.md risk table updated to match.
Also fix a doc bug in da.md: copy/move destination must be the full
/{org}/{site}/{path} prefix. Site-relative paths silently return HTTP 204
without performing the operation (verified via live testing on asthabh23).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Replace shell-style ${var} with API path placeholder {var} in apikeys,
secrets, tokens, and users resource tables
- Add missing IMS Bearer auth to sites.json curl examples in code.md and
sites.md
- Document that config POST replaces the entire org/site config (not a
merge) so callers GET → modify → POST the full object
- Correct DA folder delete/copy continuation flow: HTTP 206 with JSON
body and continuation-token form field (not response header)
- Switch DA version restore to form-data upload so it works for both
HTML and JSON files
PR #139 wrapped commit-analyzer with path filtering but tried to fix
release-notes-generator with gitRawCommitsOpts: { path: '.' } -- a
no-op because the plugin reads context.commits from semantic-release,
never gitRawCommitsOpts. Result: every skill release body and CHANGELOG
included commits from the entire repo (see slicc-handoff-v1.0.0).
- Add scripts/path-filtered-notes-generator.cjs mirroring the analyzer
wrapper -- filters context.commits via git log -- . before delegating
to the real plugin.
- Wire it into release.config.cjs in place of the bare plugin entry;
drop the dead gitRawCommitsOpts config.
- Regenerate plugins/aem/edge-delivery-services/skills/slicc-handoff/
CHANGELOG.md (skipped by PR #140 because the tag did not exist yet).
Per review feedback: defer SLICC protocol detail to the maintainer-curated
https://www.sliccy.ai/llms.txt index rather than restating it in the
skill. Adds a pointer near the top of SKILL.md and trims "How It Works"
to a one-paragraph summary that links to llms.txt for the full rel URIs,
payload shape, and public API catalog. Activation guidance, verb-prefix
rules, and example commands are kept inline so the skill stays useful
without a network fetch.
Co-authored-by: Cursor <cursoragent@cursor.com>