@softspark/ai-toolkit 1.5.0 → 1.5.1

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,15 @@ Versioning follows [Semantic Versioning](https://semver.org/).
7
7
 
8
8
  ---
9
9
 
10
+ ## v1.5.1 — Security Hardening: Script Injection, XSS, Private Data Leak (2026-04-10)
11
+
12
+ ### Fixed
13
+ - **`action.yml` script injection** — replaced `${{ inputs.command }}` direct interpolation with `env:` variable to prevent GitHub Actions script injection (OWASP A03)
14
+ - **`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
15
+ - **`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)
16
+
17
+ ---
18
+
10
19
  ## v1.5.0 — HIPAA Scanner: Deterministic Script, CI Integration, Self-Exclusion (2026-04-10)
11
20
 
12
21
  ### Added
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.5.1",
5
5
  "author": {
6
6
  "name": "SoftSpark",
7
7
  "url": "https://github.com/softspark"
@@ -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
 
@@ -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 }));
package/llms-full.txt CHANGED
@@ -15,6 +15,7 @@
15
15
  - [No Hardcoded Counts in Secondary Docs](kb/best-practices/no-hardcoded-counts.md)
16
16
  - [How-To Guides](kb/howto/README.md)
17
17
  - [SOP: Claude Toolkit Maintenance](kb/procedures/maintenance-sop.md)
18
+ - [SOP: Release Preparation](kb/procedures/release-preparation-sop.md)
18
19
  - [SOP: Release Verification](kb/procedures/release-verification-sop.md)
19
20
  - [Agents Catalog](kb/reference/agents-catalog.md)
20
21
  - [Anti-Pattern Registry Format](kb/reference/anti-pattern-registry-format.md)
@@ -601,6 +602,288 @@ What `uninstall` does:
601
602
 
602
603
  ---
603
604
 
