@theronap/cortex-mcp 0.9.97 → 0.9.98
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/skills.mjs +29 -0
- package/package.json +1 -1
package/lib/skills.mjs
CHANGED
|
@@ -361,6 +361,35 @@ export async function runSkills(argv = []) {
|
|
|
361
361
|
if (argv[0] === 'push') return runSkillsPush(argv.slice(1))
|
|
362
362
|
|
|
363
363
|
const quiet = argv.includes('--quiet')
|
|
364
|
+
|
|
365
|
+
// ── C2 (ADR-0033 §5): move the MCP config key to its new name. ─────────────
|
|
366
|
+
// This runs from the SessionStart hook because that is the only channel that reaches every seat
|
|
367
|
+
// without asking anyone to do anything. It is safe here for two reasons that both matter:
|
|
368
|
+
//
|
|
369
|
+
// • It is SELF-GUARDING. runKeyMigration adds the new namespace's allow rules and re-reads them
|
|
370
|
+
// from disk BEFORE flipping the key, and aborts leaving the machine on the old name if they
|
|
371
|
+
// did not land. The C1 release already pre-authorized both namespaces, so on a seat that took
|
|
372
|
+
// C1 there is nothing left to add — but a seat that skipped C1 entirely is handled too, which
|
|
373
|
+
// is the whole reason the guard lives on the machine rather than in the release cadence.
|
|
374
|
+
// • It is idempotent and cheap after the first run: a state file read, then nothing.
|
|
375
|
+
//
|
|
376
|
+
// FAIL-SOFT, like every other hook step. A migration hiccup must never block a session from
|
|
377
|
+
// starting; the next SessionStart tries again.
|
|
378
|
+
try {
|
|
379
|
+
const { runKeyMigration } = await import('./migrate_key.mjs')
|
|
380
|
+
const res = runKeyMigration()
|
|
381
|
+
if (!quiet && res.status === 'migrated') {
|
|
382
|
+
process.stdout.write(` ✓ MCP config key moved ${res.from} → ${res.to}. Restart to load it under the new name.\n`)
|
|
383
|
+
}
|
|
384
|
+
if (res.status === 'aborted') {
|
|
385
|
+
// Loud on stderr even when quiet: an abort means the machine is INTENTIONALLY still on the old
|
|
386
|
+
// key, and a silent abort is indistinguishable from never having tried.
|
|
387
|
+
process.stderr.write(`agnoclast: key migration held off at "${res.step}" (${res.reason}) — still on the old name, will retry.\n`)
|
|
388
|
+
}
|
|
389
|
+
} catch (e) {
|
|
390
|
+
process.stderr.write(`agnoclast: key migration skipped (${e?.message ?? e}) — will retry next session.\n`)
|
|
391
|
+
}
|
|
392
|
+
|
|
364
393
|
if (!quiet) process.stdout.write('\nAgnoclast skills — installing managed skills…\n')
|
|
365
394
|
const r = installSkills({ quiet })
|
|
366
395
|
if (!quiet) {
|