Skip to content

Add comprehensive JSON schema implementation for AdCP protocol#39

Merged
bokelley merged 3 commits into
mainfrom
json-schema
Sep 1, 2025
Merged

Add comprehensive JSON schema implementation for AdCP protocol#39
bokelley merged 3 commits into
mainfrom
json-schema

Conversation

@bokelley

@bokelley bokelley commented Sep 1, 2025

Copy link
Copy Markdown
Contributor

Summary

  • ✅ Created 36 JSON schemas covering all AdCP protocol objects and operations
  • ✅ Made schemas accessible locally via Docusaurus at /schemas/v1/
  • ✅ Added comprehensive test suite with 13 validation tests
  • ✅ Implemented pre-commit hooks using Husky for automatic validation
  • ✅ Set up CI/CD pipeline for automated testing
  • ✅ Updated documentation with schema-documentation synchronization guidelines

Test plan

  • All 36 schemas pass validation tests
  • Cross-references ($ref) resolve correctly
  • Example data validates against schemas
  • Pre-commit hook runs automatically
  • CI workflow builds and tests successfully
  • Documentation links are fixed

🤖 Generated with Claude Code

bokelley and others added 3 commits September 1, 2025 09:39
- Remove Node.js version matrix from CI (using Node 20 only)
- Remove scripts/ directory with redundant precommit checks
- Update README to reflect Husky pre-commit automation
- Simplify CI workflow to single test run
The CI was failing because husky was added to package.json but
package-lock.json wasn't updated. Running npm install fixed the sync.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@bokelley bokelley merged commit deff341 into main Sep 1, 2025
6 checks passed
bokelley added a commit that referenced this pull request May 12, 2026
Post-expert-review finding on PR #4424:

renderPlacementTags built its delete button as
  onclick="removePlacementTag('${escapeHtml(tag)}')"
escapeHtml encodes ' to &#39;, but the browser decodes the HTML
attribute before parsing the JS string literal — so a malicious
placement_tags key like `x'),alert(1)//` breaks out of the JS
context. Reachable via importFile and validateDomain paths.

Rewrote the function with createElement + textContent and a
closure-based onclick (captures `tag` directly), matching the
pattern renderPlacements/renderCollections already use.

E2E (Playwright + Docker): seeded state.placementTags with the
attribute-bypass payload + an HTML-injection payload — no dialog,
no injected <img>, payloads visible as text, delete button still
removes via closure.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
bokelley added a commit that referenced this pull request May 12, 2026
…lder (#4424)

* feat(admin): add Collections and Placements tabs to adagents.json builder (#4420)

Adds v3 parity for collections[] and placements[] surfaces to the
adagents.json builder tool (deferred from PR #4415 by expert consensus).

- Collections tab: 8-field form (collection_id, name, kind, language,
  status, cadence, description) + raw JSON escape hatch for advanced fields
- Placements tab: placement_id, name, description, property_ids checkbox
  list from state.properties, property_tags, placement_tags chip input
- Placement Tags sub-section within Placements tab (same chip+delete
  pattern as existing Signal Tags tab)
- Agent modal: optional Placement constraints section (placement_ids and
  placement_tags checkboxes — overlays on any property-scoped auth type)
- Import (importFile, startManaging) and export (exportFile,
  updateJsonPreview) all round-trip collections, placements, placement_tags
- All card renders use createElement/textContent for XSS safety

No backend or schema changes. server/src/adagents-manager.ts already
emits v3 and is field-agnostic.

https://claude.ai/code/session_01Fkmv4wwAtqD1JoKeaioXgr

* fix(admin): address pre-PR review blockers on collections/placements builder tabs

- Revert spurious adcp_version downgrade in static/schemas/source/index.json
- Strip reserved keys (collection_id, name, etc.) from advanced textarea before
  Object.assign in saveCollectionForm; prevents silent override of validated fields
- Add duplicate-ID guards on saveCollectionForm and savePlacementForm
- Convert state.placementTags from string[] to {tag:{name,description}} map,
  preserving imported metadata on round-trips (import/export/startManaging)
- removePlacementTag cascade-cleans pl.tags[] on every placement (mirrors removeSignalTag)
- createPlacementTag normalises input (.toLowerCase + /[^a-z0-9_]/ → '_')
- savePlacementForm validates property_tags pattern; normalises placement tags on save
- escapeHtml() all user-originated values in innerHTML template literals:
  showPlacementForm (prop.property_id, prop.name), updateAgentPlacementCheckboxes
  (pl.placement_id, pl.name, tag), renderPlacementTags (tag, meta.description)
- Fix hardcoded #666 colours → var(--color-text-muted) in placement checkbox empties
- Expand changeset body with full change description

https://claude.ai/code/session_01Fkmv4wwAtqD1JoKeaioXgr

* fix(admin): renderPlacementTags XSS via attribute-context escape bypass

Post-expert-review finding on PR #4424:

renderPlacementTags built its delete button as
  onclick="removePlacementTag('${escapeHtml(tag)}')"
escapeHtml encodes ' to &#39;, but the browser decodes the HTML
attribute before parsing the JS string literal — so a malicious
placement_tags key like `x'),alert(1)//` breaks out of the JS
context. Reachable via importFile and validateDomain paths.

Rewrote the function with createElement + textContent and a
closure-based onclick (captures `tag` directly), matching the
pattern renderPlacements/renderCollections already use.

E2E (Playwright + Docker): seeded state.placementTags with the
attribute-bypass payload + an HTML-injection payload — no dialog,
no injected <img>, payloads visible as text, delete button still
removes via closure.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant