@prave/shared 1.4.16 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,167 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Contextual Skill Advisor — prose recommendations behind a tiered
4
+ * freemium quota. See `apps/api/src/services/advisor.service.ts` for
5
+ * the orchestrator; the schemas below pin the request, response, and
6
+ * LLM-output shapes so a model drift on the Haiku side gets caught at
7
+ * the Zod boundary, not in the UI.
8
+ */
9
+ export declare const advisorModeSchema: z.ZodEnum<["manual", "auto"]>;
10
+ export type AdvisorMode = z.infer<typeof advisorModeSchema>;
11
+ export declare const advisorRequestSchema: z.ZodEffects<z.ZodObject<{
12
+ mode: z.ZodDefault<z.ZodEnum<["manual", "auto"]>>;
13
+ /**
14
+ * Task description for manual mode. Required when `mode === 'manual'`,
15
+ * ignored when `mode === 'auto'`. We cap at 1200 chars so a long
16
+ * paste can't blow the Haiku prompt window — the input field on the
17
+ * web side enforces the same limit.
18
+ */
19
+ task: z.ZodOptional<z.ZodString>;
20
+ }, "strip", z.ZodTypeAny, {
21
+ mode: "manual" | "auto";
22
+ task?: string | undefined;
23
+ }, {
24
+ mode?: "manual" | "auto" | undefined;
25
+ task?: string | undefined;
26
+ }>, {
27
+ mode: "manual" | "auto";
28
+ task?: string | undefined;
29
+ }, {
30
+ mode?: "manual" | "auto" | undefined;
31
+ task?: string | undefined;
32
+ }>;
33
+ export type AdvisorRequest = z.infer<typeof advisorRequestSchema>;
34
+ /**
35
+ * One recommended skill in the advisor's response. `slug` is always a
36
+ * real catalogue slug — the service drops anything Haiku invented
37
+ * before the response leaves the API.
38
+ */
39
+ export declare const advisorRecommendationSchema: z.ZodObject<{
40
+ slug: z.ZodString;
41
+ reason: z.ZodString;
42
+ }, "strip", z.ZodTypeAny, {
43
+ slug: string;
44
+ reason: string;
45
+ }, {
46
+ slug: string;
47
+ reason: string;
48
+ }>;
49
+ export type AdvisorRecommendation = z.infer<typeof advisorRecommendationSchema>;
50
+ export declare const advisorResponseSchema: z.ZodObject<{
51
+ /**
52
+ * Prose paragraph the model writes. Calmly-cased, no markdown
53
+ * fences, no emoji. The web result block renders this verbatim.
54
+ */
55
+ prose: z.ZodString;
56
+ recommendations: z.ZodArray<z.ZodObject<{
57
+ slug: z.ZodString;
58
+ reason: z.ZodString;
59
+ }, "strip", z.ZodTypeAny, {
60
+ slug: string;
61
+ reason: string;
62
+ }, {
63
+ slug: string;
64
+ reason: string;
65
+ }>, "many">;
66
+ /**
67
+ * Echoed for telemetry + cache-bust debugging. The UI doesn't render
68
+ * this but the analytics layer does.
69
+ */
70
+ mode: z.ZodEnum<["manual", "auto"]>;
71
+ /**
72
+ * After-this-call quota snapshot — saves the web UI a round-trip
73
+ * back to `GET /advisor/quota` immediately after a success.
74
+ */
75
+ quota: z.ZodObject<{
76
+ plan: z.ZodEnum<["free", "pro", "max"]>;
77
+ limit: z.ZodNumber;
78
+ used: z.ZodNumber;
79
+ remaining: z.ZodNumber;
80
+ }, "strip", z.ZodTypeAny, {
81
+ limit: number;
82
+ plan: "free" | "pro" | "max";
83
+ used: number;
84
+ remaining: number;
85
+ }, {
86
+ limit: number;
87
+ plan: "free" | "pro" | "max";
88
+ used: number;
89
+ remaining: number;
90
+ }>;
91
+ }, "strip", z.ZodTypeAny, {
92
+ mode: "manual" | "auto";
93
+ prose: string;
94
+ recommendations: {
95
+ slug: string;
96
+ reason: string;
97
+ }[];
98
+ quota: {
99
+ limit: number;
100
+ plan: "free" | "pro" | "max";
101
+ used: number;
102
+ remaining: number;
103
+ };
104
+ }, {
105
+ mode: "manual" | "auto";
106
+ prose: string;
107
+ recommendations: {
108
+ slug: string;
109
+ reason: string;
110
+ }[];
111
+ quota: {
112
+ limit: number;
113
+ plan: "free" | "pro" | "max";
114
+ used: number;
115
+ remaining: number;
116
+ };
117
+ }>;
118
+ export type AdvisorResponse = z.infer<typeof advisorResponseSchema>;
119
+ export declare const advisorQuotaResponseSchema: z.ZodObject<{
120
+ plan: z.ZodEnum<["free", "pro", "max"]>;
121
+ limit: z.ZodNumber;
122
+ used: z.ZodNumber;
123
+ remaining: z.ZodNumber;
124
+ }, "strip", z.ZodTypeAny, {
125
+ limit: number;
126
+ plan: "free" | "pro" | "max";
127
+ used: number;
128
+ remaining: number;
129
+ }, {
130
+ limit: number;
131
+ plan: "free" | "pro" | "max";
132
+ used: number;
133
+ remaining: number;
134
+ }>;
135
+ export type AdvisorQuotaResponse = z.infer<typeof advisorQuotaResponseSchema>;
136
+ /**
137
+ * Raw Haiku JSON shape — what the model is told to produce. Validated
138
+ * inside the service; mismatches throw `HttpError.internal` so the
139
+ * caller gets a clean 500 rather than half-rendered garbage.
140
+ */
141
+ export declare const advisorLlmOutputSchema: z.ZodObject<{
142
+ prose: z.ZodString;
143
+ recommendations: z.ZodArray<z.ZodObject<{
144
+ slug: z.ZodString;
145
+ reason: z.ZodString;
146
+ }, "strip", z.ZodTypeAny, {
147
+ slug: string;
148
+ reason: string;
149
+ }, {
150
+ slug: string;
151
+ reason: string;
152
+ }>, "many">;
153
+ }, "strip", z.ZodTypeAny, {
154
+ prose: string;
155
+ recommendations: {
156
+ slug: string;
157
+ reason: string;
158
+ }[];
159
+ }, {
160
+ prose: string;
161
+ recommendations: {
162
+ slug: string;
163
+ reason: string;
164
+ }[];
165
+ }>;
166
+ export type AdvisorLlmOutput = z.infer<typeof advisorLlmOutputSchema>;
167
+ //# sourceMappingURL=advisor.schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"advisor.schema.d.ts","sourceRoot":"","sources":["../../src/schemas/advisor.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB;;;;;;GAMG;AAEH,eAAO,MAAM,iBAAiB,+BAA6B,CAAA;AAC3D,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAE3D,eAAO,MAAM,oBAAoB;;IAG7B;;;;;OAKG;;;;;;;;;;;;;;EAWH,CAAA;AACJ,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAA;AAEjE;;;;GAIG;AACH,eAAO,MAAM,2BAA2B;;;;;;;;;EAGtC,CAAA;AACF,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAA;AAE/E,eAAO,MAAM,qBAAqB;IAChC;;;OAGG;;;;;;;;;;;;IAGH;;;OAGG;;IAEH;;;OAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAOH,CAAA;AACF,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA;AAEnE,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;EAAoC,CAAA;AAC3E,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAA;AAE7E;;;;GAIG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;EAUjC,CAAA;AACF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAA"}
@@ -0,0 +1,76 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Contextual Skill Advisor — prose recommendations behind a tiered
4
+ * freemium quota. See `apps/api/src/services/advisor.service.ts` for
5
+ * the orchestrator; the schemas below pin the request, response, and
6
+ * LLM-output shapes so a model drift on the Haiku side gets caught at
7
+ * the Zod boundary, not in the UI.
8
+ */
9
+ export const advisorModeSchema = z.enum(['manual', 'auto']);
10
+ export const advisorRequestSchema = z
11
+ .object({
12
+ mode: advisorModeSchema.default('manual'),
13
+ /**
14
+ * Task description for manual mode. Required when `mode === 'manual'`,
15
+ * ignored when `mode === 'auto'`. We cap at 1200 chars so a long
16
+ * paste can't blow the Haiku prompt window — the input field on the
17
+ * web side enforces the same limit.
18
+ */
19
+ task: z.string().trim().min(8).max(1200).optional(),
20
+ })
21
+ .superRefine((val, ctx) => {
22
+ if (val.mode === 'manual' && (!val.task || val.task.length < 8)) {
23
+ ctx.addIssue({
24
+ code: z.ZodIssueCode.custom,
25
+ path: ['task'],
26
+ message: 'Manual mode needs at least 8 characters of task description.',
27
+ });
28
+ }
29
+ });
30
+ /**
31
+ * One recommended skill in the advisor's response. `slug` is always a
32
+ * real catalogue slug — the service drops anything Haiku invented
33
+ * before the response leaves the API.
34
+ */
35
+ export const advisorRecommendationSchema = z.object({
36
+ slug: z.string().min(1).max(120),
37
+ reason: z.string().min(1).max(400),
38
+ });
39
+ export const advisorResponseSchema = z.object({
40
+ /**
41
+ * Prose paragraph the model writes. Calmly-cased, no markdown
42
+ * fences, no emoji. The web result block renders this verbatim.
43
+ */
44
+ prose: z.string().min(1).max(2400),
45
+ recommendations: z.array(advisorRecommendationSchema).max(5),
46
+ /**
47
+ * Echoed for telemetry + cache-bust debugging. The UI doesn't render
48
+ * this but the analytics layer does.
49
+ */
50
+ mode: advisorModeSchema,
51
+ /**
52
+ * After-this-call quota snapshot — saves the web UI a round-trip
53
+ * back to `GET /advisor/quota` immediately after a success.
54
+ */
55
+ quota: z.object({
56
+ plan: z.enum(['free', 'pro', 'max']),
57
+ limit: z.number().int().nonnegative(),
58
+ used: z.number().int().nonnegative(),
59
+ remaining: z.number().int().nonnegative(),
60
+ }),
61
+ });
62
+ export const advisorQuotaResponseSchema = advisorResponseSchema.shape.quota;
63
+ /**
64
+ * Raw Haiku JSON shape — what the model is told to produce. Validated
65
+ * inside the service; mismatches throw `HttpError.internal` so the
66
+ * caller gets a clean 500 rather than half-rendered garbage.
67
+ */
68
+ export const advisorLlmOutputSchema = z.object({
69
+ prose: z.string().min(1).max(2400),
70
+ recommendations: z
71
+ .array(z.object({
72
+ slug: z.string().min(1).max(120),
73
+ reason: z.string().min(1).max(400),
74
+ }))
75
+ .max(8), // accept up to 8 so we can drop hallucinations before capping to 5
76
+ });
@@ -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,7 @@ 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';
15
+ export * from './advisor.schema.js';
13
16
  //# 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;AAChC,cAAc,qBAAqB,CAAA"}
