@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.
@@ -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
+ });
@@ -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"}
@@ -10,3 +10,5 @@ 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';
@@ -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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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"}
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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"}
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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"}
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":"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"}
1
+ {"version":3,"file":"skill.schema.d.ts","sourceRoot":"","sources":["../../src/schemas/skill.schema.ts"],"names":[],"mappings":"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"}
@@ -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
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prave/shared",
3
- "version": "1.4.15",
3
+ "version": "1.5.0",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"