Web Scratch
フィード

launchd-ui: macOSのlaunchdを使ったcron処理をGUIで管理するアプリを作った
Web Scratch
macOSのlaunchdエージェント・デーモンをGUIで管理できるアプリ launchd-ui を作りました。GitHub: azu/launchd-uiなぜ作ったかmacOSでcron的な定期処理をやろうとすると、launchdを使うことになります。自分の場合は、git pullを定期的に実行してリポジトリを同期する仕組みや、claude --remoteでClaude Codeを起動してスクリプトを実行する処理をlaunchdで管理しています。たとえば、chronixdで収集したアクティビティデータを元に、寝る前にclaude --remoteでその日の活動をまとめる処理を自動実行しています。Claude Code on the webで実行することで、自動で処理が走りつつ、気になったことがあればスマホからでも対話的に追記できます。こういった定期処理をlaunchdで管理しているのですが、launchdの操作は基本的にCLIです。launchctl loadやlaunchctl unloadといったコマンドを毎回調べながら打つのは面倒で、今どのエージェントが動いているか、次回いつ実行されるかといった情報も確認しにくいです。GUIツールはLaunchControlなどの有料ツールが多く、探すのも面倒だったので自分で作ることにしました。主な機能launchd-uiには次の機能があります。ユーザーエージェント(~/Library/LaunchAgents/)、システムエージェント、システムデーモンの一覧と検索エージェントの開始・停止・再起動・即時実行(テストラン)スケジュール設定と次回実行日時のプレビューstdout/stderrログの表示plistファイルの詳細表示ユーザーエージェントの作成・編集・削除Finderでファイルを表示システムエージェントとデーモンは読み取り専用で、変更操作はユーザーエージェントのみに限定しています。技術スタックlaunchd-uiはTauriで作っています。バックエンドがRust、フロントエンドがReact + TypeScript + Viteという構成です。UIにはTailwind CSS v4とshadcn/uiを使っています。Tauriを選んだ理由は主に2つあります。1つ目は、launchdの操作にはlaunchctlコマンド
13時間前

mubook-hon v2: EPUBビューアーをfoliate-jsに移行、Cloudflare Workersへ移行
Web Scratch
mubook-honは、Dropboxに保存したEPUB/PDFファイルをブラウザで読めるウェブアプリです。Notionと連携して、読書メモや進捗をNotionに記録できます。mubook-hon: https://mubook-hon.jser.workers.dev/GitHub: https://github.com/azu/mubook-honURLが https://mubook-hon.vercel.app/ から https://mubook-hon.jser.workers.dev/ に変更されました。前回の記事から約2年半が経ち、大きな変更をしたので紹介します。mubook-hon: Dropboxに保存したepubやPDFを読むビューア、Notionにメモや読んでいる位置を記録できるMobile/PC対応のウェブアプリ | Web ScratchEPUBビューアーをBibiからfoliate-jsに移行EPUBの表示エンジンをBibiからfoliate-jsに移行しました。feat: replace Bibi with foliate-js for EPUB viewer by azu · Pull Request #28foliate-jsはFoliateというLinux向けの電子書籍リーダーのJavaScript実装です。Web Componentベースで実装されており、カスタマイズ性の高い点が特徴です。Bibiと比較して、次の点が改善されました。初期化の高速化 - インクリメンタルパースにより、EPUBファイルの読み込みが高速化メモリ消費の削減 - メモリ管理の改善により、メモリ使用量が減少仕組みの簡素化 - Bibiの時はMSWでService Workerプロキシを実装してBibiの求める形式/URLのパスで返す必要があり複雑だった。foliate-jsではこの回り道が不要になりシンプルに9ゾーンタップ設定画面を3x3の9ゾーンに分割し、各ゾーンにアクションを割り当てられるようになりました。feat: add customizable 9-zone tap settings for EPUB viewer by azu · Pull Request #32設定画面から、各ゾーンに「次ページ」「前ページ」「メニュー」「閉じる」「なし」を割
2ヶ月前

