@theronap/cortex-mcp 0.9.24 → 0.9.26
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 +13 -6
- package/package.json +1 -1
package/lib/server.mjs
CHANGED
|
@@ -263,6 +263,11 @@ export async function runServer(version) {
|
|
|
263
263
|
return { content: [{ type: 'text', text: `Could not read "${name}": ${e.message}` }] }
|
|
264
264
|
}
|
|
265
265
|
if (res.status === 404) {
|
|
266
|
+
// Identifier links ([[repo:owner/name]]) are JOIN KEYS, not pages — a 404 here is expected.
|
|
267
|
+
// The home/expand resolver arrives in a later slice; until then grep is the join.
|
|
268
|
+
if (/^[a-z][a-z0-9_-]*:.+/i.test(name)) {
|
|
269
|
+
return { content: [{ type: 'text', text: `"${name}" is an identifier link (a join key), not a page — there is nothing to read at it yet. \`grep "${name}"\` to find every page carrying this stamp; the timeline resolver for identifiers lands in a later slice.` }] }
|
|
270
|
+
}
|
|
266
271
|
return { content: [{ type: 'text', text: `No ${k} page named "${name}". If it's a person or team, pass kind (person/org). Otherwise \`grep "${name}"\` to locate it — it may be a red-link (a wanted page that isn't authored yet).` }] }
|
|
267
272
|
}
|
|
268
273
|
if (!res.ok) {
|
|
@@ -276,10 +281,10 @@ export async function runServer(version) {
|
|
|
276
281
|
const day = (d) => (d ? String(d).slice(0, 10) : '')
|
|
277
282
|
const blocks = page.tiers.map((t) => {
|
|
278
283
|
const secs = (t.sections ?? []).map((s) => `### ${s.heading}\n${s.body}`).join('\n\n')
|
|
279
|
-
const head = `[${t.tier}${day(t.updated_at) ? ` · authored ${day(t.updated_at)}` : ''}${t.validity && t.validity !== 'current' ? ` · ${t.validity}` : ''}]`
|
|
284
|
+
const head = `[${t.tier}${day(t.updated_at) ? ` · authored ${day(t.updated_at)}` : ''}${t.validity && t.validity !== 'current' ? ` · ${t.validity}` : ''}${t.version ? `\nversion: ${t.version}` : ''}]`
|
|
280
285
|
return [head, t.summary, secs].filter(Boolean).join('\n')
|
|
281
286
|
})
|
|
282
|
-
const footer = `— Follow any [[links]] above with read_page to go deeper.\n— If you hold fresher FIRST-HAND truth than this page — something you established THIS session (ran the command, made the change, hold the artifact) that a section here gets concretely wrong — re-author just those sections now with \`author\` (
|
|
287
|
+
const footer = `— Follow any [[links]] above with read_page to go deeper.\n— If you hold fresher FIRST-HAND truth than this page — something you established THIS session (ran the command, made the change, hold the artifact) that a section here gets concretely wrong — re-author just those sections now with \`author\` (any node you are permitted to edit; concise; a material contradiction, not merely extra detail). Pass this page's \`version\` as base_version when you re-author — if the save comes back stale, the page changed under you: re-read, then re-author. Reading a stale page you can fix IS the trigger to fix it.`
|
|
283
288
|
return { content: [{ type: 'text', text: `# ${page.title ?? name} (full authored page)\n\n${blocks.join('\n\n---\n\n')}\n\n${footer}` }] }
|
|
284
289
|
},
|
|
285
290
|
)
|
|
@@ -583,7 +588,7 @@ export async function runServer(version) {
|
|
|
583
588
|
{
|
|
584
589
|
title: 'Authoring context (call before author)',
|
|
585
590
|
description:
|
|
586
|
-
'Fetch the scaffolding to author a Cortex wiki node: the canonical NAMESPACE (existing node names — link to these with the EXACT name inside [[ ]]) and the node-type CONNECTION RULES (what kinds of links to look for). ALWAYS call this BEFORE `author` so the page links to real nodes by their established names instead of minting synonyms. Reference a node in the namespace as [[Name]]; if you reference something real that is NOT in the namespace, still write [[Name]] — that is a red-link marking a node worth creating.',
|
|
591
|
+
'Fetch the scaffolding to author a Cortex wiki node: the canonical NAMESPACE (existing node names — link to these with the EXACT name inside [[ ]]) and the node-type CONNECTION RULES (what kinds of links to look for). ALWAYS call this BEFORE `author` so the page links to real nodes by their established names instead of minting synonyms. Reference a node in the namespace as [[Name]]; if you reference something real that is NOT in the namespace, still write [[Name]] — that is a red-link marking a node worth creating. If the page IS about a specific code repo, also stamp [[repo:owner/name]] (lowercase) once — an identifier join key, not a page link.',
|
|
587
592
|
inputSchema: {
|
|
588
593
|
kind: z.enum(['project', 'person', 'org', 'user']).optional().describe('the node type you are about to author (default project)'),
|
|
589
594
|
},
|
|
@@ -627,10 +632,11 @@ export async function runServer(version) {
|
|
|
627
632
|
body: z.string().describe('dense markdown WITH inline [[links]] where the prose references another node'),
|
|
628
633
|
})).describe('3-5 sections; the page body'),
|
|
629
634
|
tier: z.enum(['accessible', 'scoped', 'confidential']).optional().describe('visibility tier (default accessible — the shareable page)'),
|
|
635
|
+
base_version: z.string().optional().describe('the `version` hash shown when you read this page (read_page) — REQUIRED when updating an existing page, so a concurrent edit is caught instead of clobbered. Omit only for a brand-new node. If the save returns "stale" or "read first", read_page again and retry with the fresh version.'),
|
|
630
636
|
},
|
|
631
637
|
},
|
|
632
|
-
async ({ kind, name, summary, sections, tier }) => {
|
|
633
|
-
const pages = [{ tier: tier ?? 'accessible', summary, sections: Array.isArray(sections) ? sections : [] }]
|
|
638
|
+
async ({ kind, name, summary, sections, tier, base_version }) => {
|
|
639
|
+
const pages = [{ tier: tier ?? 'accessible', summary, base_version, sections: Array.isArray(sections) ? sections : [] }]
|
|
634
640
|
let res
|
|
635
641
|
try {
|
|
636
642
|
res = await fetchCortex(`${BASE}/api/brain/author`, {
|
|
@@ -649,8 +655,9 @@ export async function runServer(version) {
|
|
|
649
655
|
const blue = out?.links?.blue ?? 0
|
|
650
656
|
const red = out?.links?.red ?? 0
|
|
651
657
|
const redList = Array.isArray(out?.redLinks) && out.redLinks.length ? `\nRed-links (wanted nodes): ${out.redLinks.map((r) => `[[${r}]]`).join(', ')}` : ''
|
|
658
|
+
const stamps = Array.isArray(out?.identifiers) && out.identifiers.length ? `\nIdentifier stamps (join keys): ${out.identifiers.map((i) => `[[${i}]]`).join(', ')}` : ''
|
|
652
659
|
const verb = out?.created ? 'Created + authored' : 'Authored'
|
|
653
|
-
const note = out?.built ? `${verb} "${name}" (${out.built} tier${out.built === 1 ? '' : 's'}). Links: ${blue} resolved, ${red} red.${redList}`
|
|
660
|
+
const note = out?.built ? `${verb} "${name}" (${out.built} tier${out.built === 1 ? '' : 's'}). Links: ${blue} resolved, ${red} red.${redList}${stamps}`
|
|
654
661
|
: `No change to "${name}"${out?.skipped?.length ? ` (${out.skipped.join(', ')})` : ''}.`
|
|
655
662
|
return { content: [{ type: 'text', text: note }] }
|
|
656
663
|
},
|