drafted 1.14.9 → 1.14.10
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 -6
- package/package.json +1 -1
package/mcp/server.mjs
CHANGED
|
@@ -1078,6 +1078,15 @@ function shapeSkillCatalog(result, { limit, offset = 0, compact = false } = {})
|
|
|
1078
1078
|
return result;
|
|
1079
1079
|
}
|
|
1080
1080
|
|
|
1081
|
+
// Semantic frame URL (/o/<org>/<project>/<layer>/<lane>/<label>) from a row that
|
|
1082
|
+
// carries slugs (e.g. /api/search hits). Returns null when a slug is missing so the
|
|
1083
|
+
// caller can fall back to the /f/<uuid> resolver.
|
|
1084
|
+
function semanticFrameUrl({ orgSlug, projectSlug, layer, lane, label }) {
|
|
1085
|
+
if (!orgSlug || !projectSlug || !label) return null;
|
|
1086
|
+
const e = encodeURIComponent;
|
|
1087
|
+
return `${getServerUrl()}/o/${e(orgSlug)}/${e(projectSlug)}/${e(layer || 'designs')}/${e(lane || 'default')}/${e(label)}`;
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1081
1090
|
// Build the structuredContent shape that the frame-preview widget reads.
|
|
1082
1091
|
// Tools that produce or return a frame (read/write/edit) call this so the
|
|
1083
1092
|
// model and widget see the same metadata view.
|
|
@@ -1093,7 +1102,9 @@ function frameStructuredContent(result, project = null) {
|
|
|
1093
1102
|
lane: result.lane,
|
|
1094
1103
|
width: result.width,
|
|
1095
1104
|
height: result.height,
|
|
1096
|
-
|
|
1105
|
+
// Server emits the semantic /o/<org>/<project>/<layer>/... URL; /f/<uuid> is the
|
|
1106
|
+
// fallback (still resolved + redirected server-side).
|
|
1107
|
+
frameUrl: result.frameUrl || (result.id ? `${getServerUrl()}/f/${result.id}` : undefined),
|
|
1097
1108
|
project, // {id, slug, name, orgId} of the active project — visible in client UI
|
|
1098
1109
|
};
|
|
1099
1110
|
}
|
|
@@ -1880,17 +1891,21 @@ tool('project', 'START HERE for project management. Dispatch by `action`: list (
|
|
|
1880
1891
|
joinAgentWsRoom(projectId);
|
|
1881
1892
|
const base = getServerUrl();
|
|
1882
1893
|
let projectSlug = projectId;
|
|
1883
|
-
let
|
|
1894
|
+
let orgSlug = null;
|
|
1895
|
+
let projectMeta = { id: projectId, slug: null, name: null, orgId: null, orgSlug: null };
|
|
1884
1896
|
try {
|
|
1885
1897
|
const data = await api('GET', '/api/projects');
|
|
1886
1898
|
const proj = (data.projects || []).find(p => p.id === projectId);
|
|
1887
1899
|
if (proj) {
|
|
1888
1900
|
projectSlug = proj.slug || projectId;
|
|
1889
|
-
|
|
1901
|
+
orgSlug = proj.orgSlug || null;
|
|
1902
|
+
projectMeta = { id: proj.id, slug: proj.slug || null, name: proj.name || null, orgId: proj.orgId || null, orgSlug };
|
|
1890
1903
|
}
|
|
1891
1904
|
} catch { /* fall back to projectId */ }
|
|
1892
1905
|
setMcpActiveProject(projectId, projectMeta);
|
|
1893
|
-
|
|
1906
|
+
// Semantic /o/<org-slug>/<project-slug> when the org slug is known; otherwise
|
|
1907
|
+
// the /project/<slug> resolver redirects to it.
|
|
1908
|
+
const url = orgSlug ? `${base}/o/${encodeURIComponent(orgSlug)}/${encodeURIComponent(projectSlug)}` : `${base}/project/${projectSlug}`;
|
|
1894
1909
|
// Surfacing to the user is the focus mechanism's job now (agent-active ping ->
|
|
1895
1910
|
// desktop window / notification+glow for browser tabs) — this used to also force
|
|
1896
1911
|
// `exec('open <url>')` on the MCP host machine, an unsolicited GUI action that both
|
|
@@ -3039,7 +3054,7 @@ tool('frame', 'Frame CRUD in the ACTIVE PROJECT. Dispatch by `action`: read (by
|
|
|
3039
3054
|
path: `/${r.layer}/${r.lane}/${r.label}`,
|
|
3040
3055
|
project: r.projectName,
|
|
3041
3056
|
projectId: r.projectId,
|
|
3042
|
-
frameUrl: `${getServerUrl()}/f/${r.id}`,
|
|
3057
|
+
frameUrl: semanticFrameUrl(r) || `${getServerUrl()}/f/${r.id}`,
|
|
3043
3058
|
contentType: r.contentType,
|
|
3044
3059
|
updatedAt: r.updatedAt,
|
|
3045
3060
|
})),
|
|
@@ -3112,7 +3127,11 @@ tool('ls', 'List contents of the ACTIVE PROJECT. Use ls / after project(action="
|
|
|
3112
3127
|
const projectId = getState().projectId;
|
|
3113
3128
|
const structuredContent = {
|
|
3114
3129
|
project: result?.project || result?.projectName,
|
|
3115
|
-
canvasUrl: result?.
|
|
3130
|
+
canvasUrl: result?.project?.slug
|
|
3131
|
+
? (result.project.orgSlug
|
|
3132
|
+
? `${getServerUrl()}/o/${encodeURIComponent(result.project.orgSlug)}/${encodeURIComponent(result.project.slug)}`
|
|
3133
|
+
: `${getServerUrl()}/project/${encodeURIComponent(result.project.slug)}`)
|
|
3134
|
+
: undefined,
|
|
3116
3135
|
byLayer,
|
|
3117
3136
|
truncated: result?.truncated || false,
|
|
3118
3137
|
totalAvailable: result?.totalAvailable,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "drafted",
|
|
3
|
-
"version": "1.14.
|
|
3
|
+
"version": "1.14.10",
|
|
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": [
|