@refrakt-md/cli 0.35.0 → 0.37.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/bin.js +420 -21
- package/dist/bin.js.map +1 -1
- package/dist/commands/config.d.ts +3 -2
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +110 -2
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/migrate-snippets.d.ts +65 -0
- package/dist/commands/migrate-snippets.d.ts.map +1 -0
- package/dist/commands/migrate-snippets.js +218 -0
- package/dist/commands/migrate-snippets.js.map +1 -0
- package/dist/commands/snippet-review.d.ts +66 -0
- package/dist/commands/snippet-review.d.ts.map +1 -0
- package/dist/commands/snippet-review.js +271 -0
- package/dist/commands/snippet-review.js.map +1 -0
- package/dist/commands/stale.d.ts +32 -0
- package/dist/commands/stale.d.ts.map +1 -0
- package/dist/commands/stale.js +130 -0
- package/dist/commands/stale.js.map +1 -0
- package/dist/commands/theme-validate.d.ts +23 -0
- package/dist/commands/theme-validate.d.ts.map +1 -0
- package/dist/commands/theme-validate.js +73 -0
- package/dist/commands/theme-validate.js.map +1 -0
- package/dist/commands/theme.d.ts +1 -2
- package/dist/commands/theme.d.ts.map +1 -1
- package/dist/commands/theme.js.map +1 -1
- package/dist/commands/validate-config.d.ts +35 -0
- package/dist/commands/validate-config.d.ts.map +1 -0
- package/dist/commands/validate-config.js +123 -0
- package/dist/commands/validate-config.js.map +1 -0
- package/dist/commands/validate-core.d.ts +51 -0
- package/dist/commands/validate-core.d.ts.map +1 -0
- package/dist/commands/validate-core.js +113 -0
- package/dist/commands/validate-core.js.map +1 -0
- package/dist/commands/validate.d.ts +12 -2
- package/dist/commands/validate.d.ts.map +1 -1
- package/dist/commands/validate.js +62 -60
- package/dist/commands/validate.js.map +1 -1
- package/package.json +11 -6
package/dist/bin.js
CHANGED
|
@@ -24,6 +24,15 @@ else if (command === 'scaffold-css') {
|
|
|
24
24
|
else if (command === 'validate') {
|
|
25
25
|
runValidate(args.slice(1));
|
|
26
26
|
}
|
|
27
|
+
else if (command === 'stale') {
|
|
28
|
+
runStale(args.slice(1));
|
|
29
|
+
}
|
|
30
|
+
else if (command === 'migrate' && args[1] === 'snippets') {
|
|
31
|
+
runMigrateSnippets(args.slice(2));
|
|
32
|
+
}
|
|
33
|
+
else if (command === 'snippet') {
|
|
34
|
+
runSnippetCommand(args.slice(1));
|
|
35
|
+
}
|
|
27
36
|
else if (command === 'theme') {
|
|
28
37
|
runTheme(args.slice(1));
|
|
29
38
|
}
|
|
@@ -73,7 +82,9 @@ Commands:
|
|
|
73
82
|
contracts [options] Generate structure contracts from theme config
|
|
74
83
|
i18n <subcommand> i18n tooling (extract translation keys, check coverage)
|
|
75
84
|
scaffold-css Generate CSS stub files for all runes
|
|
76
|
-
validate Validate
|
|
85
|
+
validate Validate this project's sites (config + content)
|
|
86
|
+
stale Rank documentation references by how far their target has moved
|
|
87
|
+
snippet review Stamp and check review markers on embedded source
|
|
77
88
|
theme <subcommand> Manage themes (install, info)
|
|
78
89
|
edit Launch the browser-based content editor
|
|
79
90
|
reference <subcommand> Emit rune syntax reference for authors and AI agents
|
|
@@ -123,12 +134,16 @@ Scaffold-CSS Options:
|
|
|
123
134
|
--force Overwrite existing files
|
|
124
135
|
|
|
125
136
|
Validate Options:
|
|
126
|
-
--
|
|
127
|
-
--
|
|
137
|
+
--site <name> Restrict to one site from refrakt.config.json
|
|
138
|
+
--only <content|config> Narrow to one layer (both run when absent)
|
|
139
|
+
--deep Add cross-page checks (costs a full pipeline run)
|
|
140
|
+
--format <text|json> Output format (default: text)
|
|
141
|
+
--config-path <path> Path to refrakt.config.json (default: ./refrakt.config.json)
|
|
128
142
|
|
|
129
143
|
Theme Subcommands:
|
|
130
144
|
theme install <source> Install a theme (directory, .tgz, or npm package)
|
|
131
145
|
theme info Show current theme details
|
|
146
|
+
theme validate Validate a ThemeConfig and/or theme manifest
|
|
132
147
|
|
|
133
148
|
Examples:
|
|
134
149
|
refrakt inspect hint --type=warning
|
|
@@ -852,47 +867,156 @@ function runScaffoldCss(scaffoldArgs) {
|
|
|
852
867
|
});
|
|
853
868
|
}
|
|
854
869
|
function runValidate(validateArgs) {
|
|
870
|
+
let site;
|
|
871
|
+
let only;
|
|
872
|
+
let deep = false;
|
|
873
|
+
let format;
|
|
855
874
|
let configPath;
|
|
856
|
-
let manifestPath;
|
|
857
875
|
for (let i = 0; i < validateArgs.length; i++) {
|
|
858
876
|
const arg = validateArgs[i];
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
877
|
+
// SPEC-135 D2 / D12 — retired rather than aliased through a deprecation
|
|
878
|
+
// window. These check theme-authoring artifacts, and they now live in the
|
|
879
|
+
// noun group that owns them. Pre-1.0, and the behaviour they hung off was
|
|
880
|
+
// close to a no-op, so nobody can be meaningfully depending on it; an
|
|
881
|
+
// alias would keep the audience confusion alive for no one's benefit.
|
|
882
|
+
if (arg === '--config' || arg === '--manifest') {
|
|
883
|
+
console.error(`Error: \`${arg}\` has moved to \`refrakt theme validate\`.\n`);
|
|
884
|
+
console.error(` refrakt theme validate ${arg} ${validateArgs[i + 1] ?? '<path>'}\n`);
|
|
885
|
+
console.error('It validates a theme-authoring artifact; `refrakt validate` is the');
|
|
886
|
+
console.error("site author's command. See SPEC-135 D12.");
|
|
887
|
+
process.exit(1);
|
|
888
|
+
}
|
|
889
|
+
else if (arg === '--site') {
|
|
890
|
+
site = validateArgs[++i];
|
|
891
|
+
if (!site) {
|
|
892
|
+
console.error('Error: --site requires a site name');
|
|
863
893
|
process.exit(1);
|
|
864
894
|
}
|
|
865
895
|
}
|
|
866
|
-
else if (arg === '--
|
|
867
|
-
|
|
868
|
-
if (
|
|
869
|
-
console.error('Error: --
|
|
896
|
+
else if (arg === '--only') {
|
|
897
|
+
const value = validateArgs[++i];
|
|
898
|
+
if (value !== 'content' && value !== 'config') {
|
|
899
|
+
console.error('Error: --only must be "content" or "config"');
|
|
870
900
|
process.exit(1);
|
|
871
901
|
}
|
|
902
|
+
only = value;
|
|
872
903
|
}
|
|
873
|
-
else if (arg === '--
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
904
|
+
else if (arg === '--deep') {
|
|
905
|
+
deep = true;
|
|
906
|
+
}
|
|
907
|
+
else if (arg === '--format') {
|
|
908
|
+
const value = validateArgs[++i];
|
|
909
|
+
if (value !== 'text' && value !== 'json') {
|
|
910
|
+
console.error('Error: --format must be "text" or "json"');
|
|
911
|
+
process.exit(1);
|
|
912
|
+
}
|
|
913
|
+
format = value;
|
|
914
|
+
}
|
|
915
|
+
else if (arg === '--config-path') {
|
|
916
|
+
configPath = validateArgs[++i];
|
|
917
|
+
if (!configPath) {
|
|
918
|
+
console.error('Error: --config-path requires a file path');
|
|
919
|
+
process.exit(1);
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
else if (arg === '--strict') {
|
|
923
|
+
// SPEC-135 D3 — deliberately absent. `site/` carries 35 warnings, and
|
|
924
|
+
// a gate that goes red on day one is a gate someone turns off. The
|
|
925
|
+
// severity levels already say which findings are worth stopping for.
|
|
926
|
+
console.error('Error: `--strict` does not exist. Warnings never affect the exit code.\n');
|
|
927
|
+
console.error('Severity already says which findings stop a build: errors fail, warnings');
|
|
928
|
+
console.error('do not. See SPEC-135 D3.');
|
|
929
|
+
process.exit(1);
|
|
877
930
|
}
|
|
878
931
|
else if (arg === '--help' || arg === '-h') {
|
|
879
|
-
|
|
932
|
+
printValidateUsage();
|
|
880
933
|
process.exit(0);
|
|
881
934
|
}
|
|
882
935
|
else if (arg.startsWith('-')) {
|
|
883
936
|
console.error(`Error: Unknown flag "${arg}"\n`);
|
|
884
|
-
|
|
937
|
+
printValidateUsage();
|
|
885
938
|
process.exit(1);
|
|
886
939
|
}
|
|
887
940
|
else {
|
|
888
941
|
console.error(`Error: Unexpected argument "${arg}"\n`);
|
|
889
|
-
|
|
942
|
+
printValidateUsage();
|
|
890
943
|
process.exit(1);
|
|
891
944
|
}
|
|
892
945
|
}
|
|
893
946
|
import('./commands/validate.js')
|
|
894
|
-
.then(({ validateCommand }) => {
|
|
895
|
-
|
|
947
|
+
.then(({ validateCommand }) => validateCommand({ site, only, deep, format, configPath }))
|
|
948
|
+
.catch((err) => {
|
|
949
|
+
console.error(`\nError: ${err.message}`);
|
|
950
|
+
process.exit(1);
|
|
951
|
+
});
|
|
952
|
+
}
|
|
953
|
+
function printValidateUsage() {
|
|
954
|
+
console.log(`
|
|
955
|
+
Usage: refrakt validate [options]
|
|
956
|
+
|
|
957
|
+
Validate this project's sites: config resolution, then content, for every site
|
|
958
|
+
in refrakt.config.json.
|
|
959
|
+
|
|
960
|
+
Options:
|
|
961
|
+
--site <name> Restrict to one site
|
|
962
|
+
--only <what> "content" or "config" (both run when absent)
|
|
963
|
+
--deep Add cross-page checks (broken refs, missing entities).
|
|
964
|
+
Costs a full pipeline run; off by default.
|
|
965
|
+
--format <fmt> "text" (default) or "json"
|
|
966
|
+
--config-path <p> Path to refrakt.config.json (default: ./refrakt.config.json)
|
|
967
|
+
|
|
968
|
+
Exit code is non-zero when any finding is at error severity, zero otherwise.
|
|
969
|
+
Warnings never affect it.
|
|
970
|
+
|
|
971
|
+
For theme-authoring artifacts, use \`refrakt theme validate\`.
|
|
972
|
+
`);
|
|
973
|
+
}
|
|
974
|
+
/** `refrakt theme validate` — the theme-authoring checks, moved off the bare
|
|
975
|
+
* `validate` command by WORK-579 (SPEC-135 D12). */
|
|
976
|
+
function runThemeValidate(tvArgs) {
|
|
977
|
+
let configPath;
|
|
978
|
+
let manifestPath;
|
|
979
|
+
for (let i = 0; i < tvArgs.length; i++) {
|
|
980
|
+
const arg = tvArgs[i];
|
|
981
|
+
if (arg === '--config') {
|
|
982
|
+
configPath = tvArgs[++i];
|
|
983
|
+
if (!configPath) {
|
|
984
|
+
console.error('Error: --config requires a file path');
|
|
985
|
+
process.exit(1);
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
else if (arg === '--manifest') {
|
|
989
|
+
manifestPath = tvArgs[++i];
|
|
990
|
+
if (!manifestPath) {
|
|
991
|
+
console.error('Error: --manifest requires a file path');
|
|
992
|
+
process.exit(1);
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
else if (arg === '--help' || arg === '-h') {
|
|
996
|
+
console.log(`
|
|
997
|
+
Usage: refrakt theme validate [options]
|
|
998
|
+
|
|
999
|
+
Validate theme-authoring artifacts. For a site's own content and config, use
|
|
1000
|
+
\`refrakt validate\`.
|
|
1001
|
+
|
|
1002
|
+
Options:
|
|
1003
|
+
--config <path> Validate a ThemeConfig JSON file
|
|
1004
|
+
--manifest <path> Validate a theme manifest
|
|
1005
|
+
|
|
1006
|
+
Examples:
|
|
1007
|
+
refrakt theme validate --config ./theme.config.json
|
|
1008
|
+
refrakt theme validate --manifest ./manifest.json
|
|
1009
|
+
`);
|
|
1010
|
+
process.exit(0);
|
|
1011
|
+
}
|
|
1012
|
+
else {
|
|
1013
|
+
console.error(`Error: Unexpected argument "${arg}"\n`);
|
|
1014
|
+
process.exit(1);
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
import('./commands/theme-validate.js')
|
|
1018
|
+
.then(({ themeValidateCommand }) => {
|
|
1019
|
+
themeValidateCommand({ configPath, manifestPath });
|
|
896
1020
|
})
|
|
897
1021
|
.catch((err) => {
|
|
898
1022
|
console.error(`\nError: ${err.message}`);
|
|
@@ -961,6 +1085,7 @@ Subcommands:
|
|
|
961
1085
|
install <source> Install a theme (directory, .tgz, or npm package name)
|
|
962
1086
|
info Show current theme details
|
|
963
1087
|
list List installed themes and the active one
|
|
1088
|
+
validate Validate a ThemeConfig and/or a theme manifest
|
|
964
1089
|
presets list List presets from installed packs + the active theme
|
|
965
1090
|
presets validate Validate installed preset-pack manifests
|
|
966
1091
|
|
|
@@ -977,6 +1102,13 @@ Examples:
|
|
|
977
1102
|
`);
|
|
978
1103
|
process.exit(subcommand ? 0 : 1);
|
|
979
1104
|
}
|
|
1105
|
+
// `theme validate` — the theme-authoring checks WORK-579 moved here from the
|
|
1106
|
+
// bare `refrakt validate` (SPEC-135 D12). Dispatched before `presets` so
|
|
1107
|
+
// `theme validate` and `theme presets validate` stay distinct.
|
|
1108
|
+
if (subcommand === 'validate') {
|
|
1109
|
+
runThemeValidate(themeArgs.slice(1));
|
|
1110
|
+
return;
|
|
1111
|
+
}
|
|
980
1112
|
// `theme presets <list|validate>` — preset-pack discovery/listing (SPEC-111 §4).
|
|
981
1113
|
if (subcommand === 'presets') {
|
|
982
1114
|
const action = themeArgs[1] ?? 'list';
|
|
@@ -1424,4 +1556,271 @@ async function buildReferenceContext(runesModule, assembleThemeConfig, configDir
|
|
|
1424
1556
|
}
|
|
1425
1557
|
return { runes: allRunes, fixtures, source };
|
|
1426
1558
|
}
|
|
1559
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
1560
|
+
// `refrakt stale` — SPEC-136 / WORK-594
|
|
1561
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
1562
|
+
function runStale(staleArgs) {
|
|
1563
|
+
let top;
|
|
1564
|
+
let edgeClass;
|
|
1565
|
+
let min;
|
|
1566
|
+
let format = 'text';
|
|
1567
|
+
for (let i = 0; i < staleArgs.length; i++) {
|
|
1568
|
+
const arg = staleArgs[i];
|
|
1569
|
+
if (arg === '--top') {
|
|
1570
|
+
top = Number(staleArgs[++i]);
|
|
1571
|
+
if (!Number.isInteger(top) || top < 1) {
|
|
1572
|
+
console.error('Error: --top requires a positive integer');
|
|
1573
|
+
process.exit(1);
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
else if (arg === '--class') {
|
|
1577
|
+
edgeClass = staleArgs[++i];
|
|
1578
|
+
const known = ['declared', 'embedded', 'described-link', 'prose'];
|
|
1579
|
+
if (!edgeClass || !known.includes(edgeClass)) {
|
|
1580
|
+
console.error(`Error: --class must be one of ${known.join(', ')}`);
|
|
1581
|
+
process.exit(1);
|
|
1582
|
+
}
|
|
1583
|
+
}
|
|
1584
|
+
else if (arg === '--min') {
|
|
1585
|
+
min = Number(staleArgs[++i]);
|
|
1586
|
+
if (!Number.isInteger(min) || min < 1) {
|
|
1587
|
+
console.error('Error: --min requires a positive integer');
|
|
1588
|
+
process.exit(1);
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1591
|
+
else if (arg === '--format') {
|
|
1592
|
+
const value = staleArgs[++i];
|
|
1593
|
+
if (value !== 'text' && value !== 'json') {
|
|
1594
|
+
console.error('Error: --format must be "text" or "json"');
|
|
1595
|
+
process.exit(1);
|
|
1596
|
+
}
|
|
1597
|
+
format = value;
|
|
1598
|
+
}
|
|
1599
|
+
else if (arg === '--help' || arg === '-h') {
|
|
1600
|
+
printStaleUsage();
|
|
1601
|
+
process.exit(0);
|
|
1602
|
+
}
|
|
1603
|
+
else {
|
|
1604
|
+
console.error(`Error: Unknown argument "${arg}"\n`);
|
|
1605
|
+
printStaleUsage();
|
|
1606
|
+
process.exit(1);
|
|
1607
|
+
}
|
|
1608
|
+
}
|
|
1609
|
+
import('./commands/stale.js')
|
|
1610
|
+
.then(({ staleCommand }) => staleCommand({ top, class: edgeClass, min, format }))
|
|
1611
|
+
.catch((err) => {
|
|
1612
|
+
console.error(`\nError: ${err.message}`);
|
|
1613
|
+
process.exit(1);
|
|
1614
|
+
});
|
|
1615
|
+
}
|
|
1616
|
+
function printStaleUsage() {
|
|
1617
|
+
console.log(`
|
|
1618
|
+
Usage: refrakt stale [options]
|
|
1619
|
+
|
|
1620
|
+
Rank documentation references by how far their target has moved since the page
|
|
1621
|
+
last changed:
|
|
1622
|
+
|
|
1623
|
+
staleness = commits touching the target since the referrer last changed
|
|
1624
|
+
|
|
1625
|
+
This ranks; it never fails. Findings do not affect the exit code, deliberately:
|
|
1626
|
+
the cheapest way to turn an edge green is to edit the referring page, so a gate
|
|
1627
|
+
would train people to make trivial documentation edits to clear it, destroying
|
|
1628
|
+
the signal it measures.
|
|
1629
|
+
|
|
1630
|
+
A refusal is different and does exit non-zero. A shallow clone or a non-git tree
|
|
1631
|
+
means the tool could not measure at all, which must not look like a clean
|
|
1632
|
+
corpus.
|
|
1633
|
+
|
|
1634
|
+
Options:
|
|
1635
|
+
--top <n> Bound the output (default 10)
|
|
1636
|
+
--class <name> Narrow to one edge class: declared, embedded,
|
|
1637
|
+
described-link, prose
|
|
1638
|
+
--min <n> Floor on the commit count
|
|
1639
|
+
--format <fmt> text (default) or json
|
|
1640
|
+
-h, --help Show this help
|
|
1641
|
+
|
|
1642
|
+
Content roots come from the sites declared in refrakt.config.json, so a
|
|
1643
|
+
multi-site project is scanned whole and nothing needs a flag.
|
|
1644
|
+
|
|
1645
|
+
Two optional lists under "stale" in refrakt.config.json narrow what is measured:
|
|
1646
|
+
|
|
1647
|
+
"stale": {
|
|
1648
|
+
"archival": ["docs/migration/**", "blog/**"],
|
|
1649
|
+
"generated": ["CHANGELOG.md", "**/*.generated.json"]
|
|
1650
|
+
}
|
|
1651
|
+
|
|
1652
|
+
archival globs matched against the referring PAGE — historical records
|
|
1653
|
+
(changelogs, release notes, migration guides) that are correct as
|
|
1654
|
+
written and must never be updated when the code moves on. Matching
|
|
1655
|
+
pages contribute no edges at all, so they also stop answering the
|
|
1656
|
+
"what documents this file" query.
|
|
1657
|
+
generated globs matched against the TARGET file — artifacts that change by
|
|
1658
|
+
construction, where "commits since" measures the generator rather
|
|
1659
|
+
than any divergence.
|
|
1660
|
+
|
|
1661
|
+
Both default to empty. Neither is a place to put a page that is merely noisy: a
|
|
1662
|
+
noisy page means the extraction rule is wrong, or the page's real subject is
|
|
1663
|
+
narrower than what it mentions — say so with "documents:" in its frontmatter,
|
|
1664
|
+
which replaces every inferred edge for that page. Whatever the lists remove is
|
|
1665
|
+
counted in the report footer, so the exclusions cannot quietly grow until the
|
|
1666
|
+
report is empty.
|
|
1667
|
+
|
|
1668
|
+
Note: a zero score is the absence of evidence of staleness, not evidence of
|
|
1669
|
+
freshness. The referrer side resets on any edit to the page.
|
|
1670
|
+
`);
|
|
1671
|
+
}
|
|
1672
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
1673
|
+
// `refrakt migrate snippets` — SPEC-131 D7 / WORK-590
|
|
1674
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
1675
|
+
function runMigrateSnippets(migrateArgs) {
|
|
1676
|
+
let fix = false;
|
|
1677
|
+
let format = 'text';
|
|
1678
|
+
for (const arg of migrateArgs) {
|
|
1679
|
+
if (arg === '--fix')
|
|
1680
|
+
fix = true;
|
|
1681
|
+
else if (arg === '--format=json')
|
|
1682
|
+
format = 'json';
|
|
1683
|
+
else if (arg === '--help' || arg === '-h') {
|
|
1684
|
+
console.log(`
|
|
1685
|
+
Usage: refrakt migrate snippets [--fix]
|
|
1686
|
+
|
|
1687
|
+
Convert \`lines=\` snippet and file-ref invocations to anchors, verifying that
|
|
1688
|
+
the anchored slice is byte-identical to the line-addressed one and refusing to
|
|
1689
|
+
rewrite when it is not.
|
|
1690
|
+
|
|
1691
|
+
A refusal is information rather than an obstacle: it means the anchor engine
|
|
1692
|
+
could not reproduce the slice, which is exactly the case where a human should
|
|
1693
|
+
look at what that snippet was pointing at.
|
|
1694
|
+
|
|
1695
|
+
Fenced invocations are skipped — they are examples of the syntax, not
|
|
1696
|
+
resolvable targets, so they cannot be verified and are rewritten by hand.
|
|
1697
|
+
|
|
1698
|
+
This never stamps \`reviewed\` markers (SPEC-134 D8).
|
|
1699
|
+
|
|
1700
|
+
Options:
|
|
1701
|
+
--fix Write the rewrites (default is a dry run)
|
|
1702
|
+
--format=json Machine-readable output
|
|
1703
|
+
`);
|
|
1704
|
+
process.exit(0);
|
|
1705
|
+
}
|
|
1706
|
+
else {
|
|
1707
|
+
console.error(`Error: Unknown argument "${arg}"`);
|
|
1708
|
+
process.exit(1);
|
|
1709
|
+
}
|
|
1710
|
+
}
|
|
1711
|
+
import('./commands/migrate-snippets.js')
|
|
1712
|
+
.then(({ migrateSnippets }) => {
|
|
1713
|
+
const result = migrateSnippets({ fix, format });
|
|
1714
|
+
if (format === 'json') {
|
|
1715
|
+
console.log(JSON.stringify(result, null, 2));
|
|
1716
|
+
return;
|
|
1717
|
+
}
|
|
1718
|
+
for (const r of result.rewrites) {
|
|
1719
|
+
console.log(`${r.page}:${r.line}`);
|
|
1720
|
+
console.log(` - ${r.before}`);
|
|
1721
|
+
console.log(` + ${r.after}`);
|
|
1722
|
+
console.log('');
|
|
1723
|
+
}
|
|
1724
|
+
for (const r of result.refusals) {
|
|
1725
|
+
console.log(`REFUSED ${r.page}:${r.line}`);
|
|
1726
|
+
console.log(` ${r.invocation}`);
|
|
1727
|
+
console.log(` ${r.reason}`);
|
|
1728
|
+
console.log('');
|
|
1729
|
+
}
|
|
1730
|
+
const langs = Object.entries(result.languages)
|
|
1731
|
+
.map(([k, v]) => `${k} ${v}`)
|
|
1732
|
+
.join(', ');
|
|
1733
|
+
console.log(`${result.rewrites.length} rewritable, ${result.refusals.length} refused, ` +
|
|
1734
|
+
`${result.skippedFenced} fenced (skipped).`);
|
|
1735
|
+
if (langs)
|
|
1736
|
+
console.log(`Languages reached: ${langs}.`);
|
|
1737
|
+
if (!fix && result.rewrites.length > 0)
|
|
1738
|
+
console.log('Dry run — pass --fix to write.');
|
|
1739
|
+
})
|
|
1740
|
+
.catch((err) => {
|
|
1741
|
+
console.error(`\nError: ${err.message}`);
|
|
1742
|
+
process.exit(1);
|
|
1743
|
+
});
|
|
1744
|
+
}
|
|
1745
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
1746
|
+
// `refrakt snippet review` — SPEC-134 / WORK-591 + WORK-592
|
|
1747
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
1748
|
+
function runSnippetCommand(snippetArgs) {
|
|
1749
|
+
const sub = snippetArgs[0];
|
|
1750
|
+
if (sub !== 'review') {
|
|
1751
|
+
console.error(`Error: unknown snippet subcommand "${sub ?? ''}"\n`);
|
|
1752
|
+
printSnippetReviewUsage();
|
|
1753
|
+
process.exit(1);
|
|
1754
|
+
}
|
|
1755
|
+
const rest = snippetArgs.slice(1);
|
|
1756
|
+
let all = false;
|
|
1757
|
+
let check = false;
|
|
1758
|
+
let update = false;
|
|
1759
|
+
let interactive = false;
|
|
1760
|
+
let format = 'text';
|
|
1761
|
+
const pages = [];
|
|
1762
|
+
for (const arg of rest) {
|
|
1763
|
+
if (arg === '--all')
|
|
1764
|
+
all = true;
|
|
1765
|
+
else if (arg === '--check')
|
|
1766
|
+
check = true;
|
|
1767
|
+
else if (arg === '--update')
|
|
1768
|
+
update = true;
|
|
1769
|
+
else if (arg === '--interactive')
|
|
1770
|
+
interactive = true;
|
|
1771
|
+
else if (arg === '--format=json')
|
|
1772
|
+
format = 'json';
|
|
1773
|
+
else if (arg === '--help' || arg === '-h') {
|
|
1774
|
+
printSnippetReviewUsage();
|
|
1775
|
+
process.exit(0);
|
|
1776
|
+
}
|
|
1777
|
+
else if (arg.startsWith('-')) {
|
|
1778
|
+
console.error(`Error: Unknown flag "${arg}"\n`);
|
|
1779
|
+
printSnippetReviewUsage();
|
|
1780
|
+
process.exit(1);
|
|
1781
|
+
}
|
|
1782
|
+
else {
|
|
1783
|
+
pages.push(arg);
|
|
1784
|
+
}
|
|
1785
|
+
}
|
|
1786
|
+
import('./commands/snippet-review.js')
|
|
1787
|
+
.then(({ snippetReviewCommand }) => snippetReviewCommand({ pages, all, check, update, interactive, format }))
|
|
1788
|
+
.catch((err) => {
|
|
1789
|
+
console.error(`\nError: ${err.message}`);
|
|
1790
|
+
process.exit(1);
|
|
1791
|
+
});
|
|
1792
|
+
}
|
|
1793
|
+
function printSnippetReviewUsage() {
|
|
1794
|
+
console.log(`
|
|
1795
|
+
Usage: refrakt snippet review [pages...] [options]
|
|
1796
|
+
|
|
1797
|
+
Record that a human read a quoted region and confirmed the prose around it
|
|
1798
|
+
matched. The marker freezes nothing — the snippet still tracks HEAD and
|
|
1799
|
+
re-resolves every build. When the region changes, the marker asks for a
|
|
1800
|
+
re-read.
|
|
1801
|
+
|
|
1802
|
+
Markers are never hand-written; this command writes them.
|
|
1803
|
+
|
|
1804
|
+
refrakt snippet review site/content/runes/file-ref.md stamp unmarked
|
|
1805
|
+
refrakt snippet review --all stamp every unmarked
|
|
1806
|
+
refrakt snippet review --check report, own exit code
|
|
1807
|
+
refrakt snippet review --update --interactive re-stamp what changed
|
|
1808
|
+
|
|
1809
|
+
A change that alters the content but not its meaning — a reformat — is
|
|
1810
|
+
re-stamped without prompting, because that is provable rather than a judgement
|
|
1811
|
+
made under time pressure. Everything else is held for a human.
|
|
1812
|
+
|
|
1813
|
+
Options:
|
|
1814
|
+
--all Stamp every unmarked invocation (not every invocation)
|
|
1815
|
+
--check Report stale markers; exits non-zero when any are found
|
|
1816
|
+
--update Re-stamp what changed, showing the content diff
|
|
1817
|
+
--interactive Show each held diff one at a time
|
|
1818
|
+
--format=json Machine-readable output
|
|
1819
|
+
-h, --help Show this help
|
|
1820
|
+
|
|
1821
|
+
Adoption is deliberately selective: mark the references whose prose makes
|
|
1822
|
+
specific claims about the code beside them. Marking everything makes --check
|
|
1823
|
+
permanently noisy and trains everyone to ignore it.
|
|
1824
|
+
`);
|
|
1825
|
+
}
|
|
1427
1826
|
//# sourceMappingURL=bin.js.map
|