Skip to content

Release v1.100.1 - #1310

Merged
hitalin merged 11 commits into
mainfrom
develop
Nov 2, 2026
Merged

hitalin merged 11 commits into
mainfrom
develop

Conversation

@hitalin

@hitalin hitalin commented Nov 2, 2026

Copy link
Copy Markdown
Collaborator

変更

中身

Closes #1301
Closes #1306
Closes #1308

🤖 Generated with Claude Code

hitalin and others added 11 commits November 2, 2026 00:48
…ント文脈に束ねる (#1301)

プラグインのアカウント文脈は install 単位の 1 スロットで、handler から
detach したコールバック (Async:timeout / Async:interval) は直列化の外で
走っていた。別の handler の実行中に発火すると、そのとき立っている別の
アカウントを拾って Mk:api / Nd:call が通る。

- 起動時にルートスコープの Async:timeout / Async:interval を、呼んだ時点の
  ctx.accountId を閉じ込めた版に差し替える。コールバックの発火は
  withPluginAccountContext に乗せ、仕込んだ handler のアカウントで走る。
  文脈の外 (top-level) で仕込んだものは null = fail-closed のまま
- interpreter は env より std を優先するため、env ではなく exec 前の
  スコープ組み直しで差し替える。timer の管理 (abort / pause / stopper) は
  std の実装に任せる
- interval の tick は、別の handler が長く走っている間に積み上がって
  連発しないよう、待ち 1 つで次を捨てる
- 直列化キューは残す。interpreter に実行ごとの文脈を渡す口が無く、
  スロットの排他はキューでしか保証できない (理由をコメントに記載)
- 「handler queued behind a running handler」の警告は、tick が handler の
  後ろに並ぶのが通常動作になったため外した

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…らせる (#1306)

アプリ側から入る handler の実行 3 経路は直列化の外で interp.execFn /
execFnSimple を呼び、同じアカウントのスロットを読んでいた。別の handler が
Mk:api を await している最中に発火すると、その handler のアカウントで
Mk:api / Nd:call が通る (#1301 と同じ構造、起点が timer ではなくアプリ側)。

- NoteDeckEnvContext に runWithAccount を足し、プラグインだけが
  withPluginAccountContext を渡す。widget / Play / Page はアカウント固定の
  クロージャなので未指定のまま (そのまま走る)
- Nd:on は payload の accountId (カラム / ストリーミング / ノート / 通知) を
  渡し、無いイベント (メモ / skill / テーマ) は null = fail-closed
- コマンドパレットの実行は null で包む (パレットにアカウントの文脈は無い、#941)
- capability の実行は capCtx.accountId で包む。呼び出し元の積み下ろしは
  キューで待っている間ではなく実際に走るときに行う
- handler の中から Nd:call で自分の capability を呼んだ形 (呼び出し元の連鎖に
  自分が居る) はその handler の実行の一部なので、キューに乗せず inline で
  走らせる (乗せると自分の完了を待って止まる)
- #1099 のテストは capability の実行を外側から withPluginAccountContext で
  包んでいた (本番にその経路は無い) ので、capCtx.accountId を渡す形に直した

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
withPluginAccountContext は run を同期的に始めてからキューへ登録していた。
最初の await より前に同じプラグインへ入れ子で呼ぶと、内側が登録前の
キューを見て素通りし、外側のスロットを上書きしていた (本番の経路は
aiscript の評価で必ず await を挟むので到達しないが、構造の穴として塞ぐ)。
run は必ず microtask に送り、登録を先に行う。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… は走らせない

CodeRabbit の指摘 2 件 (PR #1307)。どちらも「停止 / 解除の直前に発火した
1 件が、別の handler の完了後に遅れて走る」で、文脈は正しいアカウントのまま。

- Async:interval / Async:timeout の stopper を包み、呼ばれたら積み済みの
  発火も止める。std の Async:* は async な native で stopper を Promise で
  返すので、その形のまま包む (同期で返ると見ていた以前の読みは誤り)
- Nd:on は購読ごとに active を持ち、解除 (AiScript 側の関数 / プラグイン停止)
  で下げる。キューで待っていた分は実行時に確認して走らせない
- 回帰テスト 2 本。slow な handler が実際に走ったことも確かめ、パースに
  失敗して空振りで通らないようにした

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…-per-run

fix(plugin): プラグインのアカウント文脈を実行に束ね、別の handler のアカウントを拾わないようにする (#1301 / #1306)
…y・referer を揃える (#1308)

Nd:http (http.fetch) と export の client は redirect を Policy::limited で追い、
各 hop の検査を名前解決の resolver に任せていた。IP literal の飛び先
(Location: http://127.0.0.1/...) は名前解決を経ないので検査されず、外部の
サーバーが 302 で loopback / private / link-local の IP literal に飛ばせば
手元の口に届いていた。ssrf.rs の external_redirect_policy (共有 client と
Android worker が使用) をこの 2 つの client にも適用する。

- http_fetch / export: redirect を external_redirect_policy にし、各 hop の
  host と port を一次検査と同じ規則で検査する
- http_fetch: 最初の URL のポートも check_port_safe で検査する
- 両 client に no_proxy() (プロキシ経由だと名前解決の検査が効かない) と
  referer(false) (query を含む URL を飛び先に漏らさない) を付ける
- SECURITY.md / ROADMAP.md: 「localhost:19820 を明示 deny」は事実と違った
  (loopback 全体の deny で止まっているだけ) ので実装に合わせて直す

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…の回帰テストを足す

CodeRabbit の指摘 2 件 (PR #1309): no_proxy() と redirect 先のポート検査に
テストが無く、外しても全テストが通っていた。

- `ssrf::external_fetch_builder()` に redirect 方針 / DNS pinning / no_proxy /
  referer なしをまとめ、http_fetch と export の client はそれに timeout を足す
  だけにする (同じ 4 設定の重複を解消)
- プロキシの検証は環境変数がプロセス全体で共有されるため、単体テストに置くと
  並列の他のテスト (ssrf の redirect のテストはプロキシ無効化なしで通信する)
  と干渉する。独立した integration test (tests/outbound_proxy.rs、1 ファイル =
  1 プロセス) に置き、no_proxy() を外すと落ちることを確認済み
- redirect 先の危険ポート (公開名 + SMTP のポート) を名前解決も通信もせずに
  拒むテストを external_redirect_policy に足す (http と export の両方を覆う)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… URL にも効かせる

CodeRabbit のフォローアップ (PR #1309): export の download_one は添付の URL に
validate_external_url だけを掛けていて、http_fetch に足した check_port_safe が
効いていなかった。redirect の各 hop は共有の方針で host とポートの両方を見るのに、
最初の URL だけ 2 経路で規則がずれていた。

- validate_external_url に check_port_safe を入れ、呼び出し元 2 つ (http_fetch /
  export) の最初の URL が同じ規則で検査されるようにする
- http_fetch 側の重複した検査を外す (既存のテストは一次検査経由で通る)
- validate_external_url が禁止ポートを Err にするテストを足す

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
fix(http): 外向き fetch の redirect で IP literal の飛び先も検査し、port 検査・no_proxy・referer を揃える (#1308)
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Deploying notedeck with  Cloudflare Pages  Cloudflare Pages

Latest commit: 124c34f
Status: ✅  Deploy successful!
Preview URL: https://af557977.notedeck-d3a.pages.dev
Branch Preview URL: https://develop.notedeck-d3a.pages.dev

View logs

@coderabbitai

coderabbitai Bot commented Nov 2, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 4 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
Commits

Reviewing files that changed from the base of the PR and between d8e1039 and 124c34f.

Files ignored due to path filters: 2
  • Cargo.lock is excluded by !**/*.lock
  • src-tauri/openapi.json is excluded by !src-tauri/openapi.json
Files selected for processing: 15
  • ROADMAP.md
  • SECURITY.md
  • crates/notecore/src/commands/http.rs
  • crates/notecore/src/export_service.rs
  • crates/notecore/src/ssrf.rs
  • crates/notecore/tests/outbound_proxy.rs
  • crates/notemaid/Cargo.toml
  • package.json
  • src-tauri/Cargo.toml
  • src-tauri/tauri.conf.json
  • src/aiscript/notedeck-api.test.ts
  • src/aiscript/notedeck-api.ts
  • src/aiscript/plugin-api.test.ts
  • src/aiscript/plugin-api.ts
  • src/aiscript/sandbox.ts
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@github-actions github-actions Bot added 📖Doc Documentation related issue/PR rust Pull requests that update rust code javascript Pull requests that update javascript code labels Nov 2, 2026
@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown

API surface diff

外部アプリ向け API 面 (src-tauri/openapi.json / src/bindings.ts) が変更されています。
互換性への影響 (#709) をレビューしてください。

src-tauri/openapi.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Full diff
diff --git a/src-tauri/openapi.json b/src-tauri/openapi.json
index 5eacf20..36717ff 100644
--- a/src-tauri/openapi.json
+++ b/src-tauri/openapi.json
@@ -6,7 +6,7 @@
     "license": {
       "name": "MIT"
     },
-    "version": "1.100.0"
+    "version": "1.100.1"
   },
   "paths": {
     "/api": {

@hitalin hitalin self-assigned this Nov 2, 2026
@claude

claude Bot commented Nov 2, 2026

Copy link
Copy Markdown

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

@hitalin
hitalin merged commit 3dec14d into main Nov 2, 2026
31 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment