@docsworth/cli 0.2.0 → 0.3.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/README.md +60 -8
- package/dist/cli.js +52 -3
- package/dist/core/acl.d.ts +9 -0
- package/dist/core/acl.js +40 -6
- package/dist/core/adopt.d.ts +68 -0
- package/dist/core/adopt.js +665 -0
- package/dist/core/config.d.ts +6 -1
- package/dist/core/config.js +46 -2
- package/dist/core/edits.d.ts +13 -0
- package/dist/core/edits.js +20 -0
- package/dist/core/frontmatter.d.ts +12 -0
- package/dist/core/frontmatter.js +16 -7
- package/dist/core/gfm.d.ts +13 -0
- package/dist/core/gfm.js +244 -0
- package/dist/core/links.d.ts +82 -0
- package/dist/core/links.js +345 -0
- package/dist/core/lint.d.ts +1 -2
- package/dist/core/lint.js +40 -6
- package/dist/core/mcp/server.js +11 -2
- package/dist/core/printable.d.ts +4 -0
- package/dist/core/printable.js +16 -0
- package/dist/core/references.d.ts +38 -3
- package/dist/core/references.js +543 -41
- package/dist/core/repo.d.ts +4 -0
- package/dist/core/repo.js +3 -1
- package/dist/core/schema.d.ts +4 -0
- package/dist/core/schema.js +8 -6
- package/dist/core/search.d.ts +8 -0
- package/dist/core/search.js +34 -0
- package/dist/core/serve/server.d.ts +1 -2
- package/dist/core/serve/sessions.d.ts +5 -4
- package/dist/core/serve/sessions.js +102 -29
- package/dist/core/service.d.ts +118 -20
- package/dist/core/service.js +249 -91
- package/dist/core/stale.js +2 -1
- package/dist/core/tool-registry.js +6 -3
- package/dist/core/verify-pages.d.ts +19 -0
- package/dist/core/verify-pages.js +110 -0
- package/dist/core/version.d.ts +2 -2
- package/dist/core/version.js +2 -2
- package/dist/web/assets/index-8J-FUbb0.js +29 -0
- package/dist/web/assets/index-BGpAZzeM.css +1 -0
- package/dist/web/index.html +2 -2
- package/docs/format-spec.md +40 -2
- package/package.json +2 -2
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/bin/docsworth-mcp.mjs +1 -1
- package/dist/web/assets/index-BglLMIyN.css +0 -1
- package/dist/web/assets/index-DugFPoRu.js +0 -25
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root,:host{--dw-bg:#fbfbfa;--dw-surface:#fff;--dw-fg:#1d1d1b;--dw-muted:#6b6b66;--dw-line:#e4e3de;--dw-track:#ecebe6;--dw-accent:#2b5fa8;--dw-good:#2f7d4f;--dw-warn:#b7791f;--dw-bad:#b4442c;--dw-code:#f2f1ed;--dw-radius:8px;--dw-font:15px/1.5 system-ui, -apple-system, "Segoe UI", sans-serif;--dw-mono:13px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace;--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light}@media (prefers-color-scheme:dark){:root,:host{--dw-bg:#161615;--dw-surface:#1d1d1c;--dw-fg:#ecebe6;--dw-muted:#9a9993;--dw-line:#2c2c2a;--dw-track:#2a2a28;--dw-accent:#7aa7e8;--dw-good:#58b07c;--dw-warn:#d9a441;--dw-bad:#e0735a;--dw-code:#242422;--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}}*{box-sizing:border-box}.dw{background:var(--dw-bg);color:var(--dw-fg);font:var(--dw-font)}.dw a{color:var(--dw-accent);text-decoration:none}.dw a:hover{text-decoration:underline}.dw code{font:var(--dw-mono);background:var(--dw-code);border-radius:4px;padding:0 4px}.dw h1{margin:0 0 4px;font-size:24px;line-height:1.25}.dw h2{margin:28px 0 10px;font-size:17px}.dw-muted{color:var(--dw-muted)}.dw-num{font-variant-numeric:tabular-nums}.dw-header{border-bottom:1px solid var(--dw-line);background:var(--dw-surface);flex-wrap:wrap;align-items:center;gap:20px;padding:12px 20px;display:flex}.dw-brand{letter-spacing:-.01em;font-weight:650;color:var(--dw-fg)!important}.dw-nav{flex-wrap:wrap;gap:4px;display:flex}.dw-nav a{color:var(--dw-muted);border-radius:6px;padding:6px 10px}.dw-nav a[aria-current=page]{color:var(--dw-fg);background:var(--dw-track)}.dw-who{color:var(--dw-muted);align-items:center;gap:8px;margin-left:auto;font-size:13px;display:flex}.dw-main{max-width:1040px;margin:0 auto;padding:28px 20px 64px}.dw-sub{color:var(--dw-muted);margin:0 0 20px}.dw-save{flex-wrap:wrap;gap:8px;margin:0 0 20px;display:flex}.dw-save .dw-note{flex-basis:100%;margin:4px 0 0}.dw-tiles{grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px;display:grid}.dw-tile{border:1px solid var(--dw-line);border-radius:var(--dw-radius);background:var(--dw-surface);padding:14px 16px}.dw-tile b{font-variant-numeric:tabular-nums;font-size:28px;display:block}.dw-tile span{color:var(--dw-muted);font-size:13px}.dw-table{border-collapse:collapse;width:100%}.dw-table th,.dw-table td{text-align:left;border-bottom:1px solid var(--dw-line);vertical-align:middle;padding:8px 6px}.dw-table thead th{text-transform:uppercase;letter-spacing:.04em;color:var(--dw-muted);font-size:12px;font-weight:600}.dw-scroll{overflow-x:auto}.dw-bar{background:var(--dw-track);border-radius:4px;max-width:240px;height:8px;margin-bottom:4px;overflow:hidden}.dw-bar>span{height:100%;display:block}.dw-good{background:var(--dw-good)}.dw-warn{background:var(--dw-warn)}.dw-bad{background:var(--dw-bad)}.dw-badge{border:1px solid var(--dw-line);color:var(--dw-muted);white-space:nowrap;border-radius:999px;padding:0 7px;font-size:12px;line-height:18px;display:inline-block}.dw-badge.ok{color:var(--dw-good);border-color:currentColor}.dw-badge.warn{color:var(--dw-warn);border-color:currentColor}.dw-badge.bad{color:var(--dw-bad);border-color:currentColor}.dw-meta{color:var(--dw-muted);flex-wrap:wrap;align-items:center;gap:8px;font-size:13px;display:flex}.dw-search{gap:8px;margin-bottom:20px;display:flex}.dw-search input{flex:1}.dw-results{gap:10px;margin:0;padding:0;list-style:none;display:grid}.dw-result{border:1px solid var(--dw-line);border-radius:var(--dw-radius);background:var(--dw-surface);padding:12px 14px}.dw-result h3{margin:0 0 4px;font-size:16px}.dw-result p{color:var(--dw-muted);margin:6px 0 0;font-size:14px}.dw-excluded{border-left:3px solid var(--dw-warn);background:var(--dw-surface);margin:6px 0;padding:8px 12px}.dw-page{max-width:760px}.dw-prose{line-height:1.65}.dw-prose pre{font:var(--dw-mono);background:var(--dw-code);border-radius:var(--dw-radius);padding:12px 14px;overflow-x:auto}.dw-prose pre code{background:0 0;padding:0}.dw-prose .dw-table-scroll{margin:12px 0;overflow-x:auto}.dw-prose table{border-collapse:collapse;font-size:14px;line-height:1.45}.dw-prose th,.dw-prose td{border:1px solid var(--dw-line);text-align:left;vertical-align:top;padding:6px 10px}.dw-prose th{background:var(--dw-surface);font-weight:600}.dw-prose .dw-align-center{text-align:center}.dw-prose .dw-align-right{text-align:right}.dw-prose h1{margin-top:24px;font-size:22px}.dw-prose h2{margin-top:24px}.dw-note{border:1px solid var(--dw-line);border-left:3px solid var(--dw-warn);background:var(--dw-surface);border-radius:6px;margin:12px 0;padding:10px 12px;font-size:14px}.dw-error{border-left-color:var(--dw-bad)}.dw input,.dw select,.dw textarea,.dw button{font:inherit;color:inherit}.dw input,.dw select,.dw textarea{background:var(--dw-surface);border:1px solid var(--dw-line);border-radius:6px;width:100%;padding:8px 10px}.dw textarea{font:var(--dw-mono);resize:vertical;min-height:220px}.dw button{background:var(--dw-fg);color:var(--dw-bg);cursor:pointer;border:0;border-radius:6px;padding:8px 14px;font-weight:550}.dw button.secondary{color:var(--dw-fg);border:1px solid var(--dw-line);background:0 0}.dw button:disabled{opacity:.45;cursor:not-allowed}.dw-form{gap:14px;max-width:760px;display:grid}.dw-form label{gap:6px;font-size:14px;font-weight:550;display:grid}.dw-form .dw-row{grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px;display:grid}.dw-preview{font:var(--dw-mono);white-space:pre-wrap;background:var(--dw-code);border-radius:var(--dw-radius);max-height:260px;padding:12px 14px;overflow:auto}.dw-graph{border:1px solid var(--dw-line);border-radius:var(--dw-radius);background:var(--dw-surface);width:100%;height:auto;display:block}.dw-graph line{stroke:var(--dw-line);stroke-width:1.2px}.dw-graph circle{stroke:var(--dw-surface);stroke-width:1.5px;cursor:pointer}.dw-graph circle.dim{opacity:.35}.dw-graph text{fill:var(--dw-muted);pointer-events:none;font-size:11px}.dw-legend{color:var(--dw-muted);flex-wrap:wrap;gap:14px;margin:10px 0;font-size:13px;display:flex}.dw-teams{flex-wrap:wrap;gap:12px;margin:-8px 0 16px;font-size:14px;display:flex}.dw-swatch{vertical-align:-1px;border-radius:50%;width:10px;height:10px;margin-right:6px;display:inline-block}
|
package/dist/web/index.html
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
6
|
<title>Docsworth</title>
|
|
7
7
|
<link rel="icon" href="data:," />
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-8J-FUbb0.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="/assets/index-BGpAZzeM.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body class="dw">
|
|
12
12
|
<div id="app"></div>
|
package/docs/format-spec.md
CHANGED
|
@@ -22,6 +22,10 @@ CODEOWNERS # or .github/CODEOWNERS or docs/CODEOWNERS
|
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
Every `.md` file under the knowledge root is a page, and every page has frontmatter.
|
|
25
|
+
Inside the knowledge root, a directory whose name starts with a dot (an editor's
|
|
26
|
+
`.obsidian/`, say) is skipped, with everything in it: its files are neither pages nor lint
|
|
27
|
+
errors. The knowledge root itself is read whatever its name, and a file whose name starts
|
|
28
|
+
with a dot is a page like any other.
|
|
25
29
|
|
|
26
30
|
## Frontmatter
|
|
27
31
|
|
|
@@ -45,7 +49,30 @@ description: One sentence. # optional; used in search and compiled skills
|
|
|
45
49
|
---
|
|
46
50
|
```
|
|
47
51
|
|
|
48
|
-
Unknown fields produce a lint warning, never an error
|
|
52
|
+
Unknown fields produce a lint warning, never an error, unless the config lists them in
|
|
53
|
+
`frontmatter.extra_fields`: keys a site generator keeps there, such as Docusaurus's
|
|
54
|
+
`sidebar_position`.
|
|
55
|
+
|
|
56
|
+
## Links
|
|
57
|
+
|
|
58
|
+
Lint reads a page's links as CommonMark reads them. A `[x](y)` in code (a fenced or
|
|
59
|
+
indented block, or a code span) or in HTML is no link. A reference link counts through its
|
|
60
|
+
definition, and a definition no link uses is invisible.
|
|
61
|
+
|
|
62
|
+
A relative link must resolve inside the repo. Under the knowledge root it must name a page
|
|
63
|
+
(`.md`) or an attachment (a file with an extension, such as `diagram.png`). A link to a
|
|
64
|
+
directory, or to a file with no extension, is an error: it names no page, and a route like
|
|
65
|
+
Docusaurus's `/guides/setup` reads as one. Link the page itself (`guides/setup.md`).
|
|
66
|
+
|
|
67
|
+
A root-relative link to an attachment (`/img/x.png`) that names no file of the repo's
|
|
68
|
+
resolves in the directories `static_dirs` lists, as a docs site serves them (Docusaurus's
|
|
69
|
+
`static/`). A page never does: pages are under the knowledge root.
|
|
70
|
+
|
|
71
|
+
A root-relative link (`/docs`) is an error too when it names a directory or a file with no
|
|
72
|
+
extension outside the knowledge root, and, read from the knowledge root as a docs site
|
|
73
|
+
serves it (with or without a leading `docs/`, a number prefix, or a page's own `slug` or `id`),
|
|
74
|
+
also names a page. The repo's file and the page both answer to it. Link the one you mean,
|
|
75
|
+
with its extension.
|
|
49
76
|
|
|
50
77
|
## Ownership
|
|
51
78
|
|
|
@@ -104,6 +131,13 @@ In a page the caller can see, a reference to a page they can't see (a link in an
|
|
|
104
131
|
a URL, or its path in text) reads `[restricted page]`. A page that doesn't load counts as
|
|
105
132
|
one they can't see, and so does a link to a path under the knowledge root that is no page
|
|
106
133
|
at all: relative, or, with `github.repo` set, a GitHub URL into the repo on any branch.
|
|
134
|
+
|
|
135
|
+
Links are also read as a docs site serves them. A link to a hidden page's route reads
|
|
136
|
+
`[restricted page]` too: by its `slug`, by an `id` other than its file name, by its path
|
|
137
|
+
without number prefixes, or by its file's stem. So does a link without an extension that
|
|
138
|
+
names no page, file or directory in the repo (`/guides/gone`), for every reader. With
|
|
139
|
+
`site_url` set, a URL on the docs site counts as the route it names. A route written in
|
|
140
|
+
plain text, not as a link, is served as written.
|
|
107
141
|
See [security-model.md](security-model.md#the-one-read-path).
|
|
108
142
|
|
|
109
143
|
**`acl` isn't confidentiality.** GitHub has no per-file read permissions, so anyone with
|
|
@@ -266,7 +300,9 @@ or `applies_to` leave mirrored pages out; `owner_team` applies to them.
|
|
|
266
300
|
|
|
267
301
|
```yaml
|
|
268
302
|
format: 1
|
|
269
|
-
knowledge_root: knowledge
|
|
303
|
+
knowledge_root: knowledge # a directory in the repo, named relative to it: not . or .., not absolute, not in .git or .knowledge; a trailing slash is ignored
|
|
304
|
+
static_dirs: [website/static] # optional: directories a docs site serves at its root; lint reads /img/x.png there too
|
|
305
|
+
site_url: https://docs.example.com/docs/ # optional: where a docs site serves the pages; redaction reads a URL under it as a route
|
|
270
306
|
github:
|
|
271
307
|
org: acme # required: team owners resolve to @acme/<team>
|
|
272
308
|
repo: acme/knowledge # optional: makes GitHub the ACL authority; enables PR tools
|
|
@@ -275,6 +311,8 @@ github:
|
|
|
275
311
|
sla:
|
|
276
312
|
due_soon_days: 14
|
|
277
313
|
usage_log: true # page-id-only read log for the owner digest
|
|
314
|
+
frontmatter:
|
|
315
|
+
extra_fields: [sidebar_label, sidebar_position] # keys a site generator keeps in frontmatter; lint doesn't warn on them
|
|
278
316
|
audit_log: # attributed audit log; off unless enabled
|
|
279
317
|
enabled: true
|
|
280
318
|
dir: /var/lib/docsworth/audit # optional; default $XDG_STATE_HOME/docsworth/<repo>-<hash>/audit
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docsworth/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Git-native knowledge layer for coding agents: team-owned pages, review SLAs, a citation gate, and an MCP server agents read for free.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
"dependencies": {
|
|
62
62
|
"@modelcontextprotocol/sdk": "^1.32.2",
|
|
63
63
|
"commander": "^15.0.0",
|
|
64
|
+
"commonmark": "^0.31.2",
|
|
64
65
|
"yaml": "^2.9.1",
|
|
65
66
|
"zod": "^4.6.7"
|
|
66
67
|
},
|
|
@@ -68,7 +69,6 @@
|
|
|
68
69
|
"@mixmark-io/domino": "2.2.0",
|
|
69
70
|
"@types/commonmark": "0.27.10",
|
|
70
71
|
"@types/node": "^22.20.5",
|
|
71
|
-
"commonmark": "0.31.2",
|
|
72
72
|
"entities": "3.0.1",
|
|
73
73
|
"tsx": "^4.23.15",
|
|
74
74
|
"typescript": "^7.0.2",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "docsworth",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Team-owned, verified engineering knowledge for Claude Code: an MCP server that cites only canonical pages inside their review SLA, plus skills to draft, update and verify runbooks through PRs.",
|
|
5
5
|
"author": { "name": "docsworth" },
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -11,7 +11,7 @@ import { resolve } from "node:path";
|
|
|
11
11
|
// The npm package to run. `agent-kb` on npm belongs to another publisher and nobody owns the
|
|
12
12
|
// bare `docsworth`: never fall back to either. Kept equal to PUBLISHED_PACKAGE in
|
|
13
13
|
// src/core/version.ts by test/package-name.test.ts.
|
|
14
|
-
const PUBLISHED_PACKAGE = "@docsworth/cli@^0.
|
|
14
|
+
const PUBLISHED_PACKAGE = "@docsworth/cli@^0.3";
|
|
15
15
|
|
|
16
16
|
// The repo reaches the server in the environment, never on the command line, which Windows
|
|
17
17
|
// runs through cmd.exe: a path would split at a space there, and what follows an `&` would
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
:root,:host{--dw-bg:#fbfbfa;--dw-surface:#fff;--dw-fg:#1d1d1b;--dw-muted:#6b6b66;--dw-line:#e4e3de;--dw-track:#ecebe6;--dw-accent:#2b5fa8;--dw-good:#2f7d4f;--dw-warn:#b7791f;--dw-bad:#b4442c;--dw-code:#f2f1ed;--dw-radius:8px;--dw-font:15px/1.5 system-ui, -apple-system, "Segoe UI", sans-serif;--dw-mono:13px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace;--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light}@media (prefers-color-scheme:dark){:root,:host{--dw-bg:#161615;--dw-surface:#1d1d1c;--dw-fg:#ecebe6;--dw-muted:#9a9993;--dw-line:#2c2c2a;--dw-track:#2a2a28;--dw-accent:#7aa7e8;--dw-good:#58b07c;--dw-warn:#d9a441;--dw-bad:#e0735a;--dw-code:#242422;--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}}*{box-sizing:border-box}.dw{background:var(--dw-bg);color:var(--dw-fg);font:var(--dw-font)}.dw a{color:var(--dw-accent);text-decoration:none}.dw a:hover{text-decoration:underline}.dw code{font:var(--dw-mono);background:var(--dw-code);border-radius:4px;padding:0 4px}.dw h1{margin:0 0 4px;font-size:24px;line-height:1.25}.dw h2{margin:28px 0 10px;font-size:17px}.dw-muted{color:var(--dw-muted)}.dw-num{font-variant-numeric:tabular-nums}.dw-header{border-bottom:1px solid var(--dw-line);background:var(--dw-surface);flex-wrap:wrap;align-items:center;gap:20px;padding:12px 20px;display:flex}.dw-brand{letter-spacing:-.01em;font-weight:650;color:var(--dw-fg)!important}.dw-nav{flex-wrap:wrap;gap:4px;display:flex}.dw-nav a{color:var(--dw-muted);border-radius:6px;padding:6px 10px}.dw-nav a[aria-current=page]{color:var(--dw-fg);background:var(--dw-track)}.dw-who{color:var(--dw-muted);align-items:center;gap:8px;margin-left:auto;font-size:13px;display:flex}.dw-main{max-width:1040px;margin:0 auto;padding:28px 20px 64px}.dw-sub{color:var(--dw-muted);margin:0 0 20px}.dw-tiles{grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px;display:grid}.dw-tile{border:1px solid var(--dw-line);border-radius:var(--dw-radius);background:var(--dw-surface);padding:14px 16px}.dw-tile b{font-variant-numeric:tabular-nums;font-size:28px;display:block}.dw-tile span{color:var(--dw-muted);font-size:13px}.dw-table{border-collapse:collapse;width:100%}.dw-table th,.dw-table td{text-align:left;border-bottom:1px solid var(--dw-line);vertical-align:middle;padding:8px 6px}.dw-table thead th{text-transform:uppercase;letter-spacing:.04em;color:var(--dw-muted);font-size:12px;font-weight:600}.dw-scroll{overflow-x:auto}.dw-bar{background:var(--dw-track);border-radius:4px;max-width:240px;height:8px;margin-bottom:4px;overflow:hidden}.dw-bar>span{height:100%;display:block}.dw-good{background:var(--dw-good)}.dw-warn{background:var(--dw-warn)}.dw-bad{background:var(--dw-bad)}.dw-badge{border:1px solid var(--dw-line);color:var(--dw-muted);white-space:nowrap;border-radius:999px;padding:0 7px;font-size:12px;line-height:18px;display:inline-block}.dw-badge.ok{color:var(--dw-good);border-color:currentColor}.dw-badge.warn{color:var(--dw-warn);border-color:currentColor}.dw-badge.bad{color:var(--dw-bad);border-color:currentColor}.dw-meta{color:var(--dw-muted);flex-wrap:wrap;align-items:center;gap:8px;font-size:13px;display:flex}.dw-search{gap:8px;margin-bottom:20px;display:flex}.dw-search input{flex:1}.dw-results{gap:10px;margin:0;padding:0;list-style:none;display:grid}.dw-result{border:1px solid var(--dw-line);border-radius:var(--dw-radius);background:var(--dw-surface);padding:12px 14px}.dw-result h3{margin:0 0 4px;font-size:16px}.dw-result p{color:var(--dw-muted);margin:6px 0 0;font-size:14px}.dw-excluded{border-left:3px solid var(--dw-warn);background:var(--dw-surface);margin:6px 0;padding:8px 12px}.dw-page{max-width:760px}.dw-prose{line-height:1.65}.dw-prose pre{font:var(--dw-mono);background:var(--dw-code);border-radius:var(--dw-radius);padding:12px 14px;overflow-x:auto}.dw-prose pre code{background:0 0;padding:0}.dw-prose h1{margin-top:24px;font-size:22px}.dw-prose h2{margin-top:24px}.dw-note{border:1px solid var(--dw-line);border-left:3px solid var(--dw-warn);background:var(--dw-surface);border-radius:6px;margin:12px 0;padding:10px 12px;font-size:14px}.dw-error{border-left-color:var(--dw-bad)}.dw input,.dw select,.dw textarea,.dw button{font:inherit;color:inherit}.dw input,.dw select,.dw textarea{background:var(--dw-surface);border:1px solid var(--dw-line);border-radius:6px;width:100%;padding:8px 10px}.dw textarea{font:var(--dw-mono);resize:vertical;min-height:220px}.dw button{background:var(--dw-fg);color:var(--dw-bg);cursor:pointer;border:0;border-radius:6px;padding:8px 14px;font-weight:550}.dw button.secondary{color:var(--dw-fg);border:1px solid var(--dw-line);background:0 0}.dw button:disabled{opacity:.45;cursor:not-allowed}.dw-form{gap:14px;max-width:760px;display:grid}.dw-form label{gap:6px;font-size:14px;font-weight:550;display:grid}.dw-form .dw-row{grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px;display:grid}.dw-preview{font:var(--dw-mono);white-space:pre-wrap;background:var(--dw-code);border-radius:var(--dw-radius);max-height:260px;padding:12px 14px;overflow:auto}.dw-graph{border:1px solid var(--dw-line);border-radius:var(--dw-radius);background:var(--dw-surface);width:100%;height:560px;display:block}.dw-graph line{stroke:var(--dw-line);stroke-width:1.2px}.dw-graph circle{stroke:var(--dw-surface);stroke-width:1.5px;cursor:pointer}.dw-graph circle.dim{opacity:.35}.dw-graph text{fill:var(--dw-muted);pointer-events:none;font-size:11px}.dw-legend{color:var(--dw-muted);flex-wrap:wrap;gap:14px;margin:10px 0;font-size:13px;display:flex}.dw-swatch{vertical-align:-1px;border-radius:50%;width:10px;height:10px;margin-right:6px;display:inline-block}
|