From 790aceb71492aa9def8074ca89f3004c4c3e8bf4 Mon Sep 17 00:00:00 2001 From: YEONGUK LEE Date: Fri, 23 Oct 2026 15:42:22 +0900 Subject: [PATCH] docs: prepare Python skill 0.4.0 for runtime 1.3.0 --- .github/workflows/validate.yml | 2 + README.ja.md | 4 +- README.ko.md | 4 +- README.md | 4 +- README.zh-CN.md | 4 +- docs/usage.ja.md | 19 ++++- docs/usage.ko.md | 19 ++++- docs/usage.md | 19 ++++- docs/usage.zh-CN.md | 19 ++++- scripts/python-coverage.mjs | 72 ++++++++++++++++ scripts/python-coverage.test.mjs | 140 +++++++++++++++++++++++++++++++ scripts/validate-skill.mjs | 9 +- session-peer/SKILL.md | 21 ++++- 13 files changed, 316 insertions(+), 20 deletions(-) create mode 100644 scripts/python-coverage.mjs create mode 100644 scripts/python-coverage.test.mjs diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 45b6cc4..0ee8862 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -21,6 +21,8 @@ jobs: - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: 24 + - name: Test Python coverage and feature version contracts + run: node --test scripts/python-coverage.test.mjs - name: Validate skill metadata and README consistency run: node scripts/validate-skill.mjs - name: Discover the skill diff --git a/README.ja.md b/README.ja.md index 49ad07a..7e7ee62 100644 --- a/README.ja.md +++ b/README.ja.md @@ -16,7 +16,7 @@ ## クイックスタート -基本的な Python CLI コマンドには session-peer 0.9.1 以降が必要です。スキルで案内する Python CLI 機能をすべて使うには session-peer 1.0.1 以降が必要です。オプションのペアリング済みデバイス転送には、Unix 上で Python 3.11 以降と `session-peer[relay]` が必要です。 +基本的な Python CLI コマンドには session-peer 0.9.1 以降が必要です。公開 Python CLI の機能範囲の基準は session-peer 1.3.0 です。オプションのペアリング済みデバイス転送には、Unix 上で Python 3.11 以降と `session-peer[relay]` が必要です。 v1.0.3 のセキュリティ修正を利用するには、Python ランタイム 1.0.3 以降を使用してください。上記の互換バージョンは CLI 機能の条件であり、セキュリティ上の推奨バージョンではありません。 ### インストール @@ -48,6 +48,8 @@ npx -y skills@latest update session-peer --global --yes 別の `session-peer-ts` スキル 0.3.0 のプロファイル(最小ランタイム 0.1.0、機能説明の基準 0.4.0)は、公開済み npm ランタイム 0.4.0 が認識します。基本コマンドも、実際に選択された TypeScript ランタイムのバージョンとヘルプを確認してから使用してください。オプション機能には、プラットフォーム、非公開ストレージ、権限、書き込みプロセスの検査も適用されます。相関 ID、制限付きの待機、運用者が明示的に確認する受領記録については、[オプトイン handoff の限定的な利用ガイド](docs/typescript-handoff.md)を参照してください。キュー登録や入力の注入は自動的な受領確認ではありません。別途承認・公開された内容が固定されたスキルリリースを選び、記録されたソースコミットとコンテンツハッシュを確認してください。ランタイムの公開はスキルの公開やインストールを意味せず、インストールの許可も与えません。エージェント、プロジェクト/グローバルの適用範囲、レビュー済みコミットを指定したインストール手順は [TypeScript 設定ガイド](docs/typescript.md)を参照してください。 +Python 1.3.0 のオプション機能と利用条件は[利用ガイド](docs/usage.ja.md#python-13-の利用手順)を参照してください。 + ## ドキュメント - [TypeScript スキルの導入・バージョン固定による更新・削除](docs/typescript.md) diff --git a/README.ko.md b/README.ko.md index fbb7e1f..d3895ea 100644 --- a/README.ko.md +++ b/README.ko.md @@ -16,7 +16,7 @@ ## 빠른 시작 -기본 Python CLI 명령에는 session-peer 0.9.1 이상이 필요합니다. 스킬에 문서화된 Python CLI 기능 전체를 사용하려면 session-peer 1.0.1 이상이 필요합니다. 페어링 기기 전송은 선택 기능이며, Unix 환경에서 Python 3.11 이상과 `session-peer[relay]`가 필요합니다. +기본 Python CLI 명령에는 session-peer 0.9.1 이상이 필요합니다. 공개 Python CLI 기능 범위의 기준 버전은 session-peer 1.3.0입니다. 페어링 기기 전송은 선택 기능이며, Unix 환경에서 Python 3.11 이상과 `session-peer[relay]`가 필요합니다. v1.0.3 보안 수정을 적용하려면 Python 런타임 1.0.3 이상을 사용합니다. 위 호환 버전은 CLI(명령줄 인터페이스) 기능 지원 기준이며 보안 권장 버전과 별개입니다. ### 설치 @@ -48,6 +48,8 @@ npx -y skills@latest update session-peer --global --yes 별도의 `session-peer-ts` 스킬 0.3.0 프로필(최소 런타임 0.1.0, 기능 안내 기준 0.4.0)은 공개 npm 런타임 0.4.0이 인식합니다. 기본 명령도 실제로 선택된 TypeScript 런타임의 버전과 도움말을 확인한 뒤 사용해야 하며, 선택 기능에는 플랫폼·비공개 저장소·권한·작성자 검사도 적용됩니다. 상관관계 식별자, 제한된 대기, 운영자가 명시적으로 확인하는 수신 확인은 [선택적 handoff 범위 안내](docs/typescript-handoff.md)를 참고하세요. 큐 등록이나 입력 주입은 자동 수신 확인이 아닙니다. 별도로 승인·발행된 불변 스킬 릴리스를 선택하고 기록된 소스 커밋과 콘텐츠 해시를 확인하세요. 런타임 발행은 스킬을 발행하거나 설치하지 않으며 설치 권한도 부여하지 않습니다. 에이전트, 프로젝트 또는 전역 설치 범위, 검토된 커밋을 명시하는 설치 방법은 [TypeScript 설정 안내](docs/typescript.md)를 참고합니다. +Python 1.3.0의 선택 기능과 사용 조건은 [사용 안내](docs/usage.ko.md#python-13-사용-절차)를 참고합니다. + ## 문서 - [TypeScript 스킬 설치·고정 버전 업데이트·삭제](docs/typescript.md) diff --git a/README.md b/README.md index 47929a5..e455f07 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ The runtime demonstration shows Claude Code and Codex messaging; the skill provi ## Quick Start -Basic Python CLI commands require session-peer 0.9.1 or newer; the full set of Python CLI features documented in the skill requires session-peer 1.0.1 or newer. Paired-device transport is optional and needs `session-peer[relay]` on Unix with Python 3.11+. +Basic Python CLI commands require session-peer 0.9.1 or newer. The published Python CLI coverage reference is session-peer 1.3.0. Paired-device transport is optional and needs `session-peer[relay]` on Unix with Python 3.11+. For the v1.0.3 security fixes, use Python runtime 1.0.3 or newer. The compatibility versions above are CLI feature thresholds, not security recommendations. ### Install @@ -48,6 +48,8 @@ A `queued` or `submitted` status does not confirm that the recipient consumed th The separate `session-peer-ts` skill 0.3.0 profile (minimum runtime 0.1.0, feature coverage reference 0.4.0) is recognized by published npm runtime 0.4.0. Basic commands still require the resolved TypeScript runtime’s actual version/help checks; optional features also require their platform, private-storage, permission, and writer guards. See the [limited opt-in handoff guide](docs/typescript-handoff.md) for correlation, bounded waiting, and explicit operator-confirmed receipts; queueing or injection is not an automatic acknowledgment. Select a separately approved, published immutable skill release and verify its recorded source commit and content hash. Runtime publication does not publish, install, or authorize installation of the skill. See the [TypeScript setup guide](docs/typescript.md) for an explicit agent, project/global scope, and reviewed commit installation. +Optional Python 1.3.0 workflows and their requirements are described in the [usage guide](docs/usage.md#python-13-workflows). + ## Docs - [TypeScript skill setup, pinned updates, and removal](docs/typescript.md) diff --git a/README.zh-CN.md b/README.zh-CN.md index 88cd881..7e5d6c0 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -16,7 +16,7 @@ ## 快速开始 -基本 Python CLI 命令需要 session-peer 0.9.1 或更高版本。本技能介绍的全部 Python CLI 功能需要 session-peer 1.0.1 或更高版本。配对设备传输为可选功能,需要 `session-peer[relay]` 附加依赖项(Unix、Python 3.11 或更高版本)。 +基本 Python CLI 命令需要 session-peer 0.9.1 或更高版本。已发布 Python CLI 功能的覆盖基准为 session-peer 1.3.0。配对设备传输为可选功能,需要 `session-peer[relay]` 附加依赖项(Unix、Python 3.11 或更高版本)。 如需获得 v1.0.3 安全修复,请使用 Python 运行时 1.0.3 或更高版本。上述兼容版本是 CLI 功能门槛,并非安全建议版本。 ### 安装 @@ -48,6 +48,8 @@ npx -y skills@latest update session-peer --global --yes 独立的 `session-peer-ts` 技能 0.3.0 配置(最低运行时 0.1.0,功能说明参考版本 0.4.0)由已发布的 npm 运行时 0.4.0 识别。使用基本命令前也须核对实际选用的 TypeScript 运行时版本和帮助信息;可选功能还须通过平台、私有存储、权限和写入进程检查。关联标识符、有限等待以及由操作员明确确认的收件记录,请参阅[需主动启用的有限 handoff 指南](docs/typescript-handoff.md)。排队或注入输入并不代表自动收件确认。请选择经单独批准并已发布的不可变技能版本,核对其记录的源码提交和内容哈希。发布运行时不会发布或安装技能,也不代表获准安装技能。指定智能体、项目/全局适用范围和经审查提交版本的安装步骤,请参阅 [TypeScript 设置指南](docs/typescript.md)。 +Python 1.3.0 的可选功能及使用条件见[使用指南](docs/usage.zh-CN.md#python-13-使用流程)。 + ## 文档 - [TypeScript 技能的安装、固定版本更新与移除](docs/typescript.md) diff --git a/docs/usage.ja.md b/docs/usage.ja.md index 8d3b1fa..bfe1d13 100644 --- a/docs/usage.ja.md +++ b/docs/usage.ja.md @@ -15,6 +15,8 @@ uv、pip、POSIX 向けスタンドアロンインストーラー、およびネ このスキルでは、session-peer 0.9.1 以降で共通して使える基本コマンドを案内します。`--allow-inactive-codex-home` と `--relay-login` は session-peer 1.0.0 以降でのみ使用できます。macOS/Linux の受信側ポリシーで使う `codexBin` と、`attemptId` で接続試行を関連付けた Relay 診断には session-peer 1.0.1 以降が必要です。オプションのペアリング済みデバイス転送には `session-peer[relay]` extra(Unix、Python 3.11 以降)が必要です。 +公開 Python CLI の機能範囲の基準は session-peer 1.3.0 です。 + ## ランタイム 1.0.3 のセキュリティと運用 セキュリティ修正を利用するには、Python ランタイム 1.0.3 以降を使用してください。メタデータの最小・全機能バージョンは CLI の互換性を示し、セキュリティ推奨バージョンではありません。SSH の使用前に [v1.0.3 の接続オプション規則](https://github.com/abruption/session-peer/blob/v1.0.3/docs/cli-reference.md#limits)を確認してください。渡されたオプション全体が SSH 実行前に許可リストで検証されます。`-o` には `KEY=value`、ジャンプ先にはホスト形式を使い、`StrictHostKeyChecking` は `yes`、`ask`、`accept-new` のみ指定してください。SSH URI 形式のジャンプ先、`+` を含むユーザー名、空白区切りの `-o 'Key value'`、コマンドフック、別の設定ファイルや制御用ソケット(control socket)のパス指定、known-hosts ファイルの上書き指定は拒否されます。既存のユーザーまたはシステムの SSH 設定は運用者が信頼する範囲であり、安全な隔離環境(サンドボックス)ではありません。 @@ -33,6 +35,19 @@ Python 1.1.0 以降では、外部メッセージ本文のすべての行を引 1.1.0 で公開された別の[実験的 handoff 手順](https://github.com/abruption/session-peer/blob/v1.1.1/docs/handoff-runtime.md)は、このスキルの基本コマンドと全機能の対象範囲には含まれません。ユーザーの依頼なしに記録用の台帳(ledger)を初期化したり、受領確認の権限を作成したりしないでください。受領 ACK はローカル POSIX Claude の経路で限定的に対応します。Codex と単一宛先の POSIX ソースストリーミング SSH は相関 ID の関連付けのみ対応し、観測・ACK は非対応です。Windows とペアリング済みデバイスの handoff も非対応です。通常のキュー登録、テキストの返信、ターン終了が受領 ACK になるわけではありません。ランタイム 1.1.1 の変更は文書と開発用テストのみで、実行時の動作は変わりません。[リリースノート](https://github.com/abruption/session-peer/blob/v1.1.1/docs/releases/v1.1.1.md)を参照してください。 +## Python 1.3 の利用手順 + +以下のオプション手順には Python ランタイム 1.3.0 以降が必要です。基本 CLI の互換性下限は 0.9.1、公開 CLI の機能範囲の基準は 1.3.0 です。実際に選択されたランタイムのバージョンとコマンドのヘルプで対応を確認し、各機能のプラットフォームと権限の要件も確認します。受信機の `codexBin` 固有の最低バージョン 1.0.1 は維持します。実験的 handoff は `runtime-min-version` と `runtime-full-version` が示すコマンドの対応範囲に含めません。[公開済みランタイムのリリース](https://github.com/abruption/session-peer/releases/tag/v1.3.0)を参照してください。 + +- [送信説明](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#delivery-explanation):通常のメッセージ入力を受け取る `send --dry-run --explain` は、ローカル・SSH・ペアリング済み経路に対応し、テキストのみを出力します。`doctor --explain` は診断時点の状態を説明し、選択した対象の受信準備を判定するものではありません。`handoff status --explain` は保存済みの読み取り専用の根拠を説明します。JSON との組み合わせや、handoff SEND の correlation・ACK・observe・wait との組み合わせは拒否します。説明は既存の結果を再利用し、追加の検査・有効化・送信処理・受領確認の権限は生みません。既存の dry-run のバージョン検査は別です。ペアリング経路の追加情報は既存の検査で対応を確認し、許可リストと 8 KiB の上限を適用します。古い受信機では確認済みのネイティブ情報を維持し、不足する情報は unknown のままにします。プレビューは許可・対象の予約・ACK を与えません。終了コード 0 だけで未送信とは判断できず、unknown や想定外の送信処理も自動再送を許可しません。wake には引き続きユーザーの明示的な依頼が必要です。 +- [経路プリセット](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#route-presets)と別個の[受信者アドレス帳](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#recipient-addressbook-v130)は、macOS・Linux のローカル・SSH Claude・Codex のみを対象とします。項目の管理はユーザーの依頼に基づいて行います。`preset show` は保存済みの経路と revision を読み、`list --preset` は現在のセッションを検索します。実際のプリセット送信には `--to` と `--preset-revision` が必要で、replace/remove は `--expect-revision` を使います。値のハッシュである `dp1` は同じ名前・経路に戻すと同じ値になり、後の変更で展開済みの呼び出しが取り消されることはありません。アドレスの add/reselect 前には、`address resolve` の結果を観測 revision の `as1` とともに確認します。実際の送信には現在の `--address-revision`(`ab1`)と正確な正規対象を示す `--confirm-target` が必要です。reselect/remove は revision を検査し、add/reselect のたびに新しい binding ID を作ります。Claude は `tg1` を維持します。Codex の `aw1` は再検査される writer の観測値であり、世代の識別は未対応で、ストレージ・実行インスタンスの原子的な一貫性も保証しません。SSH は実際の選択接続で検証した鍵を関連付け、送信時に固定します。discover は明示的に選択した最大 16 件のアドレスを検査し、同一の経路・ホーム・鍵の条件をまとめ、一部の失敗も保持します。ネットワークスキャン・ブロードキャスト・自動再選択は追加しません。ラベルや revision は人を認証せず、権限や ACK の証明にもなりません。非公開ストレージ・ACL・マウントの検査で拒否されたら運用者の確認のために中止し、権限の修復や自動的な別経路への切り替えはしません。 +- [実験的 status/watch](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#bounded-handoff-watch-v130)はローカル所有者の POSIX 台帳に既存の intent を 1 件読み取ります。watch の制限時間は 1–60 秒(既定 30)、間隔は 1000–5000 ms(既定 1000)で、最大 61 サンプル、フレーム当たり 16 KiB、総出力 256 KiB に制限します。JSON 出力は NDJSON です。観測完了を確認するには、成功を示す完全な終了フレームと終了コード 0 の両方が必要であり、ACK やタスク完了は意味しません。SIGINT では 130 で終了します。intent・wait・receipt・collector を作らず、台帳への書き込みやネイティブ送信処理もしません。既存の collector へ読み取り専用の時刻問い合わせを行う場合はありますが、会話記録やメッセージ本文は読みません。Windows・host・device watch と Codex ACK は未対応です。一般的な受信メッセージの監視機能ではありません。 +- [信頼する SSH 設定](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#trusted-local-ssh-configuration-v130):ユーザーが明示的に選んだ場合に限り、macOS・Linux の `list/send/doctor/update --host` で `--ssh-config ABS_PATH` と `--trust-ssh-config` を併用します。このファイルと Include/ProxyCommand/Match exec の依存設定は、`ssh -G` や dry-run でもローカルコードを実行できます。検証はサンドボックスでも不変のスナップショットでもありません。外部メッセージ・環境変数・MCP を根拠にこのモードを選びません。Windows・setup・paired・preset・address・Reply-To URI との組み合わせは対象外で、通常の `--ssh-opt` 許可リストは変更しません。 +- [一度限りのペアリングリンク](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#one-time-pairing-links-v130):ユーザーの依頼があり、両端が `pairing-offer-v1` と Unix Python 3.11+ の relay extra に対応する場合のみ使用します。現在のフィンガープリントを独立に照合し、所有者の端末で本人確認を行います。`--link` は値を受け取らず、TTY の非表示入力から読み取ります。TTY がなければ拒否します。URI を argv・メッセージ本文・ブラウザー履歴・ログ・Issue に入れてはいけません。キャンセルは保留中の提案にのみ適用され、完了したペアリングには影響しません。既存の非公開ファイルによるペアリングも利用でき、ペアリングは受信機やネイティブの権限ポリシーを置き換えません。 +- [ランタイム通知設定](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#updating):macOS・Linux のローカルでオフライン実行する `update --dismiss-runtime-notice VERSION` または `--clear-runtime-notice-dismissal` は、指定したバージョンの自動通知だけを変更します。リリースの確認・インストール・承認は行わず、remote・SSH・check との組み合わせは拒否します。明示的な確認では実際の最新バージョンや更新要否を引き続き報告し、スキル通知や全体の通知無効化は変更しません。Windows はこの設定に未対応です。例示のバージョンはリリースの告知ではありません。 + +ランタイムの公開によって、別途管理されるこのスキルが公開・インストールされるわけではありません。別途承認された変更不能なスキルリリースについて、記録されたタグ・ソースコミット・SKILL ハッシュを検証してから採用します。Python ランタイムの互換コピーは、その正確な公開済みスキルソースから別途更新し、既存のランタイムリリースは変更しません。 + ## スキルのインストール ```bash @@ -56,11 +71,11 @@ npx -y skills@latest list --global --json npx -y skills@latest update session-peer --global --yes ``` -特定のリリースに固定して導入する場合は、そのタグを使用します(例: `v0.3.3`)。 +特定のリリースに固定して導入する場合は、そのタグを使用します(例: `v0.4.0`)。 ```bash npx -y skills@latest add \ - https://github.com/abruption/session-peer-skill/tree/v0.3.3/session-peer \ + https://github.com/abruption/session-peer-skill/tree/v0.4.0/session-peer \ --skill session-peer --global \ --agent claude-code --agent codex --agent antigravity \ --copy --yes diff --git a/docs/usage.ko.md b/docs/usage.ko.md index ca3f183..b8c6e00 100644 --- a/docs/usage.ko.md +++ b/docs/usage.ko.md @@ -15,6 +15,8 @@ uv, pip, POSIX 환경의 독립 실행형(standalone) 설치 프로그램, Windo 스킬은 session-peer 0.9.1 이상에서 공통으로 사용할 수 있는 기본 명령을 안내합니다. `--allow-inactive-codex-home`과 `--relay-login`은 session-peer 1.0.0 이상에서만 사용할 수 있습니다. macOS·Linux 수신기 정책의 `codexBin` 기능과 `attemptId`로 이벤트를 연결하는 Relay 진단에는 session-peer 1.0.1 이상이 필요합니다. 선택 기능인 페어링 기기 전송에는 `session-peer[relay]` extra(추가 설치 옵션, Unix·Python 3.11 이상)가 필요합니다. +공개 Python CLI 기능 범위의 기준 버전은 session-peer 1.3.0입니다. + ## 런타임 1.0.3 보안 및 운영 보안 수정을 적용하려면 Python 런타임 1.0.3 이상을 사용합니다. 메타데이터의 최소 버전과 전체 기능 지원 버전은 CLI(명령줄 인터페이스)의 호환 기준이며, 보안 권장 버전과 별개입니다. @@ -37,6 +39,19 @@ Python 1.1.0 이상은 외부 메시지 본문의 모든 줄을 인용하고 발 1.1.0에서 공개된 별도의 [실험적 handoff 절차](https://github.com/abruption/session-peer/blob/v1.1.1/docs/handoff-runtime.md)는 이 스킬의 기본 명령과 전체 기능 범위 기준에 포함되지 않습니다. 사용자 요청 없이 상태 기록용 원장(ledger)을 초기화하거나 수신 확인 권한을 만들지 않습니다. 수신 확인 응답(ACK)은 로컬 POSIX Claude 경로에서 제한적으로 지원합니다. Codex와 단일 목적지 POSIX 소스 스트리밍 SSH는 요청 식별자 연결만 지원하며, 관찰·ACK는 지원하지 않습니다. Windows와 페어링 기기의 handoff도 지원하지 않습니다. 일반 큐 등록, 텍스트 회신, 턴 종료가 수신 확인 ACK로 바뀌는 것은 아닙니다. 런타임 1.1.1은 문서와 개발용 테스트만 변경하며 실행 동작은 바꾸지 않습니다. [릴리스 노트](https://github.com/abruption/session-peer/blob/v1.1.1/docs/releases/v1.1.1.md)를 참고합니다. +## Python 1.3 사용 절차 + +아래 선택 절차에는 Python 런타임 1.3.0 이상이 필요합니다. 기본 CLI 호환성 하한은 0.9.1이며, 공개 CLI 기능 범위 기준은 1.3.0입니다. 실제 선택된 런타임 버전과 명령 도움말의 지원 여부를 확인하고, 각 기능의 플랫폼·권한 요구 사항도 확인합니다. 수신기 `codexBin`의 개별 최소 버전 1.0.1은 유지합니다. 실험적 handoff는 `runtime-min-version`과 `runtime-full-version`이 나타내는 명령 범위에서 제외합니다. [공개 런타임 릴리스](https://github.com/abruption/session-peer/releases/tag/v1.3.0)를 참고합니다. + +- [전송 설명](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#delivery-explanation): 일반 메시지 입력을 받는 `send --dry-run --explain`은 로컬·SSH·페어링 경로를 지원하며 텍스트로만 출력합니다. `doctor --explain`은 진단 시점의 상태를 설명하며 특정 대상의 수신 준비를 판정하지 않습니다. `handoff status --explain`은 저장된 읽기 전용 근거를 설명합니다. JSON 조합과 handoff SEND의 correlation·ACK·observe·wait 조합은 거부됩니다. 설명은 기존 결과를 재사용하며 추가 검사·활성화·제출·수신 확인 권한을 만들지 않습니다. 기존 dry-run 버전 검사는 별개입니다. 페어링 경로의 추가 정보는 기존 검사로 지원 여부를 협의하고 허용 목록과 8 KiB 한도를 적용합니다. 이전 수신기에서는 확인된 네이티브 정보만 유지하고 없는 정보는 unknown으로 남깁니다. 미리보기는 권한·대상 예약·ACK를 부여하지 않습니다. 종료 코드 0만으로 미제출을 단정할 수 없으며, unknown이나 예기치 않은 제출도 자동 재전송을 허용하지 않습니다. wake에는 여전히 사용자의 명시적 요청이 필요합니다. +- [경로 프리셋](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#route-presets)과 별도의 [수신자 주소록](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#recipient-addressbook-v130)은 macOS·Linux의 로컬·SSH Claude·Codex만 지원합니다. 항목 관리는 사용자 요청에 따라 수행합니다. `preset show`는 저장된 경로와 revision을 읽고, `list --preset`은 현재 세션을 검색합니다. 실제 프리셋 전송에는 `--to`와 `--preset-revision`이 필요하며 replace/remove는 `--expect-revision`을 사용합니다. 값의 해시인 `dp1`은 같은 이름·경로를 복원하면 같은 값이 되며, 이후 변경으로 이미 경로를 해석한 호출이 취소되지는 않습니다. 주소를 add/reselect하기 전에는 `address resolve` 결과와 관측 revision인 `as1`을 검토합니다. 실제 전송에는 현재 `--address-revision`(`ab1`)과 정확한 정규 대상인 `--confirm-target`이 필요합니다. reselect/remove는 revision을 검사하고, add/reselect할 때마다 새 binding ID를 만듭니다. Claude는 `tg1`을 유지합니다. Codex의 `aw1`은 다시 검사하는 writer 관측값이며, 세대 구분은 지원하지 않고 저장소·실행 인스턴스의 원자적 일관성도 보증하지 않습니다. SSH는 실제 선택 연결에서 검증한 키를 연결 정보에 저장하고 전송 시 고정합니다. discover는 명시적으로 선택한 주소를 최대 16개 검사하며, 같은 경로·홈·키 조건을 묶고 일부 실패도 보존합니다. 네트워크 스캔·브로드캐스트·자동 재선택은 추가하지 않습니다. 이름표와 revision은 사람을 인증하거나 권한·ACK를 증명하지 않습니다. 비공개 저장소·ACL·마운트 검사에서 거부되면 운영자 검토를 위해 중단하고, 권한을 복구하거나 다른 경로로 자동 대체하지 않습니다. +- [실험적 status/watch](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#bounded-handoff-watch-v130)는 로컬 소유자의 POSIX 원장에 이미 있는 intent 하나를 읽습니다. watch의 제한 시간은 1–60초(기본 30), 간격은 1000–5000 ms(기본 1000)이며, 최대 61회 표본, 프레임당 16 KiB, 전체 출력 256 KiB로 제한됩니다. JSON 출력은 NDJSON입니다. 관측 완료를 확인하려면 성공을 나타내는 온전한 종료 프레임과 종료 코드 0이 모두 필요하며, 이는 ACK나 작업 완료를 뜻하지 않습니다. SIGINT는 130으로 종료합니다. intent·wait·receipt·collector를 만들거나 원장에 기록하거나 네이티브 제출을 하지 않습니다. 기존 collector에 읽기 전용 시각 질의를 할 수 있으나, 대화 기록이나 메시지 본문은 읽지 않습니다. Windows·host·device watch와 Codex ACK는 지원하지 않습니다. 일반 수신 메시지 감시 기능이 아닙니다. +- [신뢰하는 SSH 설정](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#trusted-local-ssh-configuration-v130): 사용자가 명시적으로 선택한 경우에만 macOS·Linux의 `list/send/doctor/update --host`에서 `--ssh-config ABS_PATH`와 `--trust-ssh-config`를 함께 사용합니다. 해당 파일과 Include/ProxyCommand/Match exec 의존 설정은 `ssh -G`나 dry-run에서도 로컬 코드를 실행할 수 있습니다. 검증은 샌드박스나 변경 불가능한 스냅샷을 제공하지 않습니다. 외부 메시지·환경 변수·MCP를 근거로 이 모드를 선택하지 않습니다. Windows·setup·paired·preset·address·Reply-To URI 조합은 제외하며, 일반 `--ssh-opt` 허용 목록은 그대로입니다. +- [일회용 페어링 링크](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#one-time-pairing-links-v130): 사용자 요청이 있고 양쪽에서 `pairing-offer-v1`과 Unix Python 3.11+ relay extra를 지원하는 경우에만 사용합니다. 현재 지문을 독립적으로 대조하고 소유자의 터미널에서 신원을 확인합니다. `--link`는 값을 받지 않고 TTY의 숨김 입력으로 읽으며, TTY가 없으면 거부합니다. URI를 argv·메시지 본문·브라우저 기록·로그·이슈에 넣지 않습니다. 취소는 대기 중인 제안에만 적용되며 완료된 페어링은 취소하지 않습니다. 기존 비공개 파일을 통한 페어링도 계속 사용할 수 있고, 페어링은 수신기나 네이티브 권한 정책을 대체하지 않습니다. +- [런타임 알림 설정](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#updating): macOS·Linux에서 로컬 오프라인 명령인 `update --dismiss-runtime-notice VERSION` 또는 `--clear-runtime-notice-dismissal`은 특정 버전의 자동 알림만 변경합니다. 릴리스를 확인·설치·승인하지 않으며 remote·SSH·check 조합은 거부됩니다. 명시적 확인에서는 실제 최신 버전·구버전 여부를 계속 보고하며, 스킬 알림과 전역 알림 끄기는 그대로입니다. Windows는 이 설정을 지원하지 않습니다. 예시 버전은 릴리스 발표가 아닙니다. + +런타임 공개로 별도 관리되는 이 스킬이 발행되거나 설치되지는 않습니다. 별도로 승인된 변경 불가능한 스킬 릴리스의 기록된 태그·소스 커밋·SKILL 해시를 검증한 뒤에만 채택합니다. Python 런타임의 호환 사본은 그 정확한 공개 스킬 소스에서 별도로 갱신하며, 기존 런타임 릴리스는 변경하지 않습니다. + ## 스킬 설치 ```bash @@ -60,11 +75,11 @@ npx -y skills@latest list --global --json npx -y skills@latest update session-peer --global --yes ``` -특정 릴리스로 버전을 고정하여 설치하려면 해당 태그를 사용합니다(예: `v0.3.3`). +특정 릴리스로 버전을 고정하여 설치하려면 해당 태그를 사용합니다(예: `v0.4.0`). ```bash npx -y skills@latest add \ - https://github.com/abruption/session-peer-skill/tree/v0.3.3/session-peer \ + https://github.com/abruption/session-peer-skill/tree/v0.4.0/session-peer \ --skill session-peer --global \ --agent claude-code --agent codex --agent antigravity \ --copy --yes diff --git a/docs/usage.md b/docs/usage.md index 53ddeca..950797c 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -15,6 +15,8 @@ See the [session-peer installation options](https://github.com/abruption/session The skill documents basic commands shared by session-peer 0.9.1 and newer. `--allow-inactive-codex-home` and `--relay-login` require session-peer 1.0.0 or newer. macOS/Linux receiver policy `codexBin` and Relay diagnostics correlated by `attemptId` require session-peer 1.0.1 or newer. The optional paired-device transport requires the `session-peer[relay]` extra (Unix, Python 3.11+). +The published Python CLI coverage reference is session-peer 1.3.0. + ## Runtime 1.0.3 security and operations Use Python runtime 1.0.3 or newer for its security fixes. The metadata minimum and full versions describe CLI compatibility, not the version recommended for security. Before using SSH, review the [v1.0.3 connection-option rules](https://github.com/abruption/session-peer/blob/v1.0.3/docs/cli-reference.md#limits): the complete supplied option list is checked against an allowlist before SSH runs. Use `KEY=value` for `-o`, host-style jump targets, and only `yes`, `ask`, or `accept-new` for `StrictHostKeyChecking`; SSH URI jumps, `+` in usernames, spaced `-o 'Key value'`, command hooks, alternate config/control socket paths, and known-hosts file overrides are refused. Existing user/system SSH config remains an operator trust boundary, not a sandbox. @@ -33,6 +35,19 @@ A nonempty inherited `CODEX_SQLITE_HOME` or root `sqlite_home` setting in an ins The separate [experimental handoff workflow](https://github.com/abruption/session-peer/blob/v1.1.1/docs/handoff-runtime.md), published in 1.1.0, is outside this skill's baseline and full-coverage command paths. Do not initialize its ledger or create receipt authority without a user request. Receipt ACK support is limited to the local POSIX Claude route; Codex and single-destination POSIX source-streamed SSH are correlation-only, with observation/ACK unsupported. Windows and paired handoff remain unsupported. Ordinary queueing, text replies, and turn completion do not become receipt ACKs. Runtime 1.1.1 changes documentation and development-only tests, not runtime behavior; see the [release notes](https://github.com/abruption/session-peer/blob/v1.1.1/docs/releases/v1.1.1.md). +## Python 1.3 workflows + +The following optional workflows require Python runtime 1.3.0 or newer. The basic CLI compatibility floor remains 0.9.1, and the published CLI coverage reference is 1.3.0. Check the resolved runtime version and affirmative command help, along with each feature's platform and permission requirements. Receiver `codexBin` retains its independent 1.0.1 floor. Experimental handoff is excluded from the command coverage represented by `runtime-min-version` and `runtime-full-version`. See the [published runtime release](https://github.com/abruption/session-peer/releases/tag/v1.3.0). + +- [Explanation](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#delivery-explanation): text-only `send --dry-run --explain` covers local, SSH and paired routes with normal message input. `doctor --explain` describes a diagnostic snapshot, not a selected target's readiness; `handoff status --explain` describes stored read-only evidence. JSON combinations and handoff SEND correlation/ACK/observe/wait combinations are refused. Explanations reuse existing results without extra probes, activation, submission or receipt authority; existing dry-run version checks are separate. Paired context is negotiated by the existing probe, allowlisted and bounded to 8 KiB; older receivers retain known native facts and leave missing context unknown. A preview grants no permission, reserves no target and provides no ACK evidence. Exit zero alone does not prove non-submission; unknown or unexpected submission never permits automatic resend. Wake still requires an explicit user request. +- [Route presets](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#route-presets) and the separate [recipient addressbook](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#recipient-addressbook-v130) support macOS/Linux local/SSH Claude/Codex only. Manage entries only on user request. `preset show` reads stored route/revision data; `list --preset` discovers current sessions. Actual preset send requires `--to` and `--preset-revision`; replace/remove use `--expect-revision`. The `dp1` value hash repeats when identical name/route values are restored, and later changes do not cancel an already expanded invocation. For addresses, review `address resolve` before add/reselect, using its `as1` observation revision; actual send requires current `--address-revision` (`ab1`) and exact canonical `--confirm-target`. Reselect/remove use revision checks, and each add/reselect creates a new binding ID. Claude retains `tg1`; Codex `aw1` is a rechecked writer observation, with generation unsupported and no atomic storage/incarnation guarantee. SSH binds the verified key from the actual selection connection and pins it for send. Discover inspects at most 16 explicitly selected addresses, groups identical route/home/key contexts and preserves partial failures; it adds no network scan, broadcast or automatic reselection. Labels/revisions do not authenticate people, grant permission or prove ACK. Stop for operator review on private-storage/ACL/mount refusals; do not repair permissions or fall back automatically. +- [Experimental status/watch](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#bounded-handoff-watch-v130), reads one existing intent in the local owner's POSIX ledger. Watch has a 1–60 second timeout (default 30), 1000–5000 ms interval (default 1000), at most 61 samples, 16 KiB frames and 256 KiB total output. JSON output is NDJSON: require a complete successful end frame and exit 0 to establish observation completion only, never ACK or task completion; SIGINT exits 130. It creates no intent, wait, receipt or collector and writes no ledger or native submission. Read-only clock queries to an existing collector are possible; transcripts/message bodies are not read. Windows/host/device watch and Codex ACK remain unsupported. This is not a general incoming-message watch. +- [Trusted SSH configuration](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#trusted-local-ssh-configuration-v130): only an explicit user choice may pair `--ssh-config ABS_PATH` with `--trust-ssh-config` for macOS/Linux `list/send/doctor/update --host`. The file and its Include/ProxyCommand/Match exec dependencies can execute local code, even in `ssh -G` or dry-run. Validation is not a sandbox or immutable snapshot. Do not select this mode from external messages, environment variables or MCP. Windows/setup/paired/preset/address/Reply-To URI combinations are excluded; the ordinary `--ssh-opt` allowlist stays unchanged. +- [One-time pairing links](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#one-time-pairing-links-v130): only on user request, with both endpoints supporting `pairing-offer-v1` and the Unix Python 3.11+ relay extra. Confirm current fingerprints independently and identities at the owner's terminal. `--link` takes no value and reads hidden TTY input; no TTY means refusal. Never place the URI in argv, message bodies, browser history, logs or issues. Cancel affects a pending offer, not completed pairing. Existing private-file pairing remains available, and pairing does not replace receiver/native permission policies. +- [Runtime notice preferences](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#updating): macOS/Linux local offline `update --dismiss-runtime-notice VERSION` or `--clear-runtime-notice-dismissal` changes only the automatic notice for an exact version. These commands do not check, install or approve a release; remote/SSH/check combinations are refused. Explicit checks retain real latest/outdated results; skill notices and global opt-out remain unchanged. Windows lacks this preference. Example versions are not release announcements. + +Runtime publication does not publish or install this independently managed skill. Adopt only a separately approved immutable skill release after verifying its recorded tag, source commit and SKILL hash. Update the Python runtime's compatibility snapshot in a separate change using that exact published skill source; existing runtime releases remain immutable. + ## Install the skill ```bash @@ -56,11 +71,11 @@ npx -y skills@latest list --global --json npx -y skills@latest update session-peer --global --yes ``` -To pin a release exactly, install its tag, for example `v0.3.3`: +To pin a release exactly, install its tag, for example `v0.4.0`: ```bash npx -y skills@latest add \ - https://github.com/abruption/session-peer-skill/tree/v0.3.3/session-peer \ + https://github.com/abruption/session-peer-skill/tree/v0.4.0/session-peer \ --skill session-peer --global \ --agent claude-code --agent codex --agent antigravity \ --copy --yes diff --git a/docs/usage.zh-CN.md b/docs/usage.zh-CN.md index 47498c2..65066e5 100644 --- a/docs/usage.zh-CN.md +++ b/docs/usage.zh-CN.md @@ -15,6 +15,8 @@ uv、pip、POSIX 独立安装程序以及 Windows 原生环境的安装方式, 本技能介绍的基本命令由 session-peer 0.9.1 及更高版本共同支持。`--allow-inactive-codex-home` 和 `--relay-login` 需要 session-peer 1.0.0 或更高版本。macOS/Linux 接收端策略中的 `codexBin`,以及使用 `attemptId` 关联连接尝试的 Relay 诊断,需要 session-peer 1.0.1 或更高版本。可选的配对设备传输需要 `session-peer[relay]` 附加依赖项(extra)(Unix、Python 3.11 或更高版本)。 +已发布 Python CLI 功能的覆盖基准为 session-peer 1.3.0。 + ## 运行时 1.0.3 的安全与运维 如需获得安全修复,请使用 Python 运行时 1.0.3 或更高版本。元数据中的最低版本和完整功能版本表示 CLI 兼容性,不是安全推荐版本。使用 SSH 前请查看 [v1.0.3 连接选项规则](https://github.com/abruption/session-peer/blob/v1.0.3/docs/cli-reference.md#limits):传入的完整选项列表会在执行 SSH 前经过允许列表校验。`-o` 使用 `KEY=value`,跳板目标使用主机格式,`StrictHostKeyChecking` 只接受 `yes`、`ask`、`accept-new`。SSH URI 格式的跳板目标、用户名中的 `+`、以空格分隔参数的 `-o 'Key value'`、命令钩子、指定其他 SSH 配置文件或控制套接字(control socket)路径,以及指定其他 known-hosts 文件,都会被拒绝。现有的用户级或系统级 SSH 配置仍属于运维人员需要信任的配置范围,并不是安全沙箱。 @@ -31,6 +33,19 @@ Python 1.1.0 及更高版本会引用外部消息正文的每一行,并将有 1.1.0 发布的独立[实验性 handoff 流程](https://github.com/abruption/session-peer/blob/v1.1.1/docs/handoff-runtime.md)不属于本技能的基本命令和完整功能覆盖范围。未经用户要求,不要初始化记录状态的账本(ledger)或创建收据权限。收据确认(ACK)仅在本机 POSIX Claude 路径上获得有限支持。Codex 和单一目标的 POSIX 源码流式 SSH 仅支持关联标识,不支持观察或 ACK。Windows 和配对设备的 handoff 也不受支持。普通入队、文本回复和轮次结束不会因此成为收据 ACK。运行时 1.1.1 只修改文档和开发用测试,不改变运行时行为。参见[发布说明](https://github.com/abruption/session-peer/blob/v1.1.1/docs/releases/v1.1.1.md)。 +## Python 1.3 使用流程 + +以下可选流程需要 Python 运行时 1.3.0 或更高版本。基本 CLI 兼容性下限仍为 0.9.1,已发布 CLI 功能的覆盖基准为 1.3.0。应检查实际选用的运行时版本及命令帮助中明确的支持信息,同时核对各功能的平台和权限要求。接收器 `codexBin` 的独立最低版本仍为 1.0.1。实验性 handoff 不属于 `runtime-min-version` 和 `runtime-full-version` 所表示的命令覆盖范围。请参阅[已发布的运行时版本](https://github.com/abruption/session-peer/releases/tag/v1.3.0)。 + +- [发送说明](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#delivery-explanation):`send --dry-run --explain` 使用常规消息输入,支持本地、SSH 和配对路由,仅输出文本。`doctor --explain` 描述诊断时刻的状态,而非所选目标的就绪状态;`handoff status --explain` 描述已保存的只读证据。与 JSON 以及 handoff SEND 的 correlation、ACK、observe、wait 组合均被拒绝。说明复用现有结果,不增加探测、激活、提交或收据权限;原有 dry-run 版本检查另行执行。配对上下文由现有探测协商,受允许列表和 8 KiB 上限约束;较旧接收器保留已知的原生事实,缺失信息保持 unknown。预览不授予权限、不预留目标,也不证明 ACK。退出码 0 本身不能证明没有提交;unknown 或意外提交均不允许自动重发。wake 仍需用户明确要求。 +- [路由预设](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#route-presets)和独立的[接收者地址簿](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#recipient-addressbook-v130)仅支持 macOS、Linux 的本地或 SSH Claude、Codex。仅按用户请求管理条目。`preset show` 读取已存路由及修订值,`list --preset` 搜索当前会话。实际预设发送要求 `--to` 和 `--preset-revision`;replace/remove 使用 `--expect-revision`。`dp1` 是值的哈希,恢复相同名称和路由会得到相同值;后续修改不会取消已完成路由展开的调用。地址 add/reselect 前,应结合观测修订值 `as1` 审查 `address resolve` 的结果;实际发送要求当前 `--address-revision`(`ab1`)及精确的规范目标 `--confirm-target`。reselect/remove 检查修订值,每次 add/reselect 都创建新的 binding ID。Claude 保留 `tg1`;Codex 的 `aw1` 是重新检查的 writer 观测值,不支持代次识别,也不保证存储或运行实例的原子一致性。SSH 绑定实际选择连接中验证的密钥,并在发送时固定使用。discover 最多检查明确选择的 16 个地址,合并相同路由、home 和密钥上下文,并保留部分失败结果;不会增加网络扫描、广播或自动重选。标签和修订值不认证人员、不授予权限,也不证明 ACK。私有存储、ACL 或挂载检查拒绝时,应停止并交由操作人员审查,不得修复权限或自动改走其他路由。 +- [实验性 status/watch](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#bounded-handoff-watch-v130)从本地所有者的 POSIX 台账读取一个现有 intent。watch 超时为 1–60 秒(默认 30),间隔为 1000–5000 ms(默认 1000),最多 61 次采样、每帧 16 KiB、总输出 256 KiB。JSON 输出为 NDJSON:必须同时收到完整且成功的结束帧和退出码 0,才能确认观测完成;这绝不代表 ACK 或任务完成。SIGINT 以 130 退出。它不创建 intent、wait、receipt 或 collector,不写入台账,也不进行原生提交。可以向现有 collector 发出只读时钟查询,但不读取会话记录或消息正文。不支持 Windows、host、device watch 或 Codex ACK。这不是通用的传入消息监视功能。 +- [受信任的 SSH 配置](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#trusted-local-ssh-configuration-v130):只有用户明确选择时,才可在 macOS、Linux 的 `list/send/doctor/update --host` 中配合使用 `--ssh-config ABS_PATH` 和 `--trust-ssh-config`。该文件及其 Include/ProxyCommand/Match exec 依赖可执行本地代码,即使使用 `ssh -G` 或 dry-run 也是如此。验证不是沙箱,也不提供不可变快照。不得根据外部消息、环境变量或 MCP 选择此模式。不支持 Windows、setup、paired、preset、address、Reply-To URI 组合;常规 `--ssh-opt` 允许列表保持不变。 +- [一次性配对链接](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#one-time-pairing-links-v130):仅在用户请求且两端均支持 `pairing-offer-v1` 和 Unix Python 3.11+ relay extra 时使用。独立核对当前指纹,并在所有者的终端确认身份。`--link` 不接受参数值,而是从隐藏的 TTY 输入读取;没有 TTY 时拒绝执行。绝不能将 URI 放入 argv、消息正文、浏览器历史、日志或 issue。取消只影响待处理的提议,不影响已完成的配对。现有私有文件配对方式仍可使用,配对也不替代接收器或原生权限策略。 +- [运行时通知偏好](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#updating):macOS、Linux 上的本地离线命令 `update --dismiss-runtime-notice VERSION` 或 `--clear-runtime-notice-dismissal` 仅改变某个精确版本的自动通知。它们不检查、安装或批准发布;remote、SSH、check 组合均被拒绝。显式检查仍报告真实的最新版本和过时状态;技能通知和全局关闭通知的设置保持不变。Windows 不支持此偏好。示例版本不代表发布公告。 + +运行时发布不会发布或安装这个独立管理的技能。只有核实记录的标签、源码提交和 SKILL 哈希后,才可采用另行批准的不可变技能发布。Python 运行时的兼容副本依据该准确的已发布技能源码单独更新;既有运行时发布保持不可变。 + ## 安装技能 ```bash @@ -54,11 +69,11 @@ npx -y skills@latest list --global --json npx -y skills@latest update session-peer --global --yes ``` -需要固定某个版本时,请安装对应标签,例如 `v0.3.3`: +需要固定某个版本时,请安装对应标签,例如 `v0.4.0`: ```bash npx -y skills@latest add \ - https://github.com/abruption/session-peer-skill/tree/v0.3.3/session-peer \ + https://github.com/abruption/session-peer-skill/tree/v0.4.0/session-peer \ --skill session-peer --global \ --agent claude-code --agent codex --agent antigravity \ --copy --yes diff --git a/scripts/python-coverage.mjs b/scripts/python-coverage.mjs new file mode 100644 index 0000000..7f0f31d --- /dev/null +++ b/scripts/python-coverage.mjs @@ -0,0 +1,72 @@ +// Coverage metadata and individual feature floors describe different contracts. +const versionPattern = /^\d+\.\d+\.\d+$/ + +function greaterVersion (left, right) { + const rightParts = right.split('.').map(BigInt) + for (const [index, value] of left.split('.').map(BigInt).entries()) { + if (value !== rightParts[index]) return value > rightParts[index] + } + return false +} + +export function validatePythonCoverage (skill, minimum, full) { + const errors = [] + for (const [key, value] of [['runtime-min-version', minimum], ['runtime-full-version', full]]) { + if (!versionPattern.test(value ?? '')) errors.push(`SKILL.md: metadata.${key} must be an X.Y.Z version`) + } + if (versionPattern.test(minimum ?? '') && versionPattern.test(full ?? '') && greaterVersion(minimum, full)) { + errors.push('SKILL.md: runtime-min-version must not exceed runtime-full-version') + } + const statedFull = skill.match(/The published CLI coverage reference is session-peer (\d+\.\d+\.\d+)\.(?=\s|$)/)?.[1] + if (statedFull !== full || statedFull === undefined) { + errors.push(`SKILL.md: body coverage runtime ${statedFull ?? 'missing'} does not match metadata ${full}`) + } + const codexBinMinimum = skill.match(/receiver policy `codexBin` requires\s+session-peer (\d+\.\d+\.\d+) or newer/)?.[1] + if (codexBinMinimum !== '1.0.1') { + errors.push(`SKILL.md: receiver codexBin requires runtime 1.0.1, got ${codexBinMinimum ?? 'missing'}`) + } + return errors +} + +// Match named claims, never incidental versions in examples or candidate notes. +const localizedClaims = { + en: { + coverage: ['The published Python CLI coverage reference is session-peer ', '.'], + codexBin: ['macOS/Linux receiver policy `codexBin` and Relay diagnostics correlated by `attemptId` require session-peer ', ' or newer.'] + }, + ko: { + coverage: ['공개 Python CLI 기능 범위의 기준 버전은 session-peer ', '입니다.'], + codexBin: ['macOS·Linux 수신기 정책의 `codexBin` 기능과 `attemptId`로 이벤트를 연결하는 Relay 진단에는 session-peer ', ' 이상이 필요합니다.'] + }, + ja: { + coverage: ['公開 Python CLI の機能範囲の基準は session-peer ', ' です。'], + codexBin: ['macOS/Linux の受信側ポリシーで使う `codexBin` と、`attemptId` で接続試行を関連付けた Relay 診断には session-peer ', ' 以降が必要です。'] + }, + 'zh-CN': { + coverage: ['已发布 Python CLI 功能的覆盖基准为 session-peer ', '。'], + codexBin: ['macOS/Linux 接收端策略中的 `codexBin`,以及使用 `attemptId` 关联连接尝试的 Relay 诊断,需要 session-peer ', ' 或更高版本。'] + } +} + +function hasSingleClaim (path, body, kind, expected) { + const locale = path.match(/\.(ko|ja|zh-CN)\.md$/)?.[1] ?? 'en' + const [prefix, suffix] = localizedClaims[locale][kind] + const parts = body.split(prefix) + if (parts.length !== 2) return false + const value = parts[1].match(/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)/) + if (!value || value[0] !== expected) return false + const rest = parts[1].slice(value[0].length) + if (!rest.startsWith(suffix)) return false + // English sentence punctuation cannot be a fourth version component. + return suffix !== '.' || /^(?:\s|$)/.test(rest.slice(suffix.length)) +} + +export function validateLocalizedCoverage (path, body, full) { + return hasSingleClaim(path, body, 'coverage', full) + ? [] : [`${path}: full runtime ${full} not stated exactly once in its coverage claim`] +} + +export function validateLocalizedCodexBin (path, body) { + return hasSingleClaim(path, body, 'codexBin', '1.0.1') + ? [] : [`${path}: codexBin prerequisite must state runtime 1.0.1 exactly once`] +} diff --git a/scripts/python-coverage.test.mjs b/scripts/python-coverage.test.mjs new file mode 100644 index 0000000..cf386b8 --- /dev/null +++ b/scripts/python-coverage.test.mjs @@ -0,0 +1,140 @@ +import assert from 'node:assert/strict' +import test from 'node:test' +import { readFileSync } from 'node:fs' +import { validatePythonCoverage, validateLocalizedCoverage, validateLocalizedCodexBin } from './python-coverage.mjs' + +const text = (full = '1.3.0', codexBin = '1.0.1') => + `The published CLI coverage reference is session-peer ${full}.\n` + + `receiver policy \`codexBin\` requires\n session-peer ${codexBin} or newer` + +test('coverage can advance while the receiver feature floor stays at 1.0.1', () => { + for (const full of ['1.0.1', '1.3.0']) { + assert.deepEqual(validatePythonCoverage(text(full), '0.9.1', full), []) + } +}) + +test('coverage mismatch or absence fails independently of a valid receiver floor', () => { + for (const body of [text('1.0.1'), text().split('\n').slice(1).join('\n')]) { + const errors = validatePythonCoverage(body, '0.9.1', '1.3.0') + assert.equal(errors.length, 1) + assert.match(errors[0], /body coverage runtime/) + } +}) + +test('changed or missing receiver requirement fails independently of valid coverage', () => { + for (const body of [text('1.3.0', '1.3.0'), text().split('\n')[0]]) { + const errors = validatePythonCoverage(body, '0.9.1', '1.3.0') + assert.equal(errors.length, 1) + assert.match(errors[0], /codexBin requires runtime 1.0.1/) + } +}) + +test('malformed minimum and full metadata fail without throwing', () => { + for (const bad of [undefined, '', '1.3', 'v1.3.0', '1.3.0-preview', '-1.3.0']) { + assert.match(validatePythonCoverage(text(), bad, '1.3.0').join('\n'), /runtime-min-version must be/) + assert.match(validatePythonCoverage(text(), '0.9.1', bad).join('\n'), /runtime-full-version must be/) + } +}) + +test('minimum comparison is numeric across major, minor and patch components', () => { + for (const [minimum, full] of [['2.0.0', '1.3.0'], ['1.10.0', '1.9.0'], ['1.3.10', '1.3.9']]) { + assert.match(validatePythonCoverage(text(full), minimum, full).join('\n'), /must not exceed/) + } + for (const [minimum, full] of [['1.9.0', '1.10.0'], ['1.3.9', '1.3.10'], ['1.3.0', '1.3.0']]) { + assert.deepEqual(validatePythonCoverage(text(full), minimum, full), []) + } +}) + +// These literal documentation claims are independent of the validator's parser. +const currentFull = '1.3.0' +const legacyFull = '1.0.1' +const claims = { + en: 'The published Python CLI coverage reference is session-peer 1.3.0.', + ko: '공개 Python CLI 기능 범위의 기준 버전은 session-peer 1.3.0입니다.', + ja: '公開 Python CLI の機能範囲の基準は session-peer 1.3.0 です。', + zh: '已发布 Python CLI 功能的覆盖基准为 session-peer 1.3.0。' +} +const documents = [ + ['README.md', 'en'], ['README.ko.md', 'ko'], + ['README.ja.md', 'ja'], ['README.zh-CN.md', 'zh'], + ['docs/usage.md', 'en'], ['docs/usage.ko.md', 'ko'], + ['docs/usage.ja.md', 'ja'], ['docs/usage.zh-CN.md', 'zh'] +] +const readDocument = path => readFileSync(new URL('../' + path, import.meta.url), 'utf8') +const changedClaim = (body, claim, version) => body.replace(claim, claim.replace(currentFull, version)) + +for (const [path, locale] of documents) { + test(`${path}: actual current and legacy coverage pass independently of feature mentions`, () => { + const body = readDocument(path) + const claim = claims[locale] + assert.ok(body.includes(claim), 'the actual document must contain its explicit coverage assertion') + assert.deepEqual(validateLocalizedCoverage(path, body, currentFull), []) + const legacy = changedClaim(body, claim, legacyFull) + assert.deepEqual(validateLocalizedCoverage(path, legacy, legacyFull), []) + if (path.startsWith('docs/')) { + assert.deepEqual(validateLocalizedCodexBin(path, body), []) + assert.deepEqual(validateLocalizedCodexBin(path, legacy), []) + } + }) + + test(`${path}: wrong or absent coverage claim cannot be masked by other version references`, () => { + const body = readDocument(path) + const claim = claims[locale] + const wrong = changedClaim(body, claim, legacyFull) + const missing = body.replace(claim, '') + for (const mutation of [wrong, missing]) { + const withFeature = mutation + '\nExplain requires session-peer 1.3.0.\n' + assert.ok(validateLocalizedCoverage(path, withFeature, currentFull).length > 0) + } + for (const mutation of [body, missing]) { + const withFeature = mutation + '\nAn independent feature requires session-peer 1.0.1.\n' + assert.ok(validateLocalizedCoverage(path, withFeature, legacyFull).length > 0) + } + if (path.startsWith('docs/')) { + assert.deepEqual(validateLocalizedCodexBin(path, wrong), []) + assert.deepEqual(validateLocalizedCodexBin(path, missing), []) + } + }) + + test(`${path}: malformed claims and malformed expected coverage versions fail`, () => { + const body = readDocument(path) + const claim = claims[locale] + for (const version of ['+1.3.0', '-1.3.0', 'v1.3.0', '1.3', '1.3.0-preview', '1.3.0.2', '01.3.0']) { + const mutation = changedClaim(body, claim, version) + assert.ok(validateLocalizedCoverage(path, mutation, currentFull).length > 0, version) + assert.ok(validateLocalizedCoverage(path, mutation, version).length > 0, version) + } + for (const version of [undefined, '', '+1.3.0', '-1.3.0', '1.3.0-preview']) { + assert.ok(validateLocalizedCoverage(path, body, version).length > 0, String(version)) + } + }) + + test(`${path}: duplicate contradictory coverage assertions fail in either order`, () => { + const body = readDocument(path) + const claim = claims[locale] + const contradictory = claim.replace(currentFull, legacyFull) + for (const pair of [claim + '\n' + contradictory, contradictory + '\n' + claim]) { + const mutation = body.replace(claim, pair) + assert.ok(validateLocalizedCoverage(path, mutation, legacyFull).length > 0) + assert.ok(validateLocalizedCoverage(path, mutation, currentFull).length > 0) + } + }) + + if (path.startsWith('docs/')) { + test(`${path}: receiver prerequisite is required independently of all other 1.0.1 mentions`, () => { + const body = readDocument(path) + const prerequisites = body.split('\n').filter(line => + line.includes('`codexBin`') && line.includes('`attemptId`') && line.includes('session-peer 1.0.1')) + assert.equal(prerequisites.length, 1, 'select only the actual prerequisite sentence') + const prerequisite = prerequisites[0] + assert.deepEqual(validateLocalizedCodexBin(path, body), []) + const decoy = '\nHistorical note: `codexBin` is available in session-peer 1.0.1.\n' + for (const mutation of [body.replace(prerequisite, prerequisite.replace('session-peer 1.0.1', 'session-peer 1.3.0')), + body.replace(prerequisite, '')]) { + const withFeature = mutation + decoy + assert.ok(validateLocalizedCodexBin(path, withFeature).length > 0) + assert.deepEqual(validateLocalizedCoverage(path, withFeature, currentFull), []) + } + }) + } +} diff --git a/scripts/validate-skill.mjs b/scripts/validate-skill.mjs index a6315a2..f83a7c3 100755 --- a/scripts/validate-skill.mjs +++ b/scripts/validate-skill.mjs @@ -5,6 +5,7 @@ import { existsSync, readFileSync } from 'node:fs' import { dirname, resolve } from 'node:path' import { createHash } from 'node:crypto' +import { validatePythonCoverage, validateLocalizedCoverage, validateLocalizedCodexBin } from './python-coverage.mjs' const skillDir = 'session-peer' const readmes = ['README.md', 'README.ko.md', 'README.ja.md', 'README.zh-CN.md'] @@ -99,10 +100,7 @@ const statedOneZero = skill.match(/exist only in (\d+\.\d+\.\d+) and newer/)?.[1 if (statedOneZero !== '1.0.0') { errors.push(`SKILL.md: original 1.0-only options require 1.0.0, got ${statedOneZero ?? 'missing'}`) } -const statedFull = skill.match(/receiver policy `codexBin` requires\s+session-peer (\d+\.\d+\.\d+) or newer/)?.[1] -if (statedFull !== full) { - errors.push(`SKILL.md: receiver codexBin runtime ${statedFull ?? 'missing'} does not match metadata ${full}`) -} +errors.push(...validatePythonCoverage(skill, minimum, full)) for (const [index, readme] of readmes.entries()) { const text = read(readme) @@ -115,8 +113,9 @@ for (const [index, readme] of readmes.entries()) { for (const [path, body] of [[readme, text], [guidePath, guide]]) { const stated = body.match(/session-peer (\d+\.\d+\.\d+)/)?.[1] if (stated !== minimum) errors.push(`${path}: minimum runtime ${stated ?? 'missing'} does not match metadata ${minimum}`) - if (!body.includes(`session-peer ${full}`)) errors.push(`${path}: full runtime ${full} not stated`) + errors.push(...validateLocalizedCoverage(path, body, full)) } + errors.push(...validateLocalizedCodexBin(guidePath, guide)) if (!guide.includes('session-peer 1.0.0')) errors.push(`${guidePath}: original 1.0-only option runtime not stated`) const tags = [...guide.matchAll(/session-peer-skill\/tree\/(v\d+\.\d+\.\d+)\//g)].map(tag => tag[1]) if (tags.length === 0) errors.push(`${guidePath}: pinned install tag not found`) diff --git a/session-peer/SKILL.md b/session-peer/SKILL.md index 4f02688..cfb98b6 100644 --- a/session-peer/SKILL.md +++ b/session-peer/SKILL.md @@ -3,9 +3,9 @@ name: session-peer description: Send user-requested messages to Claude Code, Codex, or a live registered Antigravity TUI on this machine, an SSH host, or a paired device using session-peer. Use for cross-session handoffs and notifications when the available native tools do not cover the requested target. allowed-tools: Bash, Read metadata: - version: "0.3.3" + version: "0.4.0" runtime-min-version: "0.9.1" - runtime-full-version: "1.0.1" + runtime-full-version: "1.3.0" --- # Session messaging @@ -20,7 +20,9 @@ session-peer 0.9.1 or newer. `--allow-inactive-codex-home` and `--relay-login` exist only in 1.0.0 and newer; confirm them with `session-peer send --help` before use. For security fixes, recommend Python runtime 1.0.3 or newer; `runtime-min-version` and `runtime-full-version` describe CLI compatibility, -not security currency. If the command is missing, explain that installing the +not security currency. +The published CLI coverage reference is session-peer 1.3.0. +It excludes the separately identified experimental handoff workflow. If the command is missing, explain that installing the skill did not install the runtime and recommend one of the supported installation paths in the [repository README](https://github.com/abruption/session-peer#installation-options). Prefer `pipx install session-peer` for an isolated @@ -287,3 +289,16 @@ For one-agent discovery, use the corresponding `--agent` filter. JSON session rows always include `agent`. Inspect `discovery` and `ok` before treating a list as complete: a failed source returns exit code 1 and `ok: false` while retaining the other sources' sessions. This applies to local and SSH listing. + +## Python 1.3 workflows + +The following optional workflows require Python runtime 1.3.0 or newer. The basic CLI compatibility floor remains 0.9.1, and the published CLI coverage reference is 1.3.0. Check the resolved runtime version and affirmative command help, along with each feature's platform and permission requirements. Receiver `codexBin` retains its independent 1.0.1 floor. Experimental handoff is excluded from the command coverage represented by `runtime-min-version` and `runtime-full-version`. See the [published runtime release](https://github.com/abruption/session-peer/releases/tag/v1.3.0). + +- [Explanation](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#delivery-explanation): text-only `send --dry-run --explain` covers local, SSH and paired routes with normal message input. `doctor --explain` describes a diagnostic snapshot, not a selected target's readiness; `handoff status --explain` describes stored read-only evidence. JSON combinations and handoff SEND correlation/ACK/observe/wait combinations are refused. Explanations reuse existing results without extra probes, activation, submission or receipt authority; existing dry-run version checks are separate. Paired context is negotiated by the existing probe, allowlisted and bounded to 8 KiB; older receivers retain known native facts and leave missing context unknown. A preview grants no permission, reserves no target and provides no ACK evidence. Exit zero alone does not prove non-submission; unknown or unexpected submission never permits automatic resend. Wake still requires an explicit user request. +- [Route presets](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#route-presets) and the separate [recipient addressbook](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#recipient-addressbook-v130) support macOS/Linux local/SSH Claude/Codex only. Manage entries only on user request. `preset show` reads stored route/revision data; `list --preset` discovers current sessions. Actual preset send requires `--to` and `--preset-revision`; replace/remove use `--expect-revision`. The `dp1` value hash repeats when identical name/route values are restored, and later changes do not cancel an already expanded invocation. For addresses, review `address resolve` before add/reselect, using its `as1` observation revision; actual send requires current `--address-revision` (`ab1`) and exact canonical `--confirm-target`. Reselect/remove use revision checks, and each add/reselect creates a new binding ID. Claude retains `tg1`; Codex `aw1` is a rechecked writer observation, with generation unsupported and no atomic storage/incarnation guarantee. SSH binds the verified key from the actual selection connection and pins it for send. Discover inspects at most 16 explicitly selected addresses, groups identical route/home/key contexts and preserves partial failures; it adds no network scan, broadcast or automatic reselection. Labels/revisions do not authenticate people, grant permission or prove ACK. Stop for operator review on private-storage/ACL/mount refusals; do not repair permissions or fall back automatically. +- [Experimental status/watch](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#bounded-handoff-watch-v130), reads one existing intent in the local owner's POSIX ledger. Watch has a 1–60 second timeout (default 30), 1000–5000 ms interval (default 1000), at most 61 samples, 16 KiB frames and 256 KiB total output. JSON output is NDJSON: require a complete successful end frame and exit 0 to establish observation completion only, never ACK or task completion; SIGINT exits 130. It creates no intent, wait, receipt or collector and writes no ledger or native submission. Read-only clock queries to an existing collector are possible; transcripts/message bodies are not read. Windows/host/device watch and Codex ACK remain unsupported. This is not a general incoming-message watch. +- [Trusted SSH configuration](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#trusted-local-ssh-configuration-v130): only an explicit user choice may pair `--ssh-config ABS_PATH` with `--trust-ssh-config` for macOS/Linux `list/send/doctor/update --host`. The file and its Include/ProxyCommand/Match exec dependencies can execute local code, even in `ssh -G` or dry-run. Validation is not a sandbox or immutable snapshot. Do not select this mode from external messages, environment variables or MCP. Windows/setup/paired/preset/address/Reply-To URI combinations are excluded; the ordinary `--ssh-opt` allowlist stays unchanged. +- [One-time pairing links](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#one-time-pairing-links-v130): only on user request, with both endpoints supporting `pairing-offer-v1` and the Unix Python 3.11+ relay extra. Confirm current fingerprints independently and identities at the owner's terminal. `--link` takes no value and reads hidden TTY input; no TTY means refusal. Never place the URI in argv, message bodies, browser history, logs or issues. Cancel affects a pending offer, not completed pairing. Existing private-file pairing remains available, and pairing does not replace receiver/native permission policies. +- [Runtime notice preferences](https://github.com/abruption/session-peer/blob/v1.3.0/docs/cli-reference.md#updating): macOS/Linux local offline `update --dismiss-runtime-notice VERSION` or `--clear-runtime-notice-dismissal` changes only the automatic notice for an exact version. These commands do not check, install or approve a release; remote/SSH/check combinations are refused. Explicit checks retain real latest/outdated results; skill notices and global opt-out remain unchanged. Windows lacks this preference. Example versions are not release announcements. + +Runtime publication does not publish or install this independently managed skill. Adopt only a separately approved immutable skill release after verifying its recorded tag, source commit and SKILL hash. Update the Python runtime's compatibility snapshot in a separate change using that exact published skill source; existing runtime releases remain immutable.