drafted 1.19.5 → 1.19.6
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/install-mcp.sh +1 -1
- package/mcp/server.mjs +24 -3
- package/package.json +1 -1
- package/plugin/skills/drafted/SKILL.md +1 -1
package/install-mcp.sh
CHANGED
|
@@ -480,7 +480,7 @@ load_global_agent_instructions() {
|
|
|
480
480
|
fi
|
|
481
481
|
cat <<'DRAFTED_GLOBAL_INSTRUCTIONS'
|
|
482
482
|
<drafted>
|
|
483
|
-
You have Drafted MCP tools — a shared surface for durable, reviewable work: produce substantive output as frames on the surface (not only in chat), put knowledge in the org wiki, and encode repeatable methods as skills. The full operating manual is the `drafted` skill installed with the plugin — follow it when working with Drafted. Before writing, verify the org/project echoed in the response is the one you intend.
|
|
483
|
+
You have Drafted MCP tools — a shared surface for durable, reviewable work: produce substantive output as frames on the surface (not only in chat), put knowledge in the org wiki, and encode repeatable methods as skills. The full operating manual is the `drafted` skill installed with the plugin — follow it when working with Drafted. Address orgs by path: `fs(ls, path="/")` lists them, and `/o/<org>/<root>/...` (root ∈ wiki, skills, projects) is the canonical path form — the org is part of the path, never a separate switch. Before writing, verify the org/project echoed in the response is the one you intend.
|
|
484
484
|
</drafted>
|
|
485
485
|
DRAFTED_GLOBAL_INSTRUCTIONS
|
|
486
486
|
}
|
package/mcp/server.mjs
CHANGED
|
@@ -384,7 +384,7 @@ const TOOL_ANNOTATIONS = {
|
|
|
384
384
|
auth: { title: 'Sign in', readOnlyHint: false, destructiveHint: false, openWorldHint: true, description: 'Sign in to Drafted. `action=get_link` returns a URL immediately and starts background approval polling; after the user opens the link, later Drafted tool calls also auto-consume the approved login. `action=login` opens a browser when needed and explicitly waits/polls for approval.' },
|
|
385
385
|
|
|
386
386
|
// Identity — read-only introspection of THIS agent's session
|
|
387
|
-
whoami: { title: 'Session identity', readOnlyHint: true, destructiveHint: false, openWorldHint: false, description: 'Return THIS agent session\'s identity: its server-assigned human-readable name (the correlation key between an agent window and its web-app session tab), sessionId, userId, orgId, active projectId, editor label, server URL, and surfaced/alive state — PLUS server health
|
|
387
|
+
whoami: { title: 'Session identity', readOnlyHint: true, destructiveHint: false, openWorldHint: false, description: 'Return THIS agent session\'s identity: its server-assigned human-readable name (the correlation key between an agent window and its web-app session tab), sessionId, userId, orgId, active projectId, editor label, server URL, and surfaced/alive state — PLUS server health, the installed MCP version/update status (cached ~5min), and `googleDrive` — whether the working org has Google Drive connected: when `googleDrive.connected` is true, strongly prefer Google Workspace frames (.google-doc/.google-sheet/.google-slide) for docs, sheets, and decks; when false they cannot be created at all. Call once per session, right after starting, so a required update surfaces before you act on stale tool behavior. Read-only. Use this — not guesses from the host environment — to report which session you are.' },
|
|
388
388
|
|
|
389
389
|
// Session naming — the name-before-work gate: every agent session must set a short
|
|
390
390
|
// name describing the work before any other tool call succeeds.
|
|
@@ -2261,17 +2261,37 @@ async function sessionSurfaceBlock() {
|
|
|
2261
2261
|
};
|
|
2262
2262
|
}
|
|
2263
2263
|
|
|
2264
|
+
// Is the working org's Drive connected? Agents are told to prefer Google Workspace frames
|
|
2265
|
+
// when it is, so they need a way to ASK — this rode on `get_org` until that tool was retired
|
|
2266
|
+
// (DRAFT-36), leaving agents to probe by attempting a .google-doc write and reading the 400.
|
|
2267
|
+
// Rides on whoami, the once-per-session bootstrap that replaced it. Never throws: an
|
|
2268
|
+
// unreachable/erroring status is reported as not-connected, same as no connection.
|
|
2269
|
+
async function getGoogleDriveAvailability() {
|
|
2270
|
+
try {
|
|
2271
|
+
const status = await api('GET', '/api/google/status');
|
|
2272
|
+
return {
|
|
2273
|
+
connected: !!status?.connected,
|
|
2274
|
+
driveRootFolderName: status?.driveRootFolderName || null,
|
|
2275
|
+
preference: status?.connected
|
|
2276
|
+
? 'Google Drive is connected for this org — strongly prefer Google Workspace frames (.google-doc / .google-sheet / .google-slide) for docs, sheets, and decks.'
|
|
2277
|
+
: 'Google Drive is not connected for this org — use normal Drafted frames (.md / .html); Google Workspace writes will fail.',
|
|
2278
|
+
};
|
|
2279
|
+
} catch {
|
|
2280
|
+
return { connected: false, driveRootFolderName: null, preference: 'Google Drive status unavailable — use normal Drafted frames.' };
|
|
2281
|
+
}
|
|
2282
|
+
}
|
|
2283
|
+
|
|
2264
2284
|
// Identity + server health: report THIS agent session's own surface identity, server
|
|
2265
2285
|
// reachability, and installed-MCP staleness in ONE bootstrap call. The update data is
|
|
2266
2286
|
// cached (5min), so repeat `whoami` calls are free; the server-side update gate still
|
|
2267
2287
|
// blocks mutating calls on its own, independent of this tool. Read-only — no state changed.
|
|
2268
|
-
tool('whoami', 'Return THIS agent session\'s identity: its server-assigned human-readable name (the correlation key between an agent window and its web-app session tab), sessionId, userId, orgId, active projectId, editor label, server URL, and surfaced/alive state — PLUS server health
|
|
2288
|
+
tool('whoami', 'Return THIS agent session\'s identity: its server-assigned human-readable name (the correlation key between an agent window and its web-app session tab), sessionId, userId, orgId, active projectId, editor label, server URL, and surfaced/alive state — PLUS server health, the installed MCP version/update status (cached ~5min), and `googleDrive` — whether the working org has Google Drive connected: when `googleDrive.connected` is true, strongly prefer Google Workspace frames (.google-doc/.google-sheet/.google-slide) for docs, sheets, and decks; when false they cannot be created at all. Call once per session, right after starting, so a required update surfaces before you act on stale tool behavior. Read-only.', {}, async () => {
|
|
2269
2289
|
try {
|
|
2270
2290
|
// Ensure the child clone exists BEFORE reading identity — otherwise the /auth/me
|
|
2271
2291
|
// fallback (pre-WS-ack) queries the ROOT session and reports the wrong naming state.
|
|
2272
2292
|
await ensureSession();
|
|
2273
2293
|
const block = await sessionSurfaceBlock();
|
|
2274
|
-
const mcpUpdate = await getCachedMcpUpdateMetadata();
|
|
2294
|
+
const [mcpUpdate, googleDrive] = await Promise.all([getCachedMcpUpdateMetadata(), getGoogleDriveAvailability()]);
|
|
2275
2295
|
// Tell the agent to actually surface its name to the user — returning `name` in the JSON isn't
|
|
2276
2296
|
// enough; without an explicit instruction agents rarely say which session they are, so users
|
|
2277
2297
|
// can't match them to their tab on the Drafted surface.
|
|
@@ -2287,6 +2307,7 @@ tool('whoami', 'Return THIS agent session\'s identity: its server-assigned human
|
|
|
2287
2307
|
mcpUpdate,
|
|
2288
2308
|
editor: (process.env.DRAFTED_AGENT_NAME || '').trim() || null,
|
|
2289
2309
|
agentLabel: getAgentLabel(),
|
|
2310
|
+
googleDrive,
|
|
2290
2311
|
...block,
|
|
2291
2312
|
...(instruction ? { instruction } : {}),
|
|
2292
2313
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "drafted",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.6",
|
|
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": [
|
|
@@ -65,7 +65,7 @@ These bookend the loop. Prime/feed at the start, deposit at the end.
|
|
|
65
65
|
- **Create a project with `fs(mkdir, path="/o/<org>/projects/<name>")`** — or just `fs(write, path="/o/<org>/projects/<name>/<layer>/<lane>/<file>", content=...)` and the project + layer auto-create in the addressed org.
|
|
66
66
|
- **Default to the surface for substantive artifacts.** When asked to draft, write, plan, analyze, compare, design, document, summarize, report, spec, model, or make a deck/table, create or update frames instead of leaving the durable result only in chat. One visible frame per artifact or section.
|
|
67
67
|
- **Read before editing.** `fs(read)` returns every line hashline-annotated (`1abc|<content>`); `fs(edit, ops=[{type:"replace", lineHash:"1abc", newContent:"..."}])` targets exactly that line. For partial reads, pass `lines: "2-50"` — you get back just that range, still hash-annotated, and can edit within it.
|
|
68
|
-
- **Prefer Google Workspace when Drive is connected.**
|
|
68
|
+
- **Prefer Google Workspace when Drive is connected.** `whoami` reports it — `googleDrive.connected: true` means use `fs(write, path=".../<name>.google-doc"|".google-sheet"|".google-slide")` for docs, sheets, and decks, populated immediately with the matching native write action. False means they cannot be created at all: use `.md`/`.html` frames and don't ask the user which fallback they want.
|
|
69
69
|
- **`fs(mv, from="/o/<org>/projects/<p>/<layer>/<lane>/<file>", to="...")`** renames or moves (cross-project too). **`fs(rm, path="/o/<org>/projects/<project>")` archives** — agents never hard-delete; the archive is in the web UI.
|
|
70
70
|
- **Return a clickable link** for what you touched — the `frameUrl`/`projectUrl` in the fs response is the URL the user opens.
|
|
71
71
|
|