@paperclipai/skills-catalog 0.3.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.
Files changed (43) hide show
  1. package/catalog/bundled/docs/doc-maintenance/SKILL.md +75 -0
  2. package/catalog/bundled/paperclip-operations/issue-triage/SKILL.md +74 -0
  3. package/catalog/bundled/paperclip-operations/task-planning/SKILL.md +84 -0
  4. package/catalog/bundled/quality/qa-acceptance/SKILL.md +93 -0
  5. package/catalog/bundled/software-development/github-pr-workflow/SKILL.md +93 -0
  6. package/catalog/optional/browser/agent-browser/SKILL.md +93 -0
  7. package/catalog/optional/content/release-announcement/SKILL.md +128 -0
  8. package/catalog/optional/product/design-critique/SKILL.md +121 -0
  9. package/dist/generated/catalog.json +285 -0
  10. package/dist/scripts/build-catalog-manifest.d.ts +2 -0
  11. package/dist/scripts/build-catalog-manifest.d.ts.map +1 -0
  12. package/dist/scripts/build-catalog-manifest.js +15 -0
  13. package/dist/scripts/build-catalog-manifest.js.map +1 -0
  14. package/dist/scripts/validate-catalog.d.ts +2 -0
  15. package/dist/scripts/validate-catalog.d.ts.map +1 -0
  16. package/dist/scripts/validate-catalog.js +15 -0
  17. package/dist/scripts/validate-catalog.js.map +1 -0
  18. package/dist/src/catalog-builder.d.ts +16 -0
  19. package/dist/src/catalog-builder.d.ts.map +1 -0
  20. package/dist/src/catalog-builder.js +357 -0
  21. package/dist/src/catalog-builder.js.map +1 -0
  22. package/dist/src/catalog-builder.test.d.ts +2 -0
  23. package/dist/src/catalog-builder.test.d.ts.map +1 -0
  24. package/dist/src/catalog-builder.test.js +124 -0
  25. package/dist/src/catalog-builder.test.js.map +1 -0
  26. package/dist/src/frontmatter.d.ts +11 -0
  27. package/dist/src/frontmatter.d.ts.map +1 -0
  28. package/dist/src/frontmatter.js +141 -0
  29. package/dist/src/frontmatter.js.map +1 -0
  30. package/dist/src/index.d.ts +7 -0
  31. package/dist/src/index.d.ts.map +1 -0
  32. package/dist/src/index.js +21 -0
  33. package/dist/src/index.js.map +1 -0
  34. package/dist/src/shipped-catalog.test.d.ts +2 -0
  35. package/dist/src/shipped-catalog.test.d.ts.map +1 -0
  36. package/dist/src/shipped-catalog.test.js +83 -0
  37. package/dist/src/shipped-catalog.test.js.map +1 -0
  38. package/dist/src/types.d.ts +42 -0
  39. package/dist/src/types.d.ts.map +1 -0
  40. package/dist/src/types.js +2 -0
  41. package/dist/src/types.js.map +1 -0
  42. package/generated/catalog.json +285 -0
  43. package/package.json +49 -0
