@softspark/ai-toolkit 4.19.1 → 4.21.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 +121 -0
- package/LICENSE +201 -21
- package/NOTICE +55 -0
- package/README.md +35 -21
- package/app/.claude-plugin/plugin.json +2 -2
- package/app/hooks/_hook-io.sh +4 -0
- package/app/hooks/_locate-toolkit.sh +4 -0
- package/app/hooks/_profile-check.sh +4 -0
- package/app/hooks/_search-capability.sh +4 -0
- package/app/hooks/_session-paths.sh +4 -0
- package/app/hooks/ai-toolkit-statusline.sh +4 -0
- package/app/hooks/commit-quality.sh +4 -0
- package/app/hooks/config-desync-guard.sh +4 -0
- package/app/hooks/governance-capture.sh +4 -0
- package/app/hooks/guard-config.sh +4 -0
- package/app/hooks/guard-destructive.sh +4 -0
- package/app/hooks/guard-path.sh +4 -0
- package/app/hooks/instructions-audit.sh +4 -0
- package/app/hooks/loop-guard.sh +4 -0
- package/app/hooks/mcp-health.sh +4 -0
- package/app/hooks/notify-waiting.sh +4 -0
- package/app/hooks/post-tool-use.sh +4 -0
- package/app/hooks/pre-compact-save.sh +4 -0
- package/app/hooks/pre-compact.sh +4 -0
- package/app/hooks/quality-check.sh +4 -0
- package/app/hooks/quality-gate.sh +4 -0
- package/app/hooks/revert-guard.sh +4 -0
- package/app/hooks/save-session.sh +4 -0
- package/app/hooks/search-tracker.sh +4 -0
- package/app/hooks/session-end.sh +4 -0
- package/app/hooks/session-start.sh +4 -0
- package/app/hooks/stop-search-check.sh +4 -0
- package/app/hooks/subagent-start.sh +4 -0
- package/app/hooks/subagent-stop.sh +4 -0
- package/app/hooks/test-cohesion.sh +4 -0
- package/app/hooks/track-usage.sh +4 -0
- package/app/hooks/user-prompt-submit.sh +4 -0
- package/app/plugins/README.md +15 -15
- package/app/plugins/enterprise-pack/hooks/output-style.sh +4 -0
- package/app/plugins/enterprise-pack/hooks/status-line.sh +4 -0
- package/app/plugins/memory-pack/hooks/observation-capture.sh +4 -0
- package/app/plugins/memory-pack/hooks/session-summary.sh +4 -0
- package/app/plugins/memory-pack/scripts/init_db.py +4 -0
- package/app/plugins/memory-pack/scripts/strip_private.py +4 -0
- package/app/skills/_lib/__init__.py +4 -0
- package/app/skills/_lib/detect_utils.py +4 -0
- package/app/skills/a11y-validate/scripts/a11y-scanner.py +4 -0
- package/app/skills/analyze/scripts/complexity.py +4 -0
- package/app/skills/brand-voice/scripts/measure.py +4 -0
- package/app/skills/build/scripts/detect-build.py +4 -0
- package/app/skills/ci/scripts/ci-detect.py +4 -0
- package/app/skills/commit/scripts/pre-commit-check.py +4 -0
- package/app/skills/cve-scan/scripts/cve_scan.py +4 -0
- package/app/skills/debug/scripts/error-parser.py +4 -0
- package/app/skills/deploy/scripts/pre_deploy_check.py +4 -0
- package/app/skills/docs/scripts/doc-inventory.py +4 -0
- package/app/skills/documentation-standards/SKILL.md +25 -5
- package/app/skills/explain/scripts/dependency-graph.py +4 -0
- package/app/skills/explore/scripts/visualize.py +4 -0
- package/app/skills/fix/scripts/error-classifier.py +4 -0
- package/app/skills/health/scripts/health_check.py +4 -0
- package/app/skills/hipaa-validate/scripts/hipaa_scan.py +4 -0
- package/app/skills/lint/scripts/detect-linters.py +4 -0
- package/app/skills/migrate/scripts/migration-status.py +4 -0
- package/app/skills/plugin-creator/SKILL.md +18 -8
- package/app/skills/pr/scripts/pr-summary.py +4 -0
- package/app/skills/refactor/scripts/refactor-scan.py +4 -0
- package/app/skills/review/scripts/diff-analyzer.py +4 -0
- package/app/skills/rollback/scripts/rollback_info.py +4 -0
- package/app/skills/seo-validate/scripts/seo-scanner.py +4 -0
- package/app/skills/skill-creator/templates/reasoning-engine/search.py +4 -0
- package/app/skills/test/scripts/detect-runner.py +4 -0
- package/app/skills/write-a-prd/scripts/poll.js +4 -0
- package/benchmarks/ecosystem-doctor-snapshot.json +3 -3
- package/benchmarks/run.py +4 -0
- package/bin/ai-toolkit.js +4 -0
- package/kb/{planning/drop-cascade-hooks-after-sunset.md → history/completed/drop-cascade-hooks-after-sunset-20260710.md} +24 -0
- package/kb/{reference/language-packs.md → history/completed/language-packs-removed-20260727.md} +32 -7
- package/kb/{planning/mcp-context-trim-v4-prd.md → history/completed/mcp-context-trim-v4-prd-obsoleted-20260727.md} +43 -9
- package/kb/history/completed/no-op-plugin-packs-removed-20260727.md +127 -0
- package/kb/history/completed/tool-output-token-reduction-closed-20260727.md +190 -0
- package/kb/procedures/release-preparation-sop.md +83 -5
- package/kb/reference/comparison.md +1 -1
- package/kb/reference/enterprise-config-guide.md +1 -1
- package/kb/reference/licensing.md +148 -0
- package/kb/reference/plugin-pack-conventions.md +24 -16
- package/llms-full.txt +1182 -530
- package/llms.txt +6 -3
- package/manifest.json +1 -1
- package/package.json +3 -2
- package/scripts/_common.py +4 -0
- package/scripts/add_rule.py +4 -0
- package/scripts/audit_skills.py +4 -0
- package/scripts/benchmark_config.py +4 -0
- package/scripts/benchmark_ecosystem.py +4 -0
- package/scripts/check_deps.py +4 -0
- package/scripts/claude_app.py +4 -0
- package/scripts/codex_skill_adapter.py +4 -0
- package/scripts/compile_slm.py +4 -0
- package/scripts/config_cli.py +4 -0
- package/scripts/config_lock.py +4 -0
- package/scripts/config_merger.py +4 -0
- package/scripts/config_resolver.py +4 -0
- package/scripts/config_scaffold.py +5 -1
- package/scripts/config_validator.py +4 -0
- package/scripts/create_skill.py +4 -0
- package/scripts/dir_rules_shared.py +4 -0
- package/scripts/doctor.py +4 -0
- package/scripts/ecosystem_doctor.py +4 -0
- package/scripts/eject.py +4 -0
- package/scripts/emission.py +4 -0
- package/scripts/evaluate_skills.py +4 -0
- package/scripts/frontmatter.py +4 -0
- package/scripts/generate_agents_md.py +4 -0
- package/scripts/generate_aider_conf.py +4 -0
- package/scripts/generate_antigravity.py +4 -0
- package/scripts/generate_augment.py +4 -0
- package/scripts/generate_augment_agents.py +4 -0
- package/scripts/generate_augment_commands.py +4 -0
- package/scripts/generate_augment_hooks.py +4 -0
- package/scripts/generate_augment_rules.py +4 -0
- package/scripts/generate_augment_skills.py +4 -0
- package/scripts/generate_cline.py +4 -0
- package/scripts/generate_cline_rules.py +4 -0
- package/scripts/generate_cline_skills.py +4 -0
- package/scripts/generate_codex.py +4 -0
- package/scripts/generate_codex_agents.py +4 -0
- package/scripts/generate_codex_hooks.py +4 -0
- package/scripts/generate_codex_skills.py +4 -0
- package/scripts/generate_conventions.py +4 -0
- package/scripts/generate_copilot.py +4 -0
- package/scripts/generate_copilot_hooks.py +4 -0
- package/scripts/generate_cursor_agents.py +4 -0
- package/scripts/generate_cursor_hooks.py +4 -0
- package/scripts/generate_cursor_mdc.py +4 -0
- package/scripts/generate_cursor_rules.py +4 -0
- package/scripts/generate_cursor_skills.py +4 -0
- package/scripts/generate_devin_hooks.py +4 -0
- package/scripts/generate_gemini.py +4 -0
- package/scripts/generate_gemini_commands.py +4 -0
- package/scripts/generate_gemini_hooks.py +4 -0
- package/scripts/generate_gemini_skills.py +4 -0
- package/scripts/generate_language_rules_skills.py +4 -0
- package/scripts/generate_llms_txt.py +4 -0
- package/scripts/generate_opencode.py +4 -0
- package/scripts/generate_opencode_agents.py +4 -0
- package/scripts/generate_opencode_commands.py +4 -0
- package/scripts/generate_opencode_json.py +4 -0
- package/scripts/generate_opencode_plugin.py +4 -0
- package/scripts/generate_roo_modes.py +4 -0
- package/scripts/generate_roo_rules.py +4 -0
- package/scripts/generate_windsurf.py +4 -0
- package/scripts/generate_windsurf_rules.py +4 -0
- package/scripts/generate_windsurf_skills.py +4 -0
- package/scripts/generator_base.py +4 -0
- package/scripts/harvest_ecosystem.py +4 -0
- package/scripts/hook_sources.py +4 -0
- package/scripts/inject_hook_cli.py +4 -0
- package/scripts/inject_mcp_cli.py +4 -0
- package/scripts/inject_rule_cli.py +4 -0
- package/scripts/inject_section_cli.py +4 -0
- package/scripts/injection.py +4 -0
- package/scripts/install.py +4 -0
- package/scripts/install_git_hooks.py +4 -0
- package/scripts/install_steps/__init__.py +4 -0
- package/scripts/install_steps/ai_tools.py +4 -0
- package/scripts/install_steps/detect_language.py +4 -0
- package/scripts/install_steps/hooks.py +4 -0
- package/scripts/install_steps/install_state.py +4 -0
- package/scripts/install_steps/markers.py +4 -0
- package/scripts/install_steps/project_registry.py +4 -0
- package/scripts/install_steps/symlinks.py +4 -0
- package/scripts/instruction_core.py +4 -0
- package/scripts/mcp_editors.py +4 -0
- package/scripts/mcp_manager.py +4 -0
- package/scripts/mcp_sources.py +4 -0
- package/scripts/merge-hooks.py +4 -0
- package/scripts/migrate.py +4 -0
- package/scripts/output_filter_retirement.py +4 -0
- package/scripts/pack_codebase.py +4 -0
- package/scripts/paths.py +4 -0
- package/scripts/plugin.py +4 -0
- package/scripts/plugin_schema.py +4 -0
- package/scripts/projects_cli.py +4 -0
- package/scripts/propagate_global.py +4 -0
- package/scripts/remove_rule.py +4 -0
- package/scripts/rule_sources.py +4 -0
- package/scripts/secure_fs.py +4 -0
- package/scripts/session_state.py +4 -0
- package/scripts/session_token_stats.py +4 -0
- package/scripts/skill_pointer.py +4 -0
- package/scripts/stats.py +4 -0
- package/scripts/sync.py +4 -0
- package/scripts/test_cohesion.py +4 -0
- package/scripts/uninstall.py +4 -0
- package/scripts/update_projects.py +4 -0
- package/scripts/url_fetch.py +4 -0
- package/scripts/validate.py +37 -1
- package/scripts/version_check.py +4 -0
- package/app/plugins/csharp-pack/README.md +0 -11
- package/app/plugins/csharp-pack/plugin.json +0 -18
- package/app/plugins/frontend-pack/README.md +0 -14
- package/app/plugins/frontend-pack/plugin.json +0 -22
- package/app/plugins/java-pack/README.md +0 -11
- package/app/plugins/java-pack/plugin.json +0 -18
- package/app/plugins/kotlin-pack/README.md +0 -11
- package/app/plugins/kotlin-pack/plugin.json +0 -18
- package/app/plugins/research-pack/README.md +0 -14
- package/app/plugins/research-pack/plugin.json +0 -22
- package/app/plugins/ruby-pack/README.md +0 -11
- package/app/plugins/ruby-pack/plugin.json +0 -18
- package/app/plugins/rust-pack/README.md +0 -11
- package/app/plugins/rust-pack/plugin.json +0 -18
- package/app/plugins/security-pack/README.md +0 -15
- package/app/plugins/security-pack/plugin.json +0 -23
- package/app/plugins/swift-pack/README.md +0 -11
- package/app/plugins/swift-pack/plugin.json +0 -18
|
@@ -3,10 +3,10 @@ title: "SOP: Release Preparation"
|
|
|
3
3
|
category: procedures
|
|
4
4
|
service: ai-toolkit
|
|
5
5
|
tags: [sop, release, version, publish, changelog, semver, provenance, sarif, ecosystem, shellcheck]
|
|
6
|
-
version: "1.
|
|
6
|
+
version: "1.13.0"
|
|
7
7
|
created: "2026-04-10"
|
|
8
8
|
last_updated: "2026-07-27"
|
|
9
|
-
description: "Step-by-step checklist for preparing a new ai-toolkit release — ecosystem-sync drift check, version sync, changelog, artifact regeneration, validation, and tagging. Run BEFORE every git tag. Includes mandatory Provenance, SARIF, and checksum-pin checks added in v2.8.0, the single-run npm test discipline added in v1.8.0, the ecosystem-sync gate added in v1.9.0, the registry-vs-generators drift gate added in v1.10.0,
|
|
9
|
+
description: "Step-by-step checklist for preparing a new ai-toolkit release — ecosystem-sync drift check, version sync, changelog, artifact regeneration, validation, and tagging. Run BEFORE every git tag. Includes mandatory Provenance, SARIF, and checksum-pin checks added in v2.8.0, the single-run npm test discipline added in v1.8.0, the ecosystem-sync gate added in v1.9.0, the registry-vs-generators drift gate added in v1.10.0, the mandatory pre-tag ShellCheck gate added in v1.11.0 (publish.yml does not run ShellCheck, so a hook lint failure can publish while reddening main CI — see the v4.5.1 postmortem in Phase 5), the pre-push tag assertions added in v1.12.0 after v4.19.0 was tagged on the wrong commit (Phase 7), and the licensing gate added in v1.13.0 with the move to Apache-2.0 (Phase 5c)."
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
# SOP: Release Preparation
|
|
@@ -65,10 +65,20 @@ python3 scripts/audit_skills.py --permissions # review Bash/Write/Edit footpri
|
|
|
65
65
|
# 5b. Ecosystem gate — snapshot must be current before tag
|
|
66
66
|
python3 scripts/ecosystem_doctor.py --offline --check || { echo "STALE ecosystem snapshot — re-run doctor"; exit 1; }
|
|
67
67
|
|
|
68
|
+
# 5c. Licensing gate — SPDX headers, LICENSE, NOTICE, manifest consistency
|
|
69
|
+
npx bats tests/test_licensing.bats || { echo "LICENSING GATE FAILED"; exit 1; }
|
|
70
|
+
|
|
68
71
|
# 6. Commit + tag + push
|
|
69
72
|
git add -A && git commit -m "chore: release vX.Y.Z"
|
|
70
73
|
git tag vX.Y.Z
|
|
71
|
-
|
|
74
|
+
|
|
75
|
+
# 6a. Assert the tag before pushing it (v4.19.0 postmortem, Phase 7)
|
|
76
|
+
test "$(git rev-parse vX.Y.Z)" = "$(git rev-parse HEAD)" || { echo "FAIL: tag not on HEAD"; exit 1; }
|
|
77
|
+
git show --no-patch --format=%s vX.Y.Z | grep -qx "chore: release vX.Y.Z" || { echo "FAIL: tag not on release commit"; exit 1; }
|
|
78
|
+
|
|
79
|
+
# 6b. Branch first, then the single tag by full ref. Never --tags.
|
|
80
|
+
git push origin main
|
|
81
|
+
git push origin refs/tags/vX.Y.Z
|
|
72
82
|
```
|
|
73
83
|
|
|
74
84
|
---
|
|
@@ -332,6 +342,46 @@ python3 scripts/validate.py --strict && python3 scripts/audit_skills.py --ci &&
|
|
|
332
342
|
- Missing frontmatter → add to new KB docs
|
|
333
343
|
- Broken symlink → `ai-toolkit doctor --fix`
|
|
334
344
|
|
|
345
|
+
### Phase 5c: Licensing Gate (v4.20.0+)
|
|
346
|
+
|
|
347
|
+
The project is Apache-2.0. Attribution only works if the artefact actually
|
|
348
|
+
carries it, and every part of that is mechanically checkable.
|
|
349
|
+
|
|
350
|
+
```bash
|
|
351
|
+
# The whole gate, enforced in CI. Run it here so a failure is caught before tagging.
|
|
352
|
+
npx bats tests/test_licensing.bats
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
The seven assertions, and why each exists:
|
|
356
|
+
|
|
357
|
+
| Check | Fails when |
|
|
358
|
+
|---|---|
|
|
359
|
+
| Every shipped source file carries an SPDX header | A new `.py`/`.sh`/`.js`/`.bats` file was added without one — the common case, and the reason this is a test rather than a habit |
|
|
360
|
+
| Headers name Apache-2.0 and nothing else | A file was copied in from an MIT/GPL source with its own header intact |
|
|
361
|
+
| **No** markdown file carries an SPDX header | Someone "helpfully" ran the header script over `app/skills/` — headers there sit above parsed frontmatter and bill every session for it |
|
|
362
|
+
| `LICENSE` is the complete Apache 2.0 text | The file was truncated or replaced with a summary |
|
|
363
|
+
| `NOTICE` carries attribution, the source URL, §4(d) and the MIT-era notice | The attribution mechanism was gutted |
|
|
364
|
+
| `LICENSE` **and** `NOTICE` ship in the npm package | `package.json` `files` lost an entry — a NOTICE that never reaches the consumer cannot satisfy §4(d) |
|
|
365
|
+
| Every manifest declaring a licence declares Apache-2.0 | `package.json`, `manifest.json`, `plugin.json` and `package-lock.json` drifted apart |
|
|
366
|
+
|
|
367
|
+
**Adding source files in this release?** The header goes *after* the shebang,
|
|
368
|
+
never before it. Short SPDX form:
|
|
369
|
+
|
|
370
|
+
```
|
|
371
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
372
|
+
# Copyright 2024-2026 Lukasz Krzemien (biuro@softspark.eu)
|
|
373
|
+
# Source: https://github.com/softspark/ai-toolkit
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
`//` for JavaScript. Full convention and the reasoning behind the markdown
|
|
377
|
+
exclusion: [Licensing](../reference/licensing.md).
|
|
378
|
+
|
|
379
|
+
**Changing the licence itself?** Do not hand-type the licence text. Take it
|
|
380
|
+
verbatim from a published copy and cross-verify against a second independent
|
|
381
|
+
copy before writing `LICENSE` — a rendered or summarised licence is not the
|
|
382
|
+
licence. Prior releases stay under their original terms; a licence change
|
|
383
|
+
applies going forward and revokes nothing already granted.
|
|
384
|
+
|
|
335
385
|
### Phase 5a: Supply-Chain Hardening Verification (v2.8.0+)
|
|
336
386
|
|
|
337
387
|
These checks enforce the security standard introduced in v2.8.0. Do NOT tag a release until all pass.
|
|
@@ -405,9 +455,34 @@ git commit -m "chore: release vX.Y.Z"
|
|
|
405
455
|
|
|
406
456
|
```bash
|
|
407
457
|
git tag vX.Y.Z
|
|
408
|
-
|
|
458
|
+
|
|
459
|
+
# Assert the tag before pushing it. Both checks are one line each and both
|
|
460
|
+
# have caught a real broken release.
|
|
461
|
+
test "$(git rev-parse vX.Y.Z)" = "$(git rev-parse HEAD)" \
|
|
462
|
+
|| { echo "FAIL: tag is not on HEAD"; exit 1; }
|
|
463
|
+
git show --no-patch --format=%s vX.Y.Z | grep -qx "chore: release vX.Y.Z" \
|
|
464
|
+
|| { echo "FAIL: tag is not on the chore: release commit"; exit 1; }
|
|
465
|
+
|
|
466
|
+
# Push the branch, then the single release tag by its full ref.
|
|
467
|
+
git push origin main
|
|
468
|
+
git push origin refs/tags/vX.Y.Z
|
|
409
469
|
```
|
|
410
470
|
|
|
471
|
+
**Why the assertions (v4.19.0 postmortem).** v4.19.0 was tagged on a commit
|
|
472
|
+
that contained only a KB document and still carried `package.json` version
|
|
473
|
+
`4.18.0`; the actual release sat in the commit above it under a recycled
|
|
474
|
+
`fix:` message. `publish.yml` fired, tried to publish a version already on
|
|
475
|
+
npm, and failed. Nothing on npm, a tag pointing at the wrong tree, and the
|
|
476
|
+
only way out was rewriting a pushed commit. Both assertions above catch this
|
|
477
|
+
in under a second. Run them.
|
|
478
|
+
|
|
479
|
+
**Never `git push --tags`.** It pushes every local tag at once, and GitHub
|
|
480
|
+
suppresses tag-triggered workflow runs when many tags arrive in a single push
|
|
481
|
+
— the workflow silently does not fire and nothing publishes. Push the single
|
|
482
|
+
release tag by its full ref, as above. (Sibling evidence: this is exactly how
|
|
483
|
+
rag-mcp's `1.0.3` image build was skipped, when a `--tags` push carried 37
|
|
484
|
+
tags at once.)
|
|
485
|
+
|
|
411
486
|
This triggers `.github/workflows/publish.yml` which:
|
|
412
487
|
1. Runs `validate.py --strict`
|
|
413
488
|
2. Runs `npm test`
|
|
@@ -460,7 +535,10 @@ git push origin --delete vX.Y.Z
|
|
|
460
535
|
| 13 | ShellCheck hooks | `shellcheck --severity=warning app/hooks/*.sh` | Exit 0, no output (mirrors ci.yml; publish.yml does NOT run it) |
|
|
461
536
|
| 14 | Provenance flag check | `grep -- '--provenance' .github/workflows/publish.yml` | Present |
|
|
462
537
|
| 15 | Checksum-pin backfill | `sources.json` entries all have `sha256` | No unpinned URL sources |
|
|
538
|
+
| 15a | Licensing gate | `npx bats tests/test_licensing.bats` | 7/7 — SPDX headers, LICENSE, NOTICE, npm `files`, manifest consistency |
|
|
463
539
|
| 16 | Tests | `git add -A kb/` if the KB changed, then `npm test` | All pass |
|
|
464
540
|
| 17 | Commit | `git commit` | Clean working tree |
|
|
465
541
|
| 18 | Tag | `git tag vX.Y.Z` | Tag exists |
|
|
466
|
-
|
|
|
542
|
+
| 18a | Tag is on HEAD | `test "$(git rev-parse vX.Y.Z)" = "$(git rev-parse HEAD)"` | Exit 0 |
|
|
543
|
+
| 18b | Tag is on the release commit | `git show --no-patch --format=%s vX.Y.Z` | Reads `chore: release vX.Y.Z` |
|
|
544
|
+
| 19 | Push branch, then the single tag | `git push origin main && git push origin refs/tags/vX.Y.Z` | CI triggered with `id-token: write`. Never `--tags`. |
|
|
@@ -24,6 +24,6 @@ description: "Feature comparison of ai-toolkit vs other Claude Code toolkits and
|
|
|
24
24
|
| Session persistence | Yes | Yes | No | No |
|
|
25
25
|
| Architecture notes | **Yes** | No | No | No |
|
|
26
26
|
| KB/RAG integration | **Yes** | No | No | Yes |
|
|
27
|
-
| License |
|
|
27
|
+
| License | **Apache-2.0** (NOTICE attribution, change notices, patent grant) | MIT | MIT | MIT |
|
|
28
28
|
|
|
29
29
|
For live benchmark data, see the [ecosystem benchmark snapshot](claude-ecosystem-benchmark-snapshot.md).
|
|
@@ -137,7 +137,7 @@ Base configs can define non-overridable constraints via the `enforce` block:
|
|
|
137
137
|
{
|
|
138
138
|
"enforce": {
|
|
139
139
|
"minHookProfile": "standard",
|
|
140
|
-
"requiredPlugins": ["
|
|
140
|
+
"requiredPlugins": ["memory-pack"],
|
|
141
141
|
"forbidOverride": ["constitution", "guard-destructive"],
|
|
142
142
|
"requiredAgents": ["security-auditor"]
|
|
143
143
|
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Licensing"
|
|
3
|
+
category: reference
|
|
4
|
+
service: ai-toolkit
|
|
5
|
+
tags: [licence, apache-2.0, spdx, notice, attribution, headers, mit]
|
|
6
|
+
version: "1.0.0"
|
|
7
|
+
created: "2026-07-27"
|
|
8
|
+
last_updated: "2026-07-27"
|
|
9
|
+
description: "ai-toolkit is Apache-2.0 from v4.20.0. What that obliges a redistributor to do, why NOTICE is the point, the SPDX header convention and which files deliberately do not get one, how MIT-era contributions are handled, and the CI gate that enforces all of it."
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Licensing
|
|
13
|
+
|
|
14
|
+
ai-toolkit is licensed under the **Apache License 2.0** from v4.20.0. Releases up
|
|
15
|
+
to and including v4.20.0 were published under MIT and remain available under MIT.
|
|
16
|
+
The change applies going forward and revokes nothing already granted.
|
|
17
|
+
|
|
18
|
+
Canonical files: [`LICENSE`](../../LICENSE) (verbatim Apache-2.0 text) and
|
|
19
|
+
[`NOTICE`](../../NOTICE) (attribution).
|
|
20
|
+
|
|
21
|
+
## Why Apache-2.0, given MIT already required attribution
|
|
22
|
+
|
|
23
|
+
This is the part most often got wrong. MIT already says:
|
|
24
|
+
|
|
25
|
+
> The above copyright notice and this permission notice shall be included in all
|
|
26
|
+
> copies or substantial portions of the Software.
|
|
27
|
+
|
|
28
|
+
So attribution was never the new thing. What Apache-2.0 adds:
|
|
29
|
+
|
|
30
|
+
| Mechanism | MIT | Apache-2.0 |
|
|
31
|
+
|---|---|---|
|
|
32
|
+
| Copyright notice must be preserved | yes | yes |
|
|
33
|
+
| **`NOTICE` contents must travel into redistributions** (§4d) | — | **yes** |
|
|
34
|
+
| **Modified files must carry a notice saying they changed** (§4b) | — | **yes** |
|
|
35
|
+
| Express patent grant, terminated by patent litigation (§3) | — | yes |
|
|
36
|
+
| No rights to the licensor's names or marks (§6) | — | yes |
|
|
37
|
+
|
|
38
|
+
**`NOTICE` is the reason for the change.** It is the only mechanism in a
|
|
39
|
+
permissive licence that forces a redistributor to reproduce your attribution —
|
|
40
|
+
project name, copyright, source URL — somewhere their users can see it. Without
|
|
41
|
+
it, MIT and Apache-2.0 are close to equivalent in practice.
|
|
42
|
+
|
|
43
|
+
Consequence for packaging: `NOTICE` is listed in `package.json` `files`. A NOTICE
|
|
44
|
+
that does not reach the consumer cannot satisfy §4(d), so that entry is a
|
|
45
|
+
licensing requirement, not housekeeping, and is asserted in CI.
|
|
46
|
+
|
|
47
|
+
## What a fork owes
|
|
48
|
+
|
|
49
|
+
Fork it, modify it, ship it commercially. Three obligations:
|
|
50
|
+
|
|
51
|
+
1. **Carry the `NOTICE`** into your distribution (§4d).
|
|
52
|
+
2. **Say which files you changed** (§4b).
|
|
53
|
+
3. **Do not use the "ai-toolkit" or "SoftSpark" names or marks** as if endorsed (§6).
|
|
54
|
+
|
|
55
|
+
## Source header convention
|
|
56
|
+
|
|
57
|
+
Short SPDX form, three lines, always **after** the shebang — an interpreter
|
|
58
|
+
directive must stay on line 1 — and after a Python `coding:` line if present:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
#!/usr/bin/env bash
|
|
62
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
63
|
+
# Copyright 2024-2026 Lukasz Krzemien (biuro@softspark.eu)
|
|
64
|
+
# Source: https://github.com/softspark/ai-toolkit
|
|
65
|
+
#
|
|
66
|
+
# guard-path.sh — the file's own description continues here.
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
`//` for JavaScript. SPDX was chosen over the 13-line Apache APPENDIX boilerplate
|
|
70
|
+
because it is machine-readable — licence scanners, GitHub and SBOM tooling parse
|
|
71
|
+
it — and because 13 lines on top of every source file buries the description that a
|
|
72
|
+
reader of a hook actually needs.
|
|
73
|
+
|
|
74
|
+
### Which files get a header
|
|
75
|
+
|
|
76
|
+
| Included | Count |
|
|
77
|
+
|---|---:|
|
|
78
|
+
| `scripts/**/*.py` | 109 |
|
|
79
|
+
| `tests/*.bats` | 77 |
|
|
80
|
+
| `app/hooks/*.sh` | 32 |
|
|
81
|
+
| `app/skills/**/*.py`, `**/*.js` | 27 |
|
|
82
|
+
| `app/plugins/**/*.sh`, `**/*.py` | 6 |
|
|
83
|
+
| `bin/*.js`, `benchmarks/**/*.py` | 2 |
|
|
84
|
+
| **total** | **253** |
|
|
85
|
+
|
|
86
|
+
These are a snapshot, not a contract — the CI gate checks that *every* matching
|
|
87
|
+
file has a header, so the count moves with the codebase and nothing needs
|
|
88
|
+
updating here when it does.
|
|
89
|
+
|
|
90
|
+
### Which files deliberately do not, and why
|
|
91
|
+
|
|
92
|
+
**No markdown file carries a header.** Not `app/skills/*/SKILL.md`, not
|
|
93
|
+
`app/agents/*.md`, not `app/rules/`, not `kb/`. Two reasons, both concrete:
|
|
94
|
+
|
|
95
|
+
1. **Frontmatter.** Skill and agent files open with parsed YAML. A header above
|
|
96
|
+
it breaks parsing; a header below it is invisible where it matters.
|
|
97
|
+
2. **Token cost.** Skill and agent descriptions load into the system prompt of
|
|
98
|
+
every session — measured at 5,051 and 2,750 tokens respectively. A four-line
|
|
99
|
+
header across 108 skills and 45 agents would be a permanent per-session cost,
|
|
100
|
+
billed on every conversation forever, for a notice Apache only *recommends*.
|
|
101
|
+
`LICENSE` and `NOTICE` carry the full terms; the headers are a convenience.
|
|
102
|
+
|
|
103
|
+
This exclusion is asserted in CI, so a well-meant sweep of the header script over
|
|
104
|
+
`app/skills/` fails the build rather than silently taxing every session.
|
|
105
|
+
|
|
106
|
+
## MIT-era contributions
|
|
107
|
+
|
|
108
|
+
Contributions made while the project was MIT-licensed remain the copyright of
|
|
109
|
+
their authors and were received under MIT terms. Three contributors other than
|
|
110
|
+
the maintainer appear in the history.
|
|
111
|
+
|
|
112
|
+
MIT explicitly permits sublicensing, so those contributions are redistributed
|
|
113
|
+
here under Apache-2.0 **with the original MIT notice preserved verbatim** in
|
|
114
|
+
`NOTICE`, which is what MIT requires. This is standard practice for an MIT to
|
|
115
|
+
Apache-2.0 move and needs no contributor sign-off. A "clean" Apache-2.0 with no
|
|
116
|
+
MIT remnant would need each contributor's agreement.
|
|
117
|
+
|
|
118
|
+
*This is a description of what the project does, not legal advice.*
|
|
119
|
+
|
|
120
|
+
## Enforcement
|
|
121
|
+
|
|
122
|
+
`tests/test_licensing.bats`, seven assertions, run by `npm test` in CI:
|
|
123
|
+
|
|
124
|
+
- every shipped source file carries an SPDX header
|
|
125
|
+
- headers name Apache-2.0 and nothing else
|
|
126
|
+
- **no** markdown file carries a header
|
|
127
|
+
- `LICENSE` is the complete Apache 2.0 text, appendix included
|
|
128
|
+
- `NOTICE` carries attribution, the source URL, §4(d) and the MIT-era notice
|
|
129
|
+
- `LICENSE` and `NOTICE` both appear in `package.json` `files`
|
|
130
|
+
- every manifest declaring a licence declares Apache-2.0
|
|
131
|
+
|
|
132
|
+
It is a test rather than a checklist line on purpose. This project has two
|
|
133
|
+
same-day postmortems about SOPs that existed and were skipped; CI does not skip.
|
|
134
|
+
[Release Preparation](../procedures/release-preparation-sop.md) Phase 5c runs the
|
|
135
|
+
same gate before tagging so a failure surfaces before the tag, not after.
|
|
136
|
+
|
|
137
|
+
## If the licence ever changes again
|
|
138
|
+
|
|
139
|
+
Do not hand-type the licence text and do not paste a rendered copy — a
|
|
140
|
+
markdown-formatted licence is not the licence. Take it verbatim from a published
|
|
141
|
+
source, cross-verify against a second independent copy, and only then write
|
|
142
|
+
`LICENSE`. That is how the Apache-2.0 text in this repository was installed.
|
|
143
|
+
|
|
144
|
+
## Related
|
|
145
|
+
|
|
146
|
+
- [`LICENSE`](../../LICENSE), [`NOTICE`](../../NOTICE)
|
|
147
|
+
- [Release Preparation SOP](../procedures/release-preparation-sop.md) — Phase 5c
|
|
148
|
+
- [Distribution Model](distribution-model.md) — what ships and where
|
|
@@ -125,22 +125,30 @@ ai-toolkit plugin status --editor all # show installed packs with r
|
|
|
125
125
|
|
|
126
126
|
## Current Experimental Packs
|
|
127
127
|
|
|
128
|
-
| Pack | Domain |
|
|
129
|
-
|
|
130
|
-
| `
|
|
131
|
-
| `
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
128
|
+
| Pack | Domain | Owns | Installs (claude / codex) | Description |
|
|
129
|
+
|------|--------|------|---------------------------|-------------|
|
|
130
|
+
| `memory-pack` | memory | 2 hooks, 2 scripts, 1 skill | 4 / 4 files | SQLite persistent memory with FTS5 search |
|
|
131
|
+
| `enterprise-pack` | enterprise | 2 hooks | 2 / 2 files | Status-line and output-style overlays |
|
|
132
|
+
|
|
133
|
+
Both packs ship content in this repository. Neither fetches anything at install
|
|
134
|
+
time.
|
|
135
|
+
|
|
136
|
+
### The rule the table now enforces
|
|
137
|
+
|
|
138
|
+
**A pack must install files the core install does not.** `ai-toolkit install`
|
|
139
|
+
links every core skill and agent, so a manifest naming only core assets resolves
|
|
140
|
+
to nothing: `plugin install` reports `(0 file items)` and no file appears on
|
|
141
|
+
disk. This is not a subtle degradation — it is a complete no-op, identical on
|
|
142
|
+
every profile (`minimal`, `standard`, `strict`) and on both runtimes.
|
|
143
|
+
|
|
144
|
+
Nine packs were removed in v4.20.0 for failing this: `csharp`, `java`, `kotlin`,
|
|
145
|
+
`ruby`, `rust`, `swift`, `frontend`, `research`, `security`. Every one declared
|
|
146
|
+
only skills and agents that already ship in core, and eight of them owned nothing
|
|
147
|
+
but a `README.md`. Full measurement:
|
|
148
|
+
[`no-op-plugin-packs-removed-20260727.md`](../history/completed/no-op-plugin-packs-removed-20260727.md).
|
|
149
|
+
|
|
150
|
+
Before adding a pack, prove it does something: install core into a throwaway
|
|
151
|
+
`HOME`, install the pack, and check that the reported file count is above zero.
|
|
144
152
|
|
|
145
153
|
**A pack that downloads a binary has been tried once and retired.** `rtk-pack`
|
|
146
154
|
(v4.18.0, removed in v4.19.0) fetched a checksum-pinned artifact in
|