drafted 1.11.20 → 1.11.22

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.
Files changed (2) hide show
  1. package/mcp/server.mjs +20 -6
  2. package/package.json +1 -1
package/mcp/server.mjs CHANGED
@@ -1003,7 +1003,7 @@ async function connectAgentWs() {
1003
1003
  agentWs.on('open', () => {
1004
1004
  console.error('[MCP-WS] Connected');
1005
1005
  if (getState().projectId) {
1006
- agentWs.send(JSON.stringify({ type: 'join', projectId: getState().projectId, agent: true }));
1006
+ agentWs.send(JSON.stringify({ type: 'join', projectId: getState().projectId, agent: true, agentLabel: getAgentLabel() }));
1007
1007
  }
1008
1008
  });
1009
1009
 
@@ -1025,13 +1025,27 @@ async function connectAgentWs() {
1025
1025
  });
1026
1026
  }
1027
1027
 
1028
+ // Build a display-only label for this agent session (editor + active project).
1029
+ // Identity stays the cloned gc_session id (read server-side from the cookie);
1030
+ // this is only used for window titles / presence display.
1031
+ function getAgentLabel() {
1032
+ const editor = process.env.DRAFTED_AGENT_NAME
1033
+ || (process.env.CLAUDECODE ? 'Claude Code' : null)
1034
+ || (process.env.CURSOR_TRACE_ID ? 'Cursor' : null)
1035
+ || process.env.TERM_PROGRAM
1036
+ || 'agent';
1037
+ const meta = getState().projectMeta;
1038
+ const proj = meta?.name || meta?.slug || null;
1039
+ return proj ? `${editor} - ${proj}` : editor;
1040
+ }
1041
+
1028
1042
  async function joinAgentWsRoom(projectId) {
1029
1043
  // Ensure WS is connected (may not be after restart/session re-clone)
1030
1044
  if (!agentWs || agentWs.readyState > WebSocket.OPEN) {
1031
1045
  await connectAgentWs();
1032
1046
  }
1033
1047
  if (!agentWs) return;
1034
- const msg = JSON.stringify({ type: 'join', projectId, agent: true });
1048
+ const msg = JSON.stringify({ type: 'join', projectId, agent: true, agentLabel: getAgentLabel() });
1035
1049
  if (agentWs.readyState === WebSocket.OPEN) {
1036
1050
  agentWs.send(msg);
1037
1051
  } else if (agentWs.readyState === WebSocket.CONNECTING) {
@@ -2043,7 +2057,7 @@ tool('frame', 'Frame CRUD in the ACTIVE PROJECT. Dispatch by `action`: read (by
2043
2057
  color: z.string().optional().describe('[write] CSS color for frame border (e.g. #ff0000, red).'),
2044
2058
  operations: z.array(z.object({
2045
2059
  type: z.enum(['replace', 'delete', 'insertAfter', 'insertBefore']).describe('Edit type'),
2046
- lineHash: z.string().describe('Hash of the target line (from read output). Use the full hash to avoid ambiguity in large frames.'),
2060
+ lineHash: z.string().describe('The full line anchor copied verbatim from read output — line number + 2-char hash, e.g. "182vi" (the token left of the "|"). NOT the bare 2-char hash "vi": that is rejected, since the same hash can recur on multiple lines.'),
2047
2061
  newContent: z.string().optional().describe('New content (for replace, insertAfter, insertBefore)'),
2048
2062
  })).optional().describe('[edit] hashline edit operations'),
2049
2063
  from: z.string().optional().describe('[mv] source path /{layer}/{lane}/{filename}'),
@@ -2559,9 +2573,9 @@ tool('batch', 'Batch operations on the ACTIVE PROJECT. Response includes "projec
2559
2573
  to: z.string().optional().describe('Destination path (for mv)'),
2560
2574
  operations: z.array(z.object({
2561
2575
  type: z.enum(['replace', 'delete', 'insertAfter', 'insertBefore']),
2562
- lineHash: z.string(),
2576
+ lineHash: z.string().describe('The full line anchor from read output — line number + 2-char hash, e.g. "182vi". NOT the bare 2-char hash.'),
2563
2577
  newContent: z.string().optional(),
2564
- })).optional().describe('Edit operations (for edit). Always include lineNum.'),
2578
+ })).optional().describe('Edit operations (for edit). lineHash is the full anchor (lineNum + hash), e.g. "182vi".'),
2565
2579
  asset_path: z.string().optional().describe('Relative asset path (for upload_asset, e.g., "css/styles.css")'),
2566
2580
  content_type: z.string().optional().describe('MIME type (for upload_asset, auto-detected if omitted)'),
2567
2581
  frame_id: z.string().optional().describe('Frame ID to associate asset with (for upload_asset)'),
@@ -3118,7 +3132,7 @@ tool('wiki', 'Per-org wiki. Markdown pages with paths as hierarchy. You and othe
3118
3132
  frontmatter: z.any().optional().describe('[write] frontmatter object'),
3119
3133
  operations: z.array(z.object({
3120
3134
  type: z.enum(['replace', 'delete', 'insertAfter', 'insertBefore']).describe('Edit type'),
3121
- lineHash: z.string().describe('Hash of the target line (from read output)'),
3135
+ lineHash: z.string().describe('The full line anchor copied verbatim from read output — line number + 2-char hash, e.g. "182vi" (the token left of the "|"). NOT the bare 2-char hash.'),
3122
3136
  newContent: z.string().optional().describe('New content (for replace, insertAfter, insertBefore)'),
3123
3137
  })).optional().describe('[edit] hashline edit operations — same shape as frame.edit'),
3124
3138
  from: z.string().optional().describe('[mv] source path'),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "drafted",
3
- "version": "1.11.20",
3
+ "version": "1.11.22",
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": [