easymd-cli 0.1.3 → 0.1.5
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/package.json +1 -1
- package/src/cli/mcp.mjs +50 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "easymd-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Google Docs for markdown — collaborate on the actual .md file in your repo, live with humans and AI agents. CLI: login, auto-sync, and open .md files for real-time editing.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/cli/mcp.mjs
CHANGED
|
@@ -120,6 +120,56 @@ server.registerTool(
|
|
|
120
120
|
},
|
|
121
121
|
);
|
|
122
122
|
|
|
123
|
+
server.registerTool(
|
|
124
|
+
'update_task_state',
|
|
125
|
+
{
|
|
126
|
+
title: 'Update task state',
|
|
127
|
+
description:
|
|
128
|
+
'Update the document\'s "Task State" block — the shared execution-handoff surface between humans and agents. Only the fields you pass change; the rest are preserved. Use this to keep the doc reflecting the current goal, decisions, open questions, failed approaches, the last command you validated (with its result), and the next concrete action. Updates appear live in the open editor.',
|
|
129
|
+
inputSchema: {
|
|
130
|
+
name: z.string().describe('Document name'),
|
|
131
|
+
goal: z.string().optional().describe('Current goal / what we are trying to achieve'),
|
|
132
|
+
decisions: z.string().optional().describe('Decisions made so far'),
|
|
133
|
+
openQuestions: z.string().optional().describe('Unresolved questions'),
|
|
134
|
+
failedApproaches: z.string().optional().describe('Approaches tried that did not work'),
|
|
135
|
+
lastValidated: z.string().optional().describe('Last command you ran to validate, and its result (e.g. "`npm test` → 18 passing, 2 failing")'),
|
|
136
|
+
nextAction: z.string().optional().describe('The next concrete action'),
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
async ({ name, ...fields }) => {
|
|
140
|
+
try {
|
|
141
|
+
const state = Object.fromEntries(Object.entries(fields).filter(([, v]) => v !== undefined && v !== ''));
|
|
142
|
+
if (!Object.keys(state).length) return fail('Provide at least one field to update.');
|
|
143
|
+
await api('/api/cli/documents', { method: 'POST', body: JSON.stringify({ name, op: 'task', state }) });
|
|
144
|
+
return ok(`Updated Task State for "${name}" (${Object.keys(state).join(', ')}).`);
|
|
145
|
+
} catch (e) {
|
|
146
|
+
return fail(e.message);
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
server.registerTool(
|
|
152
|
+
'propose_change',
|
|
153
|
+
{
|
|
154
|
+
title: 'Propose a change (intent before edit)',
|
|
155
|
+
description:
|
|
156
|
+
'Propose an edit to a document WITHOUT overwriting it. State your intent (e.g. "resolve contradiction in §Auth", "add acceptance criteria", "update status") and the proposed markdown. It appears in the doc as a reviewable proposal the human can Accept or Reject — collaboration becomes intentful, not a silent overwrite. Use this for substantive changes; use update_document only for direct edits the human expects.',
|
|
157
|
+
inputSchema: {
|
|
158
|
+
name: z.string().describe('Document name'),
|
|
159
|
+
intent: z.string().describe('What this change does and why (shown to the human)'),
|
|
160
|
+
content: z.string().describe('The proposed markdown'),
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
async ({ name, intent, content }) => {
|
|
164
|
+
try {
|
|
165
|
+
await api('/api/cli/documents', { method: 'POST', body: JSON.stringify({ name, op: 'propose', intent, content }) });
|
|
166
|
+
return ok(`Proposed “${intent}” on "${name}". The owner can Accept or Reject it in the editor.`);
|
|
167
|
+
} catch (e) {
|
|
168
|
+
return fail(e.message);
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
);
|
|
172
|
+
|
|
123
173
|
const transport = new StdioServerTransport();
|
|
124
174
|
await server.connect(transport);
|
|
125
175
|
console.error(`easymd MCP ready → ${BASE} ${TOKEN ? '(authenticated)' : '(NOT logged in — run `easymd login`)'}`);
|