44reports-mcp 1.0.9 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api-client.d.ts +163 -1
- package/dist/api-client.js +95 -0
- package/dist/index.js +217 -4
- package/dist/tools/backlog.d.ts +58 -0
- package/dist/tools/backlog.js +46 -0
- package/dist/tools/backlog.test.d.ts +1 -0
- package/dist/tools/backlog.test.js +255 -0
- package/dist/tools/folders.d.ts +3 -0
- package/dist/tools/folders.js +9 -4
- package/dist/tools/products.d.ts +241 -0
- package/dist/tools/products.js +169 -0
- package/package.json +1 -1
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { addToBacklogSchema, listBacklogSchema, processBacklogSchema, createAddToBacklogTool, createListBacklogTool, createProcessBacklogTool, } from './backlog.js';
|
|
2
|
+
// --- Schema validation tests ---
|
|
3
|
+
describe('addToBacklogSchema', () => {
|
|
4
|
+
it('requires content', () => {
|
|
5
|
+
const result = addToBacklogSchema.safeParse({});
|
|
6
|
+
expect(result.success).toBe(false);
|
|
7
|
+
});
|
|
8
|
+
it('accepts content only', () => {
|
|
9
|
+
const result = addToBacklogSchema.safeParse({ content: 'User mentioned they love the dark mode feature' });
|
|
10
|
+
expect(result.success).toBe(true);
|
|
11
|
+
});
|
|
12
|
+
it('accepts all optional fields', () => {
|
|
13
|
+
const result = addToBacklogSchema.safeParse({
|
|
14
|
+
content: 'Competitor launched new pricing tier at $9.99/mo',
|
|
15
|
+
product_slug: 'my-app',
|
|
16
|
+
source: 'competitor-monitor',
|
|
17
|
+
source_context: 'weekly-research',
|
|
18
|
+
domain_hint: 'product-research',
|
|
19
|
+
tags: ['competitor', 'pricing'],
|
|
20
|
+
});
|
|
21
|
+
expect(result.success).toBe(true);
|
|
22
|
+
if (result.success) {
|
|
23
|
+
expect(result.data.product_slug).toBe('my-app');
|
|
24
|
+
expect(result.data.tags).toEqual(['competitor', 'pricing']);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
it('rejects invalid domain_hint', () => {
|
|
28
|
+
const result = addToBacklogSchema.safeParse({
|
|
29
|
+
content: 'Some observation',
|
|
30
|
+
domain_hint: 'invalid-domain',
|
|
31
|
+
});
|
|
32
|
+
expect(result.success).toBe(false);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
describe('listBacklogSchema', () => {
|
|
36
|
+
it('accepts empty input', () => {
|
|
37
|
+
const result = listBacklogSchema.safeParse({});
|
|
38
|
+
expect(result.success).toBe(true);
|
|
39
|
+
});
|
|
40
|
+
it('accepts all filters', () => {
|
|
41
|
+
const result = listBacklogSchema.safeParse({
|
|
42
|
+
product_slug: 'my-app',
|
|
43
|
+
status: 'pending',
|
|
44
|
+
limit: 10,
|
|
45
|
+
offset: 20,
|
|
46
|
+
});
|
|
47
|
+
expect(result.success).toBe(true);
|
|
48
|
+
});
|
|
49
|
+
it('rejects invalid status', () => {
|
|
50
|
+
const result = listBacklogSchema.safeParse({ status: 'invalid' });
|
|
51
|
+
expect(result.success).toBe(false);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
describe('processBacklogSchema', () => {
|
|
55
|
+
it('accepts empty input with dry_run defaulting to true', () => {
|
|
56
|
+
const result = processBacklogSchema.safeParse({});
|
|
57
|
+
expect(result.success).toBe(true);
|
|
58
|
+
if (result.success) {
|
|
59
|
+
expect(result.data.dry_run).toBe(true);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
it('accepts product_slug and dry_run false', () => {
|
|
63
|
+
const result = processBacklogSchema.safeParse({
|
|
64
|
+
product_slug: 'my-app',
|
|
65
|
+
dry_run: false,
|
|
66
|
+
});
|
|
67
|
+
expect(result.success).toBe(true);
|
|
68
|
+
if (result.success) {
|
|
69
|
+
expect(result.data.dry_run).toBe(false);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
function makeEntry(overrides = {}) {
|
|
74
|
+
return {
|
|
75
|
+
id: 'entry-1',
|
|
76
|
+
product_slug: null,
|
|
77
|
+
content: 'Test observation',
|
|
78
|
+
source: null,
|
|
79
|
+
source_context: null,
|
|
80
|
+
domain_hint: null,
|
|
81
|
+
tags: null,
|
|
82
|
+
status: 'pending',
|
|
83
|
+
result_summary: null,
|
|
84
|
+
applied_changes: null,
|
|
85
|
+
rejection_reason: null,
|
|
86
|
+
processed_at: null,
|
|
87
|
+
created_at: '2026-03-06T00:00:00Z',
|
|
88
|
+
updated_at: '2026-03-06T00:00:00Z',
|
|
89
|
+
...overrides,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
/** Simple call tracker — records arguments passed to each mock method */
|
|
93
|
+
function createTrackedClient(mocks) {
|
|
94
|
+
const calls = {
|
|
95
|
+
addBacklogEntry: [],
|
|
96
|
+
listBacklog: [],
|
|
97
|
+
processBacklog: [],
|
|
98
|
+
};
|
|
99
|
+
const client = {
|
|
100
|
+
addBacklogEntry: async (data) => {
|
|
101
|
+
calls.addBacklogEntry.push(data);
|
|
102
|
+
return mocks.addBacklogEntry?.(data) ?? {};
|
|
103
|
+
},
|
|
104
|
+
listBacklog: async (options) => {
|
|
105
|
+
calls.listBacklog.push(options);
|
|
106
|
+
return mocks.listBacklog?.(options) ?? { entries: [], total: 0 };
|
|
107
|
+
},
|
|
108
|
+
processBacklog: async (options) => {
|
|
109
|
+
calls.processBacklog.push(options);
|
|
110
|
+
return mocks.processBacklog?.(options) ?? {};
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
return { client, calls };
|
|
114
|
+
}
|
|
115
|
+
describe('add_to_backlog → list_backlog → process_backlog flow', () => {
|
|
116
|
+
it('adds an entry, lists it, then processes it', async () => {
|
|
117
|
+
const entry = makeEntry({
|
|
118
|
+
content: 'Users report competitor app Calm added sleep stories',
|
|
119
|
+
product_slug: 'my-meditation-app',
|
|
120
|
+
source: 'research-agent',
|
|
121
|
+
domain_hint: 'product-research',
|
|
122
|
+
tags: '["competitor","feature"]',
|
|
123
|
+
});
|
|
124
|
+
const processResponse = {
|
|
125
|
+
routed: 0,
|
|
126
|
+
processed: 1,
|
|
127
|
+
applied: 1,
|
|
128
|
+
rejected: 0,
|
|
129
|
+
partial: 0,
|
|
130
|
+
errors: [],
|
|
131
|
+
details: [{
|
|
132
|
+
id: entry.id,
|
|
133
|
+
status: 'applied',
|
|
134
|
+
result_summary: 'Added competitor insight to research doc',
|
|
135
|
+
applied_changes: [{ filepath: 'docs/research/competitors.md', action: 'md_append', product_slug: 'my-meditation-app' }],
|
|
136
|
+
rejection_reason: null,
|
|
137
|
+
}],
|
|
138
|
+
};
|
|
139
|
+
const { client, calls } = createTrackedClient({
|
|
140
|
+
addBacklogEntry: async () => ({ entry }),
|
|
141
|
+
listBacklog: async () => ({ entries: [entry], total: 1 }),
|
|
142
|
+
processBacklog: async () => processResponse,
|
|
143
|
+
});
|
|
144
|
+
// Step 1: Add entry
|
|
145
|
+
const addTool = createAddToBacklogTool(client);
|
|
146
|
+
const addResult = await addTool({
|
|
147
|
+
content: 'Users report competitor app Calm added sleep stories',
|
|
148
|
+
product_slug: 'my-meditation-app',
|
|
149
|
+
source: 'research-agent',
|
|
150
|
+
domain_hint: 'product-research',
|
|
151
|
+
tags: ['competitor', 'feature'],
|
|
152
|
+
});
|
|
153
|
+
expect(calls.addBacklogEntry).toHaveLength(1);
|
|
154
|
+
expect(calls.addBacklogEntry[0]).toEqual({
|
|
155
|
+
content: 'Users report competitor app Calm added sleep stories',
|
|
156
|
+
product_slug: 'my-meditation-app',
|
|
157
|
+
source: 'research-agent',
|
|
158
|
+
domain_hint: 'product-research',
|
|
159
|
+
tags: ['competitor', 'feature'],
|
|
160
|
+
});
|
|
161
|
+
expect(addResult.entry.id).toBe('entry-1');
|
|
162
|
+
expect(addResult.entry.status).toBe('pending');
|
|
163
|
+
// Step 2: List entries — verify pending entry appears
|
|
164
|
+
const listTool = createListBacklogTool(client);
|
|
165
|
+
const listResult = await listTool({
|
|
166
|
+
product_slug: 'my-meditation-app',
|
|
167
|
+
status: 'pending',
|
|
168
|
+
});
|
|
169
|
+
expect(calls.listBacklog).toHaveLength(1);
|
|
170
|
+
expect(calls.listBacklog[0].product_slug).toBe('my-meditation-app');
|
|
171
|
+
expect(calls.listBacklog[0].status).toBe('pending');
|
|
172
|
+
expect(listResult.entries).toHaveLength(1);
|
|
173
|
+
expect(listResult.total).toBe(1);
|
|
174
|
+
// Step 3: Process — verify changes applied
|
|
175
|
+
const processTool = createProcessBacklogTool(client);
|
|
176
|
+
const processResult = await processTool({
|
|
177
|
+
product_slug: 'my-meditation-app',
|
|
178
|
+
dry_run: false,
|
|
179
|
+
});
|
|
180
|
+
expect(calls.processBacklog).toHaveLength(1);
|
|
181
|
+
expect(calls.processBacklog[0].dry_run).toBe(false);
|
|
182
|
+
expect(processResult.applied).toBe(1);
|
|
183
|
+
expect(processResult.errors).toHaveLength(0);
|
|
184
|
+
expect(processResult.details[0].status).toBe('applied');
|
|
185
|
+
expect(processResult.details[0].applied_changes).toEqual([
|
|
186
|
+
{ filepath: 'docs/research/competitors.md', action: 'md_append', product_slug: 'my-meditation-app' },
|
|
187
|
+
]);
|
|
188
|
+
});
|
|
189
|
+
it('adds a global entry and processes with routing', async () => {
|
|
190
|
+
const globalEntry = makeEntry({
|
|
191
|
+
id: 'global-1',
|
|
192
|
+
content: 'App Store review mentions slow load times on iPhone 12',
|
|
193
|
+
source: 'review-monitor',
|
|
194
|
+
});
|
|
195
|
+
const processResponse = {
|
|
196
|
+
routed: 1,
|
|
197
|
+
processed: 1,
|
|
198
|
+
applied: 0,
|
|
199
|
+
rejected: 0,
|
|
200
|
+
partial: 1,
|
|
201
|
+
errors: [],
|
|
202
|
+
details: [{
|
|
203
|
+
id: 'global-1',
|
|
204
|
+
status: 'partial',
|
|
205
|
+
result_summary: 'medium confidence — needs review',
|
|
206
|
+
applied_changes: [{ filepath: 'docs/app-store/feedback.md', action: 'md_append', product_slug: 'my-app' }],
|
|
207
|
+
rejection_reason: null,
|
|
208
|
+
}],
|
|
209
|
+
};
|
|
210
|
+
const { client, calls } = createTrackedClient({
|
|
211
|
+
addBacklogEntry: async () => ({ entry: globalEntry }),
|
|
212
|
+
processBacklog: async () => processResponse,
|
|
213
|
+
});
|
|
214
|
+
// Add global entry (no product_slug)
|
|
215
|
+
const addTool = createAddToBacklogTool(client);
|
|
216
|
+
const addResult = await addTool({
|
|
217
|
+
content: 'App Store review mentions slow load times on iPhone 12',
|
|
218
|
+
source: 'review-monitor',
|
|
219
|
+
});
|
|
220
|
+
expect(addResult.entry.product_slug).toBeNull();
|
|
221
|
+
// Process all (triggers routing + processing)
|
|
222
|
+
const processTool = createProcessBacklogTool(client);
|
|
223
|
+
const processResult = await processTool({ dry_run: true });
|
|
224
|
+
expect(calls.processBacklog[0].product_slug).toBeUndefined();
|
|
225
|
+
expect(calls.processBacklog[0].dry_run).toBe(true);
|
|
226
|
+
expect(processResult.routed).toBe(1);
|
|
227
|
+
expect(processResult.details[0].status).toBe('partial');
|
|
228
|
+
});
|
|
229
|
+
it('dry_run defaults to true and previews without applying', async () => {
|
|
230
|
+
const processResponse = {
|
|
231
|
+
routed: 0,
|
|
232
|
+
processed: 2,
|
|
233
|
+
applied: 0,
|
|
234
|
+
rejected: 0,
|
|
235
|
+
partial: 0,
|
|
236
|
+
errors: [],
|
|
237
|
+
details: [
|
|
238
|
+
{ id: 'e1', status: 'pending', result_summary: '[DRY RUN] high confidence: fits brand config', applied_changes: [{ filepath: 'brand-config.json', action: 'json_patch', product_slug: 'my-app' }], rejection_reason: null },
|
|
239
|
+
{ id: 'e2', status: 'pending', result_summary: '[DRY RUN] medium confidence: could be competitor data', applied_changes: [{ filepath: 'docs/research/competitors.md', action: 'md_append', product_slug: 'my-app' }], rejection_reason: null },
|
|
240
|
+
],
|
|
241
|
+
};
|
|
242
|
+
const { client, calls } = createTrackedClient({
|
|
243
|
+
processBacklog: async () => processResponse,
|
|
244
|
+
});
|
|
245
|
+
const processTool = createProcessBacklogTool(client);
|
|
246
|
+
// No dry_run passed — should default to true via Zod schema
|
|
247
|
+
const parsed = processBacklogSchema.parse({ product_slug: 'my-app' });
|
|
248
|
+
expect(parsed.dry_run).toBe(true);
|
|
249
|
+
const result = await processTool({ product_slug: 'my-app', dry_run: true });
|
|
250
|
+
expect(calls.processBacklog[0].dry_run).toBe(true);
|
|
251
|
+
expect(result.applied).toBe(0);
|
|
252
|
+
expect(result.details).toHaveLength(2);
|
|
253
|
+
expect(result.details[0].result_summary).toContain('[DRY RUN]');
|
|
254
|
+
});
|
|
255
|
+
});
|
package/dist/tools/folders.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export declare const manageFoldersSchema: z.ZodObject<{
|
|
|
6
6
|
name: z.ZodOptional<z.ZodString>;
|
|
7
7
|
description: z.ZodOptional<z.ZodString>;
|
|
8
8
|
allowed_domains: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
9
|
+
allowed_emails: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
9
10
|
report_slugs: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
10
11
|
report_slug: z.ZodOptional<z.ZodString>;
|
|
11
12
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -14,6 +15,7 @@ export declare const manageFoldersSchema: z.ZodObject<{
|
|
|
14
15
|
slug?: string | undefined;
|
|
15
16
|
description?: string | undefined;
|
|
16
17
|
allowed_domains?: string[] | undefined;
|
|
18
|
+
allowed_emails?: string[] | undefined;
|
|
17
19
|
report_slugs?: string[] | undefined;
|
|
18
20
|
report_slug?: string | undefined;
|
|
19
21
|
}, {
|
|
@@ -22,6 +24,7 @@ export declare const manageFoldersSchema: z.ZodObject<{
|
|
|
22
24
|
slug?: string | undefined;
|
|
23
25
|
description?: string | undefined;
|
|
24
26
|
allowed_domains?: string[] | undefined;
|
|
27
|
+
allowed_emails?: string[] | undefined;
|
|
25
28
|
report_slugs?: string[] | undefined;
|
|
26
29
|
report_slug?: string | undefined;
|
|
27
30
|
}>;
|
package/dist/tools/folders.js
CHANGED
|
@@ -5,7 +5,8 @@ export const manageFoldersSchema = z.object({
|
|
|
5
5
|
slug: z.string().optional().describe('Folder slug (required for get, update, delete, add_reports, remove_report)'),
|
|
6
6
|
name: z.string().optional().describe('Folder name (required for create)'),
|
|
7
7
|
description: z.string().optional().describe('Folder description'),
|
|
8
|
-
allowed_domains: z.array(z.string()).optional().describe('Email domains that can access this folder
|
|
8
|
+
allowed_domains: z.array(z.string()).optional().describe('Email domains that can access this folder'),
|
|
9
|
+
allowed_emails: z.array(z.string()).optional().describe('Individual email addresses that can access this folder'),
|
|
9
10
|
report_slugs: z.array(z.string()).optional().describe('Report slugs to add (for add_reports action)'),
|
|
10
11
|
report_slug: z.string().optional().describe('Report slug to remove (for remove_report action)'),
|
|
11
12
|
});
|
|
@@ -19,14 +20,17 @@ export function createManageFoldersTool(client) {
|
|
|
19
20
|
case 'create': {
|
|
20
21
|
if (!input.name)
|
|
21
22
|
throw new Error('name is required for create');
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
const domains = input.allowed_domains ?? [];
|
|
24
|
+
const emails = input.allowed_emails ?? [];
|
|
25
|
+
if (domains.length === 0 && emails.length === 0) {
|
|
26
|
+
throw new Error('at least one of allowed_domains or allowed_emails is required for create');
|
|
24
27
|
}
|
|
25
28
|
return client.createFolder({
|
|
26
29
|
name: input.name,
|
|
27
30
|
slug: input.slug,
|
|
28
31
|
description: input.description,
|
|
29
|
-
allowed_domains:
|
|
32
|
+
allowed_domains: domains.length > 0 ? domains : undefined,
|
|
33
|
+
allowed_emails: emails.length > 0 ? emails : undefined,
|
|
30
34
|
});
|
|
31
35
|
}
|
|
32
36
|
case 'get': {
|
|
@@ -41,6 +45,7 @@ export function createManageFoldersTool(client) {
|
|
|
41
45
|
name: input.name,
|
|
42
46
|
description: input.description,
|
|
43
47
|
allowed_domains: input.allowed_domains,
|
|
48
|
+
allowed_emails: input.allowed_emails,
|
|
44
49
|
});
|
|
45
50
|
}
|
|
46
51
|
case 'delete': {
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { ApiClient } from '../api-client.js';
|
|
3
|
+
export declare const listProductsSchema: z.ZodObject<{
|
|
4
|
+
search: z.ZodOptional<z.ZodString>;
|
|
5
|
+
}, "strip", z.ZodTypeAny, {
|
|
6
|
+
search?: string | undefined;
|
|
7
|
+
}, {
|
|
8
|
+
search?: string | undefined;
|
|
9
|
+
}>;
|
|
10
|
+
export declare const getProductSchema: z.ZodObject<{
|
|
11
|
+
slug: z.ZodString;
|
|
12
|
+
domain: z.ZodOptional<z.ZodEnum<["product-research", "brand", "copy", "advertising", "app-store"]>>;
|
|
13
|
+
}, "strip", z.ZodTypeAny, {
|
|
14
|
+
slug: string;
|
|
15
|
+
domain?: "product-research" | "brand" | "copy" | "advertising" | "app-store" | undefined;
|
|
16
|
+
}, {
|
|
17
|
+
slug: string;
|
|
18
|
+
domain?: "product-research" | "brand" | "copy" | "advertising" | "app-store" | undefined;
|
|
19
|
+
}>;
|
|
20
|
+
export declare const readProductFileSchema: z.ZodObject<{
|
|
21
|
+
slug: z.ZodString;
|
|
22
|
+
filepath: z.ZodString;
|
|
23
|
+
}, "strip", z.ZodTypeAny, {
|
|
24
|
+
slug: string;
|
|
25
|
+
filepath: string;
|
|
26
|
+
}, {
|
|
27
|
+
slug: string;
|
|
28
|
+
filepath: string;
|
|
29
|
+
}>;
|
|
30
|
+
export declare const updateProductKnowledgeSchema: z.ZodObject<{
|
|
31
|
+
slug: z.ZodString;
|
|
32
|
+
filepath: z.ZodString;
|
|
33
|
+
content: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
34
|
+
updated_by: z.ZodOptional<z.ZodString>;
|
|
35
|
+
}, "strip", z.ZodTypeAny, {
|
|
36
|
+
slug: string;
|
|
37
|
+
content: Record<string, unknown>;
|
|
38
|
+
filepath: string;
|
|
39
|
+
updated_by?: string | undefined;
|
|
40
|
+
}, {
|
|
41
|
+
slug: string;
|
|
42
|
+
content: Record<string, unknown>;
|
|
43
|
+
filepath: string;
|
|
44
|
+
updated_by?: string | undefined;
|
|
45
|
+
}>;
|
|
46
|
+
export declare const uploadProductFilesSchema: z.ZodObject<{
|
|
47
|
+
slug: z.ZodString;
|
|
48
|
+
files: z.ZodArray<z.ZodObject<{
|
|
49
|
+
path: z.ZodString;
|
|
50
|
+
content: z.ZodString;
|
|
51
|
+
content_type: z.ZodOptional<z.ZodString>;
|
|
52
|
+
}, "strip", z.ZodTypeAny, {
|
|
53
|
+
path: string;
|
|
54
|
+
content: string;
|
|
55
|
+
content_type?: string | undefined;
|
|
56
|
+
}, {
|
|
57
|
+
path: string;
|
|
58
|
+
content: string;
|
|
59
|
+
content_type?: string | undefined;
|
|
60
|
+
}>, "many">;
|
|
61
|
+
}, "strip", z.ZodTypeAny, {
|
|
62
|
+
slug: string;
|
|
63
|
+
files: {
|
|
64
|
+
path: string;
|
|
65
|
+
content: string;
|
|
66
|
+
content_type?: string | undefined;
|
|
67
|
+
}[];
|
|
68
|
+
}, {
|
|
69
|
+
slug: string;
|
|
70
|
+
files: {
|
|
71
|
+
path: string;
|
|
72
|
+
content: string;
|
|
73
|
+
content_type?: string | undefined;
|
|
74
|
+
}[];
|
|
75
|
+
}>;
|
|
76
|
+
export declare const pullProductFilesSchema: z.ZodObject<{
|
|
77
|
+
slug: z.ZodString;
|
|
78
|
+
output_dir: z.ZodString;
|
|
79
|
+
files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
80
|
+
include_knowledge: z.ZodOptional<z.ZodBoolean>;
|
|
81
|
+
}, "strip", z.ZodTypeAny, {
|
|
82
|
+
slug: string;
|
|
83
|
+
output_dir: string;
|
|
84
|
+
files?: string[] | undefined;
|
|
85
|
+
include_knowledge?: boolean | undefined;
|
|
86
|
+
}, {
|
|
87
|
+
slug: string;
|
|
88
|
+
output_dir: string;
|
|
89
|
+
files?: string[] | undefined;
|
|
90
|
+
include_knowledge?: boolean | undefined;
|
|
91
|
+
}>;
|
|
92
|
+
export declare const getProductIndexSchema: z.ZodObject<{
|
|
93
|
+
slug: z.ZodString;
|
|
94
|
+
domain: z.ZodOptional<z.ZodEnum<["product-research", "brand", "copy", "advertising", "app-store"]>>;
|
|
95
|
+
}, "strip", z.ZodTypeAny, {
|
|
96
|
+
slug: string;
|
|
97
|
+
domain?: "product-research" | "brand" | "copy" | "advertising" | "app-store" | undefined;
|
|
98
|
+
}, {
|
|
99
|
+
slug: string;
|
|
100
|
+
domain?: "product-research" | "brand" | "copy" | "advertising" | "app-store" | undefined;
|
|
101
|
+
}>;
|
|
102
|
+
export declare const getProductHealthSchema: z.ZodObject<{
|
|
103
|
+
slug: z.ZodOptional<z.ZodString>;
|
|
104
|
+
}, "strip", z.ZodTypeAny, {
|
|
105
|
+
slug?: string | undefined;
|
|
106
|
+
}, {
|
|
107
|
+
slug?: string | undefined;
|
|
108
|
+
}>;
|
|
109
|
+
export declare const createProductSchema: z.ZodObject<{
|
|
110
|
+
name: z.ZodString;
|
|
111
|
+
slug: z.ZodOptional<z.ZodString>;
|
|
112
|
+
description: z.ZodOptional<z.ZodString>;
|
|
113
|
+
}, "strip", z.ZodTypeAny, {
|
|
114
|
+
name: string;
|
|
115
|
+
slug?: string | undefined;
|
|
116
|
+
description?: string | undefined;
|
|
117
|
+
}, {
|
|
118
|
+
name: string;
|
|
119
|
+
slug?: string | undefined;
|
|
120
|
+
description?: string | undefined;
|
|
121
|
+
}>;
|
|
122
|
+
export declare const deleteProductSchema: z.ZodObject<{
|
|
123
|
+
slug: z.ZodString;
|
|
124
|
+
}, "strip", z.ZodTypeAny, {
|
|
125
|
+
slug: string;
|
|
126
|
+
}, {
|
|
127
|
+
slug: string;
|
|
128
|
+
}>;
|
|
129
|
+
export declare const deleteProductFileSchema: z.ZodObject<{
|
|
130
|
+
slug: z.ZodString;
|
|
131
|
+
filepath: z.ZodString;
|
|
132
|
+
}, "strip", z.ZodTypeAny, {
|
|
133
|
+
slug: string;
|
|
134
|
+
filepath: string;
|
|
135
|
+
}, {
|
|
136
|
+
slug: string;
|
|
137
|
+
filepath: string;
|
|
138
|
+
}>;
|
|
139
|
+
export declare function createListProductsTool(client: ApiClient): (input: z.infer<typeof listProductsSchema>) => Promise<{
|
|
140
|
+
products: Array<{
|
|
141
|
+
id: string;
|
|
142
|
+
slug: string;
|
|
143
|
+
name: string;
|
|
144
|
+
description: string | null;
|
|
145
|
+
created_at: string;
|
|
146
|
+
updated_at: string;
|
|
147
|
+
}>;
|
|
148
|
+
total: number;
|
|
149
|
+
}>;
|
|
150
|
+
export declare function createGetProductTool(client: ApiClient): (input: z.infer<typeof getProductSchema>) => Promise<{
|
|
151
|
+
product: {
|
|
152
|
+
id: string;
|
|
153
|
+
slug: string;
|
|
154
|
+
name: string;
|
|
155
|
+
description: string | null;
|
|
156
|
+
created_at: string;
|
|
157
|
+
updated_at: string;
|
|
158
|
+
};
|
|
159
|
+
knowledge: Record<string, unknown>;
|
|
160
|
+
doc_files: Array<{
|
|
161
|
+
path: string;
|
|
162
|
+
size: number;
|
|
163
|
+
domain: string;
|
|
164
|
+
}>;
|
|
165
|
+
binary_files: Array<{
|
|
166
|
+
path: string;
|
|
167
|
+
size: number;
|
|
168
|
+
content_type: string;
|
|
169
|
+
domain: string;
|
|
170
|
+
}>;
|
|
171
|
+
}>;
|
|
172
|
+
export declare function createReadProductFileTool(client: ApiClient): (input: z.infer<typeof readProductFileSchema>) => Promise<{
|
|
173
|
+
path: string;
|
|
174
|
+
content: unknown;
|
|
175
|
+
content_type: string;
|
|
176
|
+
size?: number;
|
|
177
|
+
}>;
|
|
178
|
+
export declare function createUpdateProductKnowledgeTool(client: ApiClient): (input: z.infer<typeof updateProductKnowledgeSchema>) => Promise<{
|
|
179
|
+
success: boolean;
|
|
180
|
+
path: string;
|
|
181
|
+
merged?: unknown;
|
|
182
|
+
}>;
|
|
183
|
+
export declare function createUploadProductFilesTool(client: ApiClient): (input: z.infer<typeof uploadProductFilesSchema>) => Promise<{
|
|
184
|
+
success: boolean;
|
|
185
|
+
uploaded: string[];
|
|
186
|
+
}>;
|
|
187
|
+
export declare function createPullProductFilesTool(client: ApiClient): (input: z.infer<typeof pullProductFilesSchema>) => Promise<{
|
|
188
|
+
files_pulled: number;
|
|
189
|
+
output_dir: string;
|
|
190
|
+
files: {
|
|
191
|
+
path: string;
|
|
192
|
+
size: number;
|
|
193
|
+
}[];
|
|
194
|
+
}>;
|
|
195
|
+
export declare function createGetProductIndexTool(client: ApiClient): (input: z.infer<typeof getProductIndexSchema>) => Promise<{
|
|
196
|
+
product_slug: string;
|
|
197
|
+
updated_at: string;
|
|
198
|
+
files: Array<{
|
|
199
|
+
path: string;
|
|
200
|
+
title: string;
|
|
201
|
+
summary: string;
|
|
202
|
+
sections: string[];
|
|
203
|
+
domain: string;
|
|
204
|
+
content_type: string;
|
|
205
|
+
size: number;
|
|
206
|
+
updated_at: string;
|
|
207
|
+
}>;
|
|
208
|
+
}>;
|
|
209
|
+
export declare function createGetProductHealthTool(client: ApiClient): (input: z.infer<typeof getProductHealthSchema>) => Promise<{
|
|
210
|
+
slug: string;
|
|
211
|
+
name: string;
|
|
212
|
+
overall_score: number;
|
|
213
|
+
files: Record<string, unknown>;
|
|
214
|
+
recommendations: string[];
|
|
215
|
+
} | {
|
|
216
|
+
products: Array<{
|
|
217
|
+
slug: string;
|
|
218
|
+
name: string;
|
|
219
|
+
overall_score: number;
|
|
220
|
+
files: Record<string, {
|
|
221
|
+
score: number;
|
|
222
|
+
missing_required: string[];
|
|
223
|
+
}>;
|
|
224
|
+
}>;
|
|
225
|
+
}>;
|
|
226
|
+
export declare function createCreateProductTool(client: ApiClient): (input: z.infer<typeof createProductSchema>) => Promise<{
|
|
227
|
+
product: {
|
|
228
|
+
id: string;
|
|
229
|
+
slug: string;
|
|
230
|
+
name: string;
|
|
231
|
+
description: string | null;
|
|
232
|
+
created_at: string;
|
|
233
|
+
updated_at: string;
|
|
234
|
+
};
|
|
235
|
+
}>;
|
|
236
|
+
export declare function createDeleteProductTool(client: ApiClient): (input: z.infer<typeof deleteProductSchema>) => Promise<{
|
|
237
|
+
success: boolean;
|
|
238
|
+
}>;
|
|
239
|
+
export declare function createDeleteProductFileTool(client: ApiClient): (input: z.infer<typeof deleteProductFileSchema>) => Promise<{
|
|
240
|
+
success: boolean;
|
|
241
|
+
}>;
|