@mcptoolshop/ai-loadout 1.0.0 → 1.0.2

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/README.zh.md ADDED
@@ -0,0 +1,196 @@
1
+ <p align="center">
2
+ <a href="README.md">English</a> | <a href="README.zh.md">中文</a> | <a href="README.es.md">Español</a> | <a href="README.fr.md">Français</a> | <a href="README.hi.md">हिन्दी</a> | <a href="README.it.md">Italiano</a> | <a href="README.pt-BR.md">Português (BR)</a> | <a href="README.ja.md">日本語</a>
3
+ </p>
4
+
5
+ <p align="center">
6
+ <img src="logo.png" width="400" alt="ai-loadout">
7
+ </p>
8
+
9
+ <p align="center">
10
+ <a href="https://github.com/mcp-tool-shop-org/ai-loadout/actions/workflows/ci.yml"><img src="https://github.com/mcp-tool-shop-org/ai-loadout/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
11
+ <a href="https://www.npmjs.com/package/@mcptoolshop/ai-loadout"><img src="https://img.shields.io/npm/v/@mcptoolshop/ai-loadout" alt="npm"></a>
12
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT 许可证"></a>
13
+ </p>
14
+
15
+ 面向 AI 代理的上下文感知知识路由器。
16
+
17
+ `ai-loadout` 是一种调度表格式和匹配引擎,让 AI 代理能够为当前任务加载正确的知识。无需将所有内容都塞入上下文,你只需维护一个小型索引,按需加载有效负载。
18
+
19
+ 可以把它想象成游戏装备系统 — 在每次任务前为代理装备恰好需要的知识。
20
+
21
+ ## 安装
22
+
23
+ ```bash
24
+ npm install @mcptoolshop/ai-loadout
25
+ ```
26
+
27
+ ## 核心概念
28
+
29
+ ### 调度表
30
+
31
+ `LoadoutIndex` 是知识有效负载的结构化索引:
32
+
33
+ ```json
34
+ {
35
+ "version": "1.0.0",
36
+ "generated": "2026-03-06T12:00:00Z",
37
+ "entries": [
38
+ {
39
+ "id": "github-actions",
40
+ "path": ".rules/github-actions.md",
41
+ "keywords": ["ci", "workflow", "runner"],
42
+ "patterns": ["ci_pipeline"],
43
+ "priority": "domain",
44
+ "summary": "CI triggers, path gating, runner cost control",
45
+ "triggers": { "task": true, "plan": true, "edit": false },
46
+ "tokens_est": 680,
47
+ "lines": 56
48
+ }
49
+ ],
50
+ "budget": {
51
+ "always_loaded_est": 320,
52
+ "on_demand_total_est": 8100,
53
+ "avg_task_load_est": 520,
54
+ "avg_task_load_observed": null
55
+ }
56
+ }
57
+ ```
58
+
59
+ ### 优先级层级
60
+
61
+ | 层级 | 行为 | 示例 |
62
+ |------|------|------|
63
+ | `core` | 始终加载 | "绝不跳过测试来让 CI 通过" |
64
+ | `domain` | 当任务关键词匹配时加载 | 编辑 workflow 时的 CI 规则 |
65
+ | `manual` | 从不自动加载,仅限显式查找 | 罕见的平台问题 |
66
+
67
+ ### 有效负载 Frontmatter
68
+
69
+ 每个有效负载文件携带自己的路由元数据:
70
+
71
+ ```markdown
72
+ ---
73
+ id: github-actions
74
+ keywords: [ci, workflow, runner, dependabot]
75
+ patterns: [ci_pipeline]
76
+ priority: domain
77
+ triggers:
78
+ task: true
79
+ plan: true
80
+ edit: false
81
+ ---
82
+
83
+ # GitHub Actions Rules
84
+ CI minutes are finite...
85
+ ```
86
+
87
+ Frontmatter 是唯一的事实来源。索引从中派生。
88
+
89
+ ## API
90
+
91
+ ### `matchLoadout(task, index)`
92
+
93
+ 将任务描述与 loadout 索引进行匹配。返回应加载的条目,按匹配强度排序。
94
+
95
+ ```typescript
96
+ import { matchLoadout } from "@mcptoolshop/ai-loadout";
97
+
98
+ const results = matchLoadout("fix the CI workflow", index);
99
+ // [{ entry: { id: "github-actions", ... }, score: 0.67, matchedKeywords: ["ci", "workflow"] }]
100
+ ```
101
+
102
+ - core 条目始终包含(得分 1.0)
103
+ - manual 条目从不自动包含
104
+ - domain 条目按关键词重叠度 + 模式加分评分
105
+ - 结果按得分降序排列
106
+
107
+ ### `lookupEntry(id, index)`
108
+
109
+ 通过 ID 查找特定条目。用于 manual 条目或显式访问。
110
+
111
+ ```typescript
112
+ import { lookupEntry } from "@mcptoolshop/ai-loadout";
113
+
114
+ const entry = lookupEntry("github-actions", index);
115
+ ```
116
+
117
+ ### `parseFrontmatter(content)`
118
+
119
+ 从有效负载文件中解析类 YAML 格式的 frontmatter。
120
+
121
+ ```typescript
122
+ import { parseFrontmatter } from "@mcptoolshop/ai-loadout";
123
+
124
+ const { frontmatter, body } = parseFrontmatter(fileContent);
125
+ if (frontmatter) {
126
+ console.log(frontmatter.id, frontmatter.keywords);
127
+ }
128
+ ```
129
+
130
+ ### `serializeFrontmatter(fm)`
131
+
132
+ 将 `Frontmatter` 对象序列化回字符串。
133
+
134
+ ### `validateIndex(index)`
135
+
136
+ 验证 `LoadoutIndex` 的结构完整性。返回问题数组。
137
+
138
+ ```typescript
139
+ import { validateIndex } from "@mcptoolshop/ai-loadout";
140
+
141
+ const issues = validateIndex(index);
142
+ const errors = issues.filter(i => i.severity === "error");
143
+ if (errors.length > 0) {
144
+ console.error("Index has errors:", errors);
145
+ }
146
+ ```
147
+
148
+ 检查项:必填字段、唯一 ID、kebab-case 格式、摘要长度限制、domain 条目的关键词存在性、有效优先级、非负预算。
149
+
150
+ ### `estimateTokens(text)`
151
+
152
+ 估算文本的 token 数量。使用字符数/4 的启发式方法。
153
+
154
+ ```typescript
155
+ import { estimateTokens } from "@mcptoolshop/ai-loadout";
156
+
157
+ const tokens = estimateTokens(fileContent); // ~250
158
+ ```
159
+
160
+ ## 类型定义
161
+
162
+ ```typescript
163
+ import type {
164
+ LoadoutEntry,
165
+ LoadoutIndex,
166
+ Frontmatter,
167
+ MatchResult,
168
+ ValidationIssue,
169
+ Priority, // "core" | "domain" | "manual"
170
+ Triggers, // { task, plan, edit }
171
+ Budget,
172
+ } from "@mcptoolshop/ai-loadout";
173
+ ```
174
+
175
+ ## 使用者
176
+
177
+ - **[@mcptoolshop/claude-rules](https://github.com/mcp-tool-shop-org/claude-rules)** — Claude Code 的 CLAUDE.md 优化器。使用 ai-loadout 作为调度表和匹配引擎。
178
+
179
+ ## 安全性
180
+
181
+ 此包是一个纯数据库。它不访问文件系统、不发起网络请求、不收集遥测数据。所有 I/O 由使用者负责。
182
+
183
+ ### 威胁模型
184
+
185
+ | 威胁 | 缓解措施 |
186
+ |------|----------|
187
+ | 格式错误的 frontmatter 输入 | `parseFrontmatter()` 在无效输入时返回 `null` — 无异常、无 eval |
188
+ | 原型污染 | 手动解析器使用普通对象字面量,不对不可信的嵌套结构使用 `JSON.parse` |
189
+ | 包含错误数据的索引 | `validateIndex()` 在问题扩散前检测结构性问题 |
190
+ | Regex DoS | 无用户提供的正则表达式 — 模式作为纯字符串查找进行匹配 |
191
+
192
+ 完整安全策略请参阅 [SECURITY.md](SECURITY.md)。
193
+
194
+ ---
195
+
196
+ 由 [MCP Tool Shop](https://mcp-tool-shop.github.io/) 构建
package/SECURITY.md ADDED
@@ -0,0 +1,35 @@
1
+ # Security Policy
2
+
3
+ ## Attack Surface
4
+
5
+ `@mcptoolshop/ai-loadout` is a **pure data library**. It has:
6
+
7
+ - **No filesystem access** — does not read or write files
8
+ - **No network access** — makes no HTTP requests, opens no sockets
9
+ - **No code execution** — no `eval`, `Function()`, or dynamic imports
10
+ - **No telemetry** — collects and transmits nothing
11
+ - **No native dependencies** — pure TypeScript, zero production deps
12
+
13
+ All I/O is the consumer's responsibility. This package only transforms data structures in memory.
14
+
15
+ ## Input Validation
16
+
17
+ The `parseFrontmatter()` function processes untrusted text input. It uses simple string splitting — no YAML parser, no regex-based evaluation, no prototype pollution vectors.
18
+
19
+ The `validateIndex()` function checks structural integrity of index objects. It does not execute or interpret any field values.
20
+
21
+ ## Supported Versions
22
+
23
+ | Version | Supported |
24
+ |---------|-----------|
25
+ | 1.x | Yes |
26
+
27
+ ## Reporting a Vulnerability
28
+
29
+ If you discover a security issue, please email **64996768+mcp-tool-shop@users.noreply.github.com** with:
30
+
31
+ - Description of the vulnerability
32
+ - Steps to reproduce
33
+ - Impact assessment
34
+
35
+ We will respond within 7 days and aim to release a fix within 14 days for confirmed issues.
package/dist/types.d.ts CHANGED
@@ -45,6 +45,7 @@ export interface ValidationIssue {
45
45
  severity: IssueSeverity;
46
46
  code: string;
47
47
  message: string;
48
+ hint?: string;
48
49
  entryId?: string;
49
50
  }
50
51
  export declare const DEFAULT_TRIGGERS: Triggers;
package/dist/validate.js CHANGED
@@ -51,6 +51,7 @@ export function validateIndex(index) {
51
51
  severity: "error",
52
52
  code: "MISSING_ID",
53
53
  message: "Entry is missing an id field",
54
+ hint: "Every entry needs a unique kebab-case id",
54
55
  });
55
56
  continue;
56
57
  }
@@ -79,6 +80,7 @@ export function validateIndex(index) {
79
80
  severity: "error",
80
81
  code: "MISSING_PATH",
81
82
  message: `Entry "${entry.id}" has no path`,
83
+ hint: "Set path to the relative file location (e.g. .claude/rules/my-rule.md)",
82
84
  entryId: entry.id,
83
85
  });
84
86
  }
@@ -114,6 +116,7 @@ export function validateIndex(index) {
114
116
  severity: "error",
115
117
  code: "EMPTY_KEYWORDS",
116
118
  message: `Domain entry "${entry.id}" has no keywords — cannot be routed`,
119
+ hint: "Add keywords to frontmatter so the matcher can find this entry",
117
120
  entryId: entry.id,
118
121
  });
119
122
  }
package/logo.png ADDED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcptoolshop/ai-loadout",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Context-aware knowledge router for AI agents. Dispatch table, frontmatter spec, keyword matcher, token estimator.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -21,7 +21,9 @@
21
21
  "dist",
22
22
  "README.md",
23
23
  "CHANGELOG.md",
24
- "LICENSE"
24
+ "LICENSE",
25
+ "SECURITY.md",
26
+ "logo.png"
25
27
  ],
26
28
  "keywords": [
27
29
  "ai",