@vp-tw/dirwell 0.0.0-stage → 0.1.0-alpha.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.
Files changed (74) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/LICENSE +21 -0
  3. package/README.md +182 -2
  4. package/THEME_PACKAGE_CONTRACT.md +64 -0
  5. package/THEMING.md +88 -0
  6. package/THIRD_PARTY_NOTICES.md +14 -0
  7. package/dist/bin.d.mts +1 -0
  8. package/dist/bin.mjs +306 -0
  9. package/dist/bin.mjs.map +1 -0
  10. package/dist/bun.d.mts +7 -0
  11. package/dist/bun.mjs +7 -0
  12. package/dist/bun.mjs.map +1 -0
  13. package/dist/config-BJG2Zc3Q.d.mts +34 -0
  14. package/dist/dev-server-Q7NC1wiB.mjs +132 -0
  15. package/dist/dev-server-Q7NC1wiB.mjs.map +1 -0
  16. package/dist/esbuild.d.mts +7 -0
  17. package/dist/esbuild.mjs +7 -0
  18. package/dist/esbuild.mjs.map +1 -0
  19. package/dist/farm.d.mts +7 -0
  20. package/dist/farm.mjs +7 -0
  21. package/dist/farm.mjs.map +1 -0
  22. package/dist/generator-CtX3iHhK.mjs +1783 -0
  23. package/dist/generator-CtX3iHhK.mjs.map +1 -0
  24. package/dist/index.d.mts +47 -0
  25. package/dist/index.mjs +74 -0
  26. package/dist/index.mjs.map +1 -0
  27. package/dist/model-CWjYM17j.d.mts +100 -0
  28. package/dist/rolldown.d.mts +7 -0
  29. package/dist/rolldown.mjs +7 -0
  30. package/dist/rolldown.mjs.map +1 -0
  31. package/dist/rollup.d.mts +7 -0
  32. package/dist/rollup.mjs +7 -0
  33. package/dist/rollup.mjs.map +1 -0
  34. package/dist/rsbuild.d.mts +7 -0
  35. package/dist/rsbuild.mjs +7 -0
  36. package/dist/rsbuild.mjs.map +1 -0
  37. package/dist/rspack.d.mts +7 -0
  38. package/dist/rspack.mjs +7 -0
  39. package/dist/rspack.mjs.map +1 -0
  40. package/dist/theme-components-CXzvdQY-.mjs +8 -0
  41. package/dist/theme-components-CXzvdQY-.mjs.map +1 -0
  42. package/dist/theme-components-DW0fv9_C.d.mts +141 -0
  43. package/dist/theme-components.d.mts +2 -0
  44. package/dist/theme-components.mjs +2 -0
  45. package/dist/theme-runtime.js +1128 -0
  46. package/dist/theme-worker.js +27 -0
  47. package/dist/unplugin-CKRUCTgW.d.mts +16 -0
  48. package/dist/unplugin-p6AXhL4F.mjs +421 -0
  49. package/dist/unplugin-p6AXhL4F.mjs.map +1 -0
  50. package/dist/unplugin.d.mts +2 -0
  51. package/dist/unplugin.mjs +2 -0
  52. package/dist/vite-JBsvRvuW.mjs +282 -0
  53. package/dist/vite-JBsvRvuW.mjs.map +1 -0
  54. package/dist/vite.d.mts +12 -0
  55. package/dist/vite.mjs +2 -0
  56. package/dist/vscode-icons/NOTICE.txt +16 -0
  57. package/dist/vscode-icons/default_file.svg +1 -0
  58. package/dist/vscode-icons/default_folder.svg +1 -0
  59. package/dist/vscode-icons/file_type_css.svg +1 -0
  60. package/dist/vscode-icons/file_type_html.svg +1 -0
  61. package/dist/vscode-icons/file_type_image.svg +1 -0
  62. package/dist/vscode-icons/file_type_js.svg +1 -0
  63. package/dist/vscode-icons/file_type_json.svg +1 -0
  64. package/dist/vscode-icons/file_type_markdown.svg +1 -0
  65. package/dist/vscode-icons/file_type_pdf2.svg +1 -0
  66. package/dist/vscode-icons/file_type_shell.svg +1 -0
  67. package/dist/vscode-icons/file_type_text.svg +1 -0
  68. package/dist/vscode-icons/file_type_typescript.svg +1 -0
  69. package/dist/vscode-icons/file_type_yaml.svg +1 -0
  70. package/dist/vscode-icons/file_type_zip.svg +1 -0
  71. package/dist/webpack.d.mts +7 -0
  72. package/dist/webpack.mjs +7 -0
  73. package/dist/webpack.mjs.map +1 -0
  74. package/package.json +133 -4
