@theronap/agnoclast-mcp 0.9.190 → 0.9.191
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/context_log.mjs +47 -0
- package/package.json +1 -1
package/lib/context_log.mjs
CHANGED
|
@@ -39,6 +39,48 @@ function pruneSnapshots(dir, keep = SNAPSHOT_RETENTION) {
|
|
|
39
39
|
} catch { /* ignore — never break session start */ }
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* PURE. The blocks of the startup context a person has to ACT on — every `## ` block except the two
|
|
44
|
+
* static orientation ones — joined with a blank line between them. '' when there are none.
|
|
45
|
+
*
|
|
46
|
+
* WHY THIS IS PRINTED, NOT JUST SAVED (2026-09-30). `snapshot-context` fetched /api/mcp-context and
|
|
47
|
+
* wrote it to a file, printing only "logged startup context". That file is where the steward queue,
|
|
48
|
+
* "Pages handed to you", the successor nudge, file requests, re-tier notices and "records waiting for
|
|
49
|
+
* a home" live — and nothing on a managed seat ever read it back to the model: `hydrate` and the
|
|
50
|
+
* context skill use /api/session-context, which carries none of those blocks. One machine saw them,
|
|
51
|
+
* through a hand-written local script. Every other seat was told nothing at session start, which made
|
|
52
|
+
* "the steward is asked at every session start" true for exactly one person.
|
|
53
|
+
*
|
|
54
|
+
* Printed from THIS run's response, so there is no ordering to get wrong: the local script it
|
|
55
|
+
* replaces read latest.md from a parallel hook and showed the PREVIOUS session's blocks.
|
|
56
|
+
*
|
|
57
|
+
* Skips by distinctive ASCII substring, not the full heading: the pointer block's heading opens with
|
|
58
|
+
* a multibyte character, and a block added later surfaces here with no edit — the failure this
|
|
59
|
+
* inversion was made to end was a hook that named the two blocks it wanted and dropped the rest.
|
|
60
|
+
*/
|
|
61
|
+
export const SKIPPED_BLOCK_MARKERS = ['Your place in the org', 'This is a POINTER']
|
|
62
|
+
|
|
63
|
+
export function actionableBlocks(context) {
|
|
64
|
+
if (typeof context !== 'string' || !context) return ''
|
|
65
|
+
const blocks = []
|
|
66
|
+
let cur = null
|
|
67
|
+
for (const line of context.split('\n')) {
|
|
68
|
+
if (line.startsWith('## ')) {
|
|
69
|
+
if (cur) blocks.push(cur)
|
|
70
|
+
cur = { skip: SKIPPED_BLOCK_MARKERS.some((m) => line.includes(m)), lines: [line] }
|
|
71
|
+
} else if (cur) {
|
|
72
|
+
cur.lines.push(line)
|
|
73
|
+
}
|
|
74
|
+
// lines before the first "## " are the title and the clock: orientation, not action
|
|
75
|
+
}
|
|
76
|
+
if (cur) blocks.push(cur)
|
|
77
|
+
return blocks
|
|
78
|
+
.filter((b) => !b.skip)
|
|
79
|
+
.map((b) => b.lines.join('\n').replace(/\s+$/, ''))
|
|
80
|
+
.filter(Boolean)
|
|
81
|
+
.join('\n\n')
|
|
82
|
+
}
|
|
83
|
+
|
|
42
84
|
export async function runSnapshotContext() {
|
|
43
85
|
const out = (m) => process.stdout.write(m + '\n')
|
|
44
86
|
const token = resolveToken()
|
|
@@ -92,6 +134,11 @@ export async function runSnapshotContext() {
|
|
|
92
134
|
|
|
93
135
|
pruneSnapshots(dir)
|
|
94
136
|
|
|
137
|
+
// The action blocks go to STDOUT, which a SessionStart hook injects into the session. Before the
|
|
138
|
+
// "logged" line so a truncated preview shows what needs doing rather than a file path.
|
|
139
|
+
const blocks = actionableBlocks(context)
|
|
140
|
+
if (blocks) out(blocks + '\n')
|
|
141
|
+
|
|
95
142
|
out(`Agnoclast: logged startup context → ${file}`)
|
|
96
143
|
return 0
|
|
97
144
|
}
|
package/package.json
CHANGED