@@ -0,0 +1,141 @@
1
+ export function isPlainRecord(value) {
2
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3
+ }
4
+ export function asString(value) {
5
+ if (typeof value !== "string")
6
+ return null;
7
+ const trimmed = value.trim();
8
+ return trimmed.length > 0 ? trimmed : null;
9
+ }
10
+ export function asBoolean(value) {
11
+ return typeof value === "boolean" ? value : null;
12
+ }
13
+ export function asStringArray(value) {
14
+ if (value === undefined)
15
+ return [];
16
+ if (!Array.isArray(value))
17
+ return null;
18
+ const out = [];
19
+ for (const item of value) {
20
+ const text = asString(item);
21
+ if (!text)
22
+ return null;
23
+ out.push(text);
24
+ }
25
+ return out;
26
+ }
27
+ export function parseFrontmatterMarkdown(raw) {
28
+ const normalized = raw.replace(/\r\n/g, "\n");
29
+ if (!normalized.startsWith("---\n")) {
30
+ return { frontmatter: {}, body: normalized.trim(), hasFrontmatter: false };
31
+ }
32
+ const closing = normalized.indexOf("\n---\n", 4);
33
+ if (closing < 0) {
34
+ return { frontmatter: {}, body: normalized.trim(), hasFrontmatter: false };
35
+ }
36
+ const frontmatterRaw = normalized.slice(4, closing).trim();
37
+ const body = normalized.slice(closing + 5).trim();
38
+ return {
39
+ frontmatter: parseYamlFrontmatter(frontmatterRaw),
40
+ body,
41
+ hasFrontmatter: true,
42
+ };
43
+ }
44
+ function parseYamlFrontmatter(raw) {
45
+ const prepared = prepareYamlLines(raw);
46
+ if (prepared.length === 0)
47
+ return {};
48
+ const parsed = parseYamlBlock(prepared, 0, prepared[0].indent);
49
+ return isPlainRecord(parsed.value) ? parsed.value : {};
50
+ }
51
+ function prepareYamlLines(raw) {
52
+ return raw
53
+ .split("\n")
54
+ .map((line) => ({
55
+ indent: line.match(/^ */)?.[0].length ?? 0,
56
+ content: line.trim(),
57
+ }))
58
+ .filter((line) => line.content.length > 0 && !line.content.startsWith("#"));
59
+ }
60
+ function parseYamlBlock(lines, startIndex, indentLevel) {
61
+ let index = startIndex;
62
+ if (index >= lines.length || lines[index].indent < indentLevel) {
63
+ return { value: {}, nextIndex: index };
64
+ }
65
+ const isArray = lines[index].indent === indentLevel && lines[index].content.startsWith("-");
66
+ if (isArray) {
67
+ const values = [];
68
+ while (index < lines.length) {
69
+ const line = lines[index];
70
+ if (line.indent < indentLevel)
71
+ break;
72
+ if (line.indent !== indentLevel || !line.content.startsWith("-"))
73
+ break;
74
+ const remainder = line.content.slice(1).trim();
75
+ index += 1;
76
+ if (!remainder) {
77
+ const nested = parseYamlBlock(lines, index, indentLevel + 2);
78
+ values.push(nested.value);
79
+ index = nested.nextIndex;
80
+ continue;
81
+ }
82
+ values.push(parseYamlScalar(remainder));
83
+ }
84
+ return { value: values, nextIndex: index };
85
+ }
86
+ const record = {};
87
+ while (index < lines.length) {
88
+ const line = lines[index];
89
+ if (line.indent < indentLevel)
90
+ break;
91
+ if (line.indent !== indentLevel) {
92
+ index += 1;
93
+ continue;
94
+ }
95
+ const separatorIndex = line.content.indexOf(":");
96
+ if (separatorIndex <= 0) {
97
+ index += 1;
98
+ continue;
99
+ }
100
+ const key = line.content.slice(0, separatorIndex).trim();
101
+ const remainder = line.content.slice(separatorIndex + 1).trim();
102
+ index += 1;
103
+ if (!remainder) {
104
+ const nested = parseYamlBlock(lines, index, indentLevel + 2);
105
+ record[key] = nested.value;
106
+ index = nested.nextIndex;
107
+ continue;
108
+ }
109
+ record[key] = parseYamlScalar(remainder);
110
+ }
111
+ return { value: record, nextIndex: index };
112
+ }
113
+ function parseYamlScalar(rawValue) {
114
+ const trimmed = rawValue.trim();
115
+ if (trimmed === "")
116
+ return "";
117
+ if (trimmed === "null" || trimmed === "~")
118
+ return null;
119
+ if (trimmed === "true")
120
+ return true;
121
+ if (trimmed === "false")
122
+ return false;
123
+ if (trimmed === "[]")
124
+ return [];
125
+ if (trimmed === "{}")
126
+ return {};
127
+ if (/^-?\d+(\.\d+)?$/.test(trimmed))
128
+ return Number(trimmed);
129
+ if (trimmed.startsWith("\"") ||
130
+ trimmed.startsWith("[") ||
131
+ trimmed.startsWith("{")) {
132
+ try {
133
+ return JSON.parse(trimmed);
134
+ }
135
+ catch {
136
+ return trimmed;
137
+ }
138
+ }
139
+ return trimmed;
140
+ }
141
+ //# sourceMappingURL=frontmatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../src/frontmatter.ts"],"names":[],"mappings":"AAMA,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,OAAO,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACnC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEvC,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QACvB,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,GAAW;IAClD,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC9C,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACpC,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC;IAC7E,CAAC;IAED,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IACjD,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAChB,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC;IAC7E,CAAC;IAED,MAAM,cAAc,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3D,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAClD,OAAO;QACL,WAAW,EAAE,oBAAoB,CAAC,cAAc,CAAC;QACjD,IAAI;QACJ,cAAc,EAAE,IAAI;KACrB,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAAC,GAAW;IACvC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IACvC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACrC,MAAM,MAAM,GAAG,cAAc,CAAC,QAAQ,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAE,CAAC,MAAM,CAAC,CAAC;IAChE,OAAO,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AACzD,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAW;IACnC,OAAO,GAAG;SACP,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACd,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC;QAC1C,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE;KACrB,CAAC,CAAC;SACF,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;AAChF,CAAC;AAED,SAAS,cAAc,CACrB,KAAiD,EACjD,UAAkB,EAClB,WAAmB;IAEnB,IAAI,KAAK,GAAG,UAAU,CAAC;IACvB,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,CAAE,CAAC,MAAM,GAAG,WAAW,EAAE,CAAC;QAChE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IACzC,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAE,CAAC,MAAM,KAAK,WAAW,IAAI,KAAK,CAAC,KAAK,CAAE,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAC9F,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,MAAM,GAAc,EAAE,CAAC;QAC7B,OAAO,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAE,CAAC;YAC3B,IAAI,IAAI,CAAC,MAAM,GAAG,WAAW;gBAAE,MAAM;YACrC,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,MAAM;YAExE,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC/C,KAAK,IAAI,CAAC,CAAC;YACX,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,WAAW,GAAG,CAAC,CAAC,CAAC;gBAC7D,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC1B,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC;gBACzB,SAAS;YACX,CAAC;YAED,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC;QAC1C,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAC7C,CAAC;IAED,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,OAAO,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAE,CAAC;QAC3B,IAAI,IAAI,CAAC,MAAM,GAAG,WAAW;YAAE,MAAM;QACrC,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YAChC,KAAK,IAAI,CAAC,CAAC;YACX,SAAS;QACX,CAAC;QAED,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjD,IAAI,cAAc,IAAI,CAAC,EAAE,CAAC;YACxB,KAAK,IAAI,CAAC,CAAC;YACX,SAAS;QACX,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,IAAI,EAAE,CAAC;QACzD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAChE,KAAK,IAAI,CAAC,CAAC;QACX,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,WAAW,GAAG,CAAC,CAAC,CAAC;YAC7D,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC;YAC3B,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC;YACzB,SAAS;QACX,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;AAC7C,CAAC;AAED,SAAS,eAAe,CAAC,QAAgB;IACvC,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;IAChC,IAAI,OAAO,KAAK,EAAE;QAAE,OAAO,EAAE,CAAC;IAC9B,IAAI,OAAO,KAAK,MAAM,IAAI,OAAO,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IACvD,IAAI,OAAO,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IACpC,IAAI,OAAO,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IACtC,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,EAAE,CAAC;IAChC,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,EAAE,CAAC;IAChC,IAAI,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC;IAC5D,IACE,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC;QACxB,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;QACvB,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EACvB,CAAC;QACD,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,OAAO,CAAC;QACjB,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { CatalogManifest, CatalogSkill } from "./types.js";
2
+ export type { CatalogCompatibility, CatalogManifest, CatalogSkill, CatalogSkillFile, CatalogSkillFileKind, CatalogSkillKind, CatalogTrustLevel, CatalogValidationResult, } from "./types.js";
3
+ export declare const catalogManifest: CatalogManifest;
4
+ export declare const catalogSkills: CatalogSkill[];
5
+ export declare function getCatalogSkill(id: string): CatalogSkill | null;
6
+ export declare function resolveCatalogSkillRef(ref: string): CatalogSkill | null;
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEhE,YAAY,EACV,oBAAoB,EACpB,eAAe,EACf,YAAY,EACZ,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,EACjB,uBAAuB,GACxB,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,eAAe,EAA0B,eAAe,CAAC;AAEtE,eAAO,MAAM,aAAa,EAAE,YAAY,EAA2B,CAAC;AAKpE,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAE/D;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAWvE"}
@@ -0,0 +1,21 @@
1
+ import catalogManifestJson from "../generated/catalog.json" with { type: "json" };
2
+ export const catalogManifest = catalogManifestJson;
3
+ export const catalogSkills = catalogManifest.skills;
4
+ const skillsById = new Map(catalogSkills.map((skill) => [skill.id, skill]));
5
+ const skillsByKey = new Map(catalogSkills.map((skill) => [skill.key, skill]));
6
+ export function getCatalogSkill(id) {
7
+ return skillsById.get(id) ?? null;
8
+ }
9
+ export function resolveCatalogSkillRef(ref) {
10
+ const normalized = ref.trim();
11
+ if (normalized.length === 0)
12
+ return null;
13
+ const exactMatch = skillsById.get(normalized) ?? skillsByKey.get(normalized);
14
+ if (exactMatch)
15
+ return exactMatch;
16
+ const slugMatches = catalogSkills.filter((skill) => skill.slug === normalized);
17
+ if (slugMatches.length === 1)
18
+ return slugMatches[0];
19
+ return null;
20
+ }
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,mBAAmB,MAAM,2BAA2B,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAclF,MAAM,CAAC,MAAM,eAAe,GAAG,mBAAsC,CAAC;AAEtE,MAAM,CAAC,MAAM,aAAa,GAAmB,eAAe,CAAC,MAAM,CAAC;AAEpE,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AAC5E,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AAE9E,MAAM,UAAU,eAAe,CAAC,EAAU;IACxC,OAAO,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,GAAW;IAChD,MAAM,UAAU,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC9B,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEzC,MAAM,UAAU,GAAG,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAC7E,IAAI,UAAU;QAAE,OAAO,UAAU,CAAC;IAElC,MAAM,WAAW,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;IAC/E,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,WAAW,CAAC,CAAC,CAAE,CAAC;IAErD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=shipped-catalog.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shipped-catalog.test.d.ts","sourceRoot":"","sources":["../../src/shipped-catalog.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,83 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { catalogManifest, catalogSkills, resolveCatalogSkillRef } from "./index.js";
3
+ const EXPECTED_BUNDLED_KEYS = [
4
+ "paperclipai/bundled/docs/doc-maintenance",
5
+ "paperclipai/bundled/paperclip-operations/issue-triage",
6
+ "paperclipai/bundled/paperclip-operations/task-planning",
7
+ "paperclipai/bundled/quality/qa-acceptance",
8
+ "paperclipai/bundled/software-development/github-pr-workflow",
9
+ ];
10
+ const EXPECTED_OPTIONAL_KEYS = [
11
+ "paperclipai/optional/browser/agent-browser",
12
+ "paperclipai/optional/content/release-announcement",
13
+ "paperclipai/optional/product/design-critique",
14
+ ];
15
+ describe("shipped skills catalog", () => {
16
+ it("ships the expected bundled and optional skill set", () => {
17
+ const bundledKeys = catalogSkills
18
+ .filter((skill) => skill.kind === "bundled")
19
+ .map((skill) => skill.key)
20
+ .sort();
21
+ const optionalKeys = catalogSkills
22
+ .filter((skill) => skill.kind === "optional")
23
+ .map((skill) => skill.key)
24
+ .sort();
25
+ expect(bundledKeys).toEqual(EXPECTED_BUNDLED_KEYS);
26
+ expect(optionalKeys).toEqual(EXPECTED_OPTIONAL_KEYS);
27
+ });
28
+ it("keeps every shipped skill markdown-only until a script-bearing skill clears security review", () => {
29
+ const scriptBearing = catalogSkills.filter((skill) => skill.trustLevel !== "markdown_only");
30
+ expect(scriptBearing, formatViolations("script-bearing skills require security review", scriptBearing)).toEqual([]);
31
+ });
32
+ it("populates browse/search-relevant fields for every shipped skill", () => {
33
+ const issues = [];
34
+ for (const skill of catalogSkills) {
35
+ if (skill.compatibility !== "compatible") {
36
+ issues.push(`${skill.key} compatibility=${skill.compatibility}`);
37
+ }
38
+ if (!skill.description || skill.description.length < 40) {
39
+ issues.push(`${skill.key} description must be at least 40 characters for catalog browse/search`);
40
+ }
41
+ if (skill.recommendedForRoles.length === 0) {
42
+ issues.push(`${skill.key} must list recommendedForRoles`);
43
+ }
44
+ if (skill.tags.length === 0) {
45
+ issues.push(`${skill.key} must list tags`);
46
+ }
47
+ }
48
+ expect(issues).toEqual([]);
49
+ });
50
+ it("uses canonical paperclipai keys derived from kind/category/slug", () => {
51
+ const violations = [];
52
+ for (const skill of catalogSkills) {
53
+ const expectedKey = `paperclipai/${skill.kind}/${skill.category}/${skill.slug}`;
54
+ const expectedId = `paperclipai:${skill.kind}:${skill.category}:${skill.slug}`;
55
+ if (skill.key !== expectedKey)
56
+ violations.push(`${skill.key} should be ${expectedKey}`);
57
+ if (skill.id !== expectedId)
58
+ violations.push(`${skill.id} should be ${expectedId}`);
59
+ }
60
+ expect(violations).toEqual([]);
61
+ });
62
+ it("exposes a stable manifest header for downstream consumers", () => {
63
+ expect(catalogManifest.schemaVersion).toBe(1);
64
+ expect(catalogManifest.packageName).toBe("@paperclipai/skills-catalog");
65
+ expect(catalogSkills.length).toBe(EXPECTED_BUNDLED_KEYS.length + EXPECTED_OPTIONAL_KEYS.length);
66
+ });
67
+ it("resolves shipped skills by id, key, and unique slug", () => {
68
+ const sample = catalogSkills.find((skill) => skill.key === "paperclipai/bundled/software-development/github-pr-workflow");
69
+ expect(sample, "expected github-pr-workflow to ship in the bundled catalog").toBeDefined();
70
+ if (!sample)
71
+ return;
72
+ expect(resolveCatalogSkillRef(sample.id)).toMatchObject({ key: sample.key });
73
+ expect(resolveCatalogSkillRef(sample.key)).toMatchObject({ key: sample.key });
74
+ expect(resolveCatalogSkillRef(sample.slug)).toMatchObject({ key: sample.key });
75
+ });
76
+ });
77
+ function formatViolations(label, skills) {
78
+ if (skills.length === 0)
79
+ return label;
80
+ const detail = skills.map((skill) => `${skill.key} (${skill.trustLevel})`).join(", ");
81
+ return `${label}: ${detail}`;
82
+ }
83
+ //# sourceMappingURL=shipped-catalog.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shipped-catalog.test.js","sourceRoot":"","sources":["../../src/shipped-catalog.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ export type CatalogSkillKind = "bundled" | "optional";
2
+ export type CatalogTrustLevel = "markdown_only" | "assets" | "scripts_executables";
3
+ export type CatalogCompatibility = "compatible" | "unknown" | "invalid";
4
+ export type CatalogSkillFileKind = "skill" | "markdown" | "reference" | "script" | "asset" | "other";
5
+ export interface CatalogSkillFile {
6
+ path: string;
7
+ kind: CatalogSkillFileKind;
8
+ sizeBytes: number;
9
+ sha256: string;
10
+ }
11
+ export interface CatalogSkill {
12
+ id: string;
13
+ key: string;
14
+ kind: CatalogSkillKind;
15
+ category: string;
16
+ slug: string;
17
+ name: string;
18
+ description: string;
19
+ path: string;
20
+ entrypoint: "SKILL.md";
21
+ trustLevel: CatalogTrustLevel;
22
+ compatibility: CatalogCompatibility;
23
+ defaultInstall: boolean;
24
+ recommendedForRoles: string[];
25
+ requires: string[];
26
+ tags: string[];
27
+ files: CatalogSkillFile[];
28
+ contentHash: string;
29
+ }
30
+ export interface CatalogManifest {
31
+ schemaVersion: 1;
32
+ packageName: "@paperclipai/skills-catalog";
33
+ packageVersion: string;
34
+ generatedAt: string;
35
+ skills: CatalogSkill[];
36
+ }
37
+ export interface CatalogValidationResult {
38
+ valid: boolean;
39
+ errors: string[];
40
+ manifest: CatalogManifest;
41
+ }
42
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,UAAU,CAAC;AAEtD,MAAM,MAAM,iBAAiB,GAAG,eAAe,GAAG,QAAQ,GAAG,qBAAqB,CAAC;AAEnF,MAAM,MAAM,oBAAoB,GAAG,YAAY,GAAG,SAAS,GAAG,SAAS,CAAC;AAExE,MAAM,MAAM,oBAAoB,GAAG,OAAO,GAAG,UAAU,GAAG,WAAW,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;AAErG,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,oBAAoB,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,gBAAgB,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,UAAU,CAAC;IACvB,UAAU,EAAE,iBAAiB,CAAC;IAC9B,aAAa,EAAE,oBAAoB,CAAC;IACpC,cAAc,EAAE,OAAO,CAAC;IACxB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,CAAC,CAAC;IACjB,WAAW,EAAE,6BAA6B,CAAC;IAC3C,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,YAAY,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,eAAe,CAAC;CAC3B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,285 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "packageName": "@paperclipai/skills-catalog",
4
+ "packageVersion": "0.3.1",
5
+ "generatedAt": "2026-05-28T03:02:49.579Z",
6
+ "skills": [
7
+ {
8
+ "id": "paperclipai:bundled:docs:doc-maintenance",
9
+ "key": "paperclipai/bundled/docs/doc-maintenance",
10
+ "kind": "bundled",
11
+ "category": "docs",
12
+ "slug": "doc-maintenance",
13
+ "name": "doc-maintenance",
14
+ "description": "Keep project docs aligned with recent code and feature changes — detect drift, update affected pages, and add release-relevant notes without rewriting unchanged sections.",
15
+ "path": "catalog/bundled/docs/doc-maintenance",
16
+ "entrypoint": "SKILL.md",
17
+ "trustLevel": "markdown_only",
18
+ "compatibility": "compatible",
19
+ "defaultInstall": false,
20
+ "recommendedForRoles": [
21
+ "engineer",
22
+ "product",
23
+ "devrel"
24
+ ],
25
+ "requires": [],
26
+ "tags": [
27
+ "docs",
28
+ "documentation",
29
+ "release-notes"
30
+ ],
31
+ "files": [
32
+ {
33
+ "path": "SKILL.md",
34
+ "kind": "skill",
35
+ "sizeBytes": 4478,
36
+ "sha256": "fb0353386c5e5e5e13bcbb3233f044e3dccecf371f429d6328f26c26d7cb6169"
37
+ }
38
+ ],
39
+ "contentHash": "sha256:2e02299210fd17c1fe1867b4ee8c144a11b6fe1fe481f83b8268cfbaaf10f9aa"
40
+ },
41
+ {
42
+ "id": "paperclipai:bundled:paperclip-operations:issue-triage",
43
+ "key": "paperclipai/bundled/paperclip-operations/issue-triage",
44
+ "kind": "bundled",
45
+ "category": "paperclip-operations",
46
+ "slug": "issue-triage",
47
+ "name": "issue-triage",
48
+ "description": "Triage Paperclip inbox issues that are stale, blocked, in-review, or assigned-but-not-progressing, and decide a single next action per issue (resume, reassign, unblock, escalate, or close).",
49
+ "path": "catalog/bundled/paperclip-operations/issue-triage",
50
+ "entrypoint": "SKILL.md",
51
+ "trustLevel": "markdown_only",
52
+ "compatibility": "compatible",
53
+ "defaultInstall": false,
54
+ "recommendedForRoles": [
55
+ "manager",
56
+ "ceo",
57
+ "engineer"
58
+ ],
59
+ "requires": [],
60
+ "tags": [
61
+ "paperclip",
62
+ "triage",
63
+ "inbox",
64
+ "workflow"
65
+ ],
66
+ "files": [
67
+ {
68
+ "path": "SKILL.md",
69
+ "kind": "skill",
70
+ "sizeBytes": 4042,
71
+ "sha256": "df5bdc8bf5e017b7ba5f70a4b5323fad51d0c323278f386580f26cf43ad09160"
72
+ }
73
+ ],
74
+ "contentHash": "sha256:88dc13560371fb364963782cb4f6eeb4090fcde92ee3774479428ed6b90e11c1"
75
+ },
76
+ {
77
+ "id": "paperclipai:bundled:paperclip-operations:task-planning",
78
+ "key": "paperclipai/bundled/paperclip-operations/task-planning",
79
+ "kind": "bundled",
80
+ "category": "paperclip-operations",
81
+ "slug": "task-planning",
82
+ "name": "task-planning",
83
+ "description": "Turn a Paperclip issue or request into a structured implementation plan with child task graph, blockers, owners, and acceptance criteria, then save it as the issue `plan` document.",
84
+ "path": "catalog/bundled/paperclip-operations/task-planning",
85
+ "entrypoint": "SKILL.md",
86
+ "trustLevel": "markdown_only",
87
+ "compatibility": "compatible",
88
+ "defaultInstall": false,
89
+ "recommendedForRoles": [
90
+ "manager",
91
+ "engineer",
92
+ "product"
93
+ ],
94
+ "requires": [],
95
+ "tags": [
96
+ "paperclip",
97
+ "planning",
98
+ "issues",
99
+ "delegation"
100
+ ],
101
+ "files": [
102
+ {
103
+ "path": "SKILL.md",
104
+ "kind": "skill",
105
+ "sizeBytes": 4649,
106
+ "sha256": "2ff61e12dfaa4cf8cc548529fd176f55f1b1f5292ff9dd3eb2cb331417ab5e4e"
107
+ }
108
+ ],
109
+ "contentHash": "sha256:4fb46a4bcefad4fd46fae48c433ee497112509a8e19fb8a7745ead44d219b498"
110
+ },
111
+ {
112
+ "id": "paperclipai:bundled:quality:qa-acceptance",
113
+ "key": "paperclipai/bundled/quality/qa-acceptance",
114
+ "kind": "bundled",
115
+ "category": "quality",
116
+ "slug": "qa-acceptance",
117
+ "name": "qa-acceptance",
118
+ "description": "Produce QA acceptance criteria and a manual validation plan for a feature change — golden path, edge cases, error states, performance limits, and explicit pass/fail evidence.",
119
+ "path": "catalog/bundled/quality/qa-acceptance",
120
+ "entrypoint": "SKILL.md",
121
+ "trustLevel": "markdown_only",
122
+ "compatibility": "compatible",
123
+ "defaultInstall": false,
124
+ "recommendedForRoles": [
125
+ "qa",
126
+ "engineer",
127
+ "product"
128
+ ],
129
+ "requires": [],
130
+ "tags": [
131
+ "qa",
132
+ "acceptance",
133
+ "validation",
134
+ "testing"
135
+ ],
136
+ "files": [
137
+ {
138
+ "path": "SKILL.md",
139
+ "kind": "skill",
140
+ "sizeBytes": 3861,
141
+ "sha256": "c631b437ab26d104af6cdb963d8f679a9341439041b3cb3ec8835f4ff551b378"
142
+ }
143
+ ],
144
+ "contentHash": "sha256:32372dacaf62e93454b9855968c4eec96456ba78b509f450b3dfaa48e31ef356"
145
+ },
146
+ {
147
+ "id": "paperclipai:bundled:software-development:github-pr-workflow",
148
+ "key": "paperclipai/bundled/software-development/github-pr-workflow",
149
+ "kind": "bundled",
150
+ "category": "software-development",
151
+ "slug": "github-pr-workflow",
152
+ "name": "github-pr-workflow",
153
+ "description": "Prepare a GitHub pull request from a feature branch — branch hygiene, commit shape, title/body, verification notes, screenshots for UI work, and replies to review comments.",
154
+ "path": "catalog/bundled/software-development/github-pr-workflow",
155
+ "entrypoint": "SKILL.md",
156
+ "trustLevel": "markdown_only",
157
+ "compatibility": "compatible",
158
+ "defaultInstall": false,
159
+ "recommendedForRoles": [
160
+ "engineer"
161
+ ],
162
+ "requires": [],
163
+ "tags": [
164
+ "github",
165
+ "pull-requests",
166
+ "code-review",
167
+ "release"
168
+ ],
169
+ "files": [
170
+ {
171
+ "path": "SKILL.md",
172
+ "kind": "skill",
173
+ "sizeBytes": 3970,
174
+ "sha256": "f498ec4ebb1779dea37adeb1db8a8b22316282798e35ee02e2fc5ff627d7e261"
175
+ }
176
+ ],
177
+ "contentHash": "sha256:90f278c89aa0711be150c1cd2456ca25620d02f36995b113ca9837d756a37f6c"
178
+ },
179
+ {
180
+ "id": "paperclipai:optional:browser:agent-browser",
181
+ "key": "paperclipai/optional/browser/agent-browser",
182
+ "kind": "optional",
183
+ "category": "browser",
184
+ "slug": "agent-browser",
185
+ "name": "agent-browser",
186
+ "description": "Drive a real browser to inspect or interact with a web page or app — navigate, take screenshots, read console and network, fill simple forms — for verification tasks, not unattended automation.",
187
+ "path": "catalog/optional/browser/agent-browser",
188
+ "entrypoint": "SKILL.md",
189
+ "trustLevel": "markdown_only",
190
+ "compatibility": "compatible",
191
+ "defaultInstall": false,
192
+ "recommendedForRoles": [
193
+ "qa",
194
+ "engineer",
195
+ "researcher"
196
+ ],
197
+ "requires": [],
198
+ "tags": [
199
+ "browser",
200
+ "puppeteer",
201
+ "playwright",
202
+ "verification"
203
+ ],
204
+ "files": [
205
+ {
206
+ "path": "SKILL.md",
207
+ "kind": "skill",
208
+ "sizeBytes": 5133,
209
+ "sha256": "362f7b9d02297782bc6f0c093f495b8a0304a75bcf4b42e5c280a42b1f757b7d"
210
+ }
211
+ ],
212
+ "contentHash": "sha256:eabb2c9f7b5e1a27ebb1e05a711d61433a266478154cd671a685e99e67aadea2"
213
+ },
214
+ {
215
+ "id": "paperclipai:optional:content:release-announcement",
216
+ "key": "paperclipai/optional/content/release-announcement",
217
+ "kind": "optional",
218
+ "category": "content",
219
+ "slug": "release-announcement",
220
+ "name": "release-announcement",
221
+ "description": "Write a release announcement — changelog, blog post, in-app note, or social post — that leads with user impact, names the audience, and includes upgrade/migration steps without filler.",
222
+ "path": "catalog/optional/content/release-announcement",
223
+ "entrypoint": "SKILL.md",
224
+ "trustLevel": "markdown_only",
225
+ "compatibility": "compatible",
226
+ "defaultInstall": false,
227
+ "recommendedForRoles": [
228
+ "devrel",
229
+ "product",
230
+ "writer"
231
+ ],
232
+ "requires": [],
233
+ "tags": [
234
+ "release",
235
+ "changelog",
236
+ "announcement",
237
+ "communication"
238
+ ],
239
+ "files": [
240
+ {
241
+ "path": "SKILL.md",
242
+ "kind": "skill",
243
+ "sizeBytes": 4416,
244
+ "sha256": "062810ac34e9edc89efa701fec2eee60f16949d1944cc2cae49803cb91e8cbf4"
245
+ }
246
+ ],
247
+ "contentHash": "sha256:f22a9ed696e6614c6db2757a149f48b3295e81f78c27d065d9cb164cf4f8a9bd"
248
+ },
249
+ {
250
+ "id": "paperclipai:optional:product:design-critique",
251
+ "key": "paperclipai/optional/product/design-critique",
252
+ "kind": "optional",
253
+ "category": "product",
254
+ "slug": "design-critique",
255
+ "name": "design-critique",
256
+ "description": "Give a structured product design critique — user job clarity, hierarchy, affordance, error states, accessibility, and consistency — focused on what to change, in what order, and why.",
257
+ "path": "catalog/optional/product/design-critique",
258
+ "entrypoint": "SKILL.md",
259
+ "trustLevel": "markdown_only",
260
+ "compatibility": "compatible",
261
+ "defaultInstall": false,
262
+ "recommendedForRoles": [
263
+ "designer",
264
+ "product",
265
+ "engineer"
266
+ ],
267
+ "requires": [],
268
+ "tags": [
269
+ "design",
270
+ "product",
271
+ "ux",
272
+ "review"
273
+ ],
274
+ "files": [
275
+ {
276
+ "path": "SKILL.md",
277
+ "kind": "skill",
278
+ "sizeBytes": 4851,
279
+ "sha256": "022e619baf6cc25725946279cb8052d22af090dd6cd6dc8c20f17867f71a5d8e"
280
+ }
281
+ ],
282
+ "contentHash": "sha256:429f94df398a0697042b5bbe4755b1ff1a230aa5f41d99118ad37493ac65d21c"
283
+ }
284
+ ]
285
+ }