オープンソース活動の振り返り/GitHub Sponsorsの収入まとめ @ 2025
Web Scratch
2025年のオープンソース活動の振り返りとGitHub Sponsorsでの収入をまとめた記事です。今年はtextlintとJSer.infoにMCPサーバーを実装しました。また、JavaScript PrimerをES2025に対応し、secretlintに新しい検出ルールを追加しました。AI連携とECMAScript最新仕様への対応が中心の年でした。TSKaigi 2025とYAPC::Fukuoka 2025では、継続的なメンテナンスについて発表しました。サプライチェーン攻撃対策についてはZennに記事をまとめました。npmパッケージ/GitHub Actionsを利用する側/公開する側でサプライチェーン攻撃を防ぐためにやることメモ今までの振り返り2014年: https://efcl.info/2014/12/31/oss-in-2014/2015年: https://efcl.info/2015/12/31/oss-in-2015/2016年: https://efcl.info/2016/12/31/oss-in-2016/2017年: https://efcl.info/2017/12/30/oss-in-2017/2018年: https://efcl.info/2018/12/31/oss-in-2018/2019年: https://efcl.info/2019/12/31/oss-in-2019/2020年: https://efcl.info/2020/12/31/open-source-in-2020/2021年: https://efcl.info/2021/12/31/open-source-in-2021/2022年: https://efcl.info/2022/12/31/open-source-in-2022/2023年: https://efcl.info/2023/12/31/open-source-in-2023/2024年: https://efcl.info/2024/12/31/open-source-in-2024/オープンソース活動の種類自分のオープンソース活動の種類として、次のようなものがあります。ソフトウェア開発: textlint、Secretlint、HonKitなどの開発やメンテナンスウェブサービス開発
2ヶ月前

YAPC::Fukuoka 2025で「読む技術・書く技術・伝える技術 - 15年続けて分かった持続可能なオープンソース開発」という発表をしました
Web Scratch
YAPC::Fukuoka 2025で「読む技術・書く技術・伝える技術 - 15年続けて分かった持続可能なオープンソース開発」というタイトルで発表をしました。スライドは次のページで公開しています。スライド: 読む技術・書く技術・伝える技術 - 15年続けて分かった持続可能なオープンソース開発Proposal: https://fortee.jp/yapc-fukuoka-2025/proposal/64dbeabc-a630-4564-97ff-812106e7be81発表内容この発表では、15年間のオープンソース活動から学んだ持続可能な開発のための3つのプロジェクトについて話しています。読む技術 - JSer.infoJSer.infoは2011年から続けている週刊のJavaScript情報ブログで、これまでに750記事以上を公開しています。「整理されたデータである『情報』を伝えること」をテーマに、14年間続けてきた情報収集システムやワークフローについて紹介しています。関連記事:JSer.info 10周年: JavaScript情報の集め方、書き方、まとめ方 - JSer.infoJSer.info 6周年記念イベントを開催しました - JSer.infoJavaScript情報ってなんだっけ?書く技術 - textlinttextlintは、自然言語のLintツールで、2014年から開発を続けています。現在では200以上のルールを持つエコシステムになっており、AI時代における文章品質の自動化についても触れています。関連記事:Maintainer Month: なぜtextlintを作ったか | Web ScratchJavaScriptでルールを書けるテキスト/Markdownの校正ツール textlint を作った | Web Scratch伝える技術 - JavaScript PrimerJavaScript Primerは、2016年から開発を続けているJavaScriptの入門書です。「変化に対応できること」をテーマに、最初からLiving Standard戦略や長期的な運用を目的として設計されました。100人以上のコントリビューターが参加しており、どのように継続的なメンテナンスとコミュニティの参加を実現しているかについて話しています。関連記事:Jav
3ヶ月前

ni.zsh v1.8.0リリース: Socket Firewallによるパッケージインストール時のチェック機能を追加
Web Scratch
npm/yarn/pnpm/bunを同じコマンドで扱えるni.zshのv1.8.0をリリースしました。Release v1.8.0 · azu/ni.zshこのバージョンでは、Socket Firewallを統合し、パッケージのインストールと実行時にサプライチェーン攻撃から保護する機能を追加しました。ni.zshについては、次の記事を参照してください。npm/yarn/pnpm/bunを同じコマンドで扱える ni のzsh実装を書いた | Web Scratchni.zsh: npmインストール時のサプライチェーン攻撃を検知する機能を追加 | Web Scratchni.zsh v1.8.0の変更点主要な変更点は次の通りです。詳細はリリースノートを参照してください。Release v1.8.0 · azu/ni.zsh🛡️ Socket Firewallの統合Socket Firewallを統合し、パッケージのインストール時にセキュリティスキャンを行えるようになりました。Socket Firewallは、HTTPプロキシとしてパッケージマネージャのネットワーク通信をインターセプトし、悪意のあるパッケージがダウンロードされる前にブロックするツールです。従来のni.zshでは、Socket.dev APIを使ってリスクスコアを取得し、インストール前に確認を求める仕組みでした。Socket Firewallも基本的には同じで、自動的にインストール時にマルウェアならブロックし、潜在的なマルウェアは警告を表示します。詳しくは次の記事を参照してください。Introducing Socket Firewall: Free, Proactive Protection for Your Software Supply Chainセットアップ方法Socket Firewallの機能を使用するには、次の手順でセットアップします。Socket Firewallをグローバルにインストールnpm i -g sfw.zshrc に環境変数を追加export NI_USE_SOCKET_FIREWALL=1設定後、次のコマンドでSocket Firewallによる保護が有効になります。保護対象のコマンド次のコマンドでSocket Firewallによる保護が有効になります。ni / ni add...
4ヶ月前

