diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d137928 --- /dev/null +++ b/LICENSE @@ -0,0 +1,12 @@ +Copyright (c) 2025 IC Coder Team. All rights reserved. + +本软件及其相关文档文件(以下简称"软件")的版权归 IC Coder 所有。 + +未经版权所有者事先书面许可,不得以任何形式或方式(电子、机械、复印、录制或其他方式) +复制、分发、传播、展示、修改或创建本软件的衍生作品。 + +本软件按"原样"提供,不提供任何明示或暗示的保证,包括但不限于适销性、特定用途适用性 +和非侵权性的保证。在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责, +无论是在合同诉讼、侵权行为还是其他方面。 + +如需商业使用或获取许可,请联系:[pyjtkj@pyjtkj.com] diff --git a/PUBLISH.md b/PUBLISH.md new file mode 100644 index 0000000..d085761 --- /dev/null +++ b/PUBLISH.md @@ -0,0 +1,356 @@ +# IC Coder 插件发布流程文档 + +本文档详细说明如何将 IC Coder 插件发布到 VS Code 插件市场进行测试和正式发布。 + +## 目录 + +- [前置准备](#前置准备) +- [账号配置](#账号配置) +- [插件信息完善](#插件信息完善) +- [打包与发布](#打包与发布) +- [版本更新](#版本更新) +- [常见问题](#常见问题) + +--- + +## 前置准备 + +### 环境要求 + +- Node.js 和 pnpm 已安装 +- VS Code 1.80.0 或更高版本 +- 已安装 `@vscode/vsce` 工具(项目已包含) + +### 检查清单 + +在发布前,请确保以下文件和配置已准备就绪: + +- [x] `package.json` - 插件配置文件 +- [x] `README.md` - 插件说明文档 +- [x] `dist/` - 编译后的代码 +- [x] `media/` - 图标和资源文件 +- [ ] `CHANGELOG.md` - 版本更新日志(建议添加) +- [x] `LICENSE` - 开源许可证(建议添加) + +--- + +## 账号配置 + +### 1. 创建 Azure DevOps 账号 + +1. 访问 [Azure DevOps](https://dev.azure.com) +2. 使用 Microsoft 账号注册或登录 +3. 创建一个组织(如果还没有) + +### 2. 生成 Personal Access Token (PAT) + +这是发布插件的关键凭证,请妥善保管。 + +**步骤:** + +1. 登录 Azure DevOps +2. 点击右上角用户图标 → **User settings** → **Personal access tokens** +3. 点击 **New Token** 按钮 +4. 配置 Token 信息: + - **Name**: `vscode-publisher`(或其他易识别的名称) + - **Organization**: 选择 **All accessible organizations** + - **Expiration**: 建议选择较长期限(如 90 天或自定义) + - **Scopes**: 选择 **Custom defined** + - 展开 **Marketplace** + - 勾选 **Manage**(包含发布和管理权限) +5. 点击 **Create** 生成 Token +6. **重要**: 立即复制并保存 Token,页面关闭后将无法再次查看 + +**Token 示例格式:** + +``` +CO03l8nmFBBTNPDg7lN9a9fYwDdgsRIDVDwTrx6Esggi6HnzmrMTJQQJ99BLACAAAAAAAAAAAAAGAZDOVVyT +``` + +### 3. 创建发布者账号 + +发布者账号是你在 VS Code 市场的身份标识。 + +**步骤:** + +1. 访问 [VS Code Marketplace 管理页面](https://marketplace.visualstudio.com/manage) +2. 使用 Azure DevOps 账号登录 +3. 点击 **Create publisher** 按钮 +4. 填写发布者信息: + - **ID**: `ICCoder`(必须与 package.json 中的 `publisher` 字段一致) + - **Name**: `IC Coder`(显示名称,可自定义) + - **Email**: 你的联系邮箱 +5. 点击 **Create** 完成创建 + +**注意事项:** +- Publisher ID 一旦创建无法修改 +- Publisher ID 必须全局唯一 +- 建议使用有意义且专业的 ID + +--- + +## 插件信息完善 + +### 1. 完善 package.json + +建议在 `package.json` 中添加以下字段以提升插件质量: + +```json +{ + "repository": { + "type": "git", + "url": "https://github.com/your-org/ic-coder.git" + }, + "homepage": "https://github.com/your-org/ic-coder#readme", + "bugs": { + "url": "https://github.com/your-org/ic-coder/issues" + }, + "license": "MIT" +} +``` + +### 2. 创建 CHANGELOG.md + +版本更新日志帮助用户了解每个版本的变化。 + +**示例内容:** + +```markdown +# 更新日志 + +## [0.0.2] - 2025-12-29 + +### 新增 +- 添加发送和暂停按钮功能 +- 添加一键优化按钮组件 +- 添加 Plan 开关组件 +- 添加模式选择器组件 +- 添加上下文压缩功能 + +### 改进 +- 优化用户界面交互体验 + +## [0.0.1] - 2025-12-XX + +### 新增 +- 初始版本发布 +- Verilog 代码智能生成 +- 集成 iverilog 仿真工具 +- VCD 波形文件查看器 +``` + +### 3. 创建 LICENSE 文件 + +如果使用 MIT 许可证,创建 `LICENSE` 文件: + +``` +MIT License + +Copyright (c) 2025 IC Coder Team + +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... +``` + +### 4. 优化 README.md + +确保 README 包含: +- 清晰的功能介绍 +- 使用截图或 GIF 演示 +- 详细的使用说明 +- 系统要求 +- 常见问题解答 + +--- + +## 打包与发布 + +### 方式一:命令行发布(推荐) + +这是最便捷的发布方式,适合频繁更新。 + +**步骤:** + +1. **登录发布者账号** + +```bash +pnpm vsce login ic-coder-team +``` + +系统会提示输入 Personal Access Token,粘贴之前创建的 PAT。 + +2. **打包插件** + +```bash +# 执行生产环境构建 +pnpm run package + +# 打包成 .vsix 文件 +pnpm vsce package +``` + +这会生成 `ic-coder-plugin-0.0.2.vsix` 文件。 + +3. **发布到市场** + +```bash +pnpm vsce publish +``` + +发布成功后会显示插件的市场链接。 + +**一键发布(跳过打包步骤):** + +```bash +# 直接发布当前版本 +pnpm vsce publish +``` + +### 方式二:手动上传 + +适合首次发布或网络环境受限的情况。 + +**步骤:** + +1. 本地打包插件: +```bash +pnpm run package +pnpm vsce package[pnpm vsce package --no-dependencies] +``` + +2. 访问 [发布者管理页面](https://marketplace.visualstudio.com/manage/publishers/ic-coder-team) + +3. 点击 **New extension** → **Visual Studio Code** + +4. 上传 `ic-coder-plugin-0.0.2.vsix` 文件 + +5. 填写插件信息(如果需要)并提交 + +6. 等待审核通过 + +--- + +## 版本更新 + +### 自动更新版本号 + +使用 `vsce publish` 命令可以自动更新版本号并发布: + +```bash +# 补丁版本更新(0.0.2 → 0.0.3) +pnpm vsce publish patch + +# 次版本更新(0.0.2 → 0.1.0) +pnpm vsce publish minor + +# 主版本更新(0.0.2 → 1.0.0) +pnpm vsce publish major +``` + +### 手动指定版本 + +```bash +# 发布指定版本 +pnpm vsce publish 0.0.3 +``` + +### 更新流程建议 + +1. 修改代码并测试 +2. 更新 `CHANGELOG.md` 记录变更 +3. 提交代码到 Git +4. 执行发布命令 +5. 验证市场上的插件是否正常 + +--- + +## 常见问题 + +### 1. 发布失败:Authentication failed + +**原因:** PAT Token 无效或过期 + +**解决方案:** +- 重新生成 PAT Token +- 重新登录:`pnpm vsce login ic-coder-team` + +### 2. 发布失败:Publisher not found + +**原因:** Publisher ID 不存在或不匹配 + +**解决方案:** +- 检查 `package.json` 中的 `publisher` 字段 +- 确认已在市场创建对应的 Publisher + +### 3. 打包失败:Missing files + +**原因:** 必需文件缺失 + +**解决方案:** +- 确保 `dist/` 目录存在且包含编译后的代码 +- 运行 `pnpm run package` 重新构建 + +### 4. 插件审核被拒 + +**常见原因:** +- 插件名称或描述违反市场规则 +- 图标不符合要求(建议 128x128 PNG) +- README 内容不完整 + +**解决方案:** +- 查看审核反馈邮件 +- 修改相关内容后重新发布 + +### 5. 如何撤回已发布的版本? + +```bash +# 取消发布指定版本 +pnpm vsce unpublish ic-coder-team.ic-coder-plugin@0.0.2 + +# 取消发布整个插件(慎用) +pnpm vsce unpublish ic-coder-team.ic-coder-plugin +``` + +### 6. 如何本地测试 .vsix 文件? + +```bash +# 在 VS Code 中安装本地 .vsix 文件 +code --install-extension ic-coder-plugin-0.0.2.vsix +``` + +或者在 VS Code 中: +1. 打开扩展面板 +2. 点击 `...` 菜单 +3. 选择 **Install from VSIX...** +4. 选择 `.vsix` 文件 + +--- + +## 发布检查清单 + +在正式发布前,请确认以下事项: + +- [ ] 代码已充分测试,无明显 Bug +- [ ] `package.json` 版本号已更新 +- [ ] `CHANGELOG.md` 已记录本次更新内容 +- [ ] README.md 内容完整且准确 +- [ ] 图标和资源文件正常显示 +- [ ] 已在本地安装测试 .vsix 文件 +- [ ] 已创建 Azure DevOps PAT Token +- [ ] 已创建 VS Code Marketplace Publisher +- [ ] 已执行 `pnpm run package` 构建生产版本 + +--- + +## 参考资源 + +- [VS Code 插件发布官方文档](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) +- [vsce 工具文档](https://github.com/microsoft/vscode-vsce) +- [Azure DevOps 文档](https://docs.microsoft.com/en-us/azure/devops/) +- [VS Code 插件市场](https://marketplace.visualstudio.com/) + +--- + +**文档维护:** IC Coder Team +**最后更新:** 2025-12-29 diff --git a/docs/authentication-implementation.md b/docs/authentication-implementation.md new file mode 100644 index 0000000..546ff95 --- /dev/null +++ b/docs/authentication-implementation.md @@ -0,0 +1,573 @@ +# IC Coder 认证系统实现文档 + +## 概述 + +本文档详细说明了 IC Coder 插件如何集成 VSCode Authentication API,实现用户登录功能,并在 VSCode 左下角账户区域显示登录状态。 + +## 架构设计 + +### 核心组件 + +1. **ICCoderAuthenticationProvider** - 认证提供者 +2. **VSCode Authentication API** - VSCode 官方认证接口 +3. **本地 HTTP 服务器** - 处理登录回调 +4. **ICViewProvider** - 侧边栏视图(根据登录状态显示不同按钮) + +### 工作流程 + +``` +用户点击登录 + ↓ +调用 vscode.authentication.getSession() + ↓ +ICCoderAuthenticationProvider.createSession() + ↓ +启动本地 HTTP 服务器(动态端口) + ↓ +打开浏览器访问登录页面 + ↓ +用户在网站完成登录 + ↓ +网站重定向到 http://localhost:{port}/callback?token=xxx + ↓ +本地服务器接收 token + ↓ +创建 AuthenticationSession + ↓ +VSCode 左下角显示账户信息 +``` + +## 详细实现 + +### 1. Authentication Provider 实现 + +文件:`src/services/icCoderAuthProvider.ts` + +#### 1.1 类定义 + +```typescript +export class ICCoderAuthenticationProvider + implements vscode.AuthenticationProvider +{ + private _onDidChangeSessions = + new vscode.EventEmitter(); + public readonly onDidChangeSessions = this._onDidChangeSessions.event; + + private _sessions: vscode.AuthenticationSession[] = []; +} +``` + +**关键点:** + +- 实现 `vscode.AuthenticationProvider` 接口 +- 使用 `EventEmitter` 通知会话变化 +- 在内存中维护会话列表 + +#### 1.2 核心方法 + +##### getSessions() - 获取会话列表 + +```typescript +async getSessions(scopes?: readonly string[]): Promise { + return this._sessions; +} +``` + +##### createSession() - 创建会话(登录) + +```typescript +async createSession(scopes: readonly string[]): Promise { + const token = await this.login(); + + const session: vscode.AuthenticationSession = { + id: this.generateSessionId(), + accessToken: token, + account: { + id: "iccoder-user", + label: "IC Coder 用户", + }, + scopes: [...scopes], + }; + + this._sessions.push(session); + await this.saveSessions(); + + this._onDidChangeSessions.fire({ + added: [session], + removed: [], + changed: [], + }); + + return session; +} +``` + +**关键点:** + +- 调用 `login()` 方法获取 token +- 创建 `AuthenticationSession` 对象 +- 保存到 `globalState` +- 触发 `onDidChangeSessions` 事件通知 VSCode + +##### removeSession() - 删除会话(登出) + +```typescript +async removeSession(sessionId: string): Promise { + const sessionIndex = this._sessions.findIndex((s) => s.id === sessionId); + if (sessionIndex > -1) { + const session = this._sessions[sessionIndex]; + this._sessions.splice(sessionIndex, 1); + await this.saveSessions(); + + this._onDidChangeSessions.fire({ + added: [], + removed: [session], + changed: [], + }); + } +} +``` + +### 2. 本地 HTTP 服务器实现 + +#### 2.1 动态端口分配 + +```typescript +server.listen(0, () => { + const address = server.address(); + const port = typeof address === "object" && address ? address.port : 3000; + resolve({ server, port }); +}); +``` + +**关键点:** + +- 使用端口 `0` 让系统自动分配可用端口 +- 避免端口冲突问题 +- 支持多个用户同时使用 + +#### 2.2 回调处理 + +```typescript +if (url.pathname === "/callback") { + const token = url.searchParams.get("token"); + + if (token) { + // 返回成功页面 + res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" }); + res.end(this.getSuccessPage(iconBase64)); + + // 关闭服务器 + server.close(); + + // 返回 token + if ((server as any)._loginResolve) { + (server as any)._loginResolve(token); + } + } +} +``` + +### 3. package.json 配置 + +#### 3.1 注册 Authentication Provider + +```json +{ + "contributes": { + "authentication": [ + { + "id": "iccoder", + "label": "IC Coder" + } + ] + } +} +``` + +**关键点:** + +- `id` 必须与代码中使用的 ID 一致 +- `label` 会显示在 VSCode 账户菜单中 + +#### 3.2 注册命令 + +```json +{ + "contributes": { + "commands": [ + { + "command": "ic-coder.login", + "title": "IC Coder: 登录账户", + "category": "IC Coder" + }, + { + "command": "ic-coder.logout", + "title": "IC Coder: 退出登录", + "category": "IC Coder" + } + ] + } +} +``` + +### 4. extension.ts 注册 + +#### 4.1 注册 Authentication Provider + +```typescript +export function activate(context: vscode.ExtensionContext) { + // 注册 Authentication Provider + const authProvider = new ICCoderAuthenticationProvider(context); + context.subscriptions.push( + vscode.authentication.registerAuthenticationProvider( + "iccoder", + "IC Coder", + authProvider + ) + ); +} +``` + +#### 4.2 登录命令 + +```typescript +const loginCommand = vscode.commands.registerCommand( + "ic-coder.login", + async () => { + try { + await vscode.authentication.getSession("iccoder", [], { + createIfNone: true, + }); + } catch (error) { + vscode.window.showErrorMessage(`登录失败: ${error}`); + } + } +); +``` + +**关键点:** + +- `createIfNone: true` 会在没有会话时自动调用 `createSession()` +- VSCode 会自动处理 UI 交互 + +#### 4.3 登出命令 + +```typescript +const logoutCommand = vscode.commands.registerCommand( + "ic-coder.logout", + async () => { + try { + const session = await vscode.authentication.getSession("iccoder", [], { + createIfNone: false, + }); + if (session) { + await vscode.authentication.getSession("iccoder", [], { + clearSessionPreference: true, + forceNewSession: true, + }); + vscode.window.showInformationMessage("已退出登录"); + } + } catch (error) { + vscode.window.showInformationMessage("当前未登录"); + } + } +); +``` + +### 5. ICViewProvider 集成 + +#### 5.1 检查登录状态 + +```typescript +private async checkLoginStatus(): Promise { + try { + const session = await vscode.authentication.getSession("iccoder", [], { createIfNone: false }); + return !!session; + } catch (error) { + return false; + } +} +``` + +#### 5.2 根据登录状态显示不同按钮 + +```typescript +resolveWebviewView(webviewView: vscode.WebviewView) { + this.checkLoginStatus().then((isLoggedIn) => { + webviewView.webview.html = this.getWebviewContent( + webviewView.webview, + isLoggedIn + ); + }); +} +``` + +```typescript +${isLoggedIn + ? '' + : '' +} +``` + +### 6. 网站前端配置 + +#### 6.1 检测插件登录请求 + +```javascript +// 在登录页面检测 redirect_uri 参数 +const urlParams = new URLSearchParams(window.location.search); +const redirectUri = urlParams.get("redirect_uri"); + +if (redirectUri) { + // 保存回调地址 + localStorage.setItem("plugin_redirect_uri", redirectUri); +} +``` + +#### 6.2 登录成功后重定向 + +```javascript +// 用户登录成功,拿到 token +const token = response.data.token; + +// 检查是否需要重定向回插件 +const redirectUri = localStorage.getItem("plugin_redirect_uri"); + +if (redirectUri) { + // 重定向回插件,带上 token + window.location.href = `${redirectUri}?token=${token}`; + localStorage.removeItem("plugin_redirect_uri"); +} else { + // 正常登录流程 + router.push("/dashboard"); +} +``` + +## 关键技术点 + +### 1. 动态端口分配 + +**问题:** 固定端口可能被占用,导致登录失败 + +**解决方案:** 使用端口 `0` 让系统自动分配可用端口 + +```typescript +server.listen(0, () => { + const address = server.address(); + const port = typeof address === "object" && address ? address.port : 3000; +}); +``` + +### 2. Promise 异步等待 + +**问题:** 需要等待浏览器登录完成后才能继续 + +**解决方案:** 使用 Promise 包装回调逻辑 + +```typescript +return new Promise((resolve, reject) => { + (server as any)._loginResolve = resolve; + (server as any)._loginReject = reject; +}); +``` + +### 3. 会话持久化 + +**问题:** 重启 VSCode 后需要重新登录 + +**解决方案:** 使用 `globalState` 保存会话 + +```typescript +await this.context.globalState.update("icCoderSessions", this._sessions); +``` + +### 4. 事件通知机制 + +**问题:** VSCode 需要知道会话状态变化 + +**解决方案:** 使用 `EventEmitter` 触发事件 + +```typescript +this._onDidChangeSessions.fire({ + added: [session], + removed: [], + changed: [], +}); +``` + +## 用户体验 + +### 登录流程 + +1. 用户点击侧边栏"登录账户"按钮 +2. 浏览器自动打开登录页面 +3. 用户在网站完成登录 +4. 浏览器自动跳转到成功页面 +5. VSCode 左下角显示"IC Coder 用户" +6. 侧边栏按钮变为"开始创作" + +### 登出流程 + +1. 点击 VSCode 左下角账户图标 +2. 选择"IC Coder"账户 +3. 点击"退出"按钮 +4. 或使用命令 `IC Coder: 退出登录` + +## 常见问题 + +### Q1: 为什么不直接使用 globalState 存储 token? + +**A:** 使用 VSCode Authentication API 的优势: + +- ✅ 统一的用户体验(左下角账户区域) +- ✅ VSCode 自动管理会话生命周期 +- ✅ 支持多账户切换 +- ✅ 更好的安全性(VSCode 负责加密存储) + +### Q2: 如何处理 token 过期? + +**A:** 可以在 API 请求失败时: + +1. 检测 401 错误 +2. 调用 `removeSession()` 清除过期会话 +3. 提示用户重新登录 + +### Q3: 如何支持多个账户? + +**A:** 修改 `account` 对象: + +```typescript +account: { + id: userInfo.id, + label: userInfo.username, +} +``` + +### Q4: 登录页面如何获取用户信息? + +**A:** 可以在登录成功后,通过 API 获取用户信息: + +```typescript +const userInfo = await fetch("https://api.iccoder.com/user/info", { + headers: { Authorization: `Bearer ${token}` }, +}); + +const session: vscode.AuthenticationSession = { + account: { + id: userInfo.id, + label: userInfo.username, + }, + // ... +}; +``` + +## 安全考虑 + +### 1. Token 存储 + +- ✅ 使用 VSCode `globalState` 加密存储 +- ✅ 不在代码中硬编码敏感信息 +- ✅ Token 仅在内存和加密存储中传递 + +### 2. 本地服务器 + +- ✅ 仅监听 `localhost`,不暴露到外网 +- ✅ 使用动态端口,避免固定端口被劫持 +- ✅ 接收到 token 后立即关闭服务器 +- ✅ 设置 5 分钟超时,防止服务器长期运行 + +### 3. HTTPS 考虑 + +**当前实现:** 使用 HTTP 本地回调 + +**生产环境建议:** + +- 网站使用 HTTPS +- 本地回调使用 HTTP(localhost 不受浏览器限制) +- 或使用 `vscode://` 协议(需要网站支持) + +## 测试指南 + +### 1. 本地测试 + +```bash +# 启动调试模式 +按 F5 + +# 测试登录 +1. 打开侧边栏 +2. 点击"登录账户" +3. 在浏览器完成登录 +4. 检查左下角是否显示账户 + +# 测试登出 +1. 点击左下角账户 +2. 选择"IC Coder" +3. 点击"退出" +``` + +### 2. 调试技巧 + +```typescript +// 在 ICCoderAuthenticationProvider 中添加日志 +console.log("🔐 创建会话:", session); +console.log("🔑 Token:", token); + +// 在 ICViewProvider 中添加日志 +console.log("🔍 登录状态:", isLoggedIn); +``` + +### 3. 常见错误排查 + +| 错误 | 原因 | 解决方案 | +| ------------------------------- | --------------- | ---------------------------------- | +| `getSessions is not a function` | VSCode 版本过低 | 升级到 1.63.0+ | +| 端口被占用 | 固定端口冲突 | 使用动态端口(已实现) | +| 登录后未显示账户 | 未触发事件 | 检查 `_onDidChangeSessions.fire()` | +| 重启后需要重新登录 | 未保存会话 | 检查 `saveSessions()` 调用 | + +## 文件结构 + +``` +ic-coder/ +├── src/ +│ ├── services/ +│ │ └── icCoderAuthProvider.ts # Authentication Provider 实现 +│ ├── views/ +│ │ └── ICViewProvider.ts # 侧边栏视图(集成登录状态) +│ └── extension.ts # 注册 Provider 和命令 +├── package.json # 配置 authentication 和 commands +└── docs/ + └── authentication-implementation.md # 本文档 +``` + +## 参考资料 + +- [VSCode Authentication API](https://code.visualstudio.com/api/references/vscode-api#authentication) +- [Authentication Provider Sample](https://github.com/microsoft/vscode-extension-samples/tree/main/authentication-sample) +- [VSCode Extension Guidelines](https://code.visualstudio.com/api/references/extension-guidelines) + +## 总结 + +本实现通过以下步骤完成了 VSCode Authentication API 的集成: + +1. ✅ 创建 `ICCoderAuthenticationProvider` 类实现认证逻辑 +2. ✅ 在 `package.json` 中注册 authentication provider +3. ✅ 在 `extension.ts` 中注册 provider 和命令 +4. ✅ 实现本地 HTTP 服务器处理登录回调 +5. ✅ 使用动态端口避免冲突 +6. ✅ 集成到侧边栏视图,根据登录状态显示不同按钮 +7. ✅ 配置网站前端支持插件登录重定向 + +**最终效果:** + +- 用户登录后,VSCode 左下角显示"IC Coder 用户" +- 侧边栏根据登录状态显示"登录账户"或"开始创作"按钮 +- 支持通过账户菜单或命令进行登录/登出操作 + +--- + +**文档版本:** 1.0 +**最后更新:** 2025-12-29 +**作者:** Roe-xin diff --git a/docs/会话存储技术文档.md b/docs/会话存储技术文档.md new file mode 100644 index 0000000..8377543 --- /dev/null +++ b/docs/会话存储技术文档.md @@ -0,0 +1,751 @@ +# IC Coder 会话存储技术文档 + +## 1. 概述 + +IC Coder 的会话存储系统负责持久化保存用户与 AI 的对话历史,支持多项目、多任务的会话管理。系统采用文件系统存储方案,将会话数据按项目和任务组织,便于管理和检索。 + +### 1.1 核心特性 + +- **多项目支持**:不同项目的会话数据独立存储 +- **任务级管理**:每个会话作为独立任务进行管理 +- **分页加载**:支持历史会话的分页查询,提升性能 +- **实时更新**:会话数据实时保存,防止数据丢失 +- **统计信息**:记录 Token 使用量、对话轮次等统计数据 + +### 1.2 技术栈 + +- **存储方式**:文件系统(JSON/JSONL 格式) +- **存储位置**:`~/.iccoder/projects/{项目路径编码}/{taskId}/` +- **数据格式**: + - `meta.json`:任务元数据 + - `conversation.json`:完整对话历史 + - `conversation_meta.jsonl`:对话轮次元数据(JSONL 格式) + +--- + +## 2. 架构设计 + +### 2.1 目录结构 + +``` +~/.iccoder/ +└── projects/ + └── {项目路径编码}/ + └── {taskId}/ + ├── meta.json # 任务元数据 + ├── conversation.json # 对话历史 + └── conversation_meta.jsonl # 对话元数据 +``` + +**项目路径编码规则**: +- 移除冒号 `:` +- 将斜杠 `/` 和反斜杠 `\` 替换为 `--` +- 示例:`C:\Users\admin\Documents\Project` → `C--Users--admin--Documents--Project` + +**任务 ID 格式**: +- 格式:`task_{date}_{sequence}` +- 示例:`task_20231226_a3f9k2` +- `date`:8 位日期(YYYYMMDD) +- `sequence`:6 位随机字符串 + +### 2.2 核心类:ChatHistoryManager + +`ChatHistoryManager` 是会话存储的核心管理类,采用单例模式设计。 + +**主要职责**: +1. 管理会话存储目录 +2. 创建和切换任务 +3. 保存和加载对话历史 +4. 记录统计信息 +5. 提供会话历史查询接口 + +**关键属性**: +```typescript +private static instance: ChatHistoryManager; +private baseDir: string; // ~/.iccoder +private currentTaskId: string | null; // 当前任务 ID +private currentProjectPath: string | null; // 当前项目路径 +``` + +--- + +## 3. 数据模型 + +### 3.1 TaskMeta(任务元数据) + +存储在 `meta.json` 文件中,记录任务的基本信息和统计数据。 + +```typescript +interface TaskMeta { + taskId: string; // 任务 ID + taskName: string; // 任务名称 + projectPath: string; // 项目路径 + createdAt: string; // 创建时间(ISO 8601) + updatedAt: string; // 更新时间(ISO 8601) + stats: { + credits: number; // 消耗的积分 + totalTokens: number; // 总 Token 数 + inputTokens: number; // 输入 Token 数 + outputTokens: number; // 输出 Token 数 + }; +} +``` + +**示例**: +```json +{ + "taskId": "task_20231226_a3f9k2", + "taskName": "实现计数器功能", + "projectPath": "C:\\Users\\admin\\Documents\\Project", + "createdAt": "2023-12-26T10:30:00.000Z", + "updatedAt": "2023-12-26T11:45:00.000Z", + "stats": { + "credits": 0, + "totalTokens": 15420, + "inputTokens": 8200, + "outputTokens": 7220 + } +} +``` + +### 3.2 ChatMessage(对话消息) + +存储在 `conversation.json` 文件中,记录完整的对话历史。 + +**消息类型枚举**: +```typescript +enum MessageType { + USER = "USER", // 用户消息 + AI = "AI", // AI 消息 + SYSTEM = "SYSTEM", // 系统消息 + TOOL_EXECUTION_RESULT = "TOOL_EXECUTION_RESULT" // 工具执行结果 +} +``` + +**用户消息**: +```typescript +interface UserMessage { + type: MessageType.USER; + contents: Array<{ + type: "TEXT"; + text: string; + }>; +} +``` + +**AI 消息**: +```typescript +interface AiMessage { + type: MessageType.AI; + text: string; + toolExecutionRequests?: Array<{ + id: string; + toolName: string; + parameters: any; + }>; +} +``` + +**系统消息**: +```typescript +interface SystemMessage { + type: MessageType.SYSTEM; + text: string; +} +``` + +**工具执行结果消息**: +```typescript +interface ToolExecutionResultMessage { + type: MessageType.TOOL_EXECUTION_RESULT; + id: string; + toolName: string; + text: string; +} +``` + +### 3.3 ConversationMeta(对话轮次元数据) + +存储在 `conversation_meta.jsonl` 文件中,每行一条记录(JSONL 格式)。 + +```typescript +interface ConversationMeta { + turnId: number; // 对话轮次 ID + timestamp: string; // 时间戳(ISO 8601) + usage?: { + inputTokens?: number; + outputTokens?: number; + totalTokens?: number; + }; + model?: string; // 使用的模型 + duration?: number; // 耗时(毫秒) +} +``` + +**示例**: +```jsonl +{"turnId":1,"timestamp":"2023-12-26T10:30:15.000Z","usage":{"inputTokens":120,"outputTokens":350,"totalTokens":470},"model":"gpt-4","duration":2500} +{"turnId":2,"timestamp":"2023-12-26T10:32:30.000Z","usage":{"inputTokens":200,"outputTokens":450,"totalTokens":650},"model":"gpt-4","duration":3200} +``` + +--- + +## 4. 核心功能实现 + +### 4.1 任务创建 + +**方法**:`createTask(projectPath: string, taskName: string): Promise` + +**流程**: +1. 生成唯一的任务 ID +2. 创建任务元数据对象 +3. 创建任务目录 +4. 保存 `meta.json` +5. 初始化空的 `conversation.json` +6. 设置为当前任务 + +**代码位置**:`chatHistoryManager.ts:114-146` + +```typescript +public async createTask(projectPath: string, taskName: string): Promise { + const taskId = this.generateTaskId(); + const now = new Date().toISOString(); + + const meta: TaskMeta = { + taskId, + taskName, + projectPath, + createdAt: now, + updatedAt: now, + stats: { + credits: 0, + totalTokens: 0, + inputTokens: 0, + outputTokens: 0 + } + }; + + this.currentTaskId = taskId; + this.currentProjectPath = projectPath; + + // 创建任务目录 + const taskDir = this.getTaskDir(projectPath, taskId); + await this.ensureTaskDir(taskDir); + + // 保存 meta.json + await this.saveTaskMeta(meta); + + // 初始化空的 conversation.json + await this.saveConversation([]); + + return meta; +} +``` + +### 4.2 消息保存 + +系统提供了四种消息保存方法: + +#### 4.2.1 添加用户消息 + +**方法**:`addUserMessage(text: string): Promise` + +**代码位置**:`chatHistoryManager.ts:285-299` + +```typescript +public async addUserMessage(text: string): Promise { + await this.ensureCurrentTask(); + const messages = await this.loadConversation(); + + const userMessage: UserMessage = { + type: MessageType.USER, + contents: [{ type: "TEXT", text }] + }; + + messages.push(userMessage); + await this.saveConversation(messages); + + // 更新任务元数据 + await this.updateTaskTimestamp(); +} +``` + +#### 4.2.2 添加 AI 消息 + +**方法**:`addAiMessage(text: string, toolRequests?: any[]): Promise` + +**代码位置**:`chatHistoryManager.ts:304-319` + +#### 4.2.3 添加系统消息 + +**方法**:`addSystemMessage(text: string): Promise` + +**代码位置**:`chatHistoryManager.ts:324-335` + +#### 4.2.4 添加工具执行结果 + +**方法**:`addToolExecutionResult(id: string, toolName: string, result: string): Promise` + +**代码位置**:`chatHistoryManager.ts:340-353` + +### 4.3 对话元数据记录 + +**方法**:`recordTurnMeta(turnId, usage?, model?, duration?): Promise` + +**功能**:记录每轮对话的元数据,包括 Token 使用量、模型信息、耗时等。 + +**代码位置**:`chatHistoryManager.ts:358-378` + +```typescript +public async recordTurnMeta( + turnId: number, + usage?: { inputTokens?: number; outputTokens?: number; totalTokens?: number }, + model?: string, + duration?: number +): Promise { + const meta: ConversationMeta = { + turnId, + timestamp: new Date().toISOString(), + usage, + model, + duration + }; + + await this.appendConversationMeta(meta); + + // 更新任务统计 + if (usage) { + await this.updateTaskStats(usage); + } +} +``` + +### 4.4 会话历史查询 + +**方法**:`getConversationHistoryList(projectPath, offset, limit): Promise<{items, total, hasMore}>` + +**功能**:分页查询项目的会话历史列表。 + +**参数**: +- `projectPath`:项目路径 +- `offset`:偏移量(从第几条开始,默认 0) +- `limit`:每页数量(默认 10) + +**返回值**: +```typescript +{ + items: Array<{ + id: string; // 任务 ID + title: string; // 会话标题(第一句用户消息) + timestamp: string; // 创建时间 + }>; + total: number; // 总数 + hasMore: boolean; // 是否还有更多 +} +``` + +**代码位置**:`chatHistoryManager.ts:525-590` + +**实现逻辑**: +1. 获取项目的所有任务列表(按更新时间倒序) +2. 根据 offset 和 limit 进行分页 +3. 读取每个任务的 `conversation.json` +4. 提取第一条用户消息作为标题(截取前 50 个字符) +5. 返回分页结果 + +--- + +## 5. 前端集成 + +### 5.1 会话历史栏组件 + +**文件**:`conversationHistoryBar.ts` + +**组件结构**: +- 下拉按钮:显示 "Past Conversations" +- 下拉菜单:显示会话历史列表 +- 新建按钮:创建新会话 + +**关键功能**: + +#### 5.1.1 加载会话历史 + +```javascript +function loadMoreHistory() { + if (isLoadingHistory || (currentOffset > 0 && !hasMoreHistory)) { + return; + } + + // 检查是否已达到最大数量(100 条) + if (currentOffset >= MAX_HISTORY_ITEMS) { + return; + } + + isLoadingHistory = true; + vscode.postMessage({ + command: 'loadConversationHistory', + offset: currentOffset, + limit: HISTORY_PAGE_SIZE + }); +} +``` + +#### 5.1.2 渲染会话列表 + +```javascript +function renderConversationHistory(data) { + isLoadingHistory = false; + + // 追加新数据 + conversationHistory = conversationHistory.concat(data.items); + totalHistory = data.total; + hasMoreHistory = data.hasMore; + currentOffset += data.items.length; + + // 渲染所有历史记录 + historyList.innerHTML = conversationHistory.map(item => ` +
+
${item.title || '未命名会话'}
+
${formatTime(item.timestamp)}
+
+ `).join(''); + + // 如果还有更多数据,添加"加载更多"提示 + if (hasMoreHistory && currentOffset < MAX_HISTORY_ITEMS) { + historyList.innerHTML += ` +
+ 滚动加载更多... +
+ `; + } +} +``` + +#### 5.1.3 滚动加载 + +```javascript +historyDropdownMenu.addEventListener('scroll', () => { + const menu = historyDropdownMenu; + const scrollTop = menu.scrollTop; + const scrollHeight = menu.scrollHeight; + const clientHeight = menu.clientHeight; + + // 当滚动到距离底部 50px 时,加载更多 + if (scrollHeight - scrollTop - clientHeight < 50) { + loadMoreHistory(); + } +}); +``` + +#### 5.1.4 时间格式化 + +```javascript +function formatTime(timestamp) { + const date = new Date(timestamp); + const now = new Date(); + const diff = now - date; + + if (diff < 60000) return '刚刚'; + if (diff < 3600000) return Math.floor(diff / 60000) + '分钟前'; + if (diff < 86400000) return Math.floor(diff / 3600000) + '小时前'; + if (diff < 604800000) return Math.floor(diff / 86400000) + '天前'; + + // 超过7天显示具体日期 + return date.toLocaleDateString('zh-CN', { + year: 'numeric', + month: '2-digit', + day: '2-digit' + }); +} +``` + +### 5.2 后端消息处理 + +**文件**:`ICHelperPanel.ts` + +**消息处理流程**: + +```typescript +case "loadConversationHistory": + // 加载会话历史(支持分页) + loadConversationHistory(panel, message.offset || 0, message.limit || 10); + break; + +case "selectConversation": + // 选择会话(暂未实现) + break; + +case "createNewConversation": + // 创建新会话 - 在当前编辑器组中打开新标签页 + showICHelperPanel(context, panel.viewColumn); + break; +``` + +**加载会话历史实现**: + +```typescript +async function loadConversationHistory( + panel: vscode.WebviewPanel, + offset: number = 0, + limit: number = 10 +) { + try { + const historyManager = ChatHistoryManager.getInstance(); + const workspacePath = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath; + + if (!workspacePath) { + // 没有打开的工作区,返回空历史 + panel.webview.postMessage({ + command: "conversationHistory", + items: [], + total: 0, + hasMore: false, + }); + return; + } + + // 获取会话历史列表(支持分页) + const result = await historyManager.getConversationHistoryList( + workspacePath, + offset, + limit + ); + + // 发送会话历史到前端 + panel.webview.postMessage({ + command: "conversationHistory", + items: result.items, + total: result.total, + hasMore: result.hasMore, + }); + } catch (error) { + console.error("加载会话历史失败:", error); + // 发生错误时返回空历史 + panel.webview.postMessage({ + command: "conversationHistory", + items: [], + total: 0, + hasMore: false, + }); + } +} +``` + +--- + +## 6. 使用示例 + +### 6.1 创建新任务并保存对话 + +```typescript +const historyManager = ChatHistoryManager.getInstance(); + +// 创建新任务 +const task = await historyManager.createTask( + 'C:\\Users\\admin\\Documents\\Project', + '实现计数器功能' +); + +// 添加用户消息 +await historyManager.addUserMessage('请帮我生成一个4位计数器'); + +// 添加 AI 消息 +await historyManager.addAiMessage( + '好的,我来帮你生成一个4位计数器...', + [{ id: '1', toolName: 'generateCode', parameters: {} }] +); + +// 添加工具执行结果 +await historyManager.addToolExecutionResult( + '1', + 'generateCode', + '代码生成成功' +); + +// 记录对话元数据 +await historyManager.recordTurnMeta( + 1, + { inputTokens: 120, outputTokens: 350, totalTokens: 470 }, + 'gpt-4', + 2500 +); +``` + +### 6.2 查询会话历史 + +```typescript +const historyManager = ChatHistoryManager.getInstance(); + +// 获取第一页(前10条) +const page1 = await historyManager.getConversationHistoryList( + 'C:\\Users\\admin\\Documents\\Project', + 0, + 10 +); + +console.log('总数:', page1.total); +console.log('是否还有更多:', page1.hasMore); +console.log('会话列表:', page1.items); + +// 获取第二页(第11-20条) +const page2 = await historyManager.getConversationHistoryList( + 'C:\\Users\\admin\\Documents\\Project', + 10, + 10 +); +``` + +### 6.3 切换任务 + +```typescript +const historyManager = ChatHistoryManager.getInstance(); + +// 切换到指定任务 +const success = await historyManager.switchTask( + 'C:\\Users\\admin\\Documents\\Project', + 'task_20231226_a3f9k2' +); + +if (success) { + // 获取当前任务会话 + const session = await historyManager.getCurrentTaskSession(); + console.log('任务元数据:', session.meta); + console.log('对话历史:', session.messages); + console.log('对话元数据:', session.conversationMeta); +} +``` + +--- + +## 7. 性能优化 + +### 7.1 分页加载 + +- 前端默认每页加载 10 条记录 +- 最多显示 100 条历史记录 +- 滚动到底部时自动加载下一页 + +### 7.2 懒加载 + +- 只在打开下拉菜单时才加载会话历史 +- 避免不必要的文件读取操作 + +### 7.3 缓存机制 + +- 前端缓存已加载的会话列表 +- 避免重复请求相同数据 + +### 7.4 文件格式优化 + +- 使用 JSONL 格式存储对话元数据,支持追加写入 +- 避免频繁读写整个文件 + +--- + +## 8. 错误处理 + +### 8.1 目录不存在 + +系统会自动创建不存在的目录: + +```typescript +private async ensureTaskDir(taskDir: string): Promise { + try { + const uri = vscode.Uri.file(taskDir); + try { + await vscode.workspace.fs.stat(uri); + } catch { + // 目录不存在,创建它 + await vscode.workspace.fs.createDirectory(uri); + console.log(`创建任务目录: ${taskDir}`); + } + } catch (error) { + console.error("创建任务目录失败:", error); + throw error; + } +} +``` + +### 8.2 文件读取失败 + +读取失败时返回默认值: + +```typescript +private async loadConversation(): Promise { + try { + const uri = vscode.Uri.file(conversationPath); + const content = await vscode.workspace.fs.readFile(uri); + const data = Buffer.from(content).toString('utf-8'); + return JSON.parse(data); + } catch (error) { + // 文件不存在或读取失败,返回空数组 + return []; + } +} +``` + +### 8.3 无工作区处理 + +没有打开工作区时,自动创建默认任务: + +```typescript +private async ensureCurrentTask(): Promise { + if (!this.currentTaskId || !this.currentProjectPath) { + const workspacePath = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath; + if (workspacePath) { + await this.createTask(workspacePath, "默认任务"); + } else { + throw new Error("没有打开的工作区,无法创建任务"); + } + } +} +``` + +--- + +## 9. 未来扩展 + +### 9.1 会话切换功能 + +目前 `selectConversation` 功能暂未实现,未来可以支持: +- 点击历史会话,加载该会话的完整对话历史 +- 在新标签页中打开历史会话 +- 继续历史会话的对话 + +### 9.2 会话搜索 + +- 支持按关键词搜索会话 +- 支持按时间范围筛选 +- 支持按 Token 使用量排序 + +### 9.3 会话导出 + +- 导出为 Markdown 格式 +- 导出为 JSON 格式 +- 导出为 PDF 格式 + +### 9.4 会话统计 + +- 显示总对话轮次 +- 显示总 Token 使用量 +- 显示平均响应时间 + +### 9.5 云端同步 + +- 支持将会话数据同步到云端 +- 支持多设备访问 +- 支持团队协作 + +--- + +## 10. 总结 + +IC Coder 的会话存储系统采用文件系统存储方案,具有以下优势: + +1. **简单可靠**:无需额外的数据库依赖 +2. **易于备份**:直接复制文件即可备份 +3. **跨平台**:支持 Windows、macOS、Linux +4. **可扩展**:易于添加新的数据字段 +5. **高性能**:分页加载,避免一次性加载大量数据 + +系统已经实现了核心的会话管理功能,包括任务创建、消息保存、历史查询等,为用户提供了完整的会话历史管理体验。 diff --git a/media/ICCoder主页标志.png b/media/homepage-logo.png similarity index 100% rename from media/ICCoder主页标志.png rename to media/homepage-logo.png diff --git a/media/图案(方底).png b/media/icon.png similarity index 100% rename from media/图案(方底).png rename to media/icon.png diff --git a/media/侧边栏logo.png b/media/sidebar-icon.png similarity index 100% rename from media/侧边栏logo.png rename to media/sidebar-icon.png diff --git a/package.json b/package.json index aad18aa..003c9cf 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,13 @@ { - "name": "ic-coder-plugin", - "displayName": "IC Coder plugin", + "name": "iccoder", + "displayName": "IC Coder", "description": "Agentic Verilog Coding Platform for Real-World FPGAs", "version": "0.0.2", + "publisher": "ICCoder", "engines": { - "vscode": "^1.107.0" + "vscode": "^1.80.0" }, - "icon": "media/图案(方底).png", + "icon": "media/icon.png", "categories": [ "Other" ], @@ -18,6 +19,7 @@ "eda", "assistant" ], + "license": "SEE LICENSE IN LICENSE", "activationEvents": [ "onCommand:ic-coder.openPanel", "onView:ic-coder-sidebar", @@ -42,36 +44,6 @@ "command": "ic-coder.openVCDViewer", "title": "打开 VCD 波形查看器", "category": "IC Coder" - }, - { - "command": "ic-coder.viewHistory", - "title": "查看会话历史", - "category": "IC Coder" - }, - { - "command": "ic-coder.newSession", - "title": "新建会话", - "category": "IC Coder" - }, - { - "command": "ic-coder.exportSession", - "title": "导出当前会话", - "category": "IC Coder" - }, - { - "command": "ic-coder.deleteSession", - "title": "删除会话", - "category": "IC Coder" - }, - { - "command": "ic-coder.clearHistory", - "title": "清空会话历史", - "category": "IC Coder" - }, - { - "command": "ic-coder.searchSession", - "title": "搜索会话", - "category": "IC Coder" } ], "viewsContainers": { @@ -79,7 +51,7 @@ { "id": "ic-coder-sidebar", "title": "IC Coder", - "icon": "media/侧边栏logo.png" + "icon": "media/sidebar-icon.png" } ] }, @@ -92,6 +64,12 @@ } ] }, + "authentication": [ + { + "id": "iccoder", + "label": "IC Coder" + } + ], "configuration": { "title": "IC Coder", "properties": { @@ -128,9 +106,10 @@ "devDependencies": { "@types/mocha": "^10.0.10", "@types/node": "22.x", - "@types/vscode": "^1.107.0", + "@types/vscode": "^1.80.0", "@vscode/test-cli": "^0.0.12", "@vscode/test-electron": "^2.5.2", + "@vscode/vsce": "^3.7.1", "eslint": "^9.39.1", "ts-loader": "^9.5.4", "typescript": "^5.9.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5e33f59..456d0ca 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -40,7 +40,7 @@ importers: specifier: 22.x version: 22.19.2 '@types/vscode': - specifier: ^1.107.0 + specifier: ^1.80.0 version: 1.107.0 '@vscode/test-cli': specifier: ^0.0.12 @@ -48,6 +48,9 @@ importers: '@vscode/test-electron': specifier: ^2.5.2 version: 2.5.2 + '@vscode/vsce': + specifier: ^3.7.1 + version: 3.7.1 eslint: specifier: ^9.39.1 version: 9.39.1 @@ -69,6 +72,64 @@ importers: packages: + '@azu/format-text@1.0.2': + resolution: {integrity: sha512-Swi4N7Edy1Eqq82GxgEECXSSLyn6GOb5htRFPzBDdUkECGXtlf12ynO5oJSpWKPwCaUssOu7NfhDcCWpIC6Ywg==} + + '@azu/style-format@1.0.1': + resolution: {integrity: sha512-AHcTojlNBdD/3/KxIKlg8sxIWHfOtQszLvOpagLTO+bjC3u7SAszu1lf//u7JJC50aUSH+BVWDD/KvaA6Gfn5g==} + + '@azure/abort-controller@2.1.2': + resolution: {integrity: sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==} + engines: {node: '>=18.0.0'} + + '@azure/core-auth@1.10.1': + resolution: {integrity: sha512-ykRMW8PjVAn+RS6ww5cmK9U2CyH9p4Q88YJwvUslfuMmN98w/2rdGRLPqJYObapBCdzBVeDgYWdJnFPFb7qzpg==} + engines: {node: '>=20.0.0'} + + '@azure/core-client@1.10.1': + resolution: {integrity: sha512-Nh5PhEOeY6PrnxNPsEHRr9eimxLwgLlpmguQaHKBinFYA/RU9+kOYVOQqOrTsCL+KSxrLLl1gD8Dk5BFW/7l/w==} + engines: {node: '>=20.0.0'} + + '@azure/core-rest-pipeline@1.22.2': + resolution: {integrity: sha512-MzHym+wOi8CLUlKCQu12de0nwcq9k9Kuv43j4Wa++CsCpJwps2eeBQwD2Bu8snkxTtDKDx4GwjuR9E8yC8LNrg==} + engines: {node: '>=20.0.0'} + + '@azure/core-tracing@1.3.1': + resolution: {integrity: sha512-9MWKevR7Hz8kNzzPLfX4EAtGM2b8mr50HPDBvio96bURP/9C+HjdH3sBlLSNNrvRAr5/k/svoH457gB5IKpmwQ==} + engines: {node: '>=20.0.0'} + + '@azure/core-util@1.13.1': + resolution: {integrity: sha512-XPArKLzsvl0Hf0CaGyKHUyVgF7oDnhKoP85Xv6M4StF/1AhfORhZudHtOyf2s+FcbuQ9dPRAjB8J2KvRRMUK2A==} + engines: {node: '>=20.0.0'} + + '@azure/identity@4.13.0': + resolution: {integrity: sha512-uWC0fssc+hs1TGGVkkghiaFkkS7NkTxfnCH+Hdg+yTehTpMcehpok4PgUKKdyCH+9ldu6FhiHRv84Ntqj1vVcw==} + engines: {node: '>=20.0.0'} + + '@azure/logger@1.3.0': + resolution: {integrity: sha512-fCqPIfOcLE+CGqGPd66c8bZpwAji98tZ4JI9i/mlTNTlsIWslCfpg48s/ypyLxZTump5sypjrKn2/kY7q8oAbA==} + engines: {node: '>=20.0.0'} + + '@azure/msal-browser@4.27.0': + resolution: {integrity: sha512-bZ8Pta6YAbdd0o0PEaL1/geBsPrLEnyY/RDWqvF1PP9RUH8EMLvUMGoZFYS6jSlUan6KZ9IMTLCnwpWWpQRK/w==} + engines: {node: '>=0.8.0'} + + '@azure/msal-common@15.13.3': + resolution: {integrity: sha512-shSDU7Ioecya+Aob5xliW9IGq1Ui8y4EVSdWGyI1Gbm4Vg61WpP95LuzcY214/wEjSn6w4PZYD4/iVldErHayQ==} + engines: {node: '>=0.8.0'} + + '@azure/msal-node@3.8.4': + resolution: {integrity: sha512-lvuAwsDpPDE/jSuVQOBMpLbXuVuLsPNRwWCyK3/6bPlBk0fGWegqoZ0qjZclMWyQ2JNvIY3vHY7hoFmFmFQcOw==} + engines: {node: '>=16'} + + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + '@bcoe/v8-coverage@1.0.2': resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} @@ -146,6 +207,14 @@ packages: resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} + '@isaacs/balanced-match@4.0.1': + resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} + engines: {node: 20 || >=22} + + '@isaacs/brace-expansion@5.0.0': + resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} + engines: {node: 20 || >=22} + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -179,10 +248,86 @@ packages: '@lezer/lr@1.4.5': resolution: {integrity: sha512-/YTRKP5yPPSo1xImYQk7AZZMAgap0kegzqCSYHjAL9x1AZ0ZQW+IpcEzMKagCsbTsLnVeWkxYrCNeXG8xEPrjg==} + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} + '@secretlint/config-creator@10.2.2': + resolution: {integrity: sha512-BynOBe7Hn3LJjb3CqCHZjeNB09s/vgf0baBaHVw67w7gHF0d25c3ZsZ5+vv8TgwSchRdUCRrbbcq5i2B1fJ2QQ==} + engines: {node: '>=20.0.0'} + + '@secretlint/config-loader@10.2.2': + resolution: {integrity: sha512-ndjjQNgLg4DIcMJp4iaRD6xb9ijWQZVbd9694Ol2IszBIbGPPkwZHzJYKICbTBmh6AH/pLr0CiCaWdGJU7RbpQ==} + engines: {node: '>=20.0.0'} + + '@secretlint/core@10.2.2': + resolution: {integrity: sha512-6rdwBwLP9+TO3rRjMVW1tX+lQeo5gBbxl1I5F8nh8bgGtKwdlCMhMKsBWzWg1ostxx/tIG7OjZI0/BxsP8bUgw==} + engines: {node: '>=20.0.0'} + + '@secretlint/formatter@10.2.2': + resolution: {integrity: sha512-10f/eKV+8YdGKNQmoDUD1QnYL7TzhI2kzyx95vsJKbEa8akzLAR5ZrWIZ3LbcMmBLzxlSQMMccRmi05yDQ5YDA==} + engines: {node: '>=20.0.0'} + + '@secretlint/node@10.2.2': + resolution: {integrity: sha512-eZGJQgcg/3WRBwX1bRnss7RmHHK/YlP/l7zOQsrjexYt6l+JJa5YhUmHbuGXS94yW0++3YkEJp0kQGYhiw1DMQ==} + engines: {node: '>=20.0.0'} + + '@secretlint/profiler@10.2.2': + resolution: {integrity: sha512-qm9rWfkh/o8OvzMIfY8a5bCmgIniSpltbVlUVl983zDG1bUuQNd1/5lUEeWx5o/WJ99bXxS7yNI4/KIXfHexig==} + + '@secretlint/resolver@10.2.2': + resolution: {integrity: sha512-3md0cp12e+Ae5V+crPQYGd6aaO7ahw95s28OlULGyclyyUtf861UoRGS2prnUrKh7MZb23kdDOyGCYb9br5e4w==} + + '@secretlint/secretlint-formatter-sarif@10.2.2': + resolution: {integrity: sha512-ojiF9TGRKJJw308DnYBucHxkpNovDNu1XvPh7IfUp0A12gzTtxuWDqdpuVezL7/IP8Ua7mp5/VkDMN9OLp1doQ==} + + '@secretlint/secretlint-rule-no-dotenv@10.2.2': + resolution: {integrity: sha512-KJRbIShA9DVc5Va3yArtJ6QDzGjg3PRa1uYp9As4RsyKtKSSZjI64jVca57FZ8gbuk4em0/0Jq+uy6485wxIdg==} + engines: {node: '>=20.0.0'} + + '@secretlint/secretlint-rule-preset-recommend@10.2.2': + resolution: {integrity: sha512-K3jPqjva8bQndDKJqctnGfwuAxU2n9XNCPtbXVI5JvC7FnQiNg/yWlQPbMUlBXtBoBGFYp08A94m6fvtc9v+zA==} + engines: {node: '>=20.0.0'} + + '@secretlint/source-creator@10.2.2': + resolution: {integrity: sha512-h6I87xJfwfUTgQ7irWq7UTdq/Bm1RuQ/fYhA3dtTIAop5BwSFmZyrchph4WcoEvbN460BWKmk4RYSvPElIIvxw==} + engines: {node: '>=20.0.0'} + + '@secretlint/types@10.2.2': + resolution: {integrity: sha512-Nqc90v4lWCXyakD6xNyNACBJNJ0tNCwj2WNk/7ivyacYHxiITVgmLUFXTBOeCdy79iz6HtN9Y31uw/jbLrdOAg==} + engines: {node: '>=20.0.0'} + + '@sindresorhus/merge-streams@2.3.0': + resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} + engines: {node: '>=18'} + + '@textlint/ast-node-types@15.5.0': + resolution: {integrity: sha512-K0LEuuTo4rza8yDrlYkRdXLao8Iz/QBMsQdIxRrOOrLYb4HAtZaypZ78c+J6rDA1UlGxadZVLmkkiv4KV5fMKQ==} + + '@textlint/linter-formatter@15.5.0': + resolution: {integrity: sha512-DPTm2+VXKID41qKQWagg/4JynM6hEEpvbq0PlGsEoC4Xm7IqXIxFym3mSf5+ued0cuiIV1hR9kgXjqGdP035tw==} + + '@textlint/module-interop@15.5.0': + resolution: {integrity: sha512-rqfouEhBEgZlR9umswWXXRBcmmSM28Trpr9b0duzgehKYVc7wSQCuQMagr6YBJa2NRMfRNinupusbJXMg0ij2A==} + + '@textlint/resolver@15.5.0': + resolution: {integrity: sha512-kK5nFbg5N3kVoZExQI/dnYjCInmTltvXDnuCRrBxHI01i6kO/o8R7Lc2aFkAZ6/NUZuRPalkyDdwZJke4/R2wg==} + + '@textlint/types@15.5.0': + resolution: {integrity: sha512-EjAPbuA+3NyQ9WyFP7iUlddi35F3mGrf4tb4cZM0nWywbtEJ3+XAYqL+5RsF0qFeSguxGir09NdZOWrG9wVOUQ==} + '@types/debug@4.1.5': resolution: {integrity: sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==} @@ -207,6 +352,12 @@ packages: '@types/node@22.19.2': resolution: {integrity: sha512-LPM2G3Syo1GLzXLGJAKdqoU35XvrWzGJ21/7sgZTUpbkBaOasTj8tjwn6w+hCkqaa1TfJ/w67rJSwYItlJ2mYw==} + '@types/normalize-package-data@2.4.4': + resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + + '@types/sarif@2.1.7': + resolution: {integrity: sha512-kRz0VEkJqWLf1LLVN4pT1cg1Z9wAuvI6L97V3m2f5B76Tg8d413ddvLBPTEHAZJlnn4XSvu0FkZtViCQGVyrXQ==} + '@types/vscode@1.107.0': resolution: {integrity: sha512-XS8YE1jlyTIowP64+HoN30OlC1H9xqSlq1eoLZUgFEC8oUTO6euYZxti1xRiLSfZocs4qytTzR6xCBYtioQTCg==} @@ -269,6 +420,10 @@ packages: resolution: {integrity: sha512-LlKaciDe3GmZFphXIc79THF/YYBugZ7FS1pO581E/edlVVNbZKDy93evqmrfQ9/Y4uN0vVhX4iuchq26mK/iiA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typespec/ts-http-runtime@0.3.2': + resolution: {integrity: sha512-IlqQ/Gv22xUC1r/WQm4StLkYQmaaTsXAhUVsNE0+xiyf0yRFiH5++q78U3bw6bLKDCTmh0uqKB9eG9+Bt75Dkg==} + engines: {node: '>=20.0.0'} + '@vscode/test-cli@0.0.12': resolution: {integrity: sha512-iYN0fDg29+a2Xelle/Y56Xvv7Nc8Thzq4VwpzAF/SIE6918rDicqfsQxV6w1ttr2+SOm+10laGuY9FG2ptEKsQ==} engines: {node: '>=18'} @@ -278,6 +433,59 @@ packages: resolution: {integrity: sha512-8ukpxv4wYe0iWMRQU18jhzJOHkeGKbnw7xWRX3Zw1WJA4cEKbHcmmLPdPrPtL6rhDcrlCZN+xKRpv09n4gRHYg==} engines: {node: '>=16'} + '@vscode/vsce-sign-alpine-arm64@2.0.6': + resolution: {integrity: sha512-wKkJBsvKF+f0GfsUuGT0tSW0kZL87QggEiqNqK6/8hvqsXvpx8OsTEc3mnE1kejkh5r+qUyQ7PtF8jZYN0mo8Q==} + cpu: [arm64] + os: [alpine] + + '@vscode/vsce-sign-alpine-x64@2.0.6': + resolution: {integrity: sha512-YoAGlmdK39vKi9jA18i4ufBbd95OqGJxRvF3n6ZbCyziwy3O+JgOpIUPxv5tjeO6gQfx29qBivQ8ZZTUF2Ba0w==} + cpu: [x64] + os: [alpine] + + '@vscode/vsce-sign-darwin-arm64@2.0.6': + resolution: {integrity: sha512-5HMHaJRIQuozm/XQIiJiA0W9uhdblwwl2ZNDSSAeXGO9YhB9MH5C4KIHOmvyjUnKy4UCuiP43VKpIxW1VWP4tQ==} + cpu: [arm64] + os: [darwin] + + '@vscode/vsce-sign-darwin-x64@2.0.6': + resolution: {integrity: sha512-25GsUbTAiNfHSuRItoQafXOIpxlYj+IXb4/qarrXu7kmbH94jlm5sdWSCKrrREs8+GsXF1b+l3OB7VJy5jsykw==} + cpu: [x64] + os: [darwin] + + '@vscode/vsce-sign-linux-arm64@2.0.6': + resolution: {integrity: sha512-cfb1qK7lygtMa4NUl2582nP7aliLYuDEVpAbXJMkDq1qE+olIw/es+C8j1LJwvcRq1I2yWGtSn3EkDp9Dq5FdA==} + cpu: [arm64] + os: [linux] + + '@vscode/vsce-sign-linux-arm@2.0.6': + resolution: {integrity: sha512-UndEc2Xlq4HsuMPnwu7420uqceXjs4yb5W8E2/UkaHBB9OWCwMd3/bRe/1eLe3D8kPpxzcaeTyXiK3RdzS/1CA==} + cpu: [arm] + os: [linux] + + '@vscode/vsce-sign-linux-x64@2.0.6': + resolution: {integrity: sha512-/olerl1A4sOqdP+hjvJ1sbQjKN07Y3DVnxO4gnbn/ahtQvFrdhUi0G1VsZXDNjfqmXw57DmPi5ASnj/8PGZhAA==} + cpu: [x64] + os: [linux] + + '@vscode/vsce-sign-win32-arm64@2.0.6': + resolution: {integrity: sha512-ivM/MiGIY0PJNZBoGtlRBM/xDpwbdlCWomUWuLmIxbi1Cxe/1nooYrEQoaHD8ojVRgzdQEUzMsRbyF5cJJgYOg==} + cpu: [arm64] + os: [win32] + + '@vscode/vsce-sign-win32-x64@2.0.6': + resolution: {integrity: sha512-mgth9Kvze+u8CruYMmhHw6Zgy3GRX2S+Ed5oSokDEK5vPEwGGKnmuXua9tmFhomeAnhgJnL4DCna3TiNuGrBTQ==} + cpu: [x64] + os: [win32] + + '@vscode/vsce-sign@2.0.9': + resolution: {integrity: sha512-8IvaRvtFyzUnGGl3f5+1Cnor3LqaUWvhaUjAYO8Y39OUYlOf3cRd+dowuQYLpZcP3uwSG+mURwjEBOSq4SOJ0g==} + + '@vscode/vsce@3.7.1': + resolution: {integrity: sha512-OTm2XdMt2YkpSn2Nx7z2EJtSuhRHsTPYsSK59hr3v8jRArK+2UEoju4Jumn1CmpgoBLGI6ReHLJ/czYltNUW3g==} + engines: {node: '>= 20'} + hasBin: true + '@wavedrom/doppler@1.14.0': resolution: {integrity: sha512-LYzI70g30txDVHQcMvvJ1pnazdhWIOB6lnZUoya11+54lVgYdHn/lZJW8td7u0phHDwr7+WzV1Eqo/9Y2EHX9Q==} @@ -396,6 +604,10 @@ packages: ajv@8.17.1: resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + ansi-escapes@7.2.0: + resolution: {integrity: sha512-g6LhBsl+GBPRWGWsBtutpzBYuIIdBkLEvad5C/va/74Db018+5TZiyA26cZJAr3Rft5lprVqOIPxf5Vid6tqAw==} + engines: {node: '>=18'} + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -419,9 +631,22 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + astral-regex@2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + azure-devops-node-api@12.5.0: + resolution: {integrity: sha512-R5eFskGvOm3U/GzeAuxRkUsAl0hrAwGgWn6zAd2KrZmrEhWZVqLew4OOupbQlXUuojUzpGtq62SmdhJ06N88og==} + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + baseline-browser-mapping@2.9.6: resolution: {integrity: sha512-v9BVVpOTLB59C9E7aSnmIF8h7qRsFpx+A2nugVMTszEOMcfjlZMsXRm4LF23I3Z9AJxc8ANpIvzbzONoX9VJlg==} hasBin: true @@ -433,9 +658,22 @@ packages: binary-search@1.3.6: resolution: {integrity: sha512-nbE1WxOTTrUWIfsfZ4aHGYu5DOuNkbxGokjV6Z2kxfJK3uaAb8zNK1muzOeipoLHZjInT4Br88BHpzevc681xA==} + binaryextensions@6.11.0: + resolution: {integrity: sha512-sXnYK/Ij80TO3lcqZVV2YgfKN5QjUWIRk/XSm2J/4bd/lPko3lvk0O4ZppH6m+6hB2/GTu+ptNwVFe1xh+QLQw==} + engines: {node: '>=4'} + bindings@1.5.0: resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + boundary@2.0.0: + resolution: {integrity: sha512-rJKn5ooC9u8q13IMCrW0RSp31pxBCHE3y9V/tp3TdWSLf8Em3p6Di4NBpfzbJge9YjjFEsD0RtFEjtvHL5VyEA==} + brace-expansion@1.1.12: resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} @@ -454,9 +692,22 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + buffer-crc32@0.2.13: + resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + + buffer-equal-constant-time@1.0.1: + resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} + c8@10.1.3: resolution: {integrity: sha512-LvcyrOAaOnrrlMpW22n690PUvxiq4Uf9WMhQwNJ9vgagkL/ph1+D4uvjvDA5XCbykrc0sx+ay6pVi9YZ1GnhyA==} engines: {node: '>=18'} @@ -467,6 +718,14 @@ packages: monocart-coverage-reports: optional: true + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -486,6 +745,13 @@ packages: resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + cheerio-select@2.1.0: + resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} + + cheerio@1.1.2: + resolution: {integrity: sha512-IkxPpb5rS/d1IiLbHMgfPuS0FgiWTtFIm/Nj+2woXDLTZ7fOT2eqzgYbdMlLweqlHbsZjxEChoVK+7iph7jyQg==} + engines: {node: '>=20.18.1'} + chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} @@ -494,6 +760,9 @@ packages: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} + chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + chrome-trace-event@1.0.4: resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} engines: {node: '>=6.0'} @@ -514,6 +783,10 @@ packages: resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} engines: {node: '>=6'} + cockatiel@3.2.1: + resolution: {integrity: sha512-gfrHV6ZPkquExvMh9IOkKsBzNDk6sDuZ6DdBGUBkvFnTCqCxzpuq48RySgP0AnaqQkw2zynOFj9yly6T1Q2G5Q==} + engines: {node: '>=16'} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -524,6 +797,10 @@ packages: colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + commander@12.1.0: resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} engines: {node: '>=18'} @@ -544,6 +821,13 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + css-select@5.2.2: + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} + + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + engines: {node: '>= 6'} + debug@3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} peerDependencies: @@ -565,20 +849,72 @@ packages: resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} engines: {node: '>=10'} + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + default-browser-id@5.0.1: + resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} + engines: {node: '>=18'} + + default-browser@5.4.0: + resolution: {integrity: sha512-XDuvSq38Hr1MdN47EDvYtx3U0MTqpCEn+F6ft8z2vYDzMrvQhVp0ui9oQdqW3MvK3vqUETglt1tVGgjLuJ5izg==} + engines: {node: '>=18'} + + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + diff@7.0.0: resolution: {integrity: sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==} engines: {node: '>=0.3.1'} + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + dot-prop@6.0.1: resolution: {integrity: sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==} engines: {node: '>=10'} + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + ecdsa-sig-formatter@1.0.11: + resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + + editions@6.22.0: + resolution: {integrity: sha512-UgGlf8IW75je7HZjNDpJdCv4cGJWIi6yumFdZ0R7A8/CIhQiWUjyGLCxdHpd8bmyD1gnkfUNK0oeOXqUS2cpfQ==} + engines: {ecmascript: '>= es5', node: '>=4'} + electron-to-chromium@1.5.267: resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==} @@ -591,18 +927,52 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + encoding-sniffer@0.2.1: + resolution: {integrity: sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==} + + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + enhanced-resolve@5.18.3: resolution: {integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==} engines: {node: '>=10.13.0'} + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + envinfo@7.21.0: resolution: {integrity: sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==} engines: {node: '>=4'} hasBin: true + environment@1.1.0: + resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} + engines: {node: '>=18'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + es-module-lexer@1.7.0: resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -669,9 +1039,17 @@ packages: resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} engines: {node: '>=18.0.0'} + expand-template@2.0.3: + resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} + engines: {node: '>=6'} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} @@ -685,6 +1063,12 @@ packages: resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} engines: {node: '>= 4.9.1'} + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + + fd-slicer@1.1.0: + resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} @@ -728,6 +1112,17 @@ packages: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} + engines: {node: '>= 6'} + + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + + fs-extra@11.3.3: + resolution: {integrity: sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==} + engines: {node: '>=14.14'} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -744,6 +1139,17 @@ packages: resolution: {integrity: sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==} engines: {node: '>=18'} + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + github-from-package@0.0.0: + resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -759,10 +1165,23 @@ packages: resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} hasBin: true + glob@11.1.0: + resolution: {integrity: sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==} + engines: {node: 20 || >=22} + hasBin: true + globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} + globby@14.1.0: + resolution: {integrity: sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==} + engines: {node: '>=18'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -770,6 +1189,14 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} @@ -778,9 +1205,20 @@ packages: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true + hosted-git-info@4.1.0: + resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} + engines: {node: '>=10'} + + hosted-git-info@7.0.2: + resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} + engines: {node: ^16.14.0 || >=18.0.0} + html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + htmlparser2@10.0.0: + resolution: {integrity: sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==} + http-proxy-agent@7.0.2: resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} engines: {node: '>= 14'} @@ -789,10 +1227,17 @@ packages: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + iconv-lite@0.7.1: resolution: {integrity: sha512-2Tth85cXwGFHfvRgZWszZSvdo+0Xsqmw8k8ZwxScfcBneNUraK+dxRxRm24nszx80Y0TVio8kKLt5sLE7ZCLlw==} engines: {node: '>=0.10.0'} + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} @@ -817,9 +1262,16 @@ packages: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} + index-to-position@1.2.0: + resolution: {integrity: sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==} + engines: {node: '>=18'} + inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + interpret@3.1.1: resolution: {integrity: sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==} engines: {node: '>=10.13.0'} @@ -832,6 +1284,11 @@ packages: resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} engines: {node: '>= 0.4'} + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -844,6 +1301,11 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + is-interactive@2.0.0: resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} engines: {node: '>=12'} @@ -880,6 +1342,10 @@ packages: resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} engines: {node: '>=18'} + is-wsl@3.1.0: + resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} + engines: {node: '>=16'} + isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} @@ -902,13 +1368,24 @@ packages: resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} engines: {node: '>=8'} + istextorbinary@9.5.0: + resolution: {integrity: sha512-5mbUj3SiZXCuRf9fT3ibzbSSEWiy63gFfksmGfdOzujPjW3k+z8WvIBxcJHBoQNlaZaiyB25deviif2+osLmLw==} + engines: {node: '>=4'} + jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + jackspeak@4.1.1: + resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==} + engines: {node: 20 || >=22} + jest-worker@27.5.1: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + js-yaml@4.1.1: resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true @@ -928,9 +1405,33 @@ packages: json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonc-parser@3.3.1: + resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + + jsonfile@6.2.0: + resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} + + jsonwebtoken@9.0.3: + resolution: {integrity: sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==} + engines: {node: '>=12', npm: '>=6'} + jszip@3.10.1: resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} + jwa@2.0.1: + resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==} + + jws@4.0.1: + resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==} + + keytar@7.9.0: + resolution: {integrity: sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==} + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -938,6 +1439,10 @@ packages: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} + leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -945,6 +1450,9 @@ packages: lie@3.3.0: resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} + linkify-it@5.0.0: + resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} + llparse-builder@1.5.2: resolution: {integrity: sha512-i862UNC3YUEdlfK/NUCJxlKjtWjgAI9AJXDRgjcfRHfwFt4Sf8eFPTRsc91/2R9MBZ0kyFdfhi8SVhMsZf1gNQ==} @@ -970,9 +1478,36 @@ packages: resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} deprecated: This package is deprecated. Use the optional chaining (?.) operator instead. + lodash.includes@4.3.0: + resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} + + lodash.isboolean@3.0.3: + resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} + + lodash.isinteger@4.0.4: + resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} + + lodash.isnumber@3.0.3: + resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} + + lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + + lodash.isstring@4.0.1: + resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} + lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + lodash.once@4.1.1: + resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} + + lodash.truncate@4.4.2: + resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + log-symbols@4.1.0: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} @@ -984,13 +1519,36 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + lru-cache@11.2.4: + resolution: {integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==} + engines: {node: 20 || >=22} + + lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + make-dir@4.0.0: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} + markdown-it@14.1.0: + resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} + hasBin: true + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mdurl@2.0.0: + resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} @@ -1003,10 +1561,23 @@ packages: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + mimic-function@5.0.1: resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} engines: {node: '>=18'} + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + + minimatch@10.1.1: + resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} + engines: {node: 20 || >=22} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -1014,10 +1585,16 @@ packages: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + minipass@7.1.2: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} + mkdirp-classic@0.5.3: + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + mocha@11.7.5: resolution: {integrity: sha512-mTT6RgopEYABzXWFx+GcJ+ZQ32kp4fMf0xvpZIIfSq9Z8lC/++MtcCnQ9t5FP2veYEP95FIYSvW+U9fV4xrlig==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1026,19 +1603,50 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + mute-stream@0.0.8: + resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} + + napi-build-utils@2.0.0: + resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} + natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + node-abi@3.85.0: + resolution: {integrity: sha512-zsFhmbkAzwhTft6nd3VxcG0cvJsT70rL+BIGHWVq5fi6MwGrHwzqKaxXE+Hl2GmnGItnDKPPkO5/LQqjVkIdFg==} + engines: {node: '>=10'} + + node-addon-api@4.3.0: + resolution: {integrity: sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==} + node-releases@2.0.27: resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + node-sarif-builder@3.3.1: + resolution: {integrity: sha512-8z5dAbhpxmk/WRQHXlv4V0h+9Y4Ugk+w08lyhV/7E/CQX9yDdBc3025/EG+RSMJU2aPFh/IQ7XDV7Ti5TLt/TA==} + engines: {node: '>=20'} + + normalize-package-data@6.0.2: + resolution: {integrity: sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==} + engines: {node: ^16.14.0 || >=18.0.0} + normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + onetime@7.0.0: resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} engines: {node: '>=18'} @@ -1046,6 +1654,10 @@ packages: onml@2.1.0: resolution: {integrity: sha512-fvaSZRzprpwLFge/mcwE0CItfniNisVNamDdMK1FQUjh4ArQZ8ZWSkDaJbZc3XaANKZHq0xIa8NJpZ2HSe3oXA==} + open@10.2.0: + resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==} + engines: {node: '>=18'} + optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -1070,6 +1682,10 @@ packages: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} + p-map@7.0.4: + resolution: {integrity: sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==} + engines: {node: '>=18'} + p-try@2.2.0: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} @@ -1084,6 +1700,22 @@ packages: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} + parse-json@8.3.0: + resolution: {integrity: sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==} + engines: {node: '>=18'} + + parse-semver@1.1.1: + resolution: {integrity: sha512-Eg1OuNntBMH0ojvEKSrvDSnwLmvVuUOSdylH/pSCPNMIspLlweJyIWXCE+k/5hm3cj/EBUYwmWkjhBALNP4LXQ==} + + parse5-htmlparser2-tree-adapter@7.1.0: + resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==} + + parse5-parser-stream@7.1.2: + resolution: {integrity: sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==} + + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -1099,6 +1731,17 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} + path-scurry@2.0.1: + resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==} + engines: {node: 20 || >=22} + + path-type@6.0.0: + resolution: {integrity: sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==} + engines: {node: '>=18'} + + pend@1.2.0: + resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -1114,6 +1757,18 @@ packages: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} + pluralize@2.0.0: + resolution: {integrity: sha512-TqNZzQCD4S42De9IfnnBvILN7HAW7riLqsCyp8lgjXeysyPlX5HhqKAcJHHHb9XskE4/a+7VGC9zzx8Ls0jOAw==} + + pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + + prebuild-install@7.1.3: + resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} + engines: {node: '>=10'} + hasBin: true + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -1121,16 +1776,49 @@ packages: process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + pump@3.0.3: + resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} + + punycode.js@2.3.1: + resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} + engines: {node: '>=6'} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + qs@6.14.0: + resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} + engines: {node: '>=0.6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + rc-config-loader@4.1.3: + resolution: {integrity: sha512-kD7FqML7l800i6pS6pvLyIE2ncbk9Du8Q0gp/4hMPhJU6ZxApkoLcGD8ZeqgiAlfwZ6BlETq6qqe+12DUL207w==} + + rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + + read-pkg@9.0.1: + resolution: {integrity: sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==} + engines: {node: '>=18'} + + read@1.0.7: + resolution: {integrity: sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==} + engines: {node: '>=0.8'} + readable-stream@2.3.8: resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} @@ -1172,6 +1860,17 @@ packages: resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} engines: {node: '>=18'} + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + run-applescript@7.1.0: + resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==} + engines: {node: '>=18'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} @@ -1188,6 +1887,15 @@ packages: resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==} engines: {node: '>= 10.13.0'} + secretlint@10.2.2: + resolution: {integrity: sha512-xVpkeHV/aoWe4vP4TansF622nBEImzCY73y/0042DuJ29iKIaqgoJ8fGxre3rVSHHbxar4FdJobmTnLp9AU0eg==} + engines: {node: '>=20.0.0'} + hasBin: true + + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + semver@7.7.3: resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} engines: {node: '>=10'} @@ -1211,10 +1919,40 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + signal-exit@4.1.0: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + simple-concat@1.0.1: + resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + + simple-get@4.0.1: + resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + + slash@5.1.0: + resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} + engines: {node: '>=14.16'} + + slice-ansi@4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} @@ -1226,6 +1964,18 @@ packages: resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} engines: {node: '>= 12'} + spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + + spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + + spdx-license-ids@3.0.22: + resolution: {integrity: sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==} + stdin-discarder@0.2.2: resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} engines: {node: '>=18'} @@ -1253,10 +2003,17 @@ packages: resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} engines: {node: '>=12'} + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + structured-source@4.0.0: + resolution: {integrity: sha512-qGzRFNJDjFieQkl/sVOI2dUjHKRyL9dAJi2gCPGJLbJHBIkyOHxjuocpIEfbLioX+qSJpvbYdT49/YCdMznKxA==} + style-mod@4.1.3: resolution: {integrity: sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==} @@ -1272,14 +2029,33 @@ packages: resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} engines: {node: '>=10'} + supports-hyperlinks@3.2.0: + resolution: {integrity: sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==} + engines: {node: '>=14.18'} + supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + table@6.9.0: + resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==} + engines: {node: '>=10.0.0'} + tapable@2.3.0: resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} engines: {node: '>=6'} + tar-fs@2.1.4: + resolution: {integrity: sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==} + + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + + terminal-link@4.0.0: + resolution: {integrity: sha512-lk+vH+MccxNqgVqSnkMVKx4VLJfnLjDBGzH16JVZjKE2DoxP57s6/vt6JmXV5I3jBcfGrxNrYtC+mPtU7WJztA==} + engines: {node: '>=18'} + terser-webpack-plugin@5.3.15: resolution: {integrity: sha512-PGkOdpRFK+rb1TzVz+msVhw4YMRT9txLF4kRqvJhGhCM324xuR3REBSHALN+l+sAhKUmz0aotnjp5D+P83mLhQ==} engines: {node: '>= 10.13.0'} @@ -1305,10 +2081,21 @@ packages: resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} engines: {node: '>=18'} + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + textextensions@6.11.0: + resolution: {integrity: sha512-tXJwSr9355kFJI3lbCkPpUH5cP8/M0GGy2xLO34aZCjMXBaK3SoPnZwr/oWmo1FdCnELcs4npdCIOFtq9W3ruQ==} + engines: {node: '>=4'} + tinyglobby@0.2.15: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} + tmp@0.2.5: + resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} + engines: {node: '>=14.14'} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -1326,10 +2113,27 @@ packages: typescript: '*' webpack: ^5.0.0 + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + + tunnel@0.0.6: + resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==} + engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} + + typed-rest-client@1.8.11: + resolution: {integrity: sha512-5UvfMpd1oelmUPRbbaVnq+rHP7ng2cE4qoQkQeAqxRL6PklkxsM0g32/HL0yfvruK6ojQ5x8EE+HF4YV6DtuCA==} + typescript-eslint@8.49.0: resolution: {integrity: sha512-zRSVH1WXD0uXczCXw+nsdjGPUdx4dfrs5VQoHnUWmv1U3oNlAKv4FUNdLDhVUg+gYn+a5hUESqch//Rv5wVhrg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1342,9 +2146,31 @@ packages: engines: {node: '>=14.17'} hasBin: true + uc.micro@2.1.0: + resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + + underscore@1.13.7: + resolution: {integrity: sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==} + undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + undici@7.16.0: + resolution: {integrity: sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g==} + engines: {node: '>=20.18.1'} + + unicorn-magic@0.1.0: + resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} + engines: {node: '>=18'} + + unicorn-magic@0.3.0: + resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} + engines: {node: '>=18'} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + update-browserslist-db@1.2.2: resolution: {integrity: sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==} hasBin: true @@ -1354,19 +2180,33 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + url-join@4.0.1: + resolution: {integrity: sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==} + util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + v8-to-istanbul@9.3.0: resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} engines: {node: '>=10.12.0'} + validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + vcd-stream@1.5.0: resolution: {integrity: sha512-w7IR4CuUv1KbpDjMu6YW6yRufK5qMTGAbc7ATbjfComVEq4lwSu+nJsFH2lGAsa9g+c3zzYoSDfazuy629eFnA==} vcdrom@1.6.0: resolution: {integrity: sha512-xvhbBOHrJb2zDhHTrdFjpOb2PWgcqqHh80YaRoVFFzYVtjrSGmj0mVsqxS5Tm1Gd9hoomdarQCaYJ+nMGWAM2A==} + version-range@4.15.0: + resolution: {integrity: sha512-Ck0EJbAGxHwprkzFO966t4/5QkRuzh+/I1RxhLgUKKwEn+Cd8NwM60mE3AqBZg5gYODoXW0EFsQvbZjRlvdqbg==} + engines: {node: '>=4'} + w3c-keyname@2.2.8: resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} @@ -1410,6 +2250,14 @@ packages: webpack-cli: optional: true + whatwg-encoding@3.1.1: + resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} + engines: {node: '>=18'} + + whatwg-mimetype@4.0.0: + resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} + engines: {node: '>=18'} + which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -1433,10 +2281,28 @@ packages: resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} engines: {node: '>=12'} + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + wsl-utils@0.1.0: + resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==} + engines: {node: '>=18'} + + xml2js@0.5.0: + resolution: {integrity: sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==} + engines: {node: '>=4.0.0'} + + xmlbuilder@11.0.1: + resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} + engines: {node: '>=4.0'} + y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} @@ -1449,12 +2315,115 @@ packages: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} + yauzl@2.10.0: + resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} + + yazl@2.5.1: + resolution: {integrity: sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==} + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} snapshots: + '@azu/format-text@1.0.2': {} + + '@azu/style-format@1.0.1': + dependencies: + '@azu/format-text': 1.0.2 + + '@azure/abort-controller@2.1.2': + dependencies: + tslib: 2.8.1 + + '@azure/core-auth@1.10.1': + dependencies: + '@azure/abort-controller': 2.1.2 + '@azure/core-util': 1.13.1 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@azure/core-client@1.10.1': + dependencies: + '@azure/abort-controller': 2.1.2 + '@azure/core-auth': 1.10.1 + '@azure/core-rest-pipeline': 1.22.2 + '@azure/core-tracing': 1.3.1 + '@azure/core-util': 1.13.1 + '@azure/logger': 1.3.0 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@azure/core-rest-pipeline@1.22.2': + dependencies: + '@azure/abort-controller': 2.1.2 + '@azure/core-auth': 1.10.1 + '@azure/core-tracing': 1.3.1 + '@azure/core-util': 1.13.1 + '@azure/logger': 1.3.0 + '@typespec/ts-http-runtime': 0.3.2 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@azure/core-tracing@1.3.1': + dependencies: + tslib: 2.8.1 + + '@azure/core-util@1.13.1': + dependencies: + '@azure/abort-controller': 2.1.2 + '@typespec/ts-http-runtime': 0.3.2 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@azure/identity@4.13.0': + dependencies: + '@azure/abort-controller': 2.1.2 + '@azure/core-auth': 1.10.1 + '@azure/core-client': 1.10.1 + '@azure/core-rest-pipeline': 1.22.2 + '@azure/core-tracing': 1.3.1 + '@azure/core-util': 1.13.1 + '@azure/logger': 1.3.0 + '@azure/msal-browser': 4.27.0 + '@azure/msal-node': 3.8.4 + open: 10.2.0 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@azure/logger@1.3.0': + dependencies: + '@typespec/ts-http-runtime': 0.3.2 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@azure/msal-browser@4.27.0': + dependencies: + '@azure/msal-common': 15.13.3 + + '@azure/msal-common@15.13.3': {} + + '@azure/msal-node@3.8.4': + dependencies: + '@azure/msal-common': 15.13.3 + jsonwebtoken: 9.0.3 + uuid: 8.3.2 + + '@babel/code-frame@7.27.1': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/helper-validator-identifier@7.28.5': {} + '@bcoe/v8-coverage@1.0.2': {} '@codemirror/autocomplete@6.18.6': @@ -1547,6 +2516,12 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} + '@isaacs/balanced-match@4.0.1': {} + + '@isaacs/brace-expansion@5.0.0': + dependencies: + '@isaacs/balanced-match': 4.0.1 + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -1587,9 +2562,126 @@ snapshots: dependencies: '@lezer/common': 1.4.0 + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + '@pkgjs/parseargs@0.11.0': optional: true + '@secretlint/config-creator@10.2.2': + dependencies: + '@secretlint/types': 10.2.2 + + '@secretlint/config-loader@10.2.2': + dependencies: + '@secretlint/profiler': 10.2.2 + '@secretlint/resolver': 10.2.2 + '@secretlint/types': 10.2.2 + ajv: 8.17.1 + debug: 4.4.3(supports-color@8.1.1) + rc-config-loader: 4.1.3 + transitivePeerDependencies: + - supports-color + + '@secretlint/core@10.2.2': + dependencies: + '@secretlint/profiler': 10.2.2 + '@secretlint/types': 10.2.2 + debug: 4.4.3(supports-color@8.1.1) + structured-source: 4.0.0 + transitivePeerDependencies: + - supports-color + + '@secretlint/formatter@10.2.2': + dependencies: + '@secretlint/resolver': 10.2.2 + '@secretlint/types': 10.2.2 + '@textlint/linter-formatter': 15.5.0 + '@textlint/module-interop': 15.5.0 + '@textlint/types': 15.5.0 + chalk: 5.6.2 + debug: 4.4.3(supports-color@8.1.1) + pluralize: 8.0.0 + strip-ansi: 7.1.2 + table: 6.9.0 + terminal-link: 4.0.0 + transitivePeerDependencies: + - supports-color + + '@secretlint/node@10.2.2': + dependencies: + '@secretlint/config-loader': 10.2.2 + '@secretlint/core': 10.2.2 + '@secretlint/formatter': 10.2.2 + '@secretlint/profiler': 10.2.2 + '@secretlint/source-creator': 10.2.2 + '@secretlint/types': 10.2.2 + debug: 4.4.3(supports-color@8.1.1) + p-map: 7.0.4 + transitivePeerDependencies: + - supports-color + + '@secretlint/profiler@10.2.2': {} + + '@secretlint/resolver@10.2.2': {} + + '@secretlint/secretlint-formatter-sarif@10.2.2': + dependencies: + node-sarif-builder: 3.3.1 + + '@secretlint/secretlint-rule-no-dotenv@10.2.2': + dependencies: + '@secretlint/types': 10.2.2 + + '@secretlint/secretlint-rule-preset-recommend@10.2.2': {} + + '@secretlint/source-creator@10.2.2': + dependencies: + '@secretlint/types': 10.2.2 + istextorbinary: 9.5.0 + + '@secretlint/types@10.2.2': {} + + '@sindresorhus/merge-streams@2.3.0': {} + + '@textlint/ast-node-types@15.5.0': {} + + '@textlint/linter-formatter@15.5.0': + dependencies: + '@azu/format-text': 1.0.2 + '@azu/style-format': 1.0.1 + '@textlint/module-interop': 15.5.0 + '@textlint/resolver': 15.5.0 + '@textlint/types': 15.5.0 + chalk: 4.1.2 + debug: 4.4.3(supports-color@8.1.1) + js-yaml: 4.1.1 + lodash: 4.17.21 + pluralize: 2.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + table: 6.9.0 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + + '@textlint/module-interop@15.5.0': {} + + '@textlint/resolver@15.5.0': {} + + '@textlint/types@15.5.0': + dependencies: + '@textlint/ast-node-types': 15.5.0 + '@types/debug@4.1.5': {} '@types/eslint-scope@3.7.7': @@ -1614,6 +2706,10 @@ snapshots: dependencies: undici-types: 6.21.0 + '@types/normalize-package-data@2.4.4': {} + + '@types/sarif@2.1.7': {} + '@types/vscode@1.107.0': {} '@typescript-eslint/eslint-plugin@8.49.0(@typescript-eslint/parser@8.49.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3)': @@ -1707,6 +2803,14 @@ snapshots: '@typescript-eslint/types': 8.49.0 eslint-visitor-keys: 4.2.1 + '@typespec/ts-http-runtime@0.3.2': + dependencies: + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + '@vscode/test-cli@0.0.12': dependencies: '@types/mocha': 10.0.10 @@ -1731,6 +2835,81 @@ snapshots: transitivePeerDependencies: - supports-color + '@vscode/vsce-sign-alpine-arm64@2.0.6': + optional: true + + '@vscode/vsce-sign-alpine-x64@2.0.6': + optional: true + + '@vscode/vsce-sign-darwin-arm64@2.0.6': + optional: true + + '@vscode/vsce-sign-darwin-x64@2.0.6': + optional: true + + '@vscode/vsce-sign-linux-arm64@2.0.6': + optional: true + + '@vscode/vsce-sign-linux-arm@2.0.6': + optional: true + + '@vscode/vsce-sign-linux-x64@2.0.6': + optional: true + + '@vscode/vsce-sign-win32-arm64@2.0.6': + optional: true + + '@vscode/vsce-sign-win32-x64@2.0.6': + optional: true + + '@vscode/vsce-sign@2.0.9': + optionalDependencies: + '@vscode/vsce-sign-alpine-arm64': 2.0.6 + '@vscode/vsce-sign-alpine-x64': 2.0.6 + '@vscode/vsce-sign-darwin-arm64': 2.0.6 + '@vscode/vsce-sign-darwin-x64': 2.0.6 + '@vscode/vsce-sign-linux-arm': 2.0.6 + '@vscode/vsce-sign-linux-arm64': 2.0.6 + '@vscode/vsce-sign-linux-x64': 2.0.6 + '@vscode/vsce-sign-win32-arm64': 2.0.6 + '@vscode/vsce-sign-win32-x64': 2.0.6 + + '@vscode/vsce@3.7.1': + dependencies: + '@azure/identity': 4.13.0 + '@secretlint/node': 10.2.2 + '@secretlint/secretlint-formatter-sarif': 10.2.2 + '@secretlint/secretlint-rule-no-dotenv': 10.2.2 + '@secretlint/secretlint-rule-preset-recommend': 10.2.2 + '@vscode/vsce-sign': 2.0.9 + azure-devops-node-api: 12.5.0 + chalk: 4.1.2 + cheerio: 1.1.2 + cockatiel: 3.2.1 + commander: 12.1.0 + form-data: 4.0.5 + glob: 11.1.0 + hosted-git-info: 4.1.0 + jsonc-parser: 3.3.1 + leven: 3.1.0 + markdown-it: 14.1.0 + mime: 1.6.0 + minimatch: 3.1.2 + parse-semver: 1.1.1 + read: 1.0.7 + secretlint: 10.2.2 + semver: 7.7.3 + tmp: 0.2.5 + typed-rest-client: 1.8.11 + url-join: 4.0.1 + xml2js: 0.5.0 + yauzl: 2.10.0 + yazl: 2.5.1 + optionalDependencies: + keytar: 7.9.0 + transitivePeerDependencies: + - supports-color + '@wavedrom/doppler@1.14.0': dependencies: lodash.get: 4.4.2 @@ -1867,6 +3046,10 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 + ansi-escapes@7.2.0: + dependencies: + environment: 1.1.0 + ansi-regex@5.0.1: {} ansi-regex@6.2.2: {} @@ -1884,18 +3067,45 @@ snapshots: argparse@2.0.1: {} + astral-regex@2.0.0: {} + + asynckit@0.4.0: {} + + azure-devops-node-api@12.5.0: + dependencies: + tunnel: 0.0.6 + typed-rest-client: 1.8.11 + balanced-match@1.0.2: {} + base64-js@1.5.1: + optional: true + baseline-browser-mapping@2.9.6: {} binary-extensions@2.3.0: {} binary-search@1.3.6: {} + binaryextensions@6.11.0: + dependencies: + editions: 6.22.0 + bindings@1.5.0: dependencies: file-uri-to-path: 1.0.0 + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + optional: true + + boolbase@1.0.0: {} + + boundary@2.0.0: {} + brace-expansion@1.1.12: dependencies: balanced-match: 1.0.2 @@ -1919,8 +3129,22 @@ snapshots: node-releases: 2.0.27 update-browserslist-db: 1.2.2(browserslist@4.28.1) + buffer-crc32@0.2.13: {} + + buffer-equal-constant-time@1.0.1: {} + buffer-from@1.1.2: {} + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + optional: true + + bundle-name@4.1.0: + dependencies: + run-applescript: 7.1.0 + c8@10.1.3: dependencies: '@bcoe/v8-coverage': 1.0.2 @@ -1935,6 +3159,16 @@ snapshots: yargs: 17.7.2 yargs-parser: 21.1.1 + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + callsites@3.1.0: {} camelcase@6.3.0: {} @@ -1948,6 +3182,29 @@ snapshots: chalk@5.6.2: {} + cheerio-select@2.1.0: + dependencies: + boolbase: 1.0.0 + css-select: 5.2.2 + css-what: 6.2.2 + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + + cheerio@1.1.2: + dependencies: + cheerio-select: 2.1.0 + dom-serializer: 2.0.0 + domhandler: 5.0.3 + domutils: 3.2.2 + encoding-sniffer: 0.2.1 + htmlparser2: 10.0.0 + parse5: 7.3.0 + parse5-htmlparser2-tree-adapter: 7.1.0 + parse5-parser-stream: 7.1.2 + undici: 7.16.0 + whatwg-mimetype: 4.0.0 + chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -1964,6 +3221,9 @@ snapshots: dependencies: readdirp: 4.1.2 + chownr@1.1.4: + optional: true + chrome-trace-event@1.0.4: {} cli-cursor@5.0.0: @@ -1984,6 +3244,8 @@ snapshots: kind-of: 6.0.3 shallow-clone: 3.0.1 + cockatiel@3.2.1: {} + color-convert@2.0.1: dependencies: color-name: 1.1.4 @@ -1992,6 +3254,10 @@ snapshots: colorette@2.0.20: {} + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + commander@12.1.0: {} commander@2.20.3: {} @@ -2008,6 +3274,16 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + css-select@5.2.2: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 + + css-what@6.2.2: {} + debug@3.2.7: dependencies: ms: 2.1.3 @@ -2020,16 +3296,70 @@ snapshots: decamelize@4.0.0: {} + decompress-response@6.0.0: + dependencies: + mimic-response: 3.1.0 + optional: true + + deep-extend@0.6.0: + optional: true + deep-is@0.1.4: {} + default-browser-id@5.0.1: {} + + default-browser@5.4.0: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.1 + + define-lazy-prop@3.0.0: {} + + delayed-stream@1.0.0: {} + + detect-libc@2.1.2: + optional: true + diff@7.0.0: {} + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + dot-prop@6.0.1: dependencies: is-obj: 2.0.0 + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + eastasianwidth@0.2.0: {} + ecdsa-sig-formatter@1.0.11: + dependencies: + safe-buffer: 5.2.1 + + editions@6.22.0: + dependencies: + version-range: 4.15.0 + electron-to-chromium@1.5.267: {} emoji-regex@10.6.0: {} @@ -2038,15 +3368,46 @@ snapshots: emoji-regex@9.2.2: {} + encoding-sniffer@0.2.1: + dependencies: + iconv-lite: 0.6.3 + whatwg-encoding: 3.1.1 + + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + optional: true + enhanced-resolve@5.18.3: dependencies: graceful-fs: 4.2.11 tapable: 2.3.0 + entities@4.5.0: {} + + entities@6.0.1: {} + envinfo@7.21.0: {} + environment@1.1.0: {} + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + es-module-lexer@1.7.0: {} + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + escalade@3.2.0: {} escape-string-regexp@4.0.0: {} @@ -2128,8 +3489,19 @@ snapshots: eventsource-parser@3.0.6: {} + expand-template@2.0.3: + optional: true + fast-deep-equal@3.1.3: {} + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + fast-json-stable-stringify@2.1.0: {} fast-levenshtein@2.0.6: {} @@ -2138,6 +3510,14 @@ snapshots: fastest-levenshtein@1.0.16: {} + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + + fd-slicer@1.1.0: + dependencies: + pend: 1.2.0 + fdir@6.5.0(picomatch@4.0.3): optionalDependencies: picomatch: 4.0.3 @@ -2176,6 +3556,23 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 + form-data@4.0.5: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 + mime-types: 2.1.35 + + fs-constants@1.0.0: + optional: true + + fs-extra@11.3.3: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.0 + universalify: 2.0.1 + fsevents@2.3.3: optional: true @@ -2185,6 +3582,27 @@ snapshots: get-east-asian-width@1.4.0: {} + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + github-from-package@0.0.0: + optional: true + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -2204,20 +3622,61 @@ snapshots: package-json-from-dist: 1.0.1 path-scurry: 1.11.1 + glob@11.1.0: + dependencies: + foreground-child: 3.3.1 + jackspeak: 4.1.1 + minimatch: 10.1.1 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 2.0.1 + globals@14.0.0: {} + globby@14.1.0: + dependencies: + '@sindresorhus/merge-streams': 2.3.0 + fast-glob: 3.3.3 + ignore: 7.0.5 + path-type: 6.0.0 + slash: 5.1.0 + unicorn-magic: 0.3.0 + + gopd@1.2.0: {} + graceful-fs@4.2.11: {} has-flag@4.0.0: {} + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + hasown@2.0.2: dependencies: function-bind: 1.1.2 he@1.2.0: {} + hosted-git-info@4.1.0: + dependencies: + lru-cache: 6.0.0 + + hosted-git-info@7.0.2: + dependencies: + lru-cache: 10.4.3 + html-escaper@2.0.2: {} + htmlparser2@10.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + entities: 6.0.1 + http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.4 @@ -2232,10 +3691,17 @@ snapshots: transitivePeerDependencies: - supports-color + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + iconv-lite@0.7.1: dependencies: safer-buffer: 2.1.2 + ieee754@1.2.1: + optional: true + ignore@5.3.2: {} ignore@7.0.5: {} @@ -2254,8 +3720,13 @@ snapshots: imurmurhash@0.1.4: {} + index-to-position@1.2.0: {} + inherits@2.0.4: {} + ini@1.3.8: + optional: true + interpret@3.1.1: {} is-binary-path@2.1.0: @@ -2266,6 +3737,8 @@ snapshots: dependencies: hasown: 2.0.2 + is-docker@3.0.0: {} + is-extglob@2.1.1: {} is-fullwidth-code-point@3.0.0: {} @@ -2274,6 +3747,10 @@ snapshots: dependencies: is-extglob: 2.1.1 + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + is-interactive@2.0.0: {} is-number@7.0.0: {} @@ -2294,6 +3771,10 @@ snapshots: is-unicode-supported@2.1.0: {} + is-wsl@3.1.0: + dependencies: + is-inside-container: 1.0.0 + isarray@1.0.0: {} isexe@2.0.0: {} @@ -2313,18 +3794,30 @@ snapshots: html-escaper: 2.0.2 istanbul-lib-report: 3.0.1 + istextorbinary@9.5.0: + dependencies: + binaryextensions: 6.11.0 + editions: 6.22.0 + textextensions: 6.11.0 + jackspeak@3.4.3: dependencies: '@isaacs/cliui': 8.0.2 optionalDependencies: '@pkgjs/parseargs': 0.11.0 + jackspeak@4.1.1: + dependencies: + '@isaacs/cliui': 8.0.2 + jest-worker@27.5.1: dependencies: '@types/node': 22.19.2 merge-stream: 2.0.0 supports-color: 8.1.1 + js-tokens@4.0.0: {} + js-yaml@4.1.1: dependencies: argparse: 2.0.1 @@ -2339,6 +3832,29 @@ snapshots: json-stable-stringify-without-jsonify@1.0.1: {} + json5@2.2.3: {} + + jsonc-parser@3.3.1: {} + + jsonfile@6.2.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + jsonwebtoken@9.0.3: + dependencies: + jws: 4.0.1 + lodash.includes: 4.3.0 + lodash.isboolean: 3.0.3 + lodash.isinteger: 4.0.4 + lodash.isnumber: 3.0.3 + lodash.isplainobject: 4.0.6 + lodash.isstring: 4.0.1 + lodash.once: 4.1.1 + ms: 2.1.3 + semver: 7.7.3 + jszip@3.10.1: dependencies: lie: 3.3.0 @@ -2346,12 +3862,31 @@ snapshots: readable-stream: 2.3.8 setimmediate: 1.0.5 + jwa@2.0.1: + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 + + jws@4.0.1: + dependencies: + jwa: 2.0.1 + safe-buffer: 5.2.1 + + keytar@7.9.0: + dependencies: + node-addon-api: 4.3.0 + prebuild-install: 7.1.3 + optional: true + keyv@4.5.4: dependencies: json-buffer: 3.0.1 kind-of@6.0.3: {} + leven@3.1.0: {} + levn@0.4.1: dependencies: prelude-ls: 1.2.1 @@ -2361,6 +3896,10 @@ snapshots: dependencies: immediate: 3.0.6 + linkify-it@5.0.0: + dependencies: + uc.micro: 2.1.0 + llparse-builder@1.5.2: dependencies: '@types/debug': 4.1.5 @@ -2395,8 +3934,26 @@ snapshots: lodash.get@4.4.2: {} + lodash.includes@4.3.0: {} + + lodash.isboolean@3.0.3: {} + + lodash.isinteger@4.0.4: {} + + lodash.isnumber@3.0.3: {} + + lodash.isplainobject@4.0.6: {} + + lodash.isstring@4.0.1: {} + lodash.merge@4.6.2: {} + lodash.once@4.1.1: {} + + lodash.truncate@4.4.2: {} + + lodash@4.17.21: {} + log-symbols@4.1.0: dependencies: chalk: 4.1.2 @@ -2409,12 +3966,33 @@ snapshots: lru-cache@10.4.3: {} + lru-cache@11.2.4: {} + + lru-cache@6.0.0: + dependencies: + yallist: 4.0.0 + make-dir@4.0.0: dependencies: semver: 7.7.3 + markdown-it@14.1.0: + dependencies: + argparse: 2.0.1 + entities: 4.5.0 + linkify-it: 5.0.0 + mdurl: 2.0.0 + punycode.js: 2.3.1 + uc.micro: 2.1.0 + + math-intrinsics@1.1.0: {} + + mdurl@2.0.0: {} + merge-stream@2.0.0: {} + merge2@1.4.1: {} + micromatch@4.0.8: dependencies: braces: 3.0.3 @@ -2426,8 +4004,17 @@ snapshots: dependencies: mime-db: 1.52.0 + mime@1.6.0: {} + mimic-function@5.0.1: {} + mimic-response@3.1.0: + optional: true + + minimatch@10.1.1: + dependencies: + '@isaacs/brace-expansion': 5.0.0 + minimatch@3.1.2: dependencies: brace-expansion: 1.1.12 @@ -2436,8 +4023,14 @@ snapshots: dependencies: brace-expansion: 2.0.2 + minimist@1.2.8: + optional: true + minipass@7.1.2: {} + mkdirp-classic@0.5.3: + optional: true + mocha@11.7.5: dependencies: browser-stdout: 1.3.1 @@ -2464,14 +4057,49 @@ snapshots: ms@2.1.3: {} + mute-stream@0.0.8: {} + + napi-build-utils@2.0.0: + optional: true + natural-compare@1.4.0: {} neo-async@2.6.2: {} + node-abi@3.85.0: + dependencies: + semver: 7.7.3 + optional: true + + node-addon-api@4.3.0: + optional: true + node-releases@2.0.27: {} + node-sarif-builder@3.3.1: + dependencies: + '@types/sarif': 2.1.7 + fs-extra: 11.3.3 + + normalize-package-data@6.0.2: + dependencies: + hosted-git-info: 7.0.2 + semver: 7.7.3 + validate-npm-package-license: 3.0.4 + normalize-path@3.0.0: {} + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + object-inspect@1.13.4: {} + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + optional: true + onetime@7.0.0: dependencies: mimic-function: 5.0.1 @@ -2480,6 +4108,13 @@ snapshots: dependencies: sax: 1.4.3 + open@10.2.0: + dependencies: + default-browser: 5.4.0 + define-lazy-prop: 3.0.0 + is-inside-container: 1.0.0 + wsl-utils: 0.1.0 + optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -2517,6 +4152,8 @@ snapshots: dependencies: p-limit: 3.1.0 + p-map@7.0.4: {} + p-try@2.2.0: {} package-json-from-dist@1.0.1: {} @@ -2527,6 +4164,29 @@ snapshots: dependencies: callsites: 3.1.0 + parse-json@8.3.0: + dependencies: + '@babel/code-frame': 7.27.1 + index-to-position: 1.2.0 + type-fest: 4.41.0 + + parse-semver@1.1.1: + dependencies: + semver: 5.7.2 + + parse5-htmlparser2-tree-adapter@7.1.0: + dependencies: + domhandler: 5.0.3 + parse5: 7.3.0 + + parse5-parser-stream@7.1.2: + dependencies: + parse5: 7.3.0 + + parse5@7.3.0: + dependencies: + entities: 6.0.1 + path-exists@4.0.0: {} path-key@3.1.1: {} @@ -2538,6 +4198,15 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.2 + path-scurry@2.0.1: + dependencies: + lru-cache: 11.2.4 + minipass: 7.1.2 + + path-type@6.0.0: {} + + pend@1.2.0: {} + picocolors@1.1.1: {} picomatch@2.3.1: {} @@ -2548,16 +4217,79 @@ snapshots: dependencies: find-up: 4.1.0 + pluralize@2.0.0: {} + + pluralize@8.0.0: {} + + prebuild-install@7.1.3: + dependencies: + detect-libc: 2.1.2 + expand-template: 2.0.3 + github-from-package: 0.0.0 + minimist: 1.2.8 + mkdirp-classic: 0.5.3 + napi-build-utils: 2.0.0 + node-abi: 3.85.0 + pump: 3.0.3 + rc: 1.2.8 + simple-get: 4.0.1 + tar-fs: 2.1.4 + tunnel-agent: 0.6.0 + optional: true + prelude-ls@1.2.1: {} process-nextick-args@2.0.1: {} + pump@3.0.3: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + optional: true + + punycode.js@2.3.1: {} + punycode@2.3.1: {} + qs@6.14.0: + dependencies: + side-channel: 1.1.0 + + queue-microtask@1.2.3: {} + randombytes@2.1.0: dependencies: safe-buffer: 5.2.1 + rc-config-loader@4.1.3: + dependencies: + debug: 4.4.3(supports-color@8.1.1) + js-yaml: 4.1.1 + json5: 2.2.3 + require-from-string: 2.0.2 + transitivePeerDependencies: + - supports-color + + rc@1.2.8: + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + optional: true + + read-pkg@9.0.1: + dependencies: + '@types/normalize-package-data': 2.4.4 + normalize-package-data: 6.0.2 + parse-json: 8.3.0 + type-fest: 4.41.0 + unicorn-magic: 0.1.0 + + read@1.0.7: + dependencies: + mute-stream: 0.0.8 + readable-stream@2.3.8: dependencies: core-util-is: 1.0.3 @@ -2568,6 +4300,13 @@ snapshots: string_decoder: 1.1.1 util-deprecate: 1.0.2 + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + optional: true + readdirp@3.6.0: dependencies: picomatch: 2.3.1 @@ -2601,6 +4340,14 @@ snapshots: onetime: 7.0.0 signal-exit: 4.1.0 + reusify@1.1.0: {} + + run-applescript@7.1.0: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + safe-buffer@5.1.2: {} safe-buffer@5.2.1: {} @@ -2616,6 +4363,20 @@ snapshots: ajv-formats: 2.1.1(ajv@8.17.1) ajv-keywords: 5.1.0(ajv@8.17.1) + secretlint@10.2.2: + dependencies: + '@secretlint/config-creator': 10.2.2 + '@secretlint/formatter': 10.2.2 + '@secretlint/node': 10.2.2 + '@secretlint/profiler': 10.2.2 + debug: 4.4.3(supports-color@8.1.1) + globby: 14.1.0 + read-pkg: 9.0.1 + transitivePeerDependencies: + - supports-color + + semver@5.7.2: {} + semver@7.7.3: {} serialize-javascript@6.0.2: @@ -2634,8 +4395,54 @@ snapshots: shebang-regex@3.0.0: {} + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + signal-exit@4.1.0: {} + simple-concat@1.0.1: + optional: true + + simple-get@4.0.1: + dependencies: + decompress-response: 6.0.0 + once: 1.4.0 + simple-concat: 1.0.1 + optional: true + + slash@5.1.0: {} + + slice-ansi@4.0.0: + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + source-map-support@0.5.21: dependencies: buffer-from: 1.1.2 @@ -2645,6 +4452,20 @@ snapshots: source-map@0.7.6: {} + spdx-correct@3.2.0: + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.22 + + spdx-exceptions@2.5.0: {} + + spdx-expression-parse@3.0.1: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.22 + + spdx-license-ids@3.0.22: {} + stdin-discarder@0.2.2: {} string-width@4.2.3: @@ -2677,8 +4498,15 @@ snapshots: dependencies: ansi-regex: 6.2.2 + strip-json-comments@2.0.1: + optional: true + strip-json-comments@3.1.1: {} + structured-source@4.0.0: + dependencies: + boundary: 2.0.0 + style-mod@4.1.3: {} supports-color@10.2.2: {} @@ -2691,10 +4519,45 @@ snapshots: dependencies: has-flag: 4.0.0 + supports-hyperlinks@3.2.0: + dependencies: + has-flag: 4.0.0 + supports-color: 7.2.0 + supports-preserve-symlinks-flag@1.0.0: {} + table@6.9.0: + dependencies: + ajv: 8.17.1 + lodash.truncate: 4.4.2 + slice-ansi: 4.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + tapable@2.3.0: {} + tar-fs@2.1.4: + dependencies: + chownr: 1.1.4 + mkdirp-classic: 0.5.3 + pump: 3.0.3 + tar-stream: 2.2.0 + optional: true + + tar-stream@2.2.0: + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.5 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + optional: true + + terminal-link@4.0.0: + dependencies: + ansi-escapes: 7.2.0 + supports-hyperlinks: 3.2.0 + terser-webpack-plugin@5.3.15(webpack@5.103.0): dependencies: '@jridgewell/trace-mapping': 0.3.31 @@ -2717,11 +4580,19 @@ snapshots: glob: 10.5.0 minimatch: 9.0.5 + text-table@0.2.0: {} + + textextensions@6.11.0: + dependencies: + editions: 6.22.0 + tinyglobby@0.2.15: dependencies: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 + tmp@0.2.5: {} + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 @@ -2740,10 +4611,27 @@ snapshots: typescript: 5.9.3 webpack: 5.103.0(webpack-cli@6.0.1) + tslib@2.8.1: {} + + tunnel-agent@0.6.0: + dependencies: + safe-buffer: 5.2.1 + optional: true + + tunnel@0.0.6: {} + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 + type-fest@4.41.0: {} + + typed-rest-client@1.8.11: + dependencies: + qs: 6.14.0 + tunnel: 0.0.6 + underscore: 1.13.7 + typescript-eslint@8.49.0(eslint@9.39.1)(typescript@5.9.3): dependencies: '@typescript-eslint/eslint-plugin': 8.49.0(@typescript-eslint/parser@8.49.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3) @@ -2757,8 +4645,20 @@ snapshots: typescript@5.9.3: {} + uc.micro@2.1.0: {} + + underscore@1.13.7: {} + undici-types@6.21.0: {} + undici@7.16.0: {} + + unicorn-magic@0.1.0: {} + + unicorn-magic@0.3.0: {} + + universalify@2.0.1: {} + update-browserslist-db@1.2.2(browserslist@4.28.1): dependencies: browserslist: 4.28.1 @@ -2769,14 +4669,23 @@ snapshots: dependencies: punycode: 2.3.1 + url-join@4.0.1: {} + util-deprecate@1.0.2: {} + uuid@8.3.2: {} + v8-to-istanbul@9.3.0: dependencies: '@jridgewell/trace-mapping': 0.3.31 '@types/istanbul-lib-coverage': 2.0.6 convert-source-map: 2.0.0 + validate-npm-package-license@3.0.4: + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + vcd-stream@1.5.0: dependencies: bindings: 1.5.0 @@ -2787,6 +4696,8 @@ snapshots: vcdrom@1.6.0: {} + version-range@4.15.0: {} + w3c-keyname@2.2.8: {} watchpack@2.4.4: @@ -2862,6 +4773,12 @@ snapshots: - esbuild - uglify-js + whatwg-encoding@3.1.1: + dependencies: + iconv-lite: 0.6.3 + + whatwg-mimetype@4.0.0: {} + which@2.0.2: dependencies: isexe: 2.0.0 @@ -2884,8 +4801,24 @@ snapshots: string-width: 5.1.2 strip-ansi: 7.1.2 + wrappy@1.0.2: + optional: true + + wsl-utils@0.1.0: + dependencies: + is-wsl: 3.1.0 + + xml2js@0.5.0: + dependencies: + sax: 1.4.3 + xmlbuilder: 11.0.1 + + xmlbuilder@11.0.1: {} + y18n@5.0.8: {} + yallist@4.0.0: {} + yargs-parser@21.1.1: {} yargs-unparser@2.0.0: @@ -2905,4 +4838,13 @@ snapshots: y18n: 5.0.8 yargs-parser: 21.1.1 + yauzl@2.10.0: + dependencies: + buffer-crc32: 0.2.13 + fd-slicer: 1.1.0 + + yazl@2.5.1: + dependencies: + buffer-crc32: 0.2.13 + yocto-queue@0.1.0: {} diff --git a/src/constants/toolIcons.ts b/src/constants/toolIcons.ts index ca881be..8d866f9 100644 --- a/src/constants/toolIcons.ts +++ b/src/constants/toolIcons.ts @@ -50,3 +50,23 @@ export const SearchCode = ` `; + +/** + * 发送按钮图标 SVG(向上箭头) + */ +export const sendIconSvg = ` + + + + +`; + +/** + * 暂停按钮图标 SVG(圆形边框内的方块) + */ +export const stopIconSvg = ` + + + + +`; diff --git a/src/extension.ts b/src/extension.ts index 1c2fa0d..9abe301 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -3,26 +3,44 @@ import { ICViewProvider } from "./views/ICViewProvider"; import { showICHelperPanel } from "./panels/ICHelperPanel"; import { VCDViewerPanel } from "./panels/VCDViewerPanel"; import { ChatHistoryManager } from "./utils/chatHistoryManager"; +import { ICCoderAuthenticationProvider } from "./services/icCoderAuthProvider"; export function activate(context: vscode.ExtensionContext) { console.log("🎉 IC Coder 插件已激活!"); - // 自动打开聊天面板 - vscode.commands.executeCommand("ic-coder.openChat"); + // 注册 Authentication Provider + const authProvider = new ICCoderAuthenticationProvider(context); + context.subscriptions.push( + vscode.authentication.registerAuthenticationProvider( + "iccoder", + "IC Coder", + authProvider + ) + ); + + // 检查登录状态,如果已登录则自动打开聊天面板 + vscode.authentication.getSession("iccoder", [], { createIfNone: false }) + .then((session) => { + if (session) { + vscode.commands.executeCommand("ic-coder.openChat"); + } + }, () => { + // 未登录,不做任何操作 + }); // 注册命令:打开助手面板 const openPanelCommand = vscode.commands.registerCommand( "ic-coder.openPanel", - () => { - showICHelperPanel(context); + async () => { + await showICHelperPanel(context); } ); // 注册命令:打开聊天(用于侧边栏) const openChatCommand = vscode.commands.registerCommand( "ic-coder.openChat", - () => { - showICHelperPanel(context); + async () => { + await showICHelperPanel(context); } ); @@ -54,6 +72,40 @@ export function activate(context: vscode.ExtensionContext) { } ); + // 注册命令:用户登录 + const loginCommand = vscode.commands.registerCommand( + "ic-coder.login", + async () => { + try { + await vscode.authentication.getSession("iccoder", [], { createIfNone: true }); + } catch (error) { + vscode.window.showErrorMessage(`登录失败: ${error}`); + } + } + ); + + // 注册命令:用户登出 + const logoutCommand = vscode.commands.registerCommand( + "ic-coder.logout", + async () => { + try { + const session = await vscode.authentication.getSession("iccoder", [], { createIfNone: false }); + if (session) { + // 通过创建新会话并清除偏好来实现登出 + await vscode.authentication.getSession("iccoder", [], { + clearSessionPreference: true, + forceNewSession: true + }); + vscode.window.showInformationMessage("已退出登录"); + } else { + vscode.window.showInformationMessage("当前未登录"); + } + } catch (error) { + vscode.window.showInformationMessage("当前未登录"); + } + } + ); + // 注册命令:查看会话历史 // TODO: 这些命令需要根据新的任务架构重新实现 // 暂时注释掉,等待重新实现 @@ -102,7 +154,7 @@ export function activate(context: vscode.ExtensionContext) { */ // 注册侧边栏视图 - const viewProvider = new ICViewProvider(context.extensionUri); + const viewProvider = new ICViewProvider(context.extensionUri, context); const viewRegistration = vscode.window.registerWebviewViewProvider( "ic-coder.mainView", viewProvider @@ -113,6 +165,8 @@ export function activate(context: vscode.ExtensionContext) { openPanelCommand, openChatCommand, openVCDViewerCommand, + loginCommand, + logoutCommand, // TODO: 等待重新实现这些命令 // viewHistoryCommand, // newSessionCommand, diff --git a/src/panels/ICHelperPanel.ts b/src/panels/ICHelperPanel.ts index e5781c3..f9d227e 100644 --- a/src/panels/ICHelperPanel.ts +++ b/src/panels/ICHelperPanel.ts @@ -11,14 +11,36 @@ import { abortCurrentDialog, } from "../utils/messageHandler"; import { VCDViewerPanel } from "./VCDViewerPanel"; +import { ChatHistoryManager } from "../utils/chatHistoryManager"; +import { MessageType } from "../types/chatHistory"; /** * 创建并显示 IC 助手面板 */ -export function showICHelperPanel( +export async function showICHelperPanel( context: vscode.ExtensionContext, viewColumn?: vscode.ViewColumn ) { + // 检查用户是否已登录 + try { + const session = await vscode.authentication.getSession("iccoder", [], { createIfNone: false }); + if (!session) { + vscode.window.showWarningMessage("请先登录后再使用 IC Coder", "立即登录").then((selection) => { + if (selection === "立即登录") { + vscode.commands.executeCommand("ic-coder.login"); + } + }); + return; + } + } catch (error) { + vscode.window.showWarningMessage("请先登录后再使用 IC Coder", "立即登录").then((selection) => { + if (selection === "立即登录") { + vscode.commands.executeCommand("ic-coder.login"); + } + }); + return; + } + // 创建WebView面板 const panel = vscode.window.createWebviewPanel( "icCoder", // 面板ID @@ -31,16 +53,22 @@ export function showICHelperPanel( } ); + // 为面板生成唯一ID + const panelId = `panel_${Date.now()}_${Math.random() + .toString(36) + .substr(2, 9)}`; + (panel as any).__uniqueId = panelId; + // 设置标签页图标 panel.iconPath = vscode.Uri.joinPath( context.extensionUri, "media", - "图案(方底).png" + "icon.png" ); // 获取页面内图标URI const iconUri = panel.webview.asWebviewUri( - vscode.Uri.joinPath(context.extensionUri, "media", "图案(方底).png") + vscode.Uri.joinPath(context.extensionUri, "media", "icon.png") ); // 设置HTML内容 @@ -48,9 +76,37 @@ export function showICHelperPanel( // 处理消息 panel.webview.onDidReceiveMessage( - (message) => { + async (message) => { + const historyManager = ChatHistoryManager.getInstance(); + const panelId = (panel as any).__uniqueId; + switch (message.command) { case "sendMessage": + // 仅在用户发送消息时,确保面板有任务上下文 + // 如果没有,则创建新任务(仅在首次发送消息时) + if (!historyManager.getPanelTask(panelId)) { + const workspacePath = + vscode.workspace.workspaceFolders?.[0]?.uri.fsPath; + if (workspacePath) { + try { + const taskMeta = await historyManager.createTask( + workspacePath, + "新对话" + ); + historyManager.setPanelTask( + panelId, + taskMeta.taskId, + workspacePath + ); + } catch (error) { + console.error("创建任务失败:", error); + } + } + } + + // 切换到当前面板的任务上下文 + historyManager.switchToPanelTask(panelId); + handleUserMessage(panel, message.text, context.extensionPath); break; case "readFile": @@ -96,14 +152,22 @@ export function showICHelperPanel( showICHelperPanel(context, panel.viewColumn); break; case "loadConversationHistory": - // 加载会话历史(暂未实现) - panel.webview.postMessage({ - command: "conversationHistory", - history: [], - }); + // 加载会话历史(支持分页) + loadConversationHistory( + panel, + message.offset || 0, + message.limit || 10 + ); break; case "selectConversation": - // 选择会话(暂未实现) + // 选择会话 + if (message.conversationId) { + selectConversation( + panel, + message.conversationId, + context.extensionPath + ); + } break; // 新增:处理用户回答 case "submitAnswer": @@ -122,6 +186,17 @@ export function showICHelperPanel( undefined, context.subscriptions ); + + // 面板关闭时清理任务映射 + panel.onDidDispose( + () => { + const historyManager = ChatHistoryManager.getInstance(); + const panelId = (panel as any).__uniqueId; + historyManager.removePanelTask(panelId); + }, + undefined, + context.subscriptions + ); } /** @@ -302,3 +377,243 @@ function parseVCDSignals(content: string, maxSignals: number = 3) { return signals; } + +/** + * 加载会话历史(支持分页) + */ +async function loadConversationHistory( + panel: vscode.WebviewPanel, + offset: number = 0, + limit: number = 10 +) { + try { + const historyManager = ChatHistoryManager.getInstance(); + const workspacePath = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath; + + if (!workspacePath) { + // 没有打开的工作区,返回空历史 + panel.webview.postMessage({ + command: "conversationHistory", + items: [], + total: 0, + hasMore: false, + }); + return; + } + + // 获取会话历史列表(支持分页) + const result = await historyManager.getConversationHistoryList( + workspacePath, + offset, + limit + ); + + // 发送会话历史到前端 + panel.webview.postMessage({ + command: "conversationHistory", + items: result.items, + total: result.total, + hasMore: result.hasMore, + }); + } catch (error) { + console.error("加载会话历史失败:", error); + // 发生错误时返回空历史 + panel.webview.postMessage({ + command: "conversationHistory", + items: [], + total: 0, + hasMore: false, + }); + } +} + +/** + * 选择并加载指定的会话 + */ +async function selectConversation( + panel: vscode.WebviewPanel, + taskId: string, + extensionPath: string +) { + try { + const historyManager = ChatHistoryManager.getInstance(); + const workspacePath = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath; + + if (!workspacePath) { + vscode.window.showErrorMessage("没有打开的工作区"); + return; + } + + // 加载任务会话 + const taskSession = await historyManager.loadTaskSession( + workspacePath, + taskId + ); + + if (!taskSession) { + vscode.window.showErrorMessage( + `加载任务 ${taskId} 失败: 任务不存在或数据损坏` + ); + return; + } + + // 切换到该任务 + const switched = await historyManager.switchTask(workspacePath, taskId); + if (!switched) { + vscode.window.showErrorMessage(`切换到任务 ${taskId} 失败`); + return; + } + + // 更新面板的任务映射,确保后续对话保存到正确的任务中 + const panelId = (panel as any).__uniqueId; + historyManager.setPanelTask(panelId, taskId, workspacePath); + + // 清空当前聊天界面 + panel.webview.postMessage({ + command: "clearChat", + }); + + // 将会话历史消息转换为 segments 格式并发送到前端显示 + const segments: any[] = []; + let i = 0; + + while (i < taskSession.messages.length) { + const message = taskSession.messages[i]; + + if (message.type === MessageType.USER) { + // 用户消息 - 如果有累积的 segments,先发送 + if (segments.length > 0) { + panel.webview.postMessage({ + command: "receiveSegments", + segments: [...segments], + }); + segments.length = 0; + } + + // 发送用户消息 + const textContent = message.contents?.find((c) => c.type === "TEXT"); + if (textContent && "text" in textContent) { + panel.webview.postMessage({ + command: "addUserMessage", + text: textContent.text, + }); + } + i++; + } else if (message.type === MessageType.AI) { + // AI消息 - 如果有 segments,直接使用 + if (message.segments && message.segments.length > 0) { + panel.webview.postMessage({ + command: "receiveSegments", + segments: message.segments, + }); + i++; + } else { + // 旧格式:需要转换为 segments + // 收集连续的 AI 消息、工具调用和工具结果 + if (message.text) { + segments.push({ + type: "text", + content: message.text, + }); + } + + // 检查是否有工具调用 + if ( + message.toolExecutionRequests && + message.toolExecutionRequests.length > 0 + ) { + for (const toolReq of message.toolExecutionRequests) { + // 查找对应的工具执行结果 + let toolResult = ""; + if (i + 1 < taskSession.messages.length) { + const nextMsg = taskSession.messages[i + 1]; + if ( + nextMsg.type === MessageType.TOOL_EXECUTION_RESULT && + nextMsg.id === toolReq.id + ) { + toolResult = nextMsg.text; + i++; // 跳过工具结果消息 + } + } + + segments.push({ + type: "tool", + toolName: toolReq.name, + askId: toolReq.id, + toolResult: toolResult, + }); + } + } + + i++; + + // 继续收集后续的 AI 消息,直到遇到用户消息或有 segments 的 AI 消息 + while (i < taskSession.messages.length) { + const nextMsg = taskSession.messages[i]; + if (nextMsg.type === MessageType.USER) { + break; + } + if (nextMsg.type === MessageType.AI) { + if (nextMsg.segments && nextMsg.segments.length > 0) { + break; + } + if (nextMsg.text) { + segments.push({ + type: "text", + content: nextMsg.text, + }); + } + if ( + nextMsg.toolExecutionRequests && + nextMsg.toolExecutionRequests.length > 0 + ) { + for (const toolReq of nextMsg.toolExecutionRequests) { + let toolResult = ""; + if (i + 1 < taskSession.messages.length) { + const resultMsg = taskSession.messages[i + 1]; + if ( + resultMsg.type === MessageType.TOOL_EXECUTION_RESULT && + resultMsg.id === toolReq.id + ) { + toolResult = resultMsg.text; + i++; // 跳过工具结果消息 + } + } + segments.push({ + type: "tool", + toolName: toolReq.name, + askId: toolReq.id, + toolResult: toolResult, + }); + } + } + i++; + } else if (nextMsg.type === MessageType.TOOL_EXECUTION_RESULT) { + // 独立的工具结果(没有被上面处理的) + i++; + } else { + i++; + } + } + } + } else { + i++; + } + } + + // 发送剩余的 segments + if (segments.length > 0) { + panel.webview.postMessage({ + command: "receiveSegments", + segments: segments, + }); + } + + vscode.window.showInformationMessage( + `已加载会话: ${taskSession.meta.taskName}` + ); + } catch (error) { + console.error("选择会话失败:", error); + vscode.window.showErrorMessage(`加载会话失败: ${error}`); + } +} diff --git a/src/services/icCoderAuthProvider.ts b/src/services/icCoderAuthProvider.ts new file mode 100644 index 0000000..05c8a3c --- /dev/null +++ b/src/services/icCoderAuthProvider.ts @@ -0,0 +1,437 @@ +import * as vscode from "vscode"; +import * as http from "http"; +import * as path from "path"; +import * as fs from "fs"; + +/** + * IC Coder Authentication Provider + * 集成到 VSCode 账户系统 + */ +export class ICCoderAuthenticationProvider + implements vscode.AuthenticationProvider +{ + private static readonly AUTH_TYPE = "iccoder"; + private static readonly AUTH_NAME = "IC Coder"; + private static readonly LOGIN_URL = "http://192.168.1.108:2005/login"; + private static loginServer: http.Server | null = null; + private static currentPort: number | null = null; + + private _onDidChangeSessions = + new vscode.EventEmitter(); + public readonly onDidChangeSessions = this._onDidChangeSessions.event; + + private _sessions: vscode.AuthenticationSession[] = []; + + constructor(private readonly context: vscode.ExtensionContext) { + // 从存储中恢复会话 + this.loadSessions(); + } + + /** + * 从存储中加载会话 + */ + private async loadSessions(): Promise { + const storedSessions = this.context.globalState.get< + vscode.AuthenticationSession[] + >("icCoderSessions", []); + this._sessions = storedSessions; + } + + /** + * 保存会话到存储 + */ + private async saveSessions(): Promise { + await this.context.globalState.update("icCoderSessions", this._sessions); + } + + /** + * 获取会话列表 + */ + async getSessions( + scopes?: readonly string[] + ): Promise { + return [...this._sessions]; + } + + /** + * 创建会话(登录) + */ + async createSession( + scopes: readonly string[] + ): Promise { + try { + const token = await this.login(); + + // 创建会话 + const session: vscode.AuthenticationSession = { + id: this.generateSessionId(), + accessToken: token, + account: { + id: "iccoder-user", + label: "IC Coder 用户", + }, + scopes: [...scopes], + }; + + this._sessions.push(session); + await this.saveSessions(); + + // 触发会话变化事件 + this._onDidChangeSessions.fire({ + added: [session], + removed: [], + changed: [], + }); + + vscode.window.showInformationMessage("登录成功!窗口将自动刷新..."); + + // 延迟 1 秒后重新加载窗口,让用户看到成功消息 + setTimeout(() => { + vscode.commands.executeCommand("workbench.action.reloadWindow"); + }, 1000); + + return session; + } catch (error) { + vscode.window.showErrorMessage( + `登录失败: ${error instanceof Error ? error.message : String(error)}` + ); + throw error; + } + } + + /** + * 删除会话(登出) + */ + async removeSession(sessionId: string): Promise { + const sessionIndex = this._sessions.findIndex((s) => s.id === sessionId); + if (sessionIndex > -1) { + const session = this._sessions[sessionIndex]; + this._sessions.splice(sessionIndex, 1); + await this.saveSessions(); + + // 触发会话变化事件 + this._onDidChangeSessions.fire({ + added: [], + removed: [session], + changed: [], + }); + + vscode.window.showInformationMessage("已退出登录!窗口将自动刷新..."); + + // 延迟 1 秒后重新加载窗口,让用户看到成功消息 + setTimeout(() => { + vscode.commands.executeCommand("workbench.action.reloadWindow"); + }, 1000); + } + } + + /** + * 生成会话 ID + */ + private generateSessionId(): string { + return `iccoder-${Date.now()}-${Math.random().toString(36).substring(7)}`; + } + + /** + * 登录逻辑(打开浏览器并等待回调) + */ + private async login(): Promise { + // 如果已有服务器在运行,先关闭 + if (ICCoderAuthenticationProvider.loginServer) { + ICCoderAuthenticationProvider.loginServer.close(); + ICCoderAuthenticationProvider.loginServer = null; + } + + // 创建本地服务器监听回调 + const { server, port } = await this.createCallbackServer(); + ICCoderAuthenticationProvider.loginServer = server; + ICCoderAuthenticationProvider.currentPort = port; + + // 构建登录 URL + const callbackUrl = `http://localhost:${port}/callback`; + const loginUrl = `${ + ICCoderAuthenticationProvider.LOGIN_URL + }?redirect_uri=${encodeURIComponent(callbackUrl)}`; + + console.log("🔐 登录服务器已启动,监听端口:", port); + console.log("🌐 登录 URL:", loginUrl); + + // 打开浏览器登录 + await vscode.env.openExternal(vscode.Uri.parse(loginUrl)); + + vscode.window.showInformationMessage( + "请在浏览器中完成登录,登录成功后将自动返回..." + ); + + // 等待 token(通过 Promise) + return new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + if (ICCoderAuthenticationProvider.loginServer) { + ICCoderAuthenticationProvider.loginServer.close(); + ICCoderAuthenticationProvider.loginServer = null; + reject(new Error("登录超时")); + } + }, 5 * 60 * 1000); + + // 将 resolve 和 reject 保存到服务器上下文 + (server as any)._loginResolve = resolve; + (server as any)._loginReject = reject; + (server as any)._loginTimeout = timeout; + }); + } + + /** + * 创建本地回调服务器 + */ + private createCallbackServer(): Promise<{ + server: http.Server; + port: number; + }> { + return new Promise((resolve, reject) => { + // 读取 icon.png 并转换为 Base64 + const iconPath = path.join( + this.context.extensionPath, + "media", + "icon.png" + ); + let iconBase64 = ""; + try { + const iconBuffer = fs.readFileSync(iconPath); + iconBase64 = `data:image/png;base64,${iconBuffer.toString("base64")}`; + } catch (error) { + console.warn("无法读取 icon.png:", error); + } + + const server = http.createServer(async (req, res) => { + try { + console.log("📥 收到回调请求:", req.url); + + const url = new URL( + req.url!, + `http://localhost:${ICCoderAuthenticationProvider.currentPort}` + ); + console.log("📍 路径:", url.pathname); + console.log("📋 所有参数:", Object.fromEntries(url.searchParams)); + + if (url.pathname === "/callback") { + const token = url.searchParams.get("token"); + console.log("🔑 Token:", token ? "已获取" : "未找到"); + + if (token) { + // 返回成功页面 + res.writeHead(200, { + "Content-Type": "text/html; charset=utf-8", + }); + res.end(this.getSuccessPage(iconBase64)); + + // 关闭服务器 + server.close(); + ICCoderAuthenticationProvider.loginServer = null; + + // 清除超时 + if ((server as any)._loginTimeout) { + clearTimeout((server as any)._loginTimeout); + } + + // 返回 token + if ((server as any)._loginResolve) { + (server as any)._loginResolve(token); + } + } else { + res.writeHead(400, { + "Content-Type": "text/html; charset=utf-8", + }); + res.end(` + + + 登录失败 +

