docs-kit 1.0.7 → 1.1.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.
- checksums.yaml +4 -4
- data/README.md +86 -20
- data/app/components/docs_ui/archived_page.rb +45 -0
- data/app/components/docs_ui/brand_mark.rb +1 -2
- data/app/components/docs_ui/landing.rb +9 -18
- data/app/components/docs_ui/logo.rb +74 -0
- data/app/components/docs_ui/shell.rb +21 -1
- data/app/components/docs_ui/sidebar.rb +30 -14
- data/app/controllers/docs_kit/llms_controller.rb +8 -1
- data/app/controllers/docs_kit/mcp_controller.rb +5 -1
- data/app/controllers/docs_kit/search_controller.rb +6 -1
- data/exe/docs-kit +5 -5
- data/lib/docs_kit/brand_logo.rb +124 -0
- data/lib/docs_kit/configuration.rb +136 -4
- data/lib/docs_kit/controller.rb +11 -2
- data/lib/docs_kit/doc_version.rb +59 -0
- data/lib/docs_kit/landing_config.rb +8 -24
- data/lib/docs_kit/llms_text.rb +31 -4
- data/lib/docs_kit/markdown_export/blocks.rb +3 -2
- data/lib/docs_kit/mcp_tools.rb +2 -1
- data/lib/docs_kit/registry.rb +7 -0
- data/lib/docs_kit/scope.rb +59 -0
- data/lib/docs_kit/scoping.rb +28 -0
- data/lib/docs_kit/snapshot/entry.rb +48 -0
- data/lib/docs_kit/snapshot.rb +151 -0
- data/lib/docs_kit/templates/new_site.rb +64 -12
- data/lib/docs_kit/version.rb +1 -1
- data/lib/docs_kit.rb +3 -0
- data/lib/generators/docs_kit/install/install_generator.rb +1 -1
- data/lib/generators/docs_kit/install/templates/Dockerfile.tt +5 -5
- data/lib/generators/docs_kit/install/templates/agents_md.erb +1 -1
- data/lib/generators/docs_kit/install/templates/dockerignore +1 -0
- data/lib/generators/docs_kit/install/templates/docs_kit.rb.erb +17 -0
- data/lib/generators/docs_kit/install/templates/skill.md.erb +1 -1
- metadata +13 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b53c8fcfcdc8d5053f9019ea56edc5a1b4fce1a8760a220eb19c76a297e72d53
|
|
4
|
+
data.tar.gz: 4289ad366b8462a9617db0e696250b717c21af1a30a97126367c370452156e1d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 80f49ed3f55338303fe09ebed720679c440eaadb02a99b112b312dfebafa70b081ccbf3622f20a7a0a6b6f48771969528746465377bda9961b62ce6cf9410521
|
|
7
|
+
data.tar.gz: 3dc20bc085a7baa55b0c64098931f03d00553b26e477a606ce1fe878850d96058992cd7ef3e4cbc59bc67c1ea07eb9be26219f2d1c5f7b83a04eb22e82737c47
|
data/README.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# docs-kit
|
|
2
2
|
|
|
3
|
-
[](https://github.com/zoolutions/docs-kit/actions/workflows/ci.yml)
|
|
4
4
|
|
|
5
5
|
Shared [Phlex](https://www.phlex.fun) chrome for documentation sites built on
|
|
6
6
|
[daisyUI](https://daisyui.com). Extract the shell, sidebar, code blocks, theme
|
|
7
7
|
switcher, and page kit into one gem so multiple docs sites look identical and are
|
|
8
8
|
maintained in one place.
|
|
9
9
|
|
|
10
|
-
Reactive demos ([phlex-reactive](https://github.com/
|
|
11
|
-
and Postgres-SSE transport ([pgbus](https://github.com/
|
|
10
|
+
Reactive demos ([phlex-reactive](https://github.com/zoolutions/phlex-reactive))
|
|
11
|
+
and Postgres-SSE transport ([pgbus](https://github.com/zoolutions/pgbus)) are
|
|
12
12
|
**optional, runtime-detected** add-ons — docs-kit does not depend on them.
|
|
13
13
|
|
|
14
14
|
## What you get
|
|
@@ -137,7 +137,7 @@ fronts Puma with Thruster (`CMD ["./bin/thrust", "./bin/rails", "server"]`) for
|
|
|
137
137
|
HTTP caching, compression, and X-Sendfile — and the generator scaffolds the
|
|
138
138
|
`bin/thrust` binstub if the app lacks one, since the exec-form CMD needs the
|
|
139
139
|
file to exist in the image. Thruster listens on the routed port
|
|
140
|
-
(`HTTP_PORT=3000` —
|
|
140
|
+
(`HTTP_PORT=3000` — dash's `app_port`) and proxies to Puma on `TARGET_PORT=3001`.
|
|
141
141
|
Without thruster in the *production* bundle (absent, or only in a
|
|
142
142
|
development/test group that `BUNDLE_WITHOUT` excludes) the CMD falls back to
|
|
143
143
|
plain `rails server` — never a thrust CMD that would crash at boot.
|
|
@@ -166,6 +166,10 @@ DocsKit.configure do |c|
|
|
|
166
166
|
# once in the topbar, right after the brand. Unset (default) renders nothing.
|
|
167
167
|
c.app_link = { href: "/", label: "Back to the app" }
|
|
168
168
|
|
|
169
|
+
# Your own mark in the topbar + sidebar header instead of the text brand.
|
|
170
|
+
c.brand_logo = { paths: ["M4 2h9l5 5…Z"], viewbox: "0 0 81 45" }
|
|
171
|
+
c.topbar_brand = :mobile_only # drop the desktop duplicate (default :always)
|
|
172
|
+
|
|
169
173
|
# Repo/social links in the topbar (next to the theme switcher).
|
|
170
174
|
c.topbar_links = [
|
|
171
175
|
{ href: "https://github.com/you/phlex-reactive", label: "GitHub", icon: :github },
|
|
@@ -185,6 +189,12 @@ registry maps a heading to its authored pages (`Doc.nav_items`); a page that
|
|
|
185
189
|
isn't written yet is skipped, so there are no dead links. Register a page with
|
|
186
190
|
one line (see [Add a page](#add-a-page)) and it appears in the sidebar.
|
|
187
191
|
|
|
192
|
+
The registry's page groups ("Getting started", "REST API", …) are the top level
|
|
193
|
+
of the rendered menu — each an open, collapsible section. The heading above them
|
|
194
|
+
only appears when you register **several** headings, and then as a static label
|
|
195
|
+
(no fold): a site with one registry gets no redundant "Documentation" level, and
|
|
196
|
+
nothing in the sidebar is indented deeper than group → page.
|
|
197
|
+
|
|
188
198
|
### The two homes, the brand link, and dark code themes
|
|
189
199
|
|
|
190
200
|
These knobs cover what sites used to shim by subclassing `DocsUI::Shell` or
|
|
@@ -194,6 +204,8 @@ overriding route helpers:
|
|
|
194
204
|
|------|---------|--------------|
|
|
195
205
|
| `c.brand_href` | `"/"` | The **docs home** — the href of the topbar brand, the sidebar brand, and each page's "← Docs home" masthead link. Set it (e.g. `"/docs"`) when the docs live under a subpath, instead of subclassing `Shell` or overriding `root_path`. |
|
|
196
206
|
| `c.app_link` | `nil` | The **app home** — an opt-in `{ href:, label: }` link back to the application hosting the docs, rendered once in the topbar right after the brand (e.g. `{ href: "/", label: "Back to the app" }`). Unset renders nothing, so a standalone docs site is unchanged. External hrefs open in a new tab with `rel=noopener`. |
|
|
207
|
+
| `c.brand_logo` | `nil` | Your **brand mark**, rendered inside the brand anchor of BOTH the topbar and the sidebar header in place of the text `c.brand` (which stays the accessible name / `aria-label` fallback). Unset renders the text brand, byte-identical to before. Takes exactly one of five forms — see [The brand mark](#the-brand-mark) below. |
|
|
208
|
+
| `c.topbar_brand` | `:always` | Where the topbar renders the brand. At the drawer-pinned breakpoint (`lg:`) the sidebar brand is always visible, so the topbar copy is a duplicate — `:mobile_only` hides it there (`lg:hidden`). The default keeps today's markup verbatim. |
|
|
197
209
|
| `c.code_theme_dark` | `nil` | A second Rouge theme for **dark** daisyUI themes. `nil` keeps the single-theme behavior (fully backwards compatible). When set, `DocsUI::Code` also emits this theme's CSS scoped under `[data-theme=X] .code-highlight` for each shipped dark theme, so code blocks stay readable when the switcher flips to a dark theme. |
|
|
198
210
|
| `c.dark_themes` | daisyUI's built-in dark theme names | Which theme names count as dark for `code_theme_dark`. Intersected with `c.themes` at render time, so only shipped themes emit CSS. Override to name custom dark themes (e.g. `%w[zazu-dark]`). |
|
|
199
211
|
|
|
@@ -203,6 +215,33 @@ blocks with no JavaScript and no flash. The Rouge CSS is inlined per block
|
|
|
203
215
|
(not part of the Tailwind build), so the [theme-sync invariant](#css--the-canonical-build)
|
|
204
216
|
is unaffected — a `code_theme_dark` doesn't need a CSS rebuild.
|
|
205
217
|
|
|
218
|
+
### The brand mark
|
|
219
|
+
|
|
220
|
+
`c.brand_logo` replaces the text brand in the shell chrome (topbar + sidebar
|
|
221
|
+
header) with your own mark — no more copying private `Shell`/`Sidebar` methods
|
|
222
|
+
that go stale on upgrades. It takes **exactly one** of five forms (mixing forms,
|
|
223
|
+
or a malformed value, raises at config time):
|
|
224
|
+
|
|
225
|
+
```ruby
|
|
226
|
+
c.brand_logo = { svg: "M4 2h9l5 5…Z", viewbox: "0 0 22 24", label: "Acme" } # one path-d
|
|
227
|
+
c.brand_logo = { paths: ["M4 2…Z", "M9 7…Z"], viewbox: "0 0 81 45" } # multi-path wordmark
|
|
228
|
+
c.brand_logo = { markup: File.read("mark.svg") } # raw <svg> markup, embedded verbatim
|
|
229
|
+
c.brand_logo = { file: "app/assets/images/mark.svg" } # a .svg file, embedded inline
|
|
230
|
+
c.brand_logo = { src: "logo.png", alt: "Acme" } # an <img> from the asset pipeline
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
- The `svg:`/`paths:` forms render with `fill="currentColor"`, so the mark
|
|
234
|
+
**recolors with the active daisyUI theme**. `markup:`/`file:` are embedded
|
|
235
|
+
as-authored — use `currentColor` inside them to stay theme-adaptive. An
|
|
236
|
+
`src:` `<img>` **cannot** inherit `currentColor` and won't adapt.
|
|
237
|
+
- `markup:`/`file:` embed your own SVG verbatim (they are your site's content,
|
|
238
|
+
same trust domain as your views); both are shape-checked to be an `<svg>`
|
|
239
|
+
element at config time, and a `file:` re-reads on change in development.
|
|
240
|
+
- `label:`/`alt:` name the mark for assistive tech; unset, the mark falls back
|
|
241
|
+
to `c.brand`. The sidebar keeps the `version_badge` next to the mark.
|
|
242
|
+
- Sizing is fixed per surface (topbar `h-6`, sidebar `h-7`, landing hero `h-9`).
|
|
243
|
+
- `c.landing.logo` (the landing-hero mark) accepts the same five forms.
|
|
244
|
+
|
|
206
245
|
### Topbar links (repo & social)
|
|
207
246
|
|
|
208
247
|
Point readers at your source repo, chat, or socials from the topbar (next to the
|
|
@@ -662,7 +701,7 @@ claude mcp add --transport http docs https://your-docs.example/mcp
|
|
|
662
701
|
|
|
663
702
|
and can ask Claude to search or read your docs, which now appear as tools. The
|
|
664
703
|
JSON-RPC is stateless (each `POST` is independent — no SSE session), so it works
|
|
665
|
-
behind the existing
|
|
704
|
+
behind the existing dash/Cloudflare deploy unchanged; `GET`/`DELETE` return
|
|
666
705
|
`405`. When enabled, `/llms.txt` grows a final `## MCP` line advertising the
|
|
667
706
|
endpoint so agents discover it.
|
|
668
707
|
|
|
@@ -805,7 +844,7 @@ back to a spec.
|
|
|
805
844
|
|
|
806
845
|
```bash
|
|
807
846
|
docs-kit new my-docs # → a complete, deployable docs app
|
|
808
|
-
docs-kit new my-docs --image
|
|
847
|
+
docs-kit new my-docs --image zoolutions/my-repo --service my-repo
|
|
809
848
|
```
|
|
810
849
|
|
|
811
850
|
`docs-kit new` runs `rails new` (propshaft + importmap + turbo/stimulus, no DB)
|
|
@@ -815,7 +854,7 @@ and applies docs-kit's application template, which:
|
|
|
815
854
|
- runs `rails g docs_kit:install` (initializers, controllers, a Doc registry, a
|
|
816
855
|
sample guide page, the Bun/Tailwind build, the docs-nav Stimulus wiring),
|
|
817
856
|
- syncs the lucide icons and builds the CSS,
|
|
818
|
-
- scaffolds
|
|
857
|
+
- scaffolds dash (`config/deploy.yml`, `.dash/secrets`, an optimized
|
|
819
858
|
multi-stage `Dockerfile` + a `.dockerignore`) and a thin
|
|
820
859
|
`.github/workflows/deploy-docs.yml` that calls the reusable workflow.
|
|
821
860
|
|
|
@@ -866,7 +905,7 @@ group. Then `bundle exec rubocop` runs the docs-kit cops.
|
|
|
866
905
|
The build + deploy is defined **once** in this gem's reusable workflow
|
|
867
906
|
(`.github/workflows/deploy.yml`). `docs-kit new` scaffolds the caller for you; to
|
|
868
907
|
wire it by hand a site adds five small things and it deploys to the
|
|
869
|
-
oss-infrastructure server (
|
|
908
|
+
oss-infrastructure server (dash + GHCR + Cloudflare Tunnel).
|
|
870
909
|
|
|
871
910
|
**1. A thin caller** — `.github/workflows/deploy-docs.yml`:
|
|
872
911
|
|
|
@@ -877,46 +916,73 @@ on:
|
|
|
877
916
|
workflow_dispatch:
|
|
878
917
|
jobs:
|
|
879
918
|
deploy:
|
|
880
|
-
uses:
|
|
919
|
+
uses: zoolutions/docs-kit/.github/workflows/deploy.yml@main
|
|
881
920
|
with:
|
|
882
|
-
image:
|
|
921
|
+
image: zoolutions/<repo> # OWNER/REPO — see naming note below
|
|
883
922
|
service: <repo>
|
|
884
923
|
secrets: inherit
|
|
885
924
|
```
|
|
886
925
|
|
|
887
|
-
**2. `docs/config/deploy.yml`** — `service:` and `image:` MUST match the caller
|
|
926
|
+
**2. `docs/config/deploy.yml`** — `service:` and `image:` MUST match the caller
|
|
927
|
+
(the full file `docs-kit new` writes is in `lib/docs_kit/templates/new_site.rb`;
|
|
928
|
+
`dash docs proxy` documents every key):
|
|
888
929
|
|
|
889
930
|
```yaml
|
|
890
931
|
service: <repo>
|
|
891
|
-
image:
|
|
892
|
-
|
|
932
|
+
image: zoolutions/<repo>
|
|
933
|
+
minimum_version: 4.0.0 # dash 4: dash-proxy identity + in-place host migration
|
|
934
|
+
retain_containers: 2
|
|
935
|
+
error_pages_path: public # 502/503/504.html served during a deploy gap
|
|
936
|
+
registry: { server: ghcr.io, username: mhenrixon, password: [DASH_REGISTRY_PASSWORD] }
|
|
893
937
|
builder: { arch: amd64, context: .., dockerfile: Dockerfile } # repo root = build context
|
|
894
|
-
proxy: { host: <%= ENV["DEPLOY_DOMAIN"] %>, app_port: 3000, ssl: false, healthcheck: { path: /up } }
|
|
895
938
|
servers: { web: { hosts: [<%= ENV["DEPLOY_HOST"] %>] } }
|
|
896
939
|
ssh: { user: oss }
|
|
940
|
+
proxy:
|
|
941
|
+
host: <%= ENV["DEPLOY_DOMAIN"] %>
|
|
942
|
+
app_port: 3000
|
|
943
|
+
ssl: false # TLS terminates at Cloudflare
|
|
944
|
+
healthcheck: { path: /up, interval: 5, timeout: 30 }
|
|
945
|
+
compress: true # zstd/br/gzip at the edge
|
|
946
|
+
cache: { enabled: true, max_ttl: 300 } # stores `Cache-Control: public` responses (assets, /llms*.txt)
|
|
947
|
+
headers: { response: { set: { X-Content-Type-Options: nosniff, Referrer-Policy: strict-origin-when-cross-origin }, remove: [Server, X-Powered-By] } }
|
|
948
|
+
intercept_errors: [502, 503, 504]
|
|
949
|
+
exclude_metrics_paths: [/up]
|
|
897
950
|
```
|
|
898
951
|
|
|
952
|
+
Deliberately **not** set: `proxy.run` (`port_holder`, `log_format`, …) is
|
|
953
|
+
host-wide — every docs site on the shared host boots the same proxy, and a
|
|
954
|
+
`run:` block that differs between them makes each alternate deploy reboot it.
|
|
955
|
+
`rate_limit`/`deny_ips` need `client_ip.trusted_proxies` pinned to the tunnel's
|
|
956
|
+
address to key on visitors rather than on cloudflared; add them per site once
|
|
957
|
+
that address is known.
|
|
958
|
+
|
|
899
959
|
**3. `docs/Dockerfile`** — end the final stage with the matching label:
|
|
900
960
|
|
|
901
961
|
```dockerfile
|
|
902
962
|
LABEL service="<repo>"
|
|
903
963
|
```
|
|
904
964
|
|
|
905
|
-
**4. `docs/.
|
|
965
|
+
**4. `docs/.dash/secrets`** — `DASH_REGISTRY_PASSWORD=$DASH_REGISTRY_PASSWORD`.
|
|
906
966
|
|
|
907
967
|
**5. GitHub** — a `docs` environment with secrets `SSH_PRIVATE_KEY`,
|
|
908
968
|
`DEPLOY_HOST`, `DEPLOY_DOMAIN`. (The registry password is the auto-provided
|
|
909
969
|
`GITHUB_TOKEN` — no PAT.)
|
|
910
970
|
|
|
911
971
|
> **Naming — use the repo name, not `<repo>-docs`.** `image`/`service` must be
|
|
912
|
-
> the calling repo's `OWNER/REPO`. Pushing `ghcr.io/
|
|
972
|
+
> the calling repo's `OWNER/REPO`. Pushing `ghcr.io/zoolutions/<repo>` from the
|
|
913
973
|
> repo's own Actions run auto-links the package to the repo, so `GITHUB_TOKEN`
|
|
914
974
|
> can both push (build job) and pull (deploy) it. A different name becomes an
|
|
915
975
|
> unlinked user-scoped package `GITHUB_TOKEN` can't pull → the deploy fails.
|
|
916
976
|
|
|
917
|
-
**First deploy per host:** run `
|
|
918
|
-
any accessories (e.g. a Postgres accessory); the release workflow runs
|
|
919
|
-
`
|
|
977
|
+
**First deploy per host:** run `dash setup` (or `bin/deploy setup`) once to boot
|
|
978
|
+
any accessories (e.g. a Postgres accessory); the release workflow runs
|
|
979
|
+
`dash doctor` (a pre-flight of host, registry, proxy, ports and readiness gates)
|
|
980
|
+
and then plain `dash deploy`, which doesn't boot accessories.
|
|
981
|
+
|
|
982
|
+
**Upgrading a host to dash 4:** the first 4.x deploy renames the proxy
|
|
983
|
+
(`kamal-proxy` → `dash-proxy`, network `kamal` → `dash`, config volume copied)
|
|
984
|
+
and costs one short outage on that host while ports 80/443 change hands. It is
|
|
985
|
+
idempotent and shared by every site on the host — whichever deploys first pays it.
|
|
920
986
|
|
|
921
987
|
## CSS — the canonical build
|
|
922
988
|
|
|
@@ -1040,7 +1106,7 @@ them:
|
|
|
1040
1106
|
→ your profile → *Trusted Publishers* → *Create*, add a **pending** publisher
|
|
1041
1107
|
(works for a gem not yet pushed) with:
|
|
1042
1108
|
- Gem name: `docs-kit`
|
|
1043
|
-
- Repository: `
|
|
1109
|
+
- Repository: `zoolutions/docs-kit`
|
|
1044
1110
|
- Workflow filename: `release.yml`
|
|
1045
1111
|
- Environment: `rubygems`
|
|
1046
1112
|
2. **GitHub `rubygems` environment.** Repo *Settings → Environments → New
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module DocsUI
|
|
4
|
+
# Renders one page of an ARCHIVED documentation version — a frozen Markdown
|
|
5
|
+
# body (DocsKit::Snapshot::Entry) through today's live chrome, so archived
|
|
6
|
+
# docs get every future Shell/Sidebar/Code fix for free. The live counterpart
|
|
7
|
+
# is DocsUI::Page; this mirrors its shape with the content coming from the
|
|
8
|
+
# snapshot file instead of an authored #content method.
|
|
9
|
+
#
|
|
10
|
+
# Every kwarg defaults, so even a naive `entry.view_class.new` (a custom
|
|
11
|
+
# registry predating #renderable) renders an empty page rather than raising.
|
|
12
|
+
#
|
|
13
|
+
# NOTE (issue #61 phase 4): the "you are viewing the 1.0 docs" banner with a
|
|
14
|
+
# link to the current equivalent lands with the version switcher, not here.
|
|
15
|
+
#
|
|
16
|
+
# Deliberately does NOT include Phlex::Rails::Helpers::Routes/Request — their
|
|
17
|
+
# bodies run Rails.* at class load, which would make this class (and
|
|
18
|
+
# everything referencing it, like Snapshot::Entry#view_class) unloadable in a
|
|
19
|
+
# Rails-free render. Nothing here needs a request.
|
|
20
|
+
class ArchivedPage < Phlex::HTML
|
|
21
|
+
include DocsUI
|
|
22
|
+
|
|
23
|
+
def initialize(entry: nil)
|
|
24
|
+
@entry = entry
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def view_template
|
|
28
|
+
render DocsUI::Shell.new(title: @entry&.title) { body }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# The masthead + Markdown body — separated from the Shell wrapper so it can
|
|
32
|
+
# render (and be specced) without a Rails view context, the same seam as
|
|
33
|
+
# Shell's own topbar/theme-script specs.
|
|
34
|
+
def body
|
|
35
|
+
render DocsUI::Header.new(@entry.title) if @entry&.title
|
|
36
|
+
render DocsUI::Markdown.new(markdown_source) unless markdown_source.empty?
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def markdown_source
|
|
42
|
+
@markdown_source ||= @entry ? @entry.markdown.to_s : ""
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -19,7 +19,7 @@ module DocsUI
|
|
|
19
19
|
# token => official Simple-Icons path data (viewBox 0 0 24 24, fill rule
|
|
20
20
|
# nonzero). Sourced verbatim from simpleicons.org; each is a single <path d>.
|
|
21
21
|
# The path strings are inherently one long line each — never reflow them.
|
|
22
|
-
# rubocop:disable Layout/LineLength
|
|
22
|
+
# rubocop:disable-next Layout/LineLength
|
|
23
23
|
BRANDS = {
|
|
24
24
|
github: "M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12",
|
|
25
25
|
gitlab: "m23.6004 9.5927-.0337-.0862L20.3.9814a.851.851 0 0 0-.3362-.405.8748.8748 0 0 0-.9997.0539.8748.8748 0 0 0-.29.4399l-2.2055 6.748H7.5375l-2.2057-6.748a.8573.8573 0 0 0-.29-.4412.8748.8748 0 0 0-.9997-.0537.8585.8585 0 0 0-.3362.4049L.4332 9.5015l-.0325.0862a6.0657 6.0657 0 0 0 2.0119 7.0105l.0113.0087.03.0213 4.976 3.7264 2.462 1.8633 1.4995 1.1321a1.0085 1.0085 0 0 0 1.2197 0l1.4995-1.1321 2.4619-1.8633 5.006-3.7489.0125-.01a6.0682 6.0682 0 0 0 2.0094-7.003z",
|
|
@@ -36,7 +36,6 @@ module DocsUI
|
|
|
36
36
|
reddit: "M12 0C5.373 0 0 5.373 0 12c0 3.314 1.343 6.314 3.515 8.485l-2.286 2.286C.775 23.225 1.097 24 1.738 24H12c6.627 0 12-5.373 12-12S18.627 0 12 0Zm4.388 3.199c1.104 0 1.999.895 1.999 1.999 0 1.105-.895 2-1.999 2-.946 0-1.739-.657-1.947-1.539v.002c-1.147.162-2.032 1.15-2.032 2.341v.007c1.776.067 3.4.567 4.686 1.363.473-.363 1.064-.58 1.707-.58 1.547 0 2.802 1.254 2.802 2.802 0 1.117-.655 2.081-1.601 2.531-.088 3.256-3.637 5.876-7.997 5.876-4.361 0-7.905-2.617-7.998-5.87-.954-.447-1.614-1.415-1.614-2.538 0-1.548 1.255-2.802 2.803-2.802.645 0 1.239.218 1.712.585 1.275-.79 2.881-1.291 4.64-1.365v-.01c0-1.663 1.263-3.034 2.88-3.207.188-.911.993-1.595 1.959-1.595Zm-8.085 8.376c-.784 0-1.459.78-1.506 1.797-.047 1.016.64 1.429 1.426 1.429.786 0 1.371-.369 1.418-1.385.047-1.017-.553-1.841-1.338-1.841Zm7.406 0c-.786 0-1.385.824-1.338 1.841.047 1.017.634 1.385 1.418 1.385.785 0 1.473-.413 1.426-1.429-.046-1.017-.721-1.797-1.506-1.797Zm-3.703 4.013c-.974 0-1.907.048-2.77.135-.147.015-.241.168-.183.305.483 1.154 1.622 1.964 2.953 1.964 1.33 0 2.47-.81 2.953-1.964.057-.137-.037-.29-.184-.305-.863-.087-1.795-.135-2.769-.135Z",
|
|
37
37
|
stackoverflow: "M15.725 0l-1.72 1.277 6.39 8.588 1.716-1.277L15.725 0zm-3.94 3.418l-1.369 1.644 8.225 6.85 1.369-1.644-8.225-6.85zm-3.15 4.465l-.905 1.94 9.702 4.517.904-1.94-9.701-4.517zm-1.85 4.86l-.44 2.093 10.473 2.201.44-2.092-10.473-2.203zM1.89 15.47V24h19.19v-8.53h-2.133v6.397H4.021v-6.396H1.89zm4.265 2.133v2.13h10.66v-2.13H6.154Z"
|
|
38
38
|
}.freeze
|
|
39
|
-
# rubocop:enable Layout/LineLength
|
|
40
39
|
|
|
41
40
|
# True when `token` names a shipped brand mark (symbol or string), false for a
|
|
42
41
|
# lucide name, nil, or a blank string. The Shell uses this to decide whether a
|
|
@@ -31,9 +31,6 @@ module DocsUI
|
|
|
31
31
|
# walks the same #docs-content region Shell stamps.
|
|
32
32
|
class Landing < Phlex::HTML
|
|
33
33
|
include Phlex::Rails::Helpers::Request
|
|
34
|
-
# For the image-form hero logo (c.landing.logo = { src: … }): resolve the asset
|
|
35
|
-
# path through the site's pipeline to its digested /assets URL.
|
|
36
|
-
include Phlex::Rails::Helpers::ImageURL
|
|
37
34
|
|
|
38
35
|
def view_template
|
|
39
36
|
render DocsUI::Shell.new(title: landing.eyebrow || config.brand) do
|
|
@@ -63,20 +60,12 @@ module DocsUI
|
|
|
63
60
|
end
|
|
64
61
|
end
|
|
65
62
|
|
|
66
|
-
# The brand mark —
|
|
67
|
-
#
|
|
63
|
+
# The brand mark — the shared DocsUI::Logo renderer (any DocsKit::BrandLogo
|
|
64
|
+
# form) at hero size. Rendered above the eyebrow, like a product wordmark.
|
|
68
65
|
def logo
|
|
69
66
|
return unless (mark = landing.hero_logo)
|
|
70
67
|
|
|
71
|
-
|
|
72
|
-
svg(viewbox: mark.viewbox, class: "h-9 w-auto text-primary", fill: "currentColor",
|
|
73
|
-
role: "img", aria_label: mark.label) do |s|
|
|
74
|
-
s.title { mark.label } if mark.label
|
|
75
|
-
s.path(d: mark.svg)
|
|
76
|
-
end
|
|
77
|
-
else
|
|
78
|
-
img(src: image_url(mark.src), alt: mark.alt.to_s, class: "h-9 w-auto")
|
|
79
|
-
end
|
|
68
|
+
render DocsUI::Logo.new(mark, class: "h-9 w-auto text-primary")
|
|
80
69
|
end
|
|
81
70
|
|
|
82
71
|
def eyebrow
|
|
@@ -162,15 +151,17 @@ module DocsUI
|
|
|
162
151
|
div(class: "mt-16") do
|
|
163
152
|
h2(class: "text-sm font-semibold uppercase tracking-wide text-base-content/50") { "Documentation" }
|
|
164
153
|
div(class: "mt-6 grid gap-8 sm:grid-cols-2") do
|
|
165
|
-
|
|
154
|
+
# A lone heading would just repeat the h2 above (often literally
|
|
155
|
+
# "Documentation"), so only label the columns when there are several.
|
|
156
|
+
groups.each { |heading, items| doc_index_group(heading, items, labeled: groups.size > 1) }
|
|
166
157
|
end
|
|
167
158
|
end
|
|
168
159
|
end
|
|
169
160
|
|
|
170
|
-
def doc_index_group(heading, items)
|
|
161
|
+
def doc_index_group(heading, items, labeled:)
|
|
171
162
|
div do
|
|
172
|
-
h3(class: "text-xs font-semibold uppercase tracking-wide text-base-content/40") { heading }
|
|
173
|
-
ul(class: "mt-3 flex flex-col gap-2") do
|
|
163
|
+
h3(class: "text-xs font-semibold uppercase tracking-wide text-base-content/40") { heading } if labeled
|
|
164
|
+
ul(class: labeled ? "mt-3 flex flex-col gap-2" : "flex flex-col gap-2") do
|
|
174
165
|
items.each { |item| li { a(href: item.href, class: "link link-hover text-sm") { item.label } } }
|
|
175
166
|
end
|
|
176
167
|
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module DocsUI
|
|
4
|
+
# Renders a DocsKit::BrandLogo (config.brand_logo / config.landing.logo) as the
|
|
5
|
+
# brand mark — an inline currentColor <svg> (theme-adaptive), a verbatim
|
|
6
|
+
# site-authored <svg> embed, or an <img>.
|
|
7
|
+
#
|
|
8
|
+
# render DocsUI::Logo.new(config.brand_logo, class: "h-6 w-auto", label: config.brand)
|
|
9
|
+
#
|
|
10
|
+
# label: is the accessible-name fallback when the logo itself carries none
|
|
11
|
+
# (callers pass config.brand, so the mark always announces the site).
|
|
12
|
+
#
|
|
13
|
+
# The svg:/paths: forms emit each path-d as an ordinary Phlex-escaped
|
|
14
|
+
# attribute — config free text never bypasses the escape. The markup:/file:
|
|
15
|
+
# forms DO embed markup verbatim via raw(safe(...)): that content is the
|
|
16
|
+
# site's own deliberately-configured SVG (its initializer / its asset file —
|
|
17
|
+
# the same trust domain as the site's own views, which can already render
|
|
18
|
+
# anything), not third-party free text, and DocsKit::BrandLogo shape-checks it
|
|
19
|
+
# to be an <svg> element at config time. That authored-by-the-trusting-site
|
|
20
|
+
# rationale is the same carve-out DocsUI::BrandMark uses for its gem-authored
|
|
21
|
+
# path constants.
|
|
22
|
+
class Logo < Phlex::HTML
|
|
23
|
+
# For the src: image form — resolve the asset path through the site's
|
|
24
|
+
# pipeline to its digested /assets URL, exactly like DocsUI::Landing's img.
|
|
25
|
+
include Phlex::Rails::Helpers::ImageURL
|
|
26
|
+
|
|
27
|
+
def initialize(logo, label: nil, **attributes)
|
|
28
|
+
@logo = DocsKit::BrandLogo.from(logo)
|
|
29
|
+
@label = label
|
|
30
|
+
@attributes = attributes
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def view_template
|
|
34
|
+
if @logo.image?
|
|
35
|
+
img(src: resolved_src, alt: accessible_name.to_s, **@attributes)
|
|
36
|
+
elsif @logo.embed?
|
|
37
|
+
embedded_svg
|
|
38
|
+
else
|
|
39
|
+
inline_svg
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def accessible_name = @logo.label || @label
|
|
46
|
+
|
|
47
|
+
# The svg:/paths: forms: a currentColor mark that recolors with the active
|
|
48
|
+
# daisyUI theme; every path-d is an escaped attribute value.
|
|
49
|
+
def inline_svg
|
|
50
|
+
svg(viewBox: @logo.viewbox, fill: "currentColor", role: "img",
|
|
51
|
+
aria_label: accessible_name, **@attributes) do |s|
|
|
52
|
+
s.title { accessible_name } if accessible_name
|
|
53
|
+
@logo.paths.each { |d| s.path(d: d) }
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# The markup:/file: forms: the site's own <svg> embedded verbatim (see the
|
|
58
|
+
# class comment for the trust rationale) inside a wrapper that carries the
|
|
59
|
+
# caller's sizing — the inner svg fills it. Literal arbitrary variants so
|
|
60
|
+
# Tailwind scans them from this file.
|
|
61
|
+
def embedded_svg
|
|
62
|
+
classes = [@attributes[:class], "inline-flex [&>svg]:h-full [&>svg]:w-auto"].compact.join(" ")
|
|
63
|
+
span(role: "img", aria_label: accessible_name, **@attributes, class: classes) do
|
|
64
|
+
raw(safe(@logo.svg_markup))
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# The digested asset URL when a view context is present; off a request (an
|
|
69
|
+
# isolated render) degrade to the raw src — the DocsUI::MetaTags posture.
|
|
70
|
+
def resolved_src
|
|
71
|
+
view_context ? image_url(@logo.src) : @logo.src
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -156,7 +156,7 @@ module DocsUI
|
|
|
156
156
|
div(class: "flex-1 items-center gap-2") do
|
|
157
157
|
label(for: DRAWER_ID, class: "btn btn-square btn-ghost btn-sm lg:hidden",
|
|
158
158
|
aria_label: "Open menu") { render DocsUI::Icon.new("menu", class: "size-5") }
|
|
159
|
-
a(href: config.brand_href, class:
|
|
159
|
+
a(href: config.brand_href, class: topbar_brand_classes) { brand_mark }
|
|
160
160
|
app_home_link
|
|
161
161
|
end
|
|
162
162
|
render DocsUI::SearchBox.new if config.search_enabled?
|
|
@@ -169,6 +169,26 @@ module DocsUI
|
|
|
169
169
|
end
|
|
170
170
|
end
|
|
171
171
|
|
|
172
|
+
# The brand anchor's classes. config.topbar_brand = :mobile_only adds
|
|
173
|
+
# lg:hidden — at the drawer-pinned breakpoint the sidebar brand is already
|
|
174
|
+
# visible, so a site can drop the duplicate. The default (:always) keeps
|
|
175
|
+
# the pre-knob classes verbatim.
|
|
176
|
+
def topbar_brand_classes
|
|
177
|
+
base = "btn btn-ghost text-lg font-bold"
|
|
178
|
+
config.topbar_brand == :mobile_only ? "#{base} lg:hidden" : base
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
# The brand: the configured mark (config.brand_logo) when set, else the
|
|
182
|
+
# text brand — byte-identical to before for a site that sets nothing. The
|
|
183
|
+
# text brand stays the mark's accessible-name fallback.
|
|
184
|
+
def brand_mark
|
|
185
|
+
if (logo = config.brand_logo)
|
|
186
|
+
render DocsUI::Logo.new(logo, class: "h-6 w-auto", label: config.brand)
|
|
187
|
+
else
|
|
188
|
+
plain config.brand
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
172
192
|
# The opt-in App Home link (config.app_link) — the way back to the hosting
|
|
173
193
|
# app, rendered once, right after the brand. Nothing renders when unset, so
|
|
174
194
|
# the topbar stays byte-identical for a site that never configures it.
|
|
@@ -8,6 +8,11 @@ module DocsUI
|
|
|
8
8
|
#
|
|
9
9
|
# nav_groups is an ordered Hash:
|
|
10
10
|
# { "Heading" => { "Subgroup" => [DocsKit::NavItem, ...] } }
|
|
11
|
+
#
|
|
12
|
+
# Subgroups are the top level of the rendered menu. A lone heading (the common
|
|
13
|
+
# single-registry site) is not rendered at all — the brand masthead already
|
|
14
|
+
# labels the sidebar; with several headings, each renders as a STATIC
|
|
15
|
+
# `.menu-title` label (no fold) and only subgroups collapse.
|
|
11
16
|
class Sidebar < Phlex::HTML
|
|
12
17
|
include Phlex::Rails::Helpers::Request
|
|
13
18
|
include DaisyUI
|
|
@@ -29,7 +34,8 @@ module DocsUI
|
|
|
29
34
|
header_section
|
|
30
35
|
div(class: "flex-1 overflow-y-auto px-2 pb-6") do
|
|
31
36
|
Menu(class: "w-full gap-1") do
|
|
32
|
-
nav_groups.
|
|
37
|
+
groups = nav_groups.reject { |_, grouped| grouped.nil? || grouped.empty? }
|
|
38
|
+
groups.each { |heading, grouped| nav_group(heading, grouped, labeled: groups.size > 1) }
|
|
33
39
|
end
|
|
34
40
|
end
|
|
35
41
|
end
|
|
@@ -42,27 +48,37 @@ module DocsUI
|
|
|
42
48
|
|
|
43
49
|
def header_section
|
|
44
50
|
div(class: "flex min-h-16 items-center gap-2 px-4") do
|
|
45
|
-
a(href: config.brand_href, class: "text-lg font-bold text-base-content") {
|
|
51
|
+
a(href: config.brand_href, class: "text-lg font-bold text-base-content") { brand_mark }
|
|
46
52
|
badge = config.version_badge_text
|
|
47
53
|
span(class: "badge badge-sm badge-ghost") { badge } if badge
|
|
48
54
|
end
|
|
49
55
|
end
|
|
50
56
|
|
|
51
|
-
#
|
|
52
|
-
#
|
|
53
|
-
|
|
54
|
-
|
|
57
|
+
# The brand: the configured mark (config.brand_logo) when set, else the
|
|
58
|
+
# text brand — byte-identical to before for a site that sets nothing.
|
|
59
|
+
# Slightly taller than the topbar's h-6: this is the masthead.
|
|
60
|
+
def brand_mark
|
|
61
|
+
if (logo = config.brand_logo)
|
|
62
|
+
render DocsUI::Logo.new(logo, class: "h-7 w-auto", label: config.brand)
|
|
63
|
+
else
|
|
64
|
+
plain config.brand
|
|
65
|
+
end
|
|
66
|
+
end
|
|
55
67
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
68
|
+
# A top-level group (e.g. "Docs") holding collapsible sub-groups (e.g.
|
|
69
|
+
# "Guide", "Examples"). `grouped` is a { subgroup => [items] } Hash. The
|
|
70
|
+
# heading label only renders when the sidebar shows SEVERAL groups
|
|
71
|
+
# (labeled:) — as a static `.menu-title`, never a <details>, so subgroups
|
|
72
|
+
# stay at the menu's top level instead of gaining a nesting indent. The
|
|
73
|
+
# mt-4/first:mt-0 pair is the breathing room between one group's links and
|
|
74
|
+
# the next group's label.
|
|
75
|
+
def nav_group(heading, grouped, labeled:)
|
|
76
|
+
if labeled
|
|
77
|
+
li(class: "menu-title mt-4 text-xs font-semibold uppercase tracking-wider text-base-content/50 first:mt-0") do
|
|
78
|
+
heading
|
|
64
79
|
end
|
|
65
80
|
end
|
|
81
|
+
grouped.each { |subgroup, items| nav_subgroup(subgroup, items) }
|
|
66
82
|
end
|
|
67
83
|
|
|
68
84
|
# A collapsible sub-group: its title is a <summary> so the whole section folds
|
|
@@ -29,6 +29,11 @@ module DocsKit
|
|
|
29
29
|
# GET-only, sessionless, public text endpoints (no token to verify).
|
|
30
30
|
protect_from_forgery with: :null_session
|
|
31
31
|
|
|
32
|
+
# Every action runs in the request's version scope (params[:version] on the
|
|
33
|
+
# version-prefixed routes, else the current version), so the enumeration
|
|
34
|
+
# below serves the version the URL asked for.
|
|
35
|
+
include DocsKit::Scoping
|
|
36
|
+
|
|
32
37
|
def index
|
|
33
38
|
body = DocsKit::LlmsText.index(docs_config, base_url: request.base_url)
|
|
34
39
|
render_text(body) if stale_llms?(body)
|
|
@@ -67,9 +72,11 @@ module DocsKit
|
|
|
67
72
|
# A page's Markdown twin, rendered through this controller's view context so
|
|
68
73
|
# url helpers/CSRF resolve and relative links absolutize to portable URLs —
|
|
69
74
|
# the same path DocsKit::Controller#render_page takes for a `.md` request.
|
|
75
|
+
# renderable_for is the live-or-snapshot shim (a snapshot entry renders an
|
|
76
|
+
# ArchivedPage carrying its frozen Markdown).
|
|
70
77
|
def render_page_markdown(page)
|
|
71
78
|
DocsKit::MarkdownExport.new(
|
|
72
|
-
page
|
|
79
|
+
DocsKit::LlmsText.renderable_for(page), view_context:, base_url: request.base_url
|
|
73
80
|
).to_md
|
|
74
81
|
end
|
|
75
82
|
end
|
|
@@ -15,7 +15,7 @@ module DocsKit
|
|
|
15
15
|
# DocsKit::McpServer / DocsKit::McpTools.
|
|
16
16
|
#
|
|
17
17
|
# Stateless JSON-RPC: each POST is independent (no SSE session), so it works
|
|
18
|
-
# behind the existing
|
|
18
|
+
# behind the existing dash/Cloudflare deploy unchanged. #create delegates the
|
|
19
19
|
# whole protocol to DocsKit::McpServer#handle_json — the SDK parses the request,
|
|
20
20
|
# dispatches the tool, and serializes the response (including JSON-RPC errors),
|
|
21
21
|
# so the controller never hand-rolls the protocol.
|
|
@@ -31,6 +31,10 @@ module DocsKit
|
|
|
31
31
|
# protection outright.
|
|
32
32
|
skip_forgery_protection
|
|
33
33
|
|
|
34
|
+
# MCP tool calls run in the request's version scope; the version-aware tool
|
|
35
|
+
# arguments (issue #61 phase 6) layer per-call resolution on top of this.
|
|
36
|
+
include DocsKit::Scoping
|
|
37
|
+
|
|
34
38
|
def create
|
|
35
39
|
return head(:not_found) unless docs_config.mcp_enabled?
|
|
36
40
|
|
|
@@ -28,6 +28,11 @@ module DocsKit
|
|
|
28
28
|
# public endpoint.
|
|
29
29
|
protect_from_forgery with: :null_session
|
|
30
30
|
|
|
31
|
+
# Search follows the request's version: /1.0/docs/search searches the 1.0
|
|
32
|
+
# snapshot, /docs/search searches current — the scope swaps the enumeration
|
|
33
|
+
# source underneath DocsKit::LlmsText.pages.
|
|
34
|
+
include DocsKit::Scoping
|
|
35
|
+
|
|
31
36
|
def index
|
|
32
37
|
hits = search_index.search(query)
|
|
33
38
|
|
|
@@ -53,7 +58,7 @@ module DocsKit
|
|
|
53
58
|
def search_index
|
|
54
59
|
triples = DocsKit::LlmsText.pages(docs_config).map do |page|
|
|
55
60
|
markdown = DocsKit::MarkdownExport.new(
|
|
56
|
-
page
|
|
61
|
+
DocsKit::LlmsText.renderable_for(page), view_context:, base_url: request.base_url
|
|
57
62
|
).to_md
|
|
58
63
|
[page.title, page.href, markdown]
|
|
59
64
|
end
|
data/exe/docs-kit
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
# docs-kit CLI. One command scaffolds a complete, deployable docs site:
|
|
5
5
|
#
|
|
6
6
|
# docs-kit new my-docs
|
|
7
|
-
# docs-kit new my-docs --image
|
|
7
|
+
# docs-kit new my-docs --image zoolutions/my-repo --service my-repo
|
|
8
8
|
#
|
|
9
9
|
# It runs `rails new` with the right minimal flags and applies docs-kit's
|
|
10
10
|
# application template (lib/docs_kit/templates/new_site.rb), which adds the gem,
|
|
11
|
-
# runs `docs_kit:install`, syncs icons, builds the CSS, and scaffolds
|
|
11
|
+
# runs `docs_kit:install`, syncs icons, builds the CSS, and scaffolds dash +
|
|
12
12
|
# the reusable deploy workflow.
|
|
13
13
|
|
|
14
14
|
require "optparse"
|
|
@@ -25,9 +25,9 @@ unless command == "new"
|
|
|
25
25
|
docs-kit new NAME [--image OWNER/REPO] [--service NAME] [--gem-source SRC]
|
|
26
26
|
|
|
27
27
|
Options:
|
|
28
|
-
--image GHCR image (default
|
|
28
|
+
--image GHCR image (default zoolutions/NAME) — use OWNER/REPO for the
|
|
29
29
|
repo-linked package so GITHUB_TOKEN can push+pull it.
|
|
30
|
-
--service
|
|
30
|
+
--service dash service name (default NAME).
|
|
31
31
|
--gem-source How to depend on docs-kit: 'released' (default),
|
|
32
32
|
'path:PATH', or 'github:OWNER/REPO'.
|
|
33
33
|
USAGE
|
|
@@ -58,7 +58,7 @@ gem_source =
|
|
|
58
58
|
|
|
59
59
|
env = {
|
|
60
60
|
"DOCS_KIT_GEM_SOURCE" => gem_source,
|
|
61
|
-
"DOCS_KIT_IMAGE" => opts[:image] || "
|
|
61
|
+
"DOCS_KIT_IMAGE" => opts[:image] || "zoolutions/#{name}",
|
|
62
62
|
"DOCS_KIT_SERVICE" => opts[:service] || name
|
|
63
63
|
}
|
|
64
64
|
|