feat(observer): node-dormancy extractor + initial JSON snapshot
Two-signal availability check: dormant=true OR boundaries contains DEFERRED. Treats #17 (Tooling-marked) and #44/#50/#54/#67 (DEFERRED in boundaries) uniformly as unavailable. Tooling Прил.Н unmodified — semantics preserved. 7 vitest cases (basic, multi-row, DEFERRED-fallback, boundary check). Initial JSON: 67 nodes, 6 unavailable. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Tooling Прил.Н dormancy extractor — emits {id: unavailable_bool} JSON for
|
||||
* the missed-activation matcher (Pravila §16.4 conditional rule).
|
||||
*
|
||||
* Two signals (either is sufficient) treat a node as effectively unavailable:
|
||||
* 1. `dormant: true` — Tooling-marked permanent dormancy (e.g. #17 pg_partman,
|
||||
* native Windows-PG cannot load the extension).
|
||||
* 2. `boundaries` column contains the word DEFERRED — node is registered
|
||||
* but not active (e.g. #44 Figma MCP "DEFERRED — нет Figma-аккаунта",
|
||||
* #50 Jupyter MCP, #54 n8n-mcp). The output key is still named "dormant"
|
||||
* for consumer simplicity — semantics: "node cannot be activated right
|
||||
* now, exclude from missed-activation counts".
|
||||
*
|
||||
* Parses 9-attribute table rows; ignores headers/separators/templates.
|
||||
*
|
||||
* Security Guidance #40: pure parsing — no exec/execSync.
|
||||
*/
|
||||
import { readFileSync, writeFileSync } from 'fs';
|
||||
|
||||
const ROW_RE = /^\|\s*#(\d+)\s*\|[^|]+\|[^|]+\|[^|]+\|[^|]+\|[^|]+\|([^|]+)\|\s*(true|false)\s*\|[^|]+\|$/gm;
|
||||
|
||||
export function extractDormancy(md) {
|
||||
const out = {};
|
||||
for (const m of md.matchAll(ROW_RE)) {
|
||||
const id = `#${m[1]}`;
|
||||
const boundaries = m[2];
|
||||
const tooledDormant = m[3] === 'true';
|
||||
out[id] = tooledDormant || /\bDEFERRED\b/.test(boundaries);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
if (process.argv[1] && process.argv[1].replace(/\\/g, '/').endsWith('/extract-node-dormancy.mjs')) {
|
||||
const src = readFileSync('docs/Tooling_v8_3.md', 'utf-8');
|
||||
const dormancy = extractDormancy(src);
|
||||
writeFileSync('tools/.node-dormancy.json', JSON.stringify(dormancy, null, 2) + '\n');
|
||||
console.log(`[extract-node-dormancy] OK — ${Object.keys(dormancy).length} nodes`);
|
||||
}
|
||||
Reference in New Issue
Block a user