npm Trusted PublishingでOIDCを使ってトークンレスでCIからnpmパッケージを公開する
Web Scratch
npm Trusted Publishingが2025年7月31日に一般公開されました。これにより、OpenID Connect (OIDC)を使ってnpmトークンなしでCI/CDからnpmパッケージを公開できるようになりました。npm trusted publishing with OIDC is generally availableTrusted publishing for npm packages | npm Docsこの記事では、npm Trusted Publishingの仕組みや設定方法、実際のリリースフローについて紹介します。npm Trusted Publishingとはnpm Trusted Publishingは、npmレジストリとCI/CD環境(GitHub ActionsやGitLab CI/CD)の間でOIDCベースの信頼関係を確立する仕組みです。これにより、npmトークンを使わずにパッケージを公開できます。これまでのCIからnpmパッケージを公開する際には、長期間有効なnpmトークンをCI/CDの環境変数(Secrets)に保存する必要がありました。しかし、このアプローチにはいくつかのセキュリティリスクがあります。npmトークンがCIのログや設定ファイルに誤って露出する可能性トークンが侵害された場合、無効化するまで悪用される可能性トークンの手動ローテーションが必要必要以上に広い権限を持つことが多いgranular access tokens で scope を制限できるが、monorepo では設定/維持が難しく org 単位になりがちnpm Trusted Publishingは、これらの問題を解決します。短時間だけ有効で、かつ特定ワークフローに限定された署名付きトークンを使うため、流出しても再利用されにくい構造になっています。対応CI/CD環境現在、npm Trusted Publishingは次のCI/CD環境をサポートしています。GitHub Actions(GitHub-hosted runners)GitLab CI/CD(GitLab.com shared runners)設定方法npm Trusted Publishingの設定は大きく2つのステップで構成されます。1. npmjs.comでTrusted Publis
5ヶ月前

JavaScript Primer v7.0.0リリース: ES2025対応とIterator Helpersの新章追加
Web Scratch
JavaScript Primer v7.0.0をリリースしました 🎉リリースノート: Release v7.0.0: ECMAScript 2025サポート、イテレータとジェネレータ · asciidwango/js-primerJavaScript Primer v7.0.0では、ECMAScript 2025への対応と、新しく「イテレータとジェネレータ」の章を追加しています。Iterator Helpersをはじめとした、ES2025の新機能を学ぶことができます。NotebookLMもES2025対応版に更新しています。NotebookLM: https://notebooklm.google.com/notebook/295f7def-145e-4393-9e06-afb4e6e23781JavaScript Primer SponsorsJavaScript Primer(jsprimer)では、Open Collectiveを通じてプロジェクトの更新に関わる資金を募っています。JavaScript Primer - Open Collective今回のv7リリースにおいては、次の方々にご支援いただきました!Gold SponsorsSupportersご支援ありがとうございます!JavaScript Primerスポンサーについては、次のページを参照してください。JavaScript Primerスポンサー · JavaScript Primer #jsprimerまた、ご支援いただいた資金は、jsprimerにcontributionしてくれた方へ還元できるような仕組みを引き続き運用しています。今回から同じ金額を他のCollective(オープンソースプロジェクト)に寄付する仕組みも追加しました。 Contributorが受け取る代わりに、指定されたCollectiveへ同じ金額を寄付できます。Contributing Expenses PolicyJavaScript Primer v7.0.0の変更点JavaScript Primer v7.0.0の変更点について紹介します。リリースノートは次のページからも確認できます。Release v7.0.0: ES2025の対応/Iterator Helpersの新章追加 · asciidwango/js...
6ヶ月前