❌ 登录失败

未获取到有效的 Token

+ + `); + + if ((server as any)._loginReject) { + (server as any)._loginReject(new Error("未获取到有效的 Token")); + } + } + } else { + res.writeHead(404); + res.end("Not Found"); + } + } catch (error) { + res.writeHead(500); + res.end("Internal Server Error"); + if ((server as any)._loginReject) { + (server as any)._loginReject(error); + } + } + }); + + // 监听端口(使用 0 表示自动分配可用端口) + server.listen(0, () => { + const address = server.address(); + const port = + typeof address === "object" && address ? address.port : 3000; + resolve({ server, port }); + }); + + // 处理错误 + server.on("error", (error: NodeJS.ErrnoException) => { + reject(error); + }); + }); + } + + /** + * 获取登录成功页面 HTML + */ + private getSuccessPage(iconBase64: string): string { + return ` + + + + + + 登录成功 - IC Coder + + + +
+
+
+
+
+
+
+

登录成功!

+

您已成功登录 IC Coder
现在可以返回 VSCode 继续使用

+
+ + IC Coder +
+
+ + + `; + } +} diff --git a/src/types/chatHistory.ts b/src/types/chatHistory.ts index 9025553..ebb33dd 100644 --- a/src/types/chatHistory.ts +++ b/src/types/chatHistory.ts @@ -56,6 +56,7 @@ export interface AiMessage extends BaseMessage { text?: string; toolExecutionRequests?: ToolExecutionRequest[]; thinking?: string; + segments?: any[]; // 保存完整的 segments 信息用于还原显示 } /** diff --git a/src/utils/chatHistoryManager.ts b/src/utils/chatHistoryManager.ts index 06f1849..17609e1 100644 --- a/src/utils/chatHistoryManager.ts +++ b/src/utils/chatHistoryManager.ts @@ -8,7 +8,8 @@ import { MessageType, UserMessage, AiMessage, - SystemMessage + SystemMessage, + ToolExecutionResultMessage } from '../types/chatHistory'; /** @@ -20,6 +21,8 @@ export class ChatHistoryManager { private baseDir: string; // ~/.iccoder private currentTaskId: string | null = null; private currentProjectPath: string | null = null; + // 存储每个面板的任务信息(taskId 和 projectPath) + private panelTaskMap: Map = new Map(); private constructor() { // 设置存储路径: ~/.iccoder @@ -33,12 +36,13 @@ export class ChatHistoryManager { * 规则: * - 替换 \ 和 / 为 -- * - 替换 : 为空 - * 例如:C:\Users\admin\Documents\Project -> C--Users-admin-Documents-Project + * 例如:C:\Users\admin\Documents\Project -> C--Users--admin--Documents--Project */ private encodeProjectPath(projectPath: string): string { return projectPath - .replace(/:/g, '') // 移除冒号 - .replace(/[/\\]/g, '--'); // 替换斜杠为 -- + .replace(/\\/g, '--') // 替换反斜杠为 -- + .replace(/\//g, '--') // 替换正斜杠为 -- + .replace(/:/g, ''); // 移除冒号 } /** @@ -107,6 +111,43 @@ export class ChatHistoryManager { return ChatHistoryManager.instance; } + /** + * 为面板设置任务ID + */ + public setPanelTask(panelId: string, taskId: string, projectPath: string): void { + this.panelTaskMap.set(panelId, { taskId, projectPath }); + this.currentTaskId = taskId; + this.currentProjectPath = projectPath; + } + + /** + * 获取面板的任务ID + */ + public getPanelTask(panelId: string): string | null { + const taskInfo = this.panelTaskMap.get(panelId); + return taskInfo ? taskInfo.taskId : null; + } + + /** + * 切换到指定面板的任务上下文 + */ + public switchToPanelTask(panelId: string): boolean { + const taskInfo = this.panelTaskMap.get(panelId); + if (taskInfo) { + this.currentTaskId = taskInfo.taskId; + this.currentProjectPath = taskInfo.projectPath; + return true; + } + return false; + } + + /** + * 移除面板的任务映射 + */ + public removePanelTask(panelId: string): void { + this.panelTaskMap.delete(panelId); + } + /** * 创建新任务 */ @@ -264,17 +305,11 @@ export class ChatHistoryManager { } /** - * 确保有当前任务,如果没有则自动创建 + * 确保有当前任务,如果没有则抛出错误 */ private async ensureCurrentTask(): Promise { if (!this.currentTaskId || !this.currentProjectPath) { - // 获取当前工作区路径 - const workspacePath = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath; - if (workspacePath) { - await this.createTask(workspacePath, "默认任务"); - } else { - throw new Error("没有打开的工作区,无法创建任务"); - } + throw new Error("没有当前任务上下文,请确保已正确初始化面板任务"); } } @@ -300,14 +335,15 @@ export class ChatHistoryManager { /** * 添加AI消息 */ - public async addAiMessage(text: string, toolRequests?: any[]): Promise { + public async addAiMessage(text: string, toolRequests?: any[], segments?: any[]): Promise { await this.ensureCurrentTask(); const messages = await this.loadConversation(); const aiMessage: AiMessage = { type: MessageType.AI, text, - toolExecutionRequests: toolRequests + toolExecutionRequests: toolRequests, + segments // 保存完整的 segments 信息 }; messages.push(aiMessage); @@ -333,6 +369,24 @@ export class ChatHistoryManager { await this.saveConversation(messages); } + /** + * 添加工具执行结果消息 + */ + public async addToolExecutionResult(id: string, toolName: string, result: string): Promise { + await this.ensureCurrentTask(); + const messages = await this.loadConversation(); + + const toolResultMessage: ToolExecutionResultMessage = { + type: MessageType.TOOL_EXECUTION_RESULT, + id, + toolName, + text: result + }; + + messages.push(toolResultMessage); + await this.saveConversation(messages); + } + /** * 记录对话轮次元数据 */ @@ -450,6 +504,20 @@ export class ChatHistoryManager { tasks.push(JSON.parse(data)); } catch (error) { console.error(`加载任务 ${taskId} 失败:`, error); + // 跳过无效的任务目录 + // 尝试清理空目录 + try { + const taskDirUri = vscode.Uri.file(path.join(projectDir, taskId)); + const taskDirEntries = await vscode.workspace.fs.readDirectory(taskDirUri); + if (taskDirEntries.length === 0) { + // 目录为空,删除它 + await vscode.workspace.fs.delete(taskDirUri, { recursive: false }); + console.log(`已清理空任务目录: ${taskId}`); + } + } catch (cleanupError) { + // 清理失败,忽略错误 + console.warn(`清理任务目录 ${taskId} 失败:`, cleanupError); + } } } } @@ -494,4 +562,132 @@ export class ChatHistoryManager { public getBaseDir(): string { return this.baseDir; } + + /** + * 加载指定任务的会话内容 + * @param projectPath 项目路径 + * @param taskId 任务ID + * @returns 任务会话内容,如果任务不存在则返回null + */ + public async loadTaskSession(projectPath: string, taskId: string): Promise { + const taskDir = this.getTaskDir(projectPath, taskId); + const metaPath = path.join(taskDir, 'meta.json'); + + try { + // 检查任务是否存在 + const metaUri = vscode.Uri.file(metaPath); + const metaContent = await vscode.workspace.fs.readFile(metaUri); + const meta: TaskMeta = JSON.parse(Buffer.from(metaContent).toString('utf-8')); + + // 读取会话内容 + const conversationPath = path.join(taskDir, 'conversation.json'); + let messages: ChatMessage[] = []; + try { + const conversationUri = vscode.Uri.file(conversationPath); + const conversationContent = await vscode.workspace.fs.readFile(conversationUri); + messages = JSON.parse(Buffer.from(conversationContent).toString('utf-8')); + } catch { + // 会话文件不存在,使用空数组 + } + + // 读取会话元数据 + const conversationMetaPath = path.join(taskDir, 'conversation_meta.jsonl'); + let conversationMeta: ConversationMeta[] = []; + try { + const metaUri = vscode.Uri.file(conversationMetaPath); + const content = await vscode.workspace.fs.readFile(metaUri); + const data = Buffer.from(content).toString('utf-8'); + conversationMeta = data + .split('\n') + .filter(line => line.trim()) + .map(line => JSON.parse(line)); + } catch { + // 元数据文件不存在,使用空数组 + } + + return { + meta, + messages, + conversationMeta + }; + } catch (error) { + console.error(`加载任务 ${taskId} 的会话失败:`, error); + return null; + } + } + + /** + * 获取会话历史列表(支持分页) + * 返回格式:{ id: taskId, title: 第一句用户消息, timestamp: 创建时间 } + * @param projectPath 项目路径 + * @param offset 偏移量(从第几条开始,默认0) + * @param limit 每页数量(默认10条) + * @returns { items: 历史列表, total: 总数, hasMore: 是否还有更多 } + */ + public async getConversationHistoryList( + projectPath: string, + offset: number = 0, + limit: number = 10 + ): Promise<{ + items: Array<{ id: string; title: string; timestamp: string }>; + total: number; + hasMore: boolean; + }> { + const tasks = await this.listProjectTasks(projectPath); + const total = tasks.length; + const historyList: Array<{ id: string; title: string; timestamp: string }> = []; + + // 计算分页范围 + const start = offset; + const end = Math.min(offset + limit, total); + const limitedTasks = tasks.slice(start, end); + + for (const task of limitedTasks) { + // 读取该任务的 conversation.json 获取第一句用户消息 + const taskDir = this.getTaskDir(task.projectPath, task.taskId); + const conversationPath = path.join(taskDir, 'conversation.json'); + + try { + const uri = vscode.Uri.file(conversationPath); + const content = await vscode.workspace.fs.readFile(uri); + const data = Buffer.from(content).toString('utf-8'); + const messages: ChatMessage[] = JSON.parse(data); + + // 找到第一条用户消息 + const firstUserMessage = messages.find(msg => msg.type === MessageType.USER) as UserMessage | undefined; + + let title = '未命名会话'; + if (firstUserMessage && firstUserMessage.contents && firstUserMessage.contents.length > 0) { + const textContent = firstUserMessage.contents.find(c => c.type === 'TEXT'); + if (textContent && 'text' in textContent) { + // 截取前50个字符作为标题 + title = textContent.text.length > 50 + ? textContent.text.substring(0, 50) + '...' + : textContent.text; + } + } + + historyList.push({ + id: task.taskId, + title, + timestamp: task.createdAt + }); + } catch (error) { + console.error(`读取任务 ${task.taskId} 的会话历史失败:`, error); + // 如果读取失败,使用任务名称作为标题 + historyList.push({ + id: task.taskId, + title: task.taskName || '未命名会话', + timestamp: task.createdAt + }); + } + } + + // 返回分页结果 + return { + items: historyList, + total, + hasMore: end < total + }; + } } diff --git a/src/utils/messageHandler.ts b/src/utils/messageHandler.ts index b6cdb3f..c9fd435 100644 --- a/src/utils/messageHandler.ts +++ b/src/utils/messageHandler.ts @@ -170,6 +170,20 @@ async function handleUserMessageWithBackend( }); console.log('[MessageHandler] postMessage 返回值:', result); + // 保存完整的 segments 到历史记录 + try { + // 将完整的 segments 保存到一条 AI 消息中 + // 这样加载时可以完整还原对话样式 + const textContent = segments + .filter(s => s.type === 'text' && s.content) + .map(s => s.content) + .join('\n'); + + await historyManager.addAiMessage(textContent, undefined, segments); + } catch (error) { + console.warn("保存AI响应历史失败:", error); + } + resolve(); }, diff --git a/src/views/ICViewProvider.ts b/src/views/ICViewProvider.ts index 0eabefb..43a537a 100644 --- a/src/views/ICViewProvider.ts +++ b/src/views/ICViewProvider.ts @@ -32,12 +32,12 @@ export function showICHelperPanel(context: vscode.ExtensionContext) { panel.iconPath = vscode.Uri.joinPath( context.extensionUri, "media", - "图案(方底).png" + "icon.png" ); // 获取页面内图标URI const iconUri = panel.webview.asWebviewUri( - vscode.Uri.joinPath(context.extensionUri, "media", "图案(方底).png") + vscode.Uri.joinPath(context.extensionUri, "media", "icon.png") ); // 设置HTML内容 panel.webview.html = getWebviewContent(iconUri.toString()); @@ -59,7 +59,12 @@ export function showICHelperPanel(context: vscode.ExtensionContext) { handleRenameFile(panel, message.oldPath, message.newPath); break; case "replaceInFile": - handleReplaceInFile(panel, message.filePath, message.searchText, message.replaceText); + handleReplaceInFile( + panel, + message.filePath, + message.searchText, + message.replaceText + ); break; case "insertCode": insertCodeToEditor(message.code); @@ -77,7 +82,11 @@ export function showICHelperPanel(context: vscode.ExtensionContext) { break; // 新增:处理用户回答 case "submitAnswer": - handleUserAnswer(message.askId, message.selected, message.customInput); + handleUserAnswer( + message.askId, + message.selected, + message.customInput + ); break; // 新增:中止对话 case "abortDialog": @@ -94,7 +103,23 @@ export function showICHelperPanel(context: vscode.ExtensionContext) { * 侧边栏视图提供者 */ export class ICViewProvider implements vscode.WebviewViewProvider { - constructor(private readonly extensionUri: vscode.Uri) {} + constructor( + private readonly extensionUri: vscode.Uri, + private readonly context: vscode.ExtensionContext + ) {} + + /** + * 检查登录状态(使用 Authentication API) + */ + private async checkLoginStatus(): Promise { + try { + const session = await vscode.authentication.getSession("iccoder", [], { createIfNone: false }); + return !!session; + } catch (error) { + console.log("检查登录状态失败:", error); + return false; + } + } resolveWebviewView(webviewView: vscode.WebviewView) { webviewView.webview.options = { @@ -102,19 +127,30 @@ export class ICViewProvider implements vscode.WebviewViewProvider { localResourceRoots: [vscode.Uri.joinPath(this.extensionUri, "media")], }; - webviewView.webview.html = this.getWebviewContent(webviewView.webview); + // 检查是否已登录(使用 Authentication API) + this.checkLoginStatus().then((isLoggedIn) => { + webviewView.webview.html = this.getWebviewContent( + webviewView.webview, + isLoggedIn + ); + }); // 处理侧边栏的消息 webviewView.webview.onDidReceiveMessage((message) => { if (message.command === "openChat") { vscode.commands.executeCommand("ic-coder.openChat"); + } else if (message.command === "login") { + vscode.commands.executeCommand("ic-coder.login"); } }); } - private getWebviewContent(webview: vscode.Webview): string { + private getWebviewContent( + webview: vscode.Webview, + isLoggedIn: boolean + ): string { const logoUri = webview.asWebviewUri( - vscode.Uri.joinPath(this.extensionUri, "media", "ICCoder主页标志.png") + vscode.Uri.joinPath(this.extensionUri, "media", "icon.png") ); return ` @@ -175,7 +211,11 @@ export class ICViewProvider implements vscode.WebviewViewProvider {
IC Coder

欢迎使用 IC Coder

- + ${ + isLoggedIn + ? '' + : '' + }