@amsterdamdatalabs/enact-extensions 0.1.0 → 0.1.3

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.
Files changed (245) hide show
  1. package/README.md +96 -21
  2. package/dist/index.d.ts +5 -3
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +3 -2
  5. package/dist/index.js.map +1 -1
  6. package/dist/install.d.ts +171 -1
  7. package/dist/install.d.ts.map +1 -1
  8. package/dist/install.js +402 -49
  9. package/dist/install.js.map +1 -1
  10. package/dist/internal/codex.d.ts.map +1 -1
  11. package/dist/internal/codex.js +7 -1
  12. package/dist/internal/codex.js.map +1 -1
  13. package/dist/internal/platform.d.ts +8 -0
  14. package/dist/internal/platform.d.ts.map +1 -1
  15. package/dist/internal/platform.js +46 -2
  16. package/dist/internal/platform.js.map +1 -1
  17. package/dist/provision.d.ts +30 -0
  18. package/dist/provision.d.ts.map +1 -0
  19. package/dist/provision.js +202 -0
  20. package/dist/provision.js.map +1 -0
  21. package/dist/validate/index.d.ts +44 -0
  22. package/dist/validate/index.d.ts.map +1 -1
  23. package/dist/validate/index.js +157 -0
  24. package/dist/validate/index.js.map +1 -1
  25. package/extensions/cmux/.agents/plugin.json +37 -0
  26. package/extensions/cmux/skills/cmux/SKILL.md +82 -0
  27. package/extensions/cmux/skills/cmux/agents/openai.yaml +4 -0
  28. package/extensions/cmux/skills/cmux/references/handles-and-identify.md +35 -0
  29. package/extensions/cmux/skills/cmux/references/panes-surfaces.md +37 -0
  30. package/extensions/cmux/skills/cmux/references/trigger-flash-and-health.md +23 -0
  31. package/extensions/cmux/skills/cmux/references/windows-workspaces.md +31 -0
  32. package/extensions/cmux/skills/cmux-vm-monitor/SKILL.md +122 -0
  33. package/extensions/cmux/skills/cmux-vm-monitor/agents/openai.yaml +4 -0
  34. package/extensions/cmux/skills/cmux-vm-monitor/references/cmux-commands.md +66 -0
  35. package/extensions/cmux/skills/cmux-vm-monitor/scripts/codex_vm_monitor.sh +45 -0
  36. package/extensions/cmux/skills/cmux-workspace/SKILL.md +93 -0
  37. package/extensions/dev-state/.agents/plugin.json +35 -0
  38. package/extensions/dev-state/skills/dev-state-plan-graduation/SKILL.md +194 -0
  39. package/extensions/dev-state/skills/dev-state-plan-graduation/agents/openai.yaml +4 -0
  40. package/extensions/dev-state/skills/dev-state-plan-graduation/references/reference.md +130 -0
  41. package/extensions/devops/.agents/plugin.json +36 -0
  42. package/extensions/devops/skills/azure-devops-cli/SKILL.md +431 -0
  43. package/extensions/devops/skills/azure-devops-cli/agents/openai.yaml +4 -0
  44. package/extensions/devops/skills/ci-pipeline-strategy/SKILL.md +217 -0
  45. package/extensions/devops/skills/ci-pipeline-strategy/agents/openai.yaml +4 -0
  46. package/extensions/enact-context/.agents/plugin.json +40 -0
  47. package/extensions/enact-context/.mcp.json +8 -0
  48. package/extensions/enact-context/README.md +25 -0
  49. package/extensions/enact-context/assets/icon.png +0 -0
  50. package/extensions/enact-context/assets/logo.png +0 -0
  51. package/extensions/enact-context/hooks/hooks.json +115 -0
  52. package/extensions/enact-context/skills/enact-context/SKILL.md +149 -0
  53. package/extensions/enact-context/skills/enact-context/scripts/install.sh +69 -0
  54. package/extensions/enact-factory/.agents/plugin.json +42 -0
  55. package/extensions/enact-factory/.mcp.json +8 -0
  56. package/extensions/enact-factory/assets/icon.png +0 -0
  57. package/extensions/enact-factory/assets/logo.png +0 -0
  58. package/extensions/enact-factory/hooks/user-prompt-submit.mjs +67 -0
  59. package/extensions/enact-factory/skills/testing-strategy/SKILL.md +167 -0
  60. package/extensions/enact-factory/skills/workitem-triage/SKILL.md +22 -0
  61. package/extensions/enact-operator/.agents/plugin.json +57 -0
  62. package/extensions/enact-operator/.app.json +3 -0
  63. package/extensions/enact-operator/.mcp.json +10 -0
  64. package/extensions/enact-operator/_taxonomy.md +86 -0
  65. package/extensions/enact-operator/agents/README.md +5 -0
  66. package/extensions/enact-operator/agents/architect.toml +25 -0
  67. package/extensions/enact-operator/agents/code-reviewer.toml +24 -0
  68. package/extensions/enact-operator/agents/critic.toml +30 -0
  69. package/extensions/enact-operator/agents/executor.toml +24 -0
  70. package/extensions/enact-operator/agents/explore.toml +23 -0
  71. package/extensions/enact-operator/agents/planner.toml +24 -0
  72. package/extensions/enact-operator/agents/verifier.toml +24 -0
  73. package/extensions/enact-operator/assets/icon.png +0 -0
  74. package/extensions/enact-operator/assets/logo.png +0 -0
  75. package/extensions/enact-operator/commands/doctor.md +39 -0
  76. package/extensions/enact-operator/commands/setup.md +51 -0
  77. package/extensions/enact-operator/hooks/hooks.json +146 -0
  78. package/extensions/enact-operator/skills/_variants.md +44 -0
  79. package/extensions/enact-operator/skills/ai-slop-cleaner/SKILL.md +50 -0
  80. package/extensions/enact-operator/skills/analyze/SKILL.md +91 -0
  81. package/extensions/enact-operator/skills/ask/SKILL.md +47 -0
  82. package/extensions/enact-operator/skills/autopilot/SKILL.md +170 -0
  83. package/extensions/enact-operator/skills/autoresearch-goal/SKILL.md +79 -0
  84. package/extensions/enact-operator/skills/cancel/SKILL.md +99 -0
  85. package/extensions/enact-operator/skills/configure-notifications/SKILL.md +77 -0
  86. package/extensions/enact-operator/skills/deep-interview/SKILL.md +80 -0
  87. package/extensions/enact-operator/skills/doctor/SKILL.md +48 -0
  88. package/extensions/enact-operator/skills/hud/SKILL.md +49 -0
  89. package/extensions/enact-operator/skills/hyperplan/SKILL.md +47 -0
  90. package/extensions/enact-operator/skills/plan/SKILL.md +78 -0
  91. package/extensions/enact-operator/skills/ralph/SKILL.md +201 -0
  92. package/extensions/enact-operator/skills/ralph/gemini.md +18 -0
  93. package/extensions/enact-operator/skills/ralplan/SKILL.md +151 -0
  94. package/extensions/enact-operator/skills/remove-deadcode/SKILL.md +45 -0
  95. package/extensions/enact-operator/skills/research/SKILL.md +74 -0
  96. package/extensions/enact-operator/skills/review/SKILL.md +58 -0
  97. package/extensions/enact-operator/skills/security-research/SKILL.md +54 -0
  98. package/extensions/enact-operator/skills/setup/SKILL.md +91 -0
  99. package/extensions/enact-operator/skills/setup/scripts/install.sh +50 -0
  100. package/extensions/enact-operator/skills/skill/SKILL.md +82 -0
  101. package/extensions/enact-operator/skills/tdd/SKILL.md +59 -0
  102. package/extensions/enact-operator/skills/team/SKILL.md +199 -0
  103. package/extensions/enact-operator/skills/trace/SKILL.md +41 -0
  104. package/extensions/enact-operator/skills/ultragoal/SKILL.md +99 -0
  105. package/extensions/enact-operator/skills/ultraqa/SKILL.md +113 -0
  106. package/extensions/enact-operator/skills/ultrawork/SKILL.md +145 -0
  107. package/extensions/enact-operator/skills/ultrawork/planner.md +28 -0
  108. package/extensions/enact-operator/skills/wiki/SKILL.md +41 -0
  109. package/extensions/enact-operator/skills/work-with-workitem/SKILL.md +51 -0
  110. package/extensions/enact-wiki/.agents/plugin.json +42 -0
  111. package/extensions/enact-wiki/.mcp.json +15 -0
  112. package/extensions/enact-wiki/README.md +44 -0
  113. package/extensions/enact-wiki/assets/icon.png +0 -0
  114. package/extensions/enact-wiki/assets/logo.png +0 -0
  115. package/extensions/enact-wiki/skills/document-parser/SKILL.md +17 -0
  116. package/extensions/enact-wiki/skills/document-parser/scripts/parse.sh +60 -0
  117. package/extensions/enact-wiki/skills/document-parser/skill.json +9 -0
  118. package/extensions/enact-wiki/skills/enact-wiki/SKILL.md +30 -0
  119. package/extensions/enact-wiki/skills/enact-wiki/references/ingest.md +62 -0
  120. package/extensions/enact-wiki/skills/enact-wiki/references/manage.md +34 -0
  121. package/extensions/enact-wiki/skills/enact-wiki/references/query.md +59 -0
  122. package/extensions/enact-wiki/skills/search-lab/SKILL.md +57 -0
  123. package/extensions/enact-wiki/skills/search-lab/scripts/analyze.ts +23 -0
  124. package/{plugins/net-revenue-management/.codex-plugin → extensions/net-revenue-management/.agents}/plugin.json +10 -6
  125. package/extensions/plugin-dev/.agents/plugin.json +42 -0
  126. package/extensions/plugin-dev/.mcp.json +3 -0
  127. package/extensions/plugin-dev/agents/agent-creator.md +199 -0
  128. package/extensions/plugin-dev/agents/plugin-validator.md +91 -0
  129. package/extensions/plugin-dev/agents/skill-reviewer.md +212 -0
  130. package/extensions/plugin-dev/commands/_archive/create-marketplace.md +427 -0
  131. package/extensions/plugin-dev/commands/_archive/plugin-dev-guide.md +12 -0
  132. package/extensions/plugin-dev/commands/create-plugin.md +498 -0
  133. package/extensions/plugin-dev/commands/start.md +81 -0
  134. package/extensions/plugin-dev/hooks/hooks.json +3 -0
  135. package/extensions/plugin-dev/skills/agent-development/SKILL.md +641 -0
  136. package/extensions/plugin-dev/skills/agent-development/examples/agent-creation-prompt.md +250 -0
  137. package/extensions/plugin-dev/skills/agent-development/examples/complete-agent-examples.md +461 -0
  138. package/extensions/plugin-dev/skills/agent-development/references/advanced-agent-fields.md +246 -0
  139. package/extensions/plugin-dev/skills/agent-development/references/agent-creation-system-prompt.md +216 -0
  140. package/extensions/plugin-dev/skills/agent-development/references/permission-modes-rules.md +226 -0
  141. package/extensions/plugin-dev/skills/agent-development/references/system-prompt-design.md +464 -0
  142. package/extensions/plugin-dev/skills/agent-development/references/triggering-examples.md +474 -0
  143. package/extensions/plugin-dev/skills/agent-development/scripts/create-agent-skeleton.sh +176 -0
  144. package/extensions/plugin-dev/skills/agent-development/scripts/test-agent-trigger.sh +227 -0
  145. package/extensions/plugin-dev/skills/agent-development/scripts/validate-agent.sh +227 -0
  146. package/extensions/plugin-dev/skills/command-development/SKILL.md +763 -0
  147. package/extensions/plugin-dev/skills/command-development/examples/plugin-commands.md +612 -0
  148. package/extensions/plugin-dev/skills/command-development/examples/simple-commands.md +527 -0
  149. package/extensions/plugin-dev/skills/command-development/references/advanced-workflows.md +762 -0
  150. package/extensions/plugin-dev/skills/command-development/references/documentation-patterns.md +769 -0
  151. package/extensions/plugin-dev/skills/command-development/references/frontmatter-reference.md +508 -0
  152. package/extensions/plugin-dev/skills/command-development/references/interactive-commands.md +966 -0
  153. package/extensions/plugin-dev/skills/command-development/references/marketplace-considerations.md +943 -0
  154. package/extensions/plugin-dev/skills/command-development/references/plugin-features-reference.md +637 -0
  155. package/extensions/plugin-dev/skills/command-development/references/plugin-integration.md +191 -0
  156. package/extensions/plugin-dev/skills/command-development/references/skill-tool.md +447 -0
  157. package/extensions/plugin-dev/skills/command-development/references/testing-strategies.md +723 -0
  158. package/extensions/plugin-dev/skills/command-development/scripts/check-frontmatter.sh +234 -0
  159. package/extensions/plugin-dev/skills/command-development/scripts/validate-command.sh +160 -0
  160. package/extensions/plugin-dev/skills/hook-development/SKILL.md +861 -0
  161. package/extensions/plugin-dev/skills/hook-development/examples/load-context.sh +55 -0
  162. package/extensions/plugin-dev/skills/hook-development/examples/validate-bash.sh +57 -0
  163. package/extensions/plugin-dev/skills/hook-development/examples/validate-write.sh +48 -0
  164. package/extensions/plugin-dev/skills/hook-development/references/advanced.md +871 -0
  165. package/extensions/plugin-dev/skills/hook-development/references/hook-input-schemas.md +145 -0
  166. package/extensions/plugin-dev/skills/hook-development/references/migration.md +392 -0
  167. package/extensions/plugin-dev/skills/hook-development/references/patterns.md +430 -0
  168. package/extensions/plugin-dev/skills/hook-development/scripts/README.md +181 -0
  169. package/extensions/plugin-dev/skills/hook-development/scripts/hook-linter.sh +153 -0
  170. package/extensions/plugin-dev/skills/hook-development/scripts/test-hook.sh +276 -0
  171. package/extensions/plugin-dev/skills/hook-development/scripts/validate-hook-schema.sh +159 -0
  172. package/extensions/plugin-dev/skills/mcp-integration/SKILL.md +775 -0
  173. package/extensions/plugin-dev/skills/mcp-integration/examples/http-server.json +20 -0
  174. package/extensions/plugin-dev/skills/mcp-integration/examples/sse-server.json +19 -0
  175. package/extensions/plugin-dev/skills/mcp-integration/examples/stdio-server.json +38 -0
  176. package/extensions/plugin-dev/skills/mcp-integration/examples/ws-server.json +26 -0
  177. package/extensions/plugin-dev/skills/mcp-integration/references/authentication.md +601 -0
  178. package/extensions/plugin-dev/skills/mcp-integration/references/server-discovery.md +190 -0
  179. package/extensions/plugin-dev/skills/mcp-integration/references/server-types.md +572 -0
  180. package/extensions/plugin-dev/skills/mcp-integration/references/tool-usage.md +623 -0
  181. package/extensions/plugin-dev/skills/plugin-dev-guide/SKILL.md +222 -0
  182. package/extensions/plugin-dev/skills/plugin-structure/SKILL.md +705 -0
  183. package/extensions/plugin-dev/skills/plugin-structure/examples/advanced-plugin.md +774 -0
  184. package/extensions/plugin-dev/skills/plugin-structure/examples/minimal-plugin.md +83 -0
  185. package/extensions/plugin-dev/skills/plugin-structure/examples/standard-plugin.md +611 -0
  186. package/extensions/plugin-dev/skills/plugin-structure/references/advanced-topics.md +289 -0
  187. package/extensions/plugin-dev/skills/plugin-structure/references/component-patterns.md +592 -0
  188. package/extensions/plugin-dev/skills/plugin-structure/references/github-actions.md +233 -0
  189. package/extensions/plugin-dev/skills/plugin-structure/references/headless-ci-mode.md +193 -0
  190. package/extensions/plugin-dev/skills/plugin-structure/references/manifest-reference.md +625 -0
  191. package/extensions/plugin-dev/skills/plugin-structure/references/output-styles.md +116 -0
  192. package/extensions/plugin-dev/skills/skill-development/SKILL.md +564 -0
  193. package/extensions/plugin-dev/skills/skill-development/examples/complete-skill.md +465 -0
  194. package/extensions/plugin-dev/skills/skill-development/examples/frontmatter-templates.md +167 -0
  195. package/extensions/plugin-dev/skills/skill-development/examples/minimal-skill.md +111 -0
  196. package/extensions/plugin-dev/skills/skill-development/references/advanced-frontmatter.md +225 -0
  197. package/extensions/plugin-dev/skills/skill-development/references/commands-vs-skills.md +39 -0
  198. package/extensions/plugin-dev/skills/skill-development/references/skill-creation-workflow.md +379 -0
  199. package/extensions/plugin-dev/skills/skill-development/references/skill-creator-original.md +210 -0
  200. package/package.json +8 -11
  201. package/scripts/enact-extensions.mjs +823 -21
  202. package/scripts/hooks/session-start-drift-check.mjs +58 -0
  203. package/scripts/lib/build-index.mjs +50 -0
  204. package/scripts/lib/bundle-hash.mjs +137 -0
  205. package/scripts/lib/hooks.mjs +741 -0
  206. package/scripts/lib/ledger.mjs +163 -0
  207. package/scripts/lib/list-bundles.mjs +70 -0
  208. package/scripts/lib/outdated.mjs +144 -0
  209. package/scripts/lib/provision-mcp.mjs +16 -0
  210. package/scripts/lib/resolve-bundle.mjs +121 -0
  211. package/scripts/lib/run-install.mjs +402 -38
  212. package/scripts/lib/run-prune.mjs +73 -0
  213. package/scripts/lib/run-sync.mjs +9 -1
  214. package/scripts/lib/run-uninstall.mjs +244 -0
  215. package/scripts/lib/run-update.mjs +152 -0
  216. package/scripts/lib/run-validate.mjs +21 -18
  217. package/scripts/lib/serve.mjs +472 -0
  218. package/scripts/postinstall.mjs +63 -0
  219. package/scripts/setup-enact-context.sh +2 -2
  220. package/scripts/version-bump.sh +463 -0
  221. package/spec/codex.json +1 -11
  222. package/spec/index.json +59 -0
  223. package/web/assets/README.md +111 -0
  224. package/web/assets/logo-full.png +0 -0
  225. package/web/assets/logo-slim.png +0 -0
  226. package/web/assets/tokens/base.css +45 -0
  227. package/web/assets/tokens/colors.css +248 -0
  228. package/web/assets/tokens/effects.css +24 -0
  229. package/web/assets/tokens/fonts.css +8 -0
  230. package/web/assets/tokens/index.css +18 -0
  231. package/web/assets/tokens/spacing.css +50 -0
  232. package/web/index.html +1188 -0
  233. package/.agents/plugins/marketplace.json +0 -20
  234. package/catalog/enact-context.json +0 -9
  235. package/catalog/enact-factory.json +0 -7
  236. package/catalog/enact-operator.json +0 -7
  237. package/catalog/enact-wiki.json +0 -7
  238. package/catalog/net-revenue-management.json +0 -8
  239. package/scripts/rename-supervisor-to-operator.pl +0 -66
  240. package/scripts/sync-manifests.mjs +0 -23
  241. package/scripts/validate-catalog.mjs +0 -37
  242. package/scripts/validate-plugin.mjs +0 -10
  243. /package/{plugins → extensions}/net-revenue-management/.mcp.json +0 -0
  244. /package/{plugins → extensions}/net-revenue-management/skills/net-revenue-risks/SKILL.md +0 -0
  245. /package/{plugins → extensions}/net-revenue-management/skills/net-revenue-scenario/SKILL.md +0 -0