605
+ ## kb/procedures/release-preparation-sop.md
606
+
607
+ ---
608
+ title: "SOP: Release Preparation"
609
+ category: procedures
610
+ service: ai-toolkit
611
+ tags: [sop, release, version, publish, changelog, semver]
612
+ version: "1.5.0"
613
+ created: "2026-04-10"
614
+ last_updated: "2026-04-10"
615
+ description: "Step-by-step checklist for preparing a new ai-toolkit release — version sync, changelog, artifact regeneration, validation, and tagging. Run BEFORE every git tag."
616
+ ---
617
+
618
+ # SOP: Release Preparation
619
+
620
+ Complete checklist for preparing a new `@softspark/ai-toolkit` release.
621
+ Run this **before** tagging. After tagging and publishing, run the
622
+ [Release Verification SOP](release-verification-sop.md) to smoke-test.
623
+
624
+ **Pipeline:**
625
+ ```
626
+ Release Preparation (this SOP) → git tag → CI publish → Release Verification SOP
627
+ ```
628
+
629
+ **Time:** 5-10 minutes
630
+
631
+ ---
632
+
633
+ ## Quick Checklist (TL;DR)
634
+
635
+ ```bash
636
+ # 1. Decide version bump
637
+ # patch (1.4.2 → 1.4.3): bugfix, typo, doc fix
638
+ # minor (1.4.2 → 1.5.0): new feature, new skill, new flag
639
+ # major (1.4.2 → 2.0.0): breaking change
640
+
641
+ # 2. Sync version across all files
642
+ python3 scripts/sync_version.py X.Y.Z # if script exists, else manual
643
+
644
+ # 3. Write CHANGELOG.md entry
645
+ # 4. Regenerate artifacts
646
+ python3 scripts/generate_agents_md.py > AGENTS.md
647
+ python3 scripts/generate_llms_txt.py > llms.txt
648
+ python3 scripts/generate_llms_txt.py --full > llms-full.txt
649
+
650
+ # 5. Validate + audit + test
651
+ python3 scripts/validate.py --strict && python3 scripts/audit_skills.py --ci && npm test
652
+
653
+ # 6. Commit + tag + push
654
+ git add -A && git commit -m "chore: release vX.Y.Z"
655
+ git tag vX.Y.Z
656
+ git push origin main --tags
657
+ ```
658
+
659
+ ---
660
+
661
+ ## Phase 1: Determine Version Bump
662
+
663
+ Follow [Semantic Versioning](https://semver.org/):
664
+
665
+ | Change Type | Bump | Examples |
666
+ |-------------|------|---------|
667
+ | Bugfix, typo, doc-only | **patch** | Fix install flag, correct description |
668
+ | New feature, skill, agent, flag | **minor** | Add `/hipaa-validate`, add `--output json` |
669
+ | Breaking CLI change, removed skill, config format change | **major** | Rename `install` to `setup`, remove skill |
670
+
671
+ **Rule:** When in doubt, bump minor.
672
+
673
+ ---
674
+
675
+ ## Phase 2: Sync Version in All Files
676
+
677
+ The canonical version lives in `package.json`. These files **must** match:
678
+
679
+ ### Mandatory sync (every release)
680
+
681
+ | File | Field | How to update |
682
+ |------|-------|---------------|
683
+ | `package.json` | `"version": "X.Y.Z"` | Edit directly |
684
+ | `manifest.json` | `"version": "X.Y.Z"` | Edit directly |
685
+ | `app/.claude-plugin/plugin.json` | `"version": "X.Y.Z"` | Edit directly |
686
+
687
+ ### Auto-synced (no manual action)
688
+
689
+ | File | Mechanism |
690
+ |------|-----------|
691
+ | `package-lock.json` | Regenerated by `npm install --package-lock-only` |
692
+
693
+ ### Conditional sync (only if the doc was modified in this release)
694
+
695
+ | File | Field | When to update |
696
+ |------|-------|---------------|
697
+ | `kb/procedures/maintenance-sop.md` | frontmatter `version:` | If SOP content changed |
698
+ | `kb/reference/skills-catalog.md` | frontmatter `version:` | If skills added/removed |
699
+ | `kb/reference/agents-catalog.md` | frontmatter `version:` | If agents added/removed |
700
+ | `kb/reference/hooks-catalog.md` | frontmatter `version:` | If hooks changed |
701
+ | `kb/reference/architecture-overview.md` | frontmatter `version:` | If architecture changed |
702
+ | `kb/reference/distribution-model.md` | frontmatter `version:` | If install model changed |
703
+ | `kb/reference/global-install-model.md` | frontmatter `version:` | If install model changed |
704
+
705
+ > **Note:** KB `version:` fields track the **document version**, not the toolkit version.
706
+ > Only bump them when the document content actually changes in this release.
707
+
708
+ ### Count sync (if skills/agents/hooks changed)
709
+
710
+ | File | What to check |
711
+ |------|---------------|
712
+ | `package.json` | `"description"` — skill/agent count |
713
+ | `README.md` | Badge counts, "What You Get" table |
714
+ | `app/ARCHITECTURE.md` | Section headings with counts |
715
+
716
+ > **Tip:** `validate.py --strict` and `npm test` (metadata contract tests) catch
717
+ > count drift automatically. If tests pass, counts are correct.
718
+
719
+ ### Verification command
720
+
721
+ After syncing, verify all mandatory files match:
722
+
723
+ ```bash
724
+ VERSION=$(python3 -c "import json; print(json.load(open('package.json'))['version'])")
725
+ echo "Target: $VERSION"
726
+ echo "manifest.json: $(python3 -c "import json; print(json.load(open('manifest.json'))['version'])")"
727
+ echo "plugin.json: $(python3 -c "import json; print(json.load(open('app/.claude-plugin/plugin.json'))['version'])")"
728
+ echo "package-lock.json: $(python3 -c "import json; print(json.load(open('package-lock.json'))['version'])")"
729
+ ```
730
+
731
+ All four must print the same version. If not, fix before proceeding.
732
+
733
+ ---
734
+
735
+ ## Phase 3: Write CHANGELOG Entry
736
+
737
+ Add entry at the top of `CHANGELOG.md` (after the header, before previous release):
738
+
739
+ ```markdown
740
+ ## vX.Y.Z — Short Title (YYYY-MM-DD)
741
+
742
+ ### Added
743
+ - **Feature name** — description
744
+
745
+ ### Changed
746
+ - **What changed** — old behavior → new behavior
747
+
748
+ ### Fixed
749
+ - **Bug description** — what was broken and how it's fixed
750
+
751
+ ### Removed
752
+ - **What was removed** — migration path if any
753
+ ```
754
+
755
+ **Rules:**
756
+ - Use **bold** for feature names
757
+ - Start descriptions with a verb (Added, Changed, Fixed, Removed)
758
+ - Reference skill names with backticks and slash: `/hipaa-validate`
759
+ - Include script names: `scripts/hipaa_scan.py`
760
+ - Include count changes: `Skill count: 91 → 92`
761
+ - Date format: `YYYY-MM-DD`
762
+ - Title: short, descriptive, no version number repetition
763
+
764
+ ---
765
+
766
+ ## Phase 4: Regenerate Artifacts
767
+
768
+ ```bash
769
+ python3 scripts/generate_agents_md.py > AGENTS.md
770
+ python3 scripts/generate_llms_txt.py > llms.txt
771
+ python3 scripts/generate_llms_txt.py --full > llms-full.txt
772
+ ```
773
+
774
+ Check if anything actually changed:
775
+
776
+ ```bash
777
+ git diff --stat AGENTS.md llms.txt llms-full.txt
778
+ ```
779
+
780
+ If no diff, the artifacts are already current. If there is a diff, stage them.
781
+
782
+ ---
783
+
784
+ ## Phase 5: Validate, Audit, Test
785
+
786
+ Run the full quality gate:
787
+
788
+ ```bash
789
+ python3 scripts/validate.py --strict
790
+ python3 scripts/audit_skills.py --ci
791
+ npm test
792
+ ```
793
+
794
+ **Expected results:**
795
+ - `validate.py`: `Errors: 0 | Warnings: 0 | VALIDATION PASSED`
796
+ - `audit_skills.py`: `HIGH: 0 | WARN: 0` (INFO is acceptable)
797
+ - `npm test`: `1..N` with zero `not ok`
798
+
799
+ **One-liner:**
800
+ ```bash
801
+ python3 scripts/validate.py --strict && python3 scripts/audit_skills.py --ci && npm test
802
+ ```
803
+
804
+ **If tests fail:** Fix the issue, do NOT skip. Common failures:
805
+ - Stale counts → re-run `generate:all` or fix README/ARCHITECTURE
806
+ - Missing frontmatter → add to new KB docs
807
+ - Broken symlink → `ai-toolkit doctor --fix`
808
+
809
+ ---
810
+
811
+ ## Phase 6: Commit
812
+
813
+ Stage all release files:
814
+
815
+ ```bash
816
+ git add package.json manifest.json app/.claude-plugin/plugin.json
817
+ git add package-lock.json
818
+ git add CHANGELOG.md
819
+ git add AGENTS.md llms.txt llms-full.txt
820
+ git add -p # review and stage any other changes
821
+ ```
822
+
823
+ Commit:
824
+
825
+ ```bash
826
+ git commit -m "chore: release vX.Y.Z"
827
+ ```
828
+
829
+ ---
830
+
831
+ ## Phase 7: Tag and Push
832
+
833
+ ```bash
834
+ git tag vX.Y.Z
835
+ git push origin main --tags
836
+ ```
837
+
838
+ This triggers `.github/workflows/publish.yml` which:
839
+ 1. Runs `validate.py --strict`
840
+ 2. Runs `npm test`
841
+ 3. Publishes to npm as `@softspark/ai-toolkit@X.Y.Z`
842
+
843
+ **After CI completes:** Run the [Release Verification SOP](release-verification-sop.md)
844
+ to smoke-test the published package.
845
+
846
+ ---
847
+
848
+ ## Rollback
849
+
850
+ If a bad release was published:
851
+
852
+ ```bash
853
+ # Unpublish from npm (within 72h)
854
+ npm unpublish @softspark/ai-toolkit@X.Y.Z
855
+
856
+ # Or deprecate (preferred — doesn't break existing installs)
857
+ npm deprecate @softspark/ai-toolkit@X.Y.Z "Known issue: <description>. Use vA.B.C instead."
858
+
859
+ # Delete tag
860
+ git tag -d vX.Y.Z
861
+ git push origin --delete vX.Y.Z
862
+ ```
863
+
864
+ ---
865
+
866
+ ## Checklist Summary
867
+
868
+ | # | Step | Command / Action | Pass Criteria |
869
+ |---|------|-----------------|---------------|
870
+ | 1 | Version bump type | Decide patch/minor/major | — |
871
+ | 2 | `package.json` version | Edit `"version"` | Matches target |
872
+ | 3 | `manifest.json` version | Edit `"version"` | Matches target |
873
+ | 4 | `plugin.json` version | Edit `"version"` | Matches target |
874
+ | 5 | `package-lock.json` | `npm install --package-lock-only` | Matches target |
875
+ | 6 | Count sync | Check `package.json` description, README | `validate.py` passes |
876
+ | 7 | CHANGELOG.md | Add release entry | Entry exists for vX.Y.Z |
877
+ | 8 | Regenerate artifacts | `generate_agents_md.py`, `generate_llms_txt.py` | No unexpected diff |
878
+ | 9 | Validate | `validate.py --strict` | 0 errors, 0 warnings |
879
+ | 10 | Security audit | `audit_skills.py --ci` | 0 HIGH |
880
+ | 11 | Tests | `npm test` | All pass |
881
+ | 12 | Commit | `git commit` | Clean working tree |
882
+ | 13 | Tag | `git tag vX.Y.Z` | Tag exists |
883
+ | 14 | Push | `git push origin main --tags` | CI triggered |
884
+
885
+ ---
886
+
604
887
  ## kb/procedures/release-verification-sop.md
605
888
 
606
889
  ---
package/llms.txt CHANGED
@@ -15,6 +15,7 @@
15
15
  - [No Hardcoded Counts in Secondary Docs](kb/best-practices/no-hardcoded-counts.md)
16
16
  - [How-To Guides](kb/howto/README.md)
17
17
  - [SOP: Claude Toolkit Maintenance](kb/procedures/maintenance-sop.md)
18
+ - [SOP: Release Preparation](kb/procedures/release-preparation-sop.md)
18
19
  - [SOP: Release Verification](kb/procedures/release-verification-sop.md)
19
20
  - [Agents Catalog](kb/reference/agents-catalog.md)
20
21
  - [Anti-Pattern Registry Format](kb/reference/anti-pattern-registry-format.md)
package/manifest.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.5.0",
2
+ "version": "1.5.1",
3
3
  "components": {
4
4
  "agents": {
5
5
  "description": "44 specialized agents (orchestrator, backend, frontend, security, devops, etc.)",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softspark/ai-toolkit",
3
- "version": "1.5.0",
3
+ "version": "1.5.1",
4
4
  "description": "Professional-grade AI coding toolkit: 92 skills, 44 agents, multi-platform support (Claude, Cursor, Windsurf, Copilot, Gemini, Cline, Roo Code, Aider, Augment, Google Antigravity), machine-enforced safety constitution, persona presets, skill security auditor, expanded lifecycle hooks, 11 plugin packs, and benchmark tooling.",
5
5
  "keywords": [
6
6
  "claude",