@prave/shared 1.4.15 → 1.5.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/dist/schemas/hook.schema.d.ts +246 -0
- package/dist/schemas/hook.schema.d.ts.map +1 -0
- package/dist/schemas/hook.schema.js +129 -0
- package/dist/schemas/index.d.ts +2 -0
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/schemas/index.js +2 -0
- package/dist/schemas/install.schema.d.ts +2 -0
- package/dist/schemas/install.schema.d.ts.map +1 -1
- package/dist/schemas/search.schema.d.ts +6 -0
- package/dist/schemas/search.schema.d.ts.map +1 -1
- package/dist/schemas/security-audit.schema.d.ts +231 -0
- package/dist/schemas/security-audit.schema.d.ts.map +1 -0
- package/dist/schemas/security-audit.schema.js +76 -0
- package/dist/schemas/skill-dependency.schema.d.ts +2 -0
- package/dist/schemas/skill-dependency.schema.d.ts.map +1 -1
- package/dist/schemas/skill.schema.d.ts +35 -0
- package/dist/schemas/skill.schema.d.ts.map +1 -1
- package/dist/schemas/skill.schema.js +32 -0
- package/package.json +1 -1
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Claude Code Hook registry shape — the parallel-to-Skills primitive.
|
|
4
|
+
*
|
|
5
|
+
* V1 is **scraper-only**: rows arrive from the worker's
|
|
6
|
+
* scan-github-hook job. The web UI does not author hooks; the
|
|
7
|
+
* "Suggest a hook" modal calls `POST /api/v1/hooks/submit` with a
|
|
8
|
+
* GitHub URL, which enqueues a scan job. End-users never POST/PUT/
|
|
9
|
+
* DELETE the hook content itself.
|
|
10
|
+
*/
|
|
11
|
+
export declare const hookEventSchema: z.ZodEnum<["PreToolUse", "PostToolUse", "UserPromptSubmit", "Stop", "SubagentStop", "Notification", "PreCompact", "SessionStart"]>;
|
|
12
|
+
export type HookEvent = z.infer<typeof hookEventSchema>;
|
|
13
|
+
export declare const hookVisibilitySchema: z.ZodEnum<["public", "private"]>;
|
|
14
|
+
export type HookVisibility = z.infer<typeof hookVisibilitySchema>;
|
|
15
|
+
export declare const hookSchema: z.ZodObject<{
|
|
16
|
+
id: z.ZodString;
|
|
17
|
+
owner_id: z.ZodNullable<z.ZodString>;
|
|
18
|
+
name: z.ZodString;
|
|
19
|
+
slug: z.ZodString;
|
|
20
|
+
description: z.ZodNullable<z.ZodString>;
|
|
21
|
+
/** Claude Code lifecycle event the hook listens on. */
|
|
22
|
+
event: z.ZodEnum<["PreToolUse", "PostToolUse", "UserPromptSubmit", "Stop", "SubagentStop", "Notification", "PreCompact", "SessionStart"]>;
|
|
23
|
+
/**
|
|
24
|
+
* Tool-name glob — only relevant on the tool-events
|
|
25
|
+
* (`Pre/PostToolUse`). `null` means "any tool" and Claude Code
|
|
26
|
+
* treats it as the universal matcher.
|
|
27
|
+
*/
|
|
28
|
+
matcher: z.ZodNullable<z.ZodString>;
|
|
29
|
+
/** Shell command Claude Code spawns when the event fires. */
|
|
30
|
+
command: z.ZodString;
|
|
31
|
+
/** Optional per-hook timeout in seconds (1–600). */
|
|
32
|
+
timeout_seconds: z.ZodNullable<z.ZodNumber>;
|
|
33
|
+
visibility: z.ZodDefault<z.ZodEnum<["public", "private"]>>;
|
|
34
|
+
source_repo: z.ZodNullable<z.ZodString>;
|
|
35
|
+
license: z.ZodDefault<z.ZodString>;
|
|
36
|
+
tags: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
37
|
+
install_count: z.ZodDefault<z.ZodNumber>;
|
|
38
|
+
is_verified: z.ZodDefault<z.ZodBoolean>;
|
|
39
|
+
version: z.ZodDefault<z.ZodNumber>;
|
|
40
|
+
/** Same enum as Feature 1's security_rating; opt-in for hooks. */
|
|
41
|
+
security_rating: z.ZodOptional<z.ZodNullable<z.ZodEnum<["trusted", "low_risk", "med_risk", "critical", "pending"]>>>;
|
|
42
|
+
/** Attached by the API on GET when authenticated. */
|
|
43
|
+
bookmarked: z.ZodOptional<z.ZodBoolean>;
|
|
44
|
+
/** Attached by the API on GET when authenticated. */
|
|
45
|
+
installed: z.ZodOptional<z.ZodBoolean>;
|
|
46
|
+
/** Attached by the API: public slice of the owner profile. */
|
|
47
|
+
owner: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
48
|
+
id: z.ZodString;
|
|
49
|
+
username: z.ZodNullable<z.ZodString>;
|
|
50
|
+
display_name: z.ZodNullable<z.ZodString>;
|
|
51
|
+
avatar_url: z.ZodNullable<z.ZodString>;
|
|
52
|
+
is_creator: z.ZodBoolean;
|
|
53
|
+
is_partner: z.ZodBoolean;
|
|
54
|
+
}, "strip", z.ZodTypeAny, {
|
|
55
|
+
id: string;
|
|
56
|
+
username: string | null;
|
|
57
|
+
display_name: string | null;
|
|
58
|
+
avatar_url: string | null;
|
|
59
|
+
is_creator: boolean;
|
|
60
|
+
is_partner: boolean;
|
|
61
|
+
}, {
|
|
62
|
+
id: string;
|
|
63
|
+
username: string | null;
|
|
64
|
+
display_name: string | null;
|
|
65
|
+
avatar_url: string | null;
|
|
66
|
+
is_creator: boolean;
|
|
67
|
+
is_partner: boolean;
|
|
68
|
+
}>>>;
|
|
69
|
+
created_at: z.ZodString;
|
|
70
|
+
updated_at: z.ZodString;
|
|
71
|
+
}, "strip", z.ZodTypeAny, {
|
|
72
|
+
id: string;
|
|
73
|
+
created_at: string;
|
|
74
|
+
updated_at: string;
|
|
75
|
+
slug: string;
|
|
76
|
+
name: string;
|
|
77
|
+
description: string | null;
|
|
78
|
+
install_count: number;
|
|
79
|
+
owner_id: string | null;
|
|
80
|
+
visibility: "public" | "private";
|
|
81
|
+
source_repo: string | null;
|
|
82
|
+
license: string;
|
|
83
|
+
tags: string[];
|
|
84
|
+
is_verified: boolean;
|
|
85
|
+
version: number;
|
|
86
|
+
event: "PreToolUse" | "PostToolUse" | "UserPromptSubmit" | "Stop" | "SubagentStop" | "Notification" | "PreCompact" | "SessionStart";
|
|
87
|
+
matcher: string | null;
|
|
88
|
+
command: string;
|
|
89
|
+
timeout_seconds: number | null;
|
|
90
|
+
bookmarked?: boolean | undefined;
|
|
91
|
+
owner?: {
|
|
92
|
+
id: string;
|
|
93
|
+
username: string | null;
|
|
94
|
+
display_name: string | null;
|
|
95
|
+
avatar_url: string | null;
|
|
96
|
+
is_creator: boolean;
|
|
97
|
+
is_partner: boolean;
|
|
98
|
+
} | null | undefined;
|
|
99
|
+
security_rating?: "trusted" | "low_risk" | "med_risk" | "critical" | "pending" | null | undefined;
|
|
100
|
+
installed?: boolean | undefined;
|
|
101
|
+
}, {
|
|
102
|
+
id: string;
|
|
103
|
+
created_at: string;
|
|
104
|
+
updated_at: string;
|
|
105
|
+
slug: string;
|
|
106
|
+
name: string;
|
|
107
|
+
description: string | null;
|
|
108
|
+
owner_id: string | null;
|
|
109
|
+
source_repo: string | null;
|
|
110
|
+
event: "PreToolUse" | "PostToolUse" | "UserPromptSubmit" | "Stop" | "SubagentStop" | "Notification" | "PreCompact" | "SessionStart";
|
|
111
|
+
matcher: string | null;
|
|
112
|
+
command: string;
|
|
113
|
+
timeout_seconds: number | null;
|
|
114
|
+
install_count?: number | undefined;
|
|
115
|
+
visibility?: "public" | "private" | undefined;
|
|
116
|
+
license?: string | undefined;
|
|
117
|
+
tags?: string[] | undefined;
|
|
118
|
+
is_verified?: boolean | undefined;
|
|
119
|
+
bookmarked?: boolean | undefined;
|
|
120
|
+
owner?: {
|
|
121
|
+
id: string;
|
|
122
|
+
username: string | null;
|
|
123
|
+
display_name: string | null;
|
|
124
|
+
avatar_url: string | null;
|
|
125
|
+
is_creator: boolean;
|
|
126
|
+
is_partner: boolean;
|
|
127
|
+
} | null | undefined;
|
|
128
|
+
security_rating?: "trusted" | "low_risk" | "med_risk" | "critical" | "pending" | null | undefined;
|
|
129
|
+
version?: number | undefined;
|
|
130
|
+
installed?: boolean | undefined;
|
|
131
|
+
}>;
|
|
132
|
+
export type Hook = z.infer<typeof hookSchema>;
|
|
133
|
+
export declare const hookSortSchema: z.ZodEnum<["trending", "popular", "newest", "relevance"]>;
|
|
134
|
+
export type HookSort = z.infer<typeof hookSortSchema>;
|
|
135
|
+
export declare const hookSearchQuerySchema: z.ZodObject<{
|
|
136
|
+
q: z.ZodOptional<z.ZodString>;
|
|
137
|
+
event: z.ZodOptional<z.ZodEnum<["PreToolUse", "PostToolUse", "UserPromptSubmit", "Stop", "SubagentStop", "Notification", "PreCompact", "SessionStart"]>>;
|
|
138
|
+
tag: z.ZodOptional<z.ZodString>;
|
|
139
|
+
sort: z.ZodDefault<z.ZodEnum<["trending", "popular", "newest", "relevance"]>>;
|
|
140
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
141
|
+
offset: z.ZodDefault<z.ZodNumber>;
|
|
142
|
+
}, "strip", z.ZodTypeAny, {
|
|
143
|
+
sort: "trending" | "popular" | "newest" | "relevance";
|
|
144
|
+
limit: number;
|
|
145
|
+
offset: number;
|
|
146
|
+
q?: string | undefined;
|
|
147
|
+
tag?: string | undefined;
|
|
148
|
+
event?: "PreToolUse" | "PostToolUse" | "UserPromptSubmit" | "Stop" | "SubagentStop" | "Notification" | "PreCompact" | "SessionStart" | undefined;
|
|
149
|
+
}, {
|
|
150
|
+
sort?: "trending" | "popular" | "newest" | "relevance" | undefined;
|
|
151
|
+
q?: string | undefined;
|
|
152
|
+
tag?: string | undefined;
|
|
153
|
+
limit?: number | undefined;
|
|
154
|
+
offset?: number | undefined;
|
|
155
|
+
event?: "PreToolUse" | "PostToolUse" | "UserPromptSubmit" | "Stop" | "SubagentStop" | "Notification" | "PreCompact" | "SessionStart" | undefined;
|
|
156
|
+
}>;
|
|
157
|
+
export type HookSearchQuery = z.infer<typeof hookSearchQuerySchema>;
|
|
158
|
+
/**
|
|
159
|
+
* `POST /api/v1/hooks/submit` body — a user proposes a GitHub URL,
|
|
160
|
+
* the worker scans it. The endpoint dedupes pending scans by repo URL
|
|
161
|
+
* so spamming the form is harmless.
|
|
162
|
+
*/
|
|
163
|
+
export declare const submitHookByUrlSchema: z.ZodObject<{
|
|
164
|
+
repo_url: z.ZodEffects<z.ZodString, string, string>;
|
|
165
|
+
}, "strip", z.ZodTypeAny, {
|
|
166
|
+
repo_url: string;
|
|
167
|
+
}, {
|
|
168
|
+
repo_url: string;
|
|
169
|
+
}>;
|
|
170
|
+
export type SubmitHookByUrlInput = z.infer<typeof submitHookByUrlSchema>;
|
|
171
|
+
/**
|
|
172
|
+
* `github-hook-scan` queue payload. Scans one GitHub repo for
|
|
173
|
+
* `hook.json` files + sibling `claude/hooks/*.json`, validates them
|
|
174
|
+
* against `hookSchema`, secret-scans the command, upserts.
|
|
175
|
+
*/
|
|
176
|
+
export declare const scanGithubHookJobSchema: z.ZodObject<{
|
|
177
|
+
repo_url: z.ZodString;
|
|
178
|
+
source: z.ZodEnum<["manual", "seed", "cron", "submit"]>;
|
|
179
|
+
submitted_by: z.ZodOptional<z.ZodString>;
|
|
180
|
+
}, "strip", z.ZodTypeAny, {
|
|
181
|
+
repo_url: string;
|
|
182
|
+
source: "seed" | "manual" | "cron" | "submit";
|
|
183
|
+
submitted_by?: string | undefined;
|
|
184
|
+
}, {
|
|
185
|
+
repo_url: string;
|
|
186
|
+
source: "seed" | "manual" | "cron" | "submit";
|
|
187
|
+
submitted_by?: string | undefined;
|
|
188
|
+
}>;
|
|
189
|
+
export type ScanGithubHookJob = z.infer<typeof scanGithubHookJobSchema>;
|
|
190
|
+
/**
|
|
191
|
+
* `discover-github-hook` queue payload. Wide-scope GitHub code-search
|
|
192
|
+
* to find any public repo with a `hook.json` we don't already know.
|
|
193
|
+
*/
|
|
194
|
+
export declare const discoverGithubHookJobSchema: z.ZodObject<{
|
|
195
|
+
query: z.ZodString;
|
|
196
|
+
max_repos: z.ZodDefault<z.ZodNumber>;
|
|
197
|
+
}, "strip", z.ZodTypeAny, {
|
|
198
|
+
max_repos: number;
|
|
199
|
+
query: string;
|
|
200
|
+
}, {
|
|
201
|
+
query: string;
|
|
202
|
+
max_repos?: number | undefined;
|
|
203
|
+
}>;
|
|
204
|
+
export type DiscoverGithubHookJob = z.infer<typeof discoverGithubHookJobSchema>;
|
|
205
|
+
/** `index-hook` queue payload. */
|
|
206
|
+
export declare const indexHookJobSchema: z.ZodObject<{
|
|
207
|
+
hook_id: z.ZodString;
|
|
208
|
+
op: z.ZodEnum<["upsert", "delete"]>;
|
|
209
|
+
}, "strip", z.ZodTypeAny, {
|
|
210
|
+
op: "upsert" | "delete";
|
|
211
|
+
hook_id: string;
|
|
212
|
+
}, {
|
|
213
|
+
op: "upsert" | "delete";
|
|
214
|
+
hook_id: string;
|
|
215
|
+
}>;
|
|
216
|
+
export type IndexHookJob = z.infer<typeof indexHookJobSchema>;
|
|
217
|
+
/** `describe-hook` queue payload — Haiku-generated description. */
|
|
218
|
+
export declare const describeHookJobSchema: z.ZodObject<{
|
|
219
|
+
hook_id: z.ZodString;
|
|
220
|
+
force: z.ZodOptional<z.ZodBoolean>;
|
|
221
|
+
}, "strip", z.ZodTypeAny, {
|
|
222
|
+
hook_id: string;
|
|
223
|
+
force?: boolean | undefined;
|
|
224
|
+
}, {
|
|
225
|
+
hook_id: string;
|
|
226
|
+
force?: boolean | undefined;
|
|
227
|
+
}>;
|
|
228
|
+
export type DescribeHookJob = z.infer<typeof describeHookJobSchema>;
|
|
229
|
+
export declare const hookBulkSyncInputSchema: z.ZodObject<{
|
|
230
|
+
slugs: z.ZodArray<z.ZodString, "many">;
|
|
231
|
+
}, "strip", z.ZodTypeAny, {
|
|
232
|
+
slugs: string[];
|
|
233
|
+
}, {
|
|
234
|
+
slugs: string[];
|
|
235
|
+
}>;
|
|
236
|
+
export type HookBulkSyncInput = z.infer<typeof hookBulkSyncInputSchema>;
|
|
237
|
+
export interface HookBulkSyncItem {
|
|
238
|
+
slug: string;
|
|
239
|
+
hook: Hook | null;
|
|
240
|
+
error: string | null;
|
|
241
|
+
}
|
|
242
|
+
export interface HookBulkSyncResponse {
|
|
243
|
+
items: HookBulkSyncItem[];
|
|
244
|
+
missing: string[];
|
|
245
|
+
}
|
|
246
|
+
//# sourceMappingURL=hook.schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook.schema.d.ts","sourceRoot":"","sources":["../../src/schemas/hook.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB;;;;;;;;GAQG;AAEH,eAAO,MAAM,eAAe,oIAS1B,CAAA;AACF,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA;AAEvD,eAAO,MAAM,oBAAoB,kCAAgC,CAAA;AACjE,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAA;AAEjE,eAAO,MAAM,UAAU;;;;;;IAWrB,uDAAuD;;IAEvD;;;;OAIG;;IAEH,6DAA6D;;IAE7D,oDAAoD;;;;;;;;;IAWpD,kEAAkE;;IAMlE,qDAAqD;;IAErD,qDAAqD;;IAErD,8DAA8D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAe9D,CAAA;AACF,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAA;AAI7C,eAAO,MAAM,cAAc,2DAAyD,CAAA;AACpF,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;AAErD,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;EAOhC,CAAA;AACF,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA;AAInE;;;;GAIG;AACH,eAAO,MAAM,qBAAqB;;;;;;EAQhC,CAAA;AACF,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA;AAIxE;;;;GAIG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;EAIlC,CAAA;AACF,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAA;AAEvE;;;GAGG;AACH,eAAO,MAAM,2BAA2B;;;;;;;;;EAGtC,CAAA;AACF,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAA;AAE/E,kCAAkC;AAClC,eAAO,MAAM,kBAAkB;;;;;;;;;EAG7B,CAAA;AACF,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAA;AAE7D,mEAAmE;AACnE,eAAO,MAAM,qBAAqB;;;;;;;;;EAGhC,CAAA;AACF,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA;AAInE,eAAO,MAAM,uBAAuB;;;;;;EAElC,CAAA;AACF,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAA;AAEvE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,IAAI,GAAG,IAAI,CAAA;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,gBAAgB,EAAE,CAAA;IACzB,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Claude Code Hook registry shape — the parallel-to-Skills primitive.
|
|
4
|
+
*
|
|
5
|
+
* V1 is **scraper-only**: rows arrive from the worker's
|
|
6
|
+
* scan-github-hook job. The web UI does not author hooks; the
|
|
7
|
+
* "Suggest a hook" modal calls `POST /api/v1/hooks/submit` with a
|
|
8
|
+
* GitHub URL, which enqueues a scan job. End-users never POST/PUT/
|
|
9
|
+
* DELETE the hook content itself.
|
|
10
|
+
*/
|
|
11
|
+
export const hookEventSchema = z.enum([
|
|
12
|
+
'PreToolUse',
|
|
13
|
+
'PostToolUse',
|
|
14
|
+
'UserPromptSubmit',
|
|
15
|
+
'Stop',
|
|
16
|
+
'SubagentStop',
|
|
17
|
+
'Notification',
|
|
18
|
+
'PreCompact',
|
|
19
|
+
'SessionStart',
|
|
20
|
+
]);
|
|
21
|
+
export const hookVisibilitySchema = z.enum(['public', 'private']);
|
|
22
|
+
export const hookSchema = z.object({
|
|
23
|
+
id: z.string().uuid(),
|
|
24
|
+
owner_id: z.string().uuid().nullable(),
|
|
25
|
+
name: z.string().min(1).max(120),
|
|
26
|
+
slug: z
|
|
27
|
+
.string()
|
|
28
|
+
.min(1)
|
|
29
|
+
.max(120)
|
|
30
|
+
.regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, 'slug must be kebab-case'),
|
|
31
|
+
description: z.string().max(500).nullable(),
|
|
32
|
+
/** Claude Code lifecycle event the hook listens on. */
|
|
33
|
+
event: hookEventSchema,
|
|
34
|
+
/**
|
|
35
|
+
* Tool-name glob — only relevant on the tool-events
|
|
36
|
+
* (`Pre/PostToolUse`). `null` means "any tool" and Claude Code
|
|
37
|
+
* treats it as the universal matcher.
|
|
38
|
+
*/
|
|
39
|
+
matcher: z.string().max(120).nullable(),
|
|
40
|
+
/** Shell command Claude Code spawns when the event fires. */
|
|
41
|
+
command: z.string().min(1).max(4000),
|
|
42
|
+
/** Optional per-hook timeout in seconds (1–600). */
|
|
43
|
+
timeout_seconds: z.number().int().min(1).max(600).nullable(),
|
|
44
|
+
visibility: hookVisibilitySchema.default('public'),
|
|
45
|
+
source_repo: z.string().url().nullable(),
|
|
46
|
+
license: z.string().default('MIT'),
|
|
47
|
+
tags: z.array(z.string()).default([]),
|
|
48
|
+
install_count: z.number().int().nonnegative().default(0),
|
|
49
|
+
is_verified: z.boolean().default(false),
|
|
50
|
+
version: z.number().int().positive().default(1),
|
|
51
|
+
/** Same enum as Feature 1's security_rating; opt-in for hooks. */
|
|
52
|
+
security_rating: z
|
|
53
|
+
.enum(['trusted', 'low_risk', 'med_risk', 'critical', 'pending'])
|
|
54
|
+
.nullable()
|
|
55
|
+
.optional(),
|
|
56
|
+
/** Attached by the API on GET when authenticated. */
|
|
57
|
+
bookmarked: z.boolean().optional(),
|
|
58
|
+
/** Attached by the API on GET when authenticated. */
|
|
59
|
+
installed: z.boolean().optional(),
|
|
60
|
+
/** Attached by the API: public slice of the owner profile. */
|
|
61
|
+
owner: z
|
|
62
|
+
.object({
|
|
63
|
+
id: z.string().uuid(),
|
|
64
|
+
username: z.string().nullable(),
|
|
65
|
+
display_name: z.string().nullable(),
|
|
66
|
+
avatar_url: z.string().nullable(),
|
|
67
|
+
is_creator: z.boolean(),
|
|
68
|
+
is_partner: z.boolean(),
|
|
69
|
+
})
|
|
70
|
+
.nullable()
|
|
71
|
+
.optional(),
|
|
72
|
+
created_at: z.string().datetime(),
|
|
73
|
+
updated_at: z.string().datetime(),
|
|
74
|
+
});
|
|
75
|
+
/* ─── Discovery query ──────────────────────────────────────────── */
|
|
76
|
+
export const hookSortSchema = z.enum(['trending', 'popular', 'newest', 'relevance']);
|
|
77
|
+
export const hookSearchQuerySchema = z.object({
|
|
78
|
+
q: z.string().trim().max(200).optional(),
|
|
79
|
+
event: hookEventSchema.optional(),
|
|
80
|
+
tag: z.string().optional(),
|
|
81
|
+
sort: hookSortSchema.default('trending'),
|
|
82
|
+
limit: z.coerce.number().int().min(1).max(100).default(24),
|
|
83
|
+
offset: z.coerce.number().int().nonnegative().default(0),
|
|
84
|
+
});
|
|
85
|
+
/* ─── Submit-by-URL ────────────────────────────────────────────── */
|
|
86
|
+
/**
|
|
87
|
+
* `POST /api/v1/hooks/submit` body — a user proposes a GitHub URL,
|
|
88
|
+
* the worker scans it. The endpoint dedupes pending scans by repo URL
|
|
89
|
+
* so spamming the form is harmless.
|
|
90
|
+
*/
|
|
91
|
+
export const submitHookByUrlSchema = z.object({
|
|
92
|
+
repo_url: z
|
|
93
|
+
.string()
|
|
94
|
+
.url()
|
|
95
|
+
.refine((s) => /^https?:\/\/(www\.)?github\.com\//i.test(s), 'Only GitHub repository URLs are supported'),
|
|
96
|
+
});
|
|
97
|
+
/* ─── Worker job payloads ──────────────────────────────────────── */
|
|
98
|
+
/**
|
|
99
|
+
* `github-hook-scan` queue payload. Scans one GitHub repo for
|
|
100
|
+
* `hook.json` files + sibling `claude/hooks/*.json`, validates them
|
|
101
|
+
* against `hookSchema`, secret-scans the command, upserts.
|
|
102
|
+
*/
|
|
103
|
+
export const scanGithubHookJobSchema = z.object({
|
|
104
|
+
repo_url: z.string().url(),
|
|
105
|
+
source: z.enum(['manual', 'seed', 'cron', 'submit']),
|
|
106
|
+
submitted_by: z.string().uuid().optional(),
|
|
107
|
+
});
|
|
108
|
+
/**
|
|
109
|
+
* `discover-github-hook` queue payload. Wide-scope GitHub code-search
|
|
110
|
+
* to find any public repo with a `hook.json` we don't already know.
|
|
111
|
+
*/
|
|
112
|
+
export const discoverGithubHookJobSchema = z.object({
|
|
113
|
+
query: z.string(),
|
|
114
|
+
max_repos: z.number().int().min(1).max(1000).default(300),
|
|
115
|
+
});
|
|
116
|
+
/** `index-hook` queue payload. */
|
|
117
|
+
export const indexHookJobSchema = z.object({
|
|
118
|
+
hook_id: z.string().uuid(),
|
|
119
|
+
op: z.enum(['upsert', 'delete']),
|
|
120
|
+
});
|
|
121
|
+
/** `describe-hook` queue payload — Haiku-generated description. */
|
|
122
|
+
export const describeHookJobSchema = z.object({
|
|
123
|
+
hook_id: z.string().uuid(),
|
|
124
|
+
force: z.boolean().optional(),
|
|
125
|
+
});
|
|
126
|
+
/* ─── Bulk sync (mirror of skills bulk sync) ───────────────────── */
|
|
127
|
+
export const hookBulkSyncInputSchema = z.object({
|
|
128
|
+
slugs: z.array(z.string().min(1).max(120)).min(1).max(250),
|
|
129
|
+
});
|
package/dist/schemas/index.d.ts
CHANGED
|
@@ -10,4 +10,6 @@ export * from './install.schema.js';
|
|
|
10
10
|
export * from './intelligence.schema.js';
|
|
11
11
|
export * from './api-keys.schema.js';
|
|
12
12
|
export * from './skill-report.schema.js';
|
|
13
|
+
export * from './security-audit.schema.js';
|
|
14
|
+
export * from './hook.schema.js';
|
|
13
15
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAA;AACxC,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,oBAAoB,CAAA;AAClC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,8BAA8B,CAAA;AAC5C,cAAc,yBAAyB,CAAA;AACvC,cAAc,qBAAqB,CAAA;AACnC,cAAc,qBAAqB,CAAA;AACnC,cAAc,0BAA0B,CAAA;AACxC,cAAc,sBAAsB,CAAA;AACpC,cAAc,0BAA0B,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAA;AACxC,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,oBAAoB,CAAA;AAClC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,8BAA8B,CAAA;AAC5C,cAAc,yBAAyB,CAAA;AACvC,cAAc,qBAAqB,CAAA;AACnC,cAAc,qBAAqB,CAAA;AACnC,cAAc,0BAA0B,CAAA;AACxC,cAAc,sBAAsB,CAAA;AACpC,cAAc,0BAA0B,CAAA;AACxC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,kBAAkB,CAAA"}
|
package/dist/schemas/index.js
CHANGED
|
@@ -40,6 +40,7 @@ export declare const installRowSchema: z.ZodObject<{
|
|
|
40
40
|
license: z.ZodDefault<z.ZodString>;
|
|
41
41
|
category: z.ZodNullable<z.ZodString>;
|
|
42
42
|
tags: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
43
|
+
extracted_triggers: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
43
44
|
install_count: z.ZodDefault<z.ZodNumber>;
|
|
44
45
|
bookmark_count: z.ZodDefault<z.ZodNumber>;
|
|
45
46
|
is_verified: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -123,6 +124,7 @@ export declare const installRowSchema: z.ZodObject<{
|
|
|
123
124
|
is_creator: boolean;
|
|
124
125
|
is_partner: boolean;
|
|
125
126
|
}>>>;
|
|
127
|
+
security_rating: z.ZodOptional<z.ZodNullable<z.ZodEnum<["trusted", "low_risk", "med_risk", "critical", "pending"]>>>;
|
|
126
128
|
created_at: z.ZodString;
|
|
127
129
|
updated_at: z.ZodString;
|
|
128
130
|
}, "id" | "updated_at" | "slug" | "name" | "description" | "visibility" | "license">, "strip", z.ZodTypeAny, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install.schema.d.ts","sourceRoot":"","sources":["../../src/schemas/install.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,4DAA4D;AAC5D,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;EAMxB,CAAA;AACF,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAA;AAEnD,wDAAwD;AACxD,eAAO,MAAM,gBAAgB
|
|
1
|
+
{"version":3,"file":"install.schema.d.ts","sourceRoot":"","sources":["../../src/schemas/install.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,4DAA4D;AAC5D,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;EAMxB,CAAA;AACF,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAA;AAEnD,wDAAwD;AACxD,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAU3B,iEAAiE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEjE,CAAA;AACF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAEzD,eAAO,MAAM,wBAAwB;IACnC,0EAA0E;;;;;;EAE1E,CAAA;AACF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAA"}
|
|
@@ -15,6 +15,7 @@ export declare const skillSearchHitSchema: z.ZodObject<{
|
|
|
15
15
|
license: z.ZodDefault<z.ZodString>;
|
|
16
16
|
category: z.ZodNullable<z.ZodString>;
|
|
17
17
|
tags: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
18
|
+
extracted_triggers: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
18
19
|
install_count: z.ZodDefault<z.ZodNumber>;
|
|
19
20
|
bookmark_count: z.ZodDefault<z.ZodNumber>;
|
|
20
21
|
is_verified: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -98,6 +99,7 @@ export declare const skillSearchHitSchema: z.ZodObject<{
|
|
|
98
99
|
is_creator: boolean;
|
|
99
100
|
is_partner: boolean;
|
|
100
101
|
}>>>;
|
|
102
|
+
security_rating: z.ZodOptional<z.ZodNullable<z.ZodEnum<["trusted", "low_risk", "med_risk", "critical", "pending"]>>>;
|
|
101
103
|
created_at: z.ZodString;
|
|
102
104
|
updated_at: z.ZodString;
|
|
103
105
|
} & {
|
|
@@ -118,6 +120,7 @@ export declare const skillSearchHitSchema: z.ZodObject<{
|
|
|
118
120
|
source_repo: string | null;
|
|
119
121
|
license: string;
|
|
120
122
|
tags: string[];
|
|
123
|
+
extracted_triggers: string[];
|
|
121
124
|
bookmark_count: number;
|
|
122
125
|
is_verified: boolean;
|
|
123
126
|
price_cents: number;
|
|
@@ -154,6 +157,7 @@ export declare const skillSearchHitSchema: z.ZodObject<{
|
|
|
154
157
|
is_creator: boolean;
|
|
155
158
|
is_partner: boolean;
|
|
156
159
|
} | null | undefined;
|
|
160
|
+
security_rating?: "trusted" | "low_risk" | "med_risk" | "critical" | "pending" | null | undefined;
|
|
157
161
|
score?: number | undefined;
|
|
158
162
|
highlight?: Record<string, string[]> | undefined;
|
|
159
163
|
}, {
|
|
@@ -171,6 +175,7 @@ export declare const skillSearchHitSchema: z.ZodObject<{
|
|
|
171
175
|
visibility?: "public" | "private" | undefined;
|
|
172
176
|
license?: string | undefined;
|
|
173
177
|
tags?: string[] | undefined;
|
|
178
|
+
extracted_triggers?: string[] | undefined;
|
|
174
179
|
bookmark_count?: number | undefined;
|
|
175
180
|
is_verified?: boolean | undefined;
|
|
176
181
|
price_cents?: number | undefined;
|
|
@@ -207,6 +212,7 @@ export declare const skillSearchHitSchema: z.ZodObject<{
|
|
|
207
212
|
is_creator: boolean;
|
|
208
213
|
is_partner: boolean;
|
|
209
214
|
} | null | undefined;
|
|
215
|
+
security_rating?: "trusted" | "low_risk" | "med_risk" | "critical" | "pending" | null | undefined;
|
|
210
216
|
score?: number | undefined;
|
|
211
217
|
highlight?: Record<string, string[]> | undefined;
|
|
212
218
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.schema.d.ts","sourceRoot":"","sources":["../../src/schemas/search.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB;;;GAGG;AACH,eAAO,MAAM,oBAAoB
|
|
1
|
+
{"version":3,"file":"search.schema.d.ts","sourceRoot":"","sources":["../../src/schemas/search.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB;;;GAGG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAG/B,CAAA;AACF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAA;AAEjE,gDAAgD;AAChD,eAAO,MAAM,mBAAmB;;;;;;;;;EAG9B,CAAA;AACF,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAE/D,gDAAgD;AAChD,eAAO,MAAM,mBAAmB;;;;;;;;;EAG9B,CAAA;AACF,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAE/D;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB;;IAEjC,iFAAiF;;;;;;;;EAEjF,CAAA;AACF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAA;AAErE;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB;IAClC,kFAAkF;;IAElF,0EAA0E;;;;;;;;EAE1E,CAAA;AACF,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAA"}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Per-skill security audit shape returned by
|
|
4
|
+
* `GET /api/v1/skills/:slug/security`. Three independent sources
|
|
5
|
+
* (GEN · Socket · Snyk) are aggregated into a single overall_rating
|
|
6
|
+
* using a worst-source-wins rule (see worker `security-audit.job.ts`).
|
|
7
|
+
*
|
|
8
|
+
* Missing API keys for Socket/Snyk surface as `unavailable` rather
|
|
9
|
+
* than crashing the audit — the UI renders them as a hairline-ringed
|
|
10
|
+
* pill labelled "Audit unavailable" without affecting the trusted/
|
|
11
|
+
* critical signal from the sources that did run.
|
|
12
|
+
*
|
|
13
|
+
* GEN always runs (no external dependency); a `trusted` overall_rating
|
|
14
|
+
* still requires gen_status = 'safe' even when both vendors are
|
|
15
|
+
* unavailable.
|
|
16
|
+
*/
|
|
17
|
+
export declare const securityFindingSeveritySchema: z.ZodEnum<["low", "medium", "high", "critical"]>;
|
|
18
|
+
export type SecurityFindingSeverity = z.infer<typeof securityFindingSeveritySchema>;
|
|
19
|
+
export declare const genFindingSchema: z.ZodObject<{
|
|
20
|
+
pattern: z.ZodString;
|
|
21
|
+
severity: z.ZodEnum<["warning", "danger"]>;
|
|
22
|
+
file: z.ZodString;
|
|
23
|
+
line: z.ZodNumber;
|
|
24
|
+
snippet: z.ZodString;
|
|
25
|
+
}, "strip", z.ZodTypeAny, {
|
|
26
|
+
pattern: string;
|
|
27
|
+
severity: "warning" | "danger";
|
|
28
|
+
file: string;
|
|
29
|
+
line: number;
|
|
30
|
+
snippet: string;
|
|
31
|
+
}, {
|
|
32
|
+
pattern: string;
|
|
33
|
+
severity: "warning" | "danger";
|
|
34
|
+
file: string;
|
|
35
|
+
line: number;
|
|
36
|
+
snippet: string;
|
|
37
|
+
}>;
|
|
38
|
+
export type GenFinding = z.infer<typeof genFindingSchema>;
|
|
39
|
+
export declare const socketAlertSchema: z.ZodObject<{
|
|
40
|
+
package: z.ZodString;
|
|
41
|
+
version: z.ZodOptional<z.ZodString>;
|
|
42
|
+
type: z.ZodString;
|
|
43
|
+
severity: z.ZodOptional<z.ZodString>;
|
|
44
|
+
description: z.ZodOptional<z.ZodString>;
|
|
45
|
+
}, "strip", z.ZodTypeAny, {
|
|
46
|
+
type: string;
|
|
47
|
+
package: string;
|
|
48
|
+
description?: string | undefined;
|
|
49
|
+
version?: string | undefined;
|
|
50
|
+
severity?: string | undefined;
|
|
51
|
+
}, {
|
|
52
|
+
type: string;
|
|
53
|
+
package: string;
|
|
54
|
+
description?: string | undefined;
|
|
55
|
+
version?: string | undefined;
|
|
56
|
+
severity?: string | undefined;
|
|
57
|
+
}>;
|
|
58
|
+
export type SocketAlert = z.infer<typeof socketAlertSchema>;
|
|
59
|
+
export declare const snykVulnSchema: z.ZodObject<{
|
|
60
|
+
package: z.ZodString;
|
|
61
|
+
version: z.ZodOptional<z.ZodString>;
|
|
62
|
+
id: z.ZodString;
|
|
63
|
+
severity: z.ZodEnum<["low", "medium", "high", "critical"]>;
|
|
64
|
+
title: z.ZodString;
|
|
65
|
+
url: z.ZodOptional<z.ZodString>;
|
|
66
|
+
}, "strip", z.ZodTypeAny, {
|
|
67
|
+
id: string;
|
|
68
|
+
severity: "critical" | "medium" | "low" | "high";
|
|
69
|
+
package: string;
|
|
70
|
+
title: string;
|
|
71
|
+
url?: string | undefined;
|
|
72
|
+
version?: string | undefined;
|
|
73
|
+
}, {
|
|
74
|
+
id: string;
|
|
75
|
+
severity: "critical" | "medium" | "low" | "high";
|
|
76
|
+
package: string;
|
|
77
|
+
title: string;
|
|
78
|
+
url?: string | undefined;
|
|
79
|
+
version?: string | undefined;
|
|
80
|
+
}>;
|
|
81
|
+
export type SnykVuln = z.infer<typeof snykVulnSchema>;
|
|
82
|
+
export declare const genStatusSchema: z.ZodEnum<["pending", "safe", "warning", "danger", "failed"]>;
|
|
83
|
+
export declare const socketStatusSchema: z.ZodEnum<["pending", "ok", "alerts", "unavailable", "failed"]>;
|
|
84
|
+
export declare const snykStatusSchema: z.ZodEnum<["pending", "ok", "low", "medium", "high", "critical", "unavailable", "failed"]>;
|
|
85
|
+
export declare const overallRatingSchema: z.ZodEnum<["pending", "trusted", "low_risk", "med_risk", "critical"]>;
|
|
86
|
+
export type GenStatus = z.infer<typeof genStatusSchema>;
|
|
87
|
+
export type SocketStatus = z.infer<typeof socketStatusSchema>;
|
|
88
|
+
export type SnykStatus = z.infer<typeof snykStatusSchema>;
|
|
89
|
+
export type OverallRating = z.infer<typeof overallRatingSchema>;
|
|
90
|
+
export declare const skillSecurityAuditSchema: z.ZodObject<{
|
|
91
|
+
skill_id: z.ZodString;
|
|
92
|
+
gen_status: z.ZodEnum<["pending", "safe", "warning", "danger", "failed"]>;
|
|
93
|
+
gen_findings: z.ZodArray<z.ZodObject<{
|
|
94
|
+
pattern: z.ZodString;
|
|
95
|
+
severity: z.ZodEnum<["warning", "danger"]>;
|
|
96
|
+
file: z.ZodString;
|
|
97
|
+
line: z.ZodNumber;
|
|
98
|
+
snippet: z.ZodString;
|
|
99
|
+
}, "strip", z.ZodTypeAny, {
|
|
100
|
+
pattern: string;
|
|
101
|
+
severity: "warning" | "danger";
|
|
102
|
+
file: string;
|
|
103
|
+
line: number;
|
|
104
|
+
snippet: string;
|
|
105
|
+
}, {
|
|
106
|
+
pattern: string;
|
|
107
|
+
severity: "warning" | "danger";
|
|
108
|
+
file: string;
|
|
109
|
+
line: number;
|
|
110
|
+
snippet: string;
|
|
111
|
+
}>, "many">;
|
|
112
|
+
socket_status: z.ZodEnum<["pending", "ok", "alerts", "unavailable", "failed"]>;
|
|
113
|
+
socket_alerts: z.ZodArray<z.ZodObject<{
|
|
114
|
+
package: z.ZodString;
|
|
115
|
+
version: z.ZodOptional<z.ZodString>;
|
|
116
|
+
type: z.ZodString;
|
|
117
|
+
severity: z.ZodOptional<z.ZodString>;
|
|
118
|
+
description: z.ZodOptional<z.ZodString>;
|
|
119
|
+
}, "strip", z.ZodTypeAny, {
|
|
120
|
+
type: string;
|
|
121
|
+
package: string;
|
|
122
|
+
description?: string | undefined;
|
|
123
|
+
version?: string | undefined;
|
|
124
|
+
severity?: string | undefined;
|
|
125
|
+
}, {
|
|
126
|
+
type: string;
|
|
127
|
+
package: string;
|
|
128
|
+
description?: string | undefined;
|
|
129
|
+
version?: string | undefined;
|
|
130
|
+
severity?: string | undefined;
|
|
131
|
+
}>, "many">;
|
|
132
|
+
snyk_status: z.ZodEnum<["pending", "ok", "low", "medium", "high", "critical", "unavailable", "failed"]>;
|
|
133
|
+
snyk_vulns: z.ZodArray<z.ZodObject<{
|
|
134
|
+
package: z.ZodString;
|
|
135
|
+
version: z.ZodOptional<z.ZodString>;
|
|
136
|
+
id: z.ZodString;
|
|
137
|
+
severity: z.ZodEnum<["low", "medium", "high", "critical"]>;
|
|
138
|
+
title: z.ZodString;
|
|
139
|
+
url: z.ZodOptional<z.ZodString>;
|
|
140
|
+
}, "strip", z.ZodTypeAny, {
|
|
141
|
+
id: string;
|
|
142
|
+
severity: "critical" | "medium" | "low" | "high";
|
|
143
|
+
package: string;
|
|
144
|
+
title: string;
|
|
145
|
+
url?: string | undefined;
|
|
146
|
+
version?: string | undefined;
|
|
147
|
+
}, {
|
|
148
|
+
id: string;
|
|
149
|
+
severity: "critical" | "medium" | "low" | "high";
|
|
150
|
+
package: string;
|
|
151
|
+
title: string;
|
|
152
|
+
url?: string | undefined;
|
|
153
|
+
version?: string | undefined;
|
|
154
|
+
}>, "many">;
|
|
155
|
+
overall_rating: z.ZodEnum<["pending", "trusted", "low_risk", "med_risk", "critical"]>;
|
|
156
|
+
audited_at: z.ZodNullable<z.ZodString>;
|
|
157
|
+
updated_at: z.ZodString;
|
|
158
|
+
}, "strip", z.ZodTypeAny, {
|
|
159
|
+
skill_id: string;
|
|
160
|
+
updated_at: string;
|
|
161
|
+
gen_status: "pending" | "failed" | "warning" | "danger" | "safe";
|
|
162
|
+
gen_findings: {
|
|
163
|
+
pattern: string;
|
|
164
|
+
severity: "warning" | "danger";
|
|
165
|
+
file: string;
|
|
166
|
+
line: number;
|
|
167
|
+
snippet: string;
|
|
168
|
+
}[];
|
|
169
|
+
socket_status: "pending" | "failed" | "ok" | "alerts" | "unavailable";
|
|
170
|
+
socket_alerts: {
|
|
171
|
+
type: string;
|
|
172
|
+
package: string;
|
|
173
|
+
description?: string | undefined;
|
|
174
|
+
version?: string | undefined;
|
|
175
|
+
severity?: string | undefined;
|
|
176
|
+
}[];
|
|
177
|
+
snyk_status: "critical" | "pending" | "failed" | "medium" | "low" | "high" | "ok" | "unavailable";
|
|
178
|
+
snyk_vulns: {
|
|
179
|
+
id: string;
|
|
180
|
+
severity: "critical" | "medium" | "low" | "high";
|
|
181
|
+
package: string;
|
|
182
|
+
title: string;
|
|
183
|
+
url?: string | undefined;
|
|
184
|
+
version?: string | undefined;
|
|
185
|
+
}[];
|
|
186
|
+
overall_rating: "trusted" | "low_risk" | "med_risk" | "critical" | "pending";
|
|
187
|
+
audited_at: string | null;
|
|
188
|
+
}, {
|
|
189
|
+
skill_id: string;
|
|
190
|
+
updated_at: string;
|
|
191
|
+
gen_status: "pending" | "failed" | "warning" | "danger" | "safe";
|
|
192
|
+
gen_findings: {
|
|
193
|
+
pattern: string;
|
|
194
|
+
severity: "warning" | "danger";
|
|
195
|
+
file: string;
|
|
196
|
+
line: number;
|
|
197
|
+
snippet: string;
|
|
198
|
+
}[];
|
|
199
|
+
socket_status: "pending" | "failed" | "ok" | "alerts" | "unavailable";
|
|
200
|
+
socket_alerts: {
|
|
201
|
+
type: string;
|
|
202
|
+
package: string;
|
|
203
|
+
description?: string | undefined;
|
|
204
|
+
version?: string | undefined;
|
|
205
|
+
severity?: string | undefined;
|
|
206
|
+
}[];
|
|
207
|
+
snyk_status: "critical" | "pending" | "failed" | "medium" | "low" | "high" | "ok" | "unavailable";
|
|
208
|
+
snyk_vulns: {
|
|
209
|
+
id: string;
|
|
210
|
+
severity: "critical" | "medium" | "low" | "high";
|
|
211
|
+
package: string;
|
|
212
|
+
title: string;
|
|
213
|
+
url?: string | undefined;
|
|
214
|
+
version?: string | undefined;
|
|
215
|
+
}[];
|
|
216
|
+
overall_rating: "trusted" | "low_risk" | "med_risk" | "critical" | "pending";
|
|
217
|
+
audited_at: string | null;
|
|
218
|
+
}>;
|
|
219
|
+
export type SkillSecurityAudit = z.infer<typeof skillSecurityAuditSchema>;
|
|
220
|
+
/**
|
|
221
|
+
* BullMQ job payload for the worker's `security-audit` queue.
|
|
222
|
+
* Enqueued from three places:
|
|
223
|
+
* • the Postgres trigger (via the outbox-style pending row)
|
|
224
|
+
* • scan-github-repo, immediately after a skill upsert
|
|
225
|
+
* • the API's manual `POST /skills/:slug/security/rescan`
|
|
226
|
+
*/
|
|
227
|
+
export interface SecurityAuditJob {
|
|
228
|
+
skill_id: string;
|
|
229
|
+
trigger?: 'scan' | 'trigger' | 'rescan' | 'backfill' | 'cron';
|
|
230
|
+
}
|
|
231
|
+
//# sourceMappingURL=security-audit.schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security-audit.schema.d.ts","sourceRoot":"","sources":["../../src/schemas/security-audit.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB;;;;;;;;;;;;;;GAcG;AAEH,eAAO,MAAM,6BAA6B,kDAAgD,CAAA;AAC1F,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAA;AAEnF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;EAM3B,CAAA;AACF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAEzD,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;EAM5B,CAAA;AACF,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAE3D,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;EAOzB,CAAA;AACF,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;AAErD,eAAO,MAAM,eAAe,+DAA6D,CAAA;AACzF,eAAO,MAAM,kBAAkB,iEAM7B,CAAA;AACF,eAAO,MAAM,gBAAgB,4FAS3B,CAAA;AACF,eAAO,MAAM,mBAAmB,uEAM9B,CAAA;AAEF,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA;AACvD,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAA;AAC7D,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AACzD,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAE/D,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWnC,CAAA;AACF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAA;AAEzE;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,CAAA;CAC9D"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Per-skill security audit shape returned by
|
|
4
|
+
* `GET /api/v1/skills/:slug/security`. Three independent sources
|
|
5
|
+
* (GEN · Socket · Snyk) are aggregated into a single overall_rating
|
|
6
|
+
* using a worst-source-wins rule (see worker `security-audit.job.ts`).
|
|
7
|
+
*
|
|
8
|
+
* Missing API keys for Socket/Snyk surface as `unavailable` rather
|
|
9
|
+
* than crashing the audit — the UI renders them as a hairline-ringed
|
|
10
|
+
* pill labelled "Audit unavailable" without affecting the trusted/
|
|
11
|
+
* critical signal from the sources that did run.
|
|
12
|
+
*
|
|
13
|
+
* GEN always runs (no external dependency); a `trusted` overall_rating
|
|
14
|
+
* still requires gen_status = 'safe' even when both vendors are
|
|
15
|
+
* unavailable.
|
|
16
|
+
*/
|
|
17
|
+
export const securityFindingSeveritySchema = z.enum(['low', 'medium', 'high', 'critical']);
|
|
18
|
+
export const genFindingSchema = z.object({
|
|
19
|
+
pattern: z.string(),
|
|
20
|
+
severity: z.enum(['warning', 'danger']),
|
|
21
|
+
file: z.string(),
|
|
22
|
+
line: z.number().int().nonnegative(),
|
|
23
|
+
snippet: z.string().max(240),
|
|
24
|
+
});
|
|
25
|
+
export const socketAlertSchema = z.object({
|
|
26
|
+
package: z.string(),
|
|
27
|
+
version: z.string().optional(),
|
|
28
|
+
type: z.string(),
|
|
29
|
+
severity: z.string().optional(),
|
|
30
|
+
description: z.string().optional(),
|
|
31
|
+
});
|
|
32
|
+
export const snykVulnSchema = z.object({
|
|
33
|
+
package: z.string(),
|
|
34
|
+
version: z.string().optional(),
|
|
35
|
+
id: z.string(),
|
|
36
|
+
severity: securityFindingSeveritySchema,
|
|
37
|
+
title: z.string(),
|
|
38
|
+
url: z.string().url().optional(),
|
|
39
|
+
});
|
|
40
|
+
export const genStatusSchema = z.enum(['pending', 'safe', 'warning', 'danger', 'failed']);
|
|
41
|
+
export const socketStatusSchema = z.enum([
|
|
42
|
+
'pending',
|
|
43
|
+
'ok',
|
|
44
|
+
'alerts',
|
|
45
|
+
'unavailable',
|
|
46
|
+
'failed',
|
|
47
|
+
]);
|
|
48
|
+
export const snykStatusSchema = z.enum([
|
|
49
|
+
'pending',
|
|
50
|
+
'ok',
|
|
51
|
+
'low',
|
|
52
|
+
'medium',
|
|
53
|
+
'high',
|
|
54
|
+
'critical',
|
|
55
|
+
'unavailable',
|
|
56
|
+
'failed',
|
|
57
|
+
]);
|
|
58
|
+
export const overallRatingSchema = z.enum([
|
|
59
|
+
'pending',
|
|
60
|
+
'trusted',
|
|
61
|
+
'low_risk',
|
|
62
|
+
'med_risk',
|
|
63
|
+
'critical',
|
|
64
|
+
]);
|
|
65
|
+
export const skillSecurityAuditSchema = z.object({
|
|
66
|
+
skill_id: z.string().uuid(),
|
|
67
|
+
gen_status: genStatusSchema,
|
|
68
|
+
gen_findings: z.array(genFindingSchema),
|
|
69
|
+
socket_status: socketStatusSchema,
|
|
70
|
+
socket_alerts: z.array(socketAlertSchema),
|
|
71
|
+
snyk_status: snykStatusSchema,
|
|
72
|
+
snyk_vulns: z.array(snykVulnSchema),
|
|
73
|
+
overall_rating: overallRatingSchema,
|
|
74
|
+
audited_at: z.string().datetime().nullable(),
|
|
75
|
+
updated_at: z.string().datetime(),
|
|
76
|
+
});
|
|
@@ -44,6 +44,7 @@ export declare const dependencyRowSchema: z.ZodObject<{
|
|
|
44
44
|
license: z.ZodDefault<z.ZodString>;
|
|
45
45
|
category: z.ZodNullable<z.ZodString>;
|
|
46
46
|
tags: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
47
|
+
extracted_triggers: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
47
48
|
install_count: z.ZodDefault<z.ZodNumber>;
|
|
48
49
|
bookmark_count: z.ZodDefault<z.ZodNumber>;
|
|
49
50
|
is_verified: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -127,6 +128,7 @@ export declare const dependencyRowSchema: z.ZodObject<{
|
|
|
127
128
|
is_creator: boolean;
|
|
128
129
|
is_partner: boolean;
|
|
129
130
|
}>>>;
|
|
131
|
+
security_rating: z.ZodOptional<z.ZodNullable<z.ZodEnum<["trusted", "low_risk", "med_risk", "critical", "pending"]>>>;
|
|
130
132
|
created_at: z.ZodString;
|
|
131
133
|
updated_at: z.ZodString;
|
|
132
134
|
}, "id" | "slug" | "name" | "description" | "visibility">, "strip", z.ZodTypeAny, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill-dependency.schema.d.ts","sourceRoot":"","sources":["../../src/schemas/skill-dependency.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,4EAA4E;AAC5E,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;EAMhC,CAAA;AACF,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA;AAEnE;;;;GAIG;AACH,eAAO,MAAM,mBAAmB
|
|
1
|
+
{"version":3,"file":"skill-dependency.schema.d.ts","sourceRoot":"","sources":["../../src/schemas/skill-dependency.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,4EAA4E;AAC5E,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;EAMhC,CAAA;AACF,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA;AAEnE;;;;GAIG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAQ9B,CAAA;AACF,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAE/D,+CAA+C;AAC/C,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,+DAA+D;AAC/D,MAAM,WAAW,oBAAoB;IACnC,aAAa,EAAE,MAAM,CAAA;IACrB,KAAK,EAAE,kBAAkB,EAAE,CAAA;IAC3B,SAAS,EAAE,kBAAkB,EAAE,CAAA;CAChC;AAED,yEAAyE;AACzE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,KAAK,CAAC;QAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,GAAG,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAA;CAC3D;AAED,eAAO,MAAM,wBAAwB;;;;;;;;;;;;EAOnC,CAAA;AACF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAA"}
|
|
@@ -70,6 +70,17 @@ export declare const skillSchema: z.ZodObject<{
|
|
|
70
70
|
license: z.ZodDefault<z.ZodString>;
|
|
71
71
|
category: z.ZodNullable<z.ZodString>;
|
|
72
72
|
tags: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
73
|
+
/**
|
|
74
|
+
* Server-extracted triggers — parsed from the SKILL.md content by
|
|
75
|
+
* `extract_triggers_from_md()` (migration 057). Frontmatter
|
|
76
|
+
* `triggers:` list plus prose patterns ("Load on …", "Triggers: …",
|
|
77
|
+
* "Auto-loads when …"). Recomputed on every content write via the
|
|
78
|
+
* `skills_refresh_extracted_triggers` trigger so the value never
|
|
79
|
+
* drifts. The Discover detail page renders these as chips and only
|
|
80
|
+
* falls back to tags / "Claude reads the description" when this
|
|
81
|
+
* array is empty.
|
|
82
|
+
*/
|
|
83
|
+
extracted_triggers: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
73
84
|
install_count: z.ZodDefault<z.ZodNumber>;
|
|
74
85
|
bookmark_count: z.ZodDefault<z.ZodNumber>;
|
|
75
86
|
is_verified: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -165,6 +176,14 @@ export declare const skillSchema: z.ZodObject<{
|
|
|
165
176
|
is_creator: boolean;
|
|
166
177
|
is_partner: boolean;
|
|
167
178
|
}>>>;
|
|
179
|
+
/**
|
|
180
|
+
* Attached by the API on list + detail GETs once the worker has
|
|
181
|
+
* audited this skill. `null` = audit row exists but is still
|
|
182
|
+
* pending; `undefined` = no audit row at all (pre-trigger backlog).
|
|
183
|
+
* Cards + the detail page render a `SecurityBadge` from this value
|
|
184
|
+
* so the user can see the rating before opening anything.
|
|
185
|
+
*/
|
|
186
|
+
security_rating: z.ZodOptional<z.ZodNullable<z.ZodEnum<["trusted", "low_risk", "med_risk", "critical", "pending"]>>>;
|
|
168
187
|
created_at: z.ZodString;
|
|
169
188
|
updated_at: z.ZodString;
|
|
170
189
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -182,6 +201,7 @@ export declare const skillSchema: z.ZodObject<{
|
|
|
182
201
|
source_repo: string | null;
|
|
183
202
|
license: string;
|
|
184
203
|
tags: string[];
|
|
204
|
+
extracted_triggers: string[];
|
|
185
205
|
bookmark_count: number;
|
|
186
206
|
is_verified: boolean;
|
|
187
207
|
price_cents: number;
|
|
@@ -218,6 +238,7 @@ export declare const skillSchema: z.ZodObject<{
|
|
|
218
238
|
is_creator: boolean;
|
|
219
239
|
is_partner: boolean;
|
|
220
240
|
} | null | undefined;
|
|
241
|
+
security_rating?: "trusted" | "low_risk" | "med_risk" | "critical" | "pending" | null | undefined;
|
|
221
242
|
}, {
|
|
222
243
|
id: string;
|
|
223
244
|
content: string | null;
|
|
@@ -233,6 +254,7 @@ export declare const skillSchema: z.ZodObject<{
|
|
|
233
254
|
visibility?: "public" | "private" | undefined;
|
|
234
255
|
license?: string | undefined;
|
|
235
256
|
tags?: string[] | undefined;
|
|
257
|
+
extracted_triggers?: string[] | undefined;
|
|
236
258
|
bookmark_count?: number | undefined;
|
|
237
259
|
is_verified?: boolean | undefined;
|
|
238
260
|
price_cents?: number | undefined;
|
|
@@ -269,6 +291,7 @@ export declare const skillSchema: z.ZodObject<{
|
|
|
269
291
|
is_creator: boolean;
|
|
270
292
|
is_partner: boolean;
|
|
271
293
|
} | null | undefined;
|
|
294
|
+
security_rating?: "trusted" | "low_risk" | "med_risk" | "critical" | "pending" | null | undefined;
|
|
272
295
|
}>;
|
|
273
296
|
export type Skill = z.infer<typeof skillSchema>;
|
|
274
297
|
export declare const createSkillInputSchema: z.ZodObject<{
|
|
@@ -494,14 +517,26 @@ export declare const autoSkillFromRepoRequestSchema: z.ZodObject<{
|
|
|
494
517
|
* behind an "Advanced" disclosure in the wizard.
|
|
495
518
|
*/
|
|
496
519
|
custom_instructions: z.ZodOptional<z.ZodString>;
|
|
520
|
+
/**
|
|
521
|
+
* Optional display name override. When empty, the generator picks
|
|
522
|
+
* a name from the README / repo title — which historically went
|
|
523
|
+
* long ("Testing Node/TypeScript API and React Web Apps") and
|
|
524
|
+
* looked terrible in the sidebar / project switcher. The wizard
|
|
525
|
+
* surfaces this on step 1 as a soft suggestion so users can
|
|
526
|
+
* shorten the title up front without round-tripping through the
|
|
527
|
+
* editor settings drawer.
|
|
528
|
+
*/
|
|
529
|
+
name: z.ZodOptional<z.ZodString>;
|
|
497
530
|
}, "strip", z.ZodTypeAny, {
|
|
498
531
|
repo_url: string;
|
|
532
|
+
name?: string | undefined;
|
|
499
533
|
category?: string | undefined;
|
|
500
534
|
focus?: string | undefined;
|
|
501
535
|
triggers?: string[] | undefined;
|
|
502
536
|
custom_instructions?: string | undefined;
|
|
503
537
|
}, {
|
|
504
538
|
repo_url: string;
|
|
539
|
+
name?: string | undefined;
|
|
505
540
|
category?: string | undefined;
|
|
506
541
|
focus?: string | undefined;
|
|
507
542
|
triggers?: string[] | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill.schema.d.ts","sourceRoot":"","sources":["../../src/schemas/skill.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,eAAO,MAAM,qBAAqB,kCAAgC,CAAA;AAClE,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA;AAEnE;;;GAGG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;EAS1B,CAAA;AACF,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA;AAEvD,iFAAiF;AACjF,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;EAO5B,CAAA;AACF,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAE3D,eAAO,MAAM,WAAW
|
|
1
|
+
{"version":3,"file":"skill.schema.d.ts","sourceRoot":"","sources":["../../src/schemas/skill.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,eAAO,MAAM,qBAAqB,kCAAgC,CAAA;AAClE,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA;AAEnE;;;GAGG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;EAS1B,CAAA;AACF,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA;AAEvD,iFAAiF;AACjF,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;EAO5B,CAAA;AACF,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAE3D,eAAO,MAAM,WAAW;;;;;;;;;;;;IAgBtB;;;;;;;;;OASG;;;;;;;IAQH;;;;;OAKG;;;;IAIH,kEAAkE;;;;;;;;;;;;;;;;;;;;;;;IAElE,6DAA6D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAE7D,6EAA6E;;IAE7E,mEAAmE;;IAEnE,+EAA+E;;IAE/E,gGAAgG;;;;;;;;;;;;;;;;;;;;;;;IAYhG;;;;;;OAMG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAOH,CAAA;AACF,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAA;AAE/C,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;IA4B/B,2EAA2E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAW3E,CAAA;AACJ,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAA;AAErE,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEjC,CAAA;AACF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAA;AAErE,eAAO,MAAM,eAAe,2DAAyD,CAAA;AACrF,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA;AAEvD,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;EAOjC,CAAA;AACF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAA;AAErE,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;EAE9B,CAAA;AACF,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAI/D;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B;;IAQzC;;;OAGG;;IAEH;;;;;;;OAOG;;IAEH;;;;;OAKG;;IAEH;;;;;;OAMG;;IAEH;;;;;;;;OAQG;;;;;;;;;;;;;;;;EAEH,CAAA;AACF,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAA;AAIrF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB;;;;;;EAE9B,CAAA;AACF,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAE/D;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,OAAO,CAAA;IAClB,QAAQ,EAAE,OAAO,CAAA;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,YAAY,EAAE,CAAA;IACrB,6EAA6E;IAC7E,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB"}
|
|
@@ -39,6 +39,17 @@ export const skillSchema = z.object({
|
|
|
39
39
|
license: z.string().default('MIT'),
|
|
40
40
|
category: z.string().nullable(),
|
|
41
41
|
tags: z.array(z.string()).default([]),
|
|
42
|
+
/**
|
|
43
|
+
* Server-extracted triggers — parsed from the SKILL.md content by
|
|
44
|
+
* `extract_triggers_from_md()` (migration 057). Frontmatter
|
|
45
|
+
* `triggers:` list plus prose patterns ("Load on …", "Triggers: …",
|
|
46
|
+
* "Auto-loads when …"). Recomputed on every content write via the
|
|
47
|
+
* `skills_refresh_extracted_triggers` trigger so the value never
|
|
48
|
+
* drifts. The Discover detail page renders these as chips and only
|
|
49
|
+
* falls back to tags / "Claude reads the description" when this
|
|
50
|
+
* array is empty.
|
|
51
|
+
*/
|
|
52
|
+
extracted_triggers: z.array(z.string()).default([]),
|
|
42
53
|
install_count: z.number().int().nonnegative().default(0),
|
|
43
54
|
bookmark_count: z.number().int().nonnegative().default(0),
|
|
44
55
|
is_verified: z.boolean().default(false),
|
|
@@ -75,6 +86,17 @@ export const skillSchema = z.object({
|
|
|
75
86
|
})
|
|
76
87
|
.nullable()
|
|
77
88
|
.optional(),
|
|
89
|
+
/**
|
|
90
|
+
* Attached by the API on list + detail GETs once the worker has
|
|
91
|
+
* audited this skill. `null` = audit row exists but is still
|
|
92
|
+
* pending; `undefined` = no audit row at all (pre-trigger backlog).
|
|
93
|
+
* Cards + the detail page render a `SecurityBadge` from this value
|
|
94
|
+
* so the user can see the rating before opening anything.
|
|
95
|
+
*/
|
|
96
|
+
security_rating: z
|
|
97
|
+
.enum(['trusted', 'low_risk', 'med_risk', 'critical', 'pending'])
|
|
98
|
+
.nullable()
|
|
99
|
+
.optional(),
|
|
78
100
|
created_at: z.string().datetime(),
|
|
79
101
|
updated_at: z.string().datetime(),
|
|
80
102
|
});
|
|
@@ -172,6 +194,16 @@ export const autoSkillFromRepoRequestSchema = z.object({
|
|
|
172
194
|
* behind an "Advanced" disclosure in the wizard.
|
|
173
195
|
*/
|
|
174
196
|
custom_instructions: z.string().min(1).max(800).optional(),
|
|
197
|
+
/**
|
|
198
|
+
* Optional display name override. When empty, the generator picks
|
|
199
|
+
* a name from the README / repo title — which historically went
|
|
200
|
+
* long ("Testing Node/TypeScript API and React Web Apps") and
|
|
201
|
+
* looked terrible in the sidebar / project switcher. The wizard
|
|
202
|
+
* surfaces this on step 1 as a soft suggestion so users can
|
|
203
|
+
* shorten the title up front without round-tripping through the
|
|
204
|
+
* editor settings drawer.
|
|
205
|
+
*/
|
|
206
|
+
name: z.string().trim().min(1).max(60).optional(),
|
|
175
207
|
});
|
|
176
208
|
/* ─── Bulk sync — used by `prave sync` ─────────────────────────── */
|
|
177
209
|
/**
|