drafted 1.17.1 → 1.17.3
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 +25 -3
- package/package.json +1 -1
package/mcp/server.mjs
CHANGED
|
@@ -1940,12 +1940,19 @@ if (!isRemote) tool('auth', 'Sign in to Drafted. On a local install the DESKTOP
|
|
|
1940
1940
|
// Local install → open the desktop app's sign-in window (no link). Falls through to the
|
|
1941
1941
|
// device-code flow below only when no desktop app is installed on this platform.
|
|
1942
1942
|
{
|
|
1943
|
-
const
|
|
1944
|
-
|
|
1943
|
+
const activeSession = getState().sessionId;
|
|
1944
|
+
const bootstrapSession = getBootstrapSessionId();
|
|
1945
|
+
for (const existing of [...new Set([activeSession, bootstrapSession].filter(Boolean))]) {
|
|
1945
1946
|
try {
|
|
1946
1947
|
const meRes = await serverFetch(`${getServerUrl()}/auth/me`, { headers: { Cookie: `gc_session=${existing}` } });
|
|
1947
1948
|
if (meRes.ok) {
|
|
1948
1949
|
const me = await meRes.json();
|
|
1950
|
+
// A stale cloned agent session must never hide a valid desktop login.
|
|
1951
|
+
if (existing === bootstrapSession && existing !== activeSession) {
|
|
1952
|
+
getState().sessionId = null;
|
|
1953
|
+
await cloneSession();
|
|
1954
|
+
connectAgentWs();
|
|
1955
|
+
}
|
|
1949
1956
|
return ok({ status: 'already_authenticated', userId: me.userId, email: me.userEmail, org: me.currentOrg?.name });
|
|
1950
1957
|
}
|
|
1951
1958
|
} catch { /* stale session — continue to sign-in */ }
|
|
@@ -2886,7 +2893,22 @@ tool('fs', 'Navigate Drafted like a local filesystem. An org is the top folder:
|
|
|
2886
2893
|
return ok({ ...result, path: `/${layer}/${lane}/${filename}`, sourceType: gw });
|
|
2887
2894
|
}
|
|
2888
2895
|
else if (content) body.content = content;
|
|
2889
|
-
else if (file_path)
|
|
2896
|
+
else if (file_path) {
|
|
2897
|
+
// Local-file upload (stdio only): read the file here and send base64.
|
|
2898
|
+
// The HTTP API only accepts content/base64 — forwarding the raw path
|
|
2899
|
+
// makes the server reply 'content or base64 is required' (regression
|
|
2900
|
+
// from the fs consolidation; pre-fs write read the file locally).
|
|
2901
|
+
let resolved = file_path;
|
|
2902
|
+
try { resolved = resolve(file_path); } catch { /* keep as-is */ }
|
|
2903
|
+
if (!existsSync(resolved)) {
|
|
2904
|
+
return err(new Error(`file not found: ${file_path}`));
|
|
2905
|
+
}
|
|
2906
|
+
const buffer = readFileSync(resolved);
|
|
2907
|
+
const ext = extname(resolved).toLowerCase();
|
|
2908
|
+
const MIME = { '.png': 'image/png', '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', '.gif': 'image/gif', '.webp': 'image/webp', '.svg': 'image/svg+xml', '.pdf': 'application/pdf' };
|
|
2909
|
+
body.base64 = buffer.toString('base64');
|
|
2910
|
+
body.contentType = MIME[ext] || 'application/octet-stream';
|
|
2911
|
+
}
|
|
2890
2912
|
else if (base64) body.base64 = base64;
|
|
2891
2913
|
else return err(new Error('write requires one of content / file_path / base64 / googleType / state'));
|
|
2892
2914
|
const result = await api('PUT', `/api/fs/${filePath}`, body, orgHeader);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "drafted",
|
|
3
|
-
"version": "1.17.
|
|
3
|
+
"version": "1.17.3",
|
|
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": [
|