drafted 1.19.25 → 1.19.27
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 +52 -18
- package/package.json +1 -1
package/mcp/server.mjs
CHANGED
|
@@ -633,6 +633,11 @@ registerAppResource(
|
|
|
633
633
|
|
|
634
634
|
const AUTH_FILE = process.env.DRAFTED_AUTH_FILE || join(homedir(), '.drafted', 'auth.json');
|
|
635
635
|
const PENDING_AUTH_FILE = process.env.DRAFTED_PENDING_AUTH_FILE || `${AUTH_FILE}.pending`;
|
|
636
|
+
// The DESKTOP app's own browser session (desktop/src-tauri/src/main.rs writes it beside
|
|
637
|
+
// auth.json). Never read for a credential here — only to answer "is the app signed in?",
|
|
638
|
+
// which is a different question from "is this MCP signed in?" and the one that decides
|
|
639
|
+
// whether an agent can reach the human at all.
|
|
640
|
+
const DESKTOP_SESSION_FILE = join(dirname(AUTH_FILE), 'desktop.json');
|
|
636
641
|
|
|
637
642
|
// Active-project persistence (stdio only): see mcp/active-project-store.mjs.
|
|
638
643
|
// Persisted so a `system restart mode=mcp` / skill-edit pass that re-spawns the
|
|
@@ -2101,6 +2106,51 @@ function desktopAppBinary() {
|
|
|
2101
2106
|
return null; // e.g. Linux — no desktop app → device-code fallback
|
|
2102
2107
|
}
|
|
2103
2108
|
|
|
2109
|
+
/**
|
|
2110
|
+
* The answer to "am I signed in?", which is a question about the MACHINE, not this
|
|
2111
|
+
* process. Two things went wrong before this existed, and they are the same mistake:
|
|
2112
|
+
*
|
|
2113
|
+
* - ~/.drafted/auth.json could be missing while the in-process session was fine. The
|
|
2114
|
+
* desktop's credential burn deletes it on purpose, so `login` answered
|
|
2115
|
+
* already_authenticated — truthfully, and uselessly — while every other reader on the
|
|
2116
|
+
* machine stayed signed out. Restore it from the live session.
|
|
2117
|
+
* - The DESKTOP app could be signed out, which is what actually decides whether an agent
|
|
2118
|
+
* asking for a human reaches anybody: its focus listener needs desktop.json. An agent
|
|
2119
|
+
* must never MINT that credential (origin='browser' is the class that may approve
|
|
2120
|
+
* actions), but opening the app's sign-in window is this tool's documented job — and it
|
|
2121
|
+
* usually completes with NO interaction, because the shared cookie store still holds a
|
|
2122
|
+
* valid login.
|
|
2123
|
+
*/
|
|
2124
|
+
async function alreadyAuthenticated(me, sessionId) {
|
|
2125
|
+
const out = { status: 'already_authenticated', userId: me.userId, email: me.userEmail, org: me.currentOrg?.name };
|
|
2126
|
+
if (!getBootstrapSessionId()) {
|
|
2127
|
+
try {
|
|
2128
|
+
persistAuthSession({ sessionId, userId: me.userId, orgId: me.currentOrg?.id });
|
|
2129
|
+
out.restoredAuthFile = true;
|
|
2130
|
+
out.note = 'This session was signed in but ~/.drafted/auth.json was missing, so other readers on this machine (the desktop app, the CLI) were not. Rewrote it from the live session.';
|
|
2131
|
+
} catch { /* read-only home: report the truth rather than throwing */ }
|
|
2132
|
+
}
|
|
2133
|
+
const bin = desktopAppBinary();
|
|
2134
|
+
if (!bin) return out; // no app here: saying anything about it is noise
|
|
2135
|
+
if (!existsSync(DESKTOP_SESSION_FILE)) {
|
|
2136
|
+
if (await launchDesktopSignin()) {
|
|
2137
|
+
out.openedDesktopSignin = true;
|
|
2138
|
+
// Wait for the result rather than reporting an optimistic one — answering before it
|
|
2139
|
+
// lands is the same class of lie this whole helper exists to stop.
|
|
2140
|
+
for (let i = 0; i < 20 && !existsSync(DESKTOP_SESSION_FILE); i++) {
|
|
2141
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
2142
|
+
}
|
|
2143
|
+
}
|
|
2144
|
+
}
|
|
2145
|
+
out.desktopSignedIn = existsSync(DESKTOP_SESSION_FILE);
|
|
2146
|
+
if (out.openedDesktopSignin) {
|
|
2147
|
+
out.desktopNote = out.desktopSignedIn
|
|
2148
|
+
? 'The desktop app was signed out; opened its sign-in window and it completed on its own from the existing browser session.'
|
|
2149
|
+
: 'The desktop app is signed out and its sign-in window is open — it needs one approval there. Until then it holds no session, so an agent asking for attention cannot reach this machine.';
|
|
2150
|
+
}
|
|
2151
|
+
return out;
|
|
2152
|
+
}
|
|
2153
|
+
|
|
2104
2154
|
async function launchDesktopSignin() {
|
|
2105
2155
|
const bin = desktopAppBinary();
|
|
2106
2156
|
if (!bin) return false;
|
|
@@ -2181,7 +2231,7 @@ if (!isRemote) tool('auth', 'Sign in to Drafted.\n\n`action=get_link` ALWAYS ret
|
|
|
2181
2231
|
await cloneSession();
|
|
2182
2232
|
connectAgentWs();
|
|
2183
2233
|
}
|
|
2184
|
-
return ok(
|
|
2234
|
+
return ok(await alreadyAuthenticated(me, existing));
|
|
2185
2235
|
}
|
|
2186
2236
|
} catch { /* stale session — continue to sign-in */ }
|
|
2187
2237
|
}
|
|
@@ -2227,23 +2277,7 @@ if (!isRemote) tool('auth', 'Sign in to Drafted.\n\n`action=get_link` ALWAYS ret
|
|
|
2227
2277
|
// The desktop's focus listener is one of those readers, so an agent asking
|
|
2228
2278
|
// for a human reached nobody and the tool that exists to fix it reported
|
|
2229
2279
|
// success.
|
|
2230
|
-
|
|
2231
|
-
if (!getBootstrapSessionId()) {
|
|
2232
|
-
try {
|
|
2233
|
-
persistAuthSession({ sessionId: existing, userId: me.userId, orgId: me.currentOrg?.id });
|
|
2234
|
-
restoredAuthFile = true;
|
|
2235
|
-
} catch { /* read-only home: report the truth below rather than throwing */ }
|
|
2236
|
-
}
|
|
2237
|
-
return ok({
|
|
2238
|
-
status: 'already_authenticated',
|
|
2239
|
-
userId: me.userId,
|
|
2240
|
-
email: me.userEmail,
|
|
2241
|
-
org: me.currentOrg?.name,
|
|
2242
|
-
...(restoredAuthFile ? {
|
|
2243
|
-
restoredAuthFile: true,
|
|
2244
|
-
note: 'This session was signed in but ~/.drafted/auth.json was missing, so other readers on this machine (the desktop app, the CLI) were not. Rewrote it from the live session.',
|
|
2245
|
-
} : {}),
|
|
2246
|
-
});
|
|
2280
|
+
return ok(await alreadyAuthenticated(me, existing));
|
|
2247
2281
|
}
|
|
2248
2282
|
} catch { /* session invalid, proceed with login */ }
|
|
2249
2283
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "drafted",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.27",
|
|
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": [
|