@entropicwarrior/sdoc 0.2.6 → 0.2.8
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/README.md +24 -3
- package/package.json +3 -3
- package/src/sdoc.js +84 -4
package/README.md
CHANGED
|
@@ -29,8 +29,19 @@ Markdown has no formal structure — section boundaries are ambiguous, extractio
|
|
|
29
29
|
|
|
30
30
|
## Quick Start
|
|
31
31
|
|
|
32
|
+
### Install from the VS Code Marketplace
|
|
33
|
+
|
|
34
|
+
Search for **"SDOC - Docs for Human/Agent Teams"** by **Entropic Warrior MS Enfin** in the VS Code Extensions panel, or install from the command line:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
code --install-extension entropicwarrior-msenfin.vscode-sdoc
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
This gives you automatic updates. If you previously installed from a `.vsix` file, uninstall that version first to avoid conflicts.
|
|
41
|
+
|
|
42
|
+
### Build from source
|
|
43
|
+
|
|
32
44
|
```bash
|
|
33
|
-
# Build and install the VS Code extension
|
|
34
45
|
npm install
|
|
35
46
|
npm run package
|
|
36
47
|
code --install-extension dist/sdoc-*.vsix
|
|
@@ -74,7 +85,17 @@ Key resources for agents:
|
|
|
74
85
|
| [`docs/reference/sdoc-authoring.sdoc`](https://raw.githubusercontent.com/entropicwarrior/sdoc/main/docs/reference/sdoc-authoring.sdoc) | Skill document — drop into context to read/write SDOC immediately |
|
|
75
86
|
| [`lexica/specification.sdoc`](https://raw.githubusercontent.com/entropicwarrior/sdoc/main/lexica/specification.sdoc) | Formal spec with EBNF grammar |
|
|
76
87
|
|
|
77
|
-
All `.sdoc` files are designed for progressive disclosure
|
|
88
|
+
All `.sdoc` files are designed for progressive disclosure. The JavaScript API provides three functions that let agents navigate without loading entire files:
|
|
89
|
+
|
|
90
|
+
```javascript
|
|
91
|
+
const { extractAbout, listSections, extractSection } = require("@entropicwarrior/sdoc");
|
|
92
|
+
|
|
93
|
+
extractAbout(text); // ~50 tokens — what is this file about?
|
|
94
|
+
listSections(text); // ~50-100 tokens — what sections does it have?
|
|
95
|
+
extractSection(text, "error-handling"); // ~200-1000 tokens — give me just this section
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Total cost for a precise answer: ~750 tokens. The same lookup in Markdown requires loading the full file (5,000-50,000 tokens).
|
|
78
99
|
|
|
79
100
|
## Format at a Glance
|
|
80
101
|
|
|
@@ -159,7 +180,7 @@ Markdown-style images with optional width and alignment:
|
|
|
159
180
|
|
|
160
181
|
### Tables
|
|
161
182
|
|
|
162
|
-
Pipe-delimited tables with optional flags for appearance (`borderless`, `headerless`), width (`auto`, `60%`, `400px`), and alignment (`left`, `center`, `right`). All flags compose freely.
|
|
183
|
+
Pipe-delimited tables with optional flags for appearance (`borderless`, `headerless`), width (`auto`, `60%`, `400px`), and alignment (`left`, `center`, `right`). All flags compose freely. Cells starting with `=` are evaluated as formulas (`=SUM`, `=AVG`, `=COUNT`, arithmetic with A1 cell references).
|
|
163
184
|
|
|
164
185
|
### Lists
|
|
165
186
|
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@entropicwarrior/sdoc",
|
|
3
|
-
"displayName": "SDOC",
|
|
3
|
+
"displayName": "SDOC - Docs for Human/Agent Teams",
|
|
4
4
|
"description": "A plain-text documentation format with explicit brace scoping — deterministic parsing, AI-agent efficiency, and 10-50x token savings vs Markdown.",
|
|
5
|
-
"version": "0.2.
|
|
6
|
-
"publisher": "entropicwarrior",
|
|
5
|
+
"version": "0.2.8",
|
|
6
|
+
"publisher": "entropicwarrior-msenfin",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
package/src/sdoc.js
CHANGED
|
@@ -2416,6 +2416,54 @@ const DEFAULT_STYLE = `
|
|
|
2416
2416
|
pointer-events: none;
|
|
2417
2417
|
}
|
|
2418
2418
|
|
|
2419
|
+
/* Collapsible scope toggles */
|
|
2420
|
+
.sdoc-heading:has(.sdoc-toggle) {
|
|
2421
|
+
position: relative;
|
|
2422
|
+
}
|
|
2423
|
+
|
|
2424
|
+
.sdoc-toggle {
|
|
2425
|
+
position: absolute;
|
|
2426
|
+
left: -1.4em;
|
|
2427
|
+
top: 0;
|
|
2428
|
+
bottom: 0;
|
|
2429
|
+
width: 1.2em;
|
|
2430
|
+
cursor: pointer;
|
|
2431
|
+
opacity: 0;
|
|
2432
|
+
transition: opacity 0.15s;
|
|
2433
|
+
}
|
|
2434
|
+
|
|
2435
|
+
.sdoc-toggle::before {
|
|
2436
|
+
content: '';
|
|
2437
|
+
display: block;
|
|
2438
|
+
width: 0.45em;
|
|
2439
|
+
height: 0.45em;
|
|
2440
|
+
border-right: 2px solid var(--sdoc-muted);
|
|
2441
|
+
border-bottom: 2px solid var(--sdoc-muted);
|
|
2442
|
+
transition: transform 0.15s;
|
|
2443
|
+
transform: rotate(45deg);
|
|
2444
|
+
position: absolute;
|
|
2445
|
+
top: 0.18em;
|
|
2446
|
+
left: 50%;
|
|
2447
|
+
margin-left: -0.3em;
|
|
2448
|
+
}
|
|
2449
|
+
|
|
2450
|
+
.sdoc-scope:hover > .sdoc-heading > .sdoc-toggle {
|
|
2451
|
+
opacity: 1;
|
|
2452
|
+
}
|
|
2453
|
+
|
|
2454
|
+
.sdoc-scope.sdoc-collapsed > .sdoc-heading > .sdoc-toggle {
|
|
2455
|
+
opacity: 0.6;
|
|
2456
|
+
}
|
|
2457
|
+
|
|
2458
|
+
.sdoc-scope.sdoc-collapsed > .sdoc-heading > .sdoc-toggle::before {
|
|
2459
|
+
transform: rotate(-45deg);
|
|
2460
|
+
margin-left: -0.15em;
|
|
2461
|
+
}
|
|
2462
|
+
|
|
2463
|
+
.sdoc-scope.sdoc-collapsed > .sdoc-scope-children {
|
|
2464
|
+
display: none;
|
|
2465
|
+
}
|
|
2466
|
+
|
|
2419
2467
|
`;
|
|
2420
2468
|
|
|
2421
2469
|
const PRINT_STYLE = `
|
|
@@ -2447,9 +2495,12 @@ const PRINT_STYLE = `
|
|
|
2447
2495
|
html {
|
|
2448
2496
|
font-size: 80%;
|
|
2449
2497
|
}
|
|
2450
|
-
.sdoc-copy-btn {
|
|
2498
|
+
.sdoc-copy-btn, .sdoc-toggle {
|
|
2451
2499
|
display: none;
|
|
2452
2500
|
}
|
|
2501
|
+
.sdoc-scope.sdoc-collapsed > .sdoc-scope-children {
|
|
2502
|
+
display: block;
|
|
2503
|
+
}
|
|
2453
2504
|
body {
|
|
2454
2505
|
height: auto;
|
|
2455
2506
|
overflow: visible;
|
|
@@ -2476,6 +2527,10 @@ const PRINT_STYLE = `
|
|
|
2476
2527
|
}
|
|
2477
2528
|
`;
|
|
2478
2529
|
|
|
2530
|
+
const COLLAPSE_SCRIPT = `document.addEventListener("click",function(e){if(!e.target.classList.contains("sdoc-toggle"))return;e.stopPropagation();var s=e.target.closest(".sdoc-scope");if(s)s.classList.toggle("sdoc-collapsed")});`;
|
|
2531
|
+
|
|
2532
|
+
const COPY_SCRIPT = `document.addEventListener("click",function(e){if(!e.target.classList.contains("sdoc-copy-btn"))return;e.stopPropagation();e.preventDefault();var w=e.target.closest(".sdoc-code-wrap");if(!w)return;var c=w.querySelector("code");if(!c)return;var t=c.textContent;var b=e.target;if(navigator.clipboard){navigator.clipboard.writeText(t).then(function(){b.textContent="\\u2713";setTimeout(function(){b.textContent="\\u29C9"},1500)})}else{var a=document.createElement("textarea");a.value=t;a.style.position="fixed";a.style.opacity="0";document.body.appendChild(a);a.select();document.execCommand("copy");document.body.removeChild(a);b.textContent="\\u2713";setTimeout(function(){b.textContent="\\u29C9"},1500)}});`;
|
|
2533
|
+
|
|
2479
2534
|
const MERMAID_CDN = "https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js";
|
|
2480
2535
|
const KATEX_CDN_CSS = "https://cdn.jsdelivr.net/npm/katex@0.16/dist/katex.min.css";
|
|
2481
2536
|
const HLJS_CDN = "https://cdn.jsdelivr.net/npm/@highlightjs/cdn-assets@11.11.1/highlight.min.js";
|
|
@@ -2574,7 +2629,8 @@ function renderHtmlDocumentFromParsed(parsed, title, options = {}) {
|
|
|
2574
2629
|
|
|
2575
2630
|
const cssBase = options.cssOverride ?? DEFAULT_STYLE;
|
|
2576
2631
|
const cssAppend = options.cssAppend ? `\n${options.cssAppend}\n${PRINT_STYLE}` : `\n${PRINT_STYLE}`;
|
|
2577
|
-
const
|
|
2632
|
+
const builtinScript = COLLAPSE_SCRIPT + COPY_SCRIPT;
|
|
2633
|
+
const scriptTag = options.script ? `\n<script>${options.script}</script>` : `\n<script>${builtinScript}</script>`;
|
|
2578
2634
|
const mermaidTheme = options.mermaidTheme ?? "neutral";
|
|
2579
2635
|
const mermaidInit = mermaidTheme === "auto"
|
|
2580
2636
|
? `var isDark=window.matchMedia("(prefers-color-scheme:dark)").matches;mermaid.initialize({startOnLoad:true,theme:isDark?"dark":"neutral",themeCSS:".node rect, .node polygon, .node circle { rx: 4; ry: 4; }"});`
|
|
@@ -2781,8 +2837,32 @@ function firstParagraphPreview(nodes, maxLen) {
|
|
|
2781
2837
|
return "";
|
|
2782
2838
|
}
|
|
2783
2839
|
|
|
2840
|
+
/**
|
|
2841
|
+
* Recursively collect all tagged (has @id) scope nodes from the content tree.
|
|
2842
|
+
* Skips @meta and @about. Used for deep section discovery — lets MCP clients
|
|
2843
|
+
* find sections nested inside top-level scopes (e.g. @pass-terminology inside
|
|
2844
|
+
* @pedantic-review inside @writing).
|
|
2845
|
+
*/
|
|
2846
|
+
function getAllTaggedScopes(nodes) {
|
|
2847
|
+
const result = [];
|
|
2848
|
+
function walk(nodeList) {
|
|
2849
|
+
for (const node of nodeList) {
|
|
2850
|
+
if (node.type === "scope" && node.hasHeading) {
|
|
2851
|
+
const id = (node.id || "").toLowerCase();
|
|
2852
|
+
if (id !== "meta" && id !== "about") {
|
|
2853
|
+
result.push(node);
|
|
2854
|
+
}
|
|
2855
|
+
if (node.children) walk(node.children);
|
|
2856
|
+
}
|
|
2857
|
+
}
|
|
2858
|
+
}
|
|
2859
|
+
const doc = getDocumentScope(nodes);
|
|
2860
|
+
walk(doc ? doc.children : nodes);
|
|
2861
|
+
return result;
|
|
2862
|
+
}
|
|
2863
|
+
|
|
2784
2864
|
function listSections(nodes) {
|
|
2785
|
-
return
|
|
2865
|
+
return getAllTaggedScopes(nodes).map((node) => ({
|
|
2786
2866
|
id: node.id || null,
|
|
2787
2867
|
derivedId: slugify(node.title),
|
|
2788
2868
|
title: node.title,
|
|
@@ -2802,7 +2882,7 @@ function collectDataBlocks(children) {
|
|
|
2802
2882
|
}
|
|
2803
2883
|
|
|
2804
2884
|
function extractSection(nodes, sectionId) {
|
|
2805
|
-
const scopes =
|
|
2885
|
+
const scopes = getAllTaggedScopes(nodes);
|
|
2806
2886
|
|
|
2807
2887
|
function buildResult(node) {
|
|
2808
2888
|
const data = collectDataBlocks(node.children || []);
|