@se-studio/contentful-cms 3.15.3 → 3.15.5
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/CHANGELOG.md +12 -0
- package/HOSTED.md +20 -0
- package/README.md +1 -1
- package/dist/commands/host-scaffold.d.ts.map +1 -1
- package/dist/commands/host-scaffold.js +7 -5
- package/dist/commands/host-scaffold.js.map +1 -1
- package/dist/contentful/cma-user-agent.d.ts +1 -1
- package/dist/editor-pack/load.d.ts.map +1 -1
- package/dist/editor-pack/load.js +14 -2
- package/dist/editor-pack/load.js.map +1 -1
- package/dist/generated/help-topics.d.ts.map +1 -1
- package/dist/generated/help-topics.js +1 -1
- package/dist/generated/help-topics.js.map +1 -1
- package/dist/generated/hosted-guide.d.ts +1 -1
- package/dist/generated/hosted-guide.d.ts.map +1 -1
- package/dist/generated/hosted-guide.js +1 -1
- package/dist/generated/hosted-guide.js.map +1 -1
- package/dist/generated/version.d.ts +1 -1
- package/dist/generated/version.js +1 -1
- package/dist/hosted/index.d.ts +1 -1
- package/dist/hosted/index.d.ts.map +1 -1
- package/dist/hosted/index.js +1 -1
- package/dist/hosted/index.js.map +1 -1
- package/dist/hosted/next/pages/CmsEditPage.d.ts.map +1 -1
- package/dist/hosted/next/pages/CmsEditPage.js +1 -1
- package/dist/hosted/next/pages/CmsEditPage.js.map +1 -1
- package/dist/hosted/next/pages/HomePage.d.ts.map +1 -1
- package/dist/hosted/next/pages/HomePage.js +1 -1
- package/dist/hosted/next/pages/HomePage.js.map +1 -1
- package/dist/hosted/next/routes/mcp.d.ts +1 -0
- package/dist/hosted/next/routes/mcp.d.ts.map +1 -1
- package/dist/hosted/next/routes/mcp.js +6 -1
- package/dist/hosted/next/routes/mcp.js.map +1 -1
- package/dist/hosted/next/routes/oauth-authorization-server.d.ts +1 -0
- package/dist/hosted/next/routes/oauth-authorization-server.d.ts.map +1 -1
- package/dist/hosted/next/routes/oauth-authorization-server.js +5 -1
- package/dist/hosted/next/routes/oauth-authorization-server.js.map +1 -1
- package/dist/hosted/next/routes/oauth-protected-resource-path.d.ts +13 -0
- package/dist/hosted/next/routes/oauth-protected-resource-path.d.ts.map +1 -0
- package/dist/hosted/next/routes/oauth-protected-resource-path.js +17 -0
- package/dist/hosted/next/routes/oauth-protected-resource-path.js.map +1 -0
- package/dist/hosted/next/routes/oauth-protected-resource.d.ts +1 -0
- package/dist/hosted/next/routes/oauth-protected-resource.d.ts.map +1 -1
- package/dist/hosted/next/routes/oauth-protected-resource.js +5 -1
- package/dist/hosted/next/routes/oauth-protected-resource.js.map +1 -1
- package/dist/hosted/next/routes/oauth-register.d.ts +1 -0
- package/dist/hosted/next/routes/oauth-register.d.ts.map +1 -1
- package/dist/hosted/next/routes/oauth-register.js +5 -1
- package/dist/hosted/next/routes/oauth-register.js.map +1 -1
- package/dist/hosted/next/routes/oauth-token.d.ts +1 -0
- package/dist/hosted/next/routes/oauth-token.d.ts.map +1 -1
- package/dist/hosted/next/routes/oauth-token.js +5 -1
- package/dist/hosted/next/routes/oauth-token.js.map +1 -1
- package/dist/hosted/oauth/cimd.d.ts +17 -0
- package/dist/hosted/oauth/cimd.d.ts.map +1 -0
- package/dist/hosted/oauth/cimd.js +300 -0
- package/dist/hosted/oauth/cimd.js.map +1 -0
- package/dist/hosted/oauth/complete.d.ts +1 -0
- package/dist/hosted/oauth/complete.d.ts.map +1 -1
- package/dist/hosted/oauth/complete.js +4 -0
- package/dist/hosted/oauth/complete.js.map +1 -1
- package/dist/hosted/oauth/config.d.ts +2 -0
- package/dist/hosted/oauth/config.d.ts.map +1 -1
- package/dist/hosted/oauth/config.js +4 -0
- package/dist/hosted/oauth/config.js.map +1 -1
- package/dist/hosted/oauth/cors.d.ts +4 -0
- package/dist/hosted/oauth/cors.d.ts.map +1 -0
- package/dist/hosted/oauth/cors.js +23 -0
- package/dist/hosted/oauth/cors.js.map +1 -0
- package/dist/hosted/oauth/handlers.d.ts.map +1 -1
- package/dist/hosted/oauth/handlers.js +57 -7
- package/dist/hosted/oauth/handlers.js.map +1 -1
- package/dist/hosted/oauth/log.d.ts +2 -0
- package/dist/hosted/oauth/log.d.ts.map +1 -1
- package/dist/hosted/oauth/log.js +4 -0
- package/dist/hosted/oauth/log.js.map +1 -1
- package/dist/hosted/oauth/redirect-hosts.d.ts +4 -0
- package/dist/hosted/oauth/redirect-hosts.d.ts.map +1 -0
- package/dist/hosted/oauth/redirect-hosts.js +47 -0
- package/dist/hosted/oauth/redirect-hosts.js.map +1 -0
- package/dist/hosted/oauth/refresh.d.ts +1 -0
- package/dist/hosted/oauth/refresh.d.ts.map +1 -1
- package/dist/hosted/oauth/refresh.js +2 -0
- package/dist/hosted/oauth/refresh.js.map +1 -1
- package/dist/hosted/oauth/scopes.d.ts +15 -0
- package/dist/hosted/oauth/scopes.d.ts.map +1 -0
- package/dist/hosted/oauth/scopes.js +21 -0
- package/dist/hosted/oauth/scopes.js.map +1 -0
- package/dist/hosted/oauth/store.d.ts +4 -0
- package/dist/hosted/oauth/store.d.ts.map +1 -1
- package/dist/hosted/oauth/store.js +3 -0
- package/dist/hosted/oauth/store.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +2 -0
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools/client-tools.d.ts +11 -0
- package/dist/mcp/tools/client-tools.d.ts.map +1 -0
- package/dist/mcp/tools/client-tools.js +215 -0
- package/dist/mcp/tools/client-tools.js.map +1 -0
- package/dist/staged-upload/store.d.ts +18 -0
- package/dist/staged-upload/store.d.ts.map +1 -1
- package/dist/staged-upload/store.js +73 -0
- package/dist/staged-upload/store.js.map +1 -1
- package/dist/staged-upload/types.d.ts +2 -0
- package/dist/staged-upload/types.d.ts.map +1 -1
- package/docs/help/workflow.md +1 -1
- package/docs/mcp/hosted-guide.md +11 -8
- package/package.json +1 -1
- package/skills/core/SKILL.md +2 -7
- package/skills/manifest.json +1 -1
- package/skills/setup/SKILL.md +23 -2
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { HOSTED_INLINE_MAX_BYTES } from '../../cli/hosted-inline-limit.js';
|
|
3
|
+
import { readCustomerPlaybook } from '../../hosted/customer-playbooks.js';
|
|
4
|
+
import { getRuntimeContext } from '../../runtime/context.js';
|
|
5
|
+
import { prefixHostedToolDescription } from '../hosted-metadata.js';
|
|
6
|
+
const READ_ONLY = {
|
|
7
|
+
readOnlyHint: true,
|
|
8
|
+
destructiveHint: false,
|
|
9
|
+
idempotentHint: true,
|
|
10
|
+
openWorldHint: true,
|
|
11
|
+
};
|
|
12
|
+
const DRAFT_WRITE = {
|
|
13
|
+
readOnlyHint: false,
|
|
14
|
+
destructiveHint: false,
|
|
15
|
+
idempotentHint: false,
|
|
16
|
+
openWorldHint: true,
|
|
17
|
+
};
|
|
18
|
+
function textResult(value) {
|
|
19
|
+
return {
|
|
20
|
+
content: [{ type: 'text', text: JSON.stringify(value) }],
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/** Split cms-edit stdout into the command body and the trailing CMA stats line. */
|
|
24
|
+
export function parseCmsEditToolBody(raw) {
|
|
25
|
+
const trimmed = raw.trim();
|
|
26
|
+
const lines = trimmed.split('\n');
|
|
27
|
+
let body = trimmed;
|
|
28
|
+
const last = lines[lines.length - 1] ?? '';
|
|
29
|
+
try {
|
|
30
|
+
const stats = JSON.parse(last);
|
|
31
|
+
if (stats && typeof stats === 'object' && 'cma_requests' in stats) {
|
|
32
|
+
body = lines.slice(0, -1).join('\n').trim();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// The last line is part of the command body.
|
|
37
|
+
}
|
|
38
|
+
if (/\(exit code \d+\)\s*$/.test(body)) {
|
|
39
|
+
return { ok: false, data: null, error: body };
|
|
40
|
+
}
|
|
41
|
+
if (!body) {
|
|
42
|
+
return { ok: true, data: null };
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
return { ok: true, data: JSON.parse(body) };
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return { ok: true, data: body };
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function asSearchResults(data) {
|
|
52
|
+
if (!Array.isArray(data)) {
|
|
53
|
+
return [];
|
|
54
|
+
}
|
|
55
|
+
const results = [];
|
|
56
|
+
for (const item of data) {
|
|
57
|
+
if (!item || typeof item !== 'object')
|
|
58
|
+
continue;
|
|
59
|
+
const row = item;
|
|
60
|
+
if (typeof row.id !== 'string' || row.id.length === 0)
|
|
61
|
+
continue;
|
|
62
|
+
const title = typeof row.title === 'string' && row.title.length > 0 ? row.title : row.id;
|
|
63
|
+
const url = typeof row.slug === 'string' && row.slug.length > 0 ? `/${row.slug}` : row.id;
|
|
64
|
+
results.push({ id: row.id, title, url });
|
|
65
|
+
}
|
|
66
|
+
return results;
|
|
67
|
+
}
|
|
68
|
+
function fetchDocument(id, data) {
|
|
69
|
+
const row = data && typeof data === 'object' ? data : undefined;
|
|
70
|
+
const title = typeof row?.title === 'string' && row.title.length > 0 ? row.title : id;
|
|
71
|
+
const url = typeof row?.slug === 'string' && row.slug.length > 0 ? `/${row.slug}` : id;
|
|
72
|
+
const text = typeof data === 'string' ? data : JSON.stringify(data);
|
|
73
|
+
return { id, title, text, url };
|
|
74
|
+
}
|
|
75
|
+
async function runParsed(runCmsEdit, args) {
|
|
76
|
+
return parseCmsEditToolBody(await runCmsEdit(args));
|
|
77
|
+
}
|
|
78
|
+
export function registerClientTools(server, runCmsEdit, hosted, editorPackPath) {
|
|
79
|
+
server.tool('search', prefixHostedToolDescription('Search Contentful entries (drafts and published). Returns id, title, and url for each hit. Does not publish.', hosted), {
|
|
80
|
+
query: z.string().describe('Full-text query'),
|
|
81
|
+
limit: z.number().int().min(1).max(20).optional().describe('Max results, default 10'),
|
|
82
|
+
}, READ_ONLY, async ({ query, limit }) => {
|
|
83
|
+
const args = ['search', '-n', String(limit ?? 10), '--json', '--', query];
|
|
84
|
+
const parsed = await runParsed(runCmsEdit, args);
|
|
85
|
+
if (!parsed.ok) {
|
|
86
|
+
return textResult({ results: [], error: parsed.error });
|
|
87
|
+
}
|
|
88
|
+
return textResult({ results: asSearchResults(parsed.data) });
|
|
89
|
+
});
|
|
90
|
+
server.tool('fetch', prefixHostedToolDescription('Fetch one Contentful entry by id. Returns id, title, text, and url. Draft content is included. Does not publish.', hosted), { id: z.string().describe('Contentful entry id') }, READ_ONLY, async ({ id }) => {
|
|
91
|
+
const parsed = await runParsed(runCmsEdit, ['read', id, '--id']);
|
|
92
|
+
if (!parsed.ok) {
|
|
93
|
+
return textResult({ id, title: id, text: parsed.error ?? 'read failed', url: id });
|
|
94
|
+
}
|
|
95
|
+
return textResult(fetchDocument(id, parsed.data));
|
|
96
|
+
});
|
|
97
|
+
server.tool('read_entry', prefixHostedToolDescription('Read one entry or one field by Contentful id. No editing session required.', hosted), {
|
|
98
|
+
id: z.string().describe('Contentful entry id'),
|
|
99
|
+
field: z.string().optional().describe('Field id. Omit to read the entry.'),
|
|
100
|
+
}, READ_ONLY, async ({ id, field }) => {
|
|
101
|
+
const args = field ? ['read', id, '--id', field] : ['read', id, '--id'];
|
|
102
|
+
const parsed = await runParsed(runCmsEdit, args);
|
|
103
|
+
return textResult(parsed.ok ? { ok: true, entry: parsed.data } : { ok: false, error: parsed.error });
|
|
104
|
+
});
|
|
105
|
+
server.tool('get_editor_guide', prefixHostedToolDescription('Read one site playbook (tasks-index, capabilities, checklist, overview, routing, or a task name). Call tasks-index first.', hosted), { resource: z.string().describe('Playbook name, for example tasks-index') }, READ_ONLY, async ({ resource }) => {
|
|
106
|
+
const playbook = readCustomerPlaybook(resource, editorPackPath);
|
|
107
|
+
if (!playbook) {
|
|
108
|
+
return textResult({
|
|
109
|
+
ok: false,
|
|
110
|
+
error: `Unknown playbook: ${resource}`,
|
|
111
|
+
hint: 'Call get_editor_guide with resource "tasks-index".',
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
return textResult({ ok: true, resource: playbook.name, content: playbook.text });
|
|
115
|
+
});
|
|
116
|
+
server.tool('set_field', prefixHostedToolDescription('Set one field on the open cms-edit session. Saves nothing until save_draft. Values over 8192 bytes must use append_text. Does not publish.', hosted), {
|
|
117
|
+
ref: z.string().describe('Session ref such as @c1, or an entry id'),
|
|
118
|
+
field: z.string().describe('Field id'),
|
|
119
|
+
value: z.string().describe('New value'),
|
|
120
|
+
mode: z
|
|
121
|
+
.enum(['scalar', 'link', 'links', 'richtext'])
|
|
122
|
+
.optional()
|
|
123
|
+
.describe('scalar (default), link, links, or richtext'),
|
|
124
|
+
}, DRAFT_WRITE, async ({ ref, field, value, mode }) => {
|
|
125
|
+
const bytes = Buffer.byteLength(value);
|
|
126
|
+
if (bytes > HOSTED_INLINE_MAX_BYTES) {
|
|
127
|
+
return textResult({
|
|
128
|
+
ok: false,
|
|
129
|
+
error: `value is ${String(bytes)} bytes. Call append_text (kind text or json), then cms_edit set/rtf with --staged.`,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
const resolved = mode ?? 'scalar';
|
|
133
|
+
const args = resolved === 'richtext'
|
|
134
|
+
? ['rtf', ref, field, '--content', value]
|
|
135
|
+
: resolved === 'link'
|
|
136
|
+
? ['set', ref, field, '--link', '--', value]
|
|
137
|
+
: resolved === 'links'
|
|
138
|
+
? ['set', ref, field, '--links', '--', value]
|
|
139
|
+
: ['set', ref, field, '--', value];
|
|
140
|
+
const parsed = await runParsed(runCmsEdit, args);
|
|
141
|
+
return textResult(parsed.ok ? { ok: true, result: parsed.data } : { ok: false, error: parsed.error });
|
|
142
|
+
});
|
|
143
|
+
server.tool('diff_draft', prefixHostedToolDescription('Show unsaved draft edits in the current session.', hosted), {}, READ_ONLY, async () => {
|
|
144
|
+
const parsed = await runParsed(runCmsEdit, ['diff']);
|
|
145
|
+
return textResult(parsed.ok ? { ok: true, diff: parsed.data } : { ok: false, error: parsed.error });
|
|
146
|
+
});
|
|
147
|
+
server.tool('save_draft', prefixHostedToolDescription('Write the open session to Contentful as drafts. Does not publish, unpublish, archive, or delete.', hosted), {}, DRAFT_WRITE, async () => {
|
|
148
|
+
const parsed = await runParsed(runCmsEdit, ['save']);
|
|
149
|
+
return textResult(parsed.ok ? { ok: true, result: parsed.data } : { ok: false, error: parsed.error });
|
|
150
|
+
});
|
|
151
|
+
server.tool('append_text', prefixHostedToolDescription('Upload long text or JSON without a shell. Start with fileName, mimeType, and kind. Repeat with uploadId and offset set to the bytes value from the previous call. Set final true on the last chunk, then pass uploadId to cms_edit --staged. Each chunk is at most 8192 bytes.', hosted), {
|
|
152
|
+
chunk: z.string().describe('Next piece of the file'),
|
|
153
|
+
final: z.boolean().describe('True on the last chunk'),
|
|
154
|
+
uploadId: z.string().optional().describe('Omit on the first chunk'),
|
|
155
|
+
offset: z
|
|
156
|
+
.number()
|
|
157
|
+
.int()
|
|
158
|
+
.min(0)
|
|
159
|
+
.optional()
|
|
160
|
+
.describe('Byte offset. 0 on the first chunk, then the bytes value from the previous call'),
|
|
161
|
+
fileName: z.string().optional().describe('Required on the first chunk'),
|
|
162
|
+
mimeType: z.string().optional().describe('text/html, text/plain, or application/json'),
|
|
163
|
+
kind: z
|
|
164
|
+
.enum(['text', 'json'])
|
|
165
|
+
.optional()
|
|
166
|
+
.describe('text or json. Required on the first chunk'),
|
|
167
|
+
}, DRAFT_WRITE, async ({ chunk, final, uploadId, fileName, mimeType, kind, offset }) => {
|
|
168
|
+
const bytes = Buffer.byteLength(chunk);
|
|
169
|
+
if (bytes > HOSTED_INLINE_MAX_BYTES) {
|
|
170
|
+
return textResult({
|
|
171
|
+
ok: false,
|
|
172
|
+
error: `chunk is ${String(bytes)} bytes. Send at most ${String(HOSTED_INLINE_MAX_BYTES)} bytes per call.`,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
const context = getRuntimeContext();
|
|
176
|
+
const userId = context?.user?.userId;
|
|
177
|
+
const store = context?.stagedUploadStore;
|
|
178
|
+
if (!userId || !store) {
|
|
179
|
+
return textResult({
|
|
180
|
+
ok: false,
|
|
181
|
+
error: 'append_text requires hosted MCP (signed-in user and Redis).',
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
try {
|
|
185
|
+
let id = uploadId;
|
|
186
|
+
if (!id) {
|
|
187
|
+
if (!fileName || !mimeType || !kind) {
|
|
188
|
+
return textResult({
|
|
189
|
+
ok: false,
|
|
190
|
+
error: 'The first append_text call needs fileName, mimeType, and kind.',
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
id = await store.createPending({
|
|
194
|
+
userId,
|
|
195
|
+
fileName,
|
|
196
|
+
mimeType,
|
|
197
|
+
kind: kind,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
const result = await store.appendText({
|
|
201
|
+
userId,
|
|
202
|
+
uploadId: id,
|
|
203
|
+
chunk,
|
|
204
|
+
final,
|
|
205
|
+
offset,
|
|
206
|
+
});
|
|
207
|
+
return textResult({ ok: true, ...result });
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
211
|
+
return textResult({ ok: false, error: message });
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=client-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-tools.js","sourceRoot":"","sources":["../../../src/mcp/tools/client-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,6 +18,24 @@ export declare class StagedUploadStore {
|
|
|
18
18
|
consume(userId: string, uploadId: string): Promise<StagedUploadConsumeResult>;
|
|
19
19
|
/** Read staged bytes without deleting (pipeline fetch). */
|
|
20
20
|
peekFile(userId: string, uploadId: string): Promise<StagedUploadConsumeResult>;
|
|
21
|
+
private withSlotLock;
|
|
22
|
+
/**
|
|
23
|
+
* Append a text or JSON chunk into a pending slot. `final` marks the slot ready
|
|
24
|
+
* for `--staged` consume. Binary assets stay on the curl / direct intake path.
|
|
25
|
+
* `offset` is the byte length already stored. A retry of the same offset and
|
|
26
|
+
* chunk is a no-op.
|
|
27
|
+
*/
|
|
28
|
+
appendText(params: {
|
|
29
|
+
userId: string;
|
|
30
|
+
uploadId: string;
|
|
31
|
+
chunk: string;
|
|
32
|
+
final: boolean;
|
|
33
|
+
offset?: number;
|
|
34
|
+
}): Promise<{
|
|
35
|
+
uploadId: string;
|
|
36
|
+
bytes: number;
|
|
37
|
+
complete: boolean;
|
|
38
|
+
}>;
|
|
21
39
|
getRecord(userId: string, uploadId: string): Promise<StagedUploadRecord | null>;
|
|
22
40
|
}
|
|
23
41
|
//# sourceMappingURL=store.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/staged-upload/store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAM/D,OAAO,EAGL,KAAK,gBAAgB,EAEtB,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AA0BhF,qBAAa,iBAAiB;IAE1B,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAF5B,YACmB,KAAK,EAAE,WAAW,EAClB,SAAS,SAAa,EACrC;IAEJ,OAAO,CAAC,OAAO;IAIT,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAYnD;IAEK,aAAa,CAAC,MAAM,EAAE;QAC1B,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,CAAC,EAAE,gBAAgB,CAAC;QACxB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,GAAG,OAAO,CAAC,MAAM,CAAC,CAqClB;IAEK,SAAS,CACb,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,kBAAkB,CAAC,
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/staged-upload/store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAM/D,OAAO,EAGL,KAAK,gBAAgB,EAEtB,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AA0BhF,qBAAa,iBAAiB;IAE1B,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAF5B,YACmB,KAAK,EAAE,WAAW,EAClB,SAAS,SAAa,EACrC;IAEJ,OAAO,CAAC,OAAO;IAIT,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAYnD;IAEK,aAAa,CAAC,MAAM,EAAE;QAC1B,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,CAAC,EAAE,gBAAgB,CAAC;QACxB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,GAAG,OAAO,CAAC,MAAM,CAAC,CAqClB;IAEK,SAAS,CACb,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,kBAAkB,CAAC,CAiC7B;IAEK,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAsBlF;IAED,2DAA2D;IACrD,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAiBnF;YAEa,YAAY;IAiB1B;;;;;OAKG;IACG,UAAU,CAAC,MAAM,EAAE;QACvB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,OAAO,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC,CAkElE;IAEK,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAEpF;CACF"}
|
|
@@ -98,6 +98,7 @@ export class StagedUploadStore {
|
|
|
98
98
|
mimeType: resolvedMime,
|
|
99
99
|
byteLength: buffer.length,
|
|
100
100
|
dataBase64: buffer.toString('base64'),
|
|
101
|
+
partialText: undefined,
|
|
101
102
|
};
|
|
102
103
|
await this.redis.set(key, JSON.stringify(record), { ex: STAGED_UPLOAD_TTL_SECONDS });
|
|
103
104
|
return record;
|
|
@@ -141,6 +142,78 @@ export class StagedUploadStore {
|
|
|
141
142
|
kind: stagedKindOrAsset(existing.kind),
|
|
142
143
|
};
|
|
143
144
|
}
|
|
145
|
+
async withSlotLock(userId, uploadId, fn) {
|
|
146
|
+
const lockKey = `${this.fullKey(userId, uploadId)}:lock`;
|
|
147
|
+
const acquired = await this.redis.set(lockKey, '1', { nx: true, ex: 30 });
|
|
148
|
+
if (acquired !== true) {
|
|
149
|
+
throw new Error('Staged upload is being updated. Retry this chunk.');
|
|
150
|
+
}
|
|
151
|
+
try {
|
|
152
|
+
return await fn();
|
|
153
|
+
}
|
|
154
|
+
finally {
|
|
155
|
+
await this.redis.del(lockKey);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Append a text or JSON chunk into a pending slot. `final` marks the slot ready
|
|
160
|
+
* for `--staged` consume. Binary assets stay on the curl / direct intake path.
|
|
161
|
+
* `offset` is the byte length already stored. A retry of the same offset and
|
|
162
|
+
* chunk is a no-op.
|
|
163
|
+
*/
|
|
164
|
+
async appendText(params) {
|
|
165
|
+
return this.withSlotLock(params.userId, params.uploadId, async () => {
|
|
166
|
+
const key = this.fullKey(params.userId, params.uploadId);
|
|
167
|
+
const existing = parseRecord(await this.redis.get(key));
|
|
168
|
+
if (!existing || existing.userId !== params.userId || existing.uploadId !== params.uploadId) {
|
|
169
|
+
throw new Error('Staged upload slot not found or expired.');
|
|
170
|
+
}
|
|
171
|
+
const kind = stagedKindOrAsset(existing.kind);
|
|
172
|
+
if (kind === 'asset') {
|
|
173
|
+
throw new Error('append_text only accepts kind=text or kind=json slots.');
|
|
174
|
+
}
|
|
175
|
+
const stored = existing.status === 'ready'
|
|
176
|
+
? Buffer.from(existing.dataBase64 ?? '', 'base64').toString('utf8')
|
|
177
|
+
: (existing.partialText ?? '');
|
|
178
|
+
const storedBytes = Buffer.byteLength(stored);
|
|
179
|
+
const chunkBytes = Buffer.byteLength(params.chunk);
|
|
180
|
+
const offset = params.offset ?? (storedBytes === 0 ? 0 : undefined);
|
|
181
|
+
if (offset === undefined) {
|
|
182
|
+
throw new Error('Pass offset from the previous append_text bytes value. Use 0 on the first chunk.');
|
|
183
|
+
}
|
|
184
|
+
if (offset < storedBytes) {
|
|
185
|
+
const storedBuf = Buffer.from(stored);
|
|
186
|
+
const chunkBuf = Buffer.from(params.chunk);
|
|
187
|
+
const slice = storedBuf.subarray(offset, offset + chunkBuf.length);
|
|
188
|
+
if (slice.length !== chunkBuf.length || !slice.equals(chunkBuf)) {
|
|
189
|
+
throw new Error('Staged upload chunk does not match the bytes already stored at that offset.');
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
uploadId: params.uploadId,
|
|
193
|
+
bytes: storedBytes,
|
|
194
|
+
complete: existing.status === 'ready',
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
if (offset > storedBytes) {
|
|
198
|
+
throw new Error('Staged upload offset is past the stored text. Pass the bytes value from the previous append_text call.');
|
|
199
|
+
}
|
|
200
|
+
if (existing.status === 'ready') {
|
|
201
|
+
throw new Error('Staged upload already received.');
|
|
202
|
+
}
|
|
203
|
+
const next = `${stored}${params.chunk}`;
|
|
204
|
+
const bytes = storedBytes + chunkBytes;
|
|
205
|
+
if (bytes > hostedStagedMaxBytes()) {
|
|
206
|
+
throw new Error(`File exceeds hosted staged upload limit (${String(hostedStagedMaxBytes())} bytes).`);
|
|
207
|
+
}
|
|
208
|
+
if (!params.final) {
|
|
209
|
+
const record = { ...existing, partialText: next, byteLength: bytes };
|
|
210
|
+
await this.redis.set(key, JSON.stringify(record), { ex: STAGED_UPLOAD_TTL_SECONDS });
|
|
211
|
+
return { uploadId: params.uploadId, bytes, complete: false };
|
|
212
|
+
}
|
|
213
|
+
await this.storeFile(params.userId, params.uploadId, Buffer.from(next), existing.mimeType);
|
|
214
|
+
return { uploadId: params.uploadId, bytes, complete: true };
|
|
215
|
+
});
|
|
216
|
+
}
|
|
144
217
|
async getRecord(userId, uploadId) {
|
|
145
218
|
return parseRecord(await this.redis.get(this.fullKey(userId, uploadId)));
|
|
146
219
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/staged-upload/store.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/staged-upload/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,6 +10,8 @@ export interface StagedUploadRecord {
|
|
|
10
10
|
byteLength?: number;
|
|
11
11
|
status: StagedUploadStatus;
|
|
12
12
|
dataBase64?: string;
|
|
13
|
+
/** UTF-8 text accumulated by append_text before the slot is marked ready. */
|
|
14
|
+
partialText?: string;
|
|
13
15
|
createdAt: number;
|
|
14
16
|
}
|
|
15
17
|
export interface StagedUploadRequestResult {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/staged-upload/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAElD,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,OAAO,CAAC;AAErD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,6EAA6E;IAC7E,MAAM,EAAE,UAAU,GAAG,QAAQ,CAAC;IAC9B,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,gBAAgB,CAAC;CACxB"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/staged-upload/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAElD,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,OAAO,CAAC;AAErD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,6EAA6E;IAC7E,MAAM,EAAE,UAAU,GAAG,QAAQ,CAAC;IAC9B,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,gBAAgB,CAAC;CACxB"}
|
package/docs/help/workflow.md
CHANGED
|
@@ -177,7 +177,7 @@ Shows a summary of which entries have been modified and which fields changed.
|
|
|
177
177
|
cms-edit save
|
|
178
178
|
```
|
|
179
179
|
|
|
180
|
-
Writes all changes to Contentful as **drafts**.
|
|
180
|
+
Writes all changes to Contentful as **drafts**. Publish, unpublish, and archive use `publish plan` then `publish apply` after an explicit yes, and only when the Contentful role allows it. AI Editor cannot.
|
|
181
181
|
|
|
182
182
|
---
|
|
183
183
|
|
package/docs/mcp/hosted-guide.md
CHANGED
|
@@ -6,12 +6,7 @@ Use this guide when editing Contentful draft content through a hosted MCP connec
|
|
|
6
6
|
|
|
7
7
|
## Safety rules
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
- Publish or unpublish entries
|
|
12
|
-
- Archive or delete published entries
|
|
13
|
-
|
|
14
|
-
All `save` operations create **drafts only**. A human must review and publish in Contentful.
|
|
9
|
+
`save` writes **drafts only**. Publish, unpublish, and archive use `publish plan`, then `publish apply` after an explicit yes, and only when the signed-in Contentful role allows it. AI Editor cannot. Typed tools do not publish.
|
|
15
10
|
|
|
16
11
|
**Assets:** Always **search and reuse** first (`index sync`, then `asset search`). Raster/video go through **`cms_edit_media`** (Drive, or intake then prepare → import). Video, and an image master over 4MB, is a presigned PUT (`intake: direct`) then prepare with `httpsUrls`. An image at or under 4MB uses a function POST then `stagedUploadIds`. Never `asset upload` jpeg/png/webp/gif/mp4, and never convert those files with local ffmpeg. SVG/PDF/Lottie: staged upload then `asset upload --staged`. **`--base64` is not supported on hosted MCP.**
|
|
17
12
|
|
|
@@ -131,10 +126,10 @@ Always run `diff` before `save`. To abandon changes: `["discard"]`.
|
|
|
131
126
|
|------|-------|
|
|
132
127
|
| Edit copy, add sections, create pages/articles | **Agent + cms-edit** (drafts) |
|
|
133
128
|
| Upload new images and files | **Agent + cms-edit** — search/reuse first; raster/video via `cms_edit_media` import |
|
|
134
|
-
| Publish
|
|
129
|
+
| Publish, unpublish, or archive | **cms-edit** `publish plan`, then `publish apply` after an explicit yes, when the Contentful role allows it |
|
|
135
130
|
| Edit copy directly in Contentful | **Avoid** — use cms-edit instead |
|
|
136
131
|
|
|
137
|
-
cms-edit saves **drafts
|
|
132
|
+
cms-edit saves **drafts**. Going live needs that plan and an explicit yes. AI Editor cannot publish.
|
|
138
133
|
|
|
139
134
|
## Asset upload (hosted MCP)
|
|
140
135
|
|
|
@@ -294,6 +289,14 @@ Replace the server name and host with your site's deployment. The URL **must** e
|
|
|
294
289
|
|
|
295
290
|
OAuth is two steps: Grok obtains an MCP token, then you sign in with Contentful to link your account. If the browser flashes and closes immediately, reconnect after upgrading cms-edit (loopback redirect handling).
|
|
296
291
|
|
|
292
|
+
## Other clients
|
|
293
|
+
|
|
294
|
+
Paste the same `/api/mcp` URL. ChatGPT: Settings → Apps & Connectors → custom MCP server → OAuth → Contentful. Draft saves need a Business, Enterprise, or Edu workspace. Recreate the connector after a tool change.
|
|
295
|
+
|
|
296
|
+
Cursor and VS Code: remote HTTP MCP, then OAuth. Gemini CLI: `url` under `mcpServers`.
|
|
297
|
+
|
|
298
|
+
If the client has no shell, use `search`, `fetch`, `get_editor_guide`, `set_field`, `diff_draft`, `save_draft`, and `append_text` (chunks of at most 8192 bytes). `save_draft` writes drafts only.
|
|
299
|
+
|
|
297
300
|
## Hosted connector rules
|
|
298
301
|
|
|
299
302
|
{{HOSTED_RULES}}
|
package/package.json
CHANGED
package/skills/core/SKILL.md
CHANGED
|
@@ -25,12 +25,7 @@ Use this skill when you need to read or edit content in Contentful using **hoste
|
|
|
25
25
|
|
|
26
26
|
## Safety Rules
|
|
27
27
|
|
|
28
|
-
**
|
|
29
|
-
- Publish any entry
|
|
30
|
-
- Unpublish any entry
|
|
31
|
-
- Archive or delete published entries
|
|
32
|
-
|
|
33
|
-
All `save` operations create **draft** versions. A human must review and publish in Contentful.
|
|
28
|
+
`save` writes **drafts**. Publish, unpublish, and archive use `publish plan`, then `publish apply` after an explicit yes, and only when the signed-in Contentful role allows it. AI Editor cannot. Do not publish as part of save.
|
|
34
29
|
|
|
35
30
|
**Assets:** Upload **is** supported (`asset upload`). Default workflow: **search and reuse** existing assets first (`index sync` → `asset search`). Search by concept (`asset search --concept` / `--concept-all`) finds a subject and a tone, including files no page uses yet. Concepts are not blog tags. When uploading:
|
|
36
31
|
- **Raster/video:** `cms_edit_request_staged_upload` → curl → `cms_edit_media` prepare → wait → catalog → import with real alt. Video, and an image master over 4MB, is a presigned direct PUT (100MB, `intake: direct`) then prepare with that URL. Smaller images still use `stagedUploadIds`. Never `asset upload --staged/--url/--base64` for jpeg/png/webp/gif/mp4. The stored asset is the processed file.
|
|
@@ -204,7 +199,7 @@ Shows a diff of all modified fields across all changed entries.
|
|
|
204
199
|
cms-edit save
|
|
205
200
|
```
|
|
206
201
|
|
|
207
|
-
Writes all changes to Contentful as **drafts**.
|
|
202
|
+
Writes all changes to Contentful as **drafts**. They stay drafts until `publish plan` then `publish apply`, after an explicit yes, and only if the Contentful role allows it.
|
|
208
203
|
|
|
209
204
|
After saving, the session is cleared automatically if all changes were saved.
|
|
210
205
|
|
package/skills/manifest.json
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
"core": "Edit Contentful drafts via hosted cms-edit MCP (open → snapshot → read → set/rtf → diff → save). Local CLI content commands are disabled.",
|
|
3
3
|
"editor-tasks": "Route CMS editing intents to site task playbooks via tasks-index (hosted MCP resources or local editor-pack files).",
|
|
4
4
|
"templates": "Create or edit templates (preContent, postContent, menu, footer, colours) in Contentful via cms-edit.",
|
|
5
|
-
"setup": "Guide a user through connecting hosted cms-edit MCP for Claude
|
|
5
|
+
"setup": "Guide a user through connecting hosted cms-edit MCP for Claude, ChatGPT, Grok, Cursor, or Gemini (OAuth)."
|
|
6
6
|
}
|
package/skills/setup/SKILL.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: contentful-cms-setup
|
|
3
|
-
description: "Guide a user through connecting hosted cms-edit MCP for Claude
|
|
3
|
+
description: "Guide a user through connecting hosted cms-edit MCP for Claude, ChatGPT, Grok, Cursor, or Gemini (OAuth)."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Skill: cms-edit Setup
|
|
7
7
|
|
|
8
|
-
Use this skill when the user wants to connect Claude
|
|
8
|
+
Use this skill when the user wants to connect Claude, ChatGPT, Grok, Cursor, VS Code, or Gemini CLI to their Contentful site via **hosted cms-edit MCP**.
|
|
9
9
|
|
|
10
10
|
Local stdio MCP and the setup wizard are **not supported**. Editors connect through the site's `/cms-edit` onboarding flow.
|
|
11
11
|
|
|
@@ -68,6 +68,27 @@ Full guide: `packages/contentful-cms/docs/mcp/hosted-guide.md` (Grok Build secti
|
|
|
68
68
|
|
|
69
69
|
---
|
|
70
70
|
|
|
71
|
+
## Hosted setup (ChatGPT and other remote MCP clients)
|
|
72
|
+
|
|
73
|
+
The MCP URL is the same URL as Claude (`https://<host>/api/mcp`). The client must speak remote Streamable HTTP and OAuth. There is no local stdio server and no OpenAPI Action.
|
|
74
|
+
|
|
75
|
+
### ChatGPT
|
|
76
|
+
|
|
77
|
+
1. Settings → **Apps & Connectors** → create a custom MCP server
|
|
78
|
+
2. Paste the MCP URL and choose **OAuth**
|
|
79
|
+
3. Sign in with **Contentful**
|
|
80
|
+
4. Ask it to call `search` or `cms_edit_version`
|
|
81
|
+
|
|
82
|
+
Draft writes (`set_field`, `save_draft`) need a Business, Enterprise, or Edu workspace. Pro can be read-only. ChatGPT freezes the tool list at connect time: after a cms-edit upgrade, remove the connector and add it again.
|
|
83
|
+
|
|
84
|
+
Clients that cannot run a shell use `append_text` for bodies over 8192 bytes, then `cms_edit` with `--staged`. `save_draft` does not publish.
|
|
85
|
+
|
|
86
|
+
### Cursor, VS Code, Gemini CLI
|
|
87
|
+
|
|
88
|
+
Add the MCP URL as a remote HTTP server and complete OAuth. Cursor: `~/.cursor/mcp.json` `url`. VS Code: `.vscode/mcp.json` `servers` with `type: http`. Gemini CLI: `mcpServers.<name>.url`.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
71
92
|
## Developers (CLI + skills, not local MCP)
|
|
72
93
|
|
|
73
94
|
For engineering work in a site repo (Cursor, Grok, terminal):
|