@mcptoolshop/promo-kit 0.1.1 → 0.1.3
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 +18 -0
- package/README.md +93 -40
- package/kit.config.example.json +4 -0
- package/package.json +1 -1
- package/scripts/kit-selftest.mjs +14 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.3 — 2026-02-16
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- Config template now includes `paths.dataDir` and `paths.publicDir` so path overrides are discoverable
|
|
8
|
+
- Selftest detects unknown keys in `paths` (e.g. `paths.data` → "did you mean `paths.dataDir`?")
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Dogfood pilot: trust receipt generated against own catalog repo (commit + SHA-256 hashes)
|
|
13
|
+
|
|
14
|
+
## 0.1.2 — 2026-02-16
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- Rewrite npm README for scannability (product-page layout, split seed/artifact tables, KIT_CONFIG example)
|
|
19
|
+
- Logo sized to 420px (was 200→300, still too small on npmjs.com)
|
|
20
|
+
|
|
3
21
|
## 0.1.1 — 2026-02-16
|
|
4
22
|
|
|
5
23
|
### Fixed
|
package/README.md
CHANGED
|
@@ -1,54 +1,80 @@
|
|
|
1
|
-
<
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/mcp-tool-shop/mcp-tool-shop/main/logo.png" width="420" alt="mcp-tool-shop logo" />
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
<
|
|
5
|
+
<h1 align="center">@mcptoolshop/promo-kit</h1>
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
<p align="center">
|
|
8
|
+
<b>Portable promotion engine for tool catalogs.</b><br/>
|
|
9
|
+
Receipt-backed promotions · freeze modes · drift detection · <b>zero dependencies</b>
|
|
10
|
+
</p>
|
|
6
11
|
|
|
7
|
-
|
|
12
|
+
<p align="center">
|
|
13
|
+
<a href="https://www.npmjs.com/package/@mcptoolshop/promo-kit"><img src="https://img.shields.io/npm/v/@mcptoolshop/promo-kit?style=flat-square&color=cb3837" alt="npm version" /></a>
|
|
14
|
+
<a href="https://github.com/mcp-tool-shop/mcp-tool-shop/releases"><img src="https://img.shields.io/github/v/release/mcp-tool-shop/mcp-tool-shop?style=flat-square&label=release" alt="GitHub release" /></a>
|
|
15
|
+
<a href="https://github.com/mcp-tool-shop/mcp-tool-shop/blob/main/packages/promo-kit/LICENSE"><img src="https://img.shields.io/npm/l/@mcptoolshop/promo-kit?style=flat-square" alt="license" /></a>
|
|
16
|
+
</p>
|
|
8
17
|
|
|
9
|
-
|
|
18
|
+
---
|
|
10
19
|
|
|
11
20
|
## What it does
|
|
12
21
|
|
|
13
|
-
`promo-kit` gives your tool catalog a complete promotion pipeline:
|
|
22
|
+
`promo-kit` gives your tool catalog a complete, governed promotion pipeline:
|
|
14
23
|
|
|
15
|
-
- **
|
|
16
|
-
- **
|
|
17
|
-
- **
|
|
18
|
-
- **
|
|
24
|
+
- **Bootstraps** a zero-state data model (governance, promo queue, experiments, submissions)
|
|
25
|
+
- **Generates** promotion decisions, baselines, drift reports, and trust receipts
|
|
26
|
+
- **Verifies inputs** with SHA-256 hashes (and ties outputs back to commits)
|
|
27
|
+
- **Supports freeze modes** when you need human review
|
|
28
|
+
- **Keeps data local** (no cloud services, no trackers, no runtime npm deps)
|
|
19
29
|
|
|
20
|
-
|
|
30
|
+
If your catalog needs "trust you can audit," this is the boring machinery that makes it real.
|
|
31
|
+
|
|
32
|
+
---
|
|
21
33
|
|
|
22
34
|
## Quickstart
|
|
23
35
|
|
|
36
|
+
Install:
|
|
37
|
+
|
|
24
38
|
```bash
|
|
25
|
-
npm
|
|
39
|
+
npm i @mcptoolshop/promo-kit
|
|
40
|
+
```
|
|
26
41
|
|
|
27
|
-
|
|
42
|
+
Initialize (creates `kit.config.json` from a template if missing, then seeds data):
|
|
43
|
+
|
|
44
|
+
```bash
|
|
28
45
|
npx promo-kit init
|
|
46
|
+
```
|
|
29
47
|
|
|
30
|
-
|
|
31
|
-
# org.name, org.account, site.title, contact.email
|
|
48
|
+
Edit `kit.config.json` (minimum):
|
|
32
49
|
|
|
33
|
-
|
|
50
|
+
- `org.name`
|
|
51
|
+
- `org.account`
|
|
52
|
+
- `site.title`
|
|
53
|
+
- `contact.email`
|
|
54
|
+
|
|
55
|
+
Validate the installation:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
34
58
|
npx promo-kit selftest
|
|
35
59
|
```
|
|
36
60
|
|
|
37
|
-
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## CLI
|
|
38
64
|
|
|
39
65
|
### `promo-kit init`
|
|
40
66
|
|
|
41
|
-
Creates `kit.config.json` (if absent) and bootstraps
|
|
67
|
+
Creates `kit.config.json` (if absent) and bootstraps seed files in your configured data directory.
|
|
42
68
|
|
|
43
69
|
```bash
|
|
44
|
-
promo-kit init
|
|
45
|
-
promo-kit init --dry-run
|
|
46
|
-
promo-kit init --force
|
|
70
|
+
promo-kit init
|
|
71
|
+
promo-kit init --dry-run
|
|
72
|
+
promo-kit init --force
|
|
47
73
|
```
|
|
48
74
|
|
|
49
75
|
### `promo-kit selftest`
|
|
50
76
|
|
|
51
|
-
Validates config
|
|
77
|
+
Validates config + seeds and runs the portable core generators in dry-run mode.
|
|
52
78
|
|
|
53
79
|
```bash
|
|
54
80
|
promo-kit selftest
|
|
@@ -56,7 +82,7 @@ promo-kit selftest
|
|
|
56
82
|
|
|
57
83
|
### `promo-kit migrate`
|
|
58
84
|
|
|
59
|
-
Applies schema
|
|
85
|
+
Applies schema upgrades when `kitVersion` changes.
|
|
60
86
|
|
|
61
87
|
```bash
|
|
62
88
|
promo-kit migrate
|
|
@@ -65,25 +91,33 @@ promo-kit migrate
|
|
|
65
91
|
### Flags
|
|
66
92
|
|
|
67
93
|
```bash
|
|
68
|
-
promo-kit --version
|
|
69
|
-
promo-kit --help
|
|
70
|
-
promo-kit --print-config
|
|
94
|
+
promo-kit --version
|
|
95
|
+
promo-kit --help
|
|
96
|
+
promo-kit --print-config
|
|
71
97
|
```
|
|
72
98
|
|
|
99
|
+
---
|
|
100
|
+
|
|
73
101
|
## Programmatic API
|
|
74
102
|
|
|
75
103
|
```js
|
|
76
|
-
import {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
104
|
+
import {
|
|
105
|
+
bootstrap,
|
|
106
|
+
migrate,
|
|
107
|
+
getConfig,
|
|
108
|
+
getRoot,
|
|
109
|
+
loadKitConfig
|
|
110
|
+
} from "@mcptoolshop/promo-kit";
|
|
111
|
+
|
|
112
|
+
// Create seed files (idempotent)
|
|
113
|
+
const result = bootstrap("/path/to/project");
|
|
80
114
|
// => { success: true, errors: [], created: [...], skipped: [...] }
|
|
81
115
|
|
|
82
|
-
//
|
|
116
|
+
// Read resolved config (deep-merged with defaults)
|
|
83
117
|
const config = getConfig();
|
|
84
118
|
|
|
85
|
-
//
|
|
86
|
-
const migrationResult = migrate("/path/to/
|
|
119
|
+
// Apply migrations (if needed)
|
|
120
|
+
const migrationResult = migrate("/path/to/project");
|
|
87
121
|
```
|
|
88
122
|
|
|
89
123
|
Config utilities are also available as a separate export:
|
|
@@ -92,36 +126,55 @@ Config utilities are also available as a separate export:
|
|
|
92
126
|
import { getConfig, getRoot } from "@mcptoolshop/promo-kit/config";
|
|
93
127
|
```
|
|
94
128
|
|
|
129
|
+
---
|
|
130
|
+
|
|
95
131
|
## What it generates
|
|
96
132
|
|
|
97
|
-
`promo-kit init` creates
|
|
133
|
+
By default, `promo-kit init` creates a set of seed files in your configured data directory.
|
|
134
|
+
|
|
135
|
+
**Core seeds:**
|
|
98
136
|
|
|
99
137
|
| File | Purpose |
|
|
100
138
|
|------|---------|
|
|
101
|
-
| `governance.json` | Freeze modes,
|
|
139
|
+
| `governance.json` | Freeze modes, caps, hard rules |
|
|
102
140
|
| `promo-queue.json` | Weekly promotion candidates |
|
|
103
|
-
| `experiments.json` | Active
|
|
141
|
+
| `experiments.json` | Active experiments |
|
|
104
142
|
| `submissions.json` | External tool submissions |
|
|
105
143
|
| `overrides.json` | Per-tool metadata overrides |
|
|
106
144
|
| `ops-history.json` | Workflow run history |
|
|
107
145
|
| `feedback.jsonl` | Append-only feedback log |
|
|
108
146
|
| `worthy.json` | Worthiness rubric and scores |
|
|
147
|
+
|
|
148
|
+
**Generated artifacts** (produced by the pipeline):
|
|
149
|
+
|
|
150
|
+
| File | Purpose |
|
|
151
|
+
|------|---------|
|
|
109
152
|
| `promo-decisions.json` | Generated promotion decisions |
|
|
110
153
|
| `experiment-decisions.json` | Generated experiment decisions |
|
|
111
154
|
| `baseline.json` | Computed baseline metrics |
|
|
112
155
|
| `feedback-summary.json` | Aggregated feedback |
|
|
113
156
|
| `queue-health.json` | Queue health metrics |
|
|
114
157
|
| `recommendations.json` | Advisory recommendations |
|
|
115
|
-
| `recommendation-patch.json` | Recommended data patches |
|
|
158
|
+
| `recommendation-patch.json` | Recommended governed data patches |
|
|
116
159
|
| `decision-drift.json` | Week-over-week drift report |
|
|
117
160
|
| `telemetry/rollup.json` | Telemetry aggregates |
|
|
118
161
|
|
|
162
|
+
---
|
|
163
|
+
|
|
119
164
|
## Environment
|
|
120
165
|
|
|
121
166
|
| Variable | Purpose |
|
|
122
167
|
|----------|---------|
|
|
123
168
|
| `KIT_CONFIG` | Path to an alternate `kit.config.json` (overrides cwd discovery) |
|
|
124
169
|
|
|
170
|
+
Example:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
KIT_CONFIG=examples/pilot-org/kit.config.json npx promo-kit selftest
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
125
178
|
## Requirements
|
|
126
179
|
|
|
127
180
|
- Node.js >= 22
|
|
@@ -129,9 +182,9 @@ import { getConfig, getRoot } from "@mcptoolshop/promo-kit/config";
|
|
|
129
182
|
|
|
130
183
|
## Links
|
|
131
184
|
|
|
132
|
-
- [Portable Core docs](https://github.com/mcp-tool-shop/mcp-tool-shop/blob/main/docs/portable-core.md) —
|
|
133
|
-
- [Presskit Handbook](https://github.com/mcp-tool-shop/mcp-tool-shop/blob/main/docs/presskit-handbook.md) —
|
|
134
|
-
- [Trust Center](https://mcp-tool-shop.github.io/trust/) — live verification
|
|
185
|
+
- [Portable Core docs](https://github.com/mcp-tool-shop/mcp-tool-shop/blob/main/docs/portable-core.md) — contract + field reference
|
|
186
|
+
- [Presskit Handbook](https://github.com/mcp-tool-shop/mcp-tool-shop/blob/main/docs/presskit-handbook.md) — assets + verification walkthrough
|
|
187
|
+
- [Trust Center](https://mcp-tool-shop.github.io/trust/) — live example of the verification UX
|
|
135
188
|
|
|
136
189
|
## License
|
|
137
190
|
|
package/kit.config.example.json
CHANGED
package/package.json
CHANGED
package/scripts/kit-selftest.mjs
CHANGED
|
@@ -78,6 +78,20 @@ check("kit.config.json is valid JSON with required fields", () => {
|
|
|
78
78
|
assert(config.paths?.publicDir, "paths.publicDir missing");
|
|
79
79
|
});
|
|
80
80
|
|
|
81
|
+
// Warn about unknown keys in paths (common misconfiguration)
|
|
82
|
+
check("no unknown keys in paths", () => {
|
|
83
|
+
const knownPathKeys = new Set(["dataDir", "publicDir"]);
|
|
84
|
+
const unknownKeys = Object.keys(config.paths || {}).filter((k) => !knownPathKeys.has(k));
|
|
85
|
+
if (unknownKeys.length > 0) {
|
|
86
|
+
const hints = unknownKeys.map((k) => {
|
|
87
|
+
if (k === "data") return `"paths.data" → did you mean "paths.dataDir"?`;
|
|
88
|
+
if (k === "public") return `"paths.public" → did you mean "paths.publicDir"?`;
|
|
89
|
+
return `"paths.${k}" is not a recognized field`;
|
|
90
|
+
});
|
|
91
|
+
throw new Error(`Unknown paths keys: ${hints.join("; ")}`);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
|
|
81
95
|
check("kitVersion in supported range", () => {
|
|
82
96
|
const v = config.kitVersion;
|
|
83
97
|
assert(
|