@prave/shared 1.5.0 → 1.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,177 @@
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
+ * BM25 top-5 fallback slugs. Always populated so the UI can render
68
+ * clickable Skill cards even when `recommendations` is empty (Haiku
69
+ * said "no fit" or hallucinated unknown slugs). When this list backs
70
+ * the result, the server also refunds the rate-limit slot — the
71
+ * user wasn't billed for a zero-reasoned response.
72
+ */
73
+ candidate_slugs: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
74
+ /**
75
+ * Echoed for telemetry + cache-bust debugging. The UI doesn't render
76
+ * this but the analytics layer does.
77
+ */
78
+ mode: z.ZodEnum<["manual", "auto"]>;
79
+ /**
80
+ * After-this-call quota snapshot — saves the web UI a round-trip
81
+ * back to `GET /advisor/quota` immediately after a success.
82
+ */
83
+ quota: z.ZodObject<{
84
+ plan: z.ZodEnum<["free", "pro", "max"]>;
85
+ limit: z.ZodNumber;
86
+ used: z.ZodNumber;
87
+ remaining: z.ZodNumber;
88
+ }, "strip", z.ZodTypeAny, {
89
+ limit: number;
90
+ plan: "free" | "pro" | "max";
91
+ used: number;
92
+ remaining: number;
93
+ }, {
94
+ limit: number;
95
+ plan: "free" | "pro" | "max";
96
+ used: number;
97
+ remaining: number;
98
+ }>;
99
+ }, "strip", z.ZodTypeAny, {
100
+ mode: "manual" | "auto";
101
+ prose: string;
102
+ recommendations: {
103
+ slug: string;
104
+ reason: string;
105
+ }[];
106
+ candidate_slugs: string[];
107
+ quota: {
108
+ limit: number;
109
+ plan: "free" | "pro" | "max";
110
+ used: number;
111
+ remaining: number;
112
+ };
113
+ }, {
114
+ mode: "manual" | "auto";
115
+ prose: string;
116
+ recommendations: {
117
+ slug: string;
118
+ reason: string;
119
+ }[];
120
+ quota: {
121
+ limit: number;
122
+ plan: "free" | "pro" | "max";
123
+ used: number;
124
+ remaining: number;
125
+ };
126
+ candidate_slugs?: string[] | undefined;
127
+ }>;
128
+ export type AdvisorResponse = z.infer<typeof advisorResponseSchema>;
129
+ export declare const advisorQuotaResponseSchema: z.ZodObject<{
130
+ plan: z.ZodEnum<["free", "pro", "max"]>;
131
+ limit: z.ZodNumber;
132
+ used: z.ZodNumber;
133
+ remaining: z.ZodNumber;
134
+ }, "strip", z.ZodTypeAny, {
135
+ limit: number;
136
+ plan: "free" | "pro" | "max";
137
+ used: number;
138
+ remaining: number;
139
+ }, {
140
+ limit: number;
141
+ plan: "free" | "pro" | "max";
142
+ used: number;
143
+ remaining: number;
144
+ }>;
145
+ export type AdvisorQuotaResponse = z.infer<typeof advisorQuotaResponseSchema>;
146
+ /**
147
+ * Raw Haiku JSON shape — what the model is told to produce. Validated
148
+ * inside the service; mismatches throw `HttpError.internal` so the
149
+ * caller gets a clean 500 rather than half-rendered garbage.
150
+ */
151
+ export declare const advisorLlmOutputSchema: z.ZodObject<{
152
+ prose: z.ZodString;
153
+ recommendations: z.ZodArray<z.ZodObject<{
154
+ slug: z.ZodString;
155
+ reason: z.ZodString;
156
+ }, "strip", z.ZodTypeAny, {
157
+ slug: string;
158
+ reason: string;
159
+ }, {
160
+ slug: string;
161
+ reason: string;
162
+ }>, "many">;
163
+ }, "strip", z.ZodTypeAny, {
164
+ prose: string;
165
+ recommendations: {
166
+ slug: string;
167
+ reason: string;
168
+ }[];
169
+ }, {
170
+ prose: string;
171
+ recommendations: {
172
+ slug: string;
173
+ reason: string;
174
+ }[];
175
+ }>;
176
+ export type AdvisorLlmOutput = z.infer<typeof advisorLlmOutputSchema>;
177
+ //# 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;;;;;;OAMG;;IAEH;;;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,84 @@
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
+ * BM25 top-5 fallback slugs. Always populated so the UI can render
48
+ * clickable Skill cards even when `recommendations` is empty (Haiku
49
+ * said "no fit" or hallucinated unknown slugs). When this list backs
50
+ * the result, the server also refunds the rate-limit slot — the
51
+ * user wasn't billed for a zero-reasoned response.
52
+ */
53
+ candidate_slugs: z.array(z.string()).default([]),
54
+ /**
55
+ * Echoed for telemetry + cache-bust debugging. The UI doesn't render
56
+ * this but the analytics layer does.
57
+ */
58
+ mode: advisorModeSchema,
59
+ /**
60
+ * After-this-call quota snapshot — saves the web UI a round-trip
61
+ * back to `GET /advisor/quota` immediately after a success.
62
+ */
63
+ quota: z.object({
64
+ plan: z.enum(['free', 'pro', 'max']),
65
+ limit: z.number().int().nonnegative(),
66
+ used: z.number().int().nonnegative(),
67
+ remaining: z.number().int().nonnegative(),
68
+ }),
69
+ });
70
+ export const advisorQuotaResponseSchema = advisorResponseSchema.shape.quota;
71
+ /**
72
+ * Raw Haiku JSON shape — what the model is told to produce. Validated
73
+ * inside the service; mismatches throw `HttpError.internal` so the
74
+ * caller gets a clean 500 rather than half-rendered garbage.
75
+ */
76
+ export const advisorLlmOutputSchema = z.object({
77
+ prose: z.string().min(1).max(2400),
78
+ recommendations: z
79
+ .array(z.object({
80
+ slug: z.string().min(1).max(120),
81
+ reason: z.string().min(1).max(400),
82
+ }))
83
+ .max(8), // accept up to 8 so we can drop hallucinations before capping to 5
84
+ });
@@ -30,6 +30,16 @@ export declare const hookSchema: z.ZodObject<{
30
30
  command: z.ZodString;
31
31
  /** Optional per-hook timeout in seconds (1–600). */
32
32
  timeout_seconds: z.ZodNullable<z.ZodNumber>;
33
+ /**
34
+ * Agents whose runtime exposes a compatible lifecycle-event
35
+ * contract. Today the answer is always `['claude']` because no
36
+ * other coding agent (Codex, Gemini, Cursor, Continue, Cline, Amp,
37
+ * Aider) ships a comparable `PreToolUse`/`PostToolUse` API. The
38
+ * field exists so we can fan out — without a schema change — the
39
+ * moment those runtimes catch up. Attached server-side on every
40
+ * hook GET; not stored in the DB.
41
+ */
42
+ supported_agents: z.ZodDefault<z.ZodArray<z.ZodEnum<["claude"]>, "many">>;
33
43
  visibility: z.ZodDefault<z.ZodEnum<["public", "private"]>>;
34
44
  source_repo: z.ZodNullable<z.ZodString>;
35
45
  license: z.ZodDefault<z.ZodString>;
@@ -87,6 +97,7 @@ export declare const hookSchema: z.ZodObject<{
87
97
  matcher: string | null;
88
98
  command: string;
89
99
  timeout_seconds: number | null;
100
+ supported_agents: "claude"[];
90
101
  bookmarked?: boolean | undefined;
91
102
  owner?: {
92
103
  id: string;
@@ -127,6 +138,7 @@ export declare const hookSchema: z.ZodObject<{
127
138
  } | null | undefined;
128
139
  security_rating?: "trusted" | "low_risk" | "med_risk" | "critical" | "pending" | null | undefined;
129
140
  version?: number | undefined;
141
+ supported_agents?: "claude"[] | undefined;
130
142
  installed?: boolean | undefined;
131
143
  }>;
132
144
  export type Hook = z.infer<typeof hookSchema>;
@@ -1 +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"}
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;;IAGpD;;;;;;;;OAQG;;;;;;;;;IAWH,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"}
@@ -41,6 +41,16 @@ export const hookSchema = z.object({
41
41
  command: z.string().min(1).max(4000),
42
42
  /** Optional per-hook timeout in seconds (1–600). */
43
43
  timeout_seconds: z.number().int().min(1).max(600).nullable(),
44
+ /**
45
+ * Agents whose runtime exposes a compatible lifecycle-event
46
+ * contract. Today the answer is always `['claude']` because no
47
+ * other coding agent (Codex, Gemini, Cursor, Continue, Cline, Amp,
48
+ * Aider) ships a comparable `PreToolUse`/`PostToolUse` API. The
49
+ * field exists so we can fan out — without a schema change — the
50
+ * moment those runtimes catch up. Attached server-side on every
51
+ * hook GET; not stored in the DB.
52
+ */
53
+ supported_agents: z.array(z.enum(['claude'])).default(['claude']),
44
54
  visibility: hookVisibilitySchema.default('public'),
45
55
  source_repo: z.string().url().nullable(),
46
56
  license: z.string().default('MIT'),
@@ -12,4 +12,5 @@ export * from './api-keys.schema.js';
12
12
  export * from './skill-report.schema.js';
13
13
  export * from './security-audit.schema.js';
14
14
  export * from './hook.schema.js';
15
+ export * from './advisor.schema.js';
15
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;AACxC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,kBAAkB,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"}
@@ -12,3 +12,4 @@ export * from './api-keys.schema.js';
12
12
  export * from './skill-report.schema.js';
13
13
  export * from './security-audit.schema.js';
14
14
  export * from './hook.schema.js';
15
+ export * from './advisor.schema.js';
@@ -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.5.0",
3
+ "version": "1.5.2",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"