P11.3 + P11.4: BaseNodeAdapter query.units + wikiGen Unit column
P11.3 BaseNodeAdapter auto-wires query.units:
Implicit query.units topic registered if subclass commands don't
already declare one. Returns {node, units: {topic → {measure,
default, accepted: [...]}}} via convert.possibilities. Subclass
query.units overrides. 17/17 tests; BaseNodeAdapter.js 211 lines.
P11.4 wikiGen Unit column:
Auto-generated topic-contract table grows a Unit column showing
`<measure> (default <unit>)` for topics with units, '—' otherwise.
Effect column now uses descriptor.description when present (P11.2
field), falls back to generic per-prefix sentence. wikiGen.js 303
→ 315 lines. WIKI_TEMPLATE.md §5 sample updated.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -114,6 +114,17 @@ function spliceAutogen(filePath, marker, body) {
|
||||
|
||||
// ── Subcommand: contract ───────────────────────────────────────────────────
|
||||
|
||||
function describeUnits(units) {
|
||||
// Descriptor.units is the validated `{ measure, default }` pair the
|
||||
// commandRegistry stores; render it as `<measure> (default <unit>)` so
|
||||
// a reader sees both the dimension and the canonical default that the
|
||||
// node coerces to. Em-dash for unit-less topics keeps the column tidy.
|
||||
if (!units || typeof units !== 'object') return '—';
|
||||
const { measure, default: def } = units;
|
||||
if (!measure || !def) return '—';
|
||||
return '`' + measure + '` (default `' + def + '`)';
|
||||
}
|
||||
|
||||
function renderContract(commandsPath) {
|
||||
const abs = resolveAbs(commandsPath);
|
||||
// eslint-disable-next-line import/no-dynamic-require, global-require
|
||||
@@ -123,16 +134,17 @@ function renderContract(commandsPath) {
|
||||
}
|
||||
|
||||
const lines = [];
|
||||
lines.push('| Canonical topic | Aliases | Payload | Effect |');
|
||||
lines.push('|---|---|---|---|');
|
||||
lines.push('| Canonical topic | Aliases | Payload | Unit | Effect |');
|
||||
lines.push('|---|---|---|---|---|');
|
||||
for (const d of registry) {
|
||||
const topic = '`' + d.topic + '`';
|
||||
const aliases = (d.aliases && d.aliases.length)
|
||||
? d.aliases.map((a) => '`' + a + '`').join(', ')
|
||||
: '_(none)_';
|
||||
const payload = describeSchema(d.payloadSchema);
|
||||
const unit = describeUnits(d.units);
|
||||
const effect = d.description ? String(d.description) : topicEffectFallback(d.topic);
|
||||
lines.push(`| ${topic} | ${aliases} | ${payload} | ${effect} |`);
|
||||
lines.push(`| ${topic} | ${aliases} | ${payload} | ${unit} | ${effect} |`);
|
||||
}
|
||||
return lines.join('\n');
|
||||
}
|
||||
@@ -300,4 +312,4 @@ if (require.main === module) {
|
||||
main();
|
||||
}
|
||||
|
||||
module.exports = { renderContract, renderDatamodel, spliceAutogen, describeSchema };
|
||||
module.exports = { renderContract, renderDatamodel, spliceAutogen, describeSchema, describeUnits };
|
||||
|
||||
Reference in New Issue
Block a user