@trendai-crem/claude-skills 1.4.0 → 1.5.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.
package/README.md CHANGED
@@ -8,13 +8,14 @@ One-command Claude Code skill installer for the team. Installs curated AI agent
8
8
  npx @trendai-crem/claude-skills
9
9
  ```
10
10
 
11
- That's it. The command installs all three source types declared in `sources.json`:
11
+ That's it. The command installs all four source types declared in `sources.json`:
12
12
 
13
13
  | Source type | What it installs | How to change |
14
14
  |-------------|-----------------|---------------|
15
+ | **rules-dir** | Team-shared rules to `~/.claude/rules/team/` (loaded in every session) | Add/remove `rules/<name>.md`, bump version, PR |
15
16
  | **skills-repo** | [superpowers](https://github.com/obra/superpowers) — brainstorming, debugging, TDD, and more | Edit `sources.json`, bump version, PR |
16
17
  | **skills-dir** | Team skills in this repo's `skills/` directory | Add/remove `skills/<name>/`, bump version, PR |
17
- | **marketplace** | Plugins from `ai-skill-marketplace`, `claude-plugins-official`, and `openai-codex` | Edit `plugins` list in `sources.json`, bump version, PR |
18
+ | **marketplace** | Plugins from `ai-skill-marketplace`, `claude-plugins-official`, `openai-codex`, and `everything-claude-code` | Edit `plugins` list in `sources.json`, bump version, PR |
18
19
 
19
20
  Re-run to update everything:
20
21
 
@@ -24,6 +25,14 @@ npx @trendai-crem/claude-skills@latest
24
25
 
25
26
  Auto-update runs at session start — you'll be notified when a new version is available and it installs automatically.
26
27
 
28
+ ## Team Rules (`rules/`)
29
+
30
+ Rules are `.md` files installed to `~/.claude/rules/team/` and automatically loaded in every Claude session across all projects. Use rules for team-wide conventions that should always apply.
31
+
32
+ | Rule | Description |
33
+ |------|-------------|
34
+ | **confluence-editing** | Use `atlassian-tools` skill for Confluence edits — never use raw MCP update tools |
35
+
27
36
  ## Team Skills (`skills/`)
28
37
 
29
38
  | Skill | Trigger | Description |
@@ -49,6 +58,16 @@ Installed from [ai-skill-marketplace](https://github.com/trend-ai-taskforce/ai-s
49
58
 
50
59
  ## For Maintainers
51
60
 
61
+ ### Adding a team rule
62
+
63
+ 1. Create a branch: `git checkout -b feat/add-<rule-name>`
64
+ 2. Add `rules/<rule-name>.md` (plain markdown, no frontmatter needed)
65
+ 3. Keep rules short (<50 lines) — they consume context window in every session
66
+ 4. Bump version: `npm version patch`
67
+ 5. Commit, push, open a PR, merge — CI publishes automatically
68
+
69
+ Rules are always overwritten on install (not no-clobber) to stay in sync with the repo.
70
+
52
71
  ### Adding a team skill
53
72
 
54
73
  1. Create a branch: `git checkout -b feat/add-<skill-name>`
@@ -178,9 +197,13 @@ sources.json
178
197
 
179
198
  cli.js (thin orchestrator)
180
199
 
181
- lib/handlers/{skills-dir, skills-repo, marketplace}.js
200
+ lib/handlers/{rules-dir, skills-dir, skills-repo, marketplace}.js
182
201
 
183
202
  ~/.claude/claude-skills-manifest.json (tracks what's installed)
203
+
204
+ ~/.claude/rules/team/ ← rules-dir handler
205
+ ~/.claude/skills/ ← skills-dir, skills-repo handlers
206
+ ~/.claude/plugins/ ← marketplace handler
184
207
  ```
185
208
 
186
209
  Removals propagate automatically: remove an entry from `sources.json`, bump version, and the next auto-update uninstalls it for all team members.