@@ -0,0 +1,463 @@
1
+ #!/usr/bin/env bash
2
+ # ─────────────────────────────────────────────────────────────────────────────
3
+ # version-bump.sh
4
+ # Auto-bumps patch version (x.y.z → x.y.z+1) on a feat/* or fix/* branch,
5
+ # as the LAST CI step before the PR merges into integration.
6
+ #
7
+ # Strategy (runs on the feature branch, not on integration):
8
+ # 1. Must be on a feat/* or fix/* branch — not on integration itself.
9
+ # 2. Fetches origin/integration and compares versions:
10
+ # Same → PR did not manually bump → auto-bump on the feature branch.
11
+ # Different → developer bumped intentionally in the PR → skip silently.
12
+ # 3. Commits + pushes the bump back to the SAME feature branch (***NO_CI***
13
+ # prevents a second pipeline run). The PR then merges to integration
14
+ # already carrying the bumped version.
15
+ #
16
+ # Why not push to integration directly?
17
+ # Azure DevOps branch policy (TF402455) blocks direct pushes to protected
18
+ # branches. We never bypass this — instead we bump on the feature branch.
19
+ #
20
+ # Supported manifest types — detected from filename, no scanning:
21
+ # package.json → npm (.version)
22
+ # pyproject.toml → python ([project] version, uv / PEP 621)
23
+ # Cargo.toml → rust ([package] version)
24
+ #
25
+ # Usage:
26
+ # ./scripts/version-bump.sh --file <path/to/manifest> [OPTIONS]
27
+ #
28
+ # Options:
29
+ # -f, --file <path> REQUIRED. Exact path to the version manifest.
30
+ # -b, --branch <name> Integration branch to compare against (default: integration)
31
+ # --push Push the bump commit back to the feature branch
32
+ # -n, --dry-run Print what would change; no edits, no commit
33
+ # -h, --help Show this help
34
+ # ─────────────────────────────────────────────────────────────────────────────
35
+ set -euo pipefail
36
+
37
+ # ── ANSI colours ──────────────────────────────────────────────────────────────
38
+ RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
39
+ BLUE='\033[0;34m'; BOLD='\033[1m'; NC='\033[0m'
40
+ info() { printf "${BLUE}[INFO]${NC} %s\n" "$*"; }
41
+ ok() { printf "${GREEN}[OK]${NC} %s\n" "$*"; }
42
+ warn() { printf "${YELLOW}[WARN]${NC} %s\n" "$*"; }
43
+ die() { printf "${RED}[ERROR]${NC} %s\n" "$*" >&2; exit 1; }
44
+ step() { printf "\n${BOLD}▶ %s${NC}\n" "$*"; }
45
+
46
+ # ── State ─────────────────────────────────────────────────────────────────────
47
+ VERSION_FILE=""
48
+ PROJECT_TYPE=""
49
+ GIT_REPO_ROOT=""
50
+ CURRENT_VERSION=""
51
+ CURRENT_BRANCH=""
52
+ INTEGRATION_BRANCH="integration"
53
+ DRY_RUN=false
54
+ DO_PUSH=false
55
+
56
+ # ─────────────────────────────────────────────────────────────────────────────
57
+ usage() {
58
+ cat <<'HELP'
59
+ version-bump.sh — Bump patch version (x.y.z → x.y.z+1) on a feat/fix branch before merge
60
+
61
+ USAGE
62
+ ./scripts/version-bump.sh --file <path> [OPTIONS]
63
+
64
+ OPTIONS
65
+ -f, --file <path> REQUIRED. Exact path to the version manifest:
66
+ package.json → npm
67
+ pyproject.toml → python (PEP 621 / uv)
68
+ Cargo.toml → rust
69
+ -b, --branch <name> Integration branch to compare against (default: integration)
70
+ --push Push the bump commit back to the feature branch after committing
71
+ -n, --dry-run Show what would change; do not modify or commit
72
+ -h, --help Show this message
73
+
74
+ GUARDS
75
+ 1. Must be on a feat/* or fix/* branch — never runs on integration directly.
76
+ 2. Fetches origin/<integration-branch> and compares versions:
77
+ Same → PR did not manually bump the version → auto-bump.
78
+ Different → developer bumped intentionally in the PR → skip silently.
79
+
80
+ PUSH TARGET
81
+ The bump commit is pushed back to the CURRENT feature branch (not integration).
82
+ Azure DevOps branch policies block direct pushes to integration; we never bypass them.
83
+
84
+ CI SKIP
85
+ Bump commit message contains ***NO_CI*** — Azure DevOps' official keyword
86
+ to prevent the resulting push from re-triggering the pipeline.
87
+
88
+ AZURE PIPELINES — add as last step in the CI job, covering PR builds on feat/* / fix/*:
89
+
90
+ - script: |
91
+ git config user.email "pipeline@build.com"
92
+ git config user.name "Azure Pipelines"
93
+ git remote set-url origin \
94
+ "https://x-token:$(System.AccessToken)@dev.azure.com/org/project/_git/repo"
95
+ bash scripts/version-bump.sh --file package.json --push
96
+ displayName: Bump patch version
97
+ condition: |
98
+ and(
99
+ succeeded(),
100
+ or(
101
+ startsWith(variables['System.PullRequest.SourceBranch'], 'refs/heads/feat/'),
102
+ startsWith(variables['System.PullRequest.SourceBranch'], 'refs/heads/fix/'),
103
+ startsWith(variables['Build.SourceBranch'], 'refs/heads/feat/'),
104
+ startsWith(variables['Build.SourceBranch'], 'refs/heads/fix/')
105
+ ),
106
+ not(contains(variables['Build.SourceVersionMessage'], '***NO_CI***'))
107
+ )
108
+ env:
109
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
110
+ BUILD_SOURCEBRANCH: $(Build.SourceBranch)
111
+ SYSTEM_PULLREQUEST_SOURCEBRANCH: $(System.PullRequest.SourceBranch)
112
+ HELP
113
+ exit 0
114
+ }
115
+
116
+ # ─────────────────────────────────────────────────────────────────────────────
117
+ parse_args() {
118
+ local file_given=false
119
+ while [[ $# -gt 0 ]]; do
120
+ case "$1" in
121
+ -f|--file) VERSION_FILE="${2:?'--file requires a path'}"; file_given=true; shift 2 ;;
122
+ -b|--branch) INTEGRATION_BRANCH="${2:?'--branch requires a name'}"; shift 2 ;;
123
+ --push) DO_PUSH=true; shift ;;
124
+ -n|--dry-run) DRY_RUN=true; shift ;;
125
+ -h|--help) usage ;;
126
+ *) die "Unknown option: '$1'. Run with --help." ;;
127
+ esac
128
+ done
129
+ $file_given || die "--file <path> is required. Example: --file package.json"
130
+ }
131
+
132
+ # ─────────────────────────────────────────────────────────────────────────────
133
+ # Resolve manifest + detect type from filename (no scanning)
134
+ # ─────────────────────────────────────────────────────────────────────────────
135
+ resolve_manifest() {
136
+ step "Resolving manifest"
137
+ [[ -f "$VERSION_FILE" ]] || die "Manifest not found: '${VERSION_FILE}'"
138
+
139
+ # Physical absolute path (handles /tmp → /private/tmp on macOS etc.)
140
+ VERSION_FILE="$(cd "$(dirname "$VERSION_FILE")" && pwd -P)/$(basename "$VERSION_FILE")"
141
+
142
+ local base
143
+ base="$(basename "$VERSION_FILE")"
144
+ case "$base" in
145
+ package.json) PROJECT_TYPE="npm" ;;
146
+ pyproject.toml) PROJECT_TYPE="python" ;;
147
+ Cargo.toml) PROJECT_TYPE="rust" ;;
148
+ *) die "Unrecognised manifest '${base}'. Expected: package.json | pyproject.toml | Cargo.toml" ;;
149
+ esac
150
+
151
+ local file_dir
152
+ file_dir="$(dirname "$VERSION_FILE")"
153
+ GIT_REPO_ROOT="$(git -C "$file_dir" rev-parse --show-toplevel 2>/dev/null)" || \
154
+ die "'${VERSION_FILE}' is not inside a git repository."
155
+ GIT_REPO_ROOT="$(cd "$GIT_REPO_ROOT" && pwd -P)"
156
+
157
+ info "Manifest : ${VERSION_FILE}"
158
+ info "Type : ${BOLD}${PROJECT_TYPE}${NC}"
159
+ info "Git repo root : ${GIT_REPO_ROOT}"
160
+ }
161
+
162
+ # ─────────────────────────────────────────────────────────────────────────────
163
+ # Version readers
164
+ # ─────────────────────────────────────────────────────────────────────────────
165
+ _read_npm() {
166
+ node -e "const fs=require('fs'); process.stdout.write(JSON.parse(fs.readFileSync('$1','utf8')).version)"
167
+ }
168
+
169
+ _read_python() {
170
+ python3 - "$1" <<'PY'
171
+ import sys, re
172
+ text = open(sys.argv[1]).read()
173
+ def find_in_section(pat, text):
174
+ in_sect = False
175
+ for line in text.splitlines():
176
+ s = line.strip()
177
+ if re.match(pat, s): in_sect = True; continue
178
+ if re.match(r'^\[', s): in_sect = False
179
+ if in_sect:
180
+ m = re.match(r'^version\s*=\s*["\']([^"\']+)["\']', s)
181
+ if m: return m.group(1)
182
+ return None
183
+ ver = (find_in_section(r'^\[project\]', text)
184
+ or find_in_section(r'^\[tool\.poetry\]', text))
185
+ if not ver:
186
+ m = re.search(r'^version\s*=\s*["\']([^"\']+)["\']', text, re.M)
187
+ ver = m.group(1) if m else None
188
+ if ver: sys.stdout.write(ver); sys.exit(0)
189
+ sys.stderr.write(f"version not found in {sys.argv[1]}\n"); sys.exit(1)
190
+ PY
191
+ }
192
+
193
+ _read_rust() {
194
+ python3 - "$1" <<'PY'
195
+ import sys, re
196
+ in_pkg = False
197
+ for line in open(sys.argv[1]):
198
+ s = line.strip()
199
+ if re.match(r'^\[package\]', s): in_pkg = True; continue
200
+ if re.match(r'^\[', s): in_pkg = False
201
+ if in_pkg:
202
+ m = re.match(r'^version\s*=\s*["\']([^"\']+)["\']', s)
203
+ if m: sys.stdout.write(m.group(1)); sys.exit(0)
204
+ sys.stderr.write(f"[package] version not found in {sys.argv[1]}\n"); sys.exit(1)
205
+ PY
206
+ }
207
+
208
+ get_version() {
209
+ local file="${1:-$VERSION_FILE}"
210
+ case "$PROJECT_TYPE" in
211
+ npm) _read_npm "$file" ;;
212
+ python) _read_python "$file" ;;
213
+ rust) _read_rust "$file" ;;
214
+ esac
215
+ }
216
+
217
+ get_version_at_ref() {
218
+ local git_ref="$1"
219
+ local rel_file="${VERSION_FILE#"${GIT_REPO_ROOT}/"}"
220
+ local tmp
221
+ tmp="$(mktemp)"
222
+ trap "rm -f '${tmp}'" RETURN
223
+ git -C "$GIT_REPO_ROOT" show "${git_ref}:${rel_file}" > "$tmp" 2>/dev/null || \
224
+ die "Cannot read '${rel_file}' at ref '${git_ref}'. Is the file committed?"
225
+ get_version "$tmp"
226
+ }
227
+
228
+ # ─────────────────────────────────────────────────────────────────────────────
229
+ # Patch bumper x.y.z → x.y.(z+1)
230
+ # ─────────────────────────────────────────────────────────────────────────────
231
+ bump_patch() {
232
+ local core="${1%%[-+]*}"
233
+ local major minor patch
234
+ IFS='.' read -r major minor patch <<< "$core"
235
+ [[ "$major" =~ ^[0-9]+$ && "$minor" =~ ^[0-9]+$ && "$patch" =~ ^[0-9]+$ ]] || \
236
+ die "Cannot parse '${1}' as semver x.y.z"
237
+ echo "${major}.${minor}.$((patch + 1))"
238
+ }
239
+
240
+ # ─────────────────────────────────────────────────────────────────────────────
241
+ # Version writers
242
+ # ─────────────────────────────────────────────────────────────────────────────
243
+ _write_npm() {
244
+ python3 - "$1" "$2" <<'PY'
245
+ import json, sys
246
+ path, ver = sys.argv[1], sys.argv[2]
247
+ d = json.load(open(path))
248
+ d['version'] = ver
249
+ with open(path, 'w') as f:
250
+ json.dump(d, f, indent=2, ensure_ascii=False); f.write('\n')
251
+ PY
252
+ }
253
+
254
+ _write_python() {
255
+ python3 - "$1" "$2" <<'PY'
256
+ import sys, re
257
+ path, new_ver = sys.argv[1], sys.argv[2]
258
+ lines = open(path).readlines()
259
+ SECTIONS = [r'^\[project\]', r'^\[tool\.poetry\]']
260
+ in_target = replaced = False
261
+ result = []
262
+ for line in lines:
263
+ s = line.strip()
264
+ if any(re.match(p, s) for p in SECTIONS): in_target = True
265
+ elif re.match(r'^\[', s): in_target = False
266
+ if in_target and not replaced:
267
+ new_line = re.sub(r'^(version\s*=\s*)["\']([^"\']+)["\']',
268
+ lambda m: m.group(1) + '"' + new_ver + '"', line)
269
+ if new_line != line: replaced = True; line = new_line
270
+ result.append(line)
271
+ if not replaced:
272
+ full = re.sub(r'^(version\s*=\s*)["\']([^"\']+)["\']',
273
+ lambda m: m.group(1) + '"' + new_ver + '"',
274
+ ''.join(result), count=1, flags=re.M)
275
+ open(path, 'w').write(full)
276
+ else:
277
+ open(path, 'w').writelines(result)
278
+ PY
279
+ }
280
+
281
+ _write_rust() {
282
+ python3 - "$1" "$2" <<'PY'
283
+ import sys, re
284
+ path, new_ver = sys.argv[1], sys.argv[2]
285
+ lines = open(path).readlines()
286
+ in_pkg = replaced = False
287
+ result = []
288
+ for line in lines:
289
+ s = line.strip()
290
+ if re.match(r'^\[package\]', s): in_pkg = True
291
+ elif re.match(r'^\[', s): in_pkg = False
292
+ if in_pkg and not replaced:
293
+ new_line = re.sub(r'^(version\s*=\s*)["\']([^"\']+)["\']',
294
+ lambda m: m.group(1) + '"' + new_ver + '"', line)
295
+ if new_line != line: replaced = True; line = new_line
296
+ result.append(line)
297
+ open(path, 'w').writelines(result)
298
+ PY
299
+ }
300
+
301
+ set_version() {
302
+ case "$PROJECT_TYPE" in
303
+ npm) _write_npm "$VERSION_FILE" "$1" ;;
304
+ python) _write_python "$VERSION_FILE" "$1" ;;
305
+ rust) _write_rust "$VERSION_FILE" "$1" ;;
306
+ esac
307
+ }
308
+
309
+ # ─────────────────────────────────────────────────────────────────────────────
310
+ # Lock file updates (best-effort, non-fatal)
311
+ # ─────────────────────────────────────────────────────────────────────────────
312
+ update_lock_files() {
313
+ case "$PROJECT_TYPE" in
314
+ rust)
315
+ if command -v cargo &>/dev/null; then
316
+ info "Regenerating Cargo.lock (cargo update --workspace)…"
317
+ cargo update --workspace --quiet 2>/dev/null || warn "cargo update failed — Cargo.lock may be stale."
318
+ else
319
+ warn "cargo not found — Cargo.lock NOT updated."
320
+ fi ;;
321
+ python)
322
+ if command -v uv &>/dev/null; then
323
+ info "Regenerating uv.lock (uv lock)…"
324
+ uv lock --quiet 2>/dev/null || warn "uv lock failed — uv.lock may be stale."
325
+ fi ;;
326
+ npm)
327
+ warn "npm lock file NOT touched — run 'npm install' locally to regenerate." ;;
328
+ esac
329
+ }
330
+
331
+ # ─────────────────────────────────────────────────────────────────────────────
332
+ # Guards
333
+ # ─────────────────────────────────────────────────────────────────────────────
334
+ validate_branch() {
335
+ step "Validating source branch"
336
+ local branch
337
+ branch="$(git -C "$GIT_REPO_ROOT" rev-parse --abbrev-ref HEAD)"
338
+
339
+ # Azure Pipelines checks out in detached HEAD state.
340
+ # In PR builds, SYSTEM_PULLREQUEST_SOURCEBRANCH gives the real source branch.
341
+ # In IndividualCI builds, BUILD_SOURCEBRANCH gives the branch.
342
+ if [[ "$branch" == "HEAD" ]]; then
343
+ local pr_branch="${SYSTEM_PULLREQUEST_SOURCEBRANCH:-}"
344
+ local ci_branch="${BUILD_SOURCEBRANCH:-${GITHUB_REF:-}}"
345
+ # Azure DevOps passes '$(Var.Name)' literally when the variable is undefined.
346
+ # Discard any value that looks like an unexpanded template.
347
+ [[ "$pr_branch" == '$('* ]] && pr_branch=""
348
+ [[ "$ci_branch" == '$('* ]] && ci_branch=""
349
+ # PR build: prefer the PR source branch (not the synthetic merge ref)
350
+ local env_branch="${pr_branch:-$ci_branch}"
351
+ branch="${env_branch#refs/heads/}"
352
+ [[ -n "$branch" ]] || \
353
+ die "Detached HEAD and no branch env var set. Cannot determine branch."
354
+ info "Detached HEAD — branch from env: ${branch}"
355
+ fi
356
+
357
+ [[ "$branch" =~ ^(feat|fix)/ ]] || \
358
+ die "Expected a feat/* or fix/* branch, currently on '${branch}'. Version bump runs on feature branches before PR merge."
359
+
360
+ ok "On feature branch '${branch}'."
361
+ CURRENT_BRANCH="$branch"
362
+ }
363
+
364
+ # Guard: compare current branch version against origin/integration.
365
+ # Same → PR did not manually bump → auto-bump this branch.
366
+ # Different → manual bump in PR → skip silently (exit 0).
367
+ validate_version_unchanged() {
368
+ step "Comparing version against origin/${INTEGRATION_BRANCH}"
369
+
370
+ local rel_file="${VERSION_FILE#"${GIT_REPO_ROOT}/"}"
371
+ local v_now v_integration
372
+
373
+ v_now="$(get_version)" || die "Cannot read current version from manifest."
374
+
375
+ # Fetch latest integration so our remote tracking ref is up to date.
376
+ git -C "$GIT_REPO_ROOT" fetch origin "${INTEGRATION_BRANCH}" --quiet 2>/dev/null || \
377
+ warn "Could not fetch origin/${INTEGRATION_BRANCH} — using cached remote tracking branch."
378
+
379
+ # If the manifest doesn't exist on integration yet (new project), just bump.
380
+ if ! git -C "$GIT_REPO_ROOT" show "origin/${INTEGRATION_BRANCH}:${rel_file}" >/dev/null 2>&1; then
381
+ warn "Manifest '${rel_file}' not found on '${INTEGRATION_BRANCH}' — treating as new project; bumping."
382
+ CURRENT_VERSION="$v_now"
383
+ return
384
+ fi
385
+
386
+ local tmp
387
+ tmp="$(mktemp)"
388
+ trap "rm -f '${tmp}'" RETURN
389
+ git -C "$GIT_REPO_ROOT" show "origin/${INTEGRATION_BRANCH}:${rel_file}" > "$tmp" 2>/dev/null
390
+ v_integration="$(get_version "$tmp")" || die "Cannot read version from origin/${INTEGRATION_BRANCH}."
391
+
392
+ info "Version on this branch : ${v_now}"
393
+ info "Version on ${INTEGRATION_BRANCH} : ${v_integration}"
394
+
395
+ if [[ "$v_now" != "$v_integration" ]]; then
396
+ printf "\n${YELLOW}${BOLD}↳ Version differs (%s here vs %s on %s). Manual bump detected — skipping auto-bump.${NC}\n\n" \
397
+ "$v_now" "$v_integration" "$INTEGRATION_BRANCH"
398
+ exit 0 # clean exit — not an error
399
+ fi
400
+
401
+ ok "Versions match at ${BOLD}${v_now}${NC} — safe to auto-bump."
402
+ CURRENT_VERSION="$v_now"
403
+ }
404
+
405
+ # ─────────────────────────────────────────────────────────────────────────────
406
+ # Commit — ***NO_CI*** suppresses Azure DevOps CI on the resulting push
407
+ # ─────────────────────────────────────────────────────────────────────────────
408
+ commit_bump() {
409
+ local new_ver="$1"
410
+ git -C "$GIT_REPO_ROOT" add "$VERSION_FILE"
411
+ case "$PROJECT_TYPE" in
412
+ rust) [[ -f "${GIT_REPO_ROOT}/Cargo.lock" ]] && git -C "$GIT_REPO_ROOT" add "${GIT_REPO_ROOT}/Cargo.lock" || true ;;
413
+ python) [[ -f "${GIT_REPO_ROOT}/uv.lock" ]] && git -C "$GIT_REPO_ROOT" add "${GIT_REPO_ROOT}/uv.lock" || true ;;
414
+ esac
415
+ git -C "$GIT_REPO_ROOT" commit -m "chore: bump version ${CURRENT_VERSION} → ${new_ver} ***NO_CI***"
416
+ ok "Committed: chore: bump version ${CURRENT_VERSION} → ${new_ver} ***NO_CI***"
417
+ }
418
+
419
+ push_bump() {
420
+ local remote
421
+ remote="$(git -C "$GIT_REPO_ROOT" remote | head -1)"
422
+ [[ -n "$remote" ]] || die "No git remote found — cannot push."
423
+ info "Pushing to ${remote}/${CURRENT_BRANCH}…"
424
+ git -C "$GIT_REPO_ROOT" push "$remote" "HEAD:${CURRENT_BRANCH}"
425
+ ok "Pushed to ${remote}/${CURRENT_BRANCH}."
426
+ }
427
+
428
+ # ─────────────────────────────────────────────────────────────────────────────
429
+ # Main
430
+ # ─────────────────────────────────────────────────────────────────────────────
431
+ main() {
432
+ parse_args "$@"
433
+ resolve_manifest
434
+ validate_branch
435
+ validate_version_unchanged # exits 0 silently if version was manually bumped
436
+
437
+ local new_version
438
+ new_version="$(bump_patch "$CURRENT_VERSION")"
439
+
440
+ step "Version bump"
441
+ info " ${CURRENT_VERSION} → ${BOLD}${new_version}${NC}"
442
+
443
+ if $DRY_RUN; then
444
+ warn "Dry-run — no files modified, no commit made."
445
+ return 0
446
+ fi
447
+
448
+ set_version "$new_version"
449
+ ok "Updated ${VERSION_FILE}"
450
+ update_lock_files "$new_version"
451
+
452
+ step "Committing"
453
+ commit_bump "$new_version"
454
+
455
+ if $DO_PUSH; then
456
+ step "Pushing"
457
+ push_bump
458
+ fi
459
+
460
+ printf "\n${GREEN}${BOLD}✓ Done.${NC} Version bumped to ${BOLD}%s${NC}\n\n" "$new_version"
461
+ }
462
+
463
+ main "$@"
package/spec/codex.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "$schema": "http://json-schema.org/draft-07/schema#",
3
3
  "$id": "codex-plugin.json",
4
4
  "title": "Codex Plugin Manifest",
5
- "description": "Validates .codex-plugin/plugin.json for OpenAI Codex plugins. Matches the enact-operator plugin structure.",
5
+ "description": "Validates .codex-plugin/plugin.json for OpenAI Codex plugins. Based on the OpenAI Codex plugin build docs.",
6
6
  "type": "object",
7
7
  "required": [
8
8
  "name"
@@ -69,11 +69,6 @@
69
69
  "description": "Relative path to the skills directory.",
70
70
  "default": "./skills/"
71
71
  },
72
- "commands": {
73
- "type": "string",
74
- "description": "Relative path to slash commands directory (flat Markdown files).",
75
- "default": "./commands/"
76
- },
77
72
  "mcpServers": {
78
73
  "type": "string",
79
74
  "description": "Relative path to the .mcp.json MCP server configuration file.",
@@ -144,11 +139,6 @@
144
139
  "description": "Human-readable list of capabilities shown in the plugin directory."
145
140
  }
146
141
  }
147
- },
148
- "agents": {
149
- "type": "string",
150
- "description": "Relative path to the agents dir.",
151
- "default": "./agents/"
152
142
  }
153
143
  }
154
144
  }
@@ -0,0 +1,59 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "enact-extensions-index.json",
4
+ "title": "Enact Extensions Discovery Index",
5
+ "description": "Schema for the generated discovery index produced by `enact-extensions index`. This is a generated artifact (never committed). The schema file is committed as the contract.",
6
+ "type": "object",
7
+ "required": ["generatedAt", "count", "plugins"],
8
+ "additionalProperties": false,
9
+ "properties": {
10
+ "generatedAt": {
11
+ "description": "ISO 8601 timestamp when the index was generated, or null if not provided.",
12
+ "oneOf": [
13
+ { "type": "string", "format": "date-time" },
14
+ { "type": "null" }
15
+ ]
16
+ },
17
+ "count": {
18
+ "type": "integer",
19
+ "minimum": 0,
20
+ "description": "Total number of plugin bundles discovered. Must equal plugins.length."
21
+ },
22
+ "plugins": {
23
+ "type": "array",
24
+ "description": "Ordered list of discovered plugin bundle entries.",
25
+ "items": {
26
+ "type": "object",
27
+ "required": ["name", "version", "category", "description", "targets", "path"],
28
+ "additionalProperties": false,
29
+ "properties": {
30
+ "name": {
31
+ "type": "string",
32
+ "description": "Unique plugin identifier from .agents/plugin.json."
33
+ },
34
+ "version": {
35
+ "type": "string",
36
+ "description": "Plugin version string."
37
+ },
38
+ "category": {
39
+ "type": "string",
40
+ "description": "Plugin category (from interface.category, may be empty string)."
41
+ },
42
+ "description": {
43
+ "type": "string",
44
+ "description": "Short human-readable plugin description."
45
+ },
46
+ "targets": {
47
+ "type": "array",
48
+ "items": { "type": "string" },
49
+ "description": "Agent platforms this plugin targets (e.g. claude, codex, cursor)."
50
+ },
51
+ "path": {
52
+ "type": "string",
53
+ "description": "Repo-relative path to the plugin bundle directory (relative to package root, not absolute)."
54
+ }
55
+ }
56
+ }
57
+ }
58
+ }
59
+ }
@@ -0,0 +1,111 @@
1
+ # web/assets — Amsterdam Data Labs Design System
2
+
3
+ ## Provenance
4
+
5
+ These assets are vendored from the Amsterdam Data Labs (ADL) design system,
6
+ originally sourced from the `net-revenue-demo` repository
7
+ (`public/_ds/amsterdam-data-labs-design-system-*/tokens/`).
8
+
9
+ They are committed source — not generated — and represent the UI styling
10
+ contract for any HTML surfaces served by enact-extensions. Do not hand-edit
11
+ token values; update from the upstream design system and re-vendor.
12
+
13
+ ## Contents
14
+
15
+ ```
16
+ web/assets/
17
+ logo-full.png — ADL full wordmark (horizontal)
18
+ logo-slim.png — ADL compact mark (icon-only / slim)
19
+ tokens/
20
+ index.css — single entrypoint: @imports all 5 token files
21
+ fonts.css — Google Fonts @import (Space Grotesk / Manrope / IBM Plex Mono)
22
+ colors.css — primitive ramps (--adl-*) + semantic aliases
23
+ spacing.css — 4px-grid space scale, breakpoints, z-index
24
+ effects.css — radii, shadows, motion easing + duration
25
+ base.css — element resets that consume the tokens above
26
+ ```
27
+
28
+ Link `tokens/index.css` from HTML — it loads all five files in the correct
29
+ dependency order (fonts → colors → spacing → effects → base).
30
+
31
+ ## Key Semantic Tokens
32
+
33
+ Product code should consume **semantic** tokens only — never the raw `--adl-*`
34
+ primitive ramps.
35
+
36
+ ### Backgrounds & Surfaces
37
+
38
+ | Token | Light | Dark |
39
+ |---|---|---|
40
+ | `--bg-canvas` | `#ffffff` | `#061726` |
41
+ | `--surface-default` | `#ffffff` | `--adl-navy-900` |
42
+ | `--surface-raised` | `--adl-neutral-50` | `--adl-navy-800` |
43
+ | `--surface-sunken` | `--adl-neutral-100` | `--adl-navy-950` |
44
+
45
+ ### Text
46
+
47
+ | Token | Purpose |
48
+ |---|---|
49
+ | `--text-primary` | Body copy, headings |
50
+ | `--text-secondary` | Supporting labels |
51
+ | `--text-muted` | Placeholder, captions |
52
+ | `--text-link` | Hyperlinks |
53
+
54
+ ### Borders
55
+
56
+ | Token | Purpose |
57
+ |---|---|
58
+ | `--border-subtle` | Dividers, ghost cards |
59
+ | `--border-default` | Standard input borders |
60
+ | `--border-strong` | Emphasized outlines |
61
+ | `--border-focus` | Keyboard focus ring |
62
+
63
+ ### Brand
64
+
65
+ The ADL primary brand anchor is **`--adl-teal-500: #18949a`**.
66
+
67
+ ```css
68
+ --brand-primary: var(--adl-teal-500); /* #18949a */
69
+ --brand-primary-hover: var(--adl-teal-600);
70
+ --brand-primary-active: var(--adl-teal-700);
71
+ --brand-secondary: var(--adl-mint-400); /* #5acfb0 */
72
+ ```
73
+
74
+ ## Light / Dark Theming
75
+
76
+ Tokens switch automatically via the `[data-theme]` attribute. Apply it to
77
+ `<html>` (or any subtree root) to switch the entire surface:
78
+
79
+ ```html
80
+ <!-- light (default — no attribute needed) -->
81
+ <html>
82
+
83
+ <!-- dark -->
84
+ <html data-theme="dark">
85
+ ```
86
+
87
+ All semantic tokens resolve to their dark-mode equivalents when
88
+ `[data-theme="dark"]` is in scope. Primitive ramps (`--adl-*`) are
89
+ theme-invariant.
90
+
91
+ ## Typography
92
+
93
+ Fonts load from Google Fonts via the `@import` in `fonts.css`. No font
94
+ binaries are committed.
95
+
96
+ | Role | Family | Weights |
97
+ |---|---|---|
98
+ | Display / headings | Space Grotesk | 400 500 600 700 |
99
+ | Body / UI text | Manrope | 400 500 600 700 800 |
100
+ | Code / mono / data | IBM Plex Mono | 400 500 600 |
101
+
102
+ CSS variable references:
103
+
104
+ ```css
105
+ --font-display: "Space Grotesk", sans-serif;
106
+ --font-body: "Manrope", sans-serif;
107
+ --font-mono: "IBM Plex Mono", monospace;
108
+ ```
109
+
110
+ Replace with licensed ADL brand font binaries when they become available;
111
+ update `fonts.css` to use `@font-face` declarations pointing to local files.
Binary file
Binary file