ima-claude 2.9.0

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 (182) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +463 -0
  3. package/dist/cli.js +1064 -0
  4. package/package.json +49 -0
  5. package/platforms/claude/adapter.ts +115 -0
  6. package/platforms/junie/adapter.ts +254 -0
  7. package/platforms/junie/agents-template.md +113 -0
  8. package/platforms/junie/hook-translations.md +84 -0
  9. package/platforms/shared/detector.ts +27 -0
  10. package/platforms/shared/installer.ts +202 -0
  11. package/platforms/shared/types.ts +78 -0
  12. package/plugins/ima-claude/.claude-plugin/plugin.json +25 -0
  13. package/plugins/ima-claude/agents/explorer.md +30 -0
  14. package/plugins/ima-claude/agents/implementer.md +30 -0
  15. package/plugins/ima-claude/agents/memory.md +42 -0
  16. package/plugins/ima-claude/agents/reviewer.md +53 -0
  17. package/plugins/ima-claude/agents/tester.md +33 -0
  18. package/plugins/ima-claude/agents/wp-developer.md +46 -0
  19. package/plugins/ima-claude/hooks/README.md +145 -0
  20. package/plugins/ima-claude/hooks/atlassian_prereqs.py +112 -0
  21. package/plugins/ima-claude/hooks/block_sed_edits.py +59 -0
  22. package/plugins/ima-claude/hooks/bootstrap.sh +90 -0
  23. package/plugins/ima-claude/hooks/bootstrap_utility_check.py +94 -0
  24. package/plugins/ima-claude/hooks/composer_autoload_check.py +70 -0
  25. package/plugins/ima-claude/hooks/docs_organization.py +104 -0
  26. package/plugins/ima-claude/hooks/enforce_rg_over_grep.py +56 -0
  27. package/plugins/ima-claude/hooks/fp_utility_check.py +90 -0
  28. package/plugins/ima-claude/hooks/hook_logger.py +69 -0
  29. package/plugins/ima-claude/hooks/hooks.json +239 -0
  30. package/plugins/ima-claude/hooks/jira_issue_fetch.py +79 -0
  31. package/plugins/ima-claude/hooks/jquery_in_wordpress.py +92 -0
  32. package/plugins/ima-claude/hooks/memory_bootstrap.py +79 -0
  33. package/plugins/ima-claude/hooks/memory_store_reminder.py +75 -0
  34. package/plugins/ima-claude/hooks/prompt_coach.py +125 -0
  35. package/plugins/ima-claude/hooks/prompt_coach_digest.md +48 -0
  36. package/plugins/ima-claude/hooks/prompt_coach_system.md +30 -0
  37. package/plugins/ima-claude/hooks/sequential_thinking_check.py +81 -0
  38. package/plugins/ima-claude/hooks/serena_over_grep.py +96 -0
  39. package/plugins/ima-claude/hooks/serena_over_read.py +66 -0
  40. package/plugins/ima-claude/hooks/serena_project_check.py +133 -0
  41. package/plugins/ima-claude/hooks/sql_injection_check.py +73 -0
  42. package/plugins/ima-claude/hooks/task_master_after_plan.py +31 -0
  43. package/plugins/ima-claude/hooks/task_master_before_impl.py +93 -0
  44. package/plugins/ima-claude/hooks/tavily_extract_advanced.py +48 -0
  45. package/plugins/ima-claude/hooks/vestige_before_external.py +86 -0
  46. package/plugins/ima-claude/hooks/webfetch_to_tavily.py +42 -0
  47. package/plugins/ima-claude/hooks/websearch_to_tavily.py +41 -0
  48. package/plugins/ima-claude/hooks/wp_security_check.py +150 -0
  49. package/plugins/ima-claude/personalities/README.md +45 -0
  50. package/plugins/ima-claude/personalities/enable-40k.md +69 -0
  51. package/plugins/ima-claude/personalities/enable-templars.md +69 -0
  52. package/plugins/ima-claude/skills/.research-summary.md +340 -0
  53. package/plugins/ima-claude/skills/architect/SKILL.md +304 -0
  54. package/plugins/ima-claude/skills/compound-bridge/SKILL.md +200 -0
  55. package/plugins/ima-claude/skills/discourse/SKILL.md +440 -0
  56. package/plugins/ima-claude/skills/discourse-admin/SKILL.md +192 -0
  57. package/plugins/ima-claude/skills/discourse-admin/references/api-endpoints.md +441 -0
  58. package/plugins/ima-claude/skills/discourse-admin/references/gotchas.md +107 -0
  59. package/plugins/ima-claude/skills/discourse-admin/references/staging-defaults.md +98 -0
  60. package/plugins/ima-claude/skills/discourse-admin/scripts/discourse-admin.py +319 -0
  61. package/plugins/ima-claude/skills/docs-organize/SKILL.md +254 -0
  62. package/plugins/ima-claude/skills/docs-organize/templates/active-README.md +50 -0
  63. package/plugins/ima-claude/skills/docs-organize/templates/archive-README.md +57 -0
  64. package/plugins/ima-claude/skills/docs-organize/templates/docs-README.md +43 -0
  65. package/plugins/ima-claude/skills/docs-organize/templates/phase-archive-README.md +83 -0
  66. package/plugins/ima-claude/skills/docs-organize/templates/section-README.md +48 -0
  67. package/plugins/ima-claude/skills/docs-organize/templates/transient-README.md +79 -0
  68. package/plugins/ima-claude/skills/docs-organize/templates/transient-gitignore +9 -0
  69. package/plugins/ima-claude/skills/ember-discourse/SKILL.md +496 -0
  70. package/plugins/ima-claude/skills/functional-programmer/SKILL.md +258 -0
  71. package/plugins/ima-claude/skills/ima-bootstrap/SKILL.md +278 -0
  72. package/plugins/ima-claude/skills/ima-bootstrap/references/bootstrap-patterns.md +356 -0
  73. package/plugins/ima-claude/skills/ima-bootstrap/references/ima-brand.md +273 -0
  74. package/plugins/ima-claude/skills/ima-bootstrap/references/theme-integration.md +212 -0
  75. package/plugins/ima-claude/skills/ima-brand/SKILL.md +108 -0
  76. package/plugins/ima-claude/skills/ima-brand/references/brand-identity.md +140 -0
  77. package/plugins/ima-claude/skills/ima-brand/references/digital-standards.md +180 -0
  78. package/plugins/ima-claude/skills/ima-brand/references/visual-system.md +173 -0
  79. package/plugins/ima-claude/skills/ima-forms-expert/SKILL.md +175 -0
  80. package/plugins/ima-claude/skills/ima-forms-expert/references/container-components.md +154 -0
  81. package/plugins/ima-claude/skills/ima-forms-expert/references/examples.md +328 -0
  82. package/plugins/ima-claude/skills/ima-forms-expert/references/field-components.md +298 -0
  83. package/plugins/ima-claude/skills/ima-forms-expert/references/form-factory.md +193 -0
  84. package/plugins/ima-claude/skills/ima-forms-expert/references/quick-reference.md +153 -0
  85. package/plugins/ima-claude/skills/ima-forms-expert/references/validation-engine.md +336 -0
  86. package/plugins/ima-claude/skills/jira-checkpoint/SKILL.md +178 -0
  87. package/plugins/ima-claude/skills/jquery/SKILL.md +413 -0
  88. package/plugins/ima-claude/skills/js-fp/SKILL.md +463 -0
  89. package/plugins/ima-claude/skills/js-fp/core-principles.md +487 -0
  90. package/plugins/ima-claude/skills/js-fp/examples/pure-functions.js +260 -0
  91. package/plugins/ima-claude/skills/js-fp/examples/tests/pure-functions.test.js +262 -0
  92. package/plugins/ima-claude/skills/js-fp/references/anti-patterns.md +120 -0
  93. package/plugins/ima-claude/skills/js-fp/references/performance-patterns.md +116 -0
  94. package/plugins/ima-claude/skills/js-fp/references/testing-patterns.md +134 -0
  95. package/plugins/ima-claude/skills/js-fp-api/SKILL.md +280 -0
  96. package/plugins/ima-claude/skills/js-fp-api/examples/crud-endpoint.js +258 -0
  97. package/plugins/ima-claude/skills/js-fp-api/references/middleware-patterns.md +134 -0
  98. package/plugins/ima-claude/skills/js-fp-api/references/security-sql.md +110 -0
  99. package/plugins/ima-claude/skills/js-fp-api/references/validation-patterns.md +165 -0
  100. package/plugins/ima-claude/skills/js-fp-react/SKILL.md +447 -0
  101. package/plugins/ima-claude/skills/js-fp-react/examples/ProductCard.tsx +65 -0
  102. package/plugins/ima-claude/skills/js-fp-react/references/hooks-advanced.md +136 -0
  103. package/plugins/ima-claude/skills/js-fp-react/references/performance-patterns.md +175 -0
  104. package/plugins/ima-claude/skills/js-fp-vue/SKILL.md +322 -0
  105. package/plugins/ima-claude/skills/js-fp-vue/references/complete-examples.md +397 -0
  106. package/plugins/ima-claude/skills/js-fp-vue/references/composables-advanced.md +282 -0
  107. package/plugins/ima-claude/skills/js-fp-vue/references/reactivity-patterns.md +348 -0
  108. package/plugins/ima-claude/skills/js-fp-vue/references/testing.md +314 -0
  109. package/plugins/ima-claude/skills/js-fp-wordpress/SKILL.md +301 -0
  110. package/plugins/ima-claude/skills/js-fp-wordpress/references/ajax-patterns.md +192 -0
  111. package/plugins/ima-claude/skills/js-fp-wordpress/references/event-patterns.md +136 -0
  112. package/plugins/ima-claude/skills/js-fp-wordpress/references/wp-integration.md +248 -0
  113. package/plugins/ima-claude/skills/livecanvas/SKILL.md +209 -0
  114. package/plugins/ima-claude/skills/livecanvas/references/livecanvas-features.md +311 -0
  115. package/plugins/ima-claude/skills/livecanvas/references/loops-and-logic.md +730 -0
  116. package/plugins/ima-claude/skills/livecanvas/references/picostrap.md +227 -0
  117. package/plugins/ima-claude/skills/mcp-atlassian/SKILL.md +339 -0
  118. package/plugins/ima-claude/skills/mcp-context7/SKILL.md +109 -0
  119. package/plugins/ima-claude/skills/mcp-memory/SKILL.md +182 -0
  120. package/plugins/ima-claude/skills/mcp-qdrant/SKILL.md +233 -0
  121. package/plugins/ima-claude/skills/mcp-sequential/SKILL.md +149 -0
  122. package/plugins/ima-claude/skills/mcp-serena/SKILL.md +174 -0
  123. package/plugins/ima-claude/skills/mcp-tavily/SKILL.md +118 -0
  124. package/plugins/ima-claude/skills/mcp-vestige/SKILL.md +259 -0
  125. package/plugins/ima-claude/skills/php-authnet/SKILL.md +275 -0
  126. package/plugins/ima-claude/skills/php-authnet/references/api-reference.md +624 -0
  127. package/plugins/ima-claude/skills/php-authnet/references/sandbox-testing.md +424 -0
  128. package/plugins/ima-claude/skills/php-fp/SKILL.md +333 -0
  129. package/plugins/ima-claude/skills/php-fp/examples/pure-functions.php +403 -0
  130. package/plugins/ima-claude/skills/php-fp/examples/tests/PureFunctionsTest.php +515 -0
  131. package/plugins/ima-claude/skills/php-fp/references/core-principles.md +277 -0
  132. package/plugins/ima-claude/skills/php-fp/references/testing-patterns.md +374 -0
  133. package/plugins/ima-claude/skills/php-fp-wordpress/SKILL.md +216 -0
  134. package/plugins/ima-claude/skills/php-fp-wordpress/references/fp-patterns.md +275 -0
  135. package/plugins/ima-claude/skills/php-fp-wordpress/references/plugin-architecture.md +295 -0
  136. package/plugins/ima-claude/skills/php-fp-wordpress/references/security-examples.md +203 -0
  137. package/plugins/ima-claude/skills/php-fp-wordpress/references/testing-strategy.md +259 -0
  138. package/plugins/ima-claude/skills/phpunit-wp/SKILL.md +716 -0
  139. package/plugins/ima-claude/skills/playwright/SKILL.md +434 -0
  140. package/plugins/ima-claude/skills/playwright/references/accessibility-testing.md +153 -0
  141. package/plugins/ima-claude/skills/playwright/references/ci-cd.md +268 -0
  142. package/plugins/ima-claude/skills/playwright/references/network-mocking.md +270 -0
  143. package/plugins/ima-claude/skills/playwright/references/visual-regression.md +215 -0
  144. package/plugins/ima-claude/skills/py-fp/SKILL.md +663 -0
  145. package/plugins/ima-claude/skills/py-fp/examples/pure-functions.py +185 -0
  146. package/plugins/ima-claude/skills/py-fp/examples/tests/test_pure_functions.py +244 -0
  147. package/plugins/ima-claude/skills/py-fp/references/core-principles.md +381 -0
  148. package/plugins/ima-claude/skills/py-fp/references/testing-patterns.md +283 -0
  149. package/plugins/ima-claude/skills/quasar-fp/SKILL.md +327 -0
  150. package/plugins/ima-claude/skills/quasar-fp/metadata.json +85 -0
  151. package/plugins/ima-claude/skills/quasar-fp/references/component-patterns.md +257 -0
  152. package/plugins/ima-claude/skills/quasar-fp/references/theme-integration.md +233 -0
  153. package/plugins/ima-claude/skills/quasar-fp/references/utility-classes.md +237 -0
  154. package/plugins/ima-claude/skills/quickstart/SKILL.md +129 -0
  155. package/plugins/ima-claude/skills/rails/SKILL.md +359 -0
  156. package/plugins/ima-claude/skills/resume-session/SKILL.md +68 -0
  157. package/plugins/ima-claude/skills/rg/SKILL.md +205 -0
  158. package/plugins/ima-claude/skills/ruby-fp/SKILL.md +336 -0
  159. package/plugins/ima-claude/skills/save-session/SKILL.md +81 -0
  160. package/plugins/ima-claude/skills/scorecard/SKILL.md +96 -0
  161. package/plugins/ima-claude/skills/skill-analyzer/SKILL.md +127 -0
  162. package/plugins/ima-claude/skills/skill-analyzer/references/advanced-checklist.md +44 -0
  163. package/plugins/ima-claude/skills/skill-analyzer/references/core-checklist.md +60 -0
  164. package/plugins/ima-claude/skills/skill-analyzer/scripts/analyze_skill.py +418 -0
  165. package/plugins/ima-claude/skills/skill-creator/LICENSE.txt +202 -0
  166. package/plugins/ima-claude/skills/skill-creator/SKILL.md +343 -0
  167. package/plugins/ima-claude/skills/skill-creator/references/output-patterns.md +82 -0
  168. package/plugins/ima-claude/skills/skill-creator/references/workflows.md +28 -0
  169. package/plugins/ima-claude/skills/skill-creator/scripts/init_skill.py +303 -0
  170. package/plugins/ima-claude/skills/skill-creator/scripts/package_skill.py +110 -0
  171. package/plugins/ima-claude/skills/skill-creator/scripts/quick_validate.py +103 -0
  172. package/plugins/ima-claude/skills/task-master/SKILL.md +51 -0
  173. package/plugins/ima-claude/skills/task-planner/SKILL.md +228 -0
  174. package/plugins/ima-claude/skills/task-runner/SKILL.md +192 -0
  175. package/plugins/ima-claude/skills/unit-testing/SKILL.md +198 -0
  176. package/plugins/ima-claude/skills/unit-testing/references/mock-patterns.md +181 -0
  177. package/plugins/ima-claude/skills/unit-testing/references/tdd-workflow.md +177 -0
  178. package/plugins/ima-claude/skills/unit-testing/references/test-strategy.md +126 -0
  179. package/plugins/ima-claude/skills/wp-local/SKILL.md +246 -0
  180. package/plugins/ima-claude/skills/wp-local/references/configuration.md +198 -0
  181. package/plugins/ima-claude/skills/wp-local/references/wp-cli-reference.md +406 -0
  182. package/plugins/ima-claude/skills/wp-local/scripts/wp-local.sh +61 -0
