@nomad-e/bluma-cli 0.1.17 → 0.1.19

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 (41) hide show
  1. package/README.md +62 -12
  2. package/dist/config/native_tools.json +7 -0
  3. package/dist/config/skills/git-commit/LICENSE.txt +18 -0
  4. package/dist/config/skills/git-commit/SKILL.md +258 -0
  5. package/dist/config/skills/git-commit/references/REFERENCE.md +249 -0
  6. package/dist/config/skills/git-commit/scripts/validate_commit_msg.py +163 -0
  7. package/dist/config/skills/git-pr/LICENSE.txt +18 -0
  8. package/dist/config/skills/git-pr/SKILL.md +293 -0
  9. package/dist/config/skills/git-pr/references/REFERENCE.md +256 -0
  10. package/dist/config/skills/git-pr/scripts/validate_commits.py +112 -0
  11. package/dist/config/skills/pdf/LICENSE.txt +26 -0
  12. package/dist/config/skills/pdf/SKILL.md +327 -0
  13. package/dist/config/skills/pdf/references/FORMS.md +69 -0
  14. package/dist/config/skills/pdf/references/REFERENCE.md +52 -0
  15. package/dist/config/skills/pdf/scripts/create_report.py +59 -0
  16. package/dist/config/skills/pdf/scripts/merge_pdfs.py +39 -0
  17. package/dist/config/skills/skill-creator/LICENSE.txt +26 -0
  18. package/dist/config/skills/skill-creator/SKILL.md +229 -0
  19. package/dist/config/skills/xlsx/LICENSE.txt +18 -0
  20. package/dist/config/skills/xlsx/SKILL.md +298 -0
  21. package/dist/config/skills/xlsx/references/REFERENCE.md +337 -0
  22. package/dist/config/skills/xlsx/scripts/office/__init__.py +2 -0
  23. package/dist/config/skills/xlsx/scripts/office/__pycache__/__init__.cpython-312.pyc +0 -0
  24. package/dist/config/skills/xlsx/scripts/office/__pycache__/pack.cpython-312.pyc +0 -0
  25. package/dist/config/skills/xlsx/scripts/office/__pycache__/soffice.cpython-312.pyc +0 -0
  26. package/dist/config/skills/xlsx/scripts/office/__pycache__/unpack.cpython-312.pyc +0 -0
  27. package/dist/config/skills/xlsx/scripts/office/__pycache__/validate.cpython-312.pyc +0 -0
  28. package/dist/config/skills/xlsx/scripts/office/pack.py +58 -0
  29. package/dist/config/skills/xlsx/scripts/office/soffice.py +180 -0
  30. package/dist/config/skills/xlsx/scripts/office/unpack.py +63 -0
  31. package/dist/config/skills/xlsx/scripts/office/validate.py +122 -0
  32. package/dist/config/skills/xlsx/scripts/recalc.py +143 -0
  33. package/dist/main.js +275 -89
  34. package/package.json +1 -1
  35. package/dist/config/example.bluma-mcp.json.txt +0 -14
  36. package/dist/config/models_config.json +0 -78
  37. package/dist/skills/git-conventional/LICENSE.txt +0 -3
  38. package/dist/skills/git-conventional/SKILL.md +0 -83
  39. package/dist/skills/skill-creator/SKILL.md +0 -495
  40. package/dist/skills/testing/LICENSE.txt +0 -3
  41. package/dist/skills/testing/SKILL.md +0 -114
@@ -0,0 +1,163 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Validate a commit message against Conventional Commits format
4
+ and BluMa watermark requirements.
5
+
6
+ Usage:
7
+ python validate_commit_msg.py "<commit message>"
8
+ python validate_commit_msg.py --last
9
+ python validate_commit_msg.py --range main..HEAD
10
+
11
+ Exit codes:
12
+ 0 Message is valid
13
+ 1 Message has issues
14
+ """
15
+
16
+ import subprocess
17
+ import sys
18
+ import re
19
+
20
+ TYPES = {"feat", "fix", "refactor", "docs", "test", "perf", "style", "chore", "security", "revert"}
21
+
22
+ SUBJECT_RE = re.compile(
23
+ r'^(' + '|'.join(TYPES) + r')'
24
+ r'(\([a-zA-Z0-9_/.-]+\))?'
25
+ r'!?:\s'
26
+ r'.{1,68}$'
27
+ )
28
+
29
+ WATERMARK = "Generated-by: BluMa"
30
+
31
+
32
+ def validate_message(msg: str) -> list[str]:
33
+ issues = []
34
+ lines = msg.strip().split('\n')
35
+
36
+ if not lines:
37
+ return ["Empty commit message"]
38
+
39
+ subject = lines[0].strip()
40
+
41
+ if not SUBJECT_RE.match(subject):
42
+ parts = subject.split(':', 1)
43
+ if not parts or parts[0].split('(')[0] not in TYPES:
44
+ issues.append(f"Invalid type prefix. Expected one of: {', '.join(sorted(TYPES))}")
45
+ elif len(subject) > 72:
46
+ issues.append(f"Subject too long ({len(subject)} chars, max 72)")
47
+ else:
48
+ issues.append(f"Subject format invalid: \"{subject}\"")
49
+
50
+ if subject and subject[-1] == '.':
51
+ issues.append("Subject should not end with a period")
52
+
53
+ if subject and subject.split(': ', 1)[-1][:1].isupper():
54
+ issues.append("Subject description should start with lowercase")
55
+
56
+ if len(lines) > 1 and lines[1].strip() != '':
57
+ issues.append("Missing blank line between subject and body")
58
+
59
+ if WATERMARK not in msg:
60
+ issues.append("Missing BluMa watermark trailer")
61
+ else:
62
+ last_non_empty = ''
63
+ for line in reversed(lines):
64
+ if line.strip():
65
+ last_non_empty = line.strip()
66
+ break
67
+ if not last_non_empty.startswith("Generated-by:"):
68
+ issues.append("BluMa watermark should be the last non-empty line")
69
+
70
+ return issues
71
+
72
+
73
+ def get_last_commit_msg() -> str:
74
+ result = subprocess.run(
75
+ ["git", "log", "-1", "--format=%B"],
76
+ capture_output=True, text=True
77
+ )
78
+ if result.returncode != 0:
79
+ print(f"Error: {result.stderr.strip()}")
80
+ sys.exit(1)
81
+ return result.stdout.strip()
82
+
83
+
84
+ def get_commit_msgs(commit_range: str) -> list[tuple[str, str]]:
85
+ result = subprocess.run(
86
+ ["git", "log", commit_range, "--format=%h|||%B---END---"],
87
+ capture_output=True, text=True
88
+ )
89
+ if result.returncode != 0:
90
+ print(f"Error: {result.stderr.strip()}")
91
+ sys.exit(1)
92
+
93
+ commits = []
94
+ for block in result.stdout.split("---END---"):
95
+ block = block.strip()
96
+ if not block:
97
+ continue
98
+ parts = block.split("|||", 1)
99
+ if len(parts) == 2:
100
+ commits.append((parts[0].strip(), parts[1].strip()))
101
+ return commits
102
+
103
+
104
+ def print_result(label: str, msg: str, issues: list[str]):
105
+ subject = msg.split('\n')[0][:60]
106
+ if issues:
107
+ print(f" FAIL [{label}] {subject}")
108
+ for issue in issues:
109
+ print(f" - {issue}")
110
+ else:
111
+ print(f" OK [{label}] {subject}")
112
+
113
+
114
+ def main():
115
+ if len(sys.argv) < 2:
116
+ print("Usage:")
117
+ print(' python validate_commit_msg.py "<message>"')
118
+ print(" python validate_commit_msg.py --last")
119
+ print(" python validate_commit_msg.py --range main..HEAD")
120
+ sys.exit(1)
121
+
122
+ has_errors = False
123
+
124
+ if sys.argv[1] == "--last":
125
+ msg = get_last_commit_msg()
126
+ issues = validate_message(msg)
127
+ print("Validating last commit:\n")
128
+ print_result("HEAD", msg, issues)
129
+ has_errors = bool(issues)
130
+
131
+ elif sys.argv[1] == "--range":
132
+ if len(sys.argv) < 3:
133
+ print("Error: --range requires a commit range (e.g. main..HEAD)")
134
+ sys.exit(1)
135
+ commits = get_commit_msgs(sys.argv[2])
136
+ if not commits:
137
+ print(f"No commits in range {sys.argv[2]}")
138
+ sys.exit(0)
139
+ print(f"Validating {len(commits)} commit(s) in {sys.argv[2]}:\n")
140
+ for h, msg in commits:
141
+ issues = validate_message(msg)
142
+ print_result(h, msg, issues)
143
+ if issues:
144
+ has_errors = True
145
+
146
+ else:
147
+ msg = sys.argv[1]
148
+ issues = validate_message(msg)
149
+ print("Validating message:\n")
150
+ print_result("input", msg, issues)
151
+ has_errors = bool(issues)
152
+
153
+ print()
154
+ if has_errors:
155
+ print("Some commits need attention.")
156
+ sys.exit(1)
157
+ else:
158
+ print("All messages are valid.")
159
+ sys.exit(0)
160
+
161
+
162
+ if __name__ == "__main__":
163
+ main()
@@ -0,0 +1,18 @@
1
+ BluMa — Base Language Unit · Model Agent
2
+ Proprietary License
3
+
4
+ Copyright (c) 2024-2026 BluMa Contributors
5
+
6
+ This skill is part of the BluMa CLI distribution.
7
+ It is provided as a bundled native skill and may not be
8
+ redistributed, modified, or used outside of the BluMa agent
9
+ framework without prior written permission.
10
+
11
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
12
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
13
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
14
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
15
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
16
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
17
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
18
+ OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,293 @@
1
+ ---
2
+ name: git-pr
3
+ description: >
4
+ Use this skill for any task involving Git commits, pull requests, or code
5
+ review preparation. Triggers include: "commit", "create a PR", "pull request",
6
+ "open a PR", "prepare a merge request", "push changes", "commit my work",
7
+ "stage and commit", "git push", "submit for review", "create MR", or any
8
+ request to finalize, package, or submit code changes for review. Also use
9
+ when asked to write commit messages or PR descriptions.
10
+ license: Proprietary. LICENSE.txt has complete terms
11
+ ---
12
+
13
+ # Git PR & Commit — Professional Workflow
14
+
15
+ ## Overview
16
+
17
+ This skill produces **production-grade** commits and pull requests with
18
+ consistent structure, meaningful descriptions, and full traceability.
19
+ Every commit and PR carries a BluMa watermark for auditability.
20
+
21
+ For advanced patterns (monorepo PRs, release PRs, hotfix workflows),
22
+ see references/REFERENCE.md.
23
+
24
+ ## Commit Workflow
25
+
26
+ ### Step 1: Inspect Changes
27
+
28
+ ```bash
29
+ git status --short
30
+ git diff --staged --stat
31
+ ```
32
+
33
+ If nothing is staged, stage the relevant files first:
34
+
35
+ ```bash
36
+ git add <files>
37
+ # or
38
+ git add -A
39
+ ```
40
+
41
+ Review what will be committed:
42
+
43
+ ```bash
44
+ git diff --staged
45
+ ```
46
+
47
+ ### Step 2: Determine Commit Type
48
+
49
+ | Prefix | When to use |
50
+ |--------|-------------|
51
+ | `feat` | New feature or capability |
52
+ | `fix` | Bug fix |
53
+ | `refactor` | Code restructuring without behavior change |
54
+ | `docs` | Documentation only |
55
+ | `test` | Adding or updating tests |
56
+ | `perf` | Performance improvement |
57
+ | `style` | Formatting, whitespace, linting (no logic change) |
58
+ | `chore` | Build, CI, dependencies, tooling |
59
+ | `security` | Security fix or hardening |
60
+ | `revert` | Reverting a previous commit |
61
+
62
+ ### Step 3: Write the Commit Message
63
+
64
+ Format:
65
+
66
+ ```
67
+ <type>(<scope>): <subject>
68
+
69
+ <body>
70
+
71
+ <footer>
72
+
73
+ Generated-by: BluMa — Base Language Unit · Model Agent
74
+ ```
75
+
76
+ Rules:
77
+ - **Subject line**: imperative mood, lowercase, no period, max 72 chars.
78
+ - Good: `feat(auth): add JWT refresh token rotation`
79
+ - Bad: `Added JWT refresh token rotation.`
80
+ - **Scope**: the module, component, or area affected (optional but preferred).
81
+ - **Body**: explain WHY the change was made, not WHAT (the diff shows what).
82
+ Wrap at 72 chars. Leave a blank line after subject.
83
+ - **Footer**: reference issues (`Closes #123`, `Refs #456`), note breaking
84
+ changes (`BREAKING CHANGE: ...`).
85
+ - **Watermark**: always include the `Generated-by` trailer as the last line.
86
+
87
+ ### Step 4: Execute the Commit
88
+
89
+ ```bash
90
+ git commit -m "<type>(<scope>): <subject>
91
+
92
+ <body>
93
+
94
+ Closes #<issue>
95
+
96
+ Generated-by: BluMa — Base Language Unit · Model Agent"
97
+ ```
98
+
99
+ For multi-line messages, prefer heredoc:
100
+
101
+ ```bash
102
+ git commit -m "$(cat <<'EOF'
103
+ feat(pdf): add CSV-to-PDF report generation
104
+
105
+ Implement create_report.py script that reads CSV data and produces
106
+ a formatted PDF report using reportlab. Supports custom titles and
107
+ outputs to the artifacts directory.
108
+
109
+ - Added scripts/create_report.py with argparse CLI
110
+ - Table styling with header highlighting and grid borders
111
+ - Automatic page sizing based on data volume
112
+
113
+ Closes #42
114
+
115
+ Generated-by: BluMa — Base Language Unit · Model Agent
116
+ EOF
117
+ )"
118
+ ```
119
+
120
+ ## Pull Request Workflow
121
+
122
+ ### Step 1: Ensure Clean Branch State
123
+
124
+ ```bash
125
+ git log --oneline main..HEAD
126
+ git diff main..HEAD --stat
127
+ ```
128
+
129
+ Verify:
130
+ - All commits follow Conventional Commits (see above).
131
+ - No untracked or unstaged changes remain.
132
+ - Branch is up to date with the target branch.
133
+
134
+ ### Step 2: Push the Branch
135
+
136
+ ```bash
137
+ git push -u origin HEAD
138
+ ```
139
+
140
+ ### Step 3: Analyze All Changes for the PR
141
+
142
+ Read every commit since divergence from the target branch:
143
+
144
+ ```bash
145
+ git log main..HEAD --format="%h %s"
146
+ git diff main..HEAD
147
+ ```
148
+
149
+ Understand the full scope of changes — not just the last commit, but ALL
150
+ commits that will be included. This is critical for writing an accurate
151
+ PR description.
152
+
153
+ ### Step 4: Generate the PR Description
154
+
155
+ Use this template exactly. Fill every section. Do not skip sections — mark
156
+ them as "N/A" if they do not apply.
157
+
158
+ ```markdown
159
+ ## Description
160
+ <!-- 2-5 sentences explaining WHAT changed and WHY -->
161
+
162
+ {Concise but complete description of the changes. Focus on the problem
163
+ being solved and the approach taken. Mention any design decisions or
164
+ trade-offs made.}
165
+
166
+ ## Related Issue
167
+
168
+ Closes #{issue_number}
169
+
170
+ ## Type of Change
171
+
172
+ - [ ] Bug fix (non-breaking change which fixes an issue)
173
+ - [ ] New feature (non-breaking change which adds functionality)
174
+ - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
175
+ - [ ] Documentation update
176
+ - [ ] Refactoring (no functional changes)
177
+ - [ ] Performance improvement
178
+ - [ ] Code cleanup
179
+ - [ ] Security fix
180
+
181
+ ## Changes Made
182
+
183
+ {Bullet list of specific changes, organized by file or module:}
184
+
185
+ - **module/file.ts**: Description of change
186
+ - **module/other.ts**: Description of change
187
+
188
+ ## Testing
189
+
190
+ - [ ] Manual testing completed
191
+ - [ ] Functionality verified in development environment
192
+ - [ ] No breaking changes introduced
193
+ - [ ] Edge cases considered and tested
194
+ - [ ] Tested with different scenarios (if applicable)
195
+
196
+ {Describe specific test scenarios and results:}
197
+
198
+ 1. **Scenario**: {what was tested}
199
+ **Result**: {what happened}
200
+
201
+ ## Breaking Changes
202
+
203
+ {If any, describe what breaks and how to migrate. If none, write "None."}
204
+
205
+ ## Screenshots (if applicable)
206
+
207
+ {Add screenshots for UI changes. If none, write "N/A."}
208
+
209
+ ## Checklist
210
+
211
+ - [ ] Code follows the project's style guidelines
212
+ - [ ] Self-review of code completed
213
+ - [ ] Hard-to-understand areas are commented
214
+ - [ ] Documentation updated (if applicable)
215
+ - [ ] No new warnings generated
216
+ - [ ] Changes tested thoroughly
217
+ - [ ] Dependent changes merged and published
218
+
219
+ ## Additional Notes
220
+
221
+ {Any context, concerns, follow-up tasks, or questions for reviewers.}
222
+
223
+ ---
224
+
225
+ > *Generated by [BluMa — Base Language Unit · Model Agent](https://github.com/Nomad-e/bluma-cli)*
226
+ ```
227
+
228
+ ### Step 5: Create the PR
229
+
230
+ ```bash
231
+ gh pr create \
232
+ --title "<type>(<scope>): <subject>" \
233
+ --body "$(cat <<'EOF'
234
+ <full PR body from Step 4>
235
+ EOF
236
+ )"
237
+ ```
238
+
239
+ The PR title MUST follow the same Conventional Commits format as commit
240
+ subjects. If the PR contains multiple commits of different types, use the
241
+ most significant type (feat > fix > refactor > chore).
242
+
243
+ ### Step 6: Verify
244
+
245
+ ```bash
246
+ gh pr view --web
247
+ ```
248
+
249
+ Confirm the PR looks correct in the browser.
250
+
251
+ ## Quality Standards
252
+
253
+ Every PR generated by BluMa must:
254
+
255
+ 1. Have a title in Conventional Commits format.
256
+ 2. Include a complete description with all template sections filled.
257
+ 3. Reference the related issue (if one exists).
258
+ 4. Mark the correct "Type of Change" checkboxes.
259
+ 5. List specific changes made, organized by file/module.
260
+ 6. Describe testing scenarios and results.
261
+ 7. Document breaking changes (or explicitly state "None").
262
+ 8. Include the BluMa watermark at the bottom.
263
+ 9. Have all checklist items reviewed (checked or unchecked with justification).
264
+
265
+ ## Watermarks
266
+
267
+ **Commit trailer** (last line of every commit message):
268
+ ```
269
+ Generated-by: BluMa — Base Language Unit · Model Agent
270
+ ```
271
+
272
+ **PR footer** (last line of every PR body):
273
+ ```markdown
274
+ ---
275
+
276
+ > *Generated by [BluMa — Base Language Unit · Model Agent](https://github.com/Nomad-e/bluma-cli)*
277
+ ```
278
+
279
+ These watermarks provide auditability and attribution. They MUST be present
280
+ in every commit and PR generated by BluMa, with no exceptions.
281
+
282
+ ## Available References
283
+
284
+ - REFERENCE.md: Advanced patterns (monorepo PRs, release PRs, hotfix workflows, PR labels, reviewer assignment)
285
+
286
+ ## Available Scripts
287
+
288
+ - validate_commits.py: Validates that all commits in a range follow Conventional Commits format
289
+
290
+ ## Next Steps
291
+
292
+ - For advanced PR workflows, see references/REFERENCE.md
293
+ - To validate commits before creating a PR, run scripts/validate_commits.py