package/cli.js CHANGED
@@ -92,9 +92,11 @@ function installEccRules() {
92
92
  const eccRulesDir = join(eccMarketplace, 'rules');
93
93
  if (!existsSync(eccRulesDir)) return;
94
94
 
95
+ const ALLOWED_LANGS = new Set(['common', 'typescript', 'java', 'golang', 'python', 'swift']);
96
+
95
97
  const destDir = join(homedir(), '.claude', 'rules');
96
98
  const languages = readdirSync(eccRulesDir, { withFileTypes: true })
97
- .filter(d => d.isDirectory())
99
+ .filter(d => d.isDirectory() && ALLOWED_LANGS.has(d.name))
98
100
  .map(d => d.name);
99
101
 
100
102
  let copied = 0;
@@ -1,9 +1,11 @@
1
1
  import { skillsDirHandler } from './skills-dir.js';
2
2
  import { skillsRepoHandler } from './skills-repo.js';
3
3
  import { marketplaceHandler } from './marketplace.js';
4
+ import { rulesDirHandler } from './rules-dir.js';
4
5
 
5
6
  // Use Object.create(null) to prevent prototype chain traversal on adversarial type values.
6
7
  export const HANDLERS = Object.create(null);
7
8
  HANDLERS['skills-dir'] = skillsDirHandler;
8
9
  HANDLERS['skills-repo'] = skillsRepoHandler;
9
10
  HANDLERS['marketplace'] = marketplaceHandler;
11
+ HANDLERS['rules-dir'] = rulesDirHandler;
@@ -0,0 +1,70 @@
1
+ import { readdirSync, copyFileSync, mkdirSync, existsSync, unlinkSync, rmdirSync } from 'fs';
2
+ import { join } from 'path';
3
+ import { homedir } from 'os';
4
+
5
+ const DEST_DIR = join(homedir(), '.claude', 'rules', 'team');
6
+
7
+ /**
8
+ * Handler for team-shared rules (type: "rules-dir").
9
+ * Copies .md files from <repo>/rules/ to ~/.claude/rules/team/.
10
+ */
11
+ export const rulesDirHandler = {
12
+ /**
13
+ * Returns the set of rule file names in the source directory.
14
+ * @param {object} entry - Source entry (uses convention: <baseDir>/rules/).
15
+ * @param {string} baseDir - Repository base directory.
16
+ * @returns {Set<string>|null}
17
+ */
18
+ getDesired(entry, baseDir) {
19
+ const srcDir = join(baseDir, entry.path ?? 'rules');
20
+ try {
21
+ const names = readdirSync(srcDir)
22
+ .filter(f => f.endsWith('.md'))
23
+ .sort();
24
+ return new Set(names);
25
+ } catch (err) {
26
+ console.warn(`\nWARN: Cannot read rules directory "${srcDir}": ${err.message}`);
27
+ return null;
28
+ }
29
+ },
30
+
31
+ /**
32
+ * Copies rule .md files to ~/.claude/rules/team/.
33
+ * Always overwrites to keep rules in sync with the repo.
34
+ * @returns {Array<{label, action, ok}>}
35
+ */
36
+ install(entry, baseDir) {
37
+ const srcDir = join(baseDir, entry.path ?? 'rules');
38
+ mkdirSync(DEST_DIR, { recursive: true });
39
+
40
+ try {
41
+ const files = readdirSync(srcDir).filter(f => f.endsWith('.md'));
42
+ for (const file of files) {
43
+ copyFileSync(join(srcDir, file), join(DEST_DIR, file));
44
+ }
45
+ console.log(`\n Rules installed to ${DEST_DIR}/ (${files.length} files)`);
46
+ return [{ label: entry.label, action: 'install-group', ok: true }];
47
+ } catch (err) {
48
+ console.error(`\nFailed: ${entry.label} (${err.message})`);
49
+ return [{ label: entry.label, action: 'install-group', ok: false }];
50
+ }
51
+ },
52
+
53
+ /**
54
+ * Removes stale rule files from ~/.claude/rules/team/.
55
+ * @param {string[]} staleItems - File names to remove.
56
+ * @returns {Array<{label, action, ok}>}
57
+ */
58
+ uninstall(staleItems) {
59
+ return staleItems.map(file => {
60
+ const dest = join(DEST_DIR, file);
61
+ try {
62
+ if (existsSync(dest)) unlinkSync(dest);
63
+ return { label: file, action: 'uninstall', ok: true };
64
+ } catch (err) {
65
+ console.error(`\nFailed to remove rule ${file}: ${err.message}`);
66
+ return { label: file, action: 'uninstall', ok: false };
67
+ }
68
+ });
69
+ },
70
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trendai-crem/claude-skills",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "description": "Claude Code skills installer for the trendai-crem team",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
@@ -15,7 +15,8 @@
15
15
  "sources.json",
16
16
  "marketplace.json",
17
17
  "lib/",
18
- "skills/"
18
+ "skills/",
19
+ "rules/"
19
20
  ],
20
21
  "type": "module",
21
22
  "engines": {
@@ -0,0 +1,20 @@
1
+ # Confluence Editing
2
+
3
+ When editing Confluence pages, ALWAYS use the `atlassian-tools` skill
4
+ (confluence_cli.py retrieve → edit local .md → update --file).
5
+
6
+ NEVER use `mcp__atlassian__updateConfluencePage` with markdown contentFormat — it loses
7
+ diagrams, macros, panels, and other ADF elements.
8
+
9
+ NEVER use `mcp__atlassian__updateConfluencePage` with ADF contentFormat for large pages —
10
+ the body parameter has a size limit that truncates content.
11
+
12
+ Correct workflow:
13
+ 1. `confluence_cli.py -o <project>/.atlassian retrieve <pageId>`
14
+ 2. Edit the local `.md` file (Mermaid = ```mermaid blocks, macros = <!-- confluence-macro --> comments)
15
+ 3. `confluence_cli.py -o <project>/.atlassian update <pageId> --file <path>.md`
16
+
17
+ The atlassian-tools skill handles:
18
+ - Bidirectional HTML↔Markdown conversion preserving all Confluence elements
19
+ - Version conflict detection with auto patch-merge
20
+ - Local caching for offline editing
package/sources.json CHANGED
@@ -1,6 +1,11 @@
1
1
  {
2
2
  "version": 1,
3
3
  "sources": [
4
+ {
5
+ "type": "rules-dir",
6
+ "path": "./rules",
7
+ "label": "team-rules"
8
+ },
4
9
  {
5
10
  "type": "skills-dir",
6
11
  "path": "./skills",