@softspark/ai-toolkit 1.5.0 → 1.6.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/CHANGELOG.md CHANGED
@@ -7,6 +7,31 @@ Versioning follows [Semantic Versioning](https://semver.org/).
7
7
 
8
8
  ---
9
9
 
10
+ ## v1.6.0 — IDE Language Rules Propagation, Planning Docs, Cloud Security Pack (2026-04-10)
11
+
12
+ ### Added
13
+ - **Language rules propagation to all IDE editors** — shared `dir_rules_shared.py` module now injects language-specific and registered rules into Cursor, Windsurf, Cline, Roo Code, Augment, Antigravity, and Copilot generators. All platforms receive identical rule content from a single source of truth.
14
+ - **Local Dashboard Plan** — planning doc (`kb/planning/local-dashboard-plan.md`) for ai-toolkit UI with visual skill/agent management features
15
+ - **Enterprise Config Inheritance Plan** — planning doc (`kb/planning/enterprise-config-inheritance-plan.md`) for hierarchical config system
16
+ - **Offline SLM Profile Plan** — planning doc (`kb/planning/offline-slm-profile-plan.md`) for offline small language model profiles
17
+ - **Cloud Security Pack Plan** — planning doc (`kb/planning/cloud-security-pack-plan.md`) for multi-cloud audit (GCP/AWS/Azure)
18
+ - **193 new generator tests** — language rules propagation, content verification, cross-platform parity
19
+
20
+ ### Changed
21
+ - **Documentation standards** — added `planning` as a valid KB category in `validate.py`, `documenter` agent, `/docs` and `/documentation-standards` skills
22
+ - **Maintenance SOP** — updated to reflect language rules propagation workflow
23
+
24
+ ---
25
+
26
+ ## v1.5.1 — Security Hardening: Script Injection, XSS, Private Data Leak (2026-04-10)
27
+
28
+ ### Fixed
29
+ - **`action.yml` script injection** — replaced `${{ inputs.command }}` direct interpolation with `env:` variable to prevent GitHub Actions script injection (OWASP A03)
30
+ - **`visual-server.cjs` stored XSS** — extracted inline script to `poll.js`, added `Content-Security-Policy: script-src 'self'` header to block injected scripts in PRD visual preview
31
+ - **`strip_private.py` regex** — changed `[^<]*` to `.*?` with `re.DOTALL` flag to correctly handle multi-line `<private>` blocks and inner angle brackets (was leaking private data in edge cases)
32
+
33
+ ---
34
+
10
35
  ## v1.5.0 — HIPAA Scanner: Deterministic Script, CI Integration, Self-Exclusion (2026-04-10)
11
36
 
12
37
  ### Added
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
7
7
  [![Skills](https://img.shields.io/badge/skills-92-brightgreen)](app/skills/)
8
8
  [![Agents](https://img.shields.io/badge/agents-44-blue)](app/agents/)
9
- [![Tests](https://img.shields.io/badge/tests-439%20passing-success)](tests/)
9
+ [![Tests](https://img.shields.io/badge/tests-451%20passing-success)](tests/)
10
10
 
11
11
  ---
12
12
 
@@ -128,7 +128,7 @@ Replaces all symlinks with real files, inlines rules into CLAUDE.md, copies cons
128
128
  | Google Antigravity | `.agent/rules/*.md` + `.agent/workflows/*.md` | `ai-toolkit install --local` | project |
129
129
  | Codex / OpenCode | `AGENTS.md` | `ai-toolkit agents-md` | project |
130
130
 
131
- > **Note:** Claude Code is always installed (primary platform with full feature support). Other editors are installed on demand with `--editors <list>` or auto-detected from existing project files. All platforms receive the same agent/skill catalog, guidelines, and rules. For editors lacking native bash lifecycle hooks, `--local` installs a Git hooks fallback (`.git/hooks/pre-commit`) to enforce quality gates pre-commit.
131
+ > **Note:** Claude Code is always installed (primary platform with full feature support). Other editors are installed on demand with `--editors <list>` or auto-detected from existing project files. All platforms receive the same agent/skill catalog, guidelines, rules, language-specific rules, and registered custom rules. For editors lacking native bash lifecycle hooks, `--local` installs a Git hooks fallback (`.git/hooks/pre-commit`) to enforce quality gates pre-commit.
132
132
 
133
133
  ---
134
134
 
@@ -191,7 +191,7 @@ ai-toolkit/
191
191
  │ ├── output-styles/ # System prompt output style overrides
192
192
  │ ├── constitution.md # 5 immutable safety articles
193
193
  │ └── ARCHITECTURE.md # Full system design
194
- ├── kb/ # Reference docs, architecture notes, procedures
194
+ ├── kb/ # Reference docs, architecture notes, procedures, plans
195
195
  ├── scripts/ # Validation, install, evaluation scripts
196
196
  ├── tests/ # Bats test suite
197
197
  └── CHANGELOG.md
@@ -529,6 +529,19 @@ ai-toolkit install --local --lang go,python # multiple languages
529
529
 
530
530
  `--local` automatically detects languages using two-phase detection: config markers (package.json, go.mod, Cargo.toml, etc.) plus source file extension scanning (.py, .ts, .go, etc.). `--lang` accepts aliases (`go`, `c++`, `cs`). Rules are injected into `CLAUDE.md` and auto-updated on `ai-toolkit update --local`.
531
531
 
532
+ When `--editors` is used alongside detected or explicit languages, language rules are propagated to all configured editors — not just Claude. Each editor receives the full rule content in its native format:
533
+
534
+ | Editor | Language rule file | Activation |
535
+ |--------|-------------------|------------|
536
+ | Cursor | `.cursor/rules/ai-toolkit-lang-<lang>.mdc` | `globs` per file type (e.g. `**/*.py`) |
537
+ | Windsurf | `.windsurf/rules/ai-toolkit-lang-<lang>.md` | always loaded |
538
+ | Cline | `.cline/rules/ai-toolkit-lang-<lang>.md` | always loaded |
539
+ | Roo Code | `.roo/rules/ai-toolkit-lang-<lang>.md` | always loaded |
540
+ | Augment | `.augment/rules/ai-toolkit-lang-<lang>.md` | `auto_attached` with globs |
541
+ | Antigravity | `.agent/rules/ai-toolkit-lang-<lang>.md` | always loaded |
542
+
543
+ Registered rules (`ai-toolkit add-rule`) are also propagated to directory-based editor configs as `ai-toolkit-custom-<name>` files.
544
+
532
545
  ---
533
546
 
534
547
  ## Extension API
package/action.yml CHANGED
@@ -39,8 +39,9 @@ runs:
39
39
  - name: Run ai-toolkit
40
40
  id: run-toolkit
41
41
  shell: bash
42
+ env:
43
+ COMMAND: ${{ inputs.command }}
42
44
  run: |
43
- COMMAND="${{ inputs.command }}"
44
45
  case "$COMMAND" in
45
46
  validate|doctor) ;;
46
47
  *) echo "Error: invalid command '$COMMAND' (allowed: validate, doctor)"; exit 1 ;;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ai-toolkit",
3
3
  "description": "Professional-grade Claude Code toolkit with persona presets, skill security auditor, expanded lifecycle hooks, experimental opt-in plugin packs, benchmark harvesting, and multi-tool support.",
4
- "version": "1.5.0",
4
+ "version": "1.6.0",
5
5
  "author": {
6
6
  "name": "SoftSpark",
7
7
  "url": "https://github.com/softspark"
@@ -305,7 +305,9 @@ Lead Session (You)
305
305
  `app/plugins/mcp-templates/` ships 25 ready-to-use MCP server config templates (filesystems, databases, GitHub, Slack, etc.). Opt-in via `ai-toolkit install --modules mcp-templates` or activated automatically with `--profile strict|full`.
306
306
 
307
307
  ### Language Rules (70 files, 13 languages)
308
- `app/rules/` contains per-language coding rules injected into `CLAUDE.md`. Supported languages: TypeScript, Python, Go, Rust, Java, Kotlin, Swift, Dart, C#, PHP, C++, Ruby, and common (shared). Auto-detected from project files via `--auto-detect` or selected with `--modules rules-<lang>`.
308
+ `app/rules/` contains per-language coding rules. Supported languages: TypeScript, Python, Go, Rust, Java, Kotlin, Swift, Dart, C#, PHP, C++, Ruby, and common (shared). Auto-detected from project files via `--auto-detect` or selected with `--modules rules-<lang>`.
309
+
310
+ Language rules are propagated to **all configured editors** — not just Claude. `dir_rules_shared.build_language_rules()` reads `app/rules/<lang>/*.md`, strips frontmatter, and returns combined content per language. Each directory-based generator (Cursor, Windsurf, Cline, Roo, Augment, Antigravity) emits `ai-toolkit-lang-<lang>` files in its native format. Registered custom rules (`~/.ai-toolkit/rules/`) are similarly propagated as `ai-toolkit-custom-<name>` files via `build_registered_rules()`.
309
311
 
310
312
  ### Extension API (`inject-hook`)
311
313
  The `inject_section_cli.py` script provides a stable marker-based injection API. Any tool can add sections to `CLAUDE.md`, `constitution.md`, or `ARCHITECTURE.md` without overwriting user content, using `<!-- TOOLKIT:START:<id> -->` / `<!-- TOOLKIT:END:<id> -->` markers.
@@ -202,12 +202,12 @@ command
202
202
 
203
203
  ## Frontmatter Standards (MANDATORY)
204
204
 
205
- Follow the `documentation-standards` knowledge skill for full spec. **7 required fields:** title, category, service, tags, created, last_updated, description. **5 valid categories:** reference, howto, procedures, troubleshooting, best-practices. `validate.sh` enforces compliance — **docs without valid frontmatter block CI.**
205
+ Follow the `documentation-standards` knowledge skill for full spec. **7 required fields:** title, category, service, tags, created, last_updated, description. **6 valid categories:** reference, howto, procedures, troubleshooting, best-practices, planning. `validate.sh` enforces compliance — **docs without valid frontmatter block CI.**
206
206
 
207
207
  ## Hard Rules (ENFORCED — NO EXCEPTIONS)
208
208
 
209
209
  1. **REFUSE** to create any file in `kb/` without valid YAML frontmatter containing ALL 7 required fields (title, category, service, tags, created, last_updated, description).
210
- 2. **REFUSE** to use any category other than: `reference`, `howto`, `procedures`, `troubleshooting`, `best-practices`.
210
+ 2. **REFUSE** to use any category other than: `reference`, `howto`, `procedures`, `troubleshooting`, `best-practices`, `planning`.
211
211
  3. **REFUSE** to place a document in a directory that doesn't match its `category:` field (e.g., a `howto` doc MUST go in `kb/howto/`).
212
212
  4. **REFUSE** to write KB content in any language other than English.
213
213
  5. **ALWAYS** run `ai-toolkit validate` or `scripts/validate.py` after creating/modifying KB documents to verify compliance.
@@ -14,7 +14,7 @@ import sys
14
14
 
15
15
  def main() -> None:
16
16
  content = sys.stdin.read()
17
- cleaned = re.sub(r"<private>[^<]*</private>", "", content)
17
+ cleaned = re.sub(r"<private>.*?</private>", "", content, flags=re.DOTALL)
18
18
  sys.stdout.write(cleaned)
19
19
 
20
20
 
@@ -44,7 +44,7 @@ Generate or update documentation.
44
44
  When creating or updating documents in the `kb/` directory, follow the `documentation-standards` knowledge skill (auto-loaded). Key rules:
45
45
 
46
46
  - **7 required frontmatter fields:** title, category, service, tags, created, last_updated, description
47
- - **5 valid categories:** reference, howto, procedures, troubleshooting, best-practices
47
+ - **6 valid categories:** reference, howto, procedures, troubleshooting, best-practices, planning
48
48
  - **Category must match directory** (e.g., `category: howto` → `kb/howto/`)
49
49
  - **English only.** No exceptions.
50
50
  - **validate.sh rejects docs without valid frontmatter.**
@@ -178,7 +178,7 @@ scripts/validate.py
178
178
  # Checks: required fields present, category is valid, tags non-empty
179
179
  ```
180
180
 
181
- Valid categories: `reference`, `howto`, `procedures`, `troubleshooting`, `best-practices`.
181
+ Valid categories: `reference`, `howto`, `procedures`, `troubleshooting`, `best-practices`, `planning`.
182
182
 
183
183
  ## Anti-Patterns
184
184
 
@@ -82,30 +82,6 @@
82
82
  </div>
83
83
  </main>
84
84
  <div class="status"><span class="dot"></span>Connected</div>
85
- <script>
86
- (function () {
87
- var contentEl = document.getElementById("content");
88
- var lastHtml = "";
89
-
90
- function poll() {
91
- fetch("/content")
92
- .then(function (res) { return res.json(); })
93
- .then(function (data) {
94
- if (data.html && data.html !== lastHtml) {
95
- lastHtml = data.html;
96
- contentEl.style.opacity = "0";
97
- setTimeout(function () {
98
- contentEl.innerHTML = data.html;
99
- contentEl.style.opacity = "1";
100
- }, 80);
101
- }
102
- })
103
- .catch(function () {});
104
- }
105
-
106
- setInterval(poll, 2000);
107
- poll();
108
- })();
109
- </script>
85
+ <script src="/poll.js"></script>
110
86
  </body>
111
87
  </html>
@@ -0,0 +1,23 @@
1
+ (function () {
2
+ var contentEl = document.getElementById("content");
3
+ var lastHtml = "";
4
+
5
+ function poll() {
6
+ fetch("/content")
7
+ .then(function (res) { return res.json(); })
8
+ .then(function (data) {
9
+ if (data.html && data.html !== lastHtml) {
10
+ lastHtml = data.html;
11
+ contentEl.style.opacity = "0";
12
+ setTimeout(function () {
13
+ contentEl.innerHTML = data.html;
14
+ contentEl.style.opacity = "1";
15
+ }, 80);
16
+ }
17
+ })
18
+ .catch(function () {});
19
+ }
20
+
21
+ setInterval(poll, 2000);
22
+ poll();
23
+ })();
@@ -20,16 +20,26 @@ function resetIdleTimer() {
20
20
 
21
21
  const templatePath = path.join(__dirname, "frame-template.html");
22
22
  const templateHtml = fs.readFileSync(templatePath, "utf-8");
23
+ const pollJs = fs.readFileSync(path.join(__dirname, "poll.js"), "utf-8");
23
24
 
24
25
  const server = http.createServer((req, res) => {
25
26
  resetIdleTimer();
26
27
 
27
28
  if (req.method === "GET" && (req.url === "/" || req.url === "/index.html")) {
28
- res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
29
+ res.writeHead(200, {
30
+ "Content-Type": "text/html; charset=utf-8",
31
+ "Content-Security-Policy": "script-src 'self'",
32
+ });
29
33
  res.end(templateHtml);
30
34
  return;
31
35
  }
32
36
 
37
+ if (req.method === "GET" && req.url === "/poll.js") {
38
+ res.writeHead(200, { "Content-Type": "application/javascript; charset=utf-8" });
39
+ res.end(pollJs);
40
+ return;
41
+ }
42
+
33
43
  if (req.method === "GET" && req.url === "/content") {
34
44
  res.writeHead(200, { "Content-Type": "application/json" });
35
45
  res.end(JSON.stringify({ html: currentContent }));