diff --git a/.claude/skills/create-pr/SKILL.md b/.claude/skills/create-pr/SKILL.md new file mode 100644 index 0000000..d9a46af --- /dev/null +++ b/.claude/skills/create-pr/SKILL.md @@ -0,0 +1,63 @@ +--- +name: create-pr +description: GitHub PR作成コマンド +--- + +# GitHub PR作成コマンド + +現在のブランチの変更内容を確認し、PR テンプレートに従って GitHub 上に Pull Request を作成してください。 + +## 実行手順 + +1. 現在のブランチ名とベースブランチ(通常は develop)を確認し、差分を理解してください + +2. コードの変更内容を分析し、以下の情報を自動的に生成してください: + - PR タイトル(変更内容から適切なタイトルを推測) + - Description(変更内容の概要を説明) + - やったこと(実際の変更内容を箇条書きで) + - やらなかったこと/スコープ外の内容(推測できる範囲で) + - 備考・関連URL(関連する issue やドキュメントがあれば) + +3. 生成した内容を私に提示し、以下の項目について確認・質問してください: + - 生成した内容に修正・追加が必要か + - その他、追加すべき情報があるか + +4. 収集した情報を以下のテンプレートに当てはめて、PR本文を作成してください: + +```markdown +# Description + +[ここに説明を記載] + +# やったこと + +- [箇条書きで記載] + +# やらなかったこと + +- [箇条書きで記載、なければ「特になし」] + +# Operation Confirmation + + +## 事前準備・実行操作 +[手順を記載] + +# 備考・関連URL +[関連URLまたは「特になし」] +``` + + +5. 作成したPR内容を私に最終確認してもらい、問題なければ以下を実行: + - 未コミットの変更があれば、対象ファイルについて、私に対して「コミット」が必要なファイルか確認してください + - 現在のブランチをリモートにプッシュ + - `mcp__github__create_pull_request` ツールを使用してPRを作成 + + +6. PR作成後、作成されたPRのURLを表示してください + +## 注意事項 + + - ベースブランチは通常 `develop` ですが、確認してください + - PR 本文には必ず PR-Agent のコマンドを含めてください + - 必要に応じて、複数のコミットに分けることも検討してください diff --git a/.claude/skills/review-pr/SKILL.md b/.claude/skills/review-pr/SKILL.md new file mode 100644 index 0000000..674ab69 --- /dev/null +++ b/.claude/skills/review-pr/SKILL.md @@ -0,0 +1,125 @@ +--- +name: review-pr +description: GitHub PRをコーディングガイドラインに基づいて自動レビューするコマンド +--- + +# 概要 + +Github Pull Request をコーディングガイドラインに基づいて自動レビューし、改善点を指摘するコマンド。 +Github MCP を用いて PR の内容を取得し、品質憲章や各種ガイドラインに照らし合わせてレビューを実施する。 + +## 必須引数 + + - `$PR_URL`: Github Pull Request URL (例: ) + +## 動作フロー + +1. **PR 情報取得** - MCP経由でPullRequestの基本情報を取得 +2. **変更ファイル取得** - 変更されたファイルの一覧とdiffを取得 +3. **コード解析** - 各ファイルの変更内容を解析 +4. **ガイドライン照合** - コード品質憲章、DB設計ガイドライン等と照合 +5. **レビューコメント生成** - 改善点・指摘事項をまとめる +6. **レビュー投稿** - GitHub上にレビューコメントを投稿 + +### 🔍 基本チェック項目 + + - **命名規則の遵守** + - 変数・関数・クラス名が意図を明確に表現しているか + + - 日本語のローマ字変換を避けているか + + - **CLEANなコード** + - 凝集度(Cohesion)が高いか + - 疎結合(Loose Coupling)になっているか + - 適切にカプセル化されているか + - 抽象化のレベルが適切か + - 冗長性がないか(DRY原則) + - **関数・クラス設計** + - 単一責任の原則を守っているか + - 引数の数が適切か + - フラグ引数を使っていないか + +### 📝 コメント・ドキュメント + + - コメントよりコードで表現されているか + - 必要なコメントは背景・理由を説明しているか + - テーブル・カラムにコメントが記載されているか + +### 🧪 テスト + + - テストコードが追加・修正されているか + - F.I.R.S.Tなテストになっているか + - Fast(高速) + - Independent(独立) + - Repeatable(再現性) + - Self-Validating(自己検証) + - Timely(適時性) + +### 🔒 セキュリティ + + - 秘密情報・認証情報が含まれていないか + - 適切なバリデーションが実装されているか + - SQLインジェクション等の脆弱性がないか + +## プロダクト構成とドキュメント + +PR の diff 箇所に合わせて、下記を参照してください。 + +### 📋 ガイドライン + + - **レビューガイドライン**: `docs/dev/review-guideline.md` + +## レビューお作法 + + - Github MCPを通じてレビューを行うこと + - `mcp__github__pull_request_review_write` で pending review を作成 + - `mcp__github__add_comment_to_pending_review` を用いてファイル、行指定で該当箇所にコメントを入れていくこと + - 一通りのコメントを終えたタイミングで、 `submit_pending_pull_request_review` を用いてレビュー送信すること + - すでにインラインでPR作成車によってコメントがされている箇所がある場合、そのコメントに対して反応すること + - いずれの場合も、「Claude Code によるコメント」である旨を明記すること + +### `submit_pending_pull_request_review` 時のテンプレート + + ```text + ## 📋 コードレビュー結果 + + ### ✅ 良い点 + - + + ### ⚠️ 改善提案 + - + + ### 🚨 必須修正項目 + - + + ### 📚 参考ドキュメント + - [レビューガイドライン](docs/dev/review-guideline.md) + + *Generated by Claude Code with `/review-pr` command* + ``` + +## エラーハンドリング + + - **PR が存在しない場合**: エラーメッセージを表示し、PR番号の確認を促す + - **アクセス権限がない場合**: 権限設定の確認を促す + - **ネットワークエラー**: リトライまたは手動でのレビューを促す + - **差分が大きすぎる場合**: 重要な変更に絞ってレビューを実施 + +## 使用例 + +### 基本的な使用方法 + + ```bash + /review:review-pr https://github.com/offich/gintonic/pull/10 + ``` + + - PRの変更内容を取得 + - コーディングガイドラインに基づいてレビュー + - 改善点をGitHubにコメント投稿 + +## 注意事項 + + - レビューは自動生成の提案であり、最終的な判断は人間が行うこと + - ビジネスロジックの妥当性は判断できないため、技術的な観点のみレビュー + - 大規模なPRの場合、重要度の高い指摘に絞ってコメント + - 既存コードのスタイルに合わせることを優先 diff --git a/.fvmrc b/.fvmrc index 4cfa3d5..ac62dd3 100644 --- a/.fvmrc +++ b/.fvmrc @@ -1,3 +1,3 @@ { - "flutter": "3.29.0" + "flutter": "3.38.10" } \ No newline at end of file diff --git a/.github/templates/git-pr-release.erb b/.github/templates/git-pr-release.erb new file mode 100644 index 0000000..ebbcdf7 --- /dev/null +++ b/.github/templates/git-pr-release.erb @@ -0,0 +1,9 @@ +【Production Release】<%= Time.now.strftime('%Y-%m-%d %H:%M') %> + +## Description +Distribute DevTool Extension :rocket: + +## Target PR +<% pull_requests.each do |pr| -%> +- #<%= pr.number %> by <%= pr.mention %> +<% end -%> diff --git a/.github/workflows/code-analysis.yml b/.github/workflows/code-analysis.yml index 423c936..815aac7 100644 --- a/.github/workflows/code-analysis.yml +++ b/.github/workflows/code-analysis.yml @@ -18,7 +18,7 @@ jobs: timeout-minutes: 10 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 1 @@ -26,17 +26,17 @@ jobs: run: | mkdir -p $HOME/.ssh/ - - uses: kuhnroyal/flutter-fvm-config-action@v2 + - uses: kuhnroyal/flutter-fvm-config-action@4155f8ca4c30a4f2f50df69caa0e4259f6cd1142 # v2.3 id: fvm-config-action - - uses: subosito/flutter-action@v2.18.0 + - uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0 with: channel: ${{ steps.fvm-config-action.outputs.FLUTTER_CHANNEL }} flutter-version: ${{ steps.fvm-config-action.outputs.FLUTTER_VERSION }} cache: true - name: restore pubspec dependencies cache - uses: actions/cache@v4 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 id: pubspec_cache_id with: path: | @@ -57,21 +57,21 @@ jobs: needs: setup steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 1 - - uses: kuhnroyal/flutter-fvm-config-action@v3 + - uses: kuhnroyal/flutter-fvm-config-action@c378498f1d1962d33039c3989411093ef8a17b2c # v3.3 id: fvm-config-action - - uses: subosito/flutter-action@v2.18.0 + - uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0 with: channel: ${{ steps.fvm-config-action.outputs.FLUTTER_CHANNEL }} flutter-version: ${{ steps.fvm-config-action.outputs.FLUTTER_VERSION }} cache: true - name: restore pubspec dependencies cache - uses: actions/cache@v4 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 id: pubspec_cache_id with: path: | diff --git a/.github/workflows/create-release-pr.yml b/.github/workflows/create-release-pr.yml new file mode 100644 index 0000000..4816999 --- /dev/null +++ b/.github/workflows/create-release-pr.yml @@ -0,0 +1,33 @@ +name: Create Production Release PR + +on: + push: + branches: [develop] + +permissions: + contents: read + pull-requests: write + +jobs: + release-pull-request: + runs-on: ubuntu-latest + steps: + - name: Checkout Branch + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Setup Ruby + uses: ruby/setup-ruby@3ff19f5e2baf30647122352b96108b1fbe250c64 # v1.299.0 + with: + ruby-version: 3.3 + bundler-cache: true + + - run: gem install --no-document git-pr-release + + - run: git-pr-release + env: + GIT_PR_RELEASE_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GIT_PR_RELEASE_BRANCH_PRODUCTION: release + GIT_PR_RELEASE_BRANCH_STAGING: develop + GIT_PR_RELEASE_LABELS: release + GIT_PR_RELEASE_TEMPLATE: .github/templates/git-pr-release.erb + TZ: Asia/Tokyo diff --git a/.github/workflows/docs-analysis.yml b/.github/workflows/docs-analysis.yml new file mode 100644 index 0000000..83dc37a --- /dev/null +++ b/.github/workflows/docs-analysis.yml @@ -0,0 +1,51 @@ +name: 'docs-analysis' + +on: + push: + paths: + - 'CHANGELOG.md' + - '.claude/**/*.md' + - 'docs/**/*.md' + - 'package.json' + - 'pnpm-lock.yaml' + - '.markdownlint.jsonc' + - '.github/workflows/docs-analysis.yml' + + branches-ignore: + - release + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + lint-markdown: + runs-on: ubuntu-24.04 + timeout-minutes: 10 + + steps: + - name: checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 1 + + - uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # v4.0.1 + + - uses: pnpm/action-setup@b307475762933b98ed359c036b0e51f26b63b74b # v5.0.0 + + - name: get pnpm store path + id: pnpm-store + run: echo "path=$(pnpm store path)" >> $GITHUB_OUTPUT + + - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + id: pnpm-cache + with: + path: './node_modules' + key: pnpm-${{ hashFiles('pnpm-lock.yaml') }} + + - name: install dependencies + if: steps.pnpm-cache.outputs.cache-hit != 'true' + run: pnpm install + + - name: lint markdown + run: pnpm run lint:markdown diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index a1574be..aab6e02 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -15,18 +15,18 @@ jobs: id-token: write steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 1 - - uses: dart-lang/setup-dart@v1 + - uses: dart-lang/setup-dart@65eb853c7ba17dde3be364c3d2858773e7144260 # v1.7.2 with: sdk: 3.7.0 - - uses: kuhnroyal/flutter-fvm-config-action@v3 + - uses: kuhnroyal/flutter-fvm-config-action@c378498f1d1962d33039c3989411093ef8a17b2c # v3.3 id: fvm-config-action - - uses: subosito/flutter-action@v2.18.0 + - uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0 with: channel: ${{ steps.fvm-config-action.outputs.FLUTTER_CHANNEL }} flutter-version: ${{ steps.fvm-config-action.outputs.FLUTTER_VERSION }} diff --git a/.gitignore b/.gitignore index a23eaae..30f2158 100644 --- a/.gitignore +++ b/.gitignore @@ -76,3 +76,7 @@ app.*.map.json /extension/devtools/build/* /example/extension/devtools/build/* !*/extension/devtools/build/.gitkeep + +.mcp.json + +node_modules diff --git a/.markdownlint.jsonc b/.markdownlint.jsonc new file mode 100644 index 0000000..9accf7a --- /dev/null +++ b/.markdownlint.jsonc @@ -0,0 +1,14 @@ +{ + // Unordered list indentation + "MD007": { + "start_indented": true + }, + // Dollar signs used before commands without showing output + "MD013": false, + // Line Length + "MD014": false, + // Multiple headings with the same content + "MD024": false, + // First line in a file should be a top-level heading + "MD041": false +} diff --git a/.mcp.sample.json b/.mcp.sample.json new file mode 100644 index 0000000..e9f0418 --- /dev/null +++ b/.mcp.sample.json @@ -0,0 +1,11 @@ +{ + "mcpServers": { + "github": { + "type": "http", + "url": "https://api.githubcopilot.com/mcp/", + "headers": { + "Authorization": "Bearer ${PAT}" + } + } + } +} diff --git a/.pubignore b/.pubignore index 33121ad..15e9f35 100644 --- a/.pubignore +++ b/.pubignore @@ -2,12 +2,18 @@ .idea .fvmrc .gitignore +.markdownlint.jsonc analysis_options.yaml devtools_options.yaml renovate.json shirley.iml +CLAUDE.md +package.json +pnpm-lock.yaml +mise.toml test/ resources/ web/ +node_modules diff --git a/.serena/.gitignore b/.serena/.gitignore new file mode 100644 index 0000000..2e510af --- /dev/null +++ b/.serena/.gitignore @@ -0,0 +1,2 @@ +/cache +/project.local.yml diff --git a/.serena/project.yml b/.serena/project.yml new file mode 100644 index 0000000..d11c1e9 --- /dev/null +++ b/.serena/project.yml @@ -0,0 +1,119 @@ +# the name by which the project can be referenced within Serena +project_name: "shirley" + + +# list of languages for which language servers are started; choose from: +# al ansible bash clojure cpp +# cpp_ccls crystal csharp csharp_omnisharp dart +# elixir elm erlang fortran fsharp +# go groovy haskell haxe hlsl +# java json julia kotlin lean4 +# lua luau markdown matlab msl +# nix ocaml pascal perl php +# php_phpactor powershell python python_jedi python_ty +# r rego ruby ruby_solargraph rust +# scala solidity swift systemverilog terraform +# toml typescript typescript_vts vue yaml +# zig +# (This list may be outdated. For the current list, see values of Language enum here: +# https://github.com/oraios/serena/blob/main/src/solidlsp/ls_config.py +# For some languages, there are alternative language servers, e.g. csharp_omnisharp, ruby_solargraph.) +# Note: +# - For C, use cpp +# - For JavaScript, use typescript +# - For Free Pascal/Lazarus, use pascal +# Special requirements: +# Some languages require additional setup/installations. +# See here for details: https://oraios.github.io/serena/01-about/020_programming-languages.html#language-servers +# When using multiple languages, the first language server that supports a given file will be used for that file. +# The first language is the default language and the respective language server will be used as a fallback. +# Note that when using the JetBrains backend, language servers are not used and this list is correspondingly ignored. +languages: +- dart + +# the encoding used by text files in the project +# For a list of possible encodings, see https://docs.python.org/3.11/library/codecs.html#standard-encodings +encoding: "utf-8" + +# line ending convention to use when writing source files. +# Possible values: unset (use global setting), "lf", "crlf", or "native" (platform default) +# This does not affect Serena's own files (e.g. memories and configuration files), which always use native line endings. +line_ending: + +# The language backend to use for this project. +# If not set, the global setting from serena_config.yml is used. +# Valid values: LSP, JetBrains +# Note: the backend is fixed at startup. If a project with a different backend +# is activated post-init, an error will be returned. +language_backend: + +# whether to use project's .gitignore files to ignore files +ignore_all_files_in_gitignore: true + +# advanced configuration option allowing to configure language server-specific options. +# Maps the language key to the options. +# Have a look at the docstring of the constructors of the LS implementations within solidlsp (e.g., for C# or PHP) to see which options are available. +# No documentation on options means no options are available. +ls_specific_settings: {} + +# list of additional paths to ignore in this project. +# Same syntax as gitignore, so you can use * and **. +# Note: global ignored_paths from serena_config.yml are also applied additively. +ignored_paths: [] + +# whether the project is in read-only mode +# If set to true, all editing tools will be disabled and attempts to use them will result in an error +# Added on 2025-04-18 +read_only: false + +# list of tool names to exclude. +# This extends the existing exclusions (e.g. from the global configuration) +# Find the list of tools here: https://oraios.github.io/serena/01-about/035_tools.html +excluded_tools: [] + +# list of tools to include that would otherwise be disabled (particularly optional tools that are disabled by default). +# This extends the existing inclusions (e.g. from the global configuration). +# Find the list of tools here: https://oraios.github.io/serena/01-about/035_tools.html +included_optional_tools: [] + +# fixed set of tools to use as the base tool set (if non-empty), replacing Serena's default set of tools. +# This cannot be combined with non-empty excluded_tools or included_optional_tools. +# Find the list of tools here: https://oraios.github.io/serena/01-about/035_tools.html +fixed_tools: [] + +# list of mode names that are to be activated by default, overriding the setting in the global configuration. +# The full set of modes to be activated is base_modes (from global config) + default_modes + added_modes. +# If the setting is undefined/empty, the default_modes from the global configuration (serena_config.yml) apply. +# Otherwise, this overrides the setting from the global configuration (serena_config.yml). +# Therefore, you can set this to [] if you do not want the default modes defined in the global config to apply +# for this project. +# This setting can, in turn, be overridden by CLI parameters (--mode). +# See https://oraios.github.io/serena/02-usage/050_configuration.html#modes +default_modes: + +# list of mode names to be activated additionally for this project, e.g. ["query-projects"] +# The full set of modes to be activated is base_modes (from global config) + default_modes + added_modes. +# See https://oraios.github.io/serena/02-usage/050_configuration.html#modes +added_modes: + +# initial prompt for the project. It will always be given to the LLM upon activating the project +# (contrary to the memories, which are loaded on demand). +initial_prompt: "" + +# time budget (seconds) per tool call for the retrieval of additional symbol information +# such as docstrings or parameter information. +# This overrides the corresponding setting in the global configuration; see the documentation there. +# If null or missing, use the setting from the global configuration. +symbol_info_budget: + +# list of regex patterns which, when matched, mark a memory entry as read‑only. +# Extends the list from the global configuration, merging the two lists. +read_only_memory_patterns: [] + +# list of regex patterns for memories to completely ignore. +# Matching memories will not appear in list_memories or activate_project output +# and cannot be accessed via read_memory or write_memory. +# To access ignored memory files, use the read_file tool on the raw file path. +# Extends the list from the global configuration, merging the two lists. +# Example: ["_archive/.*", "_episodes/.*"] +ignored_memory_patterns: [] diff --git a/.serena/serena_config.yml b/.serena/serena_config.yml new file mode 100644 index 0000000..1df3be3 --- /dev/null +++ b/.serena/serena_config.yml @@ -0,0 +1,2 @@ +web_dashboard: false +web_dashboard_open_on_launch: false diff --git a/CHANGELOG.md b/CHANGELOG.md index e6ad158..20c4923 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,29 @@ -## 0.0.1 +## 0.1.0 - 2026-05-03 -* Official release. -* Rename prefix on Snackbar widget. -* Improve score on pub dev. -* Fix dart sdk version in CI. +### Changed -## 0.0.1-dev.1 + - flutter 3.38.10 -* Initial release. This package is under construction. +## [0.0.1] - 2025-03-11 + +### Added + + - Official release. + +### Changed + + - Rename prefix on Snackbar widget. + - Improve score on pub dev. + +### Fixed + + - Fix dart sdk version in CI. + +## [0.0.1-dev.1] - 2025-02-28 + +### Added + + - Initial release. This package is under construction. + +[0.0.1]: https://github.com/offich/shirley/compare/v0.0.1-dev.1...v0.0.1 +[0.0.1-dev.1]: https://github.com/offich/shirley/releases/tag/v0.0.1-dev.1 diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..941ba5d --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,69 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Overview + +**Shirley** is a Flutter DevTools Extension that provides an interactive UI for generating customizable Flutter `ElevatedButton` widget code. Users configure button properties through the UI, see a live preview, and copy the generated Dart code. + +Uses FVM to pin Flutter to `3.38.10`. Prefix Dart/Flutter commands with `fvm` (e.g., `fvm flutter run`). + +## Common Commands + +```bash +# Run in simulated DevTools environment (for local development) +fvm flutter run -d chrome --dart-define=use_simulated_environment=true + +# Run in real DevTools environment +fvm dart run devtools_extensions build_and_copy --source=. --dest=./example/extension/devtools +cd example && fvm flutter run + +# Lint and format checks (mirrors CI) +dart format --set-exit-if-changed lib test +fvm flutter analyze lib test + +# Run tests +fvm flutter test +fvm flutter test test/widget_test.dart # single test file +``` + +## Architecture + +### Data Flow + +`ButtonField` (model) → `toCode()` (code_builder AST) → Dart source string displayed in `PreviewCodeView` + +`ButtonField` → `toJsonString()` → JSON schema → `json_dynamic_widget` renders live preview in `PreviewWidgetView` + +### Key Files + +- **lib/main.dart** — Entry point; runs `ShirleyDevToolsExtension()` +- **lib/shirley.dart** — Root widgets: `ShirleyDevToolsExtension` (DevTools API event wiring) and `Shirley` (main layout with preset button configs) +- **lib/src/model/button_field.dart** — Core data model. Contains `toCode()` (generates Dart code via `code_builder`) and `toJsonString()` (generates JSON for dynamic widget rendering) + +### UI Component Tree + +``` +ShirleyDevToolsExtension +└── Shirley (presets + layout) + ├── PreviewContainer (TabBarView) + │ ├── PreviewWidgetView ← renders button via json_dynamic_widget + │ └── PreviewCodeView ← syntax-highlighted Dart code + └── FieldSettingContainer (TabBarView) + ├── QuickSettingView ← basic controls + ├── BodySettingView ← size/border settings + └── TextSettingView ← text/typography settings +``` + +All stateful widgets use `flutter_hooks` (HookWidget + `useState`/`useEffect`). + +### DevTools Extension Config + +`extension/devtools/config.yaml` — declares the extension to DevTools. `requiresConnection: false` means it works without a connected app. + +During publishing, the built extension is copied to `example/extension/devtools/` via `devtools_extensions build_and_copy`. + +## CI + +- **code-analysis.yml** — triggers on changes to `lib/`, `test/`, `pubspec.yaml`; runs format check and `flutter analyze` +- **publish.yml** — triggers on `v*` tags; validates extension, builds, copies to example/, then publishes to pub.dev diff --git a/docs/dev/review-guideline.md b/docs/dev/review-guideline.md new file mode 100644 index 0000000..d6cd34e --- /dev/null +++ b/docs/dev/review-guideline.md @@ -0,0 +1,248 @@ +# PR レビューガイドライン + +DevTools Extension のコードをレビューし、以下の観点で指摘してください。 + + - `Effective Dart のベストプラクティス遵守` + - `バグやクラッシュにつながる可能性` + - `VM Service / DTD との通信パターンの正確性` + - `非同期処理の危険パターン` + - `アイソレート変化・ホットリロードへの対応` + +特に **致命的バグパターン** の検出を最優先設定。DevTools 内でクラッシュ・フリーズ・データ化け・メモリリークを引き起こす可能性のある問題を重点的にチェックしてください。 + +## DevTools Extension 固有の前提知識 + +DevTools Extension は Flutter **Web** アプリとして iFrame 内で動作し、通常の Flutter アプリとは異なる制約があります。 + + - **通信はすべて非同期 RPC**: Extension ↔ DevTools ↔ VM Service ↔ 対象アプリ + - **ファイルシステムへの直接アクセス不可**: 必ず DTD (Dart Tooling Daemon) 経由 + - **アイソレートはホットリロードで変わる**: リスナーが古いアイソレートを参照し続けると不具合 + - **iFrame サンドボックス**: `postMessage` 以外の親ウィンドウへのアクセスは不可 + - **`requiresConnection`** が `true`(デフォルト)のとき、未接続状態で Extension は無効化される + +--- + +## レビュー観点(致命的バグ検出重点) + +### VM Service / DTD 通信 + + - [ ] **サービス呼び出しのエラーハンドリング** + - [ ] `serviceManager.callServiceExtension()` に `try-catch` / `.catchError()` があるか + - [ ] 切断中・未接続時に呼び出しが発生しないよう `isServiceAvailable` を確認しているか + - [ ] タイムアウトが設定されており、長時間ブロックしないか + - [ ] **サービス拡張のレスポンス** + - [ ] ハンドラが必ず `ServiceExtensionResponse.result()` または `.error()` を返すか + - [ ] Future が複数回完了する(ホットリスタート時の二重完了)パターンがないか + - [ ] パラメータの JSON デコードで例外が起きてもクラッシュしないか + - [ ] **DTD 利用** + - [ ] `dtdManager` が利用不可の場合に適切にフォールバックしているか + - [ ] ファイル操作が DTD 経由になっているか(直接 `dart:io` は使えない) + +### アイソレート変化・ホットリロード + + - [ ] **古いアイソレート参照** + - [ ] アイソレート変化時にリスナーを再登録しているか + - [ ] `selectedIsolate` の変化を `addListener` で監視し、処理を切り替えているか + - [ ] **ストリームの再購読** + - [ ] ホットリロード後にストリームが無効化されていないか + - [ ] `initState` で購読し `dispose` でキャンセルしているか + +### リスナー・サブスクリプションのリーク + + - [ ] **dispose 漏れ** + - [ ] `serviceManager` / `extensionManager` / `dtdManager` へのリスナーが `dispose()` でキャンセルされているか + - [ ] `StreamSubscription` が未キャンセルで放置されていないか + - [ ] タイマー・ポーリングが Extension タブを閉じると停止するか + +### 接続状態管理 + + - [ ] **未接続時の動作** + - [ ] `requiresConnection: true` の場合、未接続でサービス呼び出しを行っていないか + - [ ] 接続・切断イベントで UI 状態が正しく更新されるか + - [ ] **非同期処理中の切断** + - [ ] 長時間の処理中に切断が発生した場合にハンドリングされているか + +### 非同期処理の一般的な危険パターン + + - [ ] **unawaited Future** + - [ ] `initState` や `afterBuild` で `await` 漏れがないか + - [ ] 例外がサイレントに握りつぶされていないか + - [ ] **並行処理の管理** + - [ ] 複数の `callServiceExtension` を直列で呼ぶ必要があるとき、順序保証されているか + - [ ] `Future.wait` で一件失敗時に残りの処理が中断されないか + +--- + +### 一般的なコード品質 + + - [ ] 可読性・保守性 + - [ ] 設計原理の遵守 + - [ ] **null 安全・型安全** + - [ ] サービスレスポンスの JSON パースで null クラッシュがないか + - [ ] `serviceManager` / `dtdManager` が null のまま使われていないか + - [ ] テスト可能性 + - [ ] セキュリティ(サービス拡張のパラメータバリデーション) + +### プロジェクト固有 + + - [ ] 命名規則の統一 + - [ ] サービス拡張のメソッド名が `ext..` 形式か + - [ ] `config.yaml` に必須フィールド(`name`, `version`, `issueTracker`, `materialIconCodePoint`)があるか + - [ ] `DevToolsExtension` ウィジェットがルートに配置されているか + - [ ] 既存コードの整合性 + +--- + +## レビューで出力される内容 + +### 1. **致命的問題の指摘** + + - クラッシュ・フリーズ・メモリリークの可能性 + - VM Service / DTD の不正な使用 + - データ損失リスク(アイソレート変化時の状態喪失など) + - セキュリティ上の問題 + +### 2. **致命的バグ・クラッシュの検出パターン** + + - **dispose 漏れ**: タブを閉じてもリスナーが残り続けメモリを消費 + - **二重完了 Future**: ホットリスタートでハンドラが二度呼ばれ例外 + - **古いアイソレート参照**: ホットリロード後に無効なアイソレートへアクセス + - **切断中のサービス呼び出し**: 切断後に `callServiceExtension` してクラッシュ + - **unawaited Future**: 例外が握りつぶされてサイレント失敗 + - **JSON パースクラッシュ**: 不正なパラメータで `jsonDecode` が例外 + +### 3. **改善提案** + + - より堅牢な実装方法 + - 適切な例外処理パターン + - エラー回復戦略の提案 + +### 4. **具体的修正コード例** + + - 修正前後のコード比較 + - 推奨実装パターン + +--- + +## レビュー実行時の必須チェックリスト + +### Claude が最優先で確認すべき致命的なパターン + +#### 1. **`dispose()` でのリスナークリーンアップ漏れ** + +```dart +// 危険: タブを閉じてもリスナーが残り続ける +class _MyExtensionState extends State { + @override + void initState() { + serviceManager.onIsolateStopped.addListener(_onIsolateStopped); + } + // dispose() が未実装 → メモリリーク +} + +// 安全 +@override +void dispose() { + serviceManager.onIsolateStopped.removeListener(_onIsolateStopped); + _subscription?.cancel(); + super.dispose(); +} +``` + +#### 2. **切断チェックなしのサービス呼び出し** + +```dart +// 危険: 切断中に呼び出してクラッシュ +final result = await serviceManager.callServiceExtension('ext.myapp.getData'); + +// 安全 +if (!serviceManager.isServiceAvailable) { + return; // または UI でエラー表示 +} +final result = await serviceManager.callServiceExtension('ext.myapp.getData'); +``` + +#### 3. **ホットリロード後の古いアイソレート参照** + +```dart +// 危険: アイソレート変化を検知していない +final isolate = serviceManager.isolateManager.selectedIsolate.value; +await heavyOperation(isolate); // アイソレートが切り替わると無効 + +// 安全 +serviceManager.isolateManager.selectedIsolate.addListener(_onIsolateChanged); +// _onIsolateChanged で再初期化 +``` + +#### 4. **サービス拡張ハンドラの二重完了** + +```dart +// 危険: タイムアウト後もハンドラが完了しようとする +Future handler(String method, Map params) async { + final result = await operation().timeout(const Duration(seconds: 5)); + return ServiceExtensionResponse.result(jsonEncode(result)); // timeout後も到達する可能性 +} + +// 安全: Completer で単一完了を保証 +final completer = Completer(); +operation().timeout(const Duration(seconds: 5)).then( + (r) { if (!completer.isCompleted) completer.complete(...); }, + onError: (e) { if (!completer.isCompleted) completer.completeError(e); }, +); +return completer.future; +``` + +#### 5. **unawaited な非同期処理** + +```dart +// 危険: 例外が握りつぶされる +@override +void initState() { + super.initState(); + loadData(); // await なし +} + +// 安全 +@override +void initState() { + super.initState(); + unawaited(loadData().catchError((e) { + // エラーハンドリング + })); +} +``` + +#### 6. **JSON パースの無防備な処理** + +```dart +// 危険: 不正な JSON でクラッシュ +Future handler(String method, Map params) async { + final data = jsonDecode(params['data']!); // null / 不正 JSON でクラッシュ + +// 安全 + final rawData = params['data']; + if (rawData == null) { + return ServiceExtensionResponse.error( + ServiceExtensionResponse.invalidParams, + '"data" parameter is required', + ); + } + try { + final data = jsonDecode(rawData); + ... + } on FormatException catch (e) { + return ServiceExtensionResponse.error( + ServiceExtensionResponse.invalidParams, + 'Invalid JSON: $e', + ); + } +} +``` + +--- + +## オプション + + - `--pre-commit` : コミット前チェックモード(より厳密なレビュー) + - `--focus=performance` : 特定の観点に絞ったレビュー + - `--japanese` : 日本語でのレビュー結果出力 diff --git a/example/pubspec.lock b/example/pubspec.lock index c2c57f7..40a60ed 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -53,10 +53,10 @@ packages: dependency: transitive description: name: fake_async - sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc" + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.3.3" flutter: dependency: "direct main" description: flutter @@ -79,26 +79,26 @@ packages: dependency: transitive description: name: leak_tracker - sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec + sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" url: "https://pub.dev" source: hosted - version: "10.0.8" + version: "11.0.2" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 + sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" url: "https://pub.dev" source: hosted - version: "3.0.9" + version: "3.0.10" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" lints: dependency: transitive description: @@ -127,10 +127,10 @@ packages: dependency: transitive description: name: meta - sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c + sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.17.0" path: dependency: transitive description: @@ -188,18 +188,18 @@ packages: dependency: transitive description: name: test_api - sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd + sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 url: "https://pub.dev" source: hosted - version: "0.7.4" + version: "0.7.7" vector_math: dependency: transitive description: name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.2.0" vm_service: dependency: transitive description: @@ -209,5 +209,5 @@ packages: source: hosted version: "14.3.1" sdks: - dart: ">=3.7.0 <4.0.0" + dart: ">=3.8.0-0 <4.0.0" flutter: ">=3.18.0-18.0.pre.54" diff --git a/lib/src/ui/components/shirley_snack_bar.dart b/lib/src/ui/components/shirley_snack_bar.dart index fc14df5..ed0d41d 100644 --- a/lib/src/ui/components/shirley_snack_bar.dart +++ b/lib/src/ui/components/shirley_snack_bar.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -showSnackBar(BuildContext context, String text, {bool isError = false}) { +void showSnackBar(BuildContext context, String text, {bool isError = false}) { ScaffoldMessenger.of(context).showSnackBar( ShirleySnackBar(text: text, isError: isError), ); diff --git a/mise.toml b/mise.toml new file mode 100644 index 0000000..20fedfa --- /dev/null +++ b/mise.toml @@ -0,0 +1,2 @@ +[tools] +node = "25.9.0" diff --git a/package.json b/package.json new file mode 100644 index 0000000..0ed87bd --- /dev/null +++ b/package.json @@ -0,0 +1,20 @@ +{ + "name": "shirley", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "lint": "npm run lint:markdown", + "lint:fix": "npm run lint:markdown:fix", + "lint:markdown": "markdownlint-cli2 docs/**/*.md .claude/**/*.md CHANGELOG.md", + "lint:markdown:fix": "markdownlint-cli2 --fix docs/**/*.md .claude/**/*.md CHANGELOG.md" + }, + "keywords": [], + "author": "", + "license": "ISC", + "packageManager": "pnpm@10.11.1", + "devDependencies": { + "markdownlint-cli2": "0.22.0" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..15e8353 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,713 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + markdownlint-cli2: + specifier: 0.22.0 + version: 0.22.0 + +packages: + + '@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'} + + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} + + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + + '@types/katex@0.16.8': + resolution: {integrity: sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decode-named-character-reference@1.3.0: + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + get-east-asian-width@1.5.0: + resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==} + engines: {node: '>=18'} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + globby@16.1.1: + resolution: {integrity: sha512-dW7vl+yiAJSp6aCekaVnVJxurRv7DCOLyXqEG3RYMYUg7AuJ2jCqPkZTA8ooqC2vtnkaMcV5WfFBMuEnTu1OQg==} + engines: {node: '>=20'} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + + is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + + is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-path-inside@4.0.0: + resolution: {integrity: sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==} + engines: {node: '>=12'} + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + + jsonc-parser@3.3.1: + resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + + jsonpointer@5.0.1: + resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==} + engines: {node: '>=0.10.0'} + + katex@0.16.45: + resolution: {integrity: sha512-pQpZbdBu7wCTmQUh7ufPmLr0pFoObnGUoL/yhtwJDgmmQpbkg/0HSVti25Fu4rmd1oCR6NGWe9vqTWuWv3GcNA==} + hasBin: true + + linkify-it@5.0.0: + resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} + + markdown-it@14.1.1: + resolution: {integrity: sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==} + hasBin: true + + markdownlint-cli2-formatter-default@0.0.6: + resolution: {integrity: sha512-VVDGKsq9sgzu378swJ0fcHfSicUnMxnL8gnLm/Q4J/xsNJ4e5bA6lvAz7PCzIl0/No0lHyaWdqVD2jotxOSFMQ==} + peerDependencies: + markdownlint-cli2: '>=0.0.4' + + markdownlint-cli2@0.22.0: + resolution: {integrity: sha512-mOC9BY/XGtdX3M9n3AgERd79F0+S7w18yBBTNIQ453sI87etZfp1z4eajqSMV70CYjbxKe5ktKvT2HCpvcWx9w==} + engines: {node: '>=20'} + hasBin: true + + markdownlint@0.40.0: + resolution: {integrity: sha512-UKybllYNheWac61Ia7T6fzuQNDZimFIpCg2w6hHjgV1Qu0w1TV0LlSgryUGzM0bkKQCBhy2FDhEELB73Kb0kAg==} + engines: {node: '>=20'} + + mdurl@2.0.0: + resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-extension-directive@4.0.0: + resolution: {integrity: sha512-/C2nqVmXXmiseSSuCdItCMho7ybwwop6RrrRPk0KbOHW21JKoCldC+8rFOaundDoRBUWBnJJcxeA/Kvi34WQXg==} + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-table@2.1.1: + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + + micromark-extension-math@3.1.0: + resolution: {integrity: sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + + picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} + engines: {node: '>=8.6'} + + punycode.js@2.3.1: + resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} + engines: {node: '>=6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + slash@5.1.0: + resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} + engines: {node: '>=14.16'} + + smol-toml@1.6.0: + resolution: {integrity: sha512-4zemZi0HvTnYwLfrpk/CF9LOd9Lt87kAt50GnqhMpyF9U3poDAP2+iukq2bZsO/ufegbYehBkqINbsWxj4l4cw==} + engines: {node: '>= 18'} + + string-width@8.1.0: + resolution: {integrity: sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==} + engines: {node: '>=20'} + + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + uc.micro@2.1.0: + resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + + unicorn-magic@0.4.0: + resolution: {integrity: sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==} + engines: {node: '>=20'} + +snapshots: + + '@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 + + '@sindresorhus/merge-streams@4.0.0': {} + + '@types/debug@4.1.13': + dependencies: + '@types/ms': 2.1.0 + + '@types/katex@0.16.8': {} + + '@types/ms@2.1.0': {} + + '@types/unist@2.0.11': {} + + ansi-regex@6.2.2: {} + + argparse@2.0.1: {} + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + character-entities-legacy@3.0.0: {} + + character-entities@2.0.2: {} + + character-reference-invalid@2.0.1: {} + + commander@8.3.0: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decode-named-character-reference@1.3.0: + dependencies: + character-entities: 2.0.2 + + dequal@2.0.3: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + entities@4.5.0: {} + + 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 + + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + get-east-asian-width@1.5.0: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + globby@16.1.1: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + fast-glob: 3.3.3 + ignore: 7.0.5 + is-path-inside: 4.0.0 + slash: 5.1.0 + unicorn-magic: 0.4.0 + + ignore@7.0.5: {} + + is-alphabetical@2.0.1: {} + + is-alphanumerical@2.0.1: + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + + is-decimal@2.0.1: {} + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-hexadecimal@2.0.1: {} + + is-number@7.0.0: {} + + is-path-inside@4.0.0: {} + + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + + jsonc-parser@3.3.1: {} + + jsonpointer@5.0.1: {} + + katex@0.16.45: + dependencies: + commander: 8.3.0 + + linkify-it@5.0.0: + dependencies: + uc.micro: 2.1.0 + + markdown-it@14.1.1: + 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 + + markdownlint-cli2-formatter-default@0.0.6(markdownlint-cli2@0.22.0): + dependencies: + markdownlint-cli2: 0.22.0 + + markdownlint-cli2@0.22.0: + dependencies: + globby: 16.1.1 + js-yaml: 4.1.1 + jsonc-parser: 3.3.1 + jsonpointer: 5.0.1 + markdown-it: 14.1.1 + markdownlint: 0.40.0 + markdownlint-cli2-formatter-default: 0.0.6(markdownlint-cli2@0.22.0) + micromatch: 4.0.8 + smol-toml: 1.6.0 + transitivePeerDependencies: + - supports-color + + markdownlint@0.40.0: + dependencies: + micromark: 4.0.2 + micromark-core-commonmark: 2.0.3 + micromark-extension-directive: 4.0.0 + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-table: 2.1.1 + micromark-extension-math: 3.1.0 + micromark-util-types: 2.0.2 + string-width: 8.1.0 + transitivePeerDependencies: + - supports-color + + mdurl@2.0.0: {} + + merge2@1.4.1: {} + + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-directive@4.0.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + parse-entities: 4.0.2 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-table@2.1.1: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-math@3.1.0: + dependencies: + '@types/katex': 0.16.8 + devlop: 1.1.0 + katex: 0.16.45 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-encode@2.0.1: {} + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.2: {} + + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.13 + debug: 4.4.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.2 + + ms@2.1.3: {} + + parse-entities@4.0.2: + dependencies: + '@types/unist': 2.0.11 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.3.0 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + + picomatch@2.3.2: {} + + punycode.js@2.3.1: {} + + queue-microtask@1.2.3: {} + + reusify@1.1.0: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + slash@5.1.0: {} + + smol-toml@1.6.0: {} + + string-width@8.1.0: + dependencies: + get-east-asian-width: 1.5.0 + strip-ansi: 7.2.0 + + strip-ansi@7.2.0: + dependencies: + ansi-regex: 6.2.2 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + uc.micro@2.1.0: {} + + unicorn-magic@0.4.0: {} diff --git a/pubspec.lock b/pubspec.lock index aa8c976..9d3e270 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,31 +5,26 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: "16e298750b6d0af7ce8a3ba7c18c69c3785d11b15ec83f6dcd0ad2a0009b3cab" + sha256: c209688d9f5a5f26b2fb47a188131a6fb9e876ae9e47af3737c0b4f58a93470d url: "https://pub.dev" source: hosted - version: "76.0.0" - _macros: - dependency: transitive - description: dart - source: sdk - version: "0.3.3" + version: "91.0.0" analyzer: dependency: transitive description: name: analyzer - sha256: "1f14db053a8c23e260789e9b0980fa27f2680dd640932cae5e1137cce0e46e1e" + sha256: f51c8499b35f9b26820cfe914828a6a98a94efd5cc78b37bb7d03debae3a1d08 url: "https://pub.dev" source: hosted - version: "6.11.0" + version: "8.4.1" args: dependency: transitive description: name: args - sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6 + sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 url: "https://pub.dev" source: hosted - version: "2.6.0" + version: "2.7.0" asn1lib: dependency: transitive description: @@ -42,10 +37,10 @@ packages: dependency: transitive description: name: async - sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63 + sha256: e2eb0491ba5ddb6177742d2da23904574082139b07c1e33b8503b9f46f3e1a37 url: "https://pub.dev" source: hosted - version: "2.12.0" + version: "2.13.1" boolean_selector: dependency: transitive description: @@ -66,10 +61,18 @@ packages: dependency: transitive description: name: built_value - sha256: "28a712df2576b63c6c005c465989a348604960c0958d28be5303ba9baa841ac2" + sha256: "34e4067d30ce212937df995f03b69992eea683539ceeac7f679a1f1eba055b56" + url: "https://pub.dev" + source: hosted + version: "8.12.6" + change: + dependency: transitive + description: + name: change + sha256: "3bda1ce98526b21927cdea05688563c7065fd7e66d1abbe176c354fef3b2057b" url: "https://pub.dev" source: hosted - version: "8.9.3" + version: "0.7.5" characters: dependency: transitive description: @@ -94,6 +97,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.2" + cider: + dependency: "direct dev" + description: + name: cider + sha256: "27b9cd9526c70d6cd47299cd644cddaac8102e5f9783ef4bb440840743271883" + url: "https://pub.dev" + source: hosted + version: "0.2.10" cli_util: dependency: transitive description: @@ -114,10 +125,10 @@ packages: dependency: "direct main" description: name: code_builder - sha256: "0ec10bf4a89e4c613960bf1e8b42c64127021740fb21640c29c909826a5eea3e" + sha256: "6a6cab2ba4680d6423f34a9b972a4c9a94ebe1b62ecec4e1a1f2cba91fd1319d" url: "https://pub.dev" source: hosted - version: "4.10.1" + version: "4.11.1" collection: dependency: transitive description: @@ -162,10 +173,10 @@ packages: dependency: "direct main" description: name: cupertino_icons - sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 + sha256: "41e005c33bd814be4d3096aff55b1908d419fde52ca656c8c47719ec745873cd" url: "https://pub.dev" source: hosted - version: "1.0.8" + version: "1.0.9" dap: dependency: transitive description: @@ -174,14 +185,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" + dart_service_protocol_shared: + dependency: transitive + description: + name: dart_service_protocol_shared + sha256: "1737875c176d7e3d87bb3a359182828b542fe20a0b34198b8d31a81af5c7a76d" + url: "https://pub.dev" + source: hosted + version: "0.0.3" dart_style: dependency: "direct main" description: name: dart_style - sha256: "27eb0ae77836989a3bc541ce55595e8ceee0992807f14511552a898ddd0d88ac" + sha256: a9c30492da18ff84efe2422ba2d319a89942d93e58eb0b73d32abe822ef54b7b url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.1.3" dds_service_extensions: dependency: transitive description: @@ -190,46 +209,62 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.1" + device_info_plus: + dependency: transitive + description: + name: device_info_plus + sha256: "98f28b42168cc509abc92f88518882fd58061ea372d7999aecc424345c7bff6a" + url: "https://pub.dev" + source: hosted + version: "11.5.0" + device_info_plus_platform_interface: + dependency: transitive + description: + name: device_info_plus_platform_interface + sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f + url: "https://pub.dev" + source: hosted + version: "7.0.3" devtools_app_shared: dependency: "direct main" description: name: devtools_app_shared - sha256: "8bbe39d622841b6ba15560fa7f32114ecb3e97aa662839b7572ab3c3c3d0dc4f" + sha256: "565f51fcacfe0a44d5fb74679edb5a434307af2ed1aa241a2ee95f38ae8df33d" url: "https://pub.dev" source: hosted - version: "0.3.1" + version: "0.5.0" devtools_extensions: dependency: "direct main" description: name: devtools_extensions - sha256: "3c16905b957b2b56d145ef7fede4f3091e0e3c5deae776210148a00c874c9a0e" + sha256: "98b069c5204518f71be04d27ef66107c54daac1148b2232bc0eb48e7a64604ab" url: "https://pub.dev" source: hosted - version: "0.3.1" + version: "0.5.0" devtools_shared: dependency: transitive description: name: devtools_shared - sha256: fa71f07006dfdf3f226ec76db95a4bad156820c081452cc99d18a4f291001bee + sha256: "2daf7a9fba6a470668b26ecbd04200f7bf992aad81a2c31d12457c7791419dea" url: "https://pub.dev" source: hosted - version: "11.2.0" + version: "12.1.0" dtd: dependency: transitive description: name: dtd - sha256: "0284e4d02b9be48142c1adf0d14670fb56f0f333837e61d269e3ca7839d5e183" + sha256: "09ddb228b3d1478a093556357692a4c203ff4f9d5f8cda05dfdca0ff3fb7c5d3" url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "4.0.0" dynamic_widget_annotation: dependency: transitive description: name: dynamic_widget_annotation - sha256: "01be96f2bf6e6603cd5a3e00ee537f041d47e271069b8479ae0949cddfe537b4" + sha256: "8b2bd5c7495ec1438091701e0267f926cb73d4bd566b4bcb2c0bbf964819d4f6" url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "3.0.1" encrypt: dependency: transitive description: @@ -258,10 +293,18 @@ packages: dependency: transitive description: name: fake_async - sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc" + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.3.3" + ffi: + dependency: transitive + description: + name: ffi + sha256: "6d7fd89431262d8f3125e81b50d3847a091d846eafcd4fdb88dd06f36d705a45" + url: "https://pub.dev" + source: hosted + version: "2.2.0" file: dependency: transitive description: @@ -295,18 +338,18 @@ packages: dependency: "direct main" description: name: flutter_hooks - sha256: b772e710d16d7a20c0740c4f855095026b31c7eb5ba3ab67d2bd52021cd9461d + sha256: "8ae1f090e5f4ef5cfa6670ce1ab5dddadd33f3533a7f9ba19d9f958aa2a89f42" url: "https://pub.dev" source: hosted - version: "0.21.2" + version: "0.21.3+1" flutter_lints: dependency: "direct dev" description: name: flutter_lints - sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1" + sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1" url: "https://pub.dev" source: hosted - version: "5.0.0" + version: "6.0.0" flutter_test: dependency: "direct dev" description: flutter @@ -345,18 +388,18 @@ packages: dependency: transitive description: name: html - sha256: "1fc58edeaec4307368c60d59b7e15b9d658b57d7f3125098b6294153c75337ec" + sha256: "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602" url: "https://pub.dev" source: hosted - version: "0.15.5" + version: "0.15.6" http: dependency: transitive description: name: http - sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 + sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412" url: "https://pub.dev" source: hosted - version: "1.2.2" + version: "1.6.0" http_multi_server: dependency: transitive description: @@ -405,6 +448,22 @@ packages: url: "https://pub.dev" source: hosted version: "0.1.2" + irondash_engine_context: + dependency: transitive + description: + name: irondash_engine_context + sha256: "2bb0bc13dfda9f5aaef8dde06ecc5feb1379f5bb387d59716d799554f3f305d7" + url: "https://pub.dev" + source: hosted + version: "0.5.5" + irondash_message_channel: + dependency: transitive + description: + name: irondash_message_channel + sha256: b4101669776509c76133b8917ab8cfc704d3ad92a8c450b92934dd8884a2f060 + url: "https://pub.dev" + source: hosted + version: "0.7.0" js: dependency: transitive description: @@ -441,10 +500,10 @@ packages: dependency: "direct main" description: name: json_dynamic_widget - sha256: "5bdcf12deab654ab47be35cb0674083b07c9846bbad710bdd2e63aaaf66a860b" + sha256: db7fe638a5e270334877e44cea6e36d3f7ee6252d1dfe7c1b43a58812e0e684f url: "https://pub.dev" source: hosted - version: "9.0.0+3" + version: "12.0.0+9" json_path: dependency: transitive description: @@ -465,58 +524,58 @@ packages: dependency: transitive description: name: json_schema - sha256: b183ba828374365a89b81246c06a9a636935897d509cd846998bbc0d9bd0a2cf + sha256: f37d9c3fdfe8c9aae55fdfd5af815d24ce63c3a0f6a2c1f0982c30f43643fa1a url: "https://pub.dev" source: hosted - version: "5.2.0" + version: "5.2.2" json_theme: dependency: transitive description: name: json_theme - sha256: "3c757352d14bf76c4683e283da2fabfb75669d7478efda67011cba6a0471ca4b" + sha256: a984e1aaae7e116e5e6cc604c359f391a371cfac9ed4c7c2e6b754c28e7a4df5 url: "https://pub.dev" source: hosted - version: "8.0.0+1" + version: "11.0.0" json_theme_annotation: dependency: transitive description: name: json_theme_annotation - sha256: "61d263546a2d5c621ff3e7813def5da941d879eeb7b7e07d0e3aacc68ead85a6" + sha256: c5b9b7ad1ec53e96d36773e1fa6cd39e828848196a38f006a562f51d6432f7eb url: "https://pub.dev" source: hosted - version: "1.0.3+15" + version: "2.0.0+4" leak_tracker: dependency: transitive description: name: leak_tracker - sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec + sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" url: "https://pub.dev" source: hosted - version: "10.0.8" + version: "11.0.2" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 + sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" url: "https://pub.dev" source: hosted - version: "3.0.9" + version: "3.0.10" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" lints: dependency: transitive description: name: lints - sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7 + sha256: "12f842a479589fea194fe5c5a3095abc7be0c1f2ddfa9a0e76aed1dbd26a87df" url: "https://pub.dev" source: hosted - version: "5.1.1" + version: "6.1.0" logging: dependency: transitive description: @@ -525,14 +584,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.0" - macros: - dependency: transitive - description: - name: macros - sha256: "1d9e801cd66f7ea3663c45fc708450db1fa57f988142c64289142c9b7ee80656" - url: "https://pub.dev" - source: hosted - version: "0.1.3-main.0" markdown: dependency: transitive description: @@ -541,6 +592,14 @@ packages: url: "https://pub.dev" source: hosted version: "7.3.0" + marker: + dependency: transitive + description: + name: marker + sha256: "3dadd01f3b0ffae148ffb3b1bc04290a98e54a465cddbab59727bd2a9fe57750" + url: "https://pub.dev" + source: hosted + version: "0.6.0" matcher: dependency: transitive description: @@ -569,10 +628,10 @@ packages: dependency: transitive description: name: meta - sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c + sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.17.0" mime: dependency: transitive description: @@ -601,10 +660,10 @@ packages: dependency: "direct dev" description: name: pana - sha256: "2190c23df74361a9e7e2030ab96a7a2b5f05d301fe632a6a1a3153570c37c8a4" + sha256: ae025b2c224f225ca6dd79fb61d0397b9ab8bdb3fcfa2f9b956ffb5f1b6be650 url: "https://pub.dev" source: hosted - version: "0.22.19" + version: "0.23.11" path: dependency: transitive description: @@ -621,6 +680,14 @@ packages: url: "https://pub.dev" source: hosted version: "6.0.2" + pixel_snap: + dependency: transitive + description: + name: pixel_snap + sha256: "677410ea37b07cd37ecb6d5e6c0d8d7615a7cf3bd92ba406fd1ac57e937d1fb0" + url: "https://pub.dev" + source: hosted + version: "0.1.5" plugin_platform_interface: dependency: transitive description: @@ -681,10 +748,10 @@ packages: dependency: transitive description: name: pub_semver - sha256: "7b3cfbf654f3edd0c6298ecd5be782ce997ddf0e00531b9464b55245185bbbbd" + sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585" url: "https://pub.dev" source: hosted - version: "2.1.5" + version: "2.2.0" pubspec_parse: dependency: transitive description: @@ -834,22 +901,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.1" - syntax_highlight: - dependency: "direct main" + super_clipboard: + dependency: transitive description: - name: syntax_highlight - sha256: ee33b6aa82cc722bb9b40152a792181dee222353b486c0255fde666a3e3a4997 + name: super_clipboard + sha256: e73f3bb7e66cc9260efa1dc507f979138e7e106c3521e2dda2d0311f6d728a16 url: "https://pub.dev" source: hosted - version: "0.4.0" - tar: + version: "0.9.1" + super_native_extensions: dependency: transitive description: - name: tar - sha256: "8e67ab1baa07d3ef2c5d52cfb84e7ed4742799141e9e2ac3d0801a1a7ccb7575" + name: super_native_extensions + sha256: b9611dcb68f1047d6f3ef11af25e4e68a21b1a705bbcc3eb8cb4e9f5c3148569 url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "0.9.1" + syntax_highlight: + dependency: "direct main" + description: + name: syntax_highlight + sha256: "4d3ba40658cadba6ba55d697f29f00b43538ebb6eb4a0ca0e895c568eaced138" + url: "https://pub.dev" + source: hosted + version: "0.5.0" template_expressions: dependency: transitive description: @@ -870,26 +945,26 @@ packages: dependency: transitive description: name: test - sha256: "301b213cd241ca982e9ba50266bd3f5bd1ea33f1455554c5abb85d1be0e2d87e" + sha256: "75906bf273541b676716d1ca7627a17e4c4070a3a16272b7a3dc7da3b9f3f6b7" url: "https://pub.dev" source: hosted - version: "1.25.15" + version: "1.26.3" test_api: dependency: transitive description: name: test_api - sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd + sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 url: "https://pub.dev" source: hosted - version: "0.7.4" + version: "0.7.7" test_core: dependency: transitive description: name: test_core - sha256: "84d17c3486c8dfdbe5e12a50c8ae176d15e2a771b96909a9442b40173649ccaa" + sha256: "0cc24b5ff94b38d2ae73e1eb43cc302b77964fbf67abad1e296025b78deb53d0" url: "https://pub.dev" source: hosted - version: "0.6.8" + version: "0.6.12" typed_data: dependency: transitive description: @@ -990,10 +1065,18 @@ packages: dependency: transitive description: name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.2.0" + version_manipulation: + dependency: transitive + description: + name: version_manipulation + sha256: e90782d610bde19765d2808ec06bc8ed9e04640a4dd07d1a3d370728ce9dae7f + url: "https://pub.dev" + source: hosted + version: "0.2.0" vm_service: dependency: transitive description: @@ -1042,6 +1125,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.1" + win32: + dependency: transitive + description: + name: win32 + sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e + url: "https://pub.dev" + source: hosted + version: "5.15.0" + win32_registry: + dependency: transitive + description: + name: win32_registry + sha256: "6f1b564492d0147b330dd794fee8f512cec4977957f310f9951b5f9d83618dae" + url: "https://pub.dev" + source: hosted + version: "2.1.0" yaml: dependency: transitive description: @@ -1075,5 +1174,5 @@ packages: source: hosted version: "1.1.4+10" sdks: - dart: ">=3.7.0 <4.0.0" - flutter: ">=3.27.1" + dart: ">=3.9.0 <4.0.0" + flutter: ">=3.32.0" diff --git a/pubspec.yaml b/pubspec.yaml index 5add65d..ddf23a3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ issue_tracker: https://github.com/offich/shirley/issues # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 0.0.1 +version: 0.1.0 environment: sdk: ^3.6.0 @@ -33,14 +33,14 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: 1.0.8 - devtools_app_shared: 0.3.1 - devtools_extensions: 0.3.1 - syntax_highlight: 0.4.0 - flutter_hooks: 0.21.2 - code_builder: 4.10.1 - dart_style: 3.0.1 - json_dynamic_widget: 9.0.0+3 + cupertino_icons: 1.0.9 + devtools_app_shared: 0.5.0 + devtools_extensions: 0.5.0 + syntax_highlight: 0.5.0 + flutter_hooks: 0.21.3+1 + code_builder: 4.11.1 + dart_style: 3.1.3 + json_dynamic_widget: 12.0.0+9 flutter_colorpicker: 1.1.0 dev_dependencies: @@ -52,8 +52,9 @@ dev_dependencies: # activated in the `analysis_options.yaml` file located at the root of your # package. See that file for information about deactivating specific lint # rules and activating additional ones. - flutter_lints: 5.0.0 - pana: 0.22.19 + flutter_lints: 6.0.0 + pana: 0.23.11 + cider: 0.2.10 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec