drafted 1.19.37 → 1.19.39
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 +31 -1
- package/package.json +1 -1
package/mcp/server.mjs
CHANGED
|
@@ -1653,6 +1653,7 @@ async function resolveProjectArg(projectArg, { required = true } = {}) {
|
|
|
1653
1653
|
* /projects/<folder>/<project>/<layer>/<lane>/<file>
|
|
1654
1654
|
* /projects/<project>/<layer>/<file> (layer-root file)
|
|
1655
1655
|
* /o/<org>/projects/<project>/<layer>/<lane>/<file> (URL form)
|
|
1656
|
+
* /o/<org>[/<folder>]/tasks/<lane?>/<file> | /tasks/... (tasks root)
|
|
1656
1657
|
* /f/<uuid> | bare UUID
|
|
1657
1658
|
* Returns { frameId } or throws with a helpful message.
|
|
1658
1659
|
*/
|
|
@@ -1666,6 +1667,19 @@ async function resolveFsFramePath(path) {
|
|
|
1666
1667
|
let fsPath = p;
|
|
1667
1668
|
const urlForm = p.match(/^\/o\/[^/]+\/projects\/(.+)$/);
|
|
1668
1669
|
if (urlForm) fsPath = '/projects/' + urlForm[1];
|
|
1670
|
+
// Tasks form. This is the address Drafted PRINTS for a task (the /tasks root,
|
|
1671
|
+
// not the system project behind it), so it has to resolve here too — a printed
|
|
1672
|
+
// path that this tool rejects is the worst kind of dead end. Checked after the
|
|
1673
|
+
// /projects form so the raw `/projects/tasks/tasks/...` URL still works.
|
|
1674
|
+
const taskForm = !urlForm && (p.match(/^\/o\/([^/]+)\/(?:(.+?)\/)?tasks\/(.+)$/) || p.match(/^()()\/tasks\/(.+)$/));
|
|
1675
|
+
if (taskForm) {
|
|
1676
|
+
const sys = await api('POST', '/api/tasks/project', { create: false }, {
|
|
1677
|
+
...(taskForm[1] ? { 'X-Drafted-Org': decodeURIComponent(taskForm[1]) } : {}),
|
|
1678
|
+
...(taskForm[2] ? { 'X-Drafted-Folder': taskForm[2] } : {}),
|
|
1679
|
+
}).catch((e) => (e.status === 404 ? null : Promise.reject(e)));
|
|
1680
|
+
if (!sys?.id) throw new Error(`Not found: ${path} — this org has no tasks yet.`);
|
|
1681
|
+
fsPath = `/projects/${sys.id}/tasks/${taskForm[3]}`;
|
|
1682
|
+
}
|
|
1669
1683
|
if (!fsPath.startsWith('/projects')) {
|
|
1670
1684
|
throw new Error('Target must be a frame URL, frame ID, or path /projects/<project>/<layer>/<lane>/<file>');
|
|
1671
1685
|
}
|
|
@@ -4014,12 +4028,28 @@ tool('fs', 'Navigate Drafted like a local filesystem. A FOLDER is the single con
|
|
|
4014
4028
|
const body = {};
|
|
4015
4029
|
if (gw) {
|
|
4016
4030
|
// Google Workspace frames are created via the workspace endpoint (the
|
|
4017
|
-
// label drops the .google-* extension)
|
|
4031
|
+
// label drops the .google-* extension). Content (inline text, a local
|
|
4032
|
+
// text file, or base64) rides along: the server populates the Doc
|
|
4033
|
+
// (markdown → headings/bullets/styles/tables) or Sheet (CSV rows).
|
|
4034
|
+
let gwContent = null;
|
|
4035
|
+
if (content !== undefined && content !== null && content !== '') gwContent = String(content);
|
|
4036
|
+
else if (file_path) {
|
|
4037
|
+
const resolved = (() => { try { return resolve(file_path); } catch { return file_path; } })();
|
|
4038
|
+
if (!existsSync(resolved)) return err(new Error(`file not found: ${file_path}`));
|
|
4039
|
+
if (typeof file_path === 'string' && /\.(xlsx|xls|pdf|png|jpe?g|gif|webp|zip|docx)$/i.test(resolved)) {
|
|
4040
|
+
return err(new Error(`binary file ${basename(resolved)} cannot populate a ${gw}: pass content= (CSV for .google-sheet, markdown for .google-doc) or write a .xlsx frame instead`));
|
|
4041
|
+
}
|
|
4042
|
+
gwContent = readFileSync(resolved, 'utf8');
|
|
4043
|
+
} else if (base64) {
|
|
4044
|
+
try { gwContent = Buffer.from(base64, 'base64').toString('utf8'); } catch { gwContent = null; }
|
|
4045
|
+
}
|
|
4018
4046
|
const label = basename(filename, extname(filename)) || filename;
|
|
4019
4047
|
const result = await api('POST', '/api/google/workspace/create-frame', {
|
|
4020
4048
|
projectId: getState().projectId,
|
|
4021
4049
|
layer, lane, label, type: gw, title: title || label,
|
|
4050
|
+
...(gwContent ? { content: gwContent } : {}),
|
|
4022
4051
|
}, orgHeader);
|
|
4052
|
+
if (result?.contentError) return err(new Error(`${gw} created but content population failed: ${result.contentError} — populate via google doc-content/sheet-values actions`));
|
|
4023
4053
|
return ok({ ...result, path: `/${layer}/${lane}/${filename}`, sourceType: gw });
|
|
4024
4054
|
}
|
|
4025
4055
|
else if (content) body.content = content;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "drafted",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.39",
|
|
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": [
|