drafted 1.19.52 → 1.19.53
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/mcp/server.mjs +16 -14
- package/package.json +14 -4
package/mcp/server.mjs
CHANGED
|
@@ -174,7 +174,7 @@ export function textFromLocalFile(filePath) {
|
|
|
174
174
|
// validation, and every handler stay byte-for-byte unchanged.
|
|
175
175
|
const REMOTE_JSON_STRING_PARAMS = {
|
|
176
176
|
fs: ['ops', 'state'],
|
|
177
|
-
minion: ['target', 'checklist', 'output'],
|
|
177
|
+
minion: ['target', 'checklist', 'output', 'context'],
|
|
178
178
|
trigger: ['payload'],
|
|
179
179
|
};
|
|
180
180
|
|
|
@@ -466,7 +466,7 @@ const TOOL_ANNOTATIONS = {
|
|
|
466
466
|
screenshot: { title: 'Screenshot', readOnlyHint: true, destructiveHint: false, openWorldHint: false, description: 'Render a PNG via headless browser. `scope=frame` for a single frame, `scope=canvas` for a region of the project surface.' },
|
|
467
467
|
|
|
468
468
|
// Minions — checklist-driven intake surfaces bound to a project
|
|
469
|
-
minion: { title: 'Minions', readOnlyHint: false, destructiveHint: true, openWorldHint: false, description: 'Manage Minions:
|
|
469
|
+
minion: { title: 'Minions', readOnlyHint: false, destructiveHint: true, openWorldHint: false, description: 'Manage Minions: Drafted\'s agent for people OUTSIDE the org (bidders, clients, suppliers). A visitor opens a shareable /c/<slug>-<token> link, the Minion guides them through a checklist, writes ONE submission record into the project, and on submit marks it needs_review and queues it on output.handoff (a queue trigger) for YOUR agent to claim with trigger pending/claim/complete. A Minion never sends, shares or contacts anyone — outbound follow-up is your job. Everything in a Minion\'s config and its context pack is visible to anyone holding the link. Dispatch by `action`: meta, list, get, create, update, enable, disable, delete. QA your own Minions with test_start/test_say (works even when disabled). Requires the agent allowlist.' },
|
|
470
470
|
trigger: { title: 'Inbound triggers', readOnlyHint: false, destructiveHint: true, openWorldHint: true, description: 'Manage inbound webhook triggers for the ACTIVE PROJECT: an external system (AppSheet bot, GitHub, form tool) POSTs to the trigger URL and the server runs an agent conversation in the project from the stored prompt template + payload. Dispatch by `action`: create (returns URL + secret token ONCE — relay it to the user immediately, not retrievable later), list, update (enable/disable, edit template, daily limit, executor), rotate (new token), test (fire a synthetic delivery), deliveries (audit log), delete; for executor="queue" triggers, pending/claim/complete let a LOCAL agent poll and work queued deliveries. Requires the agent allowlist.' },
|
|
471
471
|
fs: { title: 'Filesystem', readOnlyHint: false, destructiveHint: true, openWorldHint: false, description: 'Navigate Drafted like a local filesystem: /wiki/<path> pages, /skills/<slug> procedures, /projects/<folder?>/<project>/<layer>/<lane>/<file> frames. Verbs: ls, read, write, edit, mv, rm, search, link, unlink, links.' },
|
|
472
472
|
// Google Drive mirror triage. Mutating (resolve/retry_all/sync rewrite frame
|
|
@@ -479,7 +479,7 @@ function isMutatingToolCall(name, args = {}) {
|
|
|
479
479
|
const action = args?.action;
|
|
480
480
|
switch (name) {
|
|
481
481
|
case 'minion':
|
|
482
|
-
return ['create', 'update', 'enable', 'disable', 'delete', 'test_start', 'test_say'
|
|
482
|
+
return ['create', 'update', 'enable', 'disable', 'delete', 'test_start', 'test_say'].includes(action);
|
|
483
483
|
case 'trigger':
|
|
484
484
|
return ['create', 'update', 'rotate', 'delete'].includes(action);
|
|
485
485
|
case 'fs':
|
|
@@ -3152,12 +3152,10 @@ function ensureSkillInstallIgnored(dir) {
|
|
|
3152
3152
|
|
|
3153
3153
|
|
|
3154
3154
|
tool('minion', {
|
|
3155
|
-
action: z.enum(['meta', 'list', 'get', 'create', 'update', 'enable', 'disable', 'delete', 'test_start', 'test_say'
|
|
3155
|
+
action: z.enum(['meta', 'list', 'get', 'create', 'update', 'enable', 'disable', 'delete', 'test_start', 'test_say']).describe('Operation to perform. test_* drive a QA conversation against a Minion you own (even disabled) to verify it end-to-end.'),
|
|
3156
3156
|
id: z.string().optional().describe('[get|update|enable|disable|delete|test_*] Minion ID (UUID)'),
|
|
3157
3157
|
text: z.string().optional().describe('[test_say] the consumer message to send to your test run'),
|
|
3158
3158
|
fresh: z.boolean().optional().describe('[test_start] start a brand-new run instead of resuming your latest'),
|
|
3159
|
-
actionId: z.string().optional().describe('[test_resolve] id of the pending action to resolve'),
|
|
3160
|
-
approve: z.boolean().optional().describe('[test_resolve] approve (default true) or reject the pending action'),
|
|
3161
3159
|
projectId: z.string().optional().describe('[meta|list|create] the project this Minion belongs to — REQUIRED, as a path (/projects/<name> or /projects/<folder>/<name>), slug, or UUID. Minions are project-scoped: they write producibles into that project\'s surface. No session fallback — name the project.'),
|
|
3162
3160
|
name: z.string().optional().describe('[create|update] Minion name'),
|
|
3163
3161
|
description: z.string().optional().describe('[create|update] one-line description shown to the consumer'),
|
|
@@ -3186,8 +3184,15 @@ tool('minion', {
|
|
|
3186
3184
|
sheet: z.string().describe('existing Google Sheet frame path or id to append rows to'),
|
|
3187
3185
|
tab: z.string().optional().describe('sheet tab/range name to append to, e.g. "Erfassung" (defaults to Sheet1)'),
|
|
3188
3186
|
columns: z.array(z.string()).optional().describe('columns in order; a link to the produced record is included'),
|
|
3189
|
-
}).optional().describe('
|
|
3187
|
+
}).optional().describe('one row per submission in an existing sheet. With a handoff the row travels in the handoff payload for your agent to append; without one the Minion appends it (raw values, no read access)'),
|
|
3188
|
+
handoff: z.object({
|
|
3189
|
+
triggerId: z.string().describe('a trigger with executor "queue" in the SAME project'),
|
|
3190
|
+
}).optional().describe('where a submitted record is queued for your connected agent to claim (trigger pending/claim/complete); the payload is marked trust:"untrusted-external"'),
|
|
3190
3191
|
}).optional().describe('[create|update] where/how the producible lands'),
|
|
3192
|
+
context: z.object({
|
|
3193
|
+
frames: z.array(z.string()).describe('frame ids in the SAME project, max 20'),
|
|
3194
|
+
}).optional().describe('[create|update] the brief pack the Minion may read and answer from (read_brief). DISCLOSED to every visitor — include only what they may see. The Minion cannot read anything else in the org.'),
|
|
3195
|
+
visitorDailyLimit: z.number().optional().describe('[create|update] turns per visitor per UTC day (default 30); dailyLimit is shared by all visitors'),
|
|
3191
3196
|
limit: z.number().optional().describe('[list] max results per page (default 25, max 100)'),
|
|
3192
3197
|
offset: z.number().optional().describe('[list] skip N results for pagination (default 0)'),
|
|
3193
3198
|
compact: z.boolean().optional().describe('[list] return only {id,slug,name,enabled,projectId} per Minion'),
|
|
@@ -3216,20 +3221,22 @@ tool('minion', {
|
|
|
3216
3221
|
}
|
|
3217
3222
|
case 'create': {
|
|
3218
3223
|
// projectId lives in the BODY (the POST route reads body, ignores the query).
|
|
3219
|
-
const { name, description, target, checklist, output, enabled } = args;
|
|
3224
|
+
const { name, description, target, checklist, output, enabled, context, visitorDailyLimit } = args;
|
|
3220
3225
|
if (!name || !target || !Array.isArray(checklist) || !output) {
|
|
3221
3226
|
throw new Error('name, target, checklist[], and output are required for action=create');
|
|
3222
3227
|
}
|
|
3223
3228
|
const body = { projectId: project.id, name, target, checklist, output };
|
|
3224
3229
|
if (description !== undefined) body.description = description;
|
|
3225
3230
|
if (enabled !== undefined) body.enabled = enabled;
|
|
3231
|
+
if (context !== undefined) body.context = context;
|
|
3232
|
+
if (visitorDailyLimit !== undefined) body.visitorDailyLimit = visitorDailyLimit;
|
|
3226
3233
|
const created = await scoped(() => api('POST', '/api/minions', body));
|
|
3227
3234
|
return ok({ ...created, projectPath });
|
|
3228
3235
|
}
|
|
3229
3236
|
case 'update': {
|
|
3230
3237
|
if (!args.id) throw new Error('id is required for action=update');
|
|
3231
3238
|
const body = {};
|
|
3232
|
-
for (const k of ['name', 'description', 'target', 'checklist', 'output', 'enabled']) {
|
|
3239
|
+
for (const k of ['name', 'description', 'target', 'checklist', 'output', 'enabled', 'context', 'visitorDailyLimit']) {
|
|
3233
3240
|
if (args[k] !== undefined) body[k] = args[k];
|
|
3234
3241
|
}
|
|
3235
3242
|
if (Object.keys(body).length === 0) throw new Error('At least one field is required for action=update');
|
|
@@ -3253,11 +3260,6 @@ tool('minion', {
|
|
|
3253
3260
|
if (!args.text) throw new Error('text is required for action=test_say');
|
|
3254
3261
|
return ok(await api('POST', `/api/minions/${args.id}/test-message`, { content: args.text }));
|
|
3255
3262
|
}
|
|
3256
|
-
case 'test_resolve': {
|
|
3257
|
-
if (!args.id) throw new Error('id is required for action=test_resolve');
|
|
3258
|
-
if (!args.actionId) throw new Error('actionId is required for action=test_resolve');
|
|
3259
|
-
return ok(await api('POST', `/api/minions/${args.id}/test-resolve`, { actionId: args.actionId, approve: args.approve !== false }));
|
|
3260
|
-
}
|
|
3261
3263
|
default:
|
|
3262
3264
|
throw new Error(`Unknown minion action: ${action}`);
|
|
3263
3265
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "drafted",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.53",
|
|
4
4
|
"description": "Drafted — visual thinking surface for humans and AI agents. Renders HTML, markdown, images, and code as frames on a zoomable canvas, with MCP tools for AI agents and real-time sync for humans.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -63,19 +63,29 @@
|
|
|
63
63
|
"lucide": "^1.16.0",
|
|
64
64
|
"mdast-util-from-markdown": "^2.0.3",
|
|
65
65
|
"multer": "^2.1.1",
|
|
66
|
-
"nodemailer": "^
|
|
66
|
+
"nodemailer": "^10.0.13",
|
|
67
67
|
"parse5": "^8.0.1",
|
|
68
68
|
"pg": "^8.20.0",
|
|
69
69
|
"playwright": "^1.58.2",
|
|
70
|
-
"puppeteer": "^
|
|
70
|
+
"puppeteer": "^25.12.0",
|
|
71
71
|
"qrcode-terminal": "^0.12.0",
|
|
72
72
|
"react": "^18.3.1",
|
|
73
73
|
"react-dom": "^18.3.1",
|
|
74
|
-
"sharp": "^0.
|
|
74
|
+
"sharp": "^0.35.5",
|
|
75
75
|
"ws": "^8.21.3",
|
|
76
76
|
"yaml": "^2.8.3",
|
|
77
77
|
"zod": "^4.3.6"
|
|
78
78
|
},
|
|
79
|
+
"overrides": {
|
|
80
|
+
"@excalidraw/excalidraw": {
|
|
81
|
+
"nanoid": "^3.3.19"
|
|
82
|
+
},
|
|
83
|
+
"@excalidraw/mermaid-to-excalidraw": {
|
|
84
|
+
"nanoid": "^5.1.16"
|
|
85
|
+
},
|
|
86
|
+
"immutable": "^4.3.9",
|
|
87
|
+
"lodash-es": "^4.18.1"
|
|
88
|
+
},
|
|
79
89
|
"keywords": [
|
|
80
90
|
"design",
|
|
81
91
|
"canvas",
|