diff --git a/.gitattributes b/.gitattributes index 0f36e10394c..409262d2d4d 100644 --- a/.gitattributes +++ b/.gitattributes @@ -9,6 +9,7 @@ *.bash eol=lf Makefile eol=lf packages/vscode-ide-companion/NOTICES.txt linguist-generated=true +packages/web-shell/NOTICES.txt linguist-generated=true whitespace=-blank-at-eof # Windows cmd.exe expects batch installers to be checked out with CRLF. scripts/installation/install-qwen-standalone.bat text eol=crlf diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dc6337aaf6d..59427f3b3fd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1257,18 +1257,21 @@ jobs: fi echo "Settings schema is up-to-date" - - name: 'Generate VS Code companion notices' - if: "${{ needs.classify_pr.outputs.skip_ci != 'true' && steps.ci_profile.outputs.ci_profile == 'full' }}" - run: 'npm run generate:notices --workspace=qwen-code-vscode-ide-companion' - - - name: 'Check VS Code companion notices are up-to-date' + - name: 'Generate Web Shell and VS Code companion notices' if: "${{ needs.classify_pr.outputs.skip_ci != 'true' && steps.ci_profile.outputs.ci_profile == 'full' }}" run: |- - if [[ -n $(git status --porcelain packages/vscode-ide-companion/NOTICES.txt) ]]; then + npm run generate:notices --workspace=@qwen-code/web-shell + npm run generate:notices --workspace=qwen-code-vscode-ide-companion + + - name: 'Check Web Shell and VS Code companion notices are up-to-date' + if: "${{ needs.classify_pr.outputs.skip_ci != 'true' && steps.ci_profile.outputs.ci_profile == 'full' }}" + run: |- + if [[ -n $(git status --porcelain packages/vscode-ide-companion/NOTICES.txt packages/web-shell/NOTICES.txt) ]]; then echo "Error: NOTICES.txt is out of date." echo "Please run: npm run generate:notices --workspace=qwen-code-vscode-ide-companion" + echo "And: npm run generate:notices --workspace=@qwen-code/web-shell" echo "Then commit the updated file." - git diff --stat packages/vscode-ide-companion/NOTICES.txt + git diff --stat packages/vscode-ide-companion/NOTICES.txt packages/web-shell/NOTICES.txt exit 1 fi echo "NOTICES.txt is up-to-date" diff --git a/docs/design/web-shell-file-browser.md b/docs/design/web-shell-file-browser.md new file mode 100644 index 00000000000..f1cc5154e63 --- /dev/null +++ b/docs/design/web-shell-file-browser.md @@ -0,0 +1,137 @@ +# Web Shell file browser + +[English](web-shell-file-browser.md) | [简体中文](web-shell-file-browser.zh-CN.md) + +## Problem and current state + +The right extension area offers file changes but cannot browse workspace files. +The requested interface adds a Files entry beside the existing actions, with the +selected file on the left and a persistent directory tree on the right. + +## Proposed solution + +Add an opt-in `files` right-panel item and a workspace-owned `files` tab. Enable +it in the standalone page. The empty-state action and add menu open or activate +one Files tab per workspace. Reuse existing panel sizing, closing, fullscreen, +and persistence behavior. Before selecting a file, show only the full-width tree. +Selecting a file opens the two columns with about 70% for content and 30% for +the tree, without rebuilding the tree; subsequent +file selections keep it visible. + +Use `@pierre/trees` for the read-only tree and `@pierre/diffs` File for read-only +source rendering. Retain existing Markdown, HTML and image previews. Markdown +and HTML default to rendered preview with a source toggle. Other files use the +existing supported-file/error behavior. No Git state or editing is enabled. + +Load only the root and expanded directories through the existing daemon API. +Keep loaded paths in the Pierre model; directory expansion loads direct children. +Search covers loaded paths only and never fetches search-expanded directories. +Keep the raw filter input unchanged; show an explicit no-match state within loaded +paths. Selection or Escape closes filtering. A nonempty filter consumes Escape +before fullscreen or drawer dismissal; IME composition keeps its native Escape. +Refresh clears directory cache and reloads +the root and selected file, collapsing branches. Hide the filter-scope explanation +and per-directory loading log; show retryable errors, empty directories and +truncated-list warnings only when needed. Never recurse into symlinks. +Files expose a right-click menu for relative/absolute path copying, downloading, +previewing supported Markdown/HTML/images in a separate panel tab, and referencing +the file in the current composer. Reference uses the same tag construction and +inline insertion as the built-in `@` file picker, only for the current workspace. +Reference closes a floating drawer before returning focus to the composer; +the desktop dock stays open. +Downloads reuse the existing bounded, owner-checked byte reader and cancellation. +Both columns scroll independently. The tree scrolls horizontally as a whole, +keeping indentation and complete names at deep levels. Use Pierre’s shadow-root +CSS extension to size the virtual list by its content and prevent label shrinking. A keyboard-accessible draggable separator +uses the shared shadcn resizable primitive to adjust their widths, preserving the +layout across tab switches. Leave 12px below the tree. The tree can be hidden to read content in a +narrow panel without closing the Files tab. + +## Ownership and lifecycle + +The Files tab captures workspace cwd and ID. Extend the existing artifact owner +guard with directory reads, checking authority before and after requests. Use +workspace-qualified SDK directory reads over REST (including ACP clients) whenever workspace IDs are advertised; +retain the primary route only for legacy daemons. Unavailable, ambiguous, +untrusted or changed owners fail closed. Workspace changes discard late results. +Files panes remain mounted while inactive, preserving selection, expansion, +source/preview mode, filtering, column sizes and scroll position across tab switches. Each pane +checks its own workspace owner even while hidden; closing the tab or losing its +owner discards that state. Only tab workspace identity persists across reloads. A stale persisted owner stays +blocked, but does not hide the action for reopening the current trusted owner. File content loading retains existing size limits and cancellation. + +## Scope and decisions + +No filesystem mutations, code editing, Git operations, watchers or whole-workspace +search index. Opening files does not add them to model context; the explicit +Reference action inserts a file tag without sending a prompt. Keep existing +review, attachment and file tabs unchanged. Pierre uses Shadow DOM; style its +public variables with Web Shell semantic colors. Use its vanilla entry points to +preserve the package's existing React 18/19 peer range. Pierre is a pinned build-time +dependency: its vanilla implementation is bundled, so published consumers do not +install its React peers (which require 18.3.1 or later). +The explicit `bundledDevDependencies` list seeds license generation without +including unrelated development tools. Bundled dependency licenses and NOTICE +credits ship in the npm package and the VS Code companion notice file. +Tree and source loading have local error boundaries. Failed imports offer a page +reload only in the standalone shell when credentials survive it (or no token is +needed). Embedded hosts and memory-only credentials instead offer Close Files, +without reloading the host or presenting a cached import as a local retry. +Pierre render errors propagate to the local boundary after resource cleanup. +The constructor uses the resolved shell theme; theme changes update it in place. Floating drawers traverse shadow-root tab +stops before Radix's light-DOM focus loop can skip the tree. +Source rendering is virtualized; theme changes update the renderer in place. The library +build bundles Pierre's compatible Shiki 3/4 dependency in the lazy preview chunk, +while retaining the existing Shiki 1 dependency for other renderers; files over 10,000 lines or 1,048,576 characters use plain +text to bound syntax-highlighting work. Files source previews refuse files above +4 MiB before reading their content, and apply the same cap to chunked fallback +reads. Users can download these files from the file menu. Files translations are +excluded from the transcript-only bundle. The actual shadow tree and file menu +have accessible names. + +The file menu also offers Preview for `.xlsx` files, reusing the shared spreadsheet preview in a separate workspace-scoped file tab. Opening the same file again reuses that tab; returning to Files retains the tree and inline selection. Other Excel formats retain the existing download-only behavior. + +## File changes assessment + +Pierre FileDiff can render the existing before/after text, unified/split views, +line numbers and inline changes. It can replace the visual renderer later. The +input may contain full snapshots, unified patches or partial edit fragments. +Partial fragments must not be presented with full-file line numbers, and repeated +edits to one file must retain their recorded segments. The current file-changes +feature additionally owns tool-call grouping, aggregated +line statistics, recorded-turn versus latest-workspace semantics, file opening, +downloads and missing/binary file handling. Keep those responsibilities intact. +Migrating the renderer requires separate validation of CodeMirror merge behavior, +large/truncated changes, cancellation, themes and wrapped lines. This change only +records the assessment; it does not migrate review rendering or connect Git. + +## Affected areas + +- Artifact panel, customization, standalone entry, translations and README. +- App tab opening, persistence and workspace ownership wiring. +- A workspace file browser, Pierre source renderer and focused tests. +- Guarded artifact workspace directory reads and authority tests. +- Browser E2E tests using the existing mock daemon, explicitly labeled as mock. + +## Validation and acceptance criteria + +1. Files appears beside File changes; initially only the tree is visible. Selecting + a file opens content on the left and the tree on the right. +2. Directory expansion loads direct children and reuses cached results. Deep + paths and long names remain readable through horizontal tree scrolling. +3. Selecting files changes content while keeping the tree visible. +4. Markdown renders as a document and switches to highlighted read-only source. +5. Filtering preserves input, shows no matches explicitly and does not load + directories. Refresh, empty/error and incomplete-list states are visible. +6. Right-click copy paths, byte download, preview tabs and `@` references work. +7. Untrusted/changed workspace owners and late responses cannot leak content. +8. Tab switches retain file-browser state; closing/reopening, page reload tab + restoration and narrow layouts remain usable. +9. Existing review and attachment behaviors remain covered. +10. File browsing and filtering enter the PR browser smoke gate. Focused ownership, + persistence and transport tests, build, typecheck and inspected browser screenshots provide evidence. + +## Open questions and risks + +Trees is Beta; pin the version and validate actual expansion/model-reset behavior. +Git badges, review migration, live watchers and global search are future work. diff --git a/docs/design/web-shell-file-browser.zh-CN.md b/docs/design/web-shell-file-browser.zh-CN.md new file mode 100644 index 00000000000..73720a58e6a --- /dev/null +++ b/docs/design/web-shell-file-browser.zh-CN.md @@ -0,0 +1,101 @@ +# Web Shell 文件浏览器 + +[English](web-shell-file-browser.md) | [简体中文](web-shell-file-browser.zh-CN.md) + +## 问题与现状 + +右侧拓展区提供文件更改,但无法浏览工作区文件。此次在现有操作旁新增 +「文件」入口,选中文件的内容在左侧,持续可见的目录树在右侧。 + +## 实现方案 + +新增可选的 `files` 右侧面板配置项及具有工作区归属的 `files` 页签,独立页面 +默认启用。空态入口和加号菜单打开或激活每个工作区唯一的文件页签。复用面板 +尺寸、关闭、全屏和持久化行为。尚未选择文件时仅显示占满宽度的目录树,点击 +文件后显示两列,初始约 70% 用于内容、30% 用于目录树,且不重建目录树;后续切换文件时目录树持续可见。 + +采用 `@pierre/trees` 展示只读目录树,采用 `@pierre/diffs` 的 File 展示只读 +源码。保留现有 Markdown、HTML 和图片预览。Markdown 和 HTML 默认渲染预览, +可切换源码。其他文件沿用现有文件支持及错误行为。不启用 Git 状态或编辑。 + +通过现有 daemon API 仅加载根目录和已展开目录。Pierre 模型保存已加载路径, +展开目录时加载直接子节点。搜索仅覆盖已加载路径,不读取因搜索而展开的目录。筛选输入保留原文,零匹配时明确 +展示「已加载路径内无匹配」。选择文件或按 Escape 结束筛选。筛选非空时优先消费 Escape, +不会退出全屏或关闭抽屉;输入法组合期间保留原生 Escape 行为。刷新清空目录缓存,重新加载 +根目录和当前文件,并收起分支。不展示筛选范围说明和逐目录加载日志,仅在需要时 +展示可重试错误、空目录和列表截断提示。不递归展开符号链接。两列独立滚动。目录树支持整体横向滚动,保留深层缩进和完整名称; +通过 Pierre 的 Shadow DOM CSS 扩展按内容确定虚拟列表宽度,避免名称被压缩。 +中间使用共享 shadcn 可调整尺寸组件提供 +支持键盘的拖动分隔线,切换页签保留宽度。文件树底部留出 12px。窄面板可隐藏目录树以阅读 +内容,无需关闭文件页签。文件右键菜单提供相对与绝对路径复制、下载、在独立 +页签预览 Markdown/HTML/图片,以及引用到当前输入框。引用复用内置 `@` 文件 +选择器的标签构造与行内插入,仅面向当前工作区。引用时关闭浮动抽屉,再将焦点交回输入框; +桌面停靠面板保持展开。下载复用现有大小受限、具有 +归属检查和取消支持的字节读取流程。 + +## 归属与生命周期 + +文件页签保存工作区 cwd 和 ID。扩展现有产物工作区权限守卫,目录请求前后均 +校验归属。daemon 公布工作区 ID 时通过具有工作区限定的 SDK REST 接口读取目录(包括 ACP 客户端); +仅旧 daemon 保留主工作区接口。不可用、歧义、不可信或已变更的归属均拒绝访问。 +切换工作区后丢弃迟到结果。文件页签未激活时仍保持挂载,切换页签保留选中、 +展开、源码/预览模式、筛选、列宽和滚动位置。隐藏页签仍独立校验工作区归属;关闭页签 +或归属失效时丢弃状态。页面刷新仅恢复页签工作区身份。旧归属页签继续拒绝访问,但不遮蔽重新打开当前可信 +归属的入口。 +文件内容加载保留现有大小限制和取消行为。 + +## 范围与决策 + +不实现文件系统修改、代码编辑、Git 操作、监听器或全工作区搜索索引。打开文件 +不会自动加入模型上下文;显式「引用」仅插入文件标签,不发送请求。保留现有审查、附件和文件页签行为。Pierre 使用 +Shadow DOM,通过公开变量适配 Web Shell 语义颜色。使用原生入口以保留包现有 +React 18/19 peer 范围。Pierre 固定版本并作为构建期依赖,原生实现完整打包, +发布包的使用方无需安装其要求 18.3.1 起的 React peer。 +显式 `bundledDevDependencies` 清单作为许可证生成种子,不包含无关开发工具。 +打包依赖的许可证与 NOTICE 署名同时进入 npm 发布包和 VS Code 扩展声明文件。 +文件树与源码加载各有局部错误边界。导入失败时,仅独立页面在凭据可恢复或不需要 token 时提供页面重载; +嵌入宿主和仅保存在内存中的凭据改为提供「关闭文件」,不重载宿主,也不把缓存的导入失败伪装成本地重试。 +Pierre 渲染错误在释放资源后进入局部边界;构造时即使用当前 Web Shell 主题,后续原地更新。浮动抽屉遍历 Shadow DOM 中的 Tab 焦点, +防止 Radix 仅遍历普通 DOM 的焦点循环跳过文件树。 +源码采用虚拟滚动;切换主题原地更新渲染器。库构建将 Pierre 兼容的 Shiki 3/4 +依赖打包进延迟预览模块,其他渲染器保留现有 Shiki 1 依赖;超过 10,000 行或 1,048,576 字符时使用纯文本,以限制语法高亮开销。文件树的源码预览在读取内容前拒绝超过 4 MiB 的文件,分块回退读取也使用同一上限; +用户仍可通过文件菜单下载。Files 文案不进入只读 transcript 包;实际 Shadow DOM 文件树和文件菜单均有可访问名称。 + +文件右键菜单也为 `.xlsx` 提供「预览」,复用共享表格预览,在独立且绑定工作区的文件页签中打开。同一文件重复打开复用页签,返回「文件」保留目录树和内联选中。其他 Excel 格式沿用现有的仅下载行为。 + +## 文件更改承载评估 + +Pierre FileDiff 可展示现有修改前后文本、合并或双栏视图、行号和行内变更,后续 +可替换显示层。输入可能是完整快照、统一补丁或局部编辑片段。局部片段不能展示为 +完整文件的真实行号,同一文件的多次编辑也必须保留记录的分段。目前文件更改还 +负责工具调用分组、汇总行数统计、历史轮次与最新 +工作区语义、打开文件、下载及缺失或二进制文件处理,这些职责应继续保留。 +迁移渲染器需要单独验证 CodeMirror merge 行为、大型及截断变更、取消、主题和 +折行。本次仅记录评估,不迁移审查渲染,也不接入 Git。 + +## 影响范围 + +- 产物面板、配置类型、独立入口、翻译和 README。 +- App 页签打开、持久化及工作区归属连接。 +- 工作区文件浏览器、Pierre 源码渲染器及针对性测试。 +- 具有权限守卫的产物工作区目录读取与归属测试。 +- 使用现有模拟 daemon 的浏览器 E2E 测试,明确标注模拟环境。 + +## 验证与验收标准 + +1. 「文件」与「文件更改」并列,初始仅显示目录树;选择文件后显示左侧内容、右侧目录树。 +2. 展开目录读取直接子节点并复用缓存;深层路径和长名称可通过目录树横向滚动完整阅读。 +3. 选择不同文件切换内容,目录树持续可见。 +4. Markdown 显示文档,可切换高亮只读源码。 +5. 筛选保留输入、明确展示零匹配且不加载目录;刷新、空态、错误和不完整列表提示可见。 +6. 右键路径复制、字节下载、独立预览和 `@` 引用均可用。 +7. 不可信或已变更的工作区归属及迟到响应不能泄露内容。 +8. 切换页签保留文件浏览状态;面板关闭重开、页面刷新恢复页签和窄布局保持可用。 +9. 现有审查与附件行为有回归覆盖。 +10. 文件浏览与筛选进入 PR 浏览器 smoke 门禁;归属、持久化与传输针对性测试、构建、 + 类型检查及目视检查浏览器截图提供验证证据。 + +## 未决问题与风险 + +Trees 仍处于 Beta,固定版本并验证真实的展开及模型重置行为。 +Git 标记、审查迁移、实时监听和全局搜索留待后续。 diff --git a/packages/sdk-typescript/src/daemon/DaemonClient.ts b/packages/sdk-typescript/src/daemon/DaemonClient.ts index 4a0a16759af..512ac4c4677 100644 --- a/packages/sdk-typescript/src/daemon/DaemonClient.ts +++ b/packages/sdk-typescript/src/daemon/DaemonClient.ts @@ -8431,9 +8431,11 @@ export class WorkspaceDaemonClient { dirList(dirPath: string): Promise { const query = new URLSearchParams({ path: dirPath }); - return this.get( + return this.client.workspaceJsonRequest( + this.workspaceSelector, `/list?${query.toString()}`, 'GET /workspaces/:workspace/list', + { mode: 'rest' }, ); } diff --git a/packages/sdk-typescript/test/unit/DaemonClient.test.ts b/packages/sdk-typescript/test/unit/DaemonClient.test.ts index dc2cc3c39b6..64cac2637ec 100644 --- a/packages/sdk-typescript/test/unit/DaemonClient.test.ts +++ b/packages/sdk-typescript/test/unit/DaemonClient.test.ts @@ -10740,6 +10740,78 @@ describe('DaemonClient', () => { expect(calls[0]?.headers['x-qwen-client-id']).toBe('client-1'); }); + it.each(['id', 'cwd'] as const)( + 'lists the selected workspace over REST with an ACP transport (%s)', + async (selector) => { + const body = { + kind: 'list', + path: 'src', + entries: [], + truncated: false, + }; + const { fetch, calls } = recordingFetch(() => jsonResponse(200, body)); + const transportFetch = vi.fn(async () => { + throw new Error('must use workspace REST'); + }); + const client = new DaemonClient({ + baseUrl: 'http://daemon', + token: 'list-token', + fetch, + transport: { + type: 'acp-http', + supportsReplay: true, + connected: true, + fetch: transportFetch, + async *subscribeEvents() {}, + dispose() {}, + }, + }); + const workspace = + selector === 'id' + ? client.workspaceById('workspace/id') + : client.workspaceByCwd('/tmp/work space'); + await expect(workspace.dirList('src')).resolves.toEqual(body); + expect(transportFetch).not.toHaveBeenCalled(); + expect(calls).toHaveLength(1); + expect(calls[0]).toMatchObject({ + method: 'GET', + url: `http://daemon/workspaces/${selector === 'id' ? 'workspace%2Fid' : '%2Ftmp%2Fwork%20space'}/list?path=src`, + headers: { authorization: 'Bearer list-token' }, + }); + }, + ); + + it('does not fall back to the primary directory when workspace listing is rejected', async () => { + const { fetch, calls } = recordingFetch(() => + jsonResponse(403, { + error: 'Workspace is not trusted.', + code: 'untrusted_workspace', + }), + ); + const transportFetch = vi.fn(async () => { + throw new Error('must use workspace REST'); + }); + const client = new DaemonClient({ + baseUrl: 'http://daemon', + fetch, + transport: { + type: 'acp-http', + supportsReplay: true, + connected: true, + fetch: transportFetch, + async *subscribeEvents() {}, + dispose() {}, + }, + }); + await expect( + client.workspaceById('removed-owner').dirList('.'), + ).rejects.toThrow(); + expect(transportFetch).not.toHaveBeenCalled(); + expect(calls.map((call) => call.url)).toEqual([ + 'http://daemon/workspaces/removed-owner/list?path=.', + ]); + }); + it('reads complete turn calls through encoded workspace REST without pagination', async () => { const body = { v: 1, diff --git a/packages/vscode-ide-companion/NOTICES.txt b/packages/vscode-ide-companion/NOTICES.txt index 1d52b89eb0c..9e3d5a93670 100644 --- a/packages/vscode-ide-companion/NOTICES.txt +++ b/packages/vscode-ide-companion/NOTICES.txt @@ -27412,6 +27412,33 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +============================================================ +react-resizable-panels@4.14.3 +(https://github.com/bvaughn/react-resizable-panels.git) + +The MIT License (MIT) + +Copyright (c) 2018 Brian Vaughn + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + ============================================================ rehype-katex@7.0.1 (https://github.com/remarkjs/remark-math/tree/main/packages/rehype-katex) @@ -29245,6 +29272,1529 @@ The above copyright notice and this permission notice shall be included in all c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +============================================================ +@pierre/diffs@1.5.2 +(No repository found) + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, and + distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by the + copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all other + entities that control, are controlled by, or are under common control with + that entity. For the purposes of this definition, "control" means (i) the + power, direct or indirect, to cause the direction or management of such + entity, whether by contract or otherwise, or (ii) ownership of fifty percent + (50%) or more of the outstanding shares, or (iii) beneficial ownership of + such entity. + + "You" (or "Your") shall mean an individual or Legal Entity exercising + permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation source, and + configuration files. + + "Object" form shall mean any form resulting from mechanical transformation + or translation of a Source form, including but not limited to compiled + object code, generated documentation, and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or Object form, + made available under the License, as indicated by a copyright notice that is + included in or attached to the work (an example is provided in the Appendix + below). + + "Derivative Works" shall mean any work, whether in Source or Object form, + that is based on (or derived from) the Work and for which the editorial + revisions, annotations, elaborations, or other modifications represent, as a + whole, an original work of authorship. For the purposes of this License, + Derivative Works shall not include works that remain separable from, or + merely link (or bind by name) to the interfaces of, the Work and Derivative + Works thereof. + + "Contribution" shall mean any work of authorship, including the original + version of the Work and any modifications or additions to that Work or + Derivative Works thereof, that is intentionally submitted to Licensor for + inclusion in the Work by the copyright owner or by an individual or Legal + Entity authorized to submit on behalf of the copyright owner. For the + purposes of this definition, "submitted" means any form of electronic, + verbal, or written communication sent to the Licensor or its + representatives, including but not limited to communication on electronic + mailing lists, source code control systems, and issue tracking systems that + are managed by, or on behalf of, the Licensor for the purpose of discussing + and improving the Work, but excluding communication that is conspicuously + marked or otherwise designated in writing by the copyright owner as "Not a + Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity on + behalf of whom a Contribution has been received by Licensor and subsequently + incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this + License, each Contributor hereby grants to You a perpetual, worldwide, + non-exclusive, no-charge, royalty-free, irrevocable copyright license to + reproduce, prepare Derivative Works of, publicly display, publicly perform, + sublicense, and distribute the Work and such Derivative Works in Source or + Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this + License, each Contributor hereby grants to You a perpetual, worldwide, + non-exclusive, no-charge, royalty-free, irrevocable (except as stated in + this section) patent license to make, have made, use, offer to sell, sell, + import, and otherwise transfer the Work, where such license applies only to + those patent claims licensable by such Contributor that are necessarily + infringed by their Contribution(s) alone or by combination of their + Contribution(s) with the Work to which such Contribution(s) was submitted. + If You institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work or a + Contribution incorporated within the Work constitutes direct or contributory + patent infringement, then any patent licenses granted to You under this + License for that Work shall terminate as of the date such litigation is + filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or + Derivative Works thereof in any medium, with or without modifications, and + in Source or Object form, provided that You meet the following conditions: + + (a) You must give any other recipients of the Work or Derivative Works a + copy of this License; and + + (b) You must cause any modified files to carry prominent notices stating + that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works that You + distribute, all copyright, patent, trademark, and attribution notices from + the Source form of the Work, excluding those notices that do not pertain to + any part of the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its distribution, + then any Derivative Works that You distribute must include a readable copy + of the attribution notices contained within such NOTICE file, excluding + those notices that do not pertain to any part of the Derivative Works, in at + least one of the following places: within a NOTICE text file distributed as + part of the Derivative Works; within the Source form or documentation, if + provided along with the Derivative Works; or, within a display generated by + the Derivative Works, if and wherever such third-party notices normally + appear. The contents of the NOTICE file are for informational purposes only + and do not modify the License. You may add Your own attribution notices + within Derivative Works that You distribute, alongside or as an addendum to + the NOTICE text from the Work, provided that such additional attribution + notices cannot be construed as modifying the License. + + You may add Your own copyright statement to Your modifications and may + provide additional or different license terms and conditions for use, + reproduction, or distribution of Your modifications, or for any such + Derivative Works as a whole, provided Your use, reproduction, and + distribution of the Work otherwise complies with the conditions stated in + this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any + Contribution intentionally submitted for inclusion in the Work by You to the + Licensor shall be under the terms and conditions of this License, without + any additional terms or conditions. Notwithstanding the above, nothing + herein shall supersede or modify the terms of any separate license agreement + you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, + trademarks, service marks, or product names of the Licensor, except as + required for reasonable and customary use in describing the origin of the + Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in + writing, Licensor provides the Work (and each Contributor provides its + Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied, including, without limitation, any + warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or + FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining + the appropriateness of using or redistributing the Work and assume any risks + associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in + tort (including negligence), contract, or otherwise, unless required by + applicable law (such as deliberate and grossly negligent acts) or agreed to + in writing, shall any Contributor be liable to You for damages, including + any direct, indirect, special, incidental, or consequential damages of any + character arising as a result of this License or out of the use or inability + to use the Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all other + commercial damages or losses), even if such Contributor has been advised of + the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or + Derivative Works thereof, You may choose to offer, and charge a fee for, + acceptance of support, warranty, indemnity, or other liability obligations + and/or rights consistent with this License. However, in accepting such + obligations, You may act only on Your own behalf and on Your sole + responsibility, not on behalf of any other Contributor, and only if You + agree to indemnify, defend, and hold each Contributor harmless for any + liability incurred by, or claims asserted against, such Contributor by + reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright 2025 Pierre Computer Company + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. + + +============================================================ +@shikijs/transformers@4.5.0 +(git+https://github.com/shikijs/shiki.git) + +MIT License + +Copyright (c) 2021 Pine Wu +Copyright (c) 2023 Anthony Fu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +@shikijs/core@4.5.0 +(git+https://github.com/shikijs/shiki.git) + +MIT License + +Copyright (c) 2021 Pine Wu +Copyright (c) 2023 Anthony Fu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +@shikijs/primitive@4.5.0 +(git+https://github.com/shikijs/shiki.git) + +MIT License + +Copyright (c) 2021 Pine Wu +Copyright (c) 2023 Anthony Fu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +@shikijs/types@4.5.0 +(git+https://github.com/shikijs/shiki.git) + +MIT License + +Copyright (c) 2021 Pine Wu +Copyright (c) 2023 Anthony Fu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +diff@9.0.0 +(https://github.com/kpdecker/jsdiff.git) + +BSD 3-Clause License + +Copyright (c) 2009-2015, Kevin Decker +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +============================================================ +lru_map@0.4.1 +(git+https://github.com/rsms/js-lru.git) + +Standard MIT license text (package declares MIT but ships no license file; copyright holder from package.json metadata). + +Copyright (c) Rasmus Andersson + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +============================================================ +shiki@4.5.0 +(git+https://github.com/shikijs/shiki.git) + +MIT License + +Copyright (c) 2021 Pine Wu +Copyright (c) 2023 Anthony Fu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +@shikijs/engine-javascript@4.5.0 +(git+https://github.com/shikijs/shiki.git) + +MIT License + +Copyright (c) 2021 Pine Wu +Copyright (c) 2023 Anthony Fu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +oniguruma-to-es@4.3.6 +(git+https://github.com/slevithan/oniguruma-to-es.git) + +MIT License + +Copyright (c) 2024-2026 Steven Levithan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +oniguruma-parser@0.12.2 +(git+https://github.com/slevithan/oniguruma-parser.git) + +MIT License + +Copyright (c) 2025-2026 Steven Levithan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +regex@6.1.0 +(git+https://github.com/slevithan/regex.git) + +MIT License + +Copyright (c) 2025 Steven Levithan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +regex-recursion@6.0.2 +(git+https://github.com/slevithan/regex-recursion.git) + +MIT License + +Copyright (c) 2025 Steven Levithan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +@shikijs/engine-oniguruma@4.5.0 +(git+https://github.com/shikijs/shiki.git) + +MIT License + +Copyright (c) 2021 Pine Wu +Copyright (c) 2023 Anthony Fu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +@shikijs/langs@4.5.0 +(git+https://github.com/shikijs/shiki.git) + +MIT License + +Copyright (c) 2021 Pine Wu +Copyright (c) 2023 Anthony Fu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +@shikijs/themes@4.5.0 +(git+https://github.com/shikijs/shiki.git) + +MIT License + +Copyright (c) 2021 Pine Wu +Copyright (c) 2023 Anthony Fu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +@pierre/theme@2.0.0 +(https://github.com/pierrecomputer/pierre.git) + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, and + distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by the + copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all other + entities that control, are controlled by, or are under common control with + that entity. For the purposes of this definition, "control" means (i) the + power, direct or indirect, to cause the direction or management of such + entity, whether by contract or otherwise, or (ii) ownership of fifty percent + (50%) or more of the outstanding shares, or (iii) beneficial ownership of + such entity. + + "You" (or "Your") shall mean an individual or Legal Entity exercising + permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation source, and + configuration files. + + "Object" form shall mean any form resulting from mechanical transformation + or translation of a Source form, including but not limited to compiled + object code, generated documentation, and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or Object form, + made available under the License, as indicated by a copyright notice that is + included in or attached to the work (an example is provided in the Appendix + below). + + "Derivative Works" shall mean any work, whether in Source or Object form, + that is based on (or derived from) the Work and for which the editorial + revisions, annotations, elaborations, or other modifications represent, as a + whole, an original work of authorship. For the purposes of this License, + Derivative Works shall not include works that remain separable from, or + merely link (or bind by name) to the interfaces of, the Work and Derivative + Works thereof. + + "Contribution" shall mean any work of authorship, including the original + version of the Work and any modifications or additions to that Work or + Derivative Works thereof, that is intentionally submitted to Licensor for + inclusion in the Work by the copyright owner or by an individual or Legal + Entity authorized to submit on behalf of the copyright owner. For the + purposes of this definition, "submitted" means any form of electronic, + verbal, or written communication sent to the Licensor or its + representatives, including but not limited to communication on electronic + mailing lists, source code control systems, and issue tracking systems that + are managed by, or on behalf of, the Licensor for the purpose of discussing + and improving the Work, but excluding communication that is conspicuously + marked or otherwise designated in writing by the copyright owner as "Not a + Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity on + behalf of whom a Contribution has been received by Licensor and subsequently + incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this + License, each Contributor hereby grants to You a perpetual, worldwide, + non-exclusive, no-charge, royalty-free, irrevocable copyright license to + reproduce, prepare Derivative Works of, publicly display, publicly perform, + sublicense, and distribute the Work and such Derivative Works in Source or + Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this + License, each Contributor hereby grants to You a perpetual, worldwide, + non-exclusive, no-charge, royalty-free, irrevocable (except as stated in + this section) patent license to make, have made, use, offer to sell, sell, + import, and otherwise transfer the Work, where such license applies only to + those patent claims licensable by such Contributor that are necessarily + infringed by their Contribution(s) alone or by combination of their + Contribution(s) with the Work to which such Contribution(s) was submitted. + If You institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work or a + Contribution incorporated within the Work constitutes direct or contributory + patent infringement, then any patent licenses granted to You under this + License for that Work shall terminate as of the date such litigation is + filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or + Derivative Works thereof in any medium, with or without modifications, and + in Source or Object form, provided that You meet the following conditions: + + (a) You must give any other recipients of the Work or Derivative Works a + copy of this License; and + + (b) You must cause any modified files to carry prominent notices stating + that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works that You + distribute, all copyright, patent, trademark, and attribution notices from + the Source form of the Work, excluding those notices that do not pertain to + any part of the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its distribution, + then any Derivative Works that You distribute must include a readable copy + of the attribution notices contained within such NOTICE file, excluding + those notices that do not pertain to any part of the Derivative Works, in at + least one of the following places: within a NOTICE text file distributed as + part of the Derivative Works; within the Source form or documentation, if + provided along with the Derivative Works; or, within a display generated by + the Derivative Works, if and wherever such third-party notices normally + appear. The contents of the NOTICE file are for informational purposes only + and do not modify the License. You may add Your own attribution notices + within Derivative Works that You distribute, alongside or as an addendum to + the NOTICE text from the Work, provided that such additional attribution + notices cannot be construed as modifying the License. + + You may add Your own copyright statement to Your modifications and may + provide additional or different license terms and conditions for use, + reproduction, or distribution of Your modifications, or for any such + Derivative Works as a whole, provided Your use, reproduction, and + distribution of the Work otherwise complies with the conditions stated in + this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any + Contribution intentionally submitted for inclusion in the Work by You to the + Licensor shall be under the terms and conditions of this License, without + any additional terms or conditions. Notwithstanding the above, nothing + herein shall supersede or modify the terms of any separate license agreement + you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, + trademarks, service marks, or product names of the Licensor, except as + required for reasonable and customary use in describing the origin of the + Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in + writing, Licensor provides the Work (and each Contributor provides its + Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied, including, without limitation, any + warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or + FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining + the appropriateness of using or redistributing the Work and assume any risks + associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in + tort (including negligence), contract, or otherwise, unless required by + applicable law (such as deliberate and grossly negligent acts) or agreed to + in writing, shall any Contributor be liable to You for damages, including + any direct, indirect, special, incidental, or consequential damages of any + character arising as a result of this License or out of the use or inability + to use the Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all other + commercial damages or losses), even if such Contributor has been advised of + the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or + Derivative Works thereof, You may choose to offer, and charge a fee for, + acceptance of support, warranty, indemnity, or other liability obligations + and/or rights consistent with this License. However, in accepting such + obligations, You may act only on Your own behalf and on Your sole + responsibility, not on behalf of any other Contributor, and only if You + agree to indemnify, defend, and hold each Contributor harmless for any + liability incurred by, or claims asserted against, such Contributor by + reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright 2025 Pierre Computer Company + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. + +--- NOTICE --- + +This theme was built on top of +[GitHub's Visual Studio Code Theme](https://github.com/primer/github-vscode-theme), +reusing its technique and build tooling, which we have since iterated on for +more specific language tokens. + +`@pierre/theme` is licensed under Apache-2.0 (see `LICENSE`). The original MIT +license for `primer/github-vscode-theme` is included below for attribution. + +Original license for `primer/github-vscode-theme`: + +``` +MIT License + +Copyright (c) 2020 Primer + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +``` + +============================================================ +@pierre/theming@1.0.1 +(No repository found) + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, and + distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by the + copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all other + entities that control, are controlled by, or are under common control with + that entity. For the purposes of this definition, "control" means (i) the + power, direct or indirect, to cause the direction or management of such + entity, whether by contract or otherwise, or (ii) ownership of fifty percent + (50%) or more of the outstanding shares, or (iii) beneficial ownership of + such entity. + + "You" (or "Your") shall mean an individual or Legal Entity exercising + permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation source, and + configuration files. + + "Object" form shall mean any form resulting from mechanical transformation + or translation of a Source form, including but not limited to compiled + object code, generated documentation, and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or Object form, + made available under the License, as indicated by a copyright notice that is + included in or attached to the work (an example is provided in the Appendix + below). + + "Derivative Works" shall mean any work, whether in Source or Object form, + that is based on (or derived from) the Work and for which the editorial + revisions, annotations, elaborations, or other modifications represent, as a + whole, an original work of authorship. For the purposes of this License, + Derivative Works shall not include works that remain separable from, or + merely link (or bind by name) to the interfaces of, the Work and Derivative + Works thereof. + + "Contribution" shall mean any work of authorship, including the original + version of the Work and any modifications or additions to that Work or + Derivative Works thereof, that is intentionally submitted to Licensor for + inclusion in the Work by the copyright owner or by an individual or Legal + Entity authorized to submit on behalf of the copyright owner. For the + purposes of this definition, "submitted" means any form of electronic, + verbal, or written communication sent to the Licensor or its + representatives, including but not limited to communication on electronic + mailing lists, source code control systems, and issue tracking systems that + are managed by, or on behalf of, the Licensor for the purpose of discussing + and improving the Work, but excluding communication that is conspicuously + marked or otherwise designated in writing by the copyright owner as "Not a + Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity on + behalf of whom a Contribution has been received by Licensor and subsequently + incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this + License, each Contributor hereby grants to You a perpetual, worldwide, + non-exclusive, no-charge, royalty-free, irrevocable copyright license to + reproduce, prepare Derivative Works of, publicly display, publicly perform, + sublicense, and distribute the Work and such Derivative Works in Source or + Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this + License, each Contributor hereby grants to You a perpetual, worldwide, + non-exclusive, no-charge, royalty-free, irrevocable (except as stated in + this section) patent license to make, have made, use, offer to sell, sell, + import, and otherwise transfer the Work, where such license applies only to + those patent claims licensable by such Contributor that are necessarily + infringed by their Contribution(s) alone or by combination of their + Contribution(s) with the Work to which such Contribution(s) was submitted. + If You institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work or a + Contribution incorporated within the Work constitutes direct or contributory + patent infringement, then any patent licenses granted to You under this + License for that Work shall terminate as of the date such litigation is + filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or + Derivative Works thereof in any medium, with or without modifications, and + in Source or Object form, provided that You meet the following conditions: + + (a) You must give any other recipients of the Work or Derivative Works a + copy of this License; and + + (b) You must cause any modified files to carry prominent notices stating + that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works that You + distribute, all copyright, patent, trademark, and attribution notices from + the Source form of the Work, excluding those notices that do not pertain to + any part of the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its distribution, + then any Derivative Works that You distribute must include a readable copy + of the attribution notices contained within such NOTICE file, excluding + those notices that do not pertain to any part of the Derivative Works, in at + least one of the following places: within a NOTICE text file distributed as + part of the Derivative Works; within the Source form or documentation, if + provided along with the Derivative Works; or, within a display generated by + the Derivative Works, if and wherever such third-party notices normally + appear. The contents of the NOTICE file are for informational purposes only + and do not modify the License. You may add Your own attribution notices + within Derivative Works that You distribute, alongside or as an addendum to + the NOTICE text from the Work, provided that such additional attribution + notices cannot be construed as modifying the License. + + You may add Your own copyright statement to Your modifications and may + provide additional or different license terms and conditions for use, + reproduction, or distribution of Your modifications, or for any such + Derivative Works as a whole, provided Your use, reproduction, and + distribution of the Work otherwise complies with the conditions stated in + this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any + Contribution intentionally submitted for inclusion in the Work by You to the + Licensor shall be under the terms and conditions of this License, without + any additional terms or conditions. Notwithstanding the above, nothing + herein shall supersede or modify the terms of any separate license agreement + you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, + trademarks, service marks, or product names of the Licensor, except as + required for reasonable and customary use in describing the origin of the + Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in + writing, Licensor provides the Work (and each Contributor provides its + Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied, including, without limitation, any + warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or + FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining + the appropriateness of using or redistributing the Work and assume any risks + associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in + tort (including negligence), contract, or otherwise, unless required by + applicable law (such as deliberate and grossly negligent acts) or agreed to + in writing, shall any Contributor be liable to You for damages, including + any direct, indirect, special, incidental, or consequential damages of any + character arising as a result of this License or out of the use or inability + to use the Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all other + commercial damages or losses), even if such Contributor has been advised of + the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or + Derivative Works thereof, You may choose to offer, and charge a fee for, + acceptance of support, warranty, indemnity, or other liability obligations + and/or rights consistent with this License. However, in accepting such + obligations, You may act only on Your own behalf and on Your sole + responsibility, not on behalf of any other Contributor, and only if You + agree to indemnify, defend, and hold each Contributor harmless for any + liability incurred by, or claims asserted against, such Contributor by + reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright 2025 Pierre Computer Company + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. + + +============================================================ +@pierre/trees@1.0.0-beta.6 +(No repository found) + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, and + distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by the + copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all other + entities that control, are controlled by, or are under common control with + that entity. For the purposes of this definition, "control" means (i) the + power, direct or indirect, to cause the direction or management of such + entity, whether by contract or otherwise, or (ii) ownership of fifty percent + (50%) or more of the outstanding shares, or (iii) beneficial ownership of + such entity. + + "You" (or "Your") shall mean an individual or Legal Entity exercising + permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation source, and + configuration files. + + "Object" form shall mean any form resulting from mechanical transformation + or translation of a Source form, including but not limited to compiled + object code, generated documentation, and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or Object form, + made available under the License, as indicated by a copyright notice that is + included in or attached to the work (an example is provided in the Appendix + below). + + "Derivative Works" shall mean any work, whether in Source or Object form, + that is based on (or derived from) the Work and for which the editorial + revisions, annotations, elaborations, or other modifications represent, as a + whole, an original work of authorship. For the purposes of this License, + Derivative Works shall not include works that remain separable from, or + merely link (or bind by name) to the interfaces of, the Work and Derivative + Works thereof. + + "Contribution" shall mean any work of authorship, including the original + version of the Work and any modifications or additions to that Work or + Derivative Works thereof, that is intentionally submitted to Licensor for + inclusion in the Work by the copyright owner or by an individual or Legal + Entity authorized to submit on behalf of the copyright owner. For the + purposes of this definition, "submitted" means any form of electronic, + verbal, or written communication sent to the Licensor or its + representatives, including but not limited to communication on electronic + mailing lists, source code control systems, and issue tracking systems that + are managed by, or on behalf of, the Licensor for the purpose of discussing + and improving the Work, but excluding communication that is conspicuously + marked or otherwise designated in writing by the copyright owner as "Not a + Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity on + behalf of whom a Contribution has been received by Licensor and subsequently + incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this + License, each Contributor hereby grants to You a perpetual, worldwide, + non-exclusive, no-charge, royalty-free, irrevocable copyright license to + reproduce, prepare Derivative Works of, publicly display, publicly perform, + sublicense, and distribute the Work and such Derivative Works in Source or + Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this + License, each Contributor hereby grants to You a perpetual, worldwide, + non-exclusive, no-charge, royalty-free, irrevocable (except as stated in + this section) patent license to make, have made, use, offer to sell, sell, + import, and otherwise transfer the Work, where such license applies only to + those patent claims licensable by such Contributor that are necessarily + infringed by their Contribution(s) alone or by combination of their + Contribution(s) with the Work to which such Contribution(s) was submitted. + If You institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work or a + Contribution incorporated within the Work constitutes direct or contributory + patent infringement, then any patent licenses granted to You under this + License for that Work shall terminate as of the date such litigation is + filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or + Derivative Works thereof in any medium, with or without modifications, and + in Source or Object form, provided that You meet the following conditions: + + (a) You must give any other recipients of the Work or Derivative Works a + copy of this License; and + + (b) You must cause any modified files to carry prominent notices stating + that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works that You + distribute, all copyright, patent, trademark, and attribution notices from + the Source form of the Work, excluding those notices that do not pertain to + any part of the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its distribution, + then any Derivative Works that You distribute must include a readable copy + of the attribution notices contained within such NOTICE file, excluding + those notices that do not pertain to any part of the Derivative Works, in at + least one of the following places: within a NOTICE text file distributed as + part of the Derivative Works; within the Source form or documentation, if + provided along with the Derivative Works; or, within a display generated by + the Derivative Works, if and wherever such third-party notices normally + appear. The contents of the NOTICE file are for informational purposes only + and do not modify the License. You may add Your own attribution notices + within Derivative Works that You distribute, alongside or as an addendum to + the NOTICE text from the Work, provided that such additional attribution + notices cannot be construed as modifying the License. + + You may add Your own copyright statement to Your modifications and may + provide additional or different license terms and conditions for use, + reproduction, or distribution of Your modifications, or for any such + Derivative Works as a whole, provided Your use, reproduction, and + distribution of the Work otherwise complies with the conditions stated in + this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any + Contribution intentionally submitted for inclusion in the Work by You to the + Licensor shall be under the terms and conditions of this License, without + any additional terms or conditions. Notwithstanding the above, nothing + herein shall supersede or modify the terms of any separate license agreement + you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, + trademarks, service marks, or product names of the Licensor, except as + required for reasonable and customary use in describing the origin of the + Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in + writing, Licensor provides the Work (and each Contributor provides its + Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied, including, without limitation, any + warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or + FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining + the appropriateness of using or redistributing the Work and assume any risks + associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in + tort (including negligence), contract, or otherwise, unless required by + applicable law (such as deliberate and grossly negligent acts) or agreed to + in writing, shall any Contributor be liable to You for damages, including + any direct, indirect, special, incidental, or consequential damages of any + character arising as a result of this License or out of the use or inability + to use the Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all other + commercial damages or losses), even if such Contributor has been advised of + the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or + Derivative Works thereof, You may choose to offer, and charge a fee for, + acceptance of support, warranty, indemnity, or other liability obligations + and/or rights consistent with this License. However, in accepting such + obligations, You may act only on Your own behalf and on Your sole + responsibility, not on behalf of any other Contributor, and only if You + agree to indemnify, defend, and hold each Contributor harmless for any + liability incurred by, or claims asserted against, such Contributor by + reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright 2025 Pierre Computer Company + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. + +--- NOTICE --- + +This project includes some code derived from +[@headless-tree/core](https://github.com/lukasbach/headless-tree). + +The initial version of this project used `headless-tree` as the underlying tree +implementation. We have since written our own core at `packages/path-store`, but +many of the best ideas from `headless-tree` made their way to `path-store` and +`trees`. It's hard to identify exactly which code this is at this point, but +definitely things like the drag and drop implementation and the general list +approach to rendering and I'm sure more. The work that `@lukasbach` has +contributed to this space is greatly appreciated. `<3` + +Original license for `headless-tree/core`: + +``` +MIT License + +Copyright (c) 2023 Lukas Bach + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +``` + +============================================================ +preact@11.0.0-beta.0 +(https://github.com/preactjs/preact) + +The MIT License (MIT) + +Copyright (c) 2015-present Jason Miller + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +preact-render-to-string@6.6.5 +(https://github.com/preactjs/preact-render-to-string) + +The MIT License (MIT) + +Copyright (c) 2015 Jason Miller + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +@pierre/theming@1.0.0 +(No repository found) + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, and + distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by the + copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all other + entities that control, are controlled by, or are under common control with + that entity. For the purposes of this definition, "control" means (i) the + power, direct or indirect, to cause the direction or management of such + entity, whether by contract or otherwise, or (ii) ownership of fifty percent + (50%) or more of the outstanding shares, or (iii) beneficial ownership of + such entity. + + "You" (or "Your") shall mean an individual or Legal Entity exercising + permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation source, and + configuration files. + + "Object" form shall mean any form resulting from mechanical transformation + or translation of a Source form, including but not limited to compiled + object code, generated documentation, and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or Object form, + made available under the License, as indicated by a copyright notice that is + included in or attached to the work (an example is provided in the Appendix + below). + + "Derivative Works" shall mean any work, whether in Source or Object form, + that is based on (or derived from) the Work and for which the editorial + revisions, annotations, elaborations, or other modifications represent, as a + whole, an original work of authorship. For the purposes of this License, + Derivative Works shall not include works that remain separable from, or + merely link (or bind by name) to the interfaces of, the Work and Derivative + Works thereof. + + "Contribution" shall mean any work of authorship, including the original + version of the Work and any modifications or additions to that Work or + Derivative Works thereof, that is intentionally submitted to Licensor for + inclusion in the Work by the copyright owner or by an individual or Legal + Entity authorized to submit on behalf of the copyright owner. For the + purposes of this definition, "submitted" means any form of electronic, + verbal, or written communication sent to the Licensor or its + representatives, including but not limited to communication on electronic + mailing lists, source code control systems, and issue tracking systems that + are managed by, or on behalf of, the Licensor for the purpose of discussing + and improving the Work, but excluding communication that is conspicuously + marked or otherwise designated in writing by the copyright owner as "Not a + Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity on + behalf of whom a Contribution has been received by Licensor and subsequently + incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this + License, each Contributor hereby grants to You a perpetual, worldwide, + non-exclusive, no-charge, royalty-free, irrevocable copyright license to + reproduce, prepare Derivative Works of, publicly display, publicly perform, + sublicense, and distribute the Work and such Derivative Works in Source or + Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this + License, each Contributor hereby grants to You a perpetual, worldwide, + non-exclusive, no-charge, royalty-free, irrevocable (except as stated in + this section) patent license to make, have made, use, offer to sell, sell, + import, and otherwise transfer the Work, where such license applies only to + those patent claims licensable by such Contributor that are necessarily + infringed by their Contribution(s) alone or by combination of their + Contribution(s) with the Work to which such Contribution(s) was submitted. + If You institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work or a + Contribution incorporated within the Work constitutes direct or contributory + patent infringement, then any patent licenses granted to You under this + License for that Work shall terminate as of the date such litigation is + filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or + Derivative Works thereof in any medium, with or without modifications, and + in Source or Object form, provided that You meet the following conditions: + + (a) You must give any other recipients of the Work or Derivative Works a + copy of this License; and + + (b) You must cause any modified files to carry prominent notices stating + that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works that You + distribute, all copyright, patent, trademark, and attribution notices from + the Source form of the Work, excluding those notices that do not pertain to + any part of the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its distribution, + then any Derivative Works that You distribute must include a readable copy + of the attribution notices contained within such NOTICE file, excluding + those notices that do not pertain to any part of the Derivative Works, in at + least one of the following places: within a NOTICE text file distributed as + part of the Derivative Works; within the Source form or documentation, if + provided along with the Derivative Works; or, within a display generated by + the Derivative Works, if and wherever such third-party notices normally + appear. The contents of the NOTICE file are for informational purposes only + and do not modify the License. You may add Your own attribution notices + within Derivative Works that You distribute, alongside or as an addendum to + the NOTICE text from the Work, provided that such additional attribution + notices cannot be construed as modifying the License. + + You may add Your own copyright statement to Your modifications and may + provide additional or different license terms and conditions for use, + reproduction, or distribution of Your modifications, or for any such + Derivative Works as a whole, provided Your use, reproduction, and + distribution of the Work otherwise complies with the conditions stated in + this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any + Contribution intentionally submitted for inclusion in the Work by You to the + Licensor shall be under the terms and conditions of this License, without + any additional terms or conditions. Notwithstanding the above, nothing + herein shall supersede or modify the terms of any separate license agreement + you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, + trademarks, service marks, or product names of the Licensor, except as + required for reasonable and customary use in describing the origin of the + Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in + writing, Licensor provides the Work (and each Contributor provides its + Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied, including, without limitation, any + warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or + FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining + the appropriateness of using or redistributing the Work and assume any risks + associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in + tort (including negligence), contract, or otherwise, unless required by + applicable law (such as deliberate and grossly negligent acts) or agreed to + in writing, shall any Contributor be liable to You for damages, including + any direct, indirect, special, incidental, or consequential damages of any + character arising as a result of this License or out of the use or inability + to use the Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all other + commercial damages or losses), even if such Contributor has been advised of + the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or + Derivative Works thereof, You may choose to offer, and charge a fee for, + acceptance of support, warranty, indemnity, or other liability obligations + and/or rights consistent with this License. However, in accepting such + obligations, You may act only on Your own behalf and on Your sole + responsibility, not on behalf of any other Contributor, and only if You + agree to indemnify, defend, and hold each Contributor harmless for any + liability incurred by, or claims asserted against, such Contributor by + reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright 2025 Pierre Computer Company + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. + + ============================================================ markdown-it@14.2.0 (https://github.com/markdown-it/markdown-it) diff --git a/packages/vscode-ide-companion/scripts/generate-notices.js b/packages/vscode-ide-companion/scripts/generate-notices.js index 3a509895207..3921964d30b 100644 --- a/packages/vscode-ide-companion/scripts/generate-notices.js +++ b/packages/vscode-ide-companion/scripts/generate-notices.js @@ -13,7 +13,6 @@ const projectRoot = path.resolve( path.join(path.dirname(fileURLToPath(import.meta.url)), '..', '..', '..'), ); const packagePath = path.join(projectRoot, 'packages', 'vscode-ide-companion'); -const noticeFilePath = path.join(packagePath, 'NOTICES.txt'); /** * Standard MIT license text used when a package declares MIT but ships no @@ -415,7 +414,13 @@ export async function collectDependencies( } } - for (const depName of Object.keys(manifest.dependencies ?? {})) { + const bundled = dir.split(path.sep).includes('node_modules') + ? [] + : (manifest.bundledDevDependencies ?? []); + for (const depName of [ + ...Object.keys(manifest.dependencies ?? {}), + ...bundled, + ]) { // Web Shell uses ExcelJS's prebuilt browser entry. These Node-only branches // are not in that bundle; its actual embedded packages are inventoried below. if ( @@ -452,77 +457,84 @@ export async function getExceljsBrowserNotices(packageDir) { return inventory.packages; } -async function main() { - try { - const packageJsonPath = path.join(packagePath, 'package.json'); - const packageJsonContent = await fs.readFile(packageJsonPath, 'utf-8'); - const packageJson = JSON.parse(packageJsonContent); +async function main({ packageDir = packagePath, bundledOnly = false } = {}) { + const packageJsonPath = path.join(packageDir, 'package.json'); + const packageJsonContent = await fs.readFile(packageJsonPath, 'utf-8'); + const packageJson = JSON.parse(packageJsonContent); - const allDependencies = new Map(); - const visitedDirs = new Set(); - const directDependencies = Object.keys(packageJson.dependencies); + const allDependencies = new Map(); + const visitedDirs = new Set(); + const directDependencies = bundledOnly + ? (packageJson.bundledDevDependencies ?? []) + : Object.keys(packageJson.dependencies); - // Sequential on purpose: the traversal order is the file's order, and it - // must not depend on which filesystem read finishes first. - for (const depName of directDependencies) { - await collectDependencies( - depName, - packagePath, - allDependencies, - visitedDirs, - ); + if (bundledOnly) { + if (directDependencies.length === 0) + throw new Error('No bundled dependency seeds declared'); + for (const name of directDependencies) { + if (!(await resolveInstalled(name, packageDir))) + throw new Error(`Bundled dependency ${name} is not installed`); } - - const dependencyEntries = Array.from(allDependencies.values()); - - const exceljs = dependencyEntries.find(({ name }) => name === 'exceljs'); - const browserLicenses = exceljs - ? await getExceljsBrowserNotices(exceljs.dir) - : []; - const bundledLicenses = new Map( - browserLicenses.map((license) => [ - `${license.name}@${license.version}`, - license, - ]), - ); - const licensePromises = dependencyEntries.map( - ({ name, version, dir }) => - bundledLicenses.get(`${name}@${version}`) ?? - getDependencyLicense(name, version, dir), - ); - const dependencyLicenses = [ - ...(await Promise.all(licensePromises)), - ...browserLicenses.filter( - ({ name, version }) => !allDependencies.has(`${name}@${version}`), - ), - ]; - - let noticeText = - 'This file contains third-party software notices and license terms.\n\n'; - - for (const dep of dependencyLicenses) { - noticeText += - '============================================================\n'; - noticeText += `${dep.name}@${dep.version}\n`; - noticeText += `(${dep.repository})\n\n`; - noticeText += `${dep.license}\n\n`; - } - - // Normalize line endings to LF. Third-party license files may use CRLF, - // which would otherwise be embedded verbatim and produce spurious diffs - // (the file is declared `eol=lf` in .gitattributes). - noticeText = noticeText.replace(/\r\n/g, '\n'); - - await fs.writeFile(noticeFilePath, noticeText); - console.log(`NOTICES.txt generated at ${noticeFilePath}`); - console.log(`Total dependencies: ${dependencyLicenses.length}`); - } catch (error) { - console.error('Error generating NOTICES.txt:', error); - process.exit(1); } + + // Sequential on purpose: the traversal order is the file's order, and it + // must not depend on which filesystem read finishes first. + for (const depName of directDependencies) { + await collectDependencies( + depName, + packageDir, + allDependencies, + visitedDirs, + ); + } + + const dependencyEntries = Array.from(allDependencies.values()); + + const exceljs = dependencyEntries.find(({ name }) => name === 'exceljs'); + const browserLicenses = exceljs + ? await getExceljsBrowserNotices(exceljs.dir) + : []; + const bundledLicenses = new Map( + browserLicenses.map((license) => [ + `${license.name}@${license.version}`, + license, + ]), + ); + const licensePromises = dependencyEntries.map( + ({ name, version, dir }) => + bundledLicenses.get(`${name}@${version}`) ?? + getDependencyLicense(name, version, dir), + ); + const dependencyLicenses = [ + ...(await Promise.all(licensePromises)), + ...browserLicenses.filter( + ({ name, version }) => !allDependencies.has(`${name}@${version}`), + ), + ]; + + let noticeText = + 'This file contains third-party software notices and license terms.\n\n'; + + for (const dep of dependencyLicenses) { + noticeText += + '============================================================\n'; + noticeText += `${dep.name}@${dep.version}\n`; + noticeText += `(${dep.repository})\n\n`; + noticeText += `${dep.license}\n\n`; + } + + // Normalize line endings to LF. Third-party license files may use CRLF, + // which would otherwise be embedded verbatim and produce spurious diffs + // (the file is declared `eol=lf` in .gitattributes). + noticeText = noticeText.replace(/\r\n/g, '\n'); + + const noticeFilePath = path.join(packageDir, 'NOTICES.txt'); + await fs.writeFile(noticeFilePath, noticeText); + console.log(`NOTICES.txt generated at ${noticeFilePath}`); + console.log(`Total dependencies: ${dependencyLicenses.length}`); } -export async function runNoticeGeneration(env = process.env) { +export async function runNoticeGeneration(env = process.env, options) { const skipGeneration = ['1', 'true'].includes( (env.QWEN_SKIP_NOTICE_GENERATION ?? '').toLowerCase(), ); @@ -534,7 +546,7 @@ export async function runNoticeGeneration(env = process.env) { return; } - await main(); + await main(options); } // Only run when executed directly (e.g. `npm run generate:notices`), not when @@ -543,5 +555,12 @@ if ( process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url) ) { - runNoticeGeneration().catch(console.error); + const options = + process.argv[2] === '--bundled' + ? { packageDir: path.resolve(process.argv[3]), bundledOnly: true } + : undefined; + runNoticeGeneration(process.env, options).catch((error) => { + console.error('Error generating NOTICES.txt:', error); + process.exitCode = 1; + }); } diff --git a/packages/vscode-ide-companion/scripts/generate-notices.test.js b/packages/vscode-ide-companion/scripts/generate-notices.test.js index 441f611c1e1..65768cd4044 100644 --- a/packages/vscode-ide-companion/scripts/generate-notices.test.js +++ b/packages/vscode-ide-companion/scripts/generate-notices.test.js @@ -6,6 +6,8 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import fs from 'node:fs/promises'; +import { spawnSync } from 'node:child_process'; +import { fileURLToPath } from 'node:url'; import os from 'node:os'; import path from 'node:path'; import { createRequire } from 'node:module'; @@ -392,6 +394,95 @@ describe('collectDependencies', () => { expect([...dependencies.keys()]).toEqual(['hoisted@2.0.0', 'leaf@3.1.0']); }); + + it('rejects missing bundled seeds without overwriting committed attribution', async () => { + await writePackage(root, { bundledDevDependencies: ['missing-package'] }); + const output = path.join(root, 'NOTICES.txt'); + await fs.writeFile(output, 'EXISTING ATTRIBUTION'); + await expect( + runNoticeGeneration({}, { packageDir: root, bundledOnly: true }), + ).rejects.toThrow('missing-package'); + expect(await fs.readFile(output, 'utf8')).toBe('EXISTING ATTRIBUTION'); + }); + + it('includes declared bundled dev dependencies and their notices, excluding other dev tools', async () => { + const workspace = path.join(root, 'packages', 'web-shell'); + await writePackage(workspace, { + name: '@qwen-code/web-shell', + version: '1.0.0', + bundledDevDependencies: ['bundled'], + dependencies: { ordinary: '1.0.0' }, + devDependencies: { bundled: '1.0.0', unused: '1.0.0' }, + }); + await fs.mkdir(path.join(root, 'node_modules', '@qwen-code'), { + recursive: true, + }); + await fs.symlink( + workspace, + path.join(root, 'node_modules', '@qwen-code', 'web-shell'), + 'junction', + ); + for (const name of ['ordinary', 'unused', 'extra']) + await writePackage(path.join(root, 'node_modules', name), { + name, + version: '1.0.0', + license: 'MIT', + }); + const bundled = path.join(root, 'node_modules', 'bundled'); + await writePackage(bundled, { + name: 'bundled', + version: '1.0.0', + dependencies: { leaf: '1.0.0' }, + bundledDevDependencies: ['extra'], + }); + await fs.writeFile(path.join(bundled, 'LICENSE'), 'BUNDLED LICENSE'); + await fs.writeFile(path.join(bundled, 'NOTICE.md'), 'DERIVED CODE CREDIT'); + await writePackage(path.join(root, 'node_modules', 'leaf'), { + name: 'leaf', + version: '1.0.0', + license: 'MIT', + }); + const dependencies = new Map(); + await collectDependencies( + '@qwen-code/web-shell', + root, + dependencies, + new Set(), + ); + expect([...dependencies.keys()]).toEqual([ + 'ordinary@1.0.0', + 'bundled@1.0.0', + 'leaf@1.0.0', + ]); + await runNoticeGeneration({}, { packageDir: workspace, bundledOnly: true }); + const notice = await fs.readFile( + path.join(workspace, 'NOTICES.txt'), + 'utf8', + ); + expect(notice).toContain('bundled@1.0.0'); + expect(notice).toContain('BUNDLED LICENSE'); + expect(notice).toContain('DERIVED CODE CREDIT'); + expect(notice).toContain('leaf@1.0.0'); + expect(notice).not.toContain('unused'); + expect(notice).not.toContain('ordinary'); + await fs.unlink(path.join(workspace, 'NOTICES.txt')); + const result = spawnSync( + process.execPath, + [ + fileURLToPath(new URL('./generate-notices.js', import.meta.url)), + '--bundled', + workspace, + ], + { + encoding: 'utf8', + env: { ...process.env, QWEN_SKIP_NOTICE_GENERATION: '' }, + }, + ); + expect(result.status, result.stderr).toBe(0); + expect(await fs.readFile(path.join(workspace, 'NOTICES.txt'), 'utf8')).toBe( + notice, + ); + }); }); describe('normalizeRepositoryUrl', () => { diff --git a/packages/web-shell/NOTICES.txt b/packages/web-shell/NOTICES.txt new file mode 100644 index 00000000000..c9d90dcd681 --- /dev/null +++ b/packages/web-shell/NOTICES.txt @@ -0,0 +1,2435 @@ +This file contains third-party software notices and license terms. + +============================================================ +@pierre/diffs@1.5.2 +(No repository found) + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, and + distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by the + copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all other + entities that control, are controlled by, or are under common control with + that entity. For the purposes of this definition, "control" means (i) the + power, direct or indirect, to cause the direction or management of such + entity, whether by contract or otherwise, or (ii) ownership of fifty percent + (50%) or more of the outstanding shares, or (iii) beneficial ownership of + such entity. + + "You" (or "Your") shall mean an individual or Legal Entity exercising + permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation source, and + configuration files. + + "Object" form shall mean any form resulting from mechanical transformation + or translation of a Source form, including but not limited to compiled + object code, generated documentation, and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or Object form, + made available under the License, as indicated by a copyright notice that is + included in or attached to the work (an example is provided in the Appendix + below). + + "Derivative Works" shall mean any work, whether in Source or Object form, + that is based on (or derived from) the Work and for which the editorial + revisions, annotations, elaborations, or other modifications represent, as a + whole, an original work of authorship. For the purposes of this License, + Derivative Works shall not include works that remain separable from, or + merely link (or bind by name) to the interfaces of, the Work and Derivative + Works thereof. + + "Contribution" shall mean any work of authorship, including the original + version of the Work and any modifications or additions to that Work or + Derivative Works thereof, that is intentionally submitted to Licensor for + inclusion in the Work by the copyright owner or by an individual or Legal + Entity authorized to submit on behalf of the copyright owner. For the + purposes of this definition, "submitted" means any form of electronic, + verbal, or written communication sent to the Licensor or its + representatives, including but not limited to communication on electronic + mailing lists, source code control systems, and issue tracking systems that + are managed by, or on behalf of, the Licensor for the purpose of discussing + and improving the Work, but excluding communication that is conspicuously + marked or otherwise designated in writing by the copyright owner as "Not a + Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity on + behalf of whom a Contribution has been received by Licensor and subsequently + incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this + License, each Contributor hereby grants to You a perpetual, worldwide, + non-exclusive, no-charge, royalty-free, irrevocable copyright license to + reproduce, prepare Derivative Works of, publicly display, publicly perform, + sublicense, and distribute the Work and such Derivative Works in Source or + Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this + License, each Contributor hereby grants to You a perpetual, worldwide, + non-exclusive, no-charge, royalty-free, irrevocable (except as stated in + this section) patent license to make, have made, use, offer to sell, sell, + import, and otherwise transfer the Work, where such license applies only to + those patent claims licensable by such Contributor that are necessarily + infringed by their Contribution(s) alone or by combination of their + Contribution(s) with the Work to which such Contribution(s) was submitted. + If You institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work or a + Contribution incorporated within the Work constitutes direct or contributory + patent infringement, then any patent licenses granted to You under this + License for that Work shall terminate as of the date such litigation is + filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or + Derivative Works thereof in any medium, with or without modifications, and + in Source or Object form, provided that You meet the following conditions: + + (a) You must give any other recipients of the Work or Derivative Works a + copy of this License; and + + (b) You must cause any modified files to carry prominent notices stating + that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works that You + distribute, all copyright, patent, trademark, and attribution notices from + the Source form of the Work, excluding those notices that do not pertain to + any part of the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its distribution, + then any Derivative Works that You distribute must include a readable copy + of the attribution notices contained within such NOTICE file, excluding + those notices that do not pertain to any part of the Derivative Works, in at + least one of the following places: within a NOTICE text file distributed as + part of the Derivative Works; within the Source form or documentation, if + provided along with the Derivative Works; or, within a display generated by + the Derivative Works, if and wherever such third-party notices normally + appear. The contents of the NOTICE file are for informational purposes only + and do not modify the License. You may add Your own attribution notices + within Derivative Works that You distribute, alongside or as an addendum to + the NOTICE text from the Work, provided that such additional attribution + notices cannot be construed as modifying the License. + + You may add Your own copyright statement to Your modifications and may + provide additional or different license terms and conditions for use, + reproduction, or distribution of Your modifications, or for any such + Derivative Works as a whole, provided Your use, reproduction, and + distribution of the Work otherwise complies with the conditions stated in + this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any + Contribution intentionally submitted for inclusion in the Work by You to the + Licensor shall be under the terms and conditions of this License, without + any additional terms or conditions. Notwithstanding the above, nothing + herein shall supersede or modify the terms of any separate license agreement + you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, + trademarks, service marks, or product names of the Licensor, except as + required for reasonable and customary use in describing the origin of the + Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in + writing, Licensor provides the Work (and each Contributor provides its + Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied, including, without limitation, any + warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or + FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining + the appropriateness of using or redistributing the Work and assume any risks + associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in + tort (including negligence), contract, or otherwise, unless required by + applicable law (such as deliberate and grossly negligent acts) or agreed to + in writing, shall any Contributor be liable to You for damages, including + any direct, indirect, special, incidental, or consequential damages of any + character arising as a result of this License or out of the use or inability + to use the Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all other + commercial damages or losses), even if such Contributor has been advised of + the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or + Derivative Works thereof, You may choose to offer, and charge a fee for, + acceptance of support, warranty, indemnity, or other liability obligations + and/or rights consistent with this License. However, in accepting such + obligations, You may act only on Your own behalf and on Your sole + responsibility, not on behalf of any other Contributor, and only if You + agree to indemnify, defend, and hold each Contributor harmless for any + liability incurred by, or claims asserted against, such Contributor by + reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright 2025 Pierre Computer Company + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. + + +============================================================ +@shikijs/transformers@4.5.0 +(git+https://github.com/shikijs/shiki.git) + +MIT License + +Copyright (c) 2021 Pine Wu +Copyright (c) 2023 Anthony Fu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +@shikijs/core@4.5.0 +(git+https://github.com/shikijs/shiki.git) + +MIT License + +Copyright (c) 2021 Pine Wu +Copyright (c) 2023 Anthony Fu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +@shikijs/primitive@4.5.0 +(git+https://github.com/shikijs/shiki.git) + +MIT License + +Copyright (c) 2021 Pine Wu +Copyright (c) 2023 Anthony Fu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +@shikijs/types@4.5.0 +(git+https://github.com/shikijs/shiki.git) + +MIT License + +Copyright (c) 2021 Pine Wu +Copyright (c) 2023 Anthony Fu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +@shikijs/vscode-textmate@10.0.2 +(https://github.com/shikijs/vscode-textmate) + +The MIT License (MIT) + +Copyright (c) Microsoft Corporation + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +@types/hast@3.0.5 +(https://github.com/DefinitelyTyped/DefinitelyTyped.git) + + MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE + + +============================================================ +@types/unist@3.0.3 +(https://github.com/DefinitelyTyped/DefinitelyTyped.git) + + MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE + + +============================================================ +hast-util-to-html@9.0.5 +(https://github.com/syntax-tree/hast-util-to-html) + +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +============================================================ +ccount@2.0.1 +(https://github.com/wooorm/ccount) + +(The MIT License) + +Copyright (c) 2015 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +============================================================ +comma-separated-tokens@2.0.3 +(https://github.com/wooorm/comma-separated-tokens) + +(The MIT License) + +Copyright (c) 2016 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +============================================================ +hast-util-whitespace@3.0.0 +(https://github.com/syntax-tree/hast-util-whitespace) + +(The MIT License) + +Copyright (c) 2016 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +============================================================ +html-void-elements@3.0.0 +(https://github.com/wooorm/html-void-elements) + +(The MIT License) + +Copyright (c) 2016 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +============================================================ +mdast-util-to-hast@13.2.1 +(https://github.com/syntax-tree/mdast-util-to-hast) + +(The MIT License) + +Copyright (c) 2016 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +============================================================ +@types/mdast@4.0.4 +(https://github.com/DefinitelyTyped/DefinitelyTyped.git) + + MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE + + +============================================================ +@ungap/structured-clone@1.3.0 +(git+https://github.com/ungap/structured-clone.git) + +ISC License + +Copyright (c) 2021, Andrea Giammarchi, @WebReflection + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + + +============================================================ +devlop@1.1.0 +(https://github.com/wooorm/devlop) + +(The MIT License) + +Copyright (c) 2023 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +============================================================ +dequal@2.0.3 +(https://github.com/lukeed/dequal) + +The MIT License (MIT) + +Copyright (c) Luke Edwards (lukeed.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +============================================================ +micromark-util-sanitize-uri@2.0.1 +(https://github.com/micromark/micromark/tree/main/packages/micromark-util-sanitize-uri) + +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +============================================================ +micromark-util-character@2.1.1 +(https://github.com/micromark/micromark/tree/main/packages/micromark-util-character) + +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +============================================================ +micromark-util-symbol@2.0.1 +(https://github.com/micromark/micromark/tree/main/packages/micromark-util-symbol) + +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +============================================================ +micromark-util-types@2.0.2 +(https://github.com/micromark/micromark/tree/main/packages/micromark-util-types) + +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +============================================================ +micromark-util-encode@2.0.1 +(https://github.com/micromark/micromark/tree/main/packages/micromark-util-encode) + +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +============================================================ +trim-lines@3.0.1 +(https://github.com/wooorm/trim-lines) + +(The MIT License) + +Copyright (c) 2015 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +============================================================ +unist-util-position@5.0.0 +(https://github.com/syntax-tree/unist-util-position) + +(The MIT License) + +Copyright (c) 2015 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +============================================================ +unist-util-visit@5.1.0 +(https://github.com/syntax-tree/unist-util-visit) + +(The MIT License) + +Copyright (c) 2015 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +============================================================ +unist-util-is@6.0.1 +(https://github.com/syntax-tree/unist-util-is) + +(The MIT license) + +Copyright (c) 2015 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +============================================================ +unist-util-visit-parents@6.0.2 +(https://github.com/syntax-tree/unist-util-visit-parents) + +(The MIT License) + +Copyright (c) 2016 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +============================================================ +vfile@6.0.3 +(https://github.com/vfile/vfile) + +(The MIT License) + +Copyright (c) 2015 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +============================================================ +vfile-message@4.0.3 +(https://github.com/vfile/vfile-message) + +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +============================================================ +unist-util-stringify-position@4.0.0 +(https://github.com/syntax-tree/unist-util-stringify-position) + +(The MIT License) + +Copyright (c) 2016 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +============================================================ +property-information@7.2.0 +(https://github.com/wooorm/property-information) + +(The MIT License) + +Copyright (c) Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +============================================================ +space-separated-tokens@2.0.2 +(https://github.com/wooorm/space-separated-tokens) + +(The MIT License) + +Copyright (c) 2016 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +============================================================ +stringify-entities@4.0.4 +(https://github.com/wooorm/stringify-entities) + +(The MIT License) + +Copyright (c) 2015 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +============================================================ +character-entities-html4@2.1.0 +(https://github.com/wooorm/character-entities-html4) + +(The MIT License) + +Copyright (c) 2015 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +============================================================ +character-entities-legacy@3.0.0 +(https://github.com/wooorm/character-entities-legacy) + +(The MIT License) + +Copyright (c) 2015 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +============================================================ +zwitch@2.0.4 +(https://github.com/wooorm/zwitch) + +(The MIT License) + +Copyright (c) 2016 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +============================================================ +diff@9.0.0 +(https://github.com/kpdecker/jsdiff.git) + +BSD 3-Clause License + +Copyright (c) 2009-2015, Kevin Decker +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +============================================================ +lru_map@0.4.1 +(git+https://github.com/rsms/js-lru.git) + +Standard MIT license text (package declares MIT but ships no license file; copyright holder from package.json metadata). + +Copyright (c) Rasmus Andersson + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +============================================================ +shiki@4.5.0 +(git+https://github.com/shikijs/shiki.git) + +MIT License + +Copyright (c) 2021 Pine Wu +Copyright (c) 2023 Anthony Fu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +@shikijs/engine-javascript@4.5.0 +(git+https://github.com/shikijs/shiki.git) + +MIT License + +Copyright (c) 2021 Pine Wu +Copyright (c) 2023 Anthony Fu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +oniguruma-to-es@4.3.6 +(git+https://github.com/slevithan/oniguruma-to-es.git) + +MIT License + +Copyright (c) 2024-2026 Steven Levithan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +oniguruma-parser@0.12.2 +(git+https://github.com/slevithan/oniguruma-parser.git) + +MIT License + +Copyright (c) 2025-2026 Steven Levithan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +regex@6.1.0 +(git+https://github.com/slevithan/regex.git) + +MIT License + +Copyright (c) 2025 Steven Levithan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +regex-utilities@2.3.0 +(git+https://github.com/slevithan/regex-utilities.git) + +MIT License + +Copyright (c) 2024 Steven Levithan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +regex-recursion@6.0.2 +(git+https://github.com/slevithan/regex-recursion.git) + +MIT License + +Copyright (c) 2025 Steven Levithan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +@shikijs/engine-oniguruma@4.5.0 +(git+https://github.com/shikijs/shiki.git) + +MIT License + +Copyright (c) 2021 Pine Wu +Copyright (c) 2023 Anthony Fu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +@shikijs/langs@4.5.0 +(git+https://github.com/shikijs/shiki.git) + +MIT License + +Copyright (c) 2021 Pine Wu +Copyright (c) 2023 Anthony Fu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +@shikijs/themes@4.5.0 +(git+https://github.com/shikijs/shiki.git) + +MIT License + +Copyright (c) 2021 Pine Wu +Copyright (c) 2023 Anthony Fu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +@pierre/theme@2.0.0 +(https://github.com/pierrecomputer/pierre.git) + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, and + distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by the + copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all other + entities that control, are controlled by, or are under common control with + that entity. For the purposes of this definition, "control" means (i) the + power, direct or indirect, to cause the direction or management of such + entity, whether by contract or otherwise, or (ii) ownership of fifty percent + (50%) or more of the outstanding shares, or (iii) beneficial ownership of + such entity. + + "You" (or "Your") shall mean an individual or Legal Entity exercising + permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation source, and + configuration files. + + "Object" form shall mean any form resulting from mechanical transformation + or translation of a Source form, including but not limited to compiled + object code, generated documentation, and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or Object form, + made available under the License, as indicated by a copyright notice that is + included in or attached to the work (an example is provided in the Appendix + below). + + "Derivative Works" shall mean any work, whether in Source or Object form, + that is based on (or derived from) the Work and for which the editorial + revisions, annotations, elaborations, or other modifications represent, as a + whole, an original work of authorship. For the purposes of this License, + Derivative Works shall not include works that remain separable from, or + merely link (or bind by name) to the interfaces of, the Work and Derivative + Works thereof. + + "Contribution" shall mean any work of authorship, including the original + version of the Work and any modifications or additions to that Work or + Derivative Works thereof, that is intentionally submitted to Licensor for + inclusion in the Work by the copyright owner or by an individual or Legal + Entity authorized to submit on behalf of the copyright owner. For the + purposes of this definition, "submitted" means any form of electronic, + verbal, or written communication sent to the Licensor or its + representatives, including but not limited to communication on electronic + mailing lists, source code control systems, and issue tracking systems that + are managed by, or on behalf of, the Licensor for the purpose of discussing + and improving the Work, but excluding communication that is conspicuously + marked or otherwise designated in writing by the copyright owner as "Not a + Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity on + behalf of whom a Contribution has been received by Licensor and subsequently + incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this + License, each Contributor hereby grants to You a perpetual, worldwide, + non-exclusive, no-charge, royalty-free, irrevocable copyright license to + reproduce, prepare Derivative Works of, publicly display, publicly perform, + sublicense, and distribute the Work and such Derivative Works in Source or + Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this + License, each Contributor hereby grants to You a perpetual, worldwide, + non-exclusive, no-charge, royalty-free, irrevocable (except as stated in + this section) patent license to make, have made, use, offer to sell, sell, + import, and otherwise transfer the Work, where such license applies only to + those patent claims licensable by such Contributor that are necessarily + infringed by their Contribution(s) alone or by combination of their + Contribution(s) with the Work to which such Contribution(s) was submitted. + If You institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work or a + Contribution incorporated within the Work constitutes direct or contributory + patent infringement, then any patent licenses granted to You under this + License for that Work shall terminate as of the date such litigation is + filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or + Derivative Works thereof in any medium, with or without modifications, and + in Source or Object form, provided that You meet the following conditions: + + (a) You must give any other recipients of the Work or Derivative Works a + copy of this License; and + + (b) You must cause any modified files to carry prominent notices stating + that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works that You + distribute, all copyright, patent, trademark, and attribution notices from + the Source form of the Work, excluding those notices that do not pertain to + any part of the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its distribution, + then any Derivative Works that You distribute must include a readable copy + of the attribution notices contained within such NOTICE file, excluding + those notices that do not pertain to any part of the Derivative Works, in at + least one of the following places: within a NOTICE text file distributed as + part of the Derivative Works; within the Source form or documentation, if + provided along with the Derivative Works; or, within a display generated by + the Derivative Works, if and wherever such third-party notices normally + appear. The contents of the NOTICE file are for informational purposes only + and do not modify the License. You may add Your own attribution notices + within Derivative Works that You distribute, alongside or as an addendum to + the NOTICE text from the Work, provided that such additional attribution + notices cannot be construed as modifying the License. + + You may add Your own copyright statement to Your modifications and may + provide additional or different license terms and conditions for use, + reproduction, or distribution of Your modifications, or for any such + Derivative Works as a whole, provided Your use, reproduction, and + distribution of the Work otherwise complies with the conditions stated in + this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any + Contribution intentionally submitted for inclusion in the Work by You to the + Licensor shall be under the terms and conditions of this License, without + any additional terms or conditions. Notwithstanding the above, nothing + herein shall supersede or modify the terms of any separate license agreement + you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, + trademarks, service marks, or product names of the Licensor, except as + required for reasonable and customary use in describing the origin of the + Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in + writing, Licensor provides the Work (and each Contributor provides its + Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied, including, without limitation, any + warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or + FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining + the appropriateness of using or redistributing the Work and assume any risks + associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in + tort (including negligence), contract, or otherwise, unless required by + applicable law (such as deliberate and grossly negligent acts) or agreed to + in writing, shall any Contributor be liable to You for damages, including + any direct, indirect, special, incidental, or consequential damages of any + character arising as a result of this License or out of the use or inability + to use the Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all other + commercial damages or losses), even if such Contributor has been advised of + the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or + Derivative Works thereof, You may choose to offer, and charge a fee for, + acceptance of support, warranty, indemnity, or other liability obligations + and/or rights consistent with this License. However, in accepting such + obligations, You may act only on Your own behalf and on Your sole + responsibility, not on behalf of any other Contributor, and only if You + agree to indemnify, defend, and hold each Contributor harmless for any + liability incurred by, or claims asserted against, such Contributor by + reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright 2025 Pierre Computer Company + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. + +--- NOTICE --- + +This theme was built on top of +[GitHub's Visual Studio Code Theme](https://github.com/primer/github-vscode-theme), +reusing its technique and build tooling, which we have since iterated on for +more specific language tokens. + +`@pierre/theme` is licensed under Apache-2.0 (see `LICENSE`). The original MIT +license for `primer/github-vscode-theme` is included below for attribution. + +Original license for `primer/github-vscode-theme`: + +``` +MIT License + +Copyright (c) 2020 Primer + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +``` + +============================================================ +@pierre/theming@1.0.1 +(No repository found) + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, and + distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by the + copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all other + entities that control, are controlled by, or are under common control with + that entity. For the purposes of this definition, "control" means (i) the + power, direct or indirect, to cause the direction or management of such + entity, whether by contract or otherwise, or (ii) ownership of fifty percent + (50%) or more of the outstanding shares, or (iii) beneficial ownership of + such entity. + + "You" (or "Your") shall mean an individual or Legal Entity exercising + permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation source, and + configuration files. + + "Object" form shall mean any form resulting from mechanical transformation + or translation of a Source form, including but not limited to compiled + object code, generated documentation, and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or Object form, + made available under the License, as indicated by a copyright notice that is + included in or attached to the work (an example is provided in the Appendix + below). + + "Derivative Works" shall mean any work, whether in Source or Object form, + that is based on (or derived from) the Work and for which the editorial + revisions, annotations, elaborations, or other modifications represent, as a + whole, an original work of authorship. For the purposes of this License, + Derivative Works shall not include works that remain separable from, or + merely link (or bind by name) to the interfaces of, the Work and Derivative + Works thereof. + + "Contribution" shall mean any work of authorship, including the original + version of the Work and any modifications or additions to that Work or + Derivative Works thereof, that is intentionally submitted to Licensor for + inclusion in the Work by the copyright owner or by an individual or Legal + Entity authorized to submit on behalf of the copyright owner. For the + purposes of this definition, "submitted" means any form of electronic, + verbal, or written communication sent to the Licensor or its + representatives, including but not limited to communication on electronic + mailing lists, source code control systems, and issue tracking systems that + are managed by, or on behalf of, the Licensor for the purpose of discussing + and improving the Work, but excluding communication that is conspicuously + marked or otherwise designated in writing by the copyright owner as "Not a + Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity on + behalf of whom a Contribution has been received by Licensor and subsequently + incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this + License, each Contributor hereby grants to You a perpetual, worldwide, + non-exclusive, no-charge, royalty-free, irrevocable copyright license to + reproduce, prepare Derivative Works of, publicly display, publicly perform, + sublicense, and distribute the Work and such Derivative Works in Source or + Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this + License, each Contributor hereby grants to You a perpetual, worldwide, + non-exclusive, no-charge, royalty-free, irrevocable (except as stated in + this section) patent license to make, have made, use, offer to sell, sell, + import, and otherwise transfer the Work, where such license applies only to + those patent claims licensable by such Contributor that are necessarily + infringed by their Contribution(s) alone or by combination of their + Contribution(s) with the Work to which such Contribution(s) was submitted. + If You institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work or a + Contribution incorporated within the Work constitutes direct or contributory + patent infringement, then any patent licenses granted to You under this + License for that Work shall terminate as of the date such litigation is + filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or + Derivative Works thereof in any medium, with or without modifications, and + in Source or Object form, provided that You meet the following conditions: + + (a) You must give any other recipients of the Work or Derivative Works a + copy of this License; and + + (b) You must cause any modified files to carry prominent notices stating + that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works that You + distribute, all copyright, patent, trademark, and attribution notices from + the Source form of the Work, excluding those notices that do not pertain to + any part of the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its distribution, + then any Derivative Works that You distribute must include a readable copy + of the attribution notices contained within such NOTICE file, excluding + those notices that do not pertain to any part of the Derivative Works, in at + least one of the following places: within a NOTICE text file distributed as + part of the Derivative Works; within the Source form or documentation, if + provided along with the Derivative Works; or, within a display generated by + the Derivative Works, if and wherever such third-party notices normally + appear. The contents of the NOTICE file are for informational purposes only + and do not modify the License. You may add Your own attribution notices + within Derivative Works that You distribute, alongside or as an addendum to + the NOTICE text from the Work, provided that such additional attribution + notices cannot be construed as modifying the License. + + You may add Your own copyright statement to Your modifications and may + provide additional or different license terms and conditions for use, + reproduction, or distribution of Your modifications, or for any such + Derivative Works as a whole, provided Your use, reproduction, and + distribution of the Work otherwise complies with the conditions stated in + this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any + Contribution intentionally submitted for inclusion in the Work by You to the + Licensor shall be under the terms and conditions of this License, without + any additional terms or conditions. Notwithstanding the above, nothing + herein shall supersede or modify the terms of any separate license agreement + you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, + trademarks, service marks, or product names of the Licensor, except as + required for reasonable and customary use in describing the origin of the + Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in + writing, Licensor provides the Work (and each Contributor provides its + Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied, including, without limitation, any + warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or + FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining + the appropriateness of using or redistributing the Work and assume any risks + associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in + tort (including negligence), contract, or otherwise, unless required by + applicable law (such as deliberate and grossly negligent acts) or agreed to + in writing, shall any Contributor be liable to You for damages, including + any direct, indirect, special, incidental, or consequential damages of any + character arising as a result of this License or out of the use or inability + to use the Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all other + commercial damages or losses), even if such Contributor has been advised of + the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or + Derivative Works thereof, You may choose to offer, and charge a fee for, + acceptance of support, warranty, indemnity, or other liability obligations + and/or rights consistent with this License. However, in accepting such + obligations, You may act only on Your own behalf and on Your sole + responsibility, not on behalf of any other Contributor, and only if You + agree to indemnify, defend, and hold each Contributor harmless for any + liability incurred by, or claims asserted against, such Contributor by + reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright 2025 Pierre Computer Company + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. + + +============================================================ +@pierre/trees@1.0.0-beta.6 +(No repository found) + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, and + distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by the + copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all other + entities that control, are controlled by, or are under common control with + that entity. For the purposes of this definition, "control" means (i) the + power, direct or indirect, to cause the direction or management of such + entity, whether by contract or otherwise, or (ii) ownership of fifty percent + (50%) or more of the outstanding shares, or (iii) beneficial ownership of + such entity. + + "You" (or "Your") shall mean an individual or Legal Entity exercising + permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation source, and + configuration files. + + "Object" form shall mean any form resulting from mechanical transformation + or translation of a Source form, including but not limited to compiled + object code, generated documentation, and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or Object form, + made available under the License, as indicated by a copyright notice that is + included in or attached to the work (an example is provided in the Appendix + below). + + "Derivative Works" shall mean any work, whether in Source or Object form, + that is based on (or derived from) the Work and for which the editorial + revisions, annotations, elaborations, or other modifications represent, as a + whole, an original work of authorship. For the purposes of this License, + Derivative Works shall not include works that remain separable from, or + merely link (or bind by name) to the interfaces of, the Work and Derivative + Works thereof. + + "Contribution" shall mean any work of authorship, including the original + version of the Work and any modifications or additions to that Work or + Derivative Works thereof, that is intentionally submitted to Licensor for + inclusion in the Work by the copyright owner or by an individual or Legal + Entity authorized to submit on behalf of the copyright owner. For the + purposes of this definition, "submitted" means any form of electronic, + verbal, or written communication sent to the Licensor or its + representatives, including but not limited to communication on electronic + mailing lists, source code control systems, and issue tracking systems that + are managed by, or on behalf of, the Licensor for the purpose of discussing + and improving the Work, but excluding communication that is conspicuously + marked or otherwise designated in writing by the copyright owner as "Not a + Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity on + behalf of whom a Contribution has been received by Licensor and subsequently + incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this + License, each Contributor hereby grants to You a perpetual, worldwide, + non-exclusive, no-charge, royalty-free, irrevocable copyright license to + reproduce, prepare Derivative Works of, publicly display, publicly perform, + sublicense, and distribute the Work and such Derivative Works in Source or + Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this + License, each Contributor hereby grants to You a perpetual, worldwide, + non-exclusive, no-charge, royalty-free, irrevocable (except as stated in + this section) patent license to make, have made, use, offer to sell, sell, + import, and otherwise transfer the Work, where such license applies only to + those patent claims licensable by such Contributor that are necessarily + infringed by their Contribution(s) alone or by combination of their + Contribution(s) with the Work to which such Contribution(s) was submitted. + If You institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work or a + Contribution incorporated within the Work constitutes direct or contributory + patent infringement, then any patent licenses granted to You under this + License for that Work shall terminate as of the date such litigation is + filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or + Derivative Works thereof in any medium, with or without modifications, and + in Source or Object form, provided that You meet the following conditions: + + (a) You must give any other recipients of the Work or Derivative Works a + copy of this License; and + + (b) You must cause any modified files to carry prominent notices stating + that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works that You + distribute, all copyright, patent, trademark, and attribution notices from + the Source form of the Work, excluding those notices that do not pertain to + any part of the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its distribution, + then any Derivative Works that You distribute must include a readable copy + of the attribution notices contained within such NOTICE file, excluding + those notices that do not pertain to any part of the Derivative Works, in at + least one of the following places: within a NOTICE text file distributed as + part of the Derivative Works; within the Source form or documentation, if + provided along with the Derivative Works; or, within a display generated by + the Derivative Works, if and wherever such third-party notices normally + appear. The contents of the NOTICE file are for informational purposes only + and do not modify the License. You may add Your own attribution notices + within Derivative Works that You distribute, alongside or as an addendum to + the NOTICE text from the Work, provided that such additional attribution + notices cannot be construed as modifying the License. + + You may add Your own copyright statement to Your modifications and may + provide additional or different license terms and conditions for use, + reproduction, or distribution of Your modifications, or for any such + Derivative Works as a whole, provided Your use, reproduction, and + distribution of the Work otherwise complies with the conditions stated in + this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any + Contribution intentionally submitted for inclusion in the Work by You to the + Licensor shall be under the terms and conditions of this License, without + any additional terms or conditions. Notwithstanding the above, nothing + herein shall supersede or modify the terms of any separate license agreement + you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, + trademarks, service marks, or product names of the Licensor, except as + required for reasonable and customary use in describing the origin of the + Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in + writing, Licensor provides the Work (and each Contributor provides its + Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied, including, without limitation, any + warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or + FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining + the appropriateness of using or redistributing the Work and assume any risks + associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in + tort (including negligence), contract, or otherwise, unless required by + applicable law (such as deliberate and grossly negligent acts) or agreed to + in writing, shall any Contributor be liable to You for damages, including + any direct, indirect, special, incidental, or consequential damages of any + character arising as a result of this License or out of the use or inability + to use the Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all other + commercial damages or losses), even if such Contributor has been advised of + the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or + Derivative Works thereof, You may choose to offer, and charge a fee for, + acceptance of support, warranty, indemnity, or other liability obligations + and/or rights consistent with this License. However, in accepting such + obligations, You may act only on Your own behalf and on Your sole + responsibility, not on behalf of any other Contributor, and only if You + agree to indemnify, defend, and hold each Contributor harmless for any + liability incurred by, or claims asserted against, such Contributor by + reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright 2025 Pierre Computer Company + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. + +--- NOTICE --- + +This project includes some code derived from +[@headless-tree/core](https://github.com/lukasbach/headless-tree). + +The initial version of this project used `headless-tree` as the underlying tree +implementation. We have since written our own core at `packages/path-store`, but +many of the best ideas from `headless-tree` made their way to `path-store` and +`trees`. It's hard to identify exactly which code this is at this point, but +definitely things like the drag and drop implementation and the general list +approach to rendering and I'm sure more. The work that `@lukasbach` has +contributed to this space is greatly appreciated. `<3` + +Original license for `headless-tree/core`: + +``` +MIT License + +Copyright (c) 2023 Lukas Bach + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +``` + +============================================================ +preact@11.0.0-beta.0 +(https://github.com/preactjs/preact) + +The MIT License (MIT) + +Copyright (c) 2015-present Jason Miller + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +preact-render-to-string@6.6.5 +(https://github.com/preactjs/preact-render-to-string) + +The MIT License (MIT) + +Copyright (c) 2015 Jason Miller + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +============================================================ +@pierre/theming@1.0.0 +(No repository found) + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, and + distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by the + copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all other + entities that control, are controlled by, or are under common control with + that entity. For the purposes of this definition, "control" means (i) the + power, direct or indirect, to cause the direction or management of such + entity, whether by contract or otherwise, or (ii) ownership of fifty percent + (50%) or more of the outstanding shares, or (iii) beneficial ownership of + such entity. + + "You" (or "Your") shall mean an individual or Legal Entity exercising + permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation source, and + configuration files. + + "Object" form shall mean any form resulting from mechanical transformation + or translation of a Source form, including but not limited to compiled + object code, generated documentation, and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or Object form, + made available under the License, as indicated by a copyright notice that is + included in or attached to the work (an example is provided in the Appendix + below). + + "Derivative Works" shall mean any work, whether in Source or Object form, + that is based on (or derived from) the Work and for which the editorial + revisions, annotations, elaborations, or other modifications represent, as a + whole, an original work of authorship. For the purposes of this License, + Derivative Works shall not include works that remain separable from, or + merely link (or bind by name) to the interfaces of, the Work and Derivative + Works thereof. + + "Contribution" shall mean any work of authorship, including the original + version of the Work and any modifications or additions to that Work or + Derivative Works thereof, that is intentionally submitted to Licensor for + inclusion in the Work by the copyright owner or by an individual or Legal + Entity authorized to submit on behalf of the copyright owner. For the + purposes of this definition, "submitted" means any form of electronic, + verbal, or written communication sent to the Licensor or its + representatives, including but not limited to communication on electronic + mailing lists, source code control systems, and issue tracking systems that + are managed by, or on behalf of, the Licensor for the purpose of discussing + and improving the Work, but excluding communication that is conspicuously + marked or otherwise designated in writing by the copyright owner as "Not a + Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity on + behalf of whom a Contribution has been received by Licensor and subsequently + incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this + License, each Contributor hereby grants to You a perpetual, worldwide, + non-exclusive, no-charge, royalty-free, irrevocable copyright license to + reproduce, prepare Derivative Works of, publicly display, publicly perform, + sublicense, and distribute the Work and such Derivative Works in Source or + Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this + License, each Contributor hereby grants to You a perpetual, worldwide, + non-exclusive, no-charge, royalty-free, irrevocable (except as stated in + this section) patent license to make, have made, use, offer to sell, sell, + import, and otherwise transfer the Work, where such license applies only to + those patent claims licensable by such Contributor that are necessarily + infringed by their Contribution(s) alone or by combination of their + Contribution(s) with the Work to which such Contribution(s) was submitted. + If You institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work or a + Contribution incorporated within the Work constitutes direct or contributory + patent infringement, then any patent licenses granted to You under this + License for that Work shall terminate as of the date such litigation is + filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or + Derivative Works thereof in any medium, with or without modifications, and + in Source or Object form, provided that You meet the following conditions: + + (a) You must give any other recipients of the Work or Derivative Works a + copy of this License; and + + (b) You must cause any modified files to carry prominent notices stating + that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works that You + distribute, all copyright, patent, trademark, and attribution notices from + the Source form of the Work, excluding those notices that do not pertain to + any part of the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its distribution, + then any Derivative Works that You distribute must include a readable copy + of the attribution notices contained within such NOTICE file, excluding + those notices that do not pertain to any part of the Derivative Works, in at + least one of the following places: within a NOTICE text file distributed as + part of the Derivative Works; within the Source form or documentation, if + provided along with the Derivative Works; or, within a display generated by + the Derivative Works, if and wherever such third-party notices normally + appear. The contents of the NOTICE file are for informational purposes only + and do not modify the License. You may add Your own attribution notices + within Derivative Works that You distribute, alongside or as an addendum to + the NOTICE text from the Work, provided that such additional attribution + notices cannot be construed as modifying the License. + + You may add Your own copyright statement to Your modifications and may + provide additional or different license terms and conditions for use, + reproduction, or distribution of Your modifications, or for any such + Derivative Works as a whole, provided Your use, reproduction, and + distribution of the Work otherwise complies with the conditions stated in + this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any + Contribution intentionally submitted for inclusion in the Work by You to the + Licensor shall be under the terms and conditions of this License, without + any additional terms or conditions. Notwithstanding the above, nothing + herein shall supersede or modify the terms of any separate license agreement + you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, + trademarks, service marks, or product names of the Licensor, except as + required for reasonable and customary use in describing the origin of the + Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in + writing, Licensor provides the Work (and each Contributor provides its + Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied, including, without limitation, any + warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or + FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining + the appropriateness of using or redistributing the Work and assume any risks + associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in + tort (including negligence), contract, or otherwise, unless required by + applicable law (such as deliberate and grossly negligent acts) or agreed to + in writing, shall any Contributor be liable to You for damages, including + any direct, indirect, special, incidental, or consequential damages of any + character arising as a result of this License or out of the use or inability + to use the Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all other + commercial damages or losses), even if such Contributor has been advised of + the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or + Derivative Works thereof, You may choose to offer, and charge a fee for, + acceptance of support, warranty, indemnity, or other liability obligations + and/or rights consistent with this License. However, in accepting such + obligations, You may act only on Your own behalf and on Your sole + responsibility, not on behalf of any other Contributor, and only if You + agree to indemnify, defend, and hold each Contributor harmless for any + liability incurred by, or claims asserted against, such Contributor by + reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright 2025 Pierre Computer Company + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. + + diff --git a/packages/web-shell/README.md b/packages/web-shell/README.md index 417dff8bbf5..335ecda488f 100644 --- a/packages/web-shell/README.md +++ b/packages/web-shell/README.md @@ -41,6 +41,28 @@ Shell 执行。卡片区分执行、捕获与交付状态,面板按固定版 安装。关闭 `general.enableAutoUpdate`、旧服务、桌面 shell、不支持的安装及嵌入式 服务不显示按钮。临时配对连接也不提供更新入口。使用自定义 `sidebar.footer.items` 时,通过 `update` 项控制此功能。 +## 工作区文件浏览 + +独立页面右侧拓展区的「文件」入口打开只读浏览器:未选择文件时仅展示 +Pierre 目录树,点击文件后左侧显示内容、右侧保留目录树。Markdown、HTML 和图片沿用现有预览,文本源码由 Pierre File +高亮展示;Markdown 和 HTML 可以切换预览与源码。目录按需加载,筛选仅覆盖 +已加载路径,不因筛选而读取目录;输入保留原文,零匹配时显示明确提示。刷新重新加载根目录和当前文件,并收起目录。窄面板可隐藏文件树。 +中间分隔线可拖动调整两列宽度,也支持键盘方向键;文件树底部保留留白。 +深层目录和长文件名可通过整棵树的横向滚动查看,不压缩名称。 +目录列表最多显示前 2,000 个条目,截断时有提示。符号链接不作为目录递归展开。 +切换页签保留目录展开、选中文件、源码模式、筛选及滚动位置。文件页签保存 +工作区归属,展开与选中状态不会跨页面刷新保存。不接入 Git, +不编辑文件,也不自动把打开的文件加入对话上下文。文件右键菜单支持复制相对 +或绝对路径、下载、在独立页签预览 Markdown/HTML/图片,以及通过「引用」插入 +与输入框 `@` 选择文件相同的标签。仅当前工作区文件可引用,不自动发送消息。 + +嵌入式宿主通过 `rightPanel={{ items: ['files', 'review', 'sideTask'] }}` 启用。 +此入口需要有效、可信且无歧义的 daemon 工作区归属。 + +Excel(`.xlsx`)支持内联预览,也可通过右键「预览」在独立页签打开;重复打开同一文件复用页签,其他 Excel 格式仍仅支持下载。 +文件树源码预览在读取前限制为 4 MiB,更大的文件请通过右键菜单下载。 +导入失败仅在凭据可恢复的独立页面中提供重载;嵌入宿主或仅内存凭据时提供关闭文件,保留对话和宿主页面。 + ## 开发网页预览 独立 Web Shell 的右侧面板提供「网页预览」。先通过终端启动开发服务器, diff --git a/packages/web-shell/client/App.test.tsx b/packages/web-shell/client/App.test.tsx index f3cfe46a404..b3caa4723c7 100644 --- a/packages/web-shell/client/App.test.tsx +++ b/packages/web-shell/client/App.test.tsx @@ -8,7 +8,9 @@ import { type ReactNode, } from 'react'; import { createRoot, type Root } from 'react-dom/client'; +import { createPortal } from 'react-dom'; const notificationScrollToBottom = vi.hoisted(() => vi.fn()); +const editorAddTags = vi.hoisted(() => vi.fn()); import type { ContextUsageControls, RegisterContextUsageControls, @@ -797,6 +799,7 @@ const { latestSettingsState: null as { settings: DaemonSettingDescriptor[]; } | null, + artifactPanelExtra: null as ReactNode, captureArtifactPanelOnly: false, latestArtifactPanelProps: null as React.ComponentProps< typeof ArtifactPanel @@ -897,7 +900,10 @@ vi.mock('./components/artifacts/ArtifactPanel', async (importOriginal) => { ArtifactPanel: (props: React.ComponentProps) => { testState.latestArtifactPanelProps = props; return testState.captureArtifactPanelOnly ? null : ( - + <> + + {testState.artifactPanelExtra} + ); }, }; @@ -1159,6 +1165,7 @@ vi.mock('./components/ChatEditor', async () => { props: ChatEditorTestProps, ref: React.ForwardedRef<{ clear: () => void; + addTags: (tags: unknown, options?: unknown) => void; hasAttachments: () => boolean; hasInput: () => boolean; insertText: (text: string) => void; @@ -1209,6 +1216,7 @@ vi.mock('./components/ChatEditor', async () => { testState.inputAnnotations?.length, ), hasInput: () => testState.prompt.trim().length > 0, + addTags: editorAddTags, insertText: editorInsertText, getText: () => testState.prompt, setText: (text) => { @@ -9861,6 +9869,36 @@ describe('artifact panel fullscreen', () => { await Promise.resolve(); }); expect(document.activeElement).toBe(last); + + const treeHost = document.createElement('div'); + const treeShadow = treeHost.attachShadow({ mode: 'open' }); + const treeRow = document.createElement('button'); + treeShadow.appendChild(treeRow); + surface!.appendChild(treeHost); + first.focus(); + await act(async () => { + first.dispatchEvent( + new KeyboardEvent('keydown', { + key: 'Tab', + shiftKey: true, + bubbles: true, + cancelable: true, + }), + ); + }); + expect(treeShadow.activeElement).toBe(treeRow); + await act(async () => { + treeRow.dispatchEvent( + new KeyboardEvent('keydown', { + key: 'Tab', + bubbles: true, + composed: true, + cancelable: true, + }), + ); + }); + expect(document.activeElement).toBe(first); + treeHost.remove(); }); it('pulls focus back into the docked fullscreen surface when it escapes', async () => { @@ -9896,6 +9934,16 @@ describe('artifact panel fullscreen', () => { exitFullscreen!.focus(); expect(document.activeElement).toBe(exitFullscreen); + const treeHost = document.createElement('div'); + const treeShadow = treeHost.attachShadow({ mode: 'open' }); + const treeRow = document.createElement('button'); + treeRow.setAttribute('role', 'treeitem'); + treeShadow.appendChild(treeRow); + surface!.appendChild(treeHost); + treeRow.focus({ preventScroll: true }); + expect(treeShadow.activeElement).toBe(treeRow); + treeHost.remove(); + // A Tab past the preview's last focusable lands focus natively outside // the surface: the keydown that moved it never reached the surface's // Tab-wrap handler. Pull the focus back so the keyboard stays the @@ -9939,6 +9987,110 @@ describe('artifact panel fullscreen', () => { ).toBeNull(); }); + it('tabs into and out of shadow-root rows in the floating panel', async () => { + Object.defineProperty(window, 'matchMedia', { + configurable: true, + value: vi.fn().mockImplementation((query: string) => ({ + matches: false, + media: query, + addEventListener: vi.fn(), + removeEventListener: vi.fn(), + })), + }); + testState.artifactPanelExtra = createPortal( +
+ +
, + document.body, + ); + const { container } = renderApp(); + await flush(); + act(() => + container + .querySelector( + 'button[aria-label="Toggle right panel"]', + ) + ?.click(), + ); + await flush(); + const surface = document.querySelector( + '[data-slot="drawer-content"] aside[aria-label="Right panel"]', + )!; + expect(surface).not.toBeNull(); + const input = document.createElement('input'); + const host = document.createElement('div'); + const shadow = host.attachShadow({ mode: 'open' }); + const row = document.createElement('button'); + row.setAttribute('role', 'treeitem'); + shadow.appendChild(row); + const trailing = document.createElement('button'); + trailing.textContent = 'after shadow'; + surface.append(input, host, trailing); + const tab = async (target: HTMLElement, shiftKey = false) => { + await act(async () => { + target.dispatchEvent( + new KeyboardEvent('keydown', { + key: 'Tab', + shiftKey, + bubbles: true, + composed: true, + cancelable: true, + }), + ); + }); + }; + input.focus(); + await tab(input); + expect(shadow.activeElement).toBe(row); + await tab(row, true); + expect(document.activeElement).toBe(input); + row.focus(); + await tab(row); + expect(document.activeElement).toBe(trailing); + const prevented = new KeyboardEvent('keydown', { + key: 'Tab', + bubbles: true, + cancelable: true, + }); + input.focus(); + prevented.preventDefault(); + await act(async () => { + input.dispatchEvent(prevented); + }); + expect(document.activeElement).toBe(input); + const portalEvent = new KeyboardEvent('keydown', { + key: 'Tab', + bubbles: true, + cancelable: true, + }); + await act(async () => { + document + .querySelector('[data-testid="portalled-dialog-button"]')! + .dispatchEvent(portalEvent); + }); + expect(portalEvent.defaultPrevented).toBe(false); + const reversePortalEvent = new KeyboardEvent('keydown', { + key: 'Tab', + shiftKey: true, + bubbles: true, + cancelable: true, + }); + await act(async () => { + document + .querySelector('[data-testid="portalled-dialog-button"]')! + .dispatchEvent(reversePortalEvent); + }); + expect(reversePortalEvent.defaultPrevented).toBe(false); + trailing.focus(); + await tab(trailing); + expect(document.activeElement).toBe( + surface.querySelector('button:not([disabled])'), + ); + host.remove(); + input.remove(); + trailing.remove(); + }); + it('keeps the docked fullscreen surface keyboard-operable in shadow-DOM portal mode', async () => { const { container } = renderApp({ shadowDom: { portals: true } }); await flush(); @@ -11685,6 +11837,7 @@ beforeEach(() => { testState.latestWorkflowRunsProps = null; testState.latestSplitViewProps = null; testState.latestArtifactPanelProps = null; + testState.artifactPanelExtra = null; testState.captureArtifactPanelOnly = false; rawEnqueuePrompt.mockClear(); editorClear.mockClear(); @@ -16754,6 +16907,262 @@ describe('App session callbacks', () => { expect(header?.parentElement?.contains(artifactDock ?? null)).toBe(false); }); + it.each([true, false])( + 'keeps Files ownership distinct across workspace switches (advertised=%s)', + async (advertised) => { + const workspaces = [ + { id: 'first', cwd: '/tmp/project', primary: true, trusted: true }, + { id: 'second', cwd: '/tmp/second', primary: false, trusted: true }, + ]; + mockWorkspace.capabilities = { + workspaceCwd: '/tmp/project', + ...(advertised ? { workspaces } : {}), + } as typeof mockWorkspace.capabilities; + testState.captureArtifactPanelOnly = true; + const { container, rerender } = renderApp({ + rightPanel: { items: ['files'] }, + }); + act(() => + container + .querySelector( + 'button[aria-label="Toggle right panel"]', + ) + ?.click(), + ); + act(() => testState.latestArtifactPanelProps?.onOpenFiles?.()); + const firstId = testState.latestArtifactPanelProps?.activeTabId; + mockConnection.workspaceCwd = '/tmp/second'; + if (!advertised) + mockWorkspace.capabilities = { + workspaceCwd: '/tmp/second', + } as typeof mockWorkspace.capabilities; + rerender(); + await flush(); + act(() => testState.latestArtifactPanelProps?.onOpenFiles?.()); + expect(testState.latestArtifactPanelProps?.activeTabId).not.toBe(firstId); + expect(testState.latestArtifactPanelProps?.tabs).toContainEqual( + expect.objectContaining({ + kind: 'files', + workspaceCwd: '/tmp/second', + id: advertised ? 'files:second' : 'files:/tmp/second', + }), + ); + }, + ); + + it('references a file inline and exits docked fullscreen without closing Files', async () => { + editorAddTags.mockClear(); + mockWorkspace.capabilities = { + workspaceCwd: '/tmp/project', + workspaces: [ + { id: 'owner', cwd: '/tmp/project', primary: true, trusted: true }, + ], + } as typeof mockWorkspace.capabilities; + testState.captureArtifactPanelOnly = true; + const { container } = renderApp({ rightPanel: { items: ['files'] } }); + act(() => + container + .querySelector( + 'button[aria-label="Toggle right panel"]', + ) + ?.click(), + ); + act(() => testState.latestArtifactPanelProps?.onOpenFiles?.()); + act(() => testState.latestArtifactPanelProps?.onToggleFullscreen?.()); + expect(testState.latestArtifactPanelProps?.fullscreen).toBe(true); + expect(testState.latestArtifactPanelProps?.onReferenceFile).toBeDefined(); + act(() => + testState.latestArtifactPanelProps?.onReferenceFile?.('src/app.ts'), + ); + expect(testState.latestArtifactPanelProps?.fullscreen).toBe(false); + expect(testState.latestArtifactPanelProps?.tabs).toContainEqual( + expect.objectContaining({ kind: 'files' }), + ); + expect(editorAddTags).toHaveBeenCalledWith( + [expect.objectContaining({ serialized: '@src/app.ts' })], + { placement: 'inline', position: 'end' }, + ); + act(() => testState.latestChatEditorProps?.onSubmit('/model')); + await flush(); + expect( + container.querySelector('[data-testid="model-select"]'), + ).not.toBeNull(); + expect(testState.latestArtifactPanelProps?.onReferenceFile).toBeUndefined(); + await act(async () => + container + .querySelector('[data-testid="model-select"]') + ?.click(), + ); + await flush(); + await act(async () => + container + .querySelector( + '[data-testid="open-sessions-overview"]', + ) + ?.click(), + ); + await act(async () => + testState.latestSessionOverviewProps?.onOpenSplit?.([ + 'session-1', + 'session-2', + ]), + ); + await flush(); + expect(testState.latestSplitViewProps).not.toBeNull(); + expect(testState.latestArtifactPanelProps?.onReferenceFile).toBeUndefined(); + }); + + it('opens one files tab per workspace when configured', () => { + mockWorkspace.capabilities = { + workspaceCwd: '/tmp/project', + workspaces: [ + { + id: 'project-workspace', + cwd: '/tmp/project', + primary: true, + trusted: true, + }, + ], + } as typeof mockWorkspace.capabilities; + testState.captureArtifactPanelOnly = true; + const { container } = renderApp({ rightPanel: { items: ['files'] } }); + act(() => + container + .querySelector( + 'button[aria-label="Toggle right panel"]', + ) + ?.click(), + ); + expect(testState.latestArtifactPanelProps?.onOpenFiles).toBeDefined(); + act(() => testState.latestArtifactPanelProps?.onOpenFiles?.()); + act(() => testState.latestArtifactPanelProps?.onOpenFiles?.()); + expect(testState.latestArtifactPanelProps?.tabs).toEqual([ + expect.objectContaining({ + kind: 'files', + workspaceCwd: '/tmp/project', + title: 'Files', + }), + ]); + expect(testState.latestArtifactPanelProps?.activeTabId).toBe( + testState.latestArtifactPanelProps?.tabs[0]?.id, + ); + act(() => + testState.latestArtifactPanelProps?.onOpenFilePreview( + 'README.md', + '/tmp/project', + 'project-workspace', + ), + ); + expect(testState.latestArtifactPanelProps?.tabs).toEqual([ + expect.objectContaining({ kind: 'files' }), + expect.objectContaining({ + kind: 'file', + workspacePath: 'README.md', + workspaceCwd: '/tmp/project', + workspaceId: 'project-workspace', + }), + ]); + expect(testState.latestArtifactPanelProps?.tabs[1]).not.toHaveProperty( + 'previewContent', + ); + }); + + it.each(['disabled', 'untrusted', 'unknown'] as const)( + 'does not expose files for an unavailable workspace (%s)', + async (reason) => { + mockWorkspace.capabilities = { + workspaceCwd: '/tmp/project', + workspaces: + reason === 'unknown' + ? [] + : [ + { + id: 'owner', + cwd: '/tmp/project', + primary: true, + trusted: reason !== 'untrusted', + }, + ], + } as typeof mockWorkspace.capabilities; + window.localStorage.setItem( + 'qwen-code-web-shell-right-panel-state', + JSON.stringify({ + v: 1, + ['/tmp/project\0session-1']: { + open: true, + activeTabId: 'files:stored', + tabs: [ + { + id: 'files:stored', + kind: 'files', + title: 'Files', + workspaceCwd: '/tmp/project', + workspaceId: 'owner', + }, + ], + }, + }), + ); + testState.captureArtifactPanelOnly = true; + const { container } = renderApp({ + rightPanel: { items: reason === 'disabled' ? ['review'] : ['files'] }, + }); + act(() => + container + .querySelector( + 'button[aria-label="Toggle right panel"]', + ) + ?.click(), + ); + await flush(); + await flush(); + expect( + testState.latestArtifactPanelProps?.tabs.some( + (tab) => tab.kind === 'files', + ), + ).toBe(false); + expect(testState.latestArtifactPanelProps).toBeDefined(); + expect(testState.latestArtifactPanelProps?.onOpenFiles).toBeUndefined(); + }, + ); + + it.each(['/tmp/project', '', 42, null])( + 'round trips valid persisted files tabs and rejects malformed cwd (%s)', + async (workspaceCwd) => { + mockWorkspace.capabilities = { + workspaceCwd: '/tmp/project', + workspaces: [ + { id: 'owner', cwd: '/tmp/project', primary: true, trusted: true }, + ], + } as typeof mockWorkspace.capabilities; + testState.captureArtifactPanelOnly = true; + const tab = { + id: 'files:stored', + kind: 'files', + title: 'Files', + workspaceCwd, + workspaceId: 'owner', + }; + const key = 'qwen-code-web-shell-right-panel-state'; + const sessionKey = '/tmp/project\0session-1'; + window.localStorage.setItem( + key, + JSON.stringify({ + v: 1, + [sessionKey]: { open: true, activeTabId: tab.id, tabs: [tab] }, + }), + ); + renderApp({ rightPanel: { items: ['files'] } }); + await flush(); + await flush(); + const expected = workspaceCwd === '/tmp/project' ? [tab] : []; + expect(testState.latestArtifactPanelProps?.tabs).toEqual(expected); + expect( + JSON.parse(window.localStorage.getItem(key) ?? '{}')[sessionKey]?.tabs, + ).toEqual(expected); + }, + ); + it('shows the manual terminal action when configured and advertised', () => { mockConnection.capabilities.features = ['web_terminal']; const { container } = renderApp({ diff --git a/packages/web-shell/client/App.tsx b/packages/web-shell/client/App.tsx index cd81654afae..37c652d6c86 100644 --- a/packages/web-shell/client/App.tsx +++ b/packages/web-shell/client/App.tsx @@ -1,3 +1,9 @@ +import { + createComposerTagForItem, + fileReferenceInsertText, + FILE_PROVIDER_ID, + sanitizeAtMentionItem, +} from './hooks/useAtMentionSources'; import { isModelSetupCommand, resolveModelManagement, @@ -564,9 +570,9 @@ function isWebTerminalTarget(event: Event): boolean { // so a docked panel mounting under an open DialogShell would pause the // modal's trap. The surface covers the viewport, so the keyboard is the only // escape route; wrap it at the tabbable edges like FocusScope's loop does. -function getFullscreenSurfaceTabEdges( - container: HTMLElement, -): [HTMLElement | null, HTMLElement | null] { +function getArtifactPanelTabStops( + container: HTMLElement | ShadowRoot, +): HTMLElement[] { const candidates: HTMLElement[] = []; const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, { acceptNode(node) { @@ -584,20 +590,23 @@ function getFullscreenSurfaceTabEdges( ) { return NodeFilter.FILTER_SKIP; } - return element.tabIndex >= 0 + return element.tabIndex >= 0 || element.shadowRoot ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP; }, }); while (walker.nextNode()) { - candidates.push(walker.currentNode as HTMLElement); + const element = walker.currentNode as HTMLElement; + if (element.tabIndex >= 0) candidates.push(element); + if (element.shadowRoot) { + candidates.push(...getArtifactPanelTabStops(element.shadowRoot)); + } } - const visible = candidates.filter((element) => + return candidates.filter((element) => typeof element.checkVisibility === 'function' ? element.checkVisibility({ checkVisibilityCSS: true }) : true, ); - return [visible[0] ?? null, visible[visible.length - 1] ?? null]; } const DEFAULT_COMPOSER_TOOLBAR_ACTIONS = [ 'approvalMode', @@ -1937,6 +1946,7 @@ interface ArtifactPanelPersistedState { } type PersistedArtifactPanelTab = + | Extract | Extract | Omit, 'promptLabel'> | Pick< @@ -2067,6 +2077,15 @@ function parsePersistedArtifactPanelTab( } const common = { id: tab['id'], title: tab['title'] }; switch (tab['kind']) { + case 'files': + if (typeof tab['workspaceCwd'] !== 'string' || !tab['workspaceCwd']) + return; + return { + ...common, + kind: 'files', + workspaceCwd: tab['workspaceCwd'], + workspaceId: tab['workspaceId'] as string | undefined, + }; case 'turn_calls': if ( tab['id'] !== 'turn_calls' || @@ -2244,6 +2263,8 @@ function serializeArtifactPanelTabs( return tabs.flatMap((tab): PersistedArtifactPanelTab[] => { const { id, title } = tab; switch (tab.kind) { + case 'files': + return [tab]; case 'web_preview': return [ { id, title, kind: tab.kind, url: tab.url, viewport: tab.viewport }, @@ -5188,6 +5209,15 @@ export function App({ Boolean(connection.sessionId && connection.workspaceCwd) && connection.capabilities?.features.includes(SESSION_SIDE_TASK_FEATURE) === true; + const filesAvailable = + workspaceContextActive && + rightPanelItems.includes('files') && + Boolean( + resolveArtifactWorkspaceOwner( + workspace.capabilities, + connection.workspaceCwd, + ), + ); const webPreviewAvailable = workspaceContextActive && rightPanelItems.includes('webPreview'); const trajectoryAvailable = rightPanelItems.includes('trajectory'); @@ -6563,6 +6593,7 @@ export function App({ ).some( (tab) => (tab.kind === 'terminal' && webTerminalAvailable) || + (tab.kind === 'files' && filesAvailable) || (tab.kind === 'web_preview' && webPreviewAvailable) || (tab.kind === 'workflow' && tab.sessionId === connection.sessionId && @@ -6658,6 +6689,7 @@ export function App({ const deferredPersistedTabs = (persisted?.tabs ?? []).filter( (tab) => (tab.kind === 'terminal' && !webTerminalAvailable) || + (tab.kind === 'files' && !filesAvailable) || (tab.kind === 'web_preview' && !webPreviewAvailable) || (tab.kind === 'workflow' && tab.sessionId === connection.sessionId && @@ -6742,6 +6774,8 @@ export function App({ } : undefined; } + case 'files': + return filesAvailable ? tab : undefined; case 'web_preview': return webPreviewAvailable ? tab : undefined; case 'file': { @@ -7005,6 +7039,7 @@ export function App({ sessionActions, trajectoryAvailable, webTerminalAvailable, + filesAvailable, webPreviewAvailable, workspace.baseUrl, workspace.client, @@ -7048,6 +7083,36 @@ export function App({ }, [getDefaultReviewPanelWidth], ); + const openFilesPanel = useCallback(() => { + const owner = resolveArtifactWorkspaceOwner( + workspace.capabilities, + connection.workspaceCwd, + ); + if (!filesAvailable || !owner) return; + rememberArtifactPanelTrigger(); + const tab: ArtifactPanelTab = { + id: `files:${owner.id ?? owner.cwd}`, + kind: 'files', + title: t('files.title'), + workspaceCwd: owner.cwd, + workspaceId: owner.id, + }; + setArtifactPanelTabs((tabs) => + tabs.some((item) => item.id === tab.id) ? tabs : [...tabs, tab], + ); + setActiveArtifactPanelTabId(tab.id); + setArtifactPanelWidth((width) => + Math.min(getMaxArtifactPanelWidth(), Math.max(width, 740)), + ); + setArtifactPanelOpen(true); + }, [ + connection.workspaceCwd, + filesAvailable, + getMaxArtifactPanelWidth, + rememberArtifactPanelTrigger, + t, + workspace.capabilities, + ]); const openSubagentPanelForSession = useCallback( (tool: ACPToolCall, sessionId: string, workspaceCwd?: string) => { if (getSubagentDetailsUnavailableReason(tool)) return; @@ -7404,16 +7469,20 @@ export function App({ ); const openFilePreview = useCallback( ( - change: TurnOutputFileChange, + change: TurnOutputFileChange | string, previewWorkspaceCwd?: string, previewWorkspaceId?: string, ) => { - const previewContent = getFileChangePreviewContent(change); + const path = typeof change === 'string' ? change : change.path; + const previewContent = + typeof change === 'string' + ? undefined + : getFileChangePreviewContent(change); const tab: ArtifactPanelTab = { - id: `file:${previewWorkspaceCwd ?? ''}:${change.path}`, + id: `file:${previewWorkspaceCwd ?? ''}:${path}`, kind: 'file', - title: displayPath(change.path, previewWorkspaceCwd), - workspacePath: change.path, + title: displayPath(path, previewWorkspaceCwd), + workspacePath: path, ...(previewWorkspaceCwd ? { workspaceCwd: previewWorkspaceCwd } : {}), ...(previewWorkspaceId ? { workspaceId: previewWorkspaceId } : {}), ...(previewContent !== undefined ? { previewContent } : {}), @@ -9140,7 +9209,11 @@ export function App({ const target = (event.composedPath()[0] as Element | undefined) ?? (event.target as Element | null); - if (!target || surface.contains(target) || target.contains(surface)) { + if ( + !target || + event.composedPath().includes(surface) || + target.contains(surface) + ) { return; } // The elevated toast host and any Radix layer opened from the panel @@ -9178,8 +9251,9 @@ export function App({ }, [dockedFullscreenActive, portalRoot]); const handleArtifactPanelSurfaceKeyDown = useCallback( (event: ReactKeyboardEvent) => { - if (!artifactPanelFullscreen) return; + if (!artifactPanelFullscreen && !useFloatingArtifactPanel) return; if ( + event.defaultPrevented || event.key !== 'Tab' || event.altKey || event.ctrlKey || @@ -9187,12 +9261,37 @@ export function App({ ) { return; } - const [first, last] = getFullscreenSurfaceTabEdges(event.currentTarget); - const focused = getShadowAwareActiveElement(event.currentTarget); + if (!event.nativeEvent.composedPath().includes(event.currentTarget)) + return; + const candidates = getArtifactPanelTabStops(event.currentTarget); + const first = candidates[0]; + const last = candidates[candidates.length - 1]; + let focused = getShadowAwareActiveElement(event.currentTarget); + while (focused?.shadowRoot?.activeElement) { + focused = focused.shadowRoot.activeElement; + } if (!first || !last) { if (focused === event.currentTarget) event.preventDefault(); return; } + // Radix's drawer loop only sees light DOM, so own Tab before it can + // wrap from the filter past the file tree's shadow-root rows. + if (useFloatingArtifactPanel) { + const index = candidates.indexOf(focused as HTMLElement); + const next = + index < 0 + ? event.shiftKey + ? last + : first + : candidates[ + (index + (event.shiftKey ? -1 : 1) + candidates.length) % + candidates.length + ]; + event.preventDefault(); + event.stopPropagation(); + next?.focus(); + return; + } if (!event.shiftKey && focused === last) { event.preventDefault(); first.focus(); @@ -9204,7 +9303,7 @@ export function App({ last.focus(); } }, - [artifactPanelFullscreen], + [artifactPanelFullscreen, useFloatingArtifactPanel], ); // The drawer's Radix dismiss layer only checks `event.key === 'Escape'` // (no isComposing guard), so while composing in a panel input an Escape @@ -18529,7 +18628,18 @@ export function App({ if (escArmedActionRef.current !== null) { resetEscapeState(); } - if (e.key === 'Tab' && e.shiftKey && !live.interactionBlocked) { + if ( + e.key === 'Tab' && + e.shiftKey && + !live.interactionBlocked && + !e + .composedPath() + .some( + (node) => + node instanceof Element && + node.matches('[role="dialog"], [role="alertdialog"]'), + ) + ) { e.preventDefault(); live.handleCycleMode(); } @@ -20001,6 +20111,34 @@ export function App({ onSelectTab: selectArtifactPanelTab, onCloseTab: closeArtifactPanelTab, onOpenFilePreview: openFilePreview, + onOpenFiles: filesAvailable ? openFilesPanel : undefined, + onReferenceFile: + workspaceContextActive && !dialogOpen && mainView === 'chat' + ? (path: string) => { + const tag = createComposerTagForItem( + FILE_PROVIDER_ID, + sanitizeAtMentionItem({ + id: `file:${path}`, + label: path.split('/').at(-1) ?? path, + description: path, + kind: 'insert', + fileKind: 'file', + }), + fileReferenceInsertText(path), + ); + if (!tag) return; + if (useFloatingArtifactPanel) { + closeArtifactPanel(); + } else { + setArtifactPanelFullscreen(false); + } + editorRef.current?.addTags([tag], { + placement: 'inline', + position: 'end', + }); + requestAnimationFrame(() => editorRef.current?.focus()); + } + : undefined, onOpenWebPreview: workspaceContextActive ? openWebPreviewTab : undefined, onWebPreviewChange: updateWebPreviewTab, latestReviewAvailable: latestReviewChanges.length > 0, @@ -23086,6 +23224,15 @@ export function App({ event.preventDefault(); return; } + const target = event.composedPath()[0]; + if ( + target instanceof HTMLInputElement && + target.hasAttribute('data-workspace-file-filter') && + target.value + ) { + event.preventDefault(); + return; + } // Fullscreen is the topmost surface: Escape shrinks the // panel back to its drawer width. Without this the // drawer's dismiss layer would close the panel instead. @@ -23095,15 +23242,20 @@ export function App({ }} > Right panel - - - +
+ + + +
)} diff --git a/packages/web-shell/client/build-artifact.test.ts b/packages/web-shell/client/build-artifact.test.ts index 040b31c2a73..9bd30bc9c09 100644 --- a/packages/web-shell/client/build-artifact.test.ts +++ b/packages/web-shell/client/build-artifact.test.ts @@ -2,6 +2,7 @@ import { describe, expect, it } from 'vitest'; import { readFileSync, readdirSync } from 'node:fs'; import { resolve } from 'node:path'; import postcss, { type Rule } from 'postcss'; +import { FILES_MESSAGES_EN } from './components/artifacts/files-messages'; import { LIVE_MESSAGES_EN } from './live/messages'; import { COLLAB_MESSAGES_EN } from './components/workspace-agents/messages'; @@ -133,6 +134,39 @@ describe('build artifact — package boundary', () => { expect(bundle).not.toMatch(/DaemonSessionClient\s*\{/); }); + it('bundles Pierre highlighter dependencies instead of resolving the host Shiki major', () => { + const notices = readFileSync(resolve(DIST_DIR, '../NOTICES.txt'), 'utf8'); + for (const name of ['diffs', 'trees', 'theming', 'theme']) { + expect(notices).toContain(`@pierre/${name}@`); + } + const treeAttribution = notices + .split('@pierre/trees@')[1]! + .split( + '============================================================', + )[0]!; + // This is the bundled tree's NOTICE credit, not a separate dependency entry. + expect(treeAttribution).toContain('Original license for'); + expect(treeAttribution).toContain('headless-tree/core'); + expect(notices).toContain('shiki@4.'); + expect(readPackageJavascript()).not.toMatch( + /(?:from\s*|import\s*\()\s*["']@pierre\//, + ); + const previews = readdirSync(DIST_DIR).filter((name) => + /^PierreFilePreview-.*\.js$/.test(name), + ); + expect(previews).toHaveLength(1); + const preview = readFileSync(resolve(DIST_DIR, previews[0]!), 'utf8'); + expect(preview).not.toMatch(/from\s+["']shiki["']/); + expect(preview).toContain('createJavaScriptRegexEngine'); + const hostHighlighter = readdirSync(DIST_DIR).find((name) => + /^codeHighlighter-.*\.js$/.test(name), + ); + expect(hostHighlighter).toBeDefined(); + expect(readFileSync(resolve(DIST_DIR, hostHighlighter!), 'utf8')).toContain( + 'from "shiki"', + ); + }); + it('scopes every component CSS rule to a WebShell root', () => { const unscoped: string[] = []; postcss.parse(readInjectedCss()).walkRules((rule) => { @@ -497,6 +531,16 @@ describe('build artifact — transcript entry (#11031)', () => { expect(js).not.toContain('selectionCopyListWrapper'); }); + it('excludes Files-only messages from the transcript entry', () => { + const bundle = readTranscriptBundle(); + for (const key of [ + 'files.description', + 'files.reloadUnavailable', + 'files.sourceTooLarge', + ] as const) + expect(bundle).not.toContain(FILES_MESSAGES_EN[key]); + }); + it('carries no Live Voice strings and looks none up', () => { // vite.lib.config.ts swaps client/live/messages.ts for an empty stub in // this build, which keeps ~200 entries out of every exported document. It diff --git a/packages/web-shell/client/components/artifacts/ArtifactPanel.test.tsx b/packages/web-shell/client/components/artifacts/ArtifactPanel.test.tsx index 5de976d2097..e744868ab6e 100644 --- a/packages/web-shell/client/components/artifacts/ArtifactPanel.test.tsx +++ b/packages/web-shell/client/components/artifacts/ArtifactPanel.test.tsx @@ -1,6 +1,6 @@ // @vitest-environment jsdom import { afterEach, describe, expect, it, vi } from 'vitest'; -import { act, StrictMode } from 'react'; +import { act, StrictMode, useEffect } from 'react'; import { Blob as NodeBlob } from 'node:buffer'; import { createRoot, type Root } from 'react-dom/client'; import { EditorView } from 'codemirror'; @@ -38,6 +38,7 @@ const { readWorkspaceFile: vi.fn(), readWorkspaceFileBytes: vi.fn(), fileStat: vi.fn(), + dirList: vi.fn(), }; return { mockActions: { @@ -48,6 +49,7 @@ const { readFileBytes: vi.fn(), readWorkspaceFile: vi.fn(), stat: vi.fn(), + listDirectory: vi.fn(), listScheduledTasks: vi.fn(), updateScheduledTask: vi.fn(), deleteScheduledTask: vi.fn(), @@ -94,6 +96,70 @@ vi.mock( }), ); +const reloadPolicy = vi.hoisted(() => ({ + standalone: true, + token: undefined as string | undefined, + survives: true, +})); +vi.mock('../../config/daemon-target', () => ({ + useDaemonTargetOptional: () => + reloadPolicy.standalone ? { activeToken: reloadPolicy.token } : undefined, +})); +vi.mock('../../config/daemon', async (original) => ({ + ...(await original()), + hasReloadSurvivableDaemonToken: () => reloadPolicy.survives, +})); + +const fileBrowserProps = vi.hoisted(() => ({ + loadError: undefined as Error | undefined, + sourceError: undefined as Error | undefined, + loadAttempts: 0, + previewPath: undefined as string | undefined, + current: undefined as + | { workspaceCwd: string; onReferenceFile?: (path: string) => void } + | undefined, +})); + +vi.mock('./WorkspaceFileBrowser', () => { + const WorkspaceFileBrowser = (props: { + workspaceCwd: string; + onReferenceFile?: (path: string) => void; + actions: ArtifactWorkspaceTarget['actions']; + renderPreview: ( + path: string, + source: boolean, + version: number, + ) => React.ReactNode; + }) => { + fileBrowserProps.current = props; + useEffect(() => { + void props.actions.listDirectory('.').catch(() => {}); + }, [props.actions]); + return ( +
+ {fileBrowserProps.previewPath && + props.renderPreview(fileBrowserProps.previewPath, true, 0)} +
+ ); + }; + return { + get WorkspaceFileBrowser() { + fileBrowserProps.loadAttempts++; + if (fileBrowserProps.loadError) throw fileBrowserProps.loadError; + return WorkspaceFileBrowser; + }, + }; +}); + +vi.mock('./PierreFilePreview', () => ({ + default: function MockFileSource() { + useEffect(() => { + if (fileBrowserProps.sourceError) throw fileBrowserProps.sourceError; + }, []); + return
; + }, +})); + vi.mock('../terminal/TerminalPanel', () => ({ TerminalPanel: ({ terminalId }: { terminalId: string }) => (
@@ -123,8 +189,14 @@ const { useArtifactWorkspaceTarget } = await import( const mounted: Array<{ root: Root; container: HTMLElement }> = []; let latestArtifactWorkspaceTarget: ArtifactWorkspaceTarget | undefined; -function ArtifactWorkspaceTargetProbe({ revision }: { revision: number }) { - latestArtifactWorkspaceTarget = useArtifactWorkspaceTarget('/secondary'); +function ArtifactWorkspaceTargetProbe({ + revision, + workspaceCwd = '/secondary', +}: { + revision: number; + workspaceCwd?: string; +}) { + latestArtifactWorkspaceTarget = useArtifactWorkspaceTarget(workspaceCwd); return ; } @@ -346,6 +418,13 @@ function scheduledTaskPanel( } afterEach(() => { + reloadPolicy.standalone = true; + reloadPolicy.token = undefined; + reloadPolicy.survives = true; + fileBrowserProps.loadError = undefined; + fileBrowserProps.sourceError = undefined; + fileBrowserProps.previewPath = undefined; + fileBrowserProps.loadAttempts = 0; vi.unstubAllGlobals(); sideTaskPanelProps.current = undefined; // The boundary matrix spies on DOMParser.prototype per row; restore it so @@ -372,12 +451,14 @@ afterEach(() => { mockWorkspaceActions.readFileBytes.mockReset(); mockWorkspaceActions.readWorkspaceFile.mockReset(); mockWorkspaceActions.stat.mockReset(); + mockWorkspaceActions.listDirectory.mockReset(); mockWorkspaceActions.listScheduledTasks.mockReset(); mockWorkspaceActions.updateScheduledTask.mockReset(); mockWorkspaceActions.deleteScheduledTask.mockReset(); mockSecondaryWorkspaceActions.readWorkspaceFile.mockReset(); mockSecondaryWorkspaceActions.readWorkspaceFileBytes.mockReset(); mockSecondaryWorkspaceActions.fileStat.mockReset(); + mockSecondaryWorkspaceActions.dirList.mockReset(); mockWorkspace.client.workspaceByCwd.mockClear(); mockWorkspace.capabilities.features = []; latestArtifactWorkspaceTarget = undefined; @@ -567,6 +648,96 @@ describe('ArtifactPanel web previews', () => { }); describe('artifact workspace authority', () => { + it.each(['/primary', '/secondary'])( + 'lists directories through the advertised owner for %s', + async (cwd) => { + const listing = { + kind: 'list', + path: 'src', + entries: [], + truncated: false, + }; + mockSecondaryWorkspaceActions.dirList.mockResolvedValue(listing); + const container = document.createElement('div'); + document.body.appendChild(container); + const root = createRoot(container); + mounted.push({ root, container }); + act(() => + root.render( + , + ), + ); + await expect( + latestArtifactWorkspaceTarget?.actions.listDirectory('src'), + ).resolves.toEqual(listing); + expect(mockWorkspace.client.workspaceByCwd).toHaveBeenCalledWith(cwd); + expect(mockSecondaryWorkspaceActions.dirList).toHaveBeenCalledWith('src'); + expect(mockWorkspaceActions.listDirectory).not.toHaveBeenCalled(); + }, + ); + + it('keeps the primary directory route only for legacy capabilities', async () => { + mockWorkspace.capabilities = { + workspaceCwd: '/primary', + features: [], + } as unknown as typeof mockWorkspace.capabilities; + const listing = { kind: 'list', path: '', entries: [], truncated: false }; + mockWorkspaceActions.listDirectory.mockResolvedValue(listing); + const container = document.createElement('div'); + document.body.appendChild(container); + const root = createRoot(container); + mounted.push({ root, container }); + act(() => + root.render( + , + ), + ); + await expect( + latestArtifactWorkspaceTarget?.actions.listDirectory(''), + ).resolves.toEqual(listing); + expect(mockWorkspaceActions.listDirectory).toHaveBeenCalledWith(''); + expect(mockWorkspace.client.workspaceByCwd).not.toHaveBeenCalled(); + }); + + it('rejects a pending directory result and captured actions after owner replacement', async () => { + let resolveRead: + | ((value: { + kind: string; + path: string; + entries: []; + truncated: boolean; + }) => void) + | undefined; + mockSecondaryWorkspaceActions.dirList.mockReturnValue( + new Promise((resolve) => { + resolveRead = resolve; + }), + ); + const container = document.createElement('div'); + document.body.appendChild(container); + const root = createRoot(container); + mounted.push({ root, container }); + act(() => root.render()); + const actions = latestArtifactWorkspaceTarget!.actions; + const read = actions.listDirectory(''); + mockWorkspace.capabilities = { + ...mockWorkspace.capabilities, + workspaces: mockWorkspace.capabilities.workspaces.map((owner) => + owner.cwd === '/secondary' ? { ...owner, id: 'replacement-id' } : owner, + ), + }; + act(() => root.render()); + resolveRead?.({ kind: 'list', path: '', entries: [], truncated: false }); + await expect(read).rejects.toThrow( + 'Workspace artifact owner is no longer available', + ); + await expect(actions.listDirectory('secret')).rejects.toThrow( + 'Workspace artifact owner is no longer available', + ); + expect(mockSecondaryWorkspaceActions.dirList).toHaveBeenCalledTimes(1); + expect(mockWorkspaceActions.listDirectory).not.toHaveBeenCalled(); + }); + it('keeps an in-flight read across an equivalent capabilities refresh', async () => { let resolveRead: | ((file: { content: string; truncated: boolean }) => void) @@ -2192,6 +2363,496 @@ describe('ArtifactPanel add menu', () => { expect(onCreateSideTask).not.toHaveBeenCalled(); }); + it('exposes the opt-in files action on the empty page and add menu', () => { + const onOpenFiles = vi.fn(); + const container = document.createElement('div'); + document.body.appendChild(container); + const root = createRoot(container); + mounted.push({ root, container }); + const renderPanel = (tabs: ArtifactPanelTab[]) => ( + + {}} + onCloseTab={() => {}} + onOpenFilePreview={() => {}} + onClose={() => {}} + /> + + ); + act(() => root.render(renderPanel([]))); + const action = Array.from(container.querySelectorAll('button')).find( + (button) => button.textContent?.includes('Browse workspace files'), + ); + expect(action).toBeDefined(); + act(() => action?.click()); + expect(onOpenFiles).toHaveBeenCalledTimes(1); + act(() => + root.render( + renderPanel([ + { id: 'terminal-one', kind: 'terminal', title: 'Terminal' }, + ]), + ), + ); + openAddMenu(container); + const menuItem = Array.from( + document.body.querySelectorAll('[role="menuitem"]'), + ).find((item) => item.textContent === 'Files'); + expect(menuItem).toBeDefined(); + act(() => menuItem?.click()); + expect(onOpenFiles).toHaveBeenCalledTimes(2); + }); + + it('hides Files in both entry points when the item is not opted in', () => { + const onOpenFiles = vi.fn(); + const container = document.createElement('div'); + document.body.appendChild(container); + const root = createRoot(container); + mounted.push({ root, container }); + const renderPanel = (tabs: ArtifactPanelTab[]) => ( + + {}} + onCloseTab={() => {}} + onOpenFilePreview={() => {}} + onClose={() => {}} + /> + + ); + act(() => root.render(renderPanel([]))); + expect(container.textContent).not.toContain('Browse workspace files'); + act(() => + root.render( + renderPanel([ + { id: 'terminal:test', kind: 'terminal', title: 'Terminal' }, + ]), + ), + ); + openAddMenu(container); + expect( + Array.from(document.body.querySelectorAll('[role="menuitem"]')).some( + (item) => item.textContent === 'Files', + ), + ).toBe(false); + }); + + it.each(['browser import', 'source initialization'] as const)( + 'contains a failed %s inside the files pane and offers recovery', + async (failure) => { + vi.spyOn(console, 'error').mockImplementation(() => {}); + if (failure === 'browser import') { + fileBrowserProps.loadError = new Error('File tree chunk unavailable'); + } else { + fileBrowserProps.previewPath = 'app.ts'; + fileBrowserProps.sourceError = new Error('File renderer unavailable'); + mockWorkspaceActions.stat.mockResolvedValue({ + type: 'file', + sizeBytes: 16, + modifiedMs: 1, + }); + mockWorkspaceActions.readWorkspaceFile.mockResolvedValue({ + content: 'const value = 1;', + truncated: false, + }); + } + const container = document.createElement('div'); + document.body.appendChild(container); + const root = createRoot(container); + mounted.push({ root, container }); + await act(async () => + root.render( + + {}} + onCloseTab={() => {}} + onOpenFilePreview={() => {}} + onClose={() => {}} + /> + , + ), + ); + await vi.waitFor(() => + expect(container.querySelector('[role="alert"]')).not.toBeNull(), + ); + expect( + container.querySelector('aside[aria-label="Right panel"]'), + ).not.toBeNull(); + expect( + container.querySelector('button[aria-label="Close Files"]'), + ).not.toBeNull(); + const browser = container.querySelector( + '[data-testid="workspace-file-browser"]', + ); + if (failure === 'browser import') { + expect(container.textContent).toContain('Reload page'); + expect(container.textContent).not.toContain('Try again'); + expect(fileBrowserProps.loadAttempts).toBeGreaterThan(0); + return; + } + fileBrowserProps.loadError = undefined; + fileBrowserProps.sourceError = undefined; + const retry = Array.from(container.querySelectorAll('button')).find( + (button) => button.textContent === 'Try again', + )!; + await act(async () => retry.click()); + await vi.waitFor(() => + expect(container.querySelector('[role="alert"]')).toBeNull(), + ); + expect( + container.querySelector('[data-testid="workspace-file-browser"]'), + ).not.toBeNull(); + expect( + container.querySelector('[data-testid="recovered-file-source"]'), + ).not.toBeNull(); + expect( + container.querySelector('[data-testid="workspace-file-browser"]'), + ).toBe(browser); + }, + ); + + it.each(['embedded', 'memory-token'] as const)( + 'does not reload the host for an import failure (%s)', + async (mode) => { + vi.spyOn(console, 'error').mockImplementation(() => {}); + reloadPolicy.standalone = mode !== 'embedded'; + reloadPolicy.token = 'test-memory-only'; + reloadPolicy.survives = false; + fileBrowserProps.loadError = new Error('Chunk unavailable'); + const container = document.createElement('div'); + document.body.appendChild(container); + const root = createRoot(container); + mounted.push({ root, container }); + await act(async () => + root.render( + + {}} + onCloseTab={() => {}} + onOpenFilePreview={() => {}} + onClose={() => {}} + /> + , + ), + ); + await vi.waitFor(() => + expect(container.querySelector('[role="alert"]')).not.toBeNull(), + ); + expect(container.textContent).toContain( + 'Reloading could lose your connection', + ); + expect(container.textContent).not.toContain('Reload page'); + expect(container.textContent).not.toContain('Try again'); + }, + ); + + it('refuses oversized source files before reading any content bytes', async () => { + fileBrowserProps.previewPath = 'huge.log'; + mockWorkspaceActions.stat.mockResolvedValue({ + type: 'file', + sizeBytes: 90 * 1024 * 1024, + modifiedMs: 1, + }); + const container = document.createElement('div'); + document.body.appendChild(container); + const root = createRoot(container); + mounted.push({ root, container }); + await act(async () => + root.render( + + {}} + onCloseTab={() => {}} + onOpenFilePreview={() => {}} + onClose={() => {}} + /> + , + ), + ); + await vi.waitFor(() => + expect(container.textContent).toContain('4 MiB source preview limit'), + ); + expect(mockWorkspaceActions.readWorkspaceFile).not.toHaveBeenCalled(); + expect(mockWorkspaceActions.readFileBytes).not.toHaveBeenCalled(); + }); + + it('retains files panes across tab switches and revokes a hidden workspace owner', async () => { + const container = document.createElement('div'); + document.body.appendChild(container); + const root = createRoot(container); + mounted.push({ root, container }); + const files: ArtifactPanelTab = { + id: 'files:secondary', + kind: 'files', + title: 'Files', + workspaceCwd: '/secondary', + workspaceId: 'secondary-id', + }; + const terminal: ArtifactPanelTab = { + id: 'terminal', + kind: 'terminal', + title: 'Terminal', + }; + const renderPanel = (activeTabId: string, tabs = [files, terminal]) => ( + + {}} + onCloseTab={() => {}} + onOpenFilePreview={() => {}} + onClose={() => {}} + /> + + ); + await act(async () => root.render(renderPanel(files.id))); + const browser = container.querySelector( + '[data-testid="workspace-file-browser"]', + ); + expect(browser).not.toBeNull(); + expect(browser?.getAttribute('data-cwd')).toBe('/secondary'); + act(() => root.render(renderPanel(terminal.id))); + expect( + container.querySelector('[data-testid="workspace-file-browser"]'), + ).toBe(browser); + expect(browser?.closest('[hidden]')).not.toBeNull(); + act(() => root.render(renderPanel(files.id))); + expect( + container.querySelector('[data-testid="workspace-file-browser"]'), + ).toBe(browser); + expect(browser?.closest('[hidden]')).toBeNull(); + act(() => root.render(renderPanel(terminal.id))); + mockWorkspace.capabilities = { + ...mockWorkspace.capabilities, + workspaces: mockWorkspace.capabilities.workspaces.map((owner) => + owner.id === 'secondary-id' ? { ...owner, trusted: false } : owner, + ), + }; + act(() => root.render(renderPanel(terminal.id))); + expect( + container.querySelector('[data-testid="workspace-file-browser"]'), + ).toBeNull(); + expect(container.querySelector('[role="alert"]')?.textContent).toContain( + 'removed', + ); + mockWorkspace.capabilities = { + ...mockWorkspace.capabilities, + workspaces: mockWorkspace.capabilities.workspaces.map((owner) => + owner.id === 'secondary-id' ? { ...owner, trusted: true } : owner, + ), + }; + await act(async () => root.render(renderPanel(files.id))); + expect( + container.querySelector('[data-testid="workspace-file-browser"]'), + ).not.toBeNull(); + const restored = container.querySelector( + '[data-testid="workspace-file-browser"]', + ); + expect(restored).not.toBe(browser); + expect(restored?.getAttribute('data-cwd')).toBe('/secondary'); + act(() => root.render(renderPanel(terminal.id, [terminal]))); + expect( + container.querySelector('[data-testid="workspace-file-browser"]'), + ).toBeNull(); + }); + + it.each([undefined, 'old-owner'])( + 'allows reopening files when a persisted owner is stale (%s)', + async (workspaceId) => { + const onOpenFiles = vi.fn(); + const container = document.createElement('div'); + document.body.appendChild(container); + const root = createRoot(container); + mounted.push({ root, container }); + await act(async () => + root.render( + + {}} + onCloseTab={() => {}} + onOpenFilePreview={() => {}} + onClose={() => {}} + /> + , + ), + ); + expect( + container.querySelector('[data-testid="workspace-file-browser"]'), + ).toBeNull(); + openAddMenu(container); + const item = Array.from( + document.body.querySelectorAll('[role="menuitem"]'), + ).find((item) => item.textContent === 'Files'); + expect(item).toBeDefined(); + act(() => item?.click()); + expect(onOpenFiles).toHaveBeenCalledOnce(); + expect(mockSecondaryWorkspaceActions.dirList).not.toHaveBeenCalled(); + }, + ); + + it.each(['/primary', '/secondary'])( + 'only exposes file references for the active workspace (%s)', + async (workspaceCwd) => { + const onReferenceFile = vi.fn(); + const container = document.createElement('div'); + document.body.appendChild(container); + const root = createRoot(container); + mounted.push({ root, container }); + fileBrowserProps.current = undefined; + await act(async () => + root.render( + + {}} + onCloseTab={() => {}} + onOpenFilePreview={() => {}} + onClose={() => {}} + /> + , + ), + ); + expect(fileBrowserProps.current).toBeDefined(); + if (workspaceCwd === '/secondary') { + fileBrowserProps.current?.onReferenceFile?.('src/app.ts'); + expect(onReferenceFile).toHaveBeenCalledWith('src/app.ts'); + } else { + expect(fileBrowserProps.current?.onReferenceFile).toBeUndefined(); + } + }, + ); + + it('rejects a restored files tab with a different workspace ID before mounting the tree', () => { + const container = document.createElement('div'); + document.body.appendChild(container); + const root = createRoot(container); + mounted.push({ root, container }); + act(() => + root.render( + + {}} + onCloseTab={() => {}} + onOpenFilePreview={() => {}} + onClose={() => {}} + /> + , + ), + ); + expect(container.querySelector('[role="alert"]')?.textContent).toContain( + 'removed', + ); + expect(mockSecondaryWorkspaceActions.dirList).not.toHaveBeenCalled(); + expect( + container.querySelector('[data-testid="workspace-file-browser"]'), + ).toBeNull(); + }); + it('opens the latest review from the empty page', () => { const onOpenLatestReview = vi.fn(); const container = document.createElement('div'); diff --git a/packages/web-shell/client/components/artifacts/ArtifactPanel.tsx b/packages/web-shell/client/components/artifacts/ArtifactPanel.tsx index 96fbb8e707a..b793f6278e2 100644 --- a/packages/web-shell/client/components/artifacts/ArtifactPanel.tsx +++ b/packages/web-shell/client/components/artifacts/ArtifactPanel.tsx @@ -1,3 +1,5 @@ +import { useDaemonTargetOptional } from '../../config/daemon-target'; +import { hasReloadSurvivableDaemonToken } from '../../config/daemon'; import type { DaemonSessionArtifact, SessionSource, @@ -9,6 +11,7 @@ import type { ACPToolCall, TodoItem } from '../../adapters/types'; import type { WebShellRightPanelItem } from '../../customization'; import { useConnection, + useWorkspace, type DaemonSessionOwnerSnapshot, type DaemonSessionActions, type DaemonScheduledTask, @@ -24,6 +27,7 @@ import { ExpandIcon, GaugeIcon, GlobeIcon, + FolderIcon as FilesIcon, ImageIcon, LayersIcon, WrenchIcon, @@ -38,6 +42,8 @@ import { } from 'lucide-react'; import { Skeleton } from '../ui/skeleton'; import { Button } from '../ui/button'; +import { ErrorBoundary } from '../ErrorBoundary'; +import { RootErrorFallback } from '../RootErrorFallback'; import { lazy, Suspense, @@ -60,7 +66,6 @@ import { formatRelativeTime } from '../../utils/formatRelativeTime'; import { normalizeTextMediaType } from '../../utils/imageIngestion'; import { DialogShell } from '../dialogs/DialogShell'; import { FileTypeIcon } from '../FileTypeIcon'; -import { ErrorBoundary } from '../ErrorBoundary'; import { isSafeHref, Markdown } from '../messages/Markdown'; import { DropdownMenu, @@ -125,6 +130,7 @@ import type { ContextUsageControls } from '../../hooks/useContextUsageControls'; import { ContextUsagePanel } from './ContextUsagePanel'; import { useArtifactWorkspaceTarget, + resolveArtifactWorkspaceOwner, type ArtifactWorkspaceActions, } from './useArtifactWorkspaceTarget'; import { @@ -132,6 +138,20 @@ import { ShellTaskDetail, } from '../messages/TasksStatusMessage'; +class FilePaneImportError extends Error {} + +function fileImportFailed(error: unknown): never { + throw new FilePaneImportError( + error instanceof Error ? error.message : String(error), + ); +} + +const loadWorkspaceFileBrowser = () => + import('./WorkspaceFileBrowser') + .then((module) => ({ default: module.WorkspaceFileBrowser })) + .catch(fileImportFailed); +const loadPierreFilePreview = () => + import('./PierreFilePreview').catch(fileImportFailed); const SpreadsheetPreview = lazy(() => import('./SpreadsheetPreview')); const MAX_REVIEW_SIDE_BY_SIDE_WIDTH = 700; @@ -160,6 +180,13 @@ export type ImageTabSource = { }; export type ArtifactPanelTab = + | { + id: string; + kind: 'files'; + title: string; + workspaceCwd: string; + workspaceId?: string; + } | (WebPreviewState & { id: string; kind: 'web_preview'; @@ -413,7 +440,7 @@ interface ArtifactPanelProps { onSelectTab: (tabId: string) => void; onCloseTab: (tabId: string) => void; onOpenFilePreview: ( - change: TurnOutputFileChange, + change: TurnOutputFileChange | string, workspaceCwd?: string, workspaceId?: string, ) => void; @@ -430,6 +457,8 @@ interface ArtifactPanelProps { * than for any trajectory tab at all. */ trajectoryTabId?: string; + onOpenFiles?: () => void; + onReferenceFile?: (path: string) => void; onOpenWebPreview?: () => void; onWebPreviewChange?: (tabId: string, state: WebPreviewState) => void; items?: readonly WebShellRightPanelItem[]; @@ -489,6 +518,113 @@ interface ArtifactPanelProps { onToggleFullscreen?: () => void; } +function WorkspaceFilesPane({ + tab, + workspaceCwd, + onOpenFilePreview, + onReferenceFile, + onClose, +}: { + onClose: () => void; + tab: Extract; +} & Pick< + ArtifactPanelProps, + 'workspaceCwd' | 'onOpenFilePreview' | 'onReferenceFile' +>) { + const { t, language } = useI18n(); + const daemonTarget = useDaemonTargetOptional(); + const WorkspaceFileBrowser = useMemo( + () => lazy(loadWorkspaceFileBrowser), + [], + ); + const PierreFilePreview = useMemo(() => lazy(loadPierreFilePreview), []); + const target = useArtifactWorkspaceTarget(tab.workspaceCwd); + const actions = + target?.workspaceId === tab.workspaceId ? target?.actions : undefined; + if (!actions) { + return ( +
+ {t('workspace.notFoundDescription')} +
+ ); + } + const failure = (error: Error, reset: () => void) => { + // Browsers cache rejected module imports too; only a page reload clears + // that cache. Renderer errors can remount locally without losing the tree. + const reload = error instanceof FilePaneImportError; + const canReload = () => + Boolean( + daemonTarget && + (!daemonTarget.activeToken || hasReloadSurvivableDaemonToken()), + ); + if (reload && !canReload()) + return ( +
+

{t('files.loadFailed')}

+

{t('files.reloadUnavailable')}

+ +
+ ); + return ( + { + if (canReload()) window.location.reload(); + else onClose(); + } + : reset + } + /> + ); + }; + return ( + + {t('common.loading')}
} + > + + onOpenFilePreview(path, tab.workspaceCwd, tab.workspaceId) + } + onReferenceFile={ + tab.workspaceCwd === workspaceCwd ? onReferenceFile : undefined + } + renderPreview={(path, source, version) => ( + ( + + {t('common.loading')}
+ } + > + + + + )} + /> + )} + /> + + + ); +} + export function ArtifactPanel({ contextUsageControls, artifacts, @@ -510,6 +646,8 @@ export function ArtifactPanel({ onOpenTerminal, onOpenTrajectory, trajectoryTabId, + onOpenFiles, + onReferenceFile, onOpenWebPreview, onWebPreviewChange, items = DEFAULT_RIGHT_PANEL_ITEMS, @@ -541,6 +679,11 @@ export function ArtifactPanel({ onToggleFullscreen, }: ArtifactPanelProps) { const { t } = useI18n(); + const workspace = useWorkspace(); + const filesOwner = resolveArtifactWorkspaceOwner( + workspace.capabilities, + workspaceCwd, + ); const [sideTaskMenuOpen, setSideTaskMenuOpen] = useState(false); const [previewAttachmentId, setPreviewAttachmentId] = useState(); const sideTaskMenuCloseTimerRef = useRef tab.id === trajectoryTabId); + const showFilesMenuItem = + items.includes('files') && + Boolean(onOpenFiles) && + !tabs.some( + (tab) => + tab.kind === 'files' && + tab.workspaceCwd === workspaceCwd && + tab.workspaceId === filesOwner?.id, + ); const showAddMenu = Boolean(activeTab) && - (showReviewMenuItem || + (showFilesMenuItem || + showReviewMenuItem || showSideTaskMenuItems || showTerminalMenuItem || showWebPreviewMenuItem || @@ -677,6 +830,8 @@ export function ArtifactPanel({ > {getArtifactPanelTabKind(tab) === 'review' ? ( + ) : tab.kind === 'files' ? ( + ) : tab.kind === 'workflow' ? ( + {showFilesMenuItem && ( + + + + {t('files.title')} + + + )} {showReviewMenuItem && (
{tabs @@ -907,6 +1072,23 @@ export function ArtifactPanel({ />
))} + {tabs + .filter((tab) => tab.kind === 'files') + .map((tab) => ( + + ))} {tabs .filter((tab) => tab.kind === 'terminal') .map((tab) => ( @@ -966,11 +1148,35 @@ export function ArtifactPanel({ ) : activeTab?.kind === 'terminal' || - activeTab?.kind === 'web_preview' ? null : !activeTab ? ( + activeTab?.kind === 'web_preview' || + activeTab?.kind === 'files' ? null : !activeTab ? (
+ {items.includes('files') && ( + + )} {items.includes('review') && (