AI Agentのコマンド実行にTouch IDを使った「人間の確認」を挟むCLIツール confirm-pam を作った
Web Scratch
macOS で Touch ID を使った「人間の確認」ができるシンプルな CLI ツール confirm-pam を作りました。azu/confirm-pam: CLI tool for biometric authentication confirmation promptsこのツールを使うことで、AI Agent が任意のコマンドやスクリプトの実行する前に、Touch ID による生体認証を要求できます。コマンドラインから実行される処理に対して、人間による明示的な確認ステップを追加する仕組みを提供します。confirm-pam とはconfirm-pam は、macOS の Touch ID を使った生体認証による確認プロンプトを提供する CLI ツールです。主な特徴Touch ID 認証をサポート認証ダイアログに任意のメッセージを表示0(成功)、1(失敗)、2(エラー)の 3 つの終了コードで結果を判定Rust で書かれていて、現時点だと macOS のみ対応基本的な使い方は次のようになります。# 基本的な認証プロンプトconfirm-pam "この操作を実行しますか?"# 認証成功時の終了コードは0echo $? # 0# 認証失敗時やキャンセル時の終了コードは1# Touch IDの認証を失敗またはキャンセルした場合echo $? # 1インストール方法confirm-pam はcrates.ioで公開されているため、cargo でインストールできます。cargo install confirm-pamまた、GitHub からソースコードをクローンしてビルドできます。git clone https://github.com/azu/confirm-pam.gitcd confirm-pamcargo build --release必要な環境macOS 10.12.2 以降Touch ID 対応デバイスTouch ID がシステム環境設定で有効化されていること基本的な使い方confirm-pam は非常にシンプルな API を提供しています。confirm-pam [メッセージ]メッセージを指定すると、Touch ID の認証ダイアログにそのメッセージが表示されます。# 渡したメッセージが認証ダイアログに表示されますconfirm-pam "重要な変更をコ
7ヶ月前

textlint v15.0.0をリリースしました。非推奨APIの削除とNode.js 20+サポート/MCPサーバの改善
Web Scratch
textlint v15.0.0をリリースしました!Release v15.0.0 · textlint/textlinttextlint v15.0.0 | textlinttextlint v15は、v12.3.0から非推奨としてマークされていた古いAPIをすべて削除するメジャーリリースです。textlint v15.0.0の変更点主要な変更点は次の通りです。Breaking ChangesNode.js 20+のサポート(Node.js 16,18はサポート終了TextLintEngineを削除 → createLinter()TextFixEngineを削除 → createLinter()TextLintCoreを削除 → createLinter()または@textlint/kerneltextlint(シングルトンインスタンス)を削除 → createLinter()createFormatterを削除 → loadFormatter()をNode.js 20以上が必要textlint v15では、Node.js 20.0.0以上が必要になりました。Nodejs 18はEOL(End of Life)となっているため、Node.js 20以上を使用する必要があります。https://nodejs.org/en/about/previous-releases非推奨APIの削除textlintパッケージをNode.jsモジュールとして利用する場合のみ影響を受ける変更です。textlint v15では、非推奨となっていた次のAPIが完全に削除されました。移行ガイドは次のページに用意しています。Migration Guide to textlint v15 | textlintTextLintEngine → createLinter()変更前(v14以前):const { TextLintEngine } = require("textlint");const engine = new TextLintEngine({ configFile: ".textlintrc.json"});const results = await engine.executeOnFiles(["*.md"]);const output = engine.formatResult
8ヶ月前

Secretlint v10.0.0リリース: デフォルトでシークレットをマスク表示するように変更、Node.js 20+のサポート
Web Scratch
機密情報を検出するSecretlintのv10.0.0をリリースしました!Release v10.0.0 · secretlint/secretlintこのバージョンでは、デフォルトでLintの結果のシークレットをマスクして表示するように変更されました。Secretlint v10.0.0の変更点主要な変更点は次の通りです。詳細はリリースノートを参照してください。Release v10.0.0 · secretlint/secretlint🛡️ シークレットのマスク表示がデフォルトに最も大きな変更は、見つけたシークレットをデフォルトでマスクして表示するようになったことです。変更前:✖ found credential: github_token GITHUB_TOKEN=ghp_1234567890abcdef1234567890abcdef12345678変更後(v10.0.0):✖ found credential: github_token GITHUB_TOKEN=*******************************************実際のシークレット値を確認したい場合デバッグなどで実際のシークレット値を確認したい場合は、--no-maskSecrets オプションが使用できます。# デフォルト(マスク表示)$ secretlint "**/*"~/secretlint/secretlint/examples/cli/credential 1:0 error [AWSSecretAccessKey] found AWS Secret Access Key: **************************************** @secretlint/secretlint-rule-preset-recommend > @secretlint/secretlint-rule-aws✖ 1 problems (1 errors, 0 warnings)# 実際のシークレット値を表示$ secretlint --no-maskSecrets "**/*"~/secretlint/secretlint/examples/cli/credential 1:0 error [AWSSecretAccessKey] found AWS Sec...
8ヶ月前