@uwmd/core 1.6.0 → 1.8.0
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/dist/agents/bancroft.js +4 -1
- package/dist/agents/bancroft.js.map +1 -1
- package/dist/asset-class.d.ts +98 -0
- package/dist/asset-class.d.ts.map +1 -0
- package/dist/asset-class.js +226 -0
- package/dist/asset-class.js.map +1 -0
- package/dist/browser.d.ts +23 -9
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +25 -5
- package/dist/browser.js.map +1 -1
- package/dist/calc/errors.d.ts +1 -1
- package/dist/calc/errors.d.ts.map +1 -1
- package/dist/calc/errors.js.map +1 -1
- package/dist/calc/evaluator.js +25 -1
- package/dist/calc/evaluator.js.map +1 -1
- package/dist/calc/prng.d.ts +59 -0
- package/dist/calc/prng.d.ts.map +1 -0
- package/dist/calc/prng.js +181 -0
- package/dist/calc/prng.js.map +1 -0
- package/dist/calc/sensitivity.d.ts +76 -0
- package/dist/calc/sensitivity.d.ts.map +1 -0
- package/dist/calc/sensitivity.js +160 -0
- package/dist/calc/sensitivity.js.map +1 -0
- package/dist/calc/stochastic.d.ts +97 -0
- package/dist/calc/stochastic.d.ts.map +1 -0
- package/dist/calc/stochastic.js +265 -0
- package/dist/calc/stochastic.js.map +1 -0
- package/dist/cascade.d.ts.map +1 -1
- package/dist/cascade.js +8 -4
- package/dist/cascade.js.map +1 -1
- package/dist/cli-args.d.ts +37 -0
- package/dist/cli-args.d.ts.map +1 -0
- package/dist/cli-args.js +93 -0
- package/dist/cli-args.js.map +1 -0
- package/dist/cli.js +119 -72
- package/dist/cli.js.map +1 -1
- package/dist/editor.js +25 -6
- package/dist/editor.js.map +1 -1
- package/dist/index.d.ts +24 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -5
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +16 -4
- package/dist/init.js.map +1 -1
- package/dist/integrity-canonical.d.ts.map +1 -1
- package/dist/integrity-canonical.js +10 -2
- package/dist/integrity-canonical.js.map +1 -1
- package/dist/integrity.d.ts +92 -4
- package/dist/integrity.d.ts.map +1 -1
- package/dist/integrity.js +195 -9
- package/dist/integrity.js.map +1 -1
- package/dist/lite-bridge.d.ts.map +1 -1
- package/dist/lite-bridge.js +47 -0
- package/dist/lite-bridge.js.map +1 -1
- package/dist/migrate-source-tags.d.ts +34 -0
- package/dist/migrate-source-tags.d.ts.map +1 -0
- package/dist/migrate-source-tags.js +179 -0
- package/dist/migrate-source-tags.js.map +1 -0
- package/dist/module-runtime.d.ts +57 -0
- package/dist/module-runtime.d.ts.map +1 -0
- package/dist/module-runtime.js +167 -0
- package/dist/module-runtime.js.map +1 -0
- package/dist/module-signing.d.ts +85 -0
- package/dist/module-signing.d.ts.map +1 -0
- package/dist/module-signing.js +136 -0
- package/dist/module-signing.js.map +1 -0
- package/dist/modules.d.ts +42 -0
- package/dist/modules.d.ts.map +1 -1
- package/dist/modules.js +124 -1
- package/dist/modules.js.map +1 -1
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +27 -1
- package/dist/parser.js.map +1 -1
- package/dist/protocol.d.ts +234 -21
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +352 -32
- package/dist/protocol.js.map +1 -1
- package/dist/renderer.d.ts.map +1 -1
- package/dist/renderer.js +22 -2
- package/dist/renderer.js.map +1 -1
- package/dist/report.d.ts.map +1 -1
- package/dist/report.js +17 -0
- package/dist/report.js.map +1 -1
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +9 -3
- package/dist/runner.js.map +1 -1
- package/dist/types.d.ts +118 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +44 -0
- package/dist/types.js.map +1 -1
- package/dist/validator.d.ts +26 -2
- package/dist/validator.d.ts.map +1 -1
- package/dist/validator.js +256 -19
- package/dist/validator.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +6 -2
package/dist/cli.js
CHANGED
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
// Commands: parse, validate, compact, diff, init, summary, render
|
|
4
4
|
// Usage: uwmd <command> <file> [options]
|
|
5
5
|
import { readFileSync, writeFileSync, existsSync, readdirSync, mkdirSync } from 'node:fs';
|
|
6
|
-
import { resolve, basename
|
|
6
|
+
import { resolve, basename } from 'node:path';
|
|
7
7
|
import { parseUWFile } from './parser.js';
|
|
8
8
|
import { validateUWFile } from './validator.js';
|
|
9
9
|
import { compact, diff } from './compactor.js';
|
|
10
|
+
import { migrateSourceTags } from './migrate-source-tags.js';
|
|
10
11
|
import { generateBlankUWFile } from './init.js';
|
|
11
12
|
import { render } from './renderer.js';
|
|
12
13
|
import { renderReportHtml } from './report.js';
|
|
@@ -16,6 +17,7 @@ import { CORE_CODEC_REGISTRY } from './codecs.js';
|
|
|
16
17
|
import { writeAgentBlock } from './runner.js';
|
|
17
18
|
import { applyEdit } from './editor.js';
|
|
18
19
|
import { verifyChain, verifyProvenance } from './integrity.js';
|
|
20
|
+
import { REFERENCE_IMPLEMENTATION_MANIFEST } from './protocol.js';
|
|
19
21
|
import { loadModuleManifest, createModuleRegistry, ModuleRegistryError } from './modules.js';
|
|
20
22
|
import { cmdLeaseValidate, cmdLeaseProject, cmdPackageCreate, cmdPackageVerify, cmdPackageList, cmdPackageToContext, cmdPackageContextValidate, cmdPackageEdges, } from './cli-packages.js';
|
|
21
23
|
import { evaluateCalc } from './calc/index.js';
|
|
@@ -34,6 +36,7 @@ import { detectUWSourceRepresentation, UWX_REPRESENTATION_ID, UW_LITE_SOURCE_DES
|
|
|
34
36
|
import { parseUWLite } from './lite.js';
|
|
35
37
|
import { compileUWLite, projectUWEnvelopeToLite, stringifyUWX, } from './lite-bridge.js';
|
|
36
38
|
import { UW_LITE_REPRESENTATION_ID } from './source-representation.js';
|
|
39
|
+
import { parseFlags, extractPositionals, replaceUWExtension, hostTierFlag, defaultPartsDir, readManifestFile, } from './cli-args.js';
|
|
37
40
|
const [, , command, ...args] = process.argv;
|
|
38
41
|
function readFile(path) {
|
|
39
42
|
const resolved = resolve(path);
|
|
@@ -54,30 +57,6 @@ function loadInstitutionConfig(path) {
|
|
|
54
57
|
return undefined;
|
|
55
58
|
}
|
|
56
59
|
}
|
|
57
|
-
function parseFlags(rawArgs) {
|
|
58
|
-
const flags = {};
|
|
59
|
-
for (let i = 0; i < rawArgs.length; i++) {
|
|
60
|
-
const arg = rawArgs[i];
|
|
61
|
-
if (arg.startsWith('--')) {
|
|
62
|
-
const body = arg.slice(2);
|
|
63
|
-
const eqIdx = body.indexOf('=');
|
|
64
|
-
if (eqIdx >= 0) {
|
|
65
|
-
flags[body.slice(0, eqIdx)] = body.slice(eqIdx + 1);
|
|
66
|
-
continue;
|
|
67
|
-
}
|
|
68
|
-
const key = body;
|
|
69
|
-
const next = rawArgs[i + 1];
|
|
70
|
-
if (next && !next.startsWith('--')) {
|
|
71
|
-
flags[key] = next;
|
|
72
|
-
i++;
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
flags[key] = true;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
return flags;
|
|
80
|
-
}
|
|
81
60
|
// ─── Commands ─────────────────────────────────────────────────────────────────
|
|
82
61
|
function cmdParse(file, flags) {
|
|
83
62
|
const content = readFile(file);
|
|
@@ -96,11 +75,24 @@ function cmdParse(file, flags) {
|
|
|
96
75
|
for (const warning of detection.warnings)
|
|
97
76
|
console.warn(`Warning: ${warning}`);
|
|
98
77
|
const parsed = parseUWFile(content, { strict: flags['strict'] === true });
|
|
78
|
+
// The whole ParsedUWFile minus `raw` (which is just the input echoed back).
|
|
79
|
+
// Four fields — custom_calculations, custom_scenarios, extensions, and the
|
|
80
|
+
// full `superseded` blocks — used to be dropped here, so a caller that
|
|
81
|
+
// trusted `uwmd parse` to be "the parsed file" silently lost every custom
|
|
82
|
+
// calculation and every x_* extension in the document.
|
|
83
|
+
//
|
|
84
|
+
// `superseded_blocks` is kept alongside `superseded` for compatibility: it
|
|
85
|
+
// carries only each prior block's `content`, where `superseded` carries the
|
|
86
|
+
// whole block. New callers should read `superseded`.
|
|
99
87
|
const output = {
|
|
100
88
|
frontmatter: parsed.frontmatter,
|
|
101
89
|
sections: Object.fromEntries(Object.entries(parsed.sections).map(([id, block]) => [id, block])),
|
|
102
90
|
prose: parsed.prose,
|
|
103
91
|
pipeline_log: parsed.pipeline_log.map(b => b.content),
|
|
92
|
+
custom_calculations: parsed.custom_calculations,
|
|
93
|
+
custom_scenarios: parsed.custom_scenarios,
|
|
94
|
+
extensions: parsed.extensions,
|
|
95
|
+
superseded: parsed.superseded,
|
|
104
96
|
superseded_blocks: Object.fromEntries(Object.entries(parsed.superseded).map(([id, blocks]) => [id, blocks.map(b => b.content)])),
|
|
105
97
|
};
|
|
106
98
|
console.log(JSON.stringify(output, null, flags['compact'] ? 0 : 2));
|
|
@@ -171,6 +163,40 @@ function cmdValidate(file, flags) {
|
|
|
171
163
|
console.log('');
|
|
172
164
|
process.exit(result.errors.length > 0 ? 1 : 0);
|
|
173
165
|
}
|
|
166
|
+
/**
|
|
167
|
+
* Build the `verifyChain` options from `--signing --keystore=<path>`.
|
|
168
|
+
*
|
|
169
|
+
* `@uwmd/signing` is reached by dynamic import and declared as an optional peer
|
|
170
|
+
* - the same arrangement `@anthropic-ai/sdk` gets. `@uwmd/core` must not take a
|
|
171
|
+
* crypto dependency to satisfy a flag most invocations never pass, and the
|
|
172
|
+
* layering invariant (core depends on no sibling package) forbids a static
|
|
173
|
+
* import outright.
|
|
174
|
+
*/
|
|
175
|
+
async function signingOptions(flags) {
|
|
176
|
+
if (!flags['signing'])
|
|
177
|
+
return {};
|
|
178
|
+
const keystore = flags['keystore'];
|
|
179
|
+
if (typeof keystore !== 'string' || keystore.length === 0) {
|
|
180
|
+
console.error('--signing requires --keystore=<path> to a JSON key store.');
|
|
181
|
+
process.exit(1);
|
|
182
|
+
}
|
|
183
|
+
let signing;
|
|
184
|
+
try {
|
|
185
|
+
signing = (await import('@uwmd/signing'));
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
console.error('--signing needs the optional @uwmd/signing package. Install it with `npm i @uwmd/signing`.');
|
|
189
|
+
process.exit(1);
|
|
190
|
+
}
|
|
191
|
+
try {
|
|
192
|
+
const store = await signing.loadKeyStoreFile(resolve(keystore));
|
|
193
|
+
return { signatureVerifier: signing.createBlockSignatureVerifier(store) };
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
console.error(error.message);
|
|
197
|
+
process.exit(1);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
174
200
|
async function cmdVerify(file, flags) {
|
|
175
201
|
const content = readFile(file);
|
|
176
202
|
// --resolved verifies the assembled record. Without it an externalized
|
|
@@ -191,8 +217,8 @@ async function cmdVerify(file, flags) {
|
|
|
191
217
|
}
|
|
192
218
|
let chain;
|
|
193
219
|
let prov;
|
|
194
|
-
if (runAll || onlyIntegrity) {
|
|
195
|
-
chain = await verifyChain(parsed);
|
|
220
|
+
if (runAll || onlyIntegrity || flags['signing']) {
|
|
221
|
+
chain = await verifyChain(parsed, await signingOptions(flags));
|
|
196
222
|
sections['integrity'] = chain;
|
|
197
223
|
if (!chain.ok)
|
|
198
224
|
hadError = true;
|
|
@@ -219,6 +245,12 @@ async function cmdVerify(file, flags) {
|
|
|
219
245
|
}
|
|
220
246
|
if (chain) {
|
|
221
247
|
console.log(`\nIntegrity: ${chain.ok ? 'ok' : 'FAIL'} — chains_with_hashes=${chain.chains_with_hashes}, chains_verified=${chain.chains_verified}`);
|
|
248
|
+
if (chain.signatures_present > 0) {
|
|
249
|
+
const checked = flags['signing']
|
|
250
|
+
? `${chain.signatures_verified} verified`
|
|
251
|
+
: 'not checked (pass --signing --keystore=<path>)';
|
|
252
|
+
console.log(`Signatures: ${chain.signatures_present} present, ${checked}`);
|
|
253
|
+
}
|
|
222
254
|
for (const issue of chain.issues) {
|
|
223
255
|
console.log(` [${issue.severity.toUpperCase()}] ${issue.code}${issue.section ? ` [${issue.section}]` : ''}: ${issue.message}`);
|
|
224
256
|
}
|
|
@@ -253,6 +285,24 @@ function cmdCompact(file, flags) {
|
|
|
253
285
|
writeFileSync(outPath, compacted, 'utf-8');
|
|
254
286
|
console.log(`Compacted ${totalSuperseded} superseded block(s). Wrote to: ${outPath}`);
|
|
255
287
|
}
|
|
288
|
+
function cmdMigrateSourceTags(file, flags) {
|
|
289
|
+
const content = readFile(file);
|
|
290
|
+
const result = migrateSourceTags(content);
|
|
291
|
+
for (const source of result.unmapped) {
|
|
292
|
+
console.error(`[unmapped] _meta.source '${source}' was left in place — rewrite it by hand.`);
|
|
293
|
+
}
|
|
294
|
+
if (result.changed === 0) {
|
|
295
|
+
console.log(`No legacy _meta.source values found in ${basename(file)} — nothing to migrate.`);
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
if (flags['dry-run']) {
|
|
299
|
+
console.log(`Would migrate ${result.changed} block(s) in ${basename(file)} (RFC 0031 actor/resolution split).`);
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
const outPath = flags['output'] ? resolve(flags['output']) : resolve(file);
|
|
303
|
+
writeFileSync(outPath, result.content, 'utf-8');
|
|
304
|
+
console.log(`Migrated ${result.changed} block(s). Wrote to: ${outPath}`);
|
|
305
|
+
}
|
|
256
306
|
function cmdDiff(fileA, fileB) {
|
|
257
307
|
const contentA = readFile(fileA);
|
|
258
308
|
const contentB = readFile(fileB);
|
|
@@ -402,14 +452,6 @@ async function loadEnvelope(file) {
|
|
|
402
452
|
* rather than `deal.uw.json`. (`.uw.md` does not match a `.uwx.md` filename —
|
|
403
453
|
* the suffixes genuinely differ — so it was silently a no-op, not a mis-match.)
|
|
404
454
|
*/
|
|
405
|
-
function replaceUWExtension(file, extension) {
|
|
406
|
-
const lower = file.toLowerCase();
|
|
407
|
-
for (const suffix of [UWX_EXTENSION, '.uw.csv.zip', '.uw.md', '.uw.json', '.uw.xml']) {
|
|
408
|
-
if (lower.endsWith(suffix))
|
|
409
|
-
return `${file.slice(0, -suffix.length)}${extension}`;
|
|
410
|
-
}
|
|
411
|
-
return `${file}${extension}`;
|
|
412
|
-
}
|
|
413
455
|
async function cmdConvert(file, flags) {
|
|
414
456
|
const requested = flags['to'];
|
|
415
457
|
if (typeof requested !== 'string') {
|
|
@@ -488,18 +530,6 @@ async function cmdReceiptIssue(file, flags) {
|
|
|
488
530
|
console.log('A receipt attests that these outputs follow from this record. It does not attest that the inputs are true.');
|
|
489
531
|
}
|
|
490
532
|
// ─── Modules ──────────────────────────────────────────────────────────────────
|
|
491
|
-
function readManifestFile(path) {
|
|
492
|
-
try {
|
|
493
|
-
return { ok: true, manifest: JSON.parse(readFileSync(resolve(path), 'utf-8')) };
|
|
494
|
-
}
|
|
495
|
-
catch (e) {
|
|
496
|
-
return { ok: false, message: e instanceof Error ? e.message : String(e) };
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
function hostTierFlag(flags) {
|
|
500
|
-
const tier = flags['tier'];
|
|
501
|
-
return typeof tier === 'string' ? tier : undefined;
|
|
502
|
-
}
|
|
503
533
|
function cmdModulesValidate(files, flags) {
|
|
504
534
|
const hostTier = hostTierFlag(flags);
|
|
505
535
|
const reports = files.map((file) => {
|
|
@@ -809,16 +839,7 @@ function cmdRefine(file, flags) {
|
|
|
809
839
|
}
|
|
810
840
|
// ─── Router ───────────────────────────────────────────────────────────────────
|
|
811
841
|
const flags = parseFlags(args);
|
|
812
|
-
|
|
813
|
-
const positional = [];
|
|
814
|
-
for (let _i = 0; _i < args.length; _i++) {
|
|
815
|
-
const a = args[_i];
|
|
816
|
-
if (a.startsWith('--')) {
|
|
817
|
-
_i++;
|
|
818
|
-
continue;
|
|
819
|
-
} // skip flag + its value
|
|
820
|
-
positional.push(a);
|
|
821
|
-
}
|
|
842
|
+
const positional = extractPositionals(args);
|
|
822
843
|
// ─── Composition (RFC 0021) ──────────────────────────────────────────────────
|
|
823
844
|
/** Load every `.uwpart.md` in a directory, keyed by `part_id`. */
|
|
824
845
|
function loadPartsDir(dir) {
|
|
@@ -836,10 +857,6 @@ function loadPartsDir(dir) {
|
|
|
836
857
|
}
|
|
837
858
|
return parts;
|
|
838
859
|
}
|
|
839
|
-
/** Where fragments live for a record, unless told otherwise. */
|
|
840
|
-
function defaultPartsDir(file) {
|
|
841
|
-
return resolve(dirname(resolve(file)), 'parts');
|
|
842
|
-
}
|
|
843
860
|
function cmdCompose(file, flags) {
|
|
844
861
|
const section = flags['externalize'];
|
|
845
862
|
if (typeof section !== 'string') {
|
|
@@ -969,7 +986,7 @@ function withResolved(parsed, file, flags) {
|
|
|
969
986
|
break;
|
|
970
987
|
case 'verify':
|
|
971
988
|
if (!positional[0]) {
|
|
972
|
-
console.error('Usage: uwmd verify <file> [--validate] [--integrity] [--policy] [--resolved] [--json]');
|
|
989
|
+
console.error('Usage: uwmd verify <file> [--validate] [--integrity] [--policy] [--signing --keystore=<path>] [--resolved] [--json]');
|
|
973
990
|
process.exit(1);
|
|
974
991
|
}
|
|
975
992
|
await cmdVerify(positional[0], flags);
|
|
@@ -988,6 +1005,13 @@ function withResolved(parsed, file, flags) {
|
|
|
988
1005
|
}
|
|
989
1006
|
cmdDiff(positional[0], positional[1]);
|
|
990
1007
|
break;
|
|
1008
|
+
case 'migrate':
|
|
1009
|
+
if (!positional[0] || !flags['source-tags']) {
|
|
1010
|
+
console.error('Usage: uwmd migrate <file> --source-tags [--output <file>] [--dry-run]');
|
|
1011
|
+
process.exit(1);
|
|
1012
|
+
}
|
|
1013
|
+
cmdMigrateSourceTags(positional[0], flags);
|
|
1014
|
+
break;
|
|
991
1015
|
case 'render': {
|
|
992
1016
|
if (!positional[0]) {
|
|
993
1017
|
console.error('Usage: uwmd render <file> [--format <json|csv|chat|summary>] [--profile <summary|live|compact|full|relevant>] [--sections a,b,c] [--max-tokens 12000] [--no-meta] [--output <file>] [--tier screener|analyst]');
|
|
@@ -1175,6 +1199,13 @@ function withResolved(parsed, file, flags) {
|
|
|
1175
1199
|
confidence: flags['confidence'] ?? 'medium',
|
|
1176
1200
|
};
|
|
1177
1201
|
const result = applyEdit(fileContent, parsedFile, op, ctx);
|
|
1202
|
+
// --json reports the edit instead of performing it: the conformance driver
|
|
1203
|
+
// needs the resulting content, and a driver that rewrote fixtures as a side
|
|
1204
|
+
// effect of reading them would corrupt the corpus it is testing.
|
|
1205
|
+
if (flags['json']) {
|
|
1206
|
+
console.log(JSON.stringify(result, null, 2));
|
|
1207
|
+
process.exit(result.ok ? 0 : 1);
|
|
1208
|
+
}
|
|
1178
1209
|
if (!result.ok || !result.content) {
|
|
1179
1210
|
console.error(`Edit rejected: [${result.error?.code}] ${result.error?.message}`);
|
|
1180
1211
|
if (result.error?.pointer)
|
|
@@ -1214,16 +1245,21 @@ function withResolved(parsed, file, flags) {
|
|
|
1214
1245
|
locale: 'en-US',
|
|
1215
1246
|
};
|
|
1216
1247
|
const results = decls.map((d) => evaluateCalc(d, ctx));
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
}
|
|
1221
|
-
else {
|
|
1222
|
-
console.log(`${r.calc_id} ERROR [${r.error?.code}] ${r.error?.message}`);
|
|
1223
|
-
}
|
|
1224
|
-
}
|
|
1248
|
+
// Under --json, stdout is exactly one JSON document — the conformance CLI
|
|
1249
|
+
// protocol (§II.6a) depends on that, and printing the human lines first
|
|
1250
|
+
// would make every calc response unparseable.
|
|
1225
1251
|
if (flags['json']) {
|
|
1226
|
-
console.log(JSON.stringify(results, null, 2));
|
|
1252
|
+
console.log(JSON.stringify(results.length === 1 ? results[0] : results, null, 2));
|
|
1253
|
+
}
|
|
1254
|
+
else {
|
|
1255
|
+
for (const r of results) {
|
|
1256
|
+
if (r.ok) {
|
|
1257
|
+
console.log(`${r.calc_id} = ${r.display ?? String(r.value)}`);
|
|
1258
|
+
}
|
|
1259
|
+
else {
|
|
1260
|
+
console.log(`${r.calc_id} ERROR [${r.error?.code}] ${r.error?.message}`);
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1227
1263
|
}
|
|
1228
1264
|
if (results.some((r) => !r.ok))
|
|
1229
1265
|
process.exit(1);
|
|
@@ -1402,6 +1438,11 @@ function withResolved(parsed, file, flags) {
|
|
|
1402
1438
|
}
|
|
1403
1439
|
break;
|
|
1404
1440
|
}
|
|
1441
|
+
case 'manifest':
|
|
1442
|
+
// The conformance CLI protocol's identity call (§II.6a). Emitted with no
|
|
1443
|
+
// surrounding prose so a driver can read it without a parser.
|
|
1444
|
+
console.log(JSON.stringify(REFERENCE_IMPLEMENTATION_MANIFEST, null, 2));
|
|
1445
|
+
break;
|
|
1405
1446
|
case 'receipt': {
|
|
1406
1447
|
const sub = positional[0];
|
|
1407
1448
|
if (sub === 'issue') {
|
|
@@ -1432,11 +1473,14 @@ Commands:
|
|
|
1432
1473
|
parse <file> Parse file and output JSON
|
|
1433
1474
|
validate <file> Run all validation checks
|
|
1434
1475
|
verify <file> Validate + verify integrity (hashes) + provenance (actor/policy)
|
|
1476
|
+
--signing --keystore=<path> also checks block signatures (RFC 0010,
|
|
1477
|
+
via the optional @uwmd/signing package)
|
|
1435
1478
|
render <file> Render to output format (see --format)
|
|
1436
1479
|
run <file> Invoke a Bancroft agent (see --agent)
|
|
1437
1480
|
edit <file> <op.json> Apply an EditOperation (Tier-2)
|
|
1438
1481
|
compact <file> Strip superseded blocks
|
|
1439
1482
|
diff <file-a> <file-b> Compare two files section by section
|
|
1483
|
+
migrate <file> --source-tags Rewrite legacy _meta.source values into the actor/resolution split (RFC 0031)
|
|
1440
1484
|
calc <file> <calc.json> Evaluate a calc declaration or inline formula (Tier-3)
|
|
1441
1485
|
init Generate a blank .uwx.md file
|
|
1442
1486
|
summary <file> Print quick metrics to terminal
|
|
@@ -1452,16 +1496,19 @@ Commands:
|
|
|
1452
1496
|
modules validate|list Validate module manifest files, or list the registry they form
|
|
1453
1497
|
lease validate|project Validate a lease abstract, or project it to a rent-roll row (RFC 0018)
|
|
1454
1498
|
package create|verify|... Build, verify, list, or project a UW Deal Package (RFC 0018)
|
|
1499
|
+
manifest Print this implementation's ImplementationManifest (conformance protocol)
|
|
1455
1500
|
layers List Bancroft agent layers
|
|
1456
1501
|
|
|
1457
1502
|
Options:
|
|
1458
1503
|
--output <path> Output file path (compact, init)
|
|
1459
1504
|
--dry-run Show what would change without writing (compact)
|
|
1460
|
-
--json JSON output (validate)
|
|
1505
|
+
--json JSON output on stdout, nothing else (validate, calc, edit)
|
|
1461
1506
|
--strict Throw on parse errors instead of collecting
|
|
1462
1507
|
--format <f> Render format: json|csv|chat|summary (render, default: summary)
|
|
1463
1508
|
--no-superseded Drop append-only history from the .uw.json export (export)
|
|
1464
1509
|
--resolved Resolve externalized sections first (verify, export)
|
|
1510
|
+
--signing Check _meta.signature on every block (verify; requires --keystore)
|
|
1511
|
+
--keystore <path> JSON key store mapping kid to public key (verify --signing)
|
|
1465
1512
|
--parts <dir> Fragment directory (compose, resolve, --resolved; default: ./parts)
|
|
1466
1513
|
--externalize <s> Section to split into fragments (compose)
|
|
1467
1514
|
--collection-key <k> Row identity field (compose, default: unit_id)
|