package/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # @vp-tw/dirwell
2
+
3
+ ## 0.1.0-alpha.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 9f2fdce: Initial alpha release with the CLI, SSG/MPA generation, safe symlink handling, source filters, Ledger and Plain themes, all Unplugin build hosts, and typed rendering APIs. Includes a theme-owned English, Traditional Chinese, and Japanese example and concise local dates with exact-time disclosure.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dirwell contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,183 @@
1
- # Temporary Holding Version
1
+ # Dirwell
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Dirwell turns a directory into a static file explorer. Build files for a static
4
+ host, or serve a changing folder locally. Choose SSG for portable output and
5
+ MPA when many directory pages should share assets.
6
+
7
+ ## Quick start
8
+
9
+ ```bash
10
+ pnpm install
11
+ pnpm dirwell serve ./fixture
12
+ pnpm dirwell build ./fixture -o ./generated
13
+ ```
14
+
15
+ These commands run from a repository checkout. The first starts a watch server;
16
+ the second writes a static tree. The installed CLI uses the same `dirwell`
17
+ commands. Existing `index.html` and `index.htm` files are preserved; Dirwell
18
+ uses `_dirwell.html` for those directories when that name is available.
19
+
20
+ | Need | Start with |
21
+ | ------------------------------------ | ------------------------------------------- |
22
+ | Move the output tree between paths | SSG and relative URLs, the defaults |
23
+ | Publish beneath a fixed path | `base` plus `urls: "base"` |
24
+ | Share assets across many pages | `mode: "mpa"` |
25
+ | Show only selected source files | `include` and `exclude` |
26
+ | Change icons or a few UI parts | `createDefaultTheme({ icons, components })` |
27
+ | Render basic HTML without JavaScript | `createPlainTheme()` |
28
+
29
+ The [configuration guide](./docs/src/content/docs/configuration.md) lists
30
+ accepted values, defaults, effects, and use cases for every field.
31
+
32
+ ```text
33
+ dirwell [directory] # alias for serve
34
+ dirwell serve [directory] # watch and live reload
35
+ dirwell build [directory] # generate static output
36
+ dirwell daemon start [dir] # detached server
37
+ dirwell daemon status
38
+ dirwell daemon stop
39
+ ```
40
+
41
+ ## Configuration
42
+
43
+ Create `dirwell.config.ts` when a field has no CLI flag or you want a reusable
44
+ setup:
45
+
46
+ ```ts
47
+ import { defineConfig } from "@vp-tw/dirwell";
48
+
49
+ export default defineConfig({
50
+ mode: "mpa",
51
+ base: "/downloads/",
52
+ urls: "base",
53
+ include: ["**/*.md", "assets/**"],
54
+ exclude: ["drafts/**"],
55
+ });
56
+ ```
57
+
58
+ Run `pnpm dirwell build ./public -o ./dist` to use it. The CLI's positional
59
+ directory defaults to `.` and overrides config `root`, so pass the source
60
+ path in the command.
61
+
62
+ `outputName` accepts a fixed filename or a function receiving `DirectoryData`.
63
+ Returning `null` skips the current directory. The default uses `index.html`,
64
+ then `_dirwell.html` when an index already exists, then skips if both exist.
65
+
66
+ `include` and `exclude` accept root-relative glob patterns. They select mirrored
67
+ files, generated directory pages, and search results; exclusions win. With no
68
+ patterns, every source entry is included.
69
+
70
+ URL generation supports portable depth-aware `relative` links, Vite-style
71
+ `base` prefixes for deployments such as GitHub Pages, and native
72
+ `html-base` documents using `<base href>`.
73
+
74
+ ## Output modes
75
+
76
+ - `ssg` emits a page and runtime asset in every generated directory. This is
77
+ the default and works on simple static hosts.
78
+ - `mpa` keeps every directory directly addressable while sharing runtime
79
+ assets from the output-root `__dirwell/` directory. The default theme moves
80
+ directories over 500 entries into a per-directory data asset and renders only
81
+ nearby rows, so these pages require JavaScript.
82
+
83
+ `__dirwell/` is reserved in both modes for generated assets such as broken-link
84
+ raw views.
85
+
86
+ ## Vite integration
87
+
88
+ The `@vp-tw/dirwell/vite` adapter builds one or more explorers alongside a Vite
89
+ application and serves them through Vite's development server:
90
+
91
+ ```ts
92
+ import { defineConfig } from "vite";
93
+ import Dirwell from "@vp-tw/dirwell/vite";
94
+
95
+ export default defineConfig({
96
+ plugins: [
97
+ Dirwell([
98
+ { root: "./docs", outDir: "dist/docs" },
99
+ { root: "./downloads", outDir: "dist/downloads", mode: "mpa" },
100
+ ]),
101
+ ],
102
+ });
103
+ ```
104
+
105
+ By default, Dirwell writes to a dedicated `dirwell/` subdirectory of Vite's
106
+ `build.outDir` and derives its public `base` from Vite's base path. Set
107
+ `outDir: "dist/downloads"` for another path relative to the Vite project root,
108
+ or set an absolute `outDir` for an independent publish directory. An output
109
+ outside Vite's build directory needs an explicit public `base`. The adapter
110
+ never replaces Vite's output root or an existing directory it does not own.
111
+ See [configuration](./docs/src/content/docs/configuration.md#vite-adapter) for
112
+ the full path and development-server behavior.
113
+
114
+ ## Other build tools
115
+
116
+ Adapters are available for Rollup, Rolldown, webpack, Rspack, Rsbuild, esbuild,
117
+ Farm, and Bun. Import `@vp-tw/dirwell/<host>` or use the factories from
118
+ `@vp-tw/dirwell/unplugin`. Each generates a dedicated explorer path alongside the host
119
+ output. See [build tool adapters](./docs/src/content/docs/build-tools.md) for
120
+ options, watch behavior, and verification boundaries.
121
+
122
+ ## Browser behavior
123
+
124
+ SSG pages and smaller MPA pages work without JavaScript. The runtime adds local and global
125
+ fuzzy search, type filters, configurable sorting, IME-safe keyboard controls,
126
+ Backspace parent navigation, theme persistence, and watch-mode live reload. The
127
+ global search index is fetched only after the user opens Search all files and types a query.
128
+ The index is split into bounded files; the first 100 best matches render progressively.
129
+ Search matches file names, relative paths, and symlink targets. Three independent
130
+ type controls filter physical folders, physical files, and symlinks. All are on by
131
+ default; any combination is available in the current folder and global search.
132
+
133
+ Name sorting supports raw Unicode code-point order, locale-aware comparison,
134
+ and natural numeric comparison. Modified time and file size are also available;
135
+ direction and directory grouping are independent controls.
136
+
137
+ The default theme shows modified times in the viewer's local time zone when
138
+ JavaScript is available, without repeating the offset in every row. Activate a
139
+ date with touch, pointer, or keyboard to see its exact local time and UTC instant.
140
+ Generated HTML displays labeled UTC times before the
141
+ runtime loads and when JavaScript is disabled. The plain theme always displays UTC.
142
+
143
+ ## Symlinks
144
+
145
+ Symlinks always remain visible and show their declared target. Broken links can
146
+ open their raw target text; targets outside the configured root remain
147
+ unavailable. Broken links, outside-root targets, and cycles receive explicit states.
148
+ Following directory links is opt-in. Ancestor cycles remain navigable but are
149
+ never expanded recursively.
150
+
151
+ ## Themes
152
+
153
+ Replace the complete `ExplorerTheme` or layer typed component overrides over
154
+ the default theme. See [THEMING.md](./THEMING.md) and the Starlight site in
155
+ `docs/`.
156
+
157
+ `createPlainTheme()` provides a separate browser-native listing with no
158
+ icons, JavaScript, appearance controls, or search index. It emits complete HTML
159
+ in both modes; choose the default theme for search and large-directory
160
+ virtualization. See [examples/plain](./examples/plain).
161
+ Its footer shows the repository, author, and license. Pass `project` to
162
+ `createPlainTheme()` to override the metadata and link to a published repository.
163
+
164
+ The default theme uses selected self-hosted `vscode-icons` artwork for common
165
+ file types. The icons are CC BY-SA 4.0 and may include separately protected
166
+ brand marks; Dirwell's code remains MIT-licensed. See
167
+ [Ledger theme attribution](./src/theme-default/README.md),
168
+ [third-party notices](./THIRD_PARTY_NOTICES.md), and the
169
+ [file-icons example](./examples/file-icons).
170
+
171
+ ## Development
172
+
173
+ ```bash
174
+ pnpm install
175
+ pnpm test
176
+ pnpm exec playwright install chromium --only-shell
177
+ pnpm test:browser
178
+ pnpm run check
179
+ pnpm run build
180
+ pnpm run docs:build
181
+ ```
182
+
183
+ Dirwell is MIT licensed.
@@ -0,0 +1,64 @@
1
+ # Alpha theme package contract
2
+
3
+ An independent theme package exports a factory returning `ExplorerTheme` from
4
+ `@vp-tw/dirwell`. Consumers import that factory in `dirwell.config.ts`. Complete
5
+ renderer replacement is the smallest contract: the package owns its HTML,
6
+ styles, assets, options, language controls, and browser behavior.
7
+
8
+ The [external package example](examples/theme-package) exercises this boundary
9
+ from packed distributions rather than repository source aliases. The
10
+ [i18n example](examples/i18n) separately demonstrates theme-owned localization.
11
+
12
+ ## Public surface
13
+
14
+ | Surface | Contract |
15
+ | ------------------------ | ---------------------------------------------------------------------------------------------------------------------- |
16
+ | `ExplorerTheme` | A name, optional `searchIndex`, and a synchronous or asynchronous `render(context)` function. |
17
+ | `ThemeContext` | Prepared `DirectoryData`, output mode/name, sort policy, optional HTML base, asset/index URLs, and navigation helpers. |
18
+ | `RenderedPage` | A complete HTML document and optional map of safe asset filenames to strings or bytes. |
19
+ | Default theme components | Optional typed overrides and ordered layers from `@vp-tw/dirwell/theme`; a full renderer can operate independently. |
20
+
21
+ Use `hrefFor()`, `hrefForDirectory()`, and `exitsExplorerFor()` instead of
22
+ reconstructing filesystem or deployment URLs. `hrefFor()` can return `null`;
23
+ render an unavailable label in that case. Preserve the caller's HTML base when
24
+ `documentBaseHref` is present.
25
+
26
+ Set `searchIndex: false` when the theme has no global search. Otherwise the
27
+ generator can emit index assets, but the theme still owns how they are used.
28
+ Styles and tokens remain private to each renderer. Core does not supply a locale
29
+ setting; Ledger and Plain keep their English interfaces.
30
+
31
+ ## Assets and trust
32
+
33
+ The generator validates asset filenames and deploys them beside each SSG page
34
+ or in the shared MPA `__dirwell/` directory. Refer to them with `assetHref()`.
35
+ For MPA, every use of the same asset filename must provide identical bytes;
36
+ conflicting shared assets fail the build. Choose names that do not collide with
37
+ selected source files, generated page names, or other theme assets.
38
+
39
+ Theme packages execute as trusted Node code. Rendering needs prepared source
40
+ data rather than a second source-tree traversal; packages may load their own
41
+ bundled styles/assets. Treat entry names, declared symlink targets, and visible
42
+ paths as untrusted text and escape them before HTML insertion. Avoid serializing
43
+ machine-absolute `absolutePath` or `resolvedPath` into browser output. A theme
44
+ owns its asset licenses and notices.
45
+
46
+ ## Alpha compatibility
47
+
48
+ Pin the exact Dirwell alpha used by the theme's tests in `peerDependencies`.
49
+ Retest before widening that range or accepting another alpha; this contract is
50
+ not a stable API promise. Public types and component contracts may evolve before
51
+ stable. Consumers own the decision to upgrade their Dirwell/theme pair.
52
+
53
+ The proof package deliberately replaces the full renderer. Component overrides
54
+ remain supported, but their authors must also verify the default runtime's DOM
55
+ expectations, keyboard behavior, virtualization, and theme assets against their
56
+ selected alpha version.
57
+
58
+ ## Consumer verification
59
+
60
+ `pnpm verify:package` packs Dirwell and this private theme separately, installs
61
+ them into a fresh project, and exercises their public imports. It verifies the
62
+ CLI, an external renderer with SSG/MPA assets and encoded names, public types,
63
+ and a real Rollup build. Successful local tarball consumption does not prove npm
64
+ publication or a registry install; release readback must verify those separately.
package/THEMING.md ADDED
@@ -0,0 +1,88 @@
1
+ # Theme architecture
2
+
3
+ Dirwell themes own the complete document, styles, icons, and optional browser
4
+ behavior. Choose one of three paths:
5
+
6
+ | Need | Use | Keep |
7
+ | --------------------------------------------------- | ----------------------------------------- | ------------------------------- |
8
+ | Change controls, colors, icons, or a few HTML parts | `createDefaultTheme(options)` | Default explorer behavior |
9
+ | Publish a basic no-script list | `createPlainTheme()` | Prepared entries and safe links |
10
+ | Replace the full page | An `ExplorerTheme` with `render(context)` | Prepared entries and safe links |
11
+
12
+ The [theme guide](docs/src/content/docs/themes.md) lists every default-theme
13
+ option, its accepted input, default, result, and use case. This file describes
14
+ the component contract for theme authors.
15
+
16
+ ## Component layers
17
+
18
+ Use an `ExplorerTheme` to replace the complete renderer. Use component layers
19
+ to replace selected parts of the default theme: `PageShell`, `Breadcrumbs`,
20
+ `Toolbar`, `EntryList`, `EntryRow`, `EmptyState`, `Footer`, and
21
+ `Icon`.
22
+
23
+ Each component is a typed function from props to HTML. Pass one override object
24
+ or an array of layers. Later layers win when they define the same component:
25
+
26
+ ```ts
27
+ import { createDefaultTheme, defineConfig } from "@vp-tw/dirwell";
28
+
29
+ export default defineConfig({
30
+ theme: createDefaultTheme({
31
+ globalSearch: true,
32
+ sorting: true,
33
+ project: {
34
+ author: "Your name",
35
+ authorUrl: "https://github.com/you",
36
+ repositoryUrl: "https://github.com/you/project",
37
+ license: "MIT License",
38
+ licenseUrl: "https://github.com/you/project/blob/main/LICENSE",
39
+ },
40
+ components: {
41
+ Footer: ({ parentHref }) =>
42
+ parentHref === null ? "<footer>Home</footer>" : "<footer>Nested</footer>",
43
+ },
44
+ }),
45
+ });
46
+ ```
47
+
48
+ Global search is progressive: the browser requests the generated JSON index
49
+ only after the user selects `Everywhere`. Sorting and search controls can be
50
+ disabled independently without changing the component override API.
51
+
52
+ Replacing `EntryList` or `EntryRow` disables the default MPA virtual list.
53
+ Keep those defaults for large directories unless the replacement provides its
54
+ own row loading. `virtualizeAfter` defaults to 500 entries.
55
+
56
+ Within the bundled theme, the five select controls share a private renderer,
57
+ and `--dw-control-height` gives search, select, sort, and color-scheme controls
58
+ one height. This is a default-theme styling hook, not a requirement for custom
59
+ themes. The controls keep their native `input`, `select`, `details`, and
60
+ `fieldset` semantics; override `Toolbar` to replace their markup.
61
+
62
+ The bundled explorer has its own [design specification](src/theme-default/DESIGN.md)
63
+ beside its components and styles. The repository-root `DESIGN.md` describes the
64
+ official site; neither document constrains third-party themes.
65
+
66
+ Default components are exported as `defaultThemeComponents`, so a replacement
67
+ can wrap one explicitly. This provides the useful part of Docusaurus swizzling
68
+ without virtual aliases or unsafe component categories.
69
+
70
+ Component props and names are public API. Components receive prepared
71
+ filesystem data and navigation decisions; they do not read the filesystem.
72
+ Escape untrusted file names with the exported `escapeHtml` helper.
73
+
74
+ The full `ExplorerTheme` contract can host a Svelte, Astro, React, or other SSR
75
+ adapter that returns a complete HTML string and optional assets. The
76
+ [`custom-theme`](examples/custom-theme) example builds a release catalog with
77
+ its own HTML and CSS. The [`default-theme-override`](examples/default-theme-override)
78
+ example keeps the default explorer and changes components, Catppuccin colors,
79
+ and file icons. `createDefaultTheme({ icons })` accepts light and optional dark
80
+ SVG sets, including fallbacks and extension mappings. Dirwell uses the same icon
81
+ set for static, global-search, and virtualized rows.
82
+
83
+ ## Independent alpha packages
84
+
85
+ An external package can return `ExplorerTheme` through its own factory and own
86
+ its HTML, assets, styles, options, and localization. Pin the tested Dirwell alpha
87
+ in its peer dependency. See [the package contract](THEME_PACKAGE_CONTRACT.md)
88
+ and [the separately packed example](examples/theme-package).
@@ -0,0 +1,14 @@
1
+ # Third-party notices
2
+
3
+ Dirwell's code is MIT-licensed. The default theme includes selected icons from
4
+ [vscode-icons](https://github.com/vscode-icons/vscode-icons/tree/6b4471cf8dcdeafc9d1203f9156d285fc3e9d552/icons).
5
+ The icons are licensed under [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)
6
+ and are attributed to the vscode-icons contributors. They are redistributed
7
+ without modification. Branded icons may carry additional rights belonging to
8
+ their respective owners. No endorsement is implied.
9
+
10
+ The exact icon list is in [`dist/vscode-icons/NOTICE.txt`](./dist/vscode-icons/NOTICE.txt)
11
+ in the published package, and in `src/vscode-icons/NOTICE.txt` in the source tree.
12
+ Generated sites include this notice as `vscode-icons-NOTICE.txt`. The default
13
+ theme footer links to the [Ledger theme README](./src/theme-default/README.md),
14
+ which links to the source notice.
package/dist/bin.d.mts ADDED
@@ -0,0 +1 @@
1
+ export {}