@theronap/agnoclast-mcp 0.9.178 → 0.9.180

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.
@@ -83,7 +83,11 @@ export function formatNotice(signals) {
83
83
  const group = offers.filter((o) => o.via_reason === key)
84
84
  if (!group.length) continue
85
85
  lines.push(` ${why} (${group.length}):`)
86
- for (const o of group) lines.push(` ${o.intakeItemId} ${o.source} · ${o.hoursAgo}h`)
86
+ // The title is what makes a row judgeable; an id names a unit without saying what it is.
87
+ for (const o of group) {
88
+ const name = o.title ? ` ${o.title}` : ''
89
+ lines.push(` ${o.intakeItemId}${name} · ${o.source} · ${o.hoursAgo}h`)
90
+ }
87
91
  }
88
92
  // Only when the pile genuinely exceeds the server's scan window; `total` is counted before it.
89
93
  if (total > offers.length) lines.push(` … and ${total - offers.length} beyond the scan window`)
package/lib/capture.mjs CHANGED
@@ -80,6 +80,46 @@ export function repoFullNameFrom(cwd) {
80
80
  }
81
81
  }
82
82
 
83
+ /**
84
+ * The FILES this session is working on, for ADR-0066 §7 session identifiers.
85
+ *
86
+ * 🔴 WHY: the session used to hold only `repo:<owner/name>`, while every record arrives carrying the
87
+ * exact paths it touched. Everything in a repo matches the repo, so on a live session 211 of 217
88
+ * arrivals came back "matched" — a pile with no bounded action in it, which an agent then claims
89
+ * none of. Git already knows the answer precisely, so nothing new has to be plumbed or remembered.
90
+ *
91
+ * Two questions, unioned:
92
+ * working tree vs HEAD — what is being edited right now
93
+ * base..HEAD — what this branch has already committed
94
+ *
95
+ * The second is why this survives a commit: the moment work is committed the working tree goes
96
+ * clean, and a session that had just built something would stop being a candidate for the very
97
+ * records that build produces (its own PR, its own release mail).
98
+ *
99
+ * ⚠ SCOPED TO THIS BRANCH ON PURPOSE. The base is merge-base(HEAD, origin), so a session sitting on
100
+ * an unmodified main reports NOTHING rather than the whole repo's recent history — which would be
101
+ * other people's work, claimed as attention this session never paid.
102
+ *
103
+ * Best-effort and bounded like every other git read here: a non-repo cwd, a detached head or a
104
+ * missing origin yields [], and the caller simply omits the field.
105
+ */
106
+ export function workingFilesFrom(cwd, max = 40) {
107
+ if (!cwd) return []
108
+ const run = (args) => {
109
+ try {
110
+ return execFileSync('git', ['-C', String(cwd), ...args], {
111
+ encoding: 'utf8', timeout: 2000, stdio: ['ignore', 'pipe', 'ignore'],
112
+ }).split('\n').map((l) => l.trim()).filter(Boolean)
113
+ } catch {
114
+ return []
115
+ }
116
+ }
117
+ const files = new Set(run(['diff', '--name-only', 'HEAD']))
118
+ const base = run(['merge-base', 'HEAD', 'origin/HEAD'])[0] || run(['merge-base', 'HEAD', 'origin/main'])[0]
119
+ if (base) for (const f of run(['diff', '--name-only', base, 'HEAD'])) files.add(f)
120
+ return [...files].slice(0, max)
121
+ }
122
+
83
123
  // ── SHR-01/T9 — stamp the repos the session WORKED IN, not the one it was launched from ─────────
84
124
  //
85
125
  // WHY THIS EXISTS. `repoFullNameFrom(cwd)` above reads the session's LAUNCH directory. Measured
package/lib/server.mjs CHANGED
@@ -15,7 +15,7 @@ import { buildProposal, renderProposal, withAskNotice } from './propose_obligati
15
15
  import { renderCaptureStatus } from './capture_status.mjs'
16
16
  import { renderTriage } from './red_link_triage.mjs'
17
17
  import { runCodeGraphQuery } from './code_graph_cli.mjs'
18
- import { repoFullNameFrom } from './capture.mjs'
18
+ import { repoFullNameFrom, workingFilesFrom } from './capture.mjs'
19
19
  import { spawnObligationWorker } from './obligations_worker.mjs'
20
20
  import { renderObligations } from './obligations_render.mjs'
21
21
 
@@ -203,6 +203,11 @@ export async function runServer(version) {
203
203
  cwd: process.cwd(),
204
204
  mcpVersion: version,
205
205
  repo: repoFullNameFrom(process.cwd()) ?? undefined,
206
+ // files (ADR-0066 §7, 2026-09-25): the exact paths this session is working on, so it can
207
+ // be told apart from every other session in the same repo. Holding only `repo:` made 211
208
+ // of 217 arrivals "matched" on a live session — a pile with no bounded action in it.
209
+ // Best-effort and bounded in workingFilesFrom; a non-repo cwd yields [] and is omitted.
210
+ files: workingFilesFrom(process.cwd()).slice(0, 40),
206
211
  }),
207
212
  })
208
213
  } catch { /* best-effort heartbeat — never disrupt the session */ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@theronap/agnoclast-mcp",
3
- "version": "0.9.178",
3
+ "version": "0.9.180",
4
4
  "description": "Connect your AI assistant to Cortex — your org's projects, activity, gaps, and directives, scoped to you.",
5
5
  "type": "module",
6
6
  "bin": {