skillwiki 0.10.112 → 0.10.113

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.
Files changed (35) hide show
  1. package/dist/{chunk-KJG2CSYD.js → chunk-3TKNAOJH.js} +2 -2
  2. package/dist/{chunk-LOVLZNLX.js → chunk-5D5HFQ76.js} +1 -1
  3. package/dist/{chunk-APKDTEVV.js → chunk-5RHR4FEK.js} +18 -14
  4. package/dist/{chunk-EE7W3GLA.js → chunk-6VUK2FTX.js} +1 -1
  5. package/dist/{chunk-RR6VDWSI.js → chunk-CBT35FAW.js} +3 -3
  6. package/dist/{chunk-Q6EZF37H.js → chunk-FQERKMD7.js} +456 -16
  7. package/dist/{chunk-SKOLE6US.js → chunk-IJKJGQKL.js} +1 -1
  8. package/dist/{chunk-IR2DI4Y5.js → chunk-IJWZDQDH.js} +3 -3
  9. package/dist/{chunk-TKX6PSWZ.js → chunk-JL2SCLXT.js} +1 -1
  10. package/dist/{chunk-CKQPUHM2.js → chunk-K3YZESND.js} +2 -2
  11. package/dist/{chunk-DOHWNPAZ.js → chunk-OGEAFXON.js} +1 -1
  12. package/dist/{chunk-ABRYBO4T.js → chunk-OWWWO2XS.js} +3 -3
  13. package/dist/{chunk-FCA3RRNF.js → chunk-SEY4N4CT.js} +1 -1
  14. package/dist/{chunk-7POLZOFY.js → chunk-VNSZCK5V.js} +5 -2
  15. package/dist/{chunk-25OXNFDV.js → chunk-XJ5VEIH7.js} +3 -3
  16. package/dist/cli.js +534 -114
  17. package/dist/{index-projection-UNZG5UJZ.js → index-projection-RQSOEDXM.js} +5 -5
  18. package/dist/{journal-5IW3TZ5F.js → journal-V5XHBEI5.js} +3 -3
  19. package/dist/{managed-write-preflight-L7IRQ76C.js → managed-write-preflight-2BMHZWVJ.js} +7 -7
  20. package/dist/{mcp-auth-env-X5MI5IX6.js → mcp-auth-env-QONKW4EO.js} +3 -3
  21. package/dist/{migrate-RO4BJP5T.js → migrate-SRRCXI2K.js} +6 -6
  22. package/dist/{runtime-VMFYW2K3.js → runtime-LQZIG3XN.js} +4 -4
  23. package/dist/skillwiki-mcp.js +14 -14
  24. package/dist/sources-E6KHDRDE.js +10 -0
  25. package/dist/{watcher-MGHQD3UI.js → watcher-VJ3TOU6J.js} +4 -4
  26. package/package.json +1 -1
  27. package/skills/.claude-plugin/plugin.json +1 -1
  28. package/skills/.codex-plugin/plugin.json +1 -1
  29. package/skills/.cursor-plugin/plugin.json +1 -1
  30. package/skills/package.json +1 -1
  31. package/skills/skills/wiki-ingest/SKILL.md +47 -0
  32. package/skills/skills/wiki-lint/SKILL.md +7 -0
  33. package/skills/wiki-ingest/SKILL.md +47 -0
  34. package/skills/wiki-lint/SKILL.md +7 -0
  35. package/dist/sources-AOYP6ROO.js +0 -10
@@ -18,10 +18,10 @@ import {
18
18
  resolveExistingRegularFileInsideVault,
19
19
  stripFencedBlocks,
20
20
  writeLogEvent
21
- } from "./chunk-CKQPUHM2.js";
21
+ } from "./chunk-K3YZESND.js";
22
22
  import {
23
23
  buildRootIndexUniverse
24
- } from "./chunk-KJG2CSYD.js";
24
+ } from "./chunk-3TKNAOJH.js";
25
25
  import {
26
26
  extractFrontmatter,
27
27
  filterGitIgnoredRelativePaths,
@@ -34,23 +34,23 @@ import {
34
34
  scanVault,
35
35
  splitFrontmatter,
36
36
  vaultIoConcurrency
37
- } from "./chunk-TKX6PSWZ.js";
37
+ } from "./chunk-JL2SCLXT.js";
38
38
  import {
39
39
  atomicWriteText
40
- } from "./chunk-EE7W3GLA.js";
40
+ } from "./chunk-6VUK2FTX.js";
41
41
  import {
42
42
  parseDotenvFile,
43
43
  parseDotenvText,
44
44
  profileKey,
45
45
  resolveSkillwikiHome
46
- } from "./chunk-SKOLE6US.js";
46
+ } from "./chunk-IJKJGQKL.js";
47
47
  import {
48
48
  ExitCode,
49
49
  FleetManifestSchema,
50
50
  err,
51
51
  getErrorMessage,
52
52
  ok
53
- } from "./chunk-7POLZOFY.js";
53
+ } from "./chunk-VNSZCK5V.js";
54
54
 
