@theronap/agnoclast-mcp 0.9.255 → 0.9.257
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/folder_decisions.mjs +12 -7
- package/lib/server.mjs +16 -7
- package/package.json +1 -1
package/lib/folder_decisions.mjs
CHANGED
|
@@ -29,13 +29,16 @@ export function renderFolderQuestions(body) {
|
|
|
29
29
|
if (open.length) {
|
|
30
30
|
lines.push('', `Open (${open.length}):`)
|
|
31
31
|
for (const x of open) {
|
|
32
|
-
const what =
|
|
32
|
+
const what = `folder (${x.files?.length ?? 0} changed file${x.files?.length === 1 ? '' : 's'})`
|
|
33
33
|
lines.push(`- \`${x.identifier}\` — ${what}`)
|
|
34
34
|
if (Array.isArray(x.answerWith) && x.answerWith.length > 1) {
|
|
35
35
|
lines.push(` may also be answered at: ${x.answerWith.slice(1).map((a) => `\`${a}\``).join(', ')}`)
|
|
36
36
|
}
|
|
37
37
|
if (x.earlier) {
|
|
38
|
-
|
|
38
|
+
const why = x.earlier.kind === 'not_yet'
|
|
39
|
+
? '"not yet" is no longer an answer for a GitHub folder — choose its page, or never.'
|
|
40
|
+
: 'That decision has lapsed.'
|
|
41
|
+
lines.push(` asked before: declined ${x.earlier.kind} on \`${x.earlier.identifier}\`${x.earlier.decidedBy ? ` by ${x.earlier.decidedBy}` : ''} ${String(x.earlier.decidedAt).slice(0, 10)} — "${x.earlier.reason ?? ''}". ${why}`)
|
|
39
42
|
}
|
|
40
43
|
}
|
|
41
44
|
}
|
|
@@ -44,11 +47,10 @@ export function renderFolderQuestions(body) {
|
|
|
44
47
|
for (const p of pages) lines.push(`- ${q(p.title)} (${p.tier}) — ref ${p.ref}${p.tier !== 'accessible' ? ' — needs confirmTier: true' : ''}`)
|
|
45
48
|
}
|
|
46
49
|
if (open.length) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
: { identifier: x.identifier, decline: 'not_yet', reason: 'why it belongs to no page' }))
|
|
50
|
+
// Never a `never` in the example: it is permanent, so it must be typed on purpose, not copied.
|
|
51
|
+
const example = open.slice(0, 3).map((x) => ({ identifier: x.identifier, claim: pages[0]?.ref ?? '<ref of the page about this folder>' }))
|
|
50
52
|
lines.push('', `Answer shape: folderDecisions: ${JSON.stringify(example)}`)
|
|
51
|
-
lines.push('No page fits? Author a small area page about the folder (`author`), then claim onto its ref.
|
|
53
|
+
lines.push('No page fits? Author a small area page about the folder (`author`), then claim onto its ref. Belongs to no page (generated/vendored/lockfiles/fixtures)? {identifier, decline: "never", reason} — permanent until someone claims it. There is no "not yet".')
|
|
52
54
|
if (body?.cold) lines.push('You are a cold judge here: {identifier, defer: true} hands a question to the next session that touches it.')
|
|
53
55
|
}
|
|
54
56
|
return lines.join('\n')
|
|
@@ -73,7 +75,10 @@ export function renderDeclines(declines, { heading = 'Declines' } = {}) {
|
|
|
73
75
|
if (!list.length) return []
|
|
74
76
|
const lines = [`${heading} (${list.length}) — a decline covers the identifier and everything under it:`]
|
|
75
77
|
for (const d of list) {
|
|
76
|
-
const
|
|
78
|
+
const retiredPath = d.kind === 'not_yet' && String(d.identifier).startsWith('file:')
|
|
79
|
+
const state = retiredPath
|
|
80
|
+
? 'not yet — retired for GitHub paths, asked again at the next commit there'
|
|
81
|
+
: d.active ? (d.kind === 'never' ? 'never' : d.kind === 'not_yet' ? 'not yet' : 'snoozed') : `${d.kind}, lapsed — will be asked again`
|
|
77
82
|
lines.push(` ${d.active ? '⊘' : '·'} \`${d.identifier}\`${d.brain ? ` · ${d.brain}` : ''} — ${state}${d.reason ? ` — "${d.reason}"` : ''}${d.decidedBy ? ` · ${d.decidedBy}` : ''}${d.cold ? ' (cold judge)' : ''} · ${String(d.decidedAt).slice(0, 10)}`)
|
|
78
83
|
}
|
|
79
84
|
return lines
|
package/lib/server.mjs
CHANGED
|
@@ -1205,9 +1205,14 @@ function renderNudge(payload) {
|
|
|
1205
1205
|
title: 'Claim private intake items',
|
|
1206
1206
|
description:
|
|
1207
1207
|
'Claim a lease on private intake items (relevance or cleanup). Returns decrypted payloads for the lease holder only. Requires x-cortex-session-key (set automatically by this MCP server). Aged work never blocks a claim: the response reports cleanupDueCount and how far behind the oldest unit is, and servicing it is expected but always your call. Claiming is a commitment to process — hand back anything you will not finish with intake_release, or intake_defer if it is the owner\'s decision to make. ' +
|
|
1208
|
-
'YOU ARE THE JUDGE of every unit you claim (ADR-0062): nothing is published until you materialize, and materializing is when it becomes visible. Each unit carries a `proposal` — the brain its signals point to and, for that brain, the pages it would attach to, the page that would govern it, and the `tier` it would be born with — computed without writing anything. Decide the brain, the pages (confirm, drop or add), which page should govern (the page whose reasons for restricting its audience fit the content, not a person page), and obligations. Pages only tighten a tier; if a record should be LOOSER than `tierReason.baseline`, that is the owner\'s call — intake_defer with the question.'
|
|
1208
|
+
'YOU ARE THE JUDGE of every unit you claim (ADR-0062): nothing is published until you materialize, and materializing is when it becomes visible. Each unit carries a `proposal` — the brain its signals point to and, for that brain, the pages it would attach to, the page that would govern it, and the `tier` it would be born with — computed without writing anything. Decide the brain, the pages (confirm, drop or add), which page should govern (the page whose reasons for restricting its audience fit the content, not a person page), and obligations. Pages only tighten a tier; if a record should be LOOSER than `tierReason.baseline`, that is the owner\'s call — intake_defer with the question. ' +
|
|
1209
|
+
'view "compact" (trial, only where the server enables it — otherwise you get the full response): the judge rules, your brains, the lease and the cleanup count come ONCE per response in `rules`/`brains`, not on every unit; each unit carries its full content, only the proposed brain\'s pages as one line each, and up front what intake_materialize would refuse it for (`materialize.otherHomes`, `materialize.folderQuestions`). Read `rules` before judging.',
|
|
1209
1210
|
inputSchema: {
|
|
1210
1211
|
claimKind: z.enum(['relevance', 'cleanup']).optional().describe('default relevance'),
|
|
1212
|
+
view: z.enum(['full', 'compact']).optional().describe(
|
|
1213
|
+
'default "full". "compact" sends the rules once per response instead of on every unit, and only the proposed ' +
|
|
1214
|
+
'brain\'s placement. Honoured only where the server enables it; otherwise the response is the full one.',
|
|
1215
|
+
),
|
|
1211
1216
|
limit: z.number().optional().describe('max items (default 10). Ignored when intakeItemIds is given.'),
|
|
1212
1217
|
source: z.string().optional().describe('claim only the oldest units of ONE source — e.g. "imessage", "meeting", "email", "github", "claude-code". Reaches texts without first claiming every older GitHub/session unit ahead of them. Ignored when intakeItemIds is given.'),
|
|
1213
1218
|
leaseMinutes: z.number().optional().describe('lease length in minutes, 5-60 (default 30). Prefer intake_look for read-only inspection — a short lease is only for briefly exclusive work.'),
|
|
@@ -1234,7 +1239,7 @@ function renderNudge(payload) {
|
|
|
1234
1239
|
),
|
|
1235
1240
|
},
|
|
1236
1241
|
},
|
|
1237
|
-
async ({ claimKind, limit, source, intakeItemId, intakeItemIds, leaseMinutes, intake_item_id }) => {
|
|
1242
|
+
async ({ claimKind, limit, source, intakeItemId, intakeItemIds, leaseMinutes, intake_item_id, view }) => {
|
|
1238
1243
|
// Merge the spellings before anything else looks at them. Passing both is not an error —
|
|
1239
1244
|
// the union is what the caller plainly meant. (intake_item_id: 2026-10-22, see intake_id_alias.mjs —
|
|
1240
1245
|
// dropped by the schema it would have meant a FIFO claim of the head of the queue.)
|
|
@@ -1254,6 +1259,8 @@ function renderNudge(payload) {
|
|
|
1254
1259
|
// claim into a no-op.
|
|
1255
1260
|
...(intakeItemIds ? { intakeItemIds } : {}),
|
|
1256
1261
|
...(source ? { source } : {}),
|
|
1262
|
+
// Sent only when asked for: a default claim's request body is exactly what it was.
|
|
1263
|
+
...(view === 'compact' ? { view } : {}),
|
|
1257
1264
|
}),
|
|
1258
1265
|
})
|
|
1259
1266
|
if (!res.ok) {
|
|
@@ -1286,7 +1293,9 @@ function renderNudge(payload) {
|
|
|
1286
1293
|
+ `Nothing is blocked — run intake_claim with claimKind:"cleanup" when you reach a natural break.`
|
|
1287
1294
|
}
|
|
1288
1295
|
|
|
1289
|
-
|
|
1296
|
+
// The compact view is printed without indentation — it is what the view is for. The full one, as before.
|
|
1297
|
+
const text = j?.view === 'compact' ? JSON.stringify(j) : JSON.stringify(j, null, 2)
|
|
1298
|
+
return { content: [{ type: 'text', text: text + nudge }] }
|
|
1290
1299
|
},
|
|
1291
1300
|
)
|
|
1292
1301
|
|
|
@@ -1300,7 +1309,7 @@ function renderNudge(payload) {
|
|
|
1300
1309
|
'Pass mode "preview" first when your choice differs from the claim\'s proposal: it returns the pages, the governing page and the tier this exact call would produce, and writes nothing. Never writes private intake into search/history before this call. ' +
|
|
1301
1310
|
'⚠ ADR-0051 — BEFORE you file, look for this unit\'s OTHER homes: the pages it is about beyond what an identifier matched (the design it implements, the project, the person, the decision it bears on). grep or read for them, then name them in documentIds. A call that names nothing beyond the deterministic homes still FILES, on those homes only, and says so — add pages later with route_record. ' +
|
|
1302
1311
|
'⚠ A meeting or lecture TRANSCRIPT files with NOTES in `summary` (Theron, 2026-10-08): the gist, decisions, action items and dates, names spelled right. Without them the call is REFUSED; the transcript itself is kept on the record unchanged. ' +
|
|
1303
|
-
'⚠ ADR-0077: a GitHub commit or PR does not finish until every changed
|
|
1312
|
+
'⚠ ADR-0077: a GitHub commit or PR does not finish until every changed AREA FOLDER has an answer. If a changed file\'s deepest folder has no claim and no decline, the call is REFUSED with the open questions; answer each in folderDecisions (a page to claim it onto, or decline "never") and call again. Questions are about folders, never single files: a file directly in a grab-bag folder (e.g. db/supabase/) is never asked about — it files onto its nearest claimed ancestor\'s page, or the repo\'s page.',
|
|
1304
1313
|
inputSchema: {
|
|
1305
1314
|
intakeItemId: z.string().optional().describe('intake item uuid (required — intake_item_id is accepted too)'),
|
|
1306
1315
|
intake_item_id: z.string().optional().describe(INTAKE_ID_ALIAS_NOTE),
|
|
@@ -1338,12 +1347,12 @@ function renderNudge(payload) {
|
|
|
1338
1347
|
folderDecisions: z.array(z.object({
|
|
1339
1348
|
identifier: z.string().describe('the open question\'s identifier, or a folder above it that its answerWith lists'),
|
|
1340
1349
|
claim: z.string().optional().describe('page `ref:` (or document id) of a project page ABOUT this path — never the repo\'s mother page, a person or a user page'),
|
|
1341
|
-
decline: z.enum(['never'
|
|
1350
|
+
decline: z.enum(['never']).optional().describe('never = belongs to no page (generated/build output, lockfiles, fixtures, vendored code). Permanent until someone claims the folder onto a page. There is no "not yet" for a GitHub folder: pick the page it is about, or never'),
|
|
1342
1351
|
reason: z.string().optional().describe('required with decline: why it belongs to no page — the next session asked will read it'),
|
|
1343
1352
|
defer: z.boolean().optional().describe('cold judges only (a cleanup lease): hand the question to the next session that touches it'),
|
|
1344
1353
|
confirmTier: z.boolean().optional().describe('required to claim onto a page narrower than accessible — its tier will govern every future commit there'),
|
|
1345
1354
|
})).optional().describe(
|
|
1346
|
-
'ADR-0077: one answer per open folder question from a refused call — exactly one of claim, decline or defer each. ' +
|
|
1355
|
+
'ADR-0077: one answer per open folder question from a refused call — exactly one of claim, decline ("never") or defer (cold judges only) each. ' +
|
|
1347
1356
|
'Send only after the server has listed the questions; claims and declines are written when the unit is filed.',
|
|
1348
1357
|
),
|
|
1349
1358
|
obligations: z.array(z.object({
|
|
@@ -2705,7 +2714,7 @@ function renderNudge(payload) {
|
|
|
2705
2714
|
brain: z.string().optional().describe('which brain to stop surfacing it in. Required when you belong to more than one — the call refuses rather than picking.'),
|
|
2706
2715
|
days: z.number().optional().describe('how long to stay quiet (1-365, default 90).'),
|
|
2707
2716
|
reason: z.string().optional().describe('why it belongs nowhere, in one phrase — the next person to see it resurface will want this. REQUIRED with kind.'),
|
|
2708
|
-
kind: z.enum(['never', 'not_yet']).optional().describe('ADR-0077: record a DECLINE instead of silencing the notice. never = generated/build output, lockfiles, fixtures, vendored code (a cold judge — a session holding cleanup leases — may not write it); not_yet = asked again after 10 more commits touch it or 90 days. A decline covers the identifier and everything under it, and claiming the identifier clears it.'),
|
|
2717
|
+
kind: z.enum(['never', 'not_yet']).optional().describe('ADR-0077: record a DECLINE instead of silencing the notice. never = generated/build output, lockfiles, fixtures, vendored code (a cold judge — a session holding cleanup leases — may not write it); not_yet = asked again after 10 more commits touch it or 90 days — NOT for a GitHub path (file:…), which takes a page or never (2026-10-22). A decline covers the identifier and everything under it, and claiming the identifier clears it.'),
|
|
2709
2718
|
remove: z.boolean().optional().describe('ADR-0077: UN-decline — delete the decline (or snooze) on this identifier, so the next commit that touches it is asked again.'),
|
|
2710
2719
|
},
|
|
2711
2720
|
},
|
package/package.json
CHANGED