@meyverick/agentic 5.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/AGENTS.md +234 -0
- package/CHANGELOG.md +236 -0
- package/README.md +50 -0
- package/install.ts +349 -0
- package/package.json +37 -0
- package/scripts/check-deps.mjs +587 -0
- package/scripts/git-dl.mjs +100 -0
- package/skills/check/SKILL.md +108 -0
- package/skills/check/evals/benchmark.json +40 -0
- package/skills/check/evals/evals.json +38 -0
- package/skills/check/references/diagnostic-matrix.md +170 -0
- package/skills/check/references/script-anatomy.md +154 -0
- package/skills/create-skill/SKILL.md +291 -0
- package/skills/create-skill/assets/templates/SKILL.md.template +118 -0
- package/skills/create-skill/assets/templates/evals.json.template +36 -0
- package/skills/create-skill/assets/templates/grading.json.template +26 -0
- package/skills/create-skill/evals/benchmark.json +41 -0
- package/skills/create-skill/evals/evals.json +50 -0
- package/skills/create-skill/evals/grading-template.json +36 -0
- package/skills/create-skill/evals/near-misses.json +35 -0
- package/skills/create-skill/evals/trigger-queries.json +80 -0
- package/skills/create-skill/references/antipatterns.md +123 -0
- package/skills/create-skill/references/component-decomposition.md +130 -0
- package/skills/create-skill/references/content-quality-criteria.md +61 -0
- package/skills/create-skill/references/description-optimization.md +90 -0
- package/skills/create-skill/references/eval-methodology.md +100 -0
- package/skills/create-skill/references/fragility-matching.md +88 -0
- package/skills/create-skill/references/gotchas-patterns.md +80 -0
- package/skills/create-skill/references/specification.md +77 -0
- package/skills/create-skill/scripts/audit-antipatterns.mjs +164 -0
- package/skills/create-skill/scripts/compute-benchmark.mjs +111 -0
- package/skills/create-skill/scripts/run-cold-eval.mjs +118 -0
- package/skills/create-skill/scripts/scaffold-skill.mjs +86 -0
- package/skills/create-skill/scripts/validate-routing.mjs +137 -0
- package/skills/create-skill/scripts/validate-structure.mjs +223 -0
- package/skills/design-craft/SKILL.md +134 -0
- package/skills/design-craft/evals/benchmark.json +41 -0
- package/skills/design-craft/evals/evals.json +81 -0
- package/skills/design-craft/references/anti-slop-patterns.md +49 -0
- package/skills/design-craft/references/art-direction.md +89 -0
- package/skills/design-craft/references/design-engineering.md +122 -0
- package/skills/design-craft/references/motion-craft.md +124 -0
- package/skills/design-craft/references/process.md +47 -0
- package/skills/design-craft/references/review-checklist.md +121 -0
- package/skills/guardrails/SKILL.md +118 -0
- package/skills/guardrails/evals/benchmark.json +40 -0
- package/skills/guardrails/evals/evals.json +49 -0
- package/skills/guardrails/references/guardrails-patterns.md +43 -0
- package/skills/okf-docs/SKILL.md +79 -0
- package/skills/okf-docs/evals/benchmark.json +21 -0
- package/skills/okf-docs/evals/evals.json +37 -0
- package/skills/okf-docs/references/okf-spec.md +56 -0
- package/skills/okf-docs/scripts/validate-frontmatter.mjs +130 -0
- package/skills/openspec-harden/SKILL.md +138 -0
- package/skills/openspec-harden/evals/benchmark.json +40 -0
- package/skills/openspec-harden/evals/evals.json +38 -0
- package/skills/openspec-learn/SKILL.md +216 -0
- package/skills/openspec-learn/evals/benchmark.json +44 -0
- package/skills/openspec-learn/evals/evals.json +48 -0
- package/skills/openspec-learn/evals/retrieval-bench.json +27 -0
- package/skills/openspec-learn/references/conflict-handling.md +20 -0
- package/skills/openspec-learn/references/evaluation-methodology.md +126 -0
- package/skills/openspec-learn/references/examples.md +37 -0
- package/skills/openspec-learn/references/improvement-patterns.md +155 -0
- package/skills/openspec-learn/references/report-analysis.md +104 -0
- package/skills/openspec-learn/references/skill-quality.md +103 -0
- package/skills/openspec-learn/references/tool-type-detection.md +30 -0
- package/skills/openspec-report/SKILL.md +104 -0
- package/skills/openspec-report/assets/templates/assessment.md.template +84 -0
- package/skills/openspec-report/assets/templates/report.md.template +92 -0
- package/skills/openspec-report/evals/benchmark.json +44 -0
- package/skills/openspec-report/evals/evals.json +46 -0
- package/skills/qmd-research/SKILL.md +89 -0
- package/skills/qmd-research/evals/benchmark.json +40 -0
- package/skills/qmd-research/evals/evals.json +38 -0
- package/skills/qmd-research/references/index-management.md +69 -0
- package/skills/qmd-research/references/query-craft.md +82 -0
package/install.ts
ADDED
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* install.ts - Install agentic skills, scripts, and AGENTS.md
|
|
4
|
+
*
|
|
5
|
+
* Usage: bunx @meyverick/agentic
|
|
6
|
+
* (or: bunx github:meyverick/agentic)
|
|
7
|
+
*
|
|
8
|
+
* Installs to current directory:
|
|
9
|
+
* - project/skills/* → .agents/skills/ (atomic replacement)
|
|
10
|
+
* - project/scripts/* → scripts/ (diff-based)
|
|
11
|
+
* - project/AGENTS.md → AGENTS.md
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import fs from 'fs';
|
|
15
|
+
import path from 'path';
|
|
16
|
+
import { fileURLToPath } from 'url';
|
|
17
|
+
|
|
18
|
+
// Source directory (where this script lives)
|
|
19
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
20
|
+
const __dirname = path.dirname(__filename);
|
|
21
|
+
|
|
22
|
+
// Try to find the source directory
|
|
23
|
+
function findSourceDir(): string {
|
|
24
|
+
if (fs.existsSync(path.join(__dirname, 'skills'))) {
|
|
25
|
+
return __dirname;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const parentDir = path.dirname(__dirname);
|
|
29
|
+
if (fs.existsSync(path.join(parentDir, 'skills'))) {
|
|
30
|
+
return parentDir;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const scopedNodeModules = path.join(__dirname, 'node_modules', '@meyverick', 'agentic');
|
|
34
|
+
if (fs.existsSync(scopedNodeModules) && fs.existsSync(path.join(scopedNodeModules, 'skills'))) {
|
|
35
|
+
return scopedNodeModules;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const parentScopedNodeModules = path.join(parentDir, 'node_modules', '@meyverick', 'agentic');
|
|
39
|
+
if (fs.existsSync(parentScopedNodeModules) && fs.existsSync(path.join(parentScopedNodeModules, 'skills'))) {
|
|
40
|
+
return parentScopedNodeModules;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const nodeModulesPath = path.join(__dirname, 'node_modules', 'agentic');
|
|
44
|
+
if (fs.existsSync(nodeModulesPath) && fs.existsSync(path.join(nodeModulesPath, 'skills'))) {
|
|
45
|
+
return nodeModulesPath;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const parentNodeModules = path.join(parentDir, 'node_modules', 'agentic');
|
|
49
|
+
if (fs.existsSync(parentNodeModules) && fs.existsSync(path.join(parentNodeModules, 'skills'))) {
|
|
50
|
+
return parentNodeModules;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return __dirname;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const srcDir = findSourceDir();
|
|
57
|
+
const targetDir = process.cwd();
|
|
58
|
+
|
|
59
|
+
// Track stats
|
|
60
|
+
let copied = 0;
|
|
61
|
+
let skipped = 0;
|
|
62
|
+
let replaced = 0;
|
|
63
|
+
let created = 0;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Get all files in directory recursively
|
|
67
|
+
*/
|
|
68
|
+
function getAllFiles(dir: string): string[] {
|
|
69
|
+
const files: string[] = [];
|
|
70
|
+
if (!fs.existsSync(dir)) return files;
|
|
71
|
+
|
|
72
|
+
const items = fs.readdirSync(dir);
|
|
73
|
+
for (const item of items) {
|
|
74
|
+
const itemPath = path.join(dir, item);
|
|
75
|
+
const stat = fs.statSync(itemPath);
|
|
76
|
+
if (stat.isDirectory()) {
|
|
77
|
+
files.push(...getAllFiles(itemPath).map(f => path.join(item, f)));
|
|
78
|
+
} else {
|
|
79
|
+
files.push(item);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return files;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Compare two directories - return true if ANY file differs
|
|
87
|
+
*/
|
|
88
|
+
function hasDifferences(srcDir: string, dstDir: string): boolean {
|
|
89
|
+
if (!fs.existsSync(dstDir)) return true;
|
|
90
|
+
|
|
91
|
+
const srcFiles = getAllFiles(srcDir);
|
|
92
|
+
const dstFiles = getAllFiles(dstDir);
|
|
93
|
+
|
|
94
|
+
// Different number of files = different
|
|
95
|
+
if (srcFiles.length !== dstFiles.length) return true;
|
|
96
|
+
|
|
97
|
+
// Check each file
|
|
98
|
+
for (const file of srcFiles) {
|
|
99
|
+
const srcPath = path.join(srcDir, file);
|
|
100
|
+
const dstPath = path.join(dstDir, file);
|
|
101
|
+
|
|
102
|
+
if (!fs.existsSync(dstPath)) return true;
|
|
103
|
+
|
|
104
|
+
const srcContent = fs.readFileSync(srcPath);
|
|
105
|
+
const dstContent = fs.readFileSync(dstPath);
|
|
106
|
+
|
|
107
|
+
if (!srcContent.equals(dstContent)) return true;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return false; // No differences
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Replace entire skill directory (atomic)
|
|
115
|
+
*/
|
|
116
|
+
function replaceSkill(srcDir: string, dstDir: string): void {
|
|
117
|
+
// Remove existing directory
|
|
118
|
+
if (fs.existsSync(dstDir)) {
|
|
119
|
+
fs.rmSync(dstDir, { recursive: true, force: true });
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Copy entire directory
|
|
123
|
+
fs.cpSync(srcDir, dstDir, { recursive: true });
|
|
124
|
+
replaced++;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Diff-based copy for single files (prompts, AGENTS.md)
|
|
129
|
+
*/
|
|
130
|
+
function syncFile(src: string, dst: string): boolean {
|
|
131
|
+
const dstDir = path.dirname(dst);
|
|
132
|
+
|
|
133
|
+
if (!fs.existsSync(dstDir)) {
|
|
134
|
+
fs.mkdirSync(dstDir, { recursive: true });
|
|
135
|
+
created++;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (fs.existsSync(dst)) {
|
|
139
|
+
const srcContent = fs.readFileSync(src);
|
|
140
|
+
const dstContent = fs.readFileSync(dst);
|
|
141
|
+
|
|
142
|
+
if (srcContent.equals(dstContent)) {
|
|
143
|
+
skipped++;
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
fs.copyFileSync(src, dst);
|
|
149
|
+
copied++;
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Install skills atomically
|
|
155
|
+
*/
|
|
156
|
+
function installSkills(): void {
|
|
157
|
+
const skillsSrc = path.join(srcDir, 'skills');
|
|
158
|
+
const skillsDst = path.join(targetDir, '.agents', 'skills');
|
|
159
|
+
|
|
160
|
+
console.log('📦 Skills:');
|
|
161
|
+
|
|
162
|
+
if (!fs.existsSync(skillsSrc)) {
|
|
163
|
+
console.log(' ⚠️ Source not found');
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Ensure target directory exists
|
|
168
|
+
if (!fs.existsSync(skillsDst)) {
|
|
169
|
+
fs.mkdirSync(skillsDst, { recursive: true });
|
|
170
|
+
created++;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Get all skills from source (directories only — dotfiles like
|
|
174
|
+
// .agentic-manifest.json / .ownership.json are files and never match)
|
|
175
|
+
const skills = fs.readdirSync(skillsSrc).filter(item => {
|
|
176
|
+
const itemPath = path.join(skillsSrc, item);
|
|
177
|
+
return fs.statSync(itemPath).isDirectory();
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
for (const skill of skills) {
|
|
181
|
+
const srcPath = path.join(skillsSrc, skill);
|
|
182
|
+
const dstPath = path.join(skillsDst, skill);
|
|
183
|
+
|
|
184
|
+
if (!fs.existsSync(dstPath)) {
|
|
185
|
+
// New skill - copy entirely
|
|
186
|
+
fs.cpSync(srcPath, dstPath, { recursive: true });
|
|
187
|
+
copied++;
|
|
188
|
+
console.log(` + ${skill} (new)`);
|
|
189
|
+
} else if (hasDifferences(srcPath, dstPath)) {
|
|
190
|
+
// Skill changed - replace entirely
|
|
191
|
+
// Drift warning: existing content differs from what we ship.
|
|
192
|
+
// Atomic replacement overwrites ANY local modifications.
|
|
193
|
+
console.log(` ⚠️ ${skill}: local modifications will be overwritten`);
|
|
194
|
+
replaceSkill(srcPath, dstPath);
|
|
195
|
+
console.log(` ~ ${skill} (replaced)`);
|
|
196
|
+
} else {
|
|
197
|
+
// No changes - skip
|
|
198
|
+
skipped++;
|
|
199
|
+
console.log(` = ${skill} (unchanged)`);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
console.log(`\n → ${skillsDst}`);
|
|
204
|
+
console.log(` Copied: ${copied} | Replaced: ${replaced} | Skipped: ${skipped}\n`);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Install scripts (diff-based with executable permissions)
|
|
209
|
+
*/
|
|
210
|
+
function installScripts(): void {
|
|
211
|
+
const scriptsSrc = path.join(srcDir, 'scripts');
|
|
212
|
+
const scriptsDst = path.join(targetDir, 'scripts');
|
|
213
|
+
|
|
214
|
+
console.log('📜 Scripts:');
|
|
215
|
+
|
|
216
|
+
if (!fs.existsSync(scriptsSrc)) {
|
|
217
|
+
console.log(' ⚠️ Not found\n');
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
copied = 0;
|
|
222
|
+
skipped = 0;
|
|
223
|
+
|
|
224
|
+
const scriptFiles = fs.readdirSync(scriptsSrc).filter(item => {
|
|
225
|
+
return fs.statSync(path.join(scriptsSrc, item)).isFile();
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
for (const file of scriptFiles) {
|
|
229
|
+
const srcPath = path.join(scriptsSrc, file);
|
|
230
|
+
const dstPath = path.join(scriptsDst, file);
|
|
231
|
+
|
|
232
|
+
const changed = syncFile(srcPath, dstPath);
|
|
233
|
+
try {
|
|
234
|
+
fs.chmodSync(dstPath, 0o755);
|
|
235
|
+
} catch (_) {}
|
|
236
|
+
|
|
237
|
+
if (changed) {
|
|
238
|
+
console.log(` + ${file}`);
|
|
239
|
+
} else {
|
|
240
|
+
console.log(` = ${file} (unchanged)`);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
console.log(`\n → ${scriptsDst}`);
|
|
245
|
+
console.log(` Copied: ${copied} | Skipped: ${skipped}\n`);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Install AGENTS.md (diff-based)
|
|
250
|
+
*/
|
|
251
|
+
function installAgentsMd(): void {
|
|
252
|
+
const agentsSrc = path.join(srcDir, 'AGENTS.md');
|
|
253
|
+
const agentsDst = path.join(targetDir, 'AGENTS.md');
|
|
254
|
+
|
|
255
|
+
console.log('📋 AGENTS.md:');
|
|
256
|
+
|
|
257
|
+
if (fs.existsSync(agentsSrc)) {
|
|
258
|
+
copied = 0;
|
|
259
|
+
skipped = 0;
|
|
260
|
+
syncFile(agentsSrc, agentsDst);
|
|
261
|
+
console.log(` → ${agentsDst}`);
|
|
262
|
+
console.log(` Copied: ${copied} | Skipped: ${skipped}\n`);
|
|
263
|
+
} else {
|
|
264
|
+
console.log(' ⚠️ Not found\n');
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Create openspec/reports/ directory
|
|
270
|
+
*/
|
|
271
|
+
function createReportsDir(): void {
|
|
272
|
+
const reportsDst = path.join(targetDir, 'openspec', 'reports');
|
|
273
|
+
console.log('📂 Reports directory:');
|
|
274
|
+
|
|
275
|
+
if (!fs.existsSync(reportsDst)) {
|
|
276
|
+
fs.mkdirSync(reportsDst, { recursive: true });
|
|
277
|
+
console.log(` → Created ${reportsDst}\n`);
|
|
278
|
+
} else {
|
|
279
|
+
console.log(` → ${reportsDst} (exists)\n`);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Write provenance manifest (.agents/skills/.agentic-manifest.json)
|
|
285
|
+
*
|
|
286
|
+
* Records what this installer owns so consuming-project agents can
|
|
287
|
+
* classify skill ownership without inference (ownership input). Consumer
|
|
288
|
+
* agents treat installed skills as read-only (never edit .agents/skills/*
|
|
289
|
+
* in place; reroute upstream or to project-local homes). Source skills
|
|
290
|
+
* in project/skills/* are owned and editable only by the project owner
|
|
291
|
+
* and trusted session. NEVER touches .ownership.json (user-owned adjudications).
|
|
292
|
+
*/
|
|
293
|
+
function writeProvenanceManifest(version: string): void {
|
|
294
|
+
const skillsDst = path.join(targetDir, '.agents', 'skills');
|
|
295
|
+
if (!fs.existsSync(skillsDst)) {
|
|
296
|
+
fs.mkdirSync(skillsDst, { recursive: true });
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const skillsSrc = path.join(srcDir, 'skills');
|
|
300
|
+
const scriptsSrc = path.join(srcDir, 'scripts');
|
|
301
|
+
|
|
302
|
+
const skills = fs.existsSync(skillsSrc)
|
|
303
|
+
? fs.readdirSync(skillsSrc).filter(item => fs.statSync(path.join(skillsSrc, item)).isDirectory())
|
|
304
|
+
: [];
|
|
305
|
+
|
|
306
|
+
const scripts = fs.existsSync(scriptsSrc)
|
|
307
|
+
? fs.readdirSync(scriptsSrc).filter(item => fs.statSync(path.join(scriptsSrc, item)).isFile())
|
|
308
|
+
: [];
|
|
309
|
+
|
|
310
|
+
const manifest = {
|
|
311
|
+
installed_by: 'agentic',
|
|
312
|
+
version,
|
|
313
|
+
skills,
|
|
314
|
+
scripts,
|
|
315
|
+
prompts: []
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
const manifestPath = path.join(skillsDst, '.agentic-manifest.json');
|
|
319
|
+
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + '\n');
|
|
320
|
+
console.log(`📑 Provenance manifest → ${manifestPath}`);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Main installation
|
|
325
|
+
*/
|
|
326
|
+
function install(): void {
|
|
327
|
+
// Read version from package.json
|
|
328
|
+
const packageJsonPath = path.join(srcDir, 'package.json');
|
|
329
|
+
let version = 'unknown';
|
|
330
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
331
|
+
try {
|
|
332
|
+
const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
333
|
+
version = pkg.version || 'unknown';
|
|
334
|
+
} catch (e) {}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
console.log(`🔧 Installing agentic v${version}...\n`);
|
|
338
|
+
|
|
339
|
+
installSkills();
|
|
340
|
+
installScripts();
|
|
341
|
+
installAgentsMd();
|
|
342
|
+
createReportsDir();
|
|
343
|
+
writeProvenanceManifest(version);
|
|
344
|
+
|
|
345
|
+
console.log('✅ Done!');
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// Run
|
|
349
|
+
install();
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@meyverick/agentic",
|
|
3
|
+
"version": "5.0.2",
|
|
4
|
+
"description": "AI agent skills and prompts for pi.dev",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/meyverick/agentic.git"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"install.ts",
|
|
14
|
+
"skills",
|
|
15
|
+
"scripts",
|
|
16
|
+
"AGENTS.md",
|
|
17
|
+
"README.md",
|
|
18
|
+
"CHANGELOG.md"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"check-deps": "./scripts/check-deps.mjs",
|
|
22
|
+
"git-dl": "./scripts/git-dl.mjs"
|
|
23
|
+
},
|
|
24
|
+
"bin": {
|
|
25
|
+
"agentic": "install.ts",
|
|
26
|
+
"check-deps": "scripts/check-deps.mjs",
|
|
27
|
+
"git-dl": "scripts/git-dl.mjs"
|
|
28
|
+
},
|
|
29
|
+
"keywords": [
|
|
30
|
+
"ai",
|
|
31
|
+
"agents",
|
|
32
|
+
"skills",
|
|
33
|
+
"prompts",
|
|
34
|
+
"pi"
|
|
35
|
+
],
|
|
36
|
+
"license": "MIT"
|
|
37
|
+
}
|