@@ -10,3 +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';
15
+ export * from './advisor.schema.js';
@@ -124,6 +124,7 @@ export declare const installRowSchema: z.ZodObject<{
124
124
  is_creator: boolean;
125
125
  is_partner: boolean;
126
126
  }>>>;
127
+ security_rating: z.ZodOptional<z.ZodNullable<z.ZodEnum<["trusted", "low_risk", "med_risk", "critical", "pending"]>>>;
127
128
  created_at: z.ZodString;
128
129
  updated_at: z.ZodString;
129
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"}
@@ -99,6 +99,7 @@ export declare const skillSearchHitSchema: z.ZodObject<{
99
99
  is_creator: boolean;
100
100
  is_partner: boolean;
101
101
  }>>>;
102
+ security_rating: z.ZodOptional<z.ZodNullable<z.ZodEnum<["trusted", "low_risk", "med_risk", "critical", "pending"]>>>;
102
103
  created_at: z.ZodString;
103
104
  updated_at: z.ZodString;
104
105
  } & {
@@ -156,6 +157,7 @@ export declare const skillSearchHitSchema: z.ZodObject<{
156
157
  is_creator: boolean;
157
158
  is_partner: boolean;
158
159
  } | null | undefined;
160
+ security_rating?: "trusted" | "low_risk" | "med_risk" | "critical" | "pending" | null | undefined;
159
161
  score?: number | undefined;
160
162
  highlight?: Record<string, string[]> | undefined;
161
163
  }, {
@@ -210,6 +212,7 @@ export declare const skillSearchHitSchema: z.ZodObject<{
210
212
  is_creator: boolean;
211
213
  is_partner: boolean;
212
214
  } | null | undefined;
215
+ security_rating?: "trusted" | "low_risk" | "med_risk" | "critical" | "pending" | null | undefined;
213
216
  score?: number | undefined;
214
217
  highlight?: Record<string, string[]> | undefined;
215
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
+ });
@@ -128,6 +128,7 @@ export declare const dependencyRowSchema: z.ZodObject<{
128
128
  is_creator: boolean;
129
129
  is_partner: boolean;
130
130
  }>>>;