55
55
  // src/utils/managed-write-preflight.ts
56
56
  import { existsSync as existsSync11 } from "fs";
@@ -598,7 +598,17 @@ var WARNING_ORDER = [
598
598
  "orphaned_project_pages",
599
599
  "missing_overview",
600
600
  "missing_diagram",
601
- "cycle_traps"
601
+ "cycle_traps",
602
+ "ste_sentence_length",
603
+ "ste_hedge_words",
604
+ "ste_diagram_uncertainty",
605
+ "ste_comparison_visual"
606
+ ];
607
+ var ADVISORY_WARNING_ORDER = [
608
+ "ste_sentence_length",
609
+ "ste_hedge_words",
610
+ "ste_diagram_uncertainty",
611
+ "ste_comparison_visual"
602
612
  ];
603
613
  var INFO_ORDER = [
604
614
  "bridges",
@@ -692,6 +702,15 @@ function severityForBucket(kind) {
692
702
  if (WARNING_ORDER.includes(kind)) return "warning";
693
703
  return "info";
694
704
  }
705
+ function isAdvisoryLintWarning(kind) {
706
+ return ADVISORY_WARNING_ORDER.includes(kind);
707
+ }
708
+ function lintExitCode(summary, warningBuckets) {
709
+ if (summary.errors > 0) return ExitCode.LINT_HAS_ERRORS;
710
+ const blockingWarnings = warningBuckets.filter((bucket) => !isAdvisoryLintWarning(bucket.kind)).reduce((n, bucket) => n + bucket.items.length, 0);
711
+ if (blockingWarnings > 0 || summary.info > 0) return ExitCode.LINT_HAS_WARNINGS;
712
+ return ExitCode.OK;
713
+ }
695
714
  function lintReadVault(input) {
696
715
  if (input.fix) {
697
716
  return { readPath: input.vault, readMirror: false };
@@ -766,9 +785,7 @@ function outputForOnlyBucket(input, match, fixed, unresolved, readVault = lintRe
766
785
  warnings: filtered.warning.reduce((n, b) => n + b.items.length, 0),
767
786
  info: filtered.info.reduce((n, b) => n + b.items.length, 0)
768
787
  };
769
- let exitCode = ExitCode.OK;
770
- if (summary.errors > 0) exitCode = ExitCode.LINT_HAS_ERRORS;
771
- else if (summary.warnings > 0 || summary.info > 0) exitCode = ExitCode.LINT_HAS_WARNINGS;
788
+ const exitCode = lintExitCode(summary, filtered.warning);
772
789
  const vault = lintVaultOutput(input, readVault);
773
790
  const hintLines = [
774
791
  ...readMirrorHintLines(vault),
@@ -3276,7 +3293,7 @@ function buildCliSurface() {
3276
3293
  program.command("observe").requiredOption("--text <text>").option("--kind <kind>").option("--project <slug>").option("--severity <level>").option("--capture-budget <n>").option("--wiki <name>");
3277
3294
  program.command("session-brief").option("--project <slug>").option("--write").option("--agent-memory-run-state <path>").option("--wiki <name>");
3278
3295
  program.command("memory");
3279
- program.command("ingest").requiredOption("--vault <path>").requiredOption("--type <type>").requiredOption("--title <title>").option("--tags <csv>").option("--provenance <provenance>").option("--dry-run");
3296
+ program.command("ingest").requiredOption("--vault <path>").requiredOption("--type <type>").requiredOption("--title <title>").option("--tags <csv>").option("--provenance <provenance>").option("--html").option("--dry-run");
3280
3297
  program.command("fleet");
3281
3298
  program.command("page");
3282
3299
  program.command("project-page");
@@ -3317,6 +3334,7 @@ function buildCliSurface() {
3317
3334
  tagCmd.command("reconcile").requiredOption("--page <path>").option("--from <path>").option("--tags <csv>").option("--reason <text>").option("--write").option("--wiki <name>");
3318
3335
  const pageCmd = program.commands.find((c) => c.name() === "page");
3319
3336
  pageCmd.command("publish").requiredOption("--target <path>").option("--log-note <text>").option("--write").option("--approve <token>").option("--wiki <name>");
3337
+ pageCmd.command("render-html").requiredOption("--out <file>").option("--wiki <name>");
3320
3338
  const projectPageCmd = program.commands.find((c) => c.name() === "project-page");
3321
3339
  projectPageCmd.command("publish").requiredOption("--project <slug>").requiredOption("--target <path>").option("--log-note <text>").option("--write").option("--approve <token>").option("--wiki <name>");
3322
3340
  const claimsCmd = program.commands.find((c) => c.name() === "claims");
@@ -3511,6 +3529,346 @@ function assessSourceIdentity(input) {
3511
3529
  return { status: "ok", pathSignals, sourceSignals, bodySignals, reasons };
3512
3530
  }
3513
3531
 
3532
+ // src/lint/ste.ts
3533
+ var URL_RE = /https?:\/\/[^\s)<>]+/gi;
3534
+ var CITATION_RE = /\^\[raw\/[^\]]+\]/g;
3535
+ var FENCE_OPEN = /^(\s*)(`{3,}|~{3,})(.*)$/;
3536
+ var HEADING_RE2 = /^(#{1,6})\s+(\S.*)$/;
3537
+ var ORDERED_ITEM_RE = /^(\s*)\d+\.\s+(.*)$/;
3538
+ var UNORDERED_ITEM_RE = /^(\s*)[-*+]\s+(.*)$/;
3539
+ var TABLE_ROW_RE = /^\s*\|.*\|\s*$/;
3540
+ var BLOCKQUOTE_RE = /^\s*>/;
3541
+ var LEAST_CERTAIN_RE = /^\s*\*\*Least certain:\*\*\s*$/;
3542
+ var UNCERTAINTY_HEADING_RE = /^##\s+Uncertainty\s*$/i;
3543
+ var STEPS_HEADING_RE = /^(Steps|Procedure)\b/i;
3544
+ var LEAST_CERTAIN_FOLLOWING_RE = /^\s*\*\*Least certain:\*\*\s*\n(?:[ \t]*[-*+][ \t]+\S.*\n?)+/;
3545
+ var HEDGE_PHRASES = ["appears to", "could be"];
3546
+ var HEDGE_WORDS = [
3547
+ "might",
3548
+ "may",
3549
+ "perhaps",
3550
+ "possibly",
3551
+ "probably",
3552
+ "likely",
3553
+ "seems",
3554
+ "arguably",
3555
+ "somewhat"
3556
+ ];
3557
+ var STE_PROSE_WORD_LIMIT = 25;
3558
+ var STE_INSTRUCTION_WORD_LIMIT = 20;
3559
+ function isOutputStandardV2(fm) {
3560
+ return fm.output_standard === "v2";
3561
+ }
3562
+ function stripUrlsAndCitations(text) {
3563
+ return text.replace(URL_RE, " ").replace(CITATION_RE, " ");
3564
+ }
3565
+ function countWords(text) {
3566
+ const cleaned = stripUrlsAndCitations(text).trim();
3567
+ if (!cleaned) return 0;
3568
+ return cleaned.split(/\s+/).filter(Boolean).length;
3569
+ }
3570
+ function splitSentences(text) {
3571
+ const normalized = text.replace(/\s+/g, " ").trim();
3572
+ if (!normalized) return [];
3573
+ return normalized.split(/(?<=[.!?])\s+/).map((part) => part.trim()).filter(Boolean);
3574
+ }
3575
+ function hedgePattern() {
3576
+ const phrases = HEDGE_PHRASES.map((p) => p.replace(/\s+/g, "\\s+"));
3577
+ const words = HEDGE_WORDS.map((w) => w.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
3578
+ return new RegExp(`\\b(?:${[...phrases, ...words].join("|")})\\b`, "gi");
3579
+ }
3580
+ function findHedgeMatches(text) {
3581
+ const matches = text.match(hedgePattern());
3582
+ if (!matches) return [];
3583
+ return [...new Set(matches.map((m) => m.toLowerCase().replace(/\s+/g, " ")))];
3584
+ }
3585
+ function toggleFence(line, fence) {
3586
+ const match = line.match(FENCE_OPEN);
3587
+ if (!match) return false;
3588
+ const marker = match[2];
3589
+ if (!fence.open) {
3590
+ fence.open = true;
3591
+ fence.marker = marker;
3592
+ return true;
3593
+ }
3594
+ if (marker[0] === fence.marker[0] && marker.length >= fence.marker.length && match[3].trim() === "") {
3595
+ fence.open = false;
3596
+ fence.marker = "";
3597
+ return true;
3598
+ }
3599
+ return false;
3600
+ }
3601
+ function isTableSeparator(line) {
3602
+ return /^\s*\|?\s*:?-{3,}:?\s*(\|\s*:?-{3,}:?\s*)+\|?\s*$/.test(line);
3603
+ }
3604
+ function hasMarkdownTable(body) {
3605
+ const fence = { open: false, marker: "" };
3606
+ const lines = body.split(/\r?\n/);
3607
+ for (let i = 0; i < lines.length; i++) {
3608
+ const line = lines[i];
3609
+ if (toggleFence(line, fence) || fence.open) continue;
3610
+ if (TABLE_ROW_RE.test(line) && i + 1 < lines.length && isTableSeparator(lines[i + 1])) {
3611
+ return true;
3612
+ }
3613
+ }
3614
+ return false;
3615
+ }
3616
+ function fenceLanguage(line) {
3617
+ const match = line.match(FENCE_OPEN);
3618
+ if (!match) return "";
3619
+ return match[3].trim().split(/\s+/)[0]?.toLowerCase() ?? "";
3620
+ }
3621
+ function hasMermaidBlock(body) {
3622
+ const fence = { open: false, marker: "" };
3623
+ for (const line of body.split(/\r?\n/)) {
3624
+ if (!fence.open && fenceLanguage(line) === "mermaid") return true;
3625
+ toggleFence(line, fence);
3626
+ }
3627
+ return false;
3628
+ }
3629
+ function mermaidBlocksMissingLeastCertain(body) {
3630
+ const lines = body.split(/\r?\n/);
3631
+ const fence = { open: false, marker: "" };
3632
+ let i = 0;
3633
+ while (i < lines.length) {
3634
+ const line = lines[i];
3635
+ const startingMermaid = !fence.open && fenceLanguage(line) === "mermaid";
3636
+ if (toggleFence(line, fence)) {
3637
+ if (startingMermaid) {
3638
+ i++;
3639
+ while (i < lines.length && fence.open) {
3640
+ toggleFence(lines[i], fence);
3641
+ i++;
3642
+ }
3643
+ const after = lines.slice(i).join("\n");
3644
+ if (!LEAST_CERTAIN_FOLLOWING_RE.test(after)) return true;
3645
+ continue;
3646
+ }
3647
+ i++;
3648
+ continue;
3649
+ }
3650
+ i++;
3651
+ }
3652
+ return false;
3653
+ }
3654
+ function comparisonLacksVisual(body) {
3655
+ return !hasMarkdownTable(body) && !hasMermaidBlock(body);
3656
+ }
3657
+ function headingLevel(line) {
3658
+ const match = line.match(HEADING_RE2);
3659
+ if (!match) return null;
3660
+ return { level: match[1].length, title: match[2].trim() };
3661
+ }
3662
+ function collectListItem(lines, start, markerRe) {
3663
+ const first = lines[start].replace(markerRe, "$2");
3664
+ const chunks = [first];
3665
+ let i = start + 1;
3666
+ while (i < lines.length) {
3667
+ const line = lines[i];
3668
+ if (!line.trim()) break;
3669
+ if (HEADING_RE2.test(line) || FENCE_OPEN.test(line) || ORDERED_ITEM_RE.test(line) || UNORDERED_ITEM_RE.test(line) || TABLE_ROW_RE.test(line) || BLOCKQUOTE_RE.test(line)) {
3670
+ break;
3671
+ }
3672
+ if (/^\s+\S/.test(line)) {
3673
+ chunks.push(line.trim());
3674
+ i++;
3675
+ continue;
3676
+ }
3677
+ break;
3678
+ }
3679
+ return { text: chunks.join(" "), next: i };
3680
+ }
3681
+ function findLongUnits(body) {
3682
+ const lines = body.split(/\r?\n/);
3683
+ const fence = { open: false, marker: "" };
3684
+ let underStepsUntilLevel = null;
3685
+ const findings = [];
3686
+ let paragraph = [];
3687
+ const flushParagraph = () => {
3688
+ if (paragraph.length === 0) return;
3689
+ const text = paragraph.join(" ");
3690
+ paragraph = [];
3691
+ for (const sentence of splitSentences(text)) {
3692
+ const words = countWords(sentence);
3693
+ if (words > STE_PROSE_WORD_LIMIT) {
3694
+ findings.push({ text: sentence, words, limit: STE_PROSE_WORD_LIMIT });
3695
+ }
3696
+ }
3697
+ };
3698
+ const checkInstruction = (text) => {
3699
+ const words = countWords(text);
3700
+ if (words > STE_INSTRUCTION_WORD_LIMIT) {
3701
+ findings.push({ text, words, limit: STE_INSTRUCTION_WORD_LIMIT });
3702
+ }
3703
+ };
3704
+ const checkProseChunk = (text) => {
3705
+ for (const sentence of splitSentences(text)) {
3706
+ const words = countWords(sentence);
3707
+ if (words > STE_PROSE_WORD_LIMIT) {
3708
+ findings.push({ text: sentence, words, limit: STE_PROSE_WORD_LIMIT });
3709
+ }
3710
+ }
3711
+ };
3712
+ let i = 0;
3713
+ while (i < lines.length) {
3714
+ const line = lines[i];
3715
+ if (toggleFence(line, fence)) {
3716
+ flushParagraph();
3717
+ i++;
3718
+ continue;
3719
+ }
3720
+ if (fence.open) {
3721
+ i++;
3722
+ continue;
3723
+ }
3724
+ const heading = headingLevel(line);
3725
+ if (heading) {
3726
+ flushParagraph();
3727
+ if (STEPS_HEADING_RE.test(heading.title)) {
3728
+ underStepsUntilLevel = heading.level;
3729
+ } else if (underStepsUntilLevel !== null && heading.level <= underStepsUntilLevel) {
3730
+ underStepsUntilLevel = null;
3731
+ }
3732
+ i++;
3733
+ continue;
3734
+ }
3735
+ if (BLOCKQUOTE_RE.test(line) || TABLE_ROW_RE.test(line) || isTableSeparator(line)) {
3736
+ flushParagraph();
3737
+ i++;
3738
+ continue;
3739
+ }
3740
+ const ordered = line.match(ORDERED_ITEM_RE);
3741
+ if (ordered) {
3742
+ flushParagraph();
3743
+ const item = collectListItem(lines, i, ORDERED_ITEM_RE);
3744
+ checkInstruction(item.text);
3745
+ i = item.next;
3746
+ continue;
3747
+ }
3748
+ const unordered = line.match(UNORDERED_ITEM_RE);
3749
+ if (unordered) {
3750
+ flushParagraph();
3751
+ const item = collectListItem(lines, i, UNORDERED_ITEM_RE);
3752
+ if (underStepsUntilLevel !== null) checkInstruction(item.text);
3753
+ else checkProseChunk(item.text);
3754
+ i = item.next;
3755
+ continue;
3756
+ }
3757
+ if (!line.trim()) {
3758
+ flushParagraph();
3759
+ i++;
3760
+ continue;
3761
+ }
3762
+ paragraph.push(line.trim());
3763
+ i++;
3764
+ }
3765
+ flushParagraph();
3766
+ return findings;
3767
+ }
3768
+ function hasSteSentenceLengthViolation(body) {
3769
+ return findLongUnits(body).length > 0;
3770
+ }
3771
+ function isEscapedBacktick(text, index) {
3772
+ let slashes = 0;
3773
+ for (let i = index - 1; i >= 0 && text[i] === "\\"; i--) slashes++;
3774
+ return slashes % 2 === 1;
3775
+ }
3776
+ function backtickRunLength(text, index) {
3777
+ let n = 0;
3778
+ while (index + n < text.length && text[index + n] === "`") n++;
3779
+ return n;
3780
+ }
3781
+ function stripInlineCodeSpans(text) {
3782
+ let out = "";
3783
+ let i = 0;
3784
+ while (i < text.length) {
3785
+ if (text[i] === "`" && !isEscapedBacktick(text, i)) {
3786
+ const n = backtickRunLength(text, i);
3787
+ let j = i + n;
3788
+ let closed = false;
3789
+ while (j < text.length) {
3790
+ if (text[j] === "`") {
3791
+ const m = backtickRunLength(text, j);
3792
+ if (m === n) {
3793
+ out += " ";
3794
+ i = j + m;
3795
+ closed = true;
3796
+ break;
3797
+ }
3798
+ j += m;
3799
+ continue;
3800
+ }
3801
+ j++;
3802
+ }
3803
+ if (!closed) {
3804
+ out += text.slice(i, i + n);
3805
+ i += n;
3806
+ }
3807
+ continue;
3808
+ }
3809
+ out += text[i];
3810
+ i++;
3811
+ }
3812
+ return out;
3813
+ }
3814
+ function isLeastCertainListItemLine(line) {
3815
+ return UNORDERED_ITEM_RE.test(line) || ORDERED_ITEM_RE.test(line) || /^\s+\S/.test(line);
3816
+ }
3817
+ function findHedgesOutsideAllowedRegions(body) {
3818
+ const lines = body.split(/\r?\n/);
3819
+ const fence = { open: false, marker: "" };
3820
+ let uncertaintyUntilLevel = null;
3821
+ let skippingLeastCertainList = false;
3822
+ let leastCertainSawBlank = false;
3823
+ const found = [];
3824
+ const endLeastCertainList = () => {
3825
+ skippingLeastCertainList = false;
3826
+ leastCertainSawBlank = false;
3827
+ };
3828
+ for (const line of lines) {
3829
+ if (toggleFence(line, fence)) {
3830
+ endLeastCertainList();
3831
+ continue;
3832
+ }
3833
+ if (fence.open) continue;
3834
+ const heading = headingLevel(line);
3835
+ if (heading) {
3836
+ endLeastCertainList();
3837
+ if (UNCERTAINTY_HEADING_RE.test(line)) {
3838
+ uncertaintyUntilLevel = heading.level;
3839
+ } else if (uncertaintyUntilLevel !== null && heading.level <= uncertaintyUntilLevel) {
3840
+ uncertaintyUntilLevel = null;
3841
+ }
3842
+ continue;
3843
+ }
3844
+ if (uncertaintyUntilLevel !== null || BLOCKQUOTE_RE.test(line)) {
3845
+ endLeastCertainList();
3846
+ continue;
3847
+ }
3848
+ if (LEAST_CERTAIN_RE.test(line)) {
3849
+ skippingLeastCertainList = true;
3850
+ leastCertainSawBlank = false;
3851
+ continue;
3852
+ }
3853
+ if (skippingLeastCertainList) {
3854
+ if (!line.trim()) {
3855
+ leastCertainSawBlank = true;
3856
+ continue;
3857
+ }
3858
+ if (isLeastCertainListItemLine(line) || !leastCertainSawBlank) {
3859
+ leastCertainSawBlank = false;
3860
+ continue;
3861
+ }
3862
+ endLeastCertainList();
3863
+ }
3864
+ found.push(...findHedgeMatches(stripInlineCodeSpans(line)));
3865
+ }
3866
+ return [...new Set(found)];
3867
+ }
3868
+ function hasSteHedgeViolation(body) {
3869
+ return findHedgesOutsideAllowedRegions(body).length > 0;
3870
+ }
3871
+
3514
3872
  // src/lint/rules.ts
3515
3873
  async function collectCliRefsPages(vault) {
3516
3874
  if (!existsSync4(join13(vault, "SCHEMA.md"))) {
@@ -4934,6 +5292,83 @@ var cycleTrapsRule = {
4934
5292
  return { buckets };
4935
5293
  }
4936
5294
  };
5295
+ var steSentenceLengthRule = {
5296
+ id: "ste_sentence_length",
5297
+ severity: "warning",
5298
+ async run(ctx) {
5299
+ const items = [];
5300
+ await mapWithConcurrency(ctx.scan.typedKnowledge, vaultIoConcurrency(), async (page) => {
5301
+ try {
5302
+ const text = await readPageCached(page, ctx.pageTextCache);
5303
+ const fm = extractFrontmatter(text);
5304
+ if (!fm.ok || !isOutputStandardV2(fm.data)) return;
5305
+ const split = splitFrontmatter(text);
5306
+ if (!split.ok) return;
5307
+ if (hasSteSentenceLengthViolation(split.data.body)) items.push(page.relPath);
5308
+ } catch {
5309
+ }
5310
+ });
5311
+ return { buckets: items.length > 0 ? { ste_sentence_length: items } : {} };
5312
+ }
5313
+ };
5314
+ var steHedgeWordsRule = {
5315
+ id: "ste_hedge_words",
5316
+ severity: "warning",
5317
+ async run(ctx) {
5318
+ const items = [];
5319
+ await mapWithConcurrency(ctx.scan.typedKnowledge, vaultIoConcurrency(), async (page) => {
5320
+ try {
5321
+ const text = await readPageCached(page, ctx.pageTextCache);
5322
+ const fm = extractFrontmatter(text);
5323
+ if (!fm.ok || !isOutputStandardV2(fm.data)) return;
5324
+ const split = splitFrontmatter(text);
5325
+ if (!split.ok) return;
5326
+ if (hasSteHedgeViolation(split.data.body)) items.push(page.relPath);
5327
+ } catch {
5328
+ }
5329
+ });
5330
+ return { buckets: items.length > 0 ? { ste_hedge_words: items } : {} };
5331
+ }
5332
+ };
5333
+ var steDiagramUncertaintyRule = {
5334
+ id: "ste_diagram_uncertainty",
5335
+ severity: "warning",
5336
+ async run(ctx) {
5337
+ const items = [];
5338
+ await mapWithConcurrency(ctx.scan.typedKnowledge, vaultIoConcurrency(), async (page) => {
5339
+ try {
5340
+ const text = await readPageCached(page, ctx.pageTextCache);
5341
+ const fm = extractFrontmatter(text);
5342
+ if (!fm.ok || !isOutputStandardV2(fm.data)) return;
5343
+ const split = splitFrontmatter(text);
5344
+ if (!split.ok) return;
5345
+ if (mermaidBlocksMissingLeastCertain(split.data.body)) items.push(page.relPath);
5346
+ } catch {
5347
+ }
5348
+ });
5349
+ return { buckets: items.length > 0 ? { ste_diagram_uncertainty: items } : {} };
5350
+ }
5351
+ };
5352
+ var steComparisonVisualRule = {
5353
+ id: "ste_comparison_visual",
5354
+ severity: "warning",
5355
+ async run(ctx) {
5356
+ const items = [];
5357
+ await mapWithConcurrency(ctx.scan.typedKnowledge, vaultIoConcurrency(), async (page) => {
5358
+ try {
5359
+ const text = await readPageCached(page, ctx.pageTextCache);
5360
+ const fm = extractFrontmatter(text);
5361
+ if (!fm.ok || !isOutputStandardV2(fm.data)) return;
5362
+ if (fm.data.type !== "comparison") return;
5363
+ const split = splitFrontmatter(text);
5364
+ if (!split.ok) return;
5365
+ if (comparisonLacksVisual(split.data.body)) items.push(page.relPath);
5366
+ } catch {
5367
+ }
5368
+ });
5369
+ return { buckets: items.length > 0 ? { ste_comparison_visual: items } : {} };
5370
+ }
5371
+ };
4937
5372
  var LINT_RULES = [
4938
5373
  brokenWikilinksRule,
4939
5374
  tagNotInTaxonomyRule,
@@ -4968,7 +5403,11 @@ var LINT_RULES = [
4968
5403
  orphanedProjectPagesRule,
4969
5404
  cliRefsRule,
4970
5405
  staleSectionsRule,
4971
- cycleTrapsRule
5406
+ cycleTrapsRule,
5407
+ steSentenceLengthRule,
5408
+ steHedgeWordsRule,
5409
+ steDiagramUncertaintyRule,
5410
+ steComparisonVisualRule
4972
5411
  ];
4973
5412
 
4974
5413
  // src/utils/git-archive.ts
@@ -5118,9 +5557,7 @@ var LintRunner = class {
5118
5557
  warnings: warningOut.reduce((n, b) => n + b.items.length, 0),
5119
5558
  info: infoOut.reduce((n, b) => n + b.items.length, 0)
5120
5559
  };
5121
- let exitCode = ExitCode.OK;
5122
- if (summary.errors > 0) exitCode = ExitCode.LINT_HAS_ERRORS;
5123
- else if (summary.warnings > 0 || summary.info > 0) exitCode = ExitCode.LINT_HAS_WARNINGS;
5560
+ const exitCode = lintExitCode(summary, warningOut);
5124
5561
  const vault = lintVaultOutput(input, readVault);
5125
5562
  const hintLines = [];
5126
5563
  hintLines.push(...readMirrorHintLines(vault));
@@ -6156,10 +6593,12 @@ async function runSyncPull(input) {
6156
6593
  const pathFixCount = pathFix.result.ok ? pathFix.result.data.fixed.length : 0;
6157
6594
  let lintErrors = 0;
6158
6595
  let lintWarnings = 0;
6596
+ let blockingLintWarnings = 0;
6159
6597
  const lintResult = await runLint({ vault, days: 90, lines: 200, logThreshold: 500 });
6160
6598
  if (lintResult.result.ok) {
6161
6599
  lintErrors = lintResult.result.data.summary.errors;
6162
6600
  lintWarnings = lintResult.result.data.summary.warnings;
6601
+ blockingLintWarnings = lintResult.result.data.by_severity.warning.filter((bucket) => !isAdvisoryLintWarning(bucket.kind)).reduce((n, bucket) => n + bucket.items.length, 0);
6163
6602
  }
6164
6603
  const hintParts = [];
6165
6604
  if (filesUpdated > 0) hintParts.push(`updated ${filesUpdated} file(s)`);
@@ -6167,7 +6606,7 @@ async function runSyncPull(input) {
6167
6606
  if (pathFixCount > 0) hintParts.push(`${pathFixCount} long path(s) fixed`);
6168
6607
  if (lintErrors > 0) hintParts.push(`${lintErrors} lint error(s)`);
6169
6608
  if (lintWarnings > 0) hintParts.push(`${lintWarnings} lint warning(s)`);
6170
- const exitCode = lintErrors > 0 ? ExitCode.LINT_HAS_ERRORS : lintWarnings > 0 ? ExitCode.LINT_HAS_WARNINGS : ExitCode.OK;
6609
+ const exitCode = lintErrors > 0 ? ExitCode.LINT_HAS_ERRORS : blockingLintWarnings > 0 ? ExitCode.LINT_HAS_WARNINGS : ExitCode.OK;
6171
6610
  return {
6172
6611
  exitCode,
6173
6612
  result: ok({
@@ -7280,6 +7719,7 @@ export {
7280
7719
  louvain,
7281
7720
  communityCohesion,
7282
7721
  extractIssuePage,
7722
+ isAdvisoryLintWarning,
7283
7723
  extractGitTree,
7284
7724
  runLinks,
7285
7725
  extractTaxonomy,
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  isClipOutboxKey,
4
4
  isVaultSyncKey
5
- } from "./chunk-7POLZOFY.js";
5
+ } from "./chunk-VNSZCK5V.js";
6
6
 
7
7
  // src/utils/home.ts
8
8
  import { homedir } from "os";
@@ -2,14 +2,14 @@
2
2
  import {
3
3
  ROOT_INDEX_SECTION_ORDER,
4
4
  buildRootIndexUniverse
5
- } from "./chunk-KJG2CSYD.js";
5
+ } from "./chunk-3TKNAOJH.js";
6
6
  import {
7
7
  atomicWriteText
8
- } from "./chunk-EE7W3GLA.js";
8
+ } from "./chunk-6VUK2FTX.js";
9
9
  import {
10
10
  err,
11
11
  ok
12
- } from "./chunk-7POLZOFY.js";
12
+ } from "./chunk-VNSZCK5V.js";
13
13
 
14
14
  // src/utils/index-projection.ts
15
15
  import { readFile } from "fs/promises";
@@ -3,7 +3,7 @@ import {
3
3
  err,
4
4
  getErrorMessage,
5
5
  ok
6
- } from "./chunk-7POLZOFY.js";
6
+ } from "./chunk-VNSZCK5V.js";
7
7
 
8
8
  // src/parsers/frontmatter.ts
9
9
  import yaml from "js-yaml";
@@ -4,11 +4,11 @@ import {
4
4
  readPage,
5
5
  scanSensitiveContent,
6
6
  splitFrontmatter
7
- } from "./chunk-TKX6PSWZ.js";
7
+ } from "./chunk-JL2SCLXT.js";
8
8
  import {
9
9
  err,
10
10
  ok
11
- } from "./chunk-7POLZOFY.js";
11
+ } from "./chunk-VNSZCK5V.js";
12
12
 
13
13
  // src/utils/vault-path-safety.ts
14
14
  import { lstatSync, realpathSync } from "fs";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  parseDotenvFile,
4
4
  resolveSkillwikiHome
5
- } from "./chunk-SKOLE6US.js";
5
+ } from "./chunk-IJKJGQKL.js";
6
6
 
7
7
  // src/utils/mcp-auth-env.ts
8
8
  import { join } from "path";
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  defaultLookup
4
- } from "./chunk-LOVLZNLX.js";
4
+ } from "./chunk-5D5HFQ76.js";
5
5
  import {
6
6
  parseDotenvFile,
7
7
  resolveSkillwikiHome
8
- } from "./chunk-SKOLE6US.js";
8
+ } from "./chunk-IJKJGQKL.js";
9
9
  import {
10
10
  CLIP_OUTBOX_DEFAULTS,
11
11
  ipv4InCidr,
12
12
  isClipOutboxKey,
13
13
  parseClipOutboxKeyValue
14
- } from "./chunk-7POLZOFY.js";
14
+ } from "./chunk-VNSZCK5V.js";
15
15
 
16
16
  // src/clip-outbox/runtime.ts
17
17
  import { existsSync as existsSync2 } from "fs";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  atomicWriteText
4
- } from "./chunk-EE7W3GLA.js";
4
+ } from "./chunk-6VUK2FTX.js";
5
5
 
6
6
  // src/clip-outbox/journal.ts
7
7
  import { mkdir, readFile, open } from "fs/promises";