@@ -0,0 +1,192 @@
1
+ ---
2
+ name: discourse-admin
3
+ description: "Discourse admin API for site settings, configuration export/import, categories, groups, and custom user fields. Use when: managing Discourse site configuration, deploying config to staging/production, exporting settings, bulk-updating site settings, managing groups or user fields via API. Triggers on: discourse admin, discourse settings, discourse config, site settings, config-as-code, discourse deploy, discourse staging."
4
+ ---
5
+
6
+ # Discourse Admin API
7
+
8
+ Manage Discourse site configuration programmatically via the REST API. Export settings, apply environment configs, manage groups and user fields — without clicking through the admin UI.
9
+
10
+ ## When to Use This Skill
11
+
12
+ - Exporting or importing Discourse site settings
13
+ - Deploying configuration to staging or production environments
14
+ - Bulk-updating site settings via API
15
+ - Managing groups, categories, or custom user fields programmatically
16
+ - Config-as-code workflows for Discourse
17
+
18
+ **Not this skill**: For Discourse *plugin development* (Ruby/Rails/Ember), use the `discourse` skill instead.
19
+
20
+ ## Quick Start
21
+
22
+ **Prerequisites**: Configure environments in `~/.claude/discourse-environments.json`:
23
+ ```json
24
+ {
25
+ "local": {
26
+ "url": "http://localhost:4200",
27
+ "api_key": "your-local-api-key",
28
+ "api_username": "system"
29
+ },
30
+ "staging": {
31
+ "url": "https://staging.community.example.com",
32
+ "api_key": "staging-key",
33
+ "api_username": "system"
34
+ }
35
+ }
36
+ ```
37
+
38
+ **Run commands**:
39
+ ```bash
40
+ python3 ~/.claude/skills/discourse-admin/scripts/discourse-admin.py export
41
+ python3 ~/.claude/skills/discourse-admin/scripts/discourse-admin.py import base.json staging-overlay.json
42
+ python3 ~/.claude/skills/discourse-admin/scripts/discourse-admin.py diff config.json
43
+ python3 ~/.claude/skills/discourse-admin/scripts/discourse-admin.py get title
44
+ python3 ~/.claude/skills/discourse-admin/scripts/discourse-admin.py set disable_emails yes
45
+ python3 ~/.claude/skills/discourse-admin/scripts/discourse-admin.py envs
46
+ ```
47
+
48
+ ## Environment Resolution
49
+
50
+ Resolved via priority chain (same pattern as `wp-local`):
51
+
52
+ 1. `--env` flag on command line
53
+ 2. `$DISCOURSE_ENV` environment variable
54
+ 3. `.discourse-env` file in project root or parents
55
+ 4. Falls back to `"local"`
56
+
57
+ ```bash
58
+ # Explicit env
59
+ python3 discourse-admin.py --env staging export
60
+
61
+ # Env var (set in Kitty terminal config)
62
+ export DISCOURSE_ENV=staging
63
+ python3 discourse-admin.py export
64
+
65
+ # Project file
66
+ echo "staging" > .discourse-env
67
+ python3 discourse-admin.py export
68
+ ```
69
+
70
+ **Credentials** stored in `~/.claude/discourse-environments.json` (not in repo, not in env vars).
71
+ API keys are managed at `/admin/api/keys` in each Discourse instance.
72
+
73
+ ## Config-as-Code Workflow
74
+
75
+ ### Step 1: Export Non-Default Settings
76
+
77
+ ```bash
78
+ python3 discourse-admin.py export discourse-base.json
79
+ ```
80
+
81
+ Exports only settings where value differs from default — typically 50-100 settings, not 500+.
82
+
83
+ ### Step 2: Create Environment Overlays
84
+
85
+ ```
86
+ config/
87
+ discourse-base.json # Non-default settings from local
88
+ discourse-staging.json # Staging overrides
89
+ discourse-production.json # Production overrides
90
+ ```
91
+
92
+ **Staging overlay example** (`discourse-staging.json`):
93
+ ```json
94
+ {
95
+ "title": "[STAGING] Community Forum",
96
+ "site_description": "Staging environment — do not use for real discussions",
97
+ "disable_emails": "yes",
98
+ "notification_email": "noreply-staging@example.com",
99
+ "discourse_connect_provider_secrets": "staging.example.com|staging-secret-here"
100
+ }
101
+ ```
102
+
103
+ ### Step 3: Preview Changes (Dry Run)
104
+
105
+ ```bash
106
+ # Show what would change
107
+ python3 discourse-admin.py --env staging import base.json staging.json --dry-run
108
+
109
+ # Compare remote vs desired
110
+ python3 discourse-admin.py --env staging diff base.json
111
+ ```
112
+
113
+ ### Step 4: Apply Config
114
+
115
+ ```bash
116
+ python3 discourse-admin.py --env staging import discourse-base.json discourse-staging.json
117
+ ```
118
+
119
+ Uses bulk_update endpoint (single request). Falls back to individual updates if bulk fails.
120
+
121
+ ## Site Settings API
122
+
123
+ The primary endpoint for config-as-code. ~500+ settings covering email, SSO, branding, security, etc.
124
+
125
+ ### Key Endpoints
126
+
127
+ | Method | Path | Purpose |
128
+ |--------|------|---------|
129
+ | GET | `/admin/site_settings.json` | List all settings |
130
+ | GET | `/admin/site_settings/category/{slug}.json` | Filter by category |
131
+ | PUT | `/admin/site_settings/{name}.json` | Update single setting |
132
+ | PUT | `/admin/site_settings/bulk_update.json` | Update multiple (undocumented, source-verified) |
133
+
134
+ **Setting categories:** `required`, `basic`, `users`, `email`, `login`, `security`, `onboarding`, `spam`, `rate_limits`, `developer`, `embedding`, `legal`, `branding`, `uncategorized`
135
+
136
+ ## When to Load Reference Files
137
+
138
+ ### Full API Reference
139
+ **File**: `references/api-endpoints.md`
140
+ **Load when**: You need exact parameters, response formats, or edge cases for any admin endpoint (groups, categories, users, user fields, site texts, API keys).
141
+
142
+ ### Known Gotchas
143
+ **File**: `references/gotchas.md`
144
+ **Load when**: Hitting unexpected behavior, 404s, or working with a specific Discourse version. Contains breaking changes across versions and endpoint migration history.
145
+
146
+ ### Staging Defaults
147
+ **File**: `references/staging-defaults.md`
148
+ **Load when**: Setting up a new staging environment. Contains recommended safe defaults and a pre-deploy checklist.
149
+
150
+ ## Common Staging Settings
151
+
152
+ | Setting | Staging Value | Why |
153
+ |---------|--------------|-----|
154
+ | `disable_emails` | `yes` | Prevent sending real emails |
155
+ | `title` | `[STAGING] ...` | Visual distinction |
156
+ | `notification_email` | staging address | Don't spam real inbox |
157
+ | `discourse_connect_provider_secrets` | staging domains | SSO only for staging WP sites |
158
+ | `enable_local_logins` | `true` | Allow direct login for testing |
159
+ | `min_password_length` | `6` | Easier test accounts |
160
+ | `invite_only` | `true` | Prevent public signups |
161
+
162
+ ## Rate Limiting
163
+
164
+ - Admin API rate limits are site-setting driven (not hardcoded)
165
+ - Two independent limiters: IP-based (`max_reqs_per_ip_mode`) and API-key-based (`max_admin_api_reqs_per_minute`, default 60)
166
+ - max=0 means BLOCK ALL (not unlimited) — use high numbers like 6000
167
+ - Must flush Redis rate limit keys after changing rate limit config
168
+
169
+ ## Quick Reference (Manual curl)
170
+
171
+ ```bash
172
+ # List all settings
173
+ curl -s -H "Api-Key: $KEY" -H "Api-Username: system" "$URL/admin/site_settings.json"
174
+
175
+ # Get email settings only
176
+ curl -s -H "Api-Key: $KEY" -H "Api-Username: system" "$URL/admin/site_settings/category/email.json"
177
+
178
+ # Update a single setting
179
+ curl -s -X PUT -H "Api-Key: $KEY" -H "Api-Username: system" \
180
+ -H "Content-Type: application/json" \
181
+ -d '{"disable_emails": "yes"}' \
182
+ "$URL/admin/site_settings/disable_emails.json"
183
+
184
+ # List groups
185
+ curl -s -H "Api-Key: $KEY" -H "Api-Username: system" "$URL/groups.json"
186
+
187
+ # List custom user fields
188
+ curl -s -H "Api-Key: $KEY" -H "Api-Username: system" "$URL/admin/config/user_fields.json"
189
+
190
+ # List categories
191
+ curl -s -H "Api-Key: $KEY" -H "Api-Username: system" "$URL/categories.json"
192
+ ```
@@ -0,0 +1,441 @@
1
+ # Discourse Admin API — Full Endpoint Reference
2
+
3
+ Source-verified against Discourse source code (`config/routes.rb` and controllers).
4
+ Last verified: 2026-03-02 against Discourse 2026.2.x codebase.
5
+
6
+ ## Table of Contents
7
+
8
+ 1. [Site Settings](#site-settings)
9
+ 2. [Categories](#categories)
10
+ 3. [Groups](#groups)
11
+ 4. [Users](#users)
12
+ 5. [Custom User Fields](#custom-user-fields)
13
+ 6. [Site Texts (i18n)](#site-texts)
14
+ 7. [API Keys](#api-keys)
15
+
16
+ ---
17
+
18
+ ## Site Settings
19
+
20
+ ### GET /admin/site_settings.json
21
+
22
+ List all site settings.
23
+
24
+ **Query params:**
25
+ - `categories` — filter by setting categories
26
+ - `plugin` — filter by plugin name
27
+ - `names` — filter specific setting names
28
+
29
+ **Response:** Array of settings, each with:
30
+ ```json
31
+ {
32
+ "setting": "title",
33
+ "value": "My Forum",
34
+ "default": "Discourse",
35
+ "description": "The name of this site...",
36
+ "type": "string",
37
+ "category": "required"
38
+ }
39
+ ```
40
+
41
+ ### GET /admin/site_settings/category/{slug}.json
42
+
43
+ List settings filtered to a category.
44
+
45
+ **Category slugs:** `required`, `basic`, `users`, `email`, `login`, `security`, `onboarding`, `spam`, `rate_limits`, `developer`, `embedding`, `legal`, `branding`, `uncategorized`
46
+
47
+ ### PUT /admin/site_settings/{setting_name}.json
48
+
49
+ Update a single setting.
50
+
51
+ **Body:** `{ "setting_name": "value" }`
52
+ **Response:** `200 OK` (empty body)
53
+
54
+ ### PUT /admin/site_settings/bulk_update.json
55
+
56
+ Update multiple settings in one request.
57
+
58
+ **Body:**
59
+ ```json
60
+ {
61
+ "settings": {
62
+ "setting_1": { "value": "...", "backfill": false },
63
+ "setting_2": { "value": "..." }
64
+ }
65
+ }
66
+ ```
67
+
68
+ The `backfill` flag (optional, default false) triggers retroactive application to existing users where applicable.
69
+
70
+ ### PUT /admin/site_settings/user_count.json
71
+
72
+ Get count of users affected by a setting change (useful before backfill).
73
+
74
+ ---
75
+
76
+ ## Categories
77
+
78
+ **NOTE:** Category routes are NOT under `/admin/`. Permission checks are inline in the controller via Guardian.
79
+
80
+ ### GET /categories.json
81
+
82
+ List all categories.
83
+
84
+ **Query params:** `include_subcategories` (boolean), `page` (integer)
85
+
86
+ **Response:**
87
+ ```json
88
+ {
89
+ "category_list": {
90
+ "categories": [
91
+ {
92
+ "id": 1,
93
+ "name": "General",
94
+ "color": "0088CC",
95
+ "text_color": "FFFFFF",
96
+ "slug": "general",
97
+ "topic_count": 42,
98
+ "position": 0,
99
+ "read_restricted": false,
100
+ "permission": null,
101
+ "parent_category_id": null
102
+ }
103
+ ]
104
+ }
105
+ }
106
+ ```
107
+
108
+ ### GET /site.json
109
+
110
+ Alternative: returns all categories in a flat array under `categories` key, plus trust levels and other site metadata.
111
+
112
+ ### POST /categories.json
113
+
114
+ Create category. Requires `can_create_category` permission.
115
+
116
+ **Body (required):** `name`, `color`, `text_color`
117
+ **Body (optional):** `slug`, `parent_category_id`, `description`, `permissions`
118
+
119
+ **Permissions format:**
120
+ ```json
121
+ {
122
+ "permissions": {
123
+ "everyone": 1,
124
+ "staff": 1,
125
+ "custom_group": 3
126
+ }
127
+ }
128
+ ```
129
+ Permission levels: `1` = See/Reply/Create, `2` = See/Reply, `3` = See only
130
+
131
+ ### PUT /categories/{id}.json
132
+
133
+ Update category. Requires `can_edit_category` permission.
134
+
135
+ **Body:** Any category fields.
136
+
137
+ ### DELETE /categories/{id}.json
138
+
139
+ Delete category. Requires `can_delete_category` permission.
140
+
141
+ ---
142
+
143
+ ## Groups
144
+
145
+ ### GET /groups.json
146
+
147
+ List all groups. Public groups visible without auth.
148
+
149
+ **Query params:** `page` (integer)
150
+
151
+ **Response:**
152
+ ```json
153
+ {
154
+ "groups": [
155
+ {
156
+ "id": 50,
157
+ "name": "moderators",
158
+ "display_name": "Forum Moderators",
159
+ "user_count": 5,
160
+ "visibility_level": 0,
161
+ "automatic": false
162
+ }
163
+ ]
164
+ }
165
+ ```
166
+
167
+ ### GET /groups/{group_name}.json
168
+
169
+ Get group details by name.
170
+
171
+ ### POST /admin/groups.json
172
+
173
+ Create group. Requires staff.
174
+
175
+ **Body (all under `group` key):**
176
+ ```json
177
+ {
178
+ "group": {
179
+ "name": "my-group",
180
+ "display_name": "My Group",
181
+ "visibility_level": 0,
182
+ "mentionable_level": 0,
183
+ "messageable_level": 0,
184
+ "members_visibility_level": 0,
185
+ "automatic_membership_email_domains": "",
186
+ "title": "",
187
+ "primary_group": false,
188
+ "grant_trust_level": null,
189
+ "bio_raw": "",
190
+ "public_admission": false,
191
+ "public_exit": false,
192
+ "owner_usernames": "",
193
+ "usernames": ""
194
+ }
195
+ }
196
+ ```
197
+
198
+ **Visibility levels:** `0` = public, `1` = logged-in, `2` = members, `3` = staff, `4` = owners
199
+
200
+ ### PUT /groups/{id}.json
201
+
202
+ Update group. Same fields as create under `group` key.
203
+
204
+ ### DELETE /admin/groups/{id}.json
205
+
206
+ Delete group. Requires admin.
207
+
208
+ ### PUT /groups/{id}/members.json
209
+
210
+ Add members.
211
+
212
+ **Body:** `{ "usernames": "alice,bob,charlie" }`
213
+ **Response:** `{ "success": "OK", "usernames": ["alice", "bob", "charlie"] }`
214
+
215
+ ### DELETE /groups/{id}/members.json
216
+
217
+ Remove members.
218
+
219
+ **Body:** `{ "usernames": "alice,bob" }`
220
+
221
+ ### PUT /groups/{id}/owners.json
222
+
223
+ Add group owners.
224
+
225
+ **Body:** `{ "usernames": "alice" }`
226
+
227
+ ### DELETE /admin/groups/{id}/owners.json
228
+
229
+ Remove group owner.
230
+
231
+ **Body:** `{ "user_id": 123 }` — NOTE: uses `user_id`, not `usernames`
232
+
233
+ ---
234
+
235
+ ## Users
236
+
237
+ ### POST /users.json
238
+
239
+ Create user.
240
+
241
+ **Body (required):** `name`, `username`, `email`, `password`
242
+ **Body (optional):** `active` (boolean, skip email confirm), `approved` (boolean), `user_fields[{id}]` (set custom field values by field ID)
243
+
244
+ ### GET /u/{username}.json
245
+
246
+ Get user profile. Returns `user_fields` keyed by field ID.
247
+
248
+ ### GET /admin/users/{id}.json
249
+
250
+ Get admin user view. Includes email, IP, groups, flags, suspensions.
251
+
252
+ ### PUT /u/{username}.json
253
+
254
+ Update user profile.
255
+
256
+ **Body:** `name`, `bio_raw`, `user_fields[{id}]`, `timezone`, etc.
257
+
258
+ ### GET /u/by-external/{external_id}.json
259
+
260
+ Lookup user by external (SSO/DiscourseConnect) ID. Admin required.
261
+
262
+ ### GET /admin/users/list/{flag}.json
263
+
264
+ List users by flag: `active`, `new`, `staff`, `suspended`, `blocked`, `suspect`
265
+
266
+ **Query params:** `page`, `show_emails`, `order` (`created`, `last_emailed`, etc.), `asc`
267
+
268
+ ### GET /admin/users.json
269
+
270
+ Search/filter users.
271
+
272
+ **Query params:** `filter` (searches username/email), `show_emails`
273
+
274
+ ### PUT /admin/users/{id}/activate.json
275
+
276
+ Activate user account.
277
+
278
+ ### PUT /admin/users/{id}/deactivate.json
279
+
280
+ Deactivate user account.
281
+
282
+ ### PUT /admin/users/{id}/suspend.json
283
+
284
+ Suspend user.
285
+
286
+ **Body (required):** `suspend_until` (ISO 8601), `reason`
287
+
288
+ ### PUT /admin/users/{id}/silence.json
289
+
290
+ Silence user.
291
+
292
+ **Body (required):** `silenced_till` (ISO 8601)
293
+ **Body (optional):** `reason`
294
+
295
+ **Known quirk:** If user is already silenced, the endpoint may NOT update the date.
296
+
297
+ ### DELETE /admin/users/{id}.json
298
+
299
+ Delete user.
300
+
301
+ **Body:** `delete_posts`, `block_email`, `block_urls`, `block_ip` (all boolean)
302
+
303
+ ---
304
+
305
+ ## Custom User Fields
306
+
307
+ **CRITICAL:** Endpoints migrated in Discourse 3.5.0 (late 2025). Old path `/admin/customize/user_fields.json` returns 404.
308
+
309
+ ### GET /admin/config/user_fields.json
310
+
311
+ List all custom user fields. Both `user_fields` (underscore) and `user-fields` (hyphen) work for GET.
312
+
313
+ **Response:**
314
+ ```json
315
+ [
316
+ {
317
+ "id": 1,
318
+ "name": "Company",
319
+ "description": "Your company name",
320
+ "field_type": "text",
321
+ "editable": true,
322
+ "required": false,
323
+ "show_on_profile": true,
324
+ "show_on_user_card": false,
325
+ "searchable": false,
326
+ "position": 0
327
+ }
328
+ ]
329
+ ```
330
+
331
+ ### POST /admin/config/user_fields.json
332
+
333
+ Create custom user field.
334
+
335
+ **Body:**
336
+ ```json
337
+ {
338
+ "user_field": {
339
+ "name": "Company",
340
+ "field_type": "text",
341
+ "editable": true,
342
+ "required": false,
343
+ "show_on_profile": true,
344
+ "show_on_user_card": false,
345
+ "searchable": false,
346
+ "description": "Your company name",
347
+ "options": ["Option A", "Option B"]
348
+ }
349
+ }
350
+ ```
351
+
352
+ **Field types:** `text`, `confirm`, `dropdown`, `multiselect`
353
+ **`options` required for:** `dropdown`, `multiselect`
354
+
355
+ ### PUT /admin/config/user_fields/{id}.json
356
+
357
+ Update custom user field. Same body as create under `user_field` key.
358
+
359
+ ### DELETE /admin/config/user_fields/{id}.json
360
+
361
+ Delete custom user field.
362
+
363
+ ### Setting Field Values on Users
364
+
365
+ Field values are set/read on the user object, NOT through admin user fields endpoints:
366
+
367
+ - **Create:** `POST /users.json` with `user_fields[{field_id}]`
368
+ - **Update:** `PUT /u/{username}.json` with `user_fields[{field_id}]`
369
+ - **Read:** `GET /u/{username}.json` returns `user_fields: { "1": "value" }`
370
+
371
+ ---
372
+
373
+ ## Site Texts
374
+
375
+ Manage i18n string overrides.
376
+
377
+ ### GET /admin/customize/site_texts.json
378
+
379
+ List i18n strings.
380
+
381
+ **Query params:** `q` (search), `locale`, `overridden` ("true"), `outdated` ("true"), `untranslated` ("true"), `page`
382
+
383
+ ### GET /admin/customize/site_texts/{id}.json
384
+
385
+ Get single string by key.
386
+
387
+ ### PUT /admin/customize/site_texts/{id}.json
388
+
389
+ Override string translation.
390
+
391
+ **Body:** `{ "site_text": { "value": "Custom text here" } }`
392
+
393
+ ### DELETE /admin/customize/site_texts/{id}.json
394
+
395
+ Revert to default translation.
396
+
397
+ ---
398
+
399
+ ## API Keys
400
+
401
+ ### GET /admin/api/keys.json
402
+
403
+ List API keys (paginated, max 50).
404
+
405
+ ### POST /admin/api/keys.json
406
+
407
+ Create API key.
408
+
409
+ **Body:**
410
+ ```json
411
+ {
412
+ "key": {
413
+ "username": "system",
414
+ "description": "Config management",
415
+ "scope_mode": "granular",
416
+ "scopes": []
417
+ }
418
+ }
419
+ ```
420
+
421
+ ### DELETE /admin/api/keys/{id}.json
422
+
423
+ Delete API key.
424
+
425
+ ### POST /admin/api/keys/{id}/revoke.json
426
+
427
+ Revoke key (soft delete).
428
+
429
+ ### POST /admin/api/keys/{id}/undo-revoke.json
430
+
431
+ Restore revoked key.
432
+
433
+ ---
434
+
435
+ ## Access Control Summary
436
+
437
+ | Constraint | Who | Used by |
438
+ |------------|-----|---------|
439
+ | `AdminConstraint` | `current_user.admin?` | Site settings, user fields, delete group, API keys |
440
+ | `StaffConstraint` | `current_user.staff?` | Create group, group owner management |
441
+ | Guardian `can_*` | Permission checks | Categories CRUD, user profile updates |