131
+ security_rating: z.ZodOptional<z.ZodNullable<z.ZodEnum<["trusted", "low_risk", "med_risk", "critical", "pending"]>>>;
131
132
  created_at: z.ZodString;
132
133
  updated_at: z.ZodString;
133
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"}
@@ -176,6 +176,14 @@ export declare const skillSchema: z.ZodObject<{
176
176
  is_creator: boolean;
177
177
  is_partner: boolean;
178
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"]>>>;
179
187
  created_at: z.ZodString;
180
188
  updated_at: z.ZodString;
181
189
  }, "strip", z.ZodTypeAny, {
@@ -230,6 +238,7 @@ export declare const skillSchema: z.ZodObject<{
230
238
  is_creator: boolean;
231
239
  is_partner: boolean;
232
240
  } | null | undefined;
241
+ security_rating?: "trusted" | "low_risk" | "med_risk" | "critical" | "pending" | null | undefined;
233
242
  }, {
234
243
  id: string;
235
244
  content: string | null;
@@ -282,6 +291,7 @@ export declare const skillSchema: z.ZodObject<{
282
291
  is_creator: boolean;
283
292
  is_partner: boolean;
284
293
  } | null | undefined;
294
+ security_rating?: "trusted" | "low_risk" | "med_risk" | "critical" | "pending" | null | undefined;
285
295
  }>;
286
296
  export type Skill = z.infer<typeof skillSchema>;
287
297
  export declare const createSkillInputSchema: z.ZodObject<{
@@ -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;;;;;;;;;;;;IAgBtB;;;;;;;;;OASG;;;;;;;IAQH;;;;;OAKG;;;;IAIH,kEAAkE;;;;;;;;;;;;;;;;;;;;;;;IAElE,6DAA6D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAE7D,6EAA6E;;IAE7E,mEAAmE;;IAEnE,+EAA+E;;IAE/E,gGAAgG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAchG,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"}
1
+ {"version":3,"file":"skill.schema.d.ts","sourceRoot":"","sources":["../../src/schemas/skill.schema.ts"],"names":[],"mappings":"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"}
@@ -86,6 +86,17 @@ export const skillSchema = z.object({
86
86
  })
87
87
  .nullable()
88
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(),
89
100
  created_at: z.string().datetime(),
90
101
  updated_at: z.string().datetime(),
91
102
  });
@@ -99,6 +99,14 @@ export interface PlanLimits {
99
99
  usage_history_days: number | null;
100
100
  /** CSV export of usage history. */
101
101
  can_usage_export: boolean;
102
+ /**
103
+ * Daily call cap on the Contextual Skill Advisor (the prose-
104
+ * recommendation endpoint). Tiered freemium — every plan can call
105
+ * the advisor, but Free runs out fast (3) and Max gets the most
106
+ * (30). Quota lives in Redis fixed-window buckets; see
107
+ * `apps/api/src/config/rate-limit-buckets.ts`.
108
+ */
109
+ advisor_calls_per_day: number;
102
110
  /** Public profile page at `/u/<username>`. */
103
111
  can_public_profile: boolean;
104
112
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"plan-limits.d.ts","sourceRoot":"","sources":["../../src/types/plan-limits.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAA;AACxD,OAAO,EAAe,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAE/D;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,UAAU;IACzB,+EAA+E;IAC/E,KAAK,EAAE,MAAM,CAAA;IACb,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAA;IACf,2EAA2E;IAC3E,iBAAiB,EAAE,MAAM,CAAA;IACzB,gEAAgE;IAChE,gBAAgB,EAAE,MAAM,CAAA;IACxB,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAA;IACZ,0DAA0D;IAC1D,SAAS,EAAE,OAAO,CAAA;IAGlB,+EAA+E;IAC/E,YAAY,EAAE,OAAO,CAAA;IACrB,8BAA8B;IAC9B,YAAY,EAAE,OAAO,CAAA;IACrB;;;;;;;;OAQG;IACH,mBAAmB,EAAE,OAAO,CAAA;IAG5B;;;OAGG;IACH,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAA;IACpC,4BAA4B;IAC5B,YAAY,EAAE,OAAO,CAAA;IACrB,wDAAwD;IACxD,cAAc,EAAE,OAAO,CAAA;IACvB,yCAAyC;IACzC,sBAAsB,EAAE,OAAO,CAAA;IAG/B,0CAA0C;IAC1C,oBAAoB,EAAE,OAAO,CAAA;IAC7B,0CAA0C;IAC1C,qBAAqB,EAAE,OAAO,CAAA;IAC9B;;OAEG;IACH,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAA;IACnC,oDAAoD;IACpD,kBAAkB,EAAE,OAAO,CAAA;IAG3B,gDAAgD;IAChD,gBAAgB,EAAE,OAAO,CAAA;IACzB;;;;;OAKG;IACH,wBAAwB,EAAE,MAAM,GAAG,IAAI,CAAA;IACvC;;;;;;;;OAQG;IACH,wBAAwB,EAAE,MAAM,GAAG,IAAI,CAAA;IACvC;;;;;OAKG;IACH,yBAAyB,EAAE,OAAO,CAAA;IAClC,uDAAuD;IACvD,aAAa,EAAE,OAAO,CAAA;IACtB,qCAAqC;IACrC,kBAAkB,EAAE,OAAO,CAAA;IAC3B;;;OAGG;IACH,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,mCAAmC;IACnC,gBAAgB,EAAE,OAAO,CAAA;IAGzB,8CAA8C;IAC9C,kBAAkB,EAAE,OAAO,CAAA;IAC3B;;;OAGG;IACH,oBAAoB,EAAE,OAAO,CAAA;IAC7B,oDAAoD;IACpD,kBAAkB,EAAE,OAAO,CAAA;IAC3B,mEAAmE;IACnE,kBAAkB,EAAE,OAAO,CAAA;IAG3B,6CAA6C;IAC7C,oBAAoB,EAAE,OAAO,CAAA;IAC7B,+CAA+C;IAC/C,gBAAgB,EAAE,OAAO,CAAA;IAGzB;;;;;OAKG;IACH,mBAAmB,EAAE,SAAS,SAAS,EAAE,CAAA;CAC1C;AAKD,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,IAAI,EAAE,UAAU,CAyJhD,CAAA;AAED,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAI1C,CAAA;AAED,8DAA8D;AAC9D,eAAO,MAAM,SAAS,GAAI,QAAQ,IAAI,EAAE,UAAU,IAAI,KAAG,OACf,CAAA;AAE1C;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,GAAI,SAAS,MAAM,UAAU,KAAG,IAAI,GAAG,IAU7D,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,SAAS,GAAI,MAAM,IAAI,KAAG,MAAiC,CAAA;AAExE;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAAI,MAAM,IAAI,EAAE,eAAe,MAAM,KAAG,MAAM,GAAG,IAI9E,CAAA"}
1
+ {"version":3,"file":"plan-limits.d.ts","sourceRoot":"","sources":["../../src/types/plan-limits.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAA;AACxD,OAAO,EAAe,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAE/D;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,UAAU;IACzB,+EAA+E;IAC/E,KAAK,EAAE,MAAM,CAAA;IACb,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAA;IACf,2EAA2E;IAC3E,iBAAiB,EAAE,MAAM,CAAA;IACzB,gEAAgE;IAChE,gBAAgB,EAAE,MAAM,CAAA;IACxB,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAA;IACZ,0DAA0D;IAC1D,SAAS,EAAE,OAAO,CAAA;IAGlB,+EAA+E;IAC/E,YAAY,EAAE,OAAO,CAAA;IACrB,8BAA8B;IAC9B,YAAY,EAAE,OAAO,CAAA;IACrB;;;;;;;;OAQG;IACH,mBAAmB,EAAE,OAAO,CAAA;IAG5B;;;OAGG;IACH,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAA;IACpC,4BAA4B;IAC5B,YAAY,EAAE,OAAO,CAAA;IACrB,wDAAwD;IACxD,cAAc,EAAE,OAAO,CAAA;IACvB,yCAAyC;IACzC,sBAAsB,EAAE,OAAO,CAAA;IAG/B,0CAA0C;IAC1C,oBAAoB,EAAE,OAAO,CAAA;IAC7B,0CAA0C;IAC1C,qBAAqB,EAAE,OAAO,CAAA;IAC9B;;OAEG;IACH,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAA;IACnC,oDAAoD;IACpD,kBAAkB,EAAE,OAAO,CAAA;IAG3B,gDAAgD;IAChD,gBAAgB,EAAE,OAAO,CAAA;IACzB;;;;;OAKG;IACH,wBAAwB,EAAE,MAAM,GAAG,IAAI,CAAA;IACvC;;;;;;;;OAQG;IACH,wBAAwB,EAAE,MAAM,GAAG,IAAI,CAAA;IACvC;;;;;OAKG;IACH,yBAAyB,EAAE,OAAO,CAAA;IAClC,uDAAuD;IACvD,aAAa,EAAE,OAAO,CAAA;IACtB,qCAAqC;IACrC,kBAAkB,EAAE,OAAO,CAAA;IAC3B;;;OAGG;IACH,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,mCAAmC;IACnC,gBAAgB,EAAE,OAAO,CAAA;IAGzB;;;;;;OAMG;IACH,qBAAqB,EAAE,MAAM,CAAA;IAG7B,8CAA8C;IAC9C,kBAAkB,EAAE,OAAO,CAAA;IAC3B;;;OAGG;IACH,oBAAoB,EAAE,OAAO,CAAA;IAC7B,oDAAoD;IACpD,kBAAkB,EAAE,OAAO,CAAA;IAC3B,mEAAmE;IACnE,kBAAkB,EAAE,OAAO,CAAA;IAG3B,6CAA6C;IAC7C,oBAAoB,EAAE,OAAO,CAAA;IAC7B,+CAA+C;IAC/C,gBAAgB,EAAE,OAAO,CAAA;IAGzB;;;;;OAKG;IACH,mBAAmB,EAAE,SAAS,SAAS,EAAE,CAAA;CAC1C;AAKD,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,IAAI,EAAE,UAAU,CA+JhD,CAAA;AAED,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAI1C,CAAA;AAED,8DAA8D;AAC9D,eAAO,MAAM,SAAS,GAAI,QAAQ,IAAI,EAAE,UAAU,IAAI,KAAG,OACf,CAAA;AAE1C;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,GAAI,SAAS,MAAM,UAAU,KAAG,IAAI,GAAG,IAU7D,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,SAAS,GAAI,MAAM,IAAI,KAAG,MAAiC,CAAA;AAExE;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAAI,MAAM,IAAI,EAAE,eAAe,MAAM,KAAG,MAAM,GAAG,IAI9E,CAAA"}
@@ -37,6 +37,7 @@ export const PLAN_LIMITS = {
37
37
  can_usage_tracking: false,
38
38
  usage_history_days: 0,
39
39
  can_usage_export: false,
40
+ advisor_calls_per_day: 3,
40
41
  can_public_profile: false,
41
42
  can_magic_link_share: false,
42
43
  has_verified_badge: false,
@@ -80,6 +81,7 @@ export const PLAN_LIMITS = {
80
81
  can_usage_tracking: true,
81
82
  usage_history_days: 30,
82
83
  can_usage_export: false,
84
+ advisor_calls_per_day: 10,
83
85
  can_public_profile: true,
84
86
  can_magic_link_share: false,
85
87
  has_verified_badge: true,
@@ -121,6 +123,7 @@ export const PLAN_LIMITS = {
121
123
  can_usage_tracking: true,
122
124
  usage_history_days: null,
123
125
  can_usage_export: true,
126
+ advisor_calls_per_day: 30,
124
127
  can_public_profile: true,
125
128
  can_magic_link_share: true,
126
129
  has_verified_badge: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prave/shared",
3
- "version": "1.4.16",
3
+ "version": "1.5.1",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"