@theronap/agnoclast-mcp 0.9.241 → 0.9.242
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/lib/server.mjs +47 -2
- package/package.json +1 -1
package/lib/server.mjs
CHANGED
|
@@ -2366,7 +2366,8 @@ function renderNudge(payload) {
|
|
|
2366
2366
|
const lines = revs.map((r) => {
|
|
2367
2367
|
// "Theron via Frack" — the label only ever reaches the token's owner (bdb2339b phase 2).
|
|
2368
2368
|
const via = r.via_token_label ? ` via ${r.via_token_label}` : ''
|
|
2369
|
-
const
|
|
2369
|
+
const agentOf = r.actor_agent_of ? ` (agent of ${r.actor_agent_of})` : ''
|
|
2370
|
+
const who = r.actor_name ? ` · ${r.actor_name}${agentOf}${via}` : (via ? ` ·${via}` : '')
|
|
2370
2371
|
// change_kind first and bracketed so a column of [correct] is scannable — the whole point is
|
|
2371
2372
|
// that a page with repeated corrections looks different at a glance from one that only grew.
|
|
2372
2373
|
const what = r.change_kind ? ` · [${r.change_kind}]` : ''
|
|
@@ -2421,7 +2422,7 @@ function renderNudge(payload) {
|
|
|
2421
2422
|
? `# ${name} — rev ${d.to.revNo} (first version)`
|
|
2422
2423
|
: `# ${name} — rev ${d.from.revNo} → rev ${d.to.revNo}`
|
|
2423
2424
|
const meta = []
|
|
2424
|
-
meta.push(`${String(d.to.createdAt).slice(0, 10)} · ${d.to.op}${d.to.changeKind ? ` · [${d.to.changeKind}]` : ''}${d.to.actorName ? ` · ${d.to.actorName}${d.to.viaTokenLabel ? ` via ${d.to.viaTokenLabel}` : ''}` : ''}`)
|
|
2425
|
+
meta.push(`${String(d.to.createdAt).slice(0, 10)} · ${d.to.op}${d.to.changeKind ? ` · [${d.to.changeKind}]` : ''}${d.to.actorName ? ` · ${d.to.actorName}${d.to.actorAgentOf ? ` (agent of ${d.to.actorAgentOf})` : ''}${d.to.viaTokenLabel ? ` via ${d.to.viaTokenLabel}` : ''}` : ''}`)
|
|
2425
2426
|
if (d.to.reason) meta.push(`reason: ${d.to.reason}`)
|
|
2426
2427
|
if (d.to.sessionKey) meta.push(`session: ${String(d.to.sessionKey).slice(0, 24)}`)
|
|
2427
2428
|
const body = []
|
|
@@ -4918,6 +4919,50 @@ function renderNudge(payload) {
|
|
|
4918
4919
|
},
|
|
4919
4920
|
)
|
|
4920
4921
|
|
|
4922
|
+
// share_calendar — share YOUR OWN calendar with one person (ADR-0086; Theron, 2026-10-17). Same shape as
|
|
4923
|
+
// share_record: NOT auto-allowed (a disclosure to someone, so it prompts), and only when the person asks.
|
|
4924
|
+
// Nothing is emailed by this tool; it returns the link for the person to send.
|
|
4925
|
+
server.registerTool(
|
|
4926
|
+
'share_calendar',
|
|
4927
|
+
{
|
|
4928
|
+
title: 'Share your calendar with someone',
|
|
4929
|
+
description:
|
|
4930
|
+
'Share the person\'s OWN calendar with one other person by email address. They get their own read-only link ' +
|
|
4931
|
+
'(agnoclast.com/c/…); if they use Agnoclast it also appears on their calendar until revoked. scope "busy" ' +
|
|
4932
|
+
'(default) shows only busy blocks; "titles" also shows event titles (never notes, places or attendees). This does ' +
|
|
4933
|
+
'NOT send anything: give the person the link to send, or they can send it from the Share calendar panel. Only ' +
|
|
4934
|
+
'when the person asks to share their calendar; never on your own initiative. Turn it off on agnoclast.com/calendar.',
|
|
4935
|
+
inputSchema: {
|
|
4936
|
+
email: z.string().describe('the email address of the person to share with'),
|
|
4937
|
+
scope: z.enum(['busy', 'titles']).optional().describe('busy = busy blocks only (default); titles = event titles too'),
|
|
4938
|
+
},
|
|
4939
|
+
},
|
|
4940
|
+
async ({ email, scope }) => {
|
|
4941
|
+
let res
|
|
4942
|
+
try {
|
|
4943
|
+
res = await fetchCortex(`${BASE}/api/calendar/shares`, {
|
|
4944
|
+
method: 'POST',
|
|
4945
|
+
headers: { Authorization: `Bearer ${TOKEN}`, 'Content-Type': 'application/json' },
|
|
4946
|
+
body: JSON.stringify({ action: 'share_with', email, scope: scope ?? 'busy' }),
|
|
4947
|
+
})
|
|
4948
|
+
} catch (e) {
|
|
4949
|
+
return toolError(`Could not share the calendar: ${e.message}`)
|
|
4950
|
+
}
|
|
4951
|
+
if (res.status === 400 || res.status === 409) {
|
|
4952
|
+
const b = await res.json().catch(() => null)
|
|
4953
|
+
return toolError(`Not shared: ${b?.error ?? 'refused'}`)
|
|
4954
|
+
}
|
|
4955
|
+
if (!res.ok) {
|
|
4956
|
+
const d = classify(res.status, res.headers.get('content-type'), await res.text(), res.headers.get('x-vercel-id'))
|
|
4957
|
+
return toolError(`Could not share the calendar: ${d.message}`)
|
|
4958
|
+
}
|
|
4959
|
+
const out = await res.json()
|
|
4960
|
+
return { content: [{ type: 'text', text:
|
|
4961
|
+
`Shared your calendar (${out.share.scope === 'titles' ? 'with event titles' : 'busy times only'}) with ${out.share.recipientEmail}:\n${out.url}\n` +
|
|
4962
|
+
`Nothing was sent — give them this link. It is shown only once. If they use Agnoclast it is already on their calendar. share id: ${out.share.id}` }] }
|
|
4963
|
+
},
|
|
4964
|
+
)
|
|
4965
|
+
|
|
4921
4966
|
// set_record_notes — write the NOTES layer of one of your own transcripts (Theron, 2026-10-08: "two
|
|
4922
4967
|
// layers … a summary and notes from the transcript … the full transcript"). The server keeps the
|
|
4923
4968
|
// before-state in record history and refuses anything that is not your own kept transcript.
|
package/package.json
CHANGED