@clix-so/clix-agent-skills 0.2.3 → 0.2.5

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.
package/README.md CHANGED
@@ -21,6 +21,9 @@ by AI clients.
21
21
  - **clix-api-triggered-campaigns**: Configure API-triggered campaigns in the
22
22
  console and trigger them from your backend with safe auth, dynamic filters
23
23
  (`trigger.*`), and personalization patterns
24
+ - **clix-skill-creator**: Create new Clix agent skills by researching Clix SDK +
25
+ docs via Clix MCP Server, then generating a complete skill folder (SKILL.md,
26
+ references, scripts, examples) aligned with this repo’s conventions
24
27
 
25
28
  ## Installing Skills
26
29
 
@@ -68,7 +71,7 @@ npx @clix-so/clix-agent-skills@latest install integration --client cursor --glob
68
71
 
69
72
  # Install all available skills at once (repo root)
70
73
  npx @clix-so/clix-agent-skills@latest install --all --client cursor
71
- # This will install: integration, event-tracking, user-management, personalization, api-triggered-campaigns
74
+ # This will install: integration, event-tracking, user-management, personalization, api-triggered-campaigns, skill-creator
72
75
 
73
76
  # Install all available skills globally (system root)
74
77
  npx @clix-so/clix-agent-skills@latest install --all --client cursor --global
@@ -78,13 +81,13 @@ npx @clix-so/clix-agent-skills@latest install --all --client cursor --global
78
81
 
79
82
  | Client | Flag | Default Path |
80
83
  | -------------- | ------------------------------------ | ------------------ |
81
- | Amp | `--client amp` | `.amp/skills/` |
84
+ | Amp | `--client amp` | `.agents/skills/` |
82
85
  | Claude Code | `--client claude` (or `claude-code`) | `.claude/skills/` |
83
86
  | Codex | `--client codex` | `.codex/skills/` |
84
87
  | Cursor | `--client cursor` | `.cursor/skills/` |
85
88
  | Gemini CLI | `--client gemini` | `.gemini/skills/` |
86
89
  | GitHub Copilot | `--client github` | `.github/skills/` |
87
- | Goose | `--client goose` | `.goose/skills/` |
90
+ | Goose | `--client goose` | `.agents/skills/` |
88
91
  | Letta | `--client letta` | `.skills/` |
89
92
  | OpenCode | `--client opencode` | `.opencode/skill/` |
90
93
  | VS Code | `--client vscode` | `.vscode/skills/` |
@@ -103,7 +106,7 @@ To install specific skills:
103
106
  1. Visit the Marketplace section in `/plugin`
104
107
  2. Select `Browse plugins`
105
108
  3. Choose the skills you wish to install
106
- 4. Install skill
109
+ 4. Install your preferred skill
107
110
 
108
111
  Alternatively, you can install a single skill directly by running:
109
112
 
@@ -67,7 +67,9 @@ async function installSkill(skillName, options) {
67
67
  relativeDest = ".amazonq/skills";
68
68
  break;
69
69
  case "amp":
70
- relativeDest = ".amp/skills";
70
+ // Amp looks for workspace skills in `.agents/skills/` and user skills in `~/.config/agents/skills/`.
71
+ // We map `--global` to the user-level location.
72
+ relativeDest = options.global ? ".config/agents/skills" : ".agents/skills";
71
73
  break;
72
74
  case "claude":
73
75
  case "claude-code":
@@ -92,7 +94,11 @@ async function installSkill(skillName, options) {
92
94
  relativeDest = ".skills";
93
95
  break;
94
96
  case "goose":
95
- relativeDest = ".goose/skills";
97
+ // Goose supports portable skill locations too:
98
+ // - project: `./.agents/skills/`
99
+ // - global : `~/.config/agents/skills/`
100
+ // We default to the portable locations, but users can still override via --path.
101
+ relativeDest = options.global ? ".config/agents/skills" : ".agents/skills";
96
102
  break;
97
103
  case "kiro":
98
104
  relativeDest = ".kiro/skills";
package/llms.txt CHANGED
@@ -9,9 +9,7 @@ Each entry includes the file path, type, and description for semantic search.
9
9
 
10
10
  ## clix-api-triggered-campaigns
11
11
 
12
- Helps developers configure API-triggered campaigns in the Clix console and trigger them from backend services with safe auth, payload schemas, dynamic audience filters (trigger.*), and personalization best practices. Use when the user mentions transactional notifications, backend-triggered sends, campaign_id trigger APIs, or "API-triggered campaigns".
13
-
14
- - [clix-api-triggered-campaigns](https://raw.githubusercontent.com/clix-so/skills/refs/heads/main/skills/api-triggered-campaigns/SKILL.md): Helps developers configure API-triggered campaigns in the Clix console and trigger them from backend services with safe auth, payload schemas, dynamic audience filters (trigger.*), and personalization best practices. Use when the user mentions transactional notifications, backend-triggered sends, campaign_id trigger APIs, or "API-triggered campaigns".
12
+ - [clix-api-triggered-campaigns](https://raw.githubusercontent.com/clix-so/skills/refs/heads/main/skills/api-triggered-campaigns/SKILL.md): Main skill documentation
15
13
 
16
14
  ### References
17
15
 
@@ -35,9 +33,7 @@ Helps developers configure API-triggered campaigns in the Clix console and trigg
35
33
 
36
34
  ## clix-event-tracking
37
35
 
38
- Implements Clix event tracking (Clix.trackEvent) with consistent naming, safe property schemas, and campaign-ready validation. Use when adding, reviewing, or debugging event tracking; when configuring event-triggered campaigns; or when the user mentions events, tracking, funnels, or properties — or when the user types `clix-event-tracking`.
39
-
40
- - [clix-event-tracking](https://raw.githubusercontent.com/clix-so/skills/refs/heads/main/skills/event-tracking/SKILL.md): Implements Clix event tracking (Clix.trackEvent) with consistent naming, safe property schemas, and campaign-ready validation. Use when adding, reviewing, or debugging event tracking; when configuring event-triggered campaigns; or when the user mentions events, tracking, funnels, or properties — or when the user types `clix-event-tracking`.
36
+ - [clix-event-tracking](https://raw.githubusercontent.com/clix-so/skills/refs/heads/main/skills/event-tracking/SKILL.md): Main skill documentation
41
37
 
42
38
  ### References
43
39
 
@@ -55,9 +51,7 @@ Implements Clix event tracking (Clix.trackEvent) with consistent naming, safe pr
55
51
 
56
52
  ## clix-integration
57
53
 
58
- Integrates Clix Mobile SDK into iOS, Android, Flutter, and React Native projects. Provides step-by-step guidance for installation, initialization, and verification. Use when the user asks to install, setup, integrate Clix or when the user types `clix-integration` / "clix integration".
59
-
60
- - [clix-integration](https://raw.githubusercontent.com/clix-so/skills/refs/heads/main/skills/integration/SKILL.md): Integrates Clix Mobile SDK into iOS, Android, Flutter, and React Native projects. Provides step-by-step guidance for installation, initialization, and verification. Use when the user asks to install, setup, integrate Clix or when the user types `clix-integration` / "clix integration".
54
+ - [clix-integration](https://raw.githubusercontent.com/clix-so/skills/refs/heads/main/skills/integration/SKILL.md): Main skill documentation
61
55
 
62
56
  ### References
63
57
 
@@ -82,9 +76,7 @@ Integrates Clix Mobile SDK into iOS, Android, Flutter, and React Native projects
82
76
 
83
77
  ## clix-personalization
84
78
 
85
- Helps developers author and debug Clix personalization templates (Liquid-style) for message content, deep links/URLs, and audience targeting. Use when the user mentions personalization variables, Liquid, templates, conditional logic, loops, filters, deep links, message logs, or when the user types `clix-personalization`.
86
-
87
- - [clix-personalization](https://raw.githubusercontent.com/clix-so/skills/refs/heads/main/skills/personalization/SKILL.md): Helps developers author and debug Clix personalization templates (Liquid-style) for message content, deep links/URLs, and audience targeting. Use when the user mentions personalization variables, Liquid, templates, conditional logic, loops, filters, deep links, message logs, or when the user types `clix-personalization`.
79
+ - [clix-personalization](https://raw.githubusercontent.com/clix-so/skills/refs/heads/main/skills/personalization/SKILL.md): Main skill documentation
88
80
 
89
81
  ### References
90
82
 
@@ -98,11 +90,30 @@ Helps developers author and debug Clix personalization templates (Liquid-style)
98
90
 
99
91
  ---
100
92
 
101
- ## clix-user-management
93
+ ## clix-skill-creator
94
+
95
+ - [clix-skill-creator](https://raw.githubusercontent.com/clix-so/skills/refs/heads/main/skills/skill-creator/SKILL.md): Main skill documentation
96
+
97
+ ### References
98
+
99
+ - [Mcp Research Playbook (Reference)](https://raw.githubusercontent.com/clix-so/skills/refs/heads/main/skills/skill-creator/references/mcp-research-playbook.md): Reference documentation for skill-creator skill
100
+ - [Skill Template (Reference)](https://raw.githubusercontent.com/clix-so/skills/refs/heads/main/skills/skill-creator/references/skill-template.md): Reference documentation for skill-creator skill
102
101
 
103
- Implements Clix user identification and user properties (setUserId, removeUserId, setUserProperty/setUserProperties, removeUserProperty/removeUserProperties) with safe schemas, logout best practices, and campaign-ready personalization/audience usage. Use when the user mentions login/logout, userId, user properties, personalization, audience targeting or when the user types `clix-user-management`.
102
+ ### Examples
103
+
104
+ - [Skill Brief Example (Example)](https://raw.githubusercontent.com/clix-so/skills/refs/heads/main/skills/skill-creator/examples/skill-brief-example.yaml): Code example for skill-creator skill
105
+
106
+ ### Scripts
107
+
108
+ - [Validate Same Scope (Script)](https://raw.githubusercontent.com/clix-so/skills/refs/heads/main/skills/skill-creator/scripts/validate-same-scope.sh): Utility script for skill-creator skill
109
+ - [Validate Skill Location (Script)](https://raw.githubusercontent.com/clix-so/skills/refs/heads/main/skills/skill-creator/scripts/validate-skill-location.sh): Utility script for skill-creator skill
110
+ - [Validate Skill Scaffold (Script)](https://raw.githubusercontent.com/clix-so/skills/refs/heads/main/skills/skill-creator/scripts/validate-skill-scaffold.sh): Utility script for skill-creator skill
111
+
112
+ ---
113
+
114
+ ## clix-user-management
104
115
 
105
- - [clix-user-management](https://raw.githubusercontent.com/clix-so/skills/refs/heads/main/skills/user-management/SKILL.md): Implements Clix user identification and user properties (setUserId, removeUserId, setUserProperty/setUserProperties, removeUserProperty/removeUserProperties) with safe schemas, logout best practices, and campaign-ready personalization/audience usage. Use when the user mentions login/logout, userId, user properties, personalization, audience targeting or when the user types `clix-user-management`.
116
+ - [clix-user-management](https://raw.githubusercontent.com/clix-so/skills/refs/heads/main/skills/user-management/SKILL.md): Main skill documentation
106
117
 
107
118
  ### References
108
119
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clix-so/clix-agent-skills",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "description": "An open collection of agent skills for Clix.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -2,8 +2,7 @@
2
2
  name: clix-api-triggered-campaigns
3
3
  display-name: API-Triggered Campaigns
4
4
  short-description: API-triggered campaign setup
5
- description:
6
- Helps developers configure API-triggered campaigns in the Clix console and
5
+ description: Helps developers configure API-triggered campaigns in the Clix console and
7
6
  trigger them from backend services with safe auth, payload schemas, dynamic
8
7
  audience filters (trigger.*), and personalization best practices. Use when the
9
8
  user mentions transactional notifications, backend-triggered sends,
@@ -2,8 +2,7 @@
2
2
  name: clix-event-tracking
3
3
  display-name: Event Tracking
4
4
  short-description: Event tracking setup
5
- description:
6
- Implements Clix event tracking (Clix.trackEvent) with consistent naming, safe
5
+ description: Implements Clix event tracking (Clix.trackEvent) with consistent naming, safe
7
6
  property schemas, and campaign-ready validation. Use when adding, reviewing,
8
7
  or debugging event tracking; when configuring event-triggered campaigns; or
9
8
  when the user mentions events, tracking, funnels, or properties — or when the
@@ -101,7 +100,8 @@ The skill directory is typically:
101
100
 
102
101
  - `.cursor/skills/event-tracking/` (Cursor)
103
102
  - `.claude/skills/event-tracking/` (Claude Code)
104
- - `.vscode/skills/event-tracking/` (VS Code/Amp)
103
+ - `.vscode/skills/event-tracking/` (VS Code)
104
+ - `.agents/skills/event-tracking/` (Amp)
105
105
  - Or check where this skill was installed
106
106
 
107
107
  If validation fails: fix the plan first, then implement.
@@ -2,8 +2,7 @@
2
2
  name: clix-integration
3
3
  display-name: SDK Integration
4
4
  short-description: SDK integration guide
5
- description:
6
- Integrates Clix Mobile SDK into iOS, Android, Flutter, and React Native
5
+ description: Integrates Clix Mobile SDK into iOS, Android, Flutter, and React Native
7
6
  projects. Provides step-by-step guidance for installation, initialization, and
8
7
  verification. Use when the user asks to install, setup, integrate Clix or when
9
8
  the user types `clix-integration` / "clix integration".
@@ -241,8 +241,7 @@ try {
241
241
  ### Provide Fallbacks
242
242
 
243
243
  ```typescript
244
- const projectId =
245
- process.env.CLIX_PROJECT_ID || process.env.REACT_APP_CLIX_PROJECT_ID || "";
244
+ const projectId = process.env.CLIX_PROJECT_ID || process.env.REACT_APP_CLIX_PROJECT_ID || "";
246
245
 
247
246
  if (!projectId) {
248
247
  console.warn("Clix: No project ID found, analytics disabled");
@@ -2,8 +2,7 @@
2
2
  name: clix-personalization
3
3
  display-name: Personalization
4
4
  short-description: Personalization templates
5
- description:
6
- Helps developers author and debug Clix personalization templates
5
+ description: Helps developers author and debug Clix personalization templates
7
6
  (Liquid-style) for message content, deep links/URLs, and audience targeting.
8
7
  Use when the user mentions personalization variables, Liquid, templates,
9
8
  conditional logic, loops, filters, deep links, message logs, or when the user
@@ -0,0 +1,204 @@
1
+ Copyright (c) 2026 Clix (https://clix.so/)
2
+
3
+ Apache License
4
+ Version 2.0, January 2004
5
+ http://www.apache.org/licenses/
6
+
7
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
8
+
9
+ 1. Definitions.
10
+
11
+ "License" shall mean the terms and conditions for use, reproduction,
12
+ and distribution as defined by Sections 1 through 9 of this document.
13
+
14
+ "Licensor" shall mean the copyright owner or entity authorized by
15
+ the copyright owner that is granting the License.
16
+
17
+ "Legal Entity" shall mean the union of the acting entity and all
18
+ other entities that control, are controlled by, or are under common
19
+ control with that entity. For the purposes of this definition,
20
+ "control" means (i) the power, direct or indirect, to cause the
21
+ direction or management of such entity, whether by contract or
22
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
23
+ outstanding shares, or (iii) beneficial ownership of such entity.
24
+
25
+ "You" (or "Your") shall mean an individual or Legal Entity
26
+ exercising permissions granted by this License.
27
+
28
+ "Source" form shall mean the preferred form for making modifications,
29
+ including but not limited to software source code, documentation
30
+ source, and configuration files.
31
+
32
+ "Object" form shall mean any form resulting from mechanical
33
+ transformation or translation of a Source form, including but
34
+ not limited to compiled object code, generated documentation,
35
+ and conversions to other media types.
36
+
37
+ "Work" shall mean the work of authorship, whether in Source or
38
+ Object form, made available under the License, as indicated by a
39
+ copyright notice that is included in or attached to the work
40
+ (an example is provided in the Appendix below).
41
+
42
+ "Derivative Works" shall mean any work, whether in Source or Object
43
+ form, that is based on (or derived from) the Work and for which the
44
+ editorial revisions, annotations, elaborations, or other modifications
45
+ represent, as a whole, an original work of authorship. For the purposes
46
+ of this License, Derivative Works shall not include works that remain
47
+ separable from, or merely link (or bind by name) to the interfaces of,
48
+ the Work and Derivative Works thereof.
49
+
50
+ "Contribution" shall mean any work of authorship, including
51
+ the original version of the Work and any modifications or additions
52
+ to that Work or Derivative Works thereof, that is intentionally
53
+ submitted to Licensor for inclusion in the Work by the copyright owner
54
+ or by an individual or Legal Entity authorized to submit on behalf of
55
+ the copyright owner. For the purposes of this definition, "submitted"
56
+ means any form of electronic, verbal, or written communication sent
57
+ to the Licensor or its representatives, including but not limited to
58
+ communication on electronic mailing lists, source code control systems,
59
+ and issue tracking systems that are managed by, or on behalf of, the
60
+ Licensor for the purpose of discussing and improving the Work, but
61
+ excluding communication that is conspicuously marked or otherwise
62
+ designated in writing by the copyright owner as "Not a Contribution."
63
+
64
+ "Contributor" shall mean Licensor and any individual or Legal Entity
65
+ on behalf of whom a Contribution has been received by Licensor and
66
+ subsequently incorporated within the Work.
67
+
68
+ 2. Grant of Copyright License. Subject to the terms and conditions of
69
+ this License, each Contributor hereby grants to You a perpetual,
70
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
71
+ copyright license to reproduce, prepare Derivative Works of,
72
+ publicly display, publicly perform, sublicense, and distribute the
73
+ Work and such Derivative Works in Source or Object form.
74
+
75
+ 3. Grant of Patent License. Subject to the terms and conditions of
76
+ this License, each Contributor hereby grants to You a perpetual,
77
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
78
+ (except as stated in this section) patent license to make, have made,
79
+ use, offer to sell, sell, import, and otherwise transfer the Work,
80
+ where such license applies only to those patent claims licensable
81
+ by such Contributor that are necessarily infringed by their
82
+ Contribution(s) alone or by combination of their Contribution(s)
83
+ with the Work to which such Contribution(s) was submitted. If You
84
+ institute patent litigation against any entity (including a
85
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
86
+ or a Contribution incorporated within the Work constitutes direct
87
+ or contributory patent infringement, then any patent licenses
88
+ granted to You under this License for that Work shall terminate
89
+ as of the date such litigation is filed.
90
+
91
+ 4. Redistribution. You may reproduce and distribute copies of the
92
+ Work or Derivative Works thereof in any medium, with or without
93
+ modifications, and in Source or Object form, provided that You
94
+ meet the following conditions:
95
+
96
+ (a) You must give any other recipients of the Work or
97
+ Derivative Works a copy of this License; and
98
+
99
+ (b) You must cause any modified files to carry prominent notices
100
+ stating that You changed the files; and
101
+
102
+ (c) You must retain, in the Source form of any Derivative Works
103
+ that You distribute, all copyright, patent, trademark, and
104
+ attribution notices from the Source form of the Work,
105
+ excluding those notices that do not pertain to any part of
106
+ the Derivative Works; and
107
+
108
+ (d) If the Work includes a "NOTICE" text file as part of its
109
+ distribution, then any Derivative Works that You distribute must
110
+ include a readable copy of the attribution notices contained
111
+ within such NOTICE file, excluding those notices that do not
112
+ pertain to any part of the Derivative Works, in at least one
113
+ of the following places: within a NOTICE text file distributed
114
+ as part of the Derivative Works; within the Source form or
115
+ documentation, if provided along with the Derivative Works; or,
116
+ within a display generated by the Derivative Works, if and
117
+ wherever such third-party notices normally appear. The contents
118
+ of the NOTICE file are for informational purposes only and
119
+ do not modify the License. You may add Your own attribution
120
+ notices within Derivative Works that You distribute, alongside
121
+ or as an addendum to the NOTICE text from the Work, provided
122
+ that such additional attribution notices cannot be construed
123
+ as modifying the License.
124
+
125
+ You may add Your own copyright statement to Your modifications and
126
+ may provide additional or different license terms and conditions
127
+ for use, reproduction, or distribution of Your modifications, or
128
+ for any such Derivative Works as a whole, provided Your use,
129
+ reproduction, and distribution of the Work otherwise complies with
130
+ the conditions stated in this License.
131
+
132
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
133
+ any Contribution intentionally submitted for inclusion in the Work
134
+ by You to the Licensor shall be under the terms and conditions of
135
+ this License, without any additional terms or conditions.
136
+ Notwithstanding the above, nothing herein shall supersede or modify
137
+ the terms of any separate license agreement you may have executed
138
+ with Licensor regarding such Contributions.
139
+
140
+ 6. Trademarks. This License does not grant permission to use the trade
141
+ names, trademarks, service marks, or product names of the Licensor,
142
+ except as required for reasonable and customary use in describing the
143
+ origin of the Work and reproducing the content of the NOTICE file.
144
+
145
+ 7. Disclaimer of Warranty. Unless required by applicable law or
146
+ agreed to in writing, Licensor provides the Work (and each
147
+ Contributor provides its Contributions) on an "AS IS" BASIS,
148
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
149
+ implied, including, without limitation, any warranties or conditions
150
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
151
+ PARTICULAR PURPOSE. You are solely responsible for determining the
152
+ appropriateness of using or redistributing the Work and assume any
153
+ risks associated with Your exercise of permissions under this License.
154
+
155
+ 8. Limitation of Liability. In no event and under no legal theory,
156
+ whether in tort (including negligence), contract, or otherwise,
157
+ unless required by applicable law (such as deliberate and grossly
158
+ negligent acts) or agreed to in writing, shall any Contributor be
159
+ liable to You for damages, including any direct, indirect, special,
160
+ incidental, or consequential damages of any character arising as a
161
+ result of this License or out of the use or inability to use the
162
+ Work (including but not limited to damages for loss of goodwill,
163
+ work stoppage, computer failure or malfunction, or any and all
164
+ other commercial damages or losses), even if such Contributor
165
+ has been advised of the possibility of such damages.
166
+
167
+ 9. Accepting Warranty or Additional Liability. While redistributing
168
+ the Work or Derivative Works thereof, You may choose to offer,
169
+ and charge a fee for, acceptance of support, warranty, indemnity,
170
+ or other liability obligations and/or rights consistent with this
171
+ License. However, in accepting such obligations, You may act only
172
+ on Your own behalf and on Your sole responsibility, not on behalf
173
+ of any other Contributor, and only if You agree to indemnify,
174
+ defend, and hold each Contributor harmless for any liability
175
+ incurred by, or claims asserted against, such Contributor by reason
176
+ of your accepting any such warranty or additional liability.
177
+
178
+ END OF TERMS AND CONDITIONS
179
+
180
+ APPENDIX: How to apply the Apache License to your work.
181
+
182
+ To apply the Apache License to your work, attach the following
183
+ boilerplate notice, with the fields enclosed by brackets "[]"
184
+ replaced with your own identifying information. (Don't include
185
+ the brackets!) The text should be enclosed in the appropriate
186
+ comment syntax for the file format. We also recommend that a
187
+ file or class name and description of purpose be included on the
188
+ same "printed page" as the copyright notice for easier
189
+ identification within third-party archives.
190
+
191
+ Copyright (c) 2026 Clix (https://clix.so/)
192
+
193
+ Licensed under the Apache License, Version 2.0 (the "License");
194
+ you may not use this file except in compliance with the License.
195
+ You may obtain a copy of the License at
196
+
197
+ http://www.apache.org/licenses/LICENSE-2.0
198
+
199
+ Unless required by applicable law or agreed to in writing, software
200
+ distributed under the License is distributed on an "AS IS" BASIS,
201
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
202
+ See the License for the specific language governing permissions and
203
+ limitations under the License.
204
+
@@ -0,0 +1,195 @@
1
+ ---
2
+ name: clix-skill-creator
3
+ display-name: Skill Creator
4
+ short-description: Generate new Clix agent skills
5
+ description: Helps authors create new Clix agent skills by first researching the latest Clix
6
+ SDK + docs via the Clix MCP Server, then generating a complete skill folder
7
+ (SKILL.md, references, scripts, examples) aligned with the conventions in this
8
+ repository. Use when the user asks to create/author a new Clix skill, extend
9
+ the skills library, or when the user types `clix-skill-creator`.
10
+ user-invocable: true
11
+ ---
12
+
13
+ # Clix Skill Creator
14
+
15
+ Use this skill to **create a new Clix skill** that matches a user's need, while
16
+ avoiding duplicated scope and **preventing hallucinated API usage** by relying
17
+ on the Clix MCP server as the source of truth.
18
+
19
+ This is a “meta-skill”: it does not integrate an SDK directly; it guides you to
20
+ produce **another skill folder** (docs + deterministic scripts) that does.
21
+
22
+ ## When to use this skill
23
+
24
+ - User says: “Create a new skill for Clix that helps with X”
25
+ - Internal request: “We need a new skill for feature X in Clix”
26
+ - User provides a workflow that is not well-covered by existing skills
27
+ - User types: `clix-skill-creator`
28
+
29
+ ## Non-goals (important)
30
+
31
+ - Do **not** create a new skill if the request can be satisfied by combining
32
+ existing skills (integration + event tracking + personalization + user
33
+ management + API-triggered campaigns).
34
+ - Do **not** invent SDK methods, endpoints, or constraints. If you can’t confirm
35
+ via MCP, treat it as unknown and ask the user or add a TODO note.
36
+ - Do **not** embed secrets, project IDs, API keys, or customer data in the skill.
37
+
38
+ ## MCP-first (mandatory source of truth)
39
+
40
+ Before writing any new “Clix API behavior” or “SDK signature” into a newly
41
+ generated skill:
42
+
43
+ - **MUST** use `clix-mcp-server:search_docs` to confirm conceptual behavior,
44
+ limits, and console semantics.
45
+ - **MUST** use `clix-mcp-server:search_sdk` to confirm exact method signatures
46
+ for each platform (iOS/Android/Flutter/React Native) that the new skill will
47
+ mention.
48
+
49
+ If `clix-mcp-server` tools are not available:
50
+
51
+ - Ask the user whether to install the MCP server (prefer using the existing
52
+ installer in `skills/integration/scripts/install-mcp.sh`).
53
+ - If the user declines, proceed with an explicit “static fallback may be
54
+ outdated” warning and minimize hard claims.
55
+
56
+ ## Workflow (copy + check off)
57
+
58
+ ```
59
+ Clix skill creation progress:
60
+ - [ ] 1) Intake: user need → crisp problem statement + acceptance criteria
61
+ - [ ] 2) Scope check: confirm this isn’t already covered by existing skills
62
+ - [ ] 3) MCP research: gather evidence (docs + SDK signatures) for the target scope
63
+ - [ ] 4) Draft a Skill Brief (name, trigger phrases, inputs/outputs, guardrails)
64
+ - [ ] 5) Generate scaffold (SKILL.md + references/ + scripts/ + examples/)
65
+ - [ ] 6) Validate scaffold (structure + frontmatter + MCP-first section)
66
+ - [ ] 7) Wire-in (README + llms index + tests if needed)
67
+ ```
68
+
69
+ ## 1) Intake: minimum questions
70
+
71
+ Ask only what’s needed to define a stable skill boundary:
72
+
73
+ - **Goal**: what outcome should the skill reliably produce?
74
+ - **Audience**: app devs, backend devs, marketers/ops, or mixed?
75
+ - **Platform** (if SDK-related): iOS / Android / Flutter / React Native
76
+ - **Clix capability**: push / in-app / email / audiences / journeys / etc.
77
+ - **Constraints**: PII policy, compliance, performance limits, rate limits
78
+ - **Success criteria**: what does “done” look like?
79
+
80
+ ## 2) Reference official skills (match repo style)
81
+
82
+ Before creating a new skill, use the existing **official Clix skills** in this
83
+ repo as your style guide so the generated skill matches the standards here
84
+ (format, tone, workflow, validators), while still being tailored to the user’s
85
+ need.
86
+
87
+ - Study how they are written:
88
+ - YAML frontmatter conventions
89
+ - MCP-first “source of truth” behavior
90
+ - Progressive disclosure (`references/`, `scripts/`, `examples/`)
91
+ - Plan artifacts + deterministic validators (bash scripts)
92
+ - Then generate the new skill based on the user’s need using the same patterns.
93
+ If the need is clearly a tiny addition to an existing skill, prefer adding a
94
+ `references/` doc or `examples/` file there instead of creating a new skill.
95
+
96
+ - `clix-integration`
97
+ - `clix-event-tracking`
98
+ - `clix-user-management`
99
+ - `clix-personalization`
100
+ - `clix-api-triggered-campaigns`
101
+
102
+ ## 3) MCP research: build an “Evidence Pack”
103
+
104
+ Create a short evidence pack that you will cite while writing the new skill:
105
+
106
+ - **Docs evidence** (from `clix-mcp-server:search_docs`)
107
+ - behavior guarantees
108
+ - constraints/limits
109
+ - console terminology
110
+ - **SDK evidence** (from `clix-mcp-server:search_sdk`)
111
+ - exact signatures per platform
112
+ - initialization / required params
113
+ - error behavior (throws? returns promise?)
114
+
115
+ Store the evidence in your notes (or as a `references/` markdown file in the new
116
+ skill), with the search queries you used so future maintainers can refresh it.
117
+
118
+ ## 4) Draft a Skill Brief (output format)
119
+
120
+ Produce this brief for approval _before_ generating files:
121
+
122
+ ```yaml
123
+ skill:
124
+ folder_name: "<kebab-case>" # e.g. "push-troubleshooting"
125
+ name: "clix-<kebab-case>" # e.g. "clix-push-troubleshooting"
126
+ display_name: "<Title Case>"
127
+ short_description: "<short>"
128
+ description: "<2-3 lines>"
129
+ user_invocable: true
130
+
131
+ triggers:
132
+ - "phrases the user might say"
133
+
134
+ inputs:
135
+ - "minimal inputs the skill will ask for"
136
+
137
+ outputs:
138
+ - "artifacts the skill produces (plan JSON, code changes, checklists)"
139
+
140
+ guardrails:
141
+ - "MCP-first requirements"
142
+ - "security / PII constraints"
143
+
144
+ files_to_generate:
145
+ skill_md: true
146
+ references:
147
+ - "<doc>.md"
148
+ scripts:
149
+ - "<script>.sh"
150
+ examples:
151
+ - "<optional>"
152
+ ```
153
+
154
+ ## 5) Generate scaffold (repo conventions)
155
+
156
+ In this repository, a “complete” skill folder should include:
157
+
158
+ - `SKILL.md` (with YAML frontmatter; MCP-first; workflow; progressive disclosure)
159
+ - `LICENSE.txt`
160
+ - `references/` (markdown docs; not empty)
161
+ - `scripts/` (deterministic bash scripts; not empty)
162
+ - `examples/` (optional, but recommended when copy/paste code is useful)
163
+
164
+ ## 6) Validate scaffold (fast feedback loop)
165
+
166
+ After generating a new skill folder, validate it:
167
+
168
+ ```bash
169
+ bash <skill-dir>/scripts/validate-same-scope.sh path/to/installed/skill-creator path/to/new-skill-folder
170
+ bash <skill-dir>/scripts/validate-skill-location.sh path/to/new-skill-folder --mode repo
171
+ bash <skill-dir>/scripts/validate-skill-scaffold.sh path/to/new-skill-folder
172
+ ```
173
+
174
+ This should check:
175
+
176
+ - the new skill is installed at the **same scope** as `skill-creator` (project-level
177
+ vs user-level), i.e. the new skill folder lives next to the installed
178
+ `skill-creator` under the same `.../skills/` directory
179
+ - the skill folder is in the correct `skills/<name>/` location (for this repo)
180
+ - required files exist
181
+ - `references/` and `scripts/` are present and non-empty
182
+ - `SKILL.md` has valid frontmatter keys
183
+ - the skill includes an MCP-first section referencing `clix-mcp-server`
184
+
185
+ ## Progressive Disclosure
186
+
187
+ - **Level 1**: This `SKILL.md` (always loaded)
188
+ - **Level 2**: `references/` (load when authoring the new skill)
189
+ - **Level 3**: `examples/` (load when copy/pasting scaffolds)
190
+ - **Level 4**: `scripts/` (execute directly; do not load into context)
191
+
192
+ ## References
193
+
194
+ - `references/skill-template.md`
195
+ - `references/mcp-research-playbook.md`
@@ -0,0 +1,41 @@
1
+ skill:
2
+ folder_name: 'push-troubleshooting'
3
+ name: 'clix-push-troubleshooting'
4
+ display_name: 'Push Troubleshooting'
5
+ short_description: 'Debug push delivery and rendering issues'
6
+ description: >
7
+ Helps developers diagnose push notification delivery, permissions, token
8
+ registration, and template rendering issues. Uses Clix MCP Server as the
9
+ source of truth for SDK signatures and docs behavior.
10
+ user_invocable: true
11
+
12
+ triggers:
13
+ - 'push notifications not arriving'
14
+ - 'APNs token not registered'
15
+ - 'FCM token changed'
16
+ - 'message logs show template error'
17
+
18
+ inputs:
19
+ - 'platform (iOS/Android/Flutter/React Native)'
20
+ - 'app state (fresh install vs update)'
21
+ - 'what you see in Clix Message Logs (if available)'
22
+
23
+ outputs:
24
+ - 'a step-by-step debug plan'
25
+ - 'a minimal repro checklist'
26
+ - 'code changes (if needed) to fix initialization/token registration'
27
+
28
+ guardrails:
29
+ - 'MCP-first: do not claim SDK signatures without clix-mcp-server:search_sdk'
30
+ - 'no secrets; redact tokens and IDs'
31
+ - 'avoid duplicated scope with clix-integration unless troubleshooting-specific'
32
+
33
+ files_to_generate:
34
+ skill_md: true
35
+ references:
36
+ - 'debugging-checklist.md'
37
+ - 'common-failure-modes.md'
38
+ scripts:
39
+ - 'validate-debug-plan.sh'
40
+ examples:
41
+ - 'sample-log-snippets.md'
@@ -0,0 +1,75 @@
1
+ # MCP Research Playbook (Clix)
2
+
3
+ This playbook helps you **research accurately** before authoring a new Clix
4
+ skill. The goal is to collect enough evidence so the skill can be maintained
5
+ without guessing.
6
+
7
+ ## Golden rules
8
+
9
+ - **SDK signatures must come from** `clix-mcp-server:search_sdk` (not memory).
10
+ - **Behavior/limits must come from** `clix-mcp-server:search_docs`.
11
+ - When evidence is unclear, write that uncertainty into the skill and ask the
12
+ user for confirmation instead of asserting.
13
+
14
+ ## Recommended research sequence
15
+
16
+ ### 1) Identify the “feature nouns”
17
+
18
+ Extract the keywords from the user need:
19
+
20
+ - Channel: push / in-app / email / SMS / etc.
21
+ - Trigger type: event-triggered / API-triggered / scheduled
22
+ - Domain: journeys, segments, templates, attribution, deep links, etc.
23
+ - Platform: iOS / Android / Flutter / React Native (if SDK involved)
24
+
25
+ ### 2) Search docs first (conceptual contracts)
26
+
27
+ Use `clix-mcp-server:search_docs` queries like:
28
+
29
+ - `"<feature> limits"`
30
+ - `"<feature> troubleshooting"`
31
+ - `"<feature> required fields"`
32
+ - `"<endpoint or concept> authentication headers"`
33
+ - `"Message Logs template rendering errors"`
34
+
35
+ Record:
36
+
37
+ - constraints/limits (e.g. maximum attributes, payload limits)
38
+ - required fields
39
+ - “this is how the console behaves” statements
40
+
41
+ ### 3) Search SDK next (exact signatures)
42
+
43
+ Use `clix-mcp-server:search_sdk` queries like:
44
+
45
+ - `"initialize"`
46
+ - `"setUserId"`
47
+ - `"setUserProperty"`
48
+ - `"trackEvent"`
49
+ - `"push token"`
50
+ - `"<feature name>"` + platform filters
51
+
52
+ For each platform you care about, capture:
53
+
54
+ - method name + parameters (types if available)
55
+ - return type (sync vs async)
56
+ - error behavior (throws? returns error object?)
57
+
58
+ ### 4) Convert evidence into a skill contract
59
+
60
+ In the new skill’s `SKILL.md`:
61
+
62
+ - include an MCP-first section
63
+ - include concrete “workflow” steps
64
+ - avoid large static API tables unless you can keep them synced (prefer “use MCP
65
+ to fetch the exact signature” instead)
66
+
67
+ ## Suggested “Evidence Pack” format
68
+
69
+ In the new skill’s `references/`, create an `evidence.md` (or similar) containing:
70
+
71
+ - the **queries** you ran
72
+ - the **high-signal excerpts** (short)
73
+ - a short “what we conclude” paragraph per excerpt
74
+
75
+ This makes maintenance and debugging dramatically easier.
@@ -0,0 +1,74 @@
1
+ # Skill Template (for new Clix skills)
2
+
3
+ This document is a **copy/paste scaffold** for creating a new skill in the style
4
+ of this repository.
5
+
6
+ ## Folder structure
7
+
8
+ Create:
9
+
10
+ - `skills/<folder-name>/SKILL.md`
11
+ - `skills/<folder-name>/LICENSE.txt`
12
+ - `skills/<folder-name>/references/<docs>.md` (at least 1 file)
13
+ - `skills/<folder-name>/scripts/<script>.sh` (at least 1 file)
14
+ - `skills/<folder-name>/examples/` (optional but recommended)
15
+
16
+ ## `SKILL.md` skeleton
17
+
18
+ ```markdown
19
+ ---
20
+ name: clix-<kebab-case>
21
+ display-name: <Title Case>
22
+ short-description: <short>
23
+ description: <2-3 lines. Include when to use. Mention MCP-first explicitly.>
24
+ user-invocable: true
25
+ ---
26
+
27
+ # <Title Case>
28
+
29
+ ## What this skill does
30
+
31
+ - ...
32
+
33
+ ## MCP-first (source of truth)
34
+
35
+ If Clix MCP tools are available, treat them as the **source of truth**:
36
+
37
+ - `clix-mcp-server:search_docs` for conceptual behavior + limits
38
+ - `clix-mcp-server:search_sdk` for platform signatures (when SDK calls are involved)
39
+
40
+ If MCP tools are not available:
41
+
42
+ - Ask to install MCP (preferred), otherwise use references/ and clearly warn that
43
+ static docs may be outdated.
44
+
45
+ ## Workflow (copy + check off)
46
+ ```
47
+
48
+ <Skill> progress:
49
+
50
+ - [ ] 1. Confirm minimum inputs
51
+ - [ ] 2. Draft a plan artifact (JSON / checklist / table)
52
+ - [ ] 3. Validate plan (script)
53
+ - [ ] 4. Implement (code/config)
54
+ - [ ] 5. Verify (Clix console + runtime)
55
+
56
+ ```
57
+
58
+ ## Progressive Disclosure
59
+
60
+ - **Level 1**: This `SKILL.md`
61
+ - **Level 2**: `references/`
62
+ - **Level 3**: `examples/`
63
+ - **Level 4**: `scripts/` (execute; do not load)
64
+ ```
65
+
66
+ ## Quality checklist (before publishing)
67
+
68
+ - **No hallucinations**: every SDK signature in the skill can be re-derived from
69
+ `clix-mcp-server:search_sdk` queries documented in references.
70
+ - **No secrets**: no project IDs / API keys / customer data in examples.
71
+ - **Scope crisp**: the skill does one job well; if it’s a grab bag, split it.
72
+ - **Backstops**: include a deterministic script for validating the “plan artifact”
73
+ (JSON schema or structure checks).
74
+ - **Good UX**: minimal intake questions; concrete outputs the user can approve.
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # Validate that a newly generated skill is installed at the same scope as this skill:
4
+ # it must live under the same parent "skills" directory as the installed `skill-creator`.
5
+ #
6
+ # Rationale:
7
+ # - If `skill-creator` is installed at project level (e.g. .cursor/skills/skill-creator),
8
+ # the generated skill should also be project level (e.g. .cursor/skills/<new-skill>).
9
+ # - If `skill-creator` is installed at user/global level (e.g. ~/.cursor/skills/skill-creator),
10
+ # the generated skill should also be user/global (e.g. ~/.cursor/skills/<new-skill>).
11
+ #
12
+ # Usage:
13
+ # bash skills/skill-creator/scripts/validate-same-scope.sh <skill-creator-dir> <new-skill-dir>
14
+ #
15
+ set -euo pipefail
16
+
17
+ creator_dir="${1:-}"
18
+ new_skill_dir="${2:-}"
19
+
20
+ if [[ -z "$creator_dir" || -z "$new_skill_dir" ]]; then
21
+ echo "Usage: bash skills/skill-creator/scripts/validate-same-scope.sh <skill-creator-dir> <new-skill-dir>" >&2
22
+ exit 2
23
+ fi
24
+
25
+ if [[ ! -d "$creator_dir" ]]; then
26
+ echo "Error: skill-creator directory not found: $creator_dir" >&2
27
+ exit 2
28
+ fi
29
+
30
+ if [[ ! -d "$new_skill_dir" ]]; then
31
+ echo "Error: new skill directory not found: $new_skill_dir" >&2
32
+ exit 2
33
+ fi
34
+
35
+ creator_parent="$(dirname "$creator_dir")"
36
+ new_parent="$(dirname "$new_skill_dir")"
37
+
38
+ creator_parent_base="$(basename "$creator_parent")"
39
+ new_parent_base="$(basename "$new_parent")"
40
+
41
+ if [[ "$creator_parent_base" != "skills" && "$creator_parent_base" != "skill" && "$creator_parent_base" != ".skills" ]]; then
42
+ echo "ERROR: skill-creator must live under a skills directory (skills/ or skill/ or .skills/)." >&2
43
+ echo " creator_dir: $creator_dir" >&2
44
+ exit 1
45
+ fi
46
+
47
+ if [[ "$new_parent_base" != "skills" && "$new_parent_base" != "skill" && "$new_parent_base" != ".skills" ]]; then
48
+ echo "ERROR: new skill must live under a skills directory (skills/ or skill/ or .skills/)." >&2
49
+ echo " new_skill_dir: $new_skill_dir" >&2
50
+ exit 1
51
+ fi
52
+
53
+ if [[ "$creator_parent" != "$new_parent" ]]; then
54
+ echo "ERROR: scope mismatch. Expected new skill to be installed next to skill-creator under the same skills directory." >&2
55
+ echo " skill_creator_parent: $creator_parent" >&2
56
+ echo " new_skill_parent: $new_parent" >&2
57
+ exit 1
58
+ fi
59
+
60
+ echo "OK: skill scope matches (same parent skills directory)"
61
+
@@ -0,0 +1,204 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # Validate that a generated skill folder is placed in the correct "skills" directory.
4
+ #
5
+ # Usage:
6
+ # bash skills/skill-creator/scripts/validate-skill-location.sh <skill-folder> [--mode repo|client] [--client <name>]
7
+ #
8
+ # Modes:
9
+ # - repo : expects the skill folder to live under: skills/<skill-folder-name>/
10
+ # - client: expects the skill folder to live under a client skills directory:
11
+ # (.*)/skills/<skill-folder-name>/ OR (.*)/skill/<skill-folder-name>/ (OpenCode)
12
+ #
13
+ # If --client is provided in client mode, this script will also check that the path
14
+ # contains the expected client directory segment (best-effort).
15
+ #
16
+ set -euo pipefail
17
+
18
+ skill_dir="${1:-}"
19
+ mode="repo"
20
+ client=""
21
+
22
+ shift || true
23
+ while [[ "${1:-}" != "" ]]; do
24
+ case "$1" in
25
+ --mode)
26
+ if [[ -z "${2:-}" || "${2:-}" == "-"* ]]; then
27
+ echo "Error: --mode requires a value" >&2
28
+ exit 2
29
+ fi
30
+ mode="${2:-}"
31
+ shift 2
32
+ ;;
33
+ --client)
34
+ if [[ -z "${2:-}" || "${2:-}" == "-"* ]]; then
35
+ echo "Error: --client requires a value" >&2
36
+ exit 2
37
+ fi
38
+ client="${2:-}"
39
+ shift 2
40
+ ;;
41
+ -h|--help)
42
+ cat <<'EOF'
43
+ Validate skill folder location.
44
+
45
+ Usage:
46
+ bash skills/skill-creator/scripts/validate-skill-location.sh <skill-folder> [--mode repo|client] [--client <name>]
47
+
48
+ Examples:
49
+ bash skills/skill-creator/scripts/validate-skill-location.sh skills/personalization --mode repo
50
+ bash skills/skill-creator/scripts/validate-skill-location.sh .cursor/skills/personalization --mode client --client cursor
51
+ EOF
52
+ exit 0
53
+ ;;
54
+ *)
55
+ echo "Unknown arg: $1" >&2
56
+ exit 2
57
+ ;;
58
+ esac
59
+ done
60
+
61
+ if [[ -z "$skill_dir" ]]; then
62
+ echo "Error: missing <skill-folder> argument" >&2
63
+ exit 2
64
+ fi
65
+
66
+ if [[ ! -d "$skill_dir" ]]; then
67
+ echo "Error: directory not found: $skill_dir" >&2
68
+ exit 2
69
+ fi
70
+
71
+ skills_parent="$(basename "$(dirname "$skill_dir")")"
72
+
73
+ case "$mode" in
74
+ repo)
75
+ if [[ "$skills_parent" != "skills" ]]; then
76
+ echo "ERROR: Invalid location: expected skill folder under 'skills/<name>/' but got parent '$skills_parent'." >&2
77
+ echo " Path: $skill_dir" >&2
78
+ exit 1
79
+ fi
80
+ ;;
81
+ client)
82
+ # Client installs usually use "skills/" (most clients), "skill/" (OpenCode),
83
+ # or ".skills/" (Letta).
84
+ if [[ "$skills_parent" != "skills" && "$skills_parent" != "skill" && "$skills_parent" != ".skills" ]]; then
85
+ echo "ERROR: Invalid location: expected skill folder under '<client>/(skills|skill|.skills)/<name>/' but got parent '$skills_parent'." >&2
86
+ echo " Path: $skill_dir" >&2
87
+ exit 1
88
+ fi
89
+
90
+ if [[ -n "$client" ]]; then
91
+ # Best-effort path segment checks (not exhaustive, but catches common mistakes).
92
+ case "${client,,}" in
93
+ cursor)
94
+ [[ "$skill_dir" == *"/.cursor/skills/"* || "$skill_dir" == ".cursor/skills/"* ]] || {
95
+ echo "ERROR: Expected Cursor skill path to include '.cursor/skills/'" >&2
96
+ echo " Path: $skill_dir" >&2
97
+ exit 1
98
+ }
99
+ ;;
100
+ claude|claude-code)
101
+ [[ "$skill_dir" == *"/.claude/skills/"* || "$skill_dir" == ".claude/skills/"* ]] || {
102
+ echo "ERROR: Expected Claude skill path to include '.claude/skills/'" >&2
103
+ echo " Path: $skill_dir" >&2
104
+ exit 1
105
+ }
106
+ ;;
107
+ codex)
108
+ [[ "$skill_dir" == *"/.codex/skills/"* || "$skill_dir" == ".codex/skills/"* ]] || {
109
+ echo "ERROR: Expected Codex skill path to include '.codex/skills/'" >&2
110
+ echo " Path: $skill_dir" >&2
111
+ exit 1
112
+ }
113
+ ;;
114
+ opencode)
115
+ [[ "$skill_dir" == *"/.opencode/skill/"* || "$skill_dir" == ".opencode/skill/"* ]] || {
116
+ echo "ERROR: Expected OpenCode skill path to include '.opencode/skill/'" >&2
117
+ echo " Path: $skill_dir" >&2
118
+ exit 1
119
+ }
120
+ # OpenCode uses singular "skill", reject "skills" for this client.
121
+ [[ "$skill_dir" != *"/.opencode/skills/"* && "$skill_dir" != ".opencode/skills/"* ]] || {
122
+ echo "ERROR: Expected OpenCode skill path to include '.opencode/skill/' (singular), not '.opencode/skills/'" >&2
123
+ echo " Path: $skill_dir" >&2
124
+ exit 1
125
+ }
126
+ ;;
127
+ vscode)
128
+ [[ "$skill_dir" == *"/.vscode/skills/"* || "$skill_dir" == ".vscode/skills/"* ]] || {
129
+ echo "ERROR: Expected VS Code skill path to include '.vscode/skills/'" >&2
130
+ echo " Path: $skill_dir" >&2
131
+ exit 1
132
+ }
133
+ ;;
134
+ amp)
135
+ # Amp uses `.agents/skills/` in a workspace and `~/.config/agents/skills/` globally.
136
+ [[ "$skill_dir" == *"/.agents/skills/"* || "$skill_dir" == ".agents/skills/"* ]] || {
137
+ echo "ERROR: Expected Amp skill path to include '.agents/skills/'" >&2
138
+ echo " Path: $skill_dir" >&2
139
+ exit 1
140
+ }
141
+ ;;
142
+ goose)
143
+ # Goose supports both goose-specific and portable skill locations.
144
+ [[
145
+ "$skill_dir" == *"/.goose/skills/"* ||
146
+ "$skill_dir" == ".goose/skills/"* ||
147
+ "$skill_dir" == *"/.agents/skills/"* ||
148
+ "$skill_dir" == ".agents/skills/"*
149
+ ]] || {
150
+ echo "ERROR: Expected Goose skill path to include '.goose/skills/' or '.agents/skills/'" >&2
151
+ echo " Path: $skill_dir" >&2
152
+ exit 1
153
+ }
154
+ ;;
155
+ github|copilot)
156
+ [[ "$skill_dir" == *"/.github/skills/"* || "$skill_dir" == ".github/skills/"* ]] || {
157
+ echo "ERROR: Expected GitHub Copilot skill path to include '.github/skills/'" >&2
158
+ echo " Path: $skill_dir" >&2
159
+ exit 1
160
+ }
161
+ ;;
162
+ gemini)
163
+ [[ "$skill_dir" == *"/.gemini/skills/"* || "$skill_dir" == ".gemini/skills/"* ]] || {
164
+ echo "ERROR: Expected Gemini skill path to include '.gemini/skills/'" >&2
165
+ echo " Path: $skill_dir" >&2
166
+ exit 1
167
+ }
168
+ ;;
169
+ kiro)
170
+ [[ "$skill_dir" == *"/.kiro/skills/"* || "$skill_dir" == ".kiro/skills/"* ]] || {
171
+ echo "ERROR: Expected Kiro skill path to include '.kiro/skills/'" >&2
172
+ echo " Path: $skill_dir" >&2
173
+ exit 1
174
+ }
175
+ ;;
176
+ amazonq)
177
+ [[ "$skill_dir" == *"/.amazonq/skills/"* || "$skill_dir" == ".amazonq/skills/"* ]] || {
178
+ echo "ERROR: Expected AmazonQ skill path to include '.amazonq/skills/'" >&2
179
+ echo " Path: $skill_dir" >&2
180
+ exit 1
181
+ }
182
+ ;;
183
+ letta)
184
+ # Letta uses a root-level `.skills/` directory.
185
+ [[ "$skill_dir" == *"/.skills/"* || "$skill_dir" == ".skills/"* ]] || {
186
+ echo "ERROR: Expected Letta skill path to include '.skills/'" >&2
187
+ echo " Path: $skill_dir" >&2
188
+ exit 1
189
+ }
190
+ ;;
191
+ *)
192
+ # Unknown client; skip strict segment check.
193
+ ;;
194
+ esac
195
+ fi
196
+ ;;
197
+ *)
198
+ echo "Error: --mode must be 'repo' or 'client' (got '$mode')" >&2
199
+ exit 2
200
+ ;;
201
+ esac
202
+
203
+ echo "OK: skill location looks OK ($mode)"
204
+
@@ -0,0 +1,207 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # Validate a Clix Agent Skill scaffold (folder structure + frontmatter).
4
+ #
5
+ # Usage:
6
+ # bash skills/skill-creator/scripts/validate-skill-scaffold.sh path/to/skill-folder
7
+ #
8
+ # Validates:
9
+ # - SKILL.md and LICENSE.txt exist
10
+ # - references/ and scripts/ exist and are non-empty
11
+ # - SKILL.md has YAML frontmatter with required keys
12
+ # - SKILL.md contains an MCP-first section that references `clix-mcp-server`
13
+ #
14
+ set -euo pipefail
15
+
16
+ skill_dir="${1:-}"
17
+ if [[ -z "$skill_dir" ]]; then
18
+ echo "Usage: bash skills/skill-creator/scripts/validate-skill-scaffold.sh path/to/skill-folder" >&2
19
+ exit 2
20
+ fi
21
+
22
+ if [[ ! -d "$skill_dir" ]]; then
23
+ echo "Error: directory not found: $skill_dir" >&2
24
+ exit 2
25
+ fi
26
+
27
+ validate_with_python() {
28
+ python3 - "$skill_dir" <<'PY'
29
+ import os
30
+ import re
31
+ import sys
32
+
33
+ skill_dir = sys.argv[1]
34
+
35
+ errors = []
36
+
37
+ def require_file(name: str):
38
+ p = os.path.join(skill_dir, name)
39
+ if not os.path.isfile(p):
40
+ errors.append(f"missing required file: {name}")
41
+ return p
42
+
43
+ def require_non_empty_dir(name: str):
44
+ p = os.path.join(skill_dir, name)
45
+ if not os.path.isdir(p):
46
+ errors.append(f"missing required directory: {name}/")
47
+ return
48
+ entries = [e for e in os.listdir(p) if not e.startswith(".")]
49
+ if len(entries) == 0:
50
+ errors.append(f"required directory is empty: {name}/")
51
+
52
+ skill_md_path = require_file("SKILL.md")
53
+ require_file("LICENSE.txt")
54
+ require_non_empty_dir("references")
55
+ require_non_empty_dir("scripts")
56
+
57
+ frontmatter = None
58
+ try:
59
+ with open(skill_md_path, "r", encoding="utf-8") as f:
60
+ content = f.read()
61
+ except Exception as e:
62
+ errors.append(f"failed to read SKILL.md: {e}")
63
+ content = ""
64
+
65
+ m = re.match(r"^---\n([\s\S]*?)\n---\n", content)
66
+ if not m:
67
+ errors.append("SKILL.md must start with YAML frontmatter delimited by ---")
68
+ else:
69
+ frontmatter = m.group(1)
70
+ # IMPORTANT: avoid substring false-positives:
71
+ # - "display-name:" contains "name:"
72
+ # - "short-description:" contains "description:"
73
+ # So we must match keys at beginning-of-line only.
74
+ def has_key(key: str) -> bool:
75
+ return re.search(rf"^{re.escape(key)}\s*", frontmatter, re.M) is not None
76
+
77
+ required_keys = [
78
+ "name:",
79
+ "display-name:",
80
+ "short-description:",
81
+ "description:",
82
+ "user-invocable:",
83
+ ]
84
+ for k in required_keys:
85
+ if not has_key(k):
86
+ errors.append(f"frontmatter missing key: {k.rstrip(':')}")
87
+
88
+ name_match = re.search(r"^name:\s*(.+)$", frontmatter, re.M)
89
+ if name_match:
90
+ name = name_match.group(1).strip()
91
+ if not name.startswith("clix-"):
92
+ errors.append("frontmatter name should start with 'clix-'")
93
+
94
+ inv_match = re.search(r"^user-invocable:\s*(.+)$", frontmatter, re.M)
95
+ if inv_match:
96
+ val = inv_match.group(1).strip().lower()
97
+ if val not in ("true", "false"):
98
+ errors.append("frontmatter user-invocable must be true or false")
99
+
100
+ if "clix-mcp-server" not in content:
101
+ errors.append("SKILL.md must reference 'clix-mcp-server' (MCP-first requirement)")
102
+
103
+ if errors:
104
+ print("ERROR: skill scaffold validation failed:")
105
+ for e in errors:
106
+ print(f"- {e}")
107
+ sys.exit(1)
108
+
109
+ print("OK: skill scaffold validation passed")
110
+ PY
111
+ }
112
+
113
+ if command -v python3 >/dev/null 2>&1; then
114
+ validate_with_python
115
+ exit 0
116
+ fi
117
+
118
+ echo "Warning: python3 not found; falling back to basic checks with node if available." >&2
119
+ if command -v node >/dev/null 2>&1; then
120
+ node - "$skill_dir" <<'NODE'
121
+ const fs = require("fs");
122
+ const path = require("path");
123
+
124
+ const skillDir = process.argv[1];
125
+ const errors = [];
126
+
127
+ function hasFrontmatterKey(frontmatter, key) {
128
+ // Match key at beginning of line only (avoid substring collisions):
129
+ // - "display-name:" contains "name:"
130
+ // - "short-description:" contains "description:"
131
+ const re = new RegExp(`^${key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\s*`, "m");
132
+ return re.test(frontmatter);
133
+ }
134
+
135
+ function requireFile(name) {
136
+ const p = path.join(skillDir, name);
137
+ if (!fs.existsSync(p) || !fs.statSync(p).isFile()) errors.push(`missing required file: ${name}`);
138
+ return p;
139
+ }
140
+
141
+ function requireNonEmptyDir(name) {
142
+ const p = path.join(skillDir, name);
143
+ if (!fs.existsSync(p) || !fs.statSync(p).isDirectory()) {
144
+ errors.push(`missing required directory: ${name}/`);
145
+ return;
146
+ }
147
+ const entries = fs.readdirSync(p).filter((e) => !e.startsWith("."));
148
+ if (entries.length === 0) errors.push(`required directory is empty: ${name}/`);
149
+ }
150
+
151
+ const skillMd = requireFile("SKILL.md");
152
+ requireFile("LICENSE.txt");
153
+ requireNonEmptyDir("references");
154
+ requireNonEmptyDir("scripts");
155
+
156
+ let content = "";
157
+ try {
158
+ content = fs.readFileSync(skillMd, "utf8");
159
+ } catch (e) {
160
+ errors.push(`failed to read SKILL.md: ${String(e)}`);
161
+ }
162
+
163
+ // Frontmatter validation (best-effort; mirrors Python validator behavior).
164
+ if (!content.startsWith("---\n")) {
165
+ errors.push("SKILL.md must start with YAML frontmatter (---)");
166
+ } else {
167
+ const m = content.match(/^---\n([\s\S]*?)\n---\n/);
168
+ if (!m) {
169
+ errors.push("SKILL.md must start with YAML frontmatter delimited by ---");
170
+ } else {
171
+ const frontmatter = m[1];
172
+ const required = ["name:", "display-name:", "short-description:", "description:", "user-invocable:"];
173
+ for (const k of required) {
174
+ if (!hasFrontmatterKey(frontmatter, k)) {
175
+ errors.push(`frontmatter missing key: ${k.replace(/:$/, "")}`);
176
+ }
177
+ }
178
+
179
+ const nameMatch = frontmatter.match(/^name:\s*(.+)$/m);
180
+ if (nameMatch) {
181
+ const name = (nameMatch[1] || "").trim();
182
+ if (!name.startsWith("clix-")) errors.push("frontmatter name should start with 'clix-'");
183
+ }
184
+
185
+ const invMatch = frontmatter.match(/^user-invocable:\s*(.+)$/m);
186
+ if (invMatch) {
187
+ const val = (invMatch[1] || "").trim().toLowerCase();
188
+ if (!["true", "false"].includes(val)) errors.push("frontmatter user-invocable must be true or false");
189
+ }
190
+ }
191
+ }
192
+ if (!content.includes("clix-mcp-server")) errors.push("SKILL.md must reference 'clix-mcp-server'");
193
+
194
+ if (errors.length) {
195
+ console.error("ERROR: skill scaffold validation failed:");
196
+ for (const e of errors) console.error(`- ${e}`);
197
+ process.exit(1);
198
+ }
199
+
200
+ console.log("OK: skill scaffold validation passed");
201
+ NODE
202
+ exit 0
203
+ fi
204
+
205
+ echo "Error: neither python3 nor node found; cannot validate." >&2
206
+ exit 2
207
+
@@ -2,8 +2,7 @@
2
2
  name: clix-user-management
3
3
  display-name: User Management
4
4
  short-description: User management setup
5
- description:
6
- Implements Clix user identification and user properties (setUserId,
5
+ description: Implements Clix user identification and user properties (setUserId,
7
6
  removeUserId, setUserProperty/setUserProperties,
8
7
  removeUserProperty/removeUserProperties) with safe schemas, logout best
9
8
  practices, and campaign-ready personalization/audience usage. Use when the