diff --git a/.claude/commands/compile-knowledge.md b/.claude/commands/compile-knowledge.md index df28bac3e..5f7b9edb1 100644 --- a/.claude/commands/compile-knowledge.md +++ b/.claude/commands/compile-knowledge.md @@ -1,11 +1,11 @@ --- name: compile-knowledge -description: Compile the OpenIAP knowledge base into the context files AI assistants load. Use after editing anything under knowledge/, or when the user asks to compile, recompile, or refresh the knowledge base or agent context. +description: Compile the OpenIAP knowledge base into the shared reference and public AI files. Use after editing anything under knowledge/, or when the user asks to compile, recompile, or refresh the knowledge base or agent context. --- # Compile Knowledge Base -Compile the OpenIAP knowledge base to generate context files for AI assistants. +Compile the OpenIAP knowledge base into a shared reference and public AI files. > **Full documentation:** See `scripts/agent/README.md` for detailed setup and troubleshooting. @@ -13,11 +13,11 @@ Compile the OpenIAP knowledge base to generate context files for AI assistants. ### Output Files -| Output | Location | Purpose | -| --------------- | ---------------------------- | ---------------------------- | -| `context.md` | `knowledge/_claude-context/` | Claude Code context | -| `llms.txt` | `packages/docs/public/` | AI assistant quick reference | -| `llms-full.txt` | `packages/docs/public/` | AI assistant full reference | +| Output | Location | Purpose | +| --------------- | --------------------------- | ---------------------------- | +| `context.md` | `knowledge/_agent-context/` | Generated shared reference | +| `llms.txt` | `packages/docs/public/` | AI assistant quick reference | +| `llms-full.txt` | `packages/docs/public/` | AI assistant full reference | ### Commands @@ -73,16 +73,16 @@ bun run compile:ai ### 2. Verify Output ```bash -ls -la ../../knowledge/_claude-context/ +ls -la ../../knowledge/_agent-context/ ls -la ../../packages/docs/public/llms*.txt ``` ### 3. Review Generated Changes ```bash -git add knowledge/_claude-context/context.md -git add packages/docs/public/llms.txt -git add packages/docs/public/llms-full.txt +git -C ../.. add knowledge/_agent-context/context.md knowledge/_claude-context +git -C ../.. add packages/docs/public/llms.txt +git -C ../.. add packages/docs/public/llms-full.txt ``` Commit or push generated context only when the user requested publication or it @@ -94,7 +94,7 @@ context changes local and report them. ```text knowledge/ ├── internal/ ─┐ -└── external/ ─┴─► compile:ai ─┬► context.md (Claude Code) +└── external/ ─┴─► compile:ai ─┬► context.md (shared reference) ├► llms.txt (Quick Ref) └► llms-full.txt (Full Ref) ``` diff --git a/.claude/commands/release.md b/.claude/commands/release.md index f0bcce9c1..1cea5c840 100644 --- a/.claude/commands/release.md +++ b/.claude/commands/release.md @@ -51,7 +51,7 @@ Every release lane's version-bump commit also runs `scripts/sync-release-generated.sh`, which regenerates and stages the files derived from version metadata (`packages/docs/src/generated/version-metadata.json`, `packages/docs/public/llms.txt`, `packages/docs/public/llms-full.txt`, -`knowledge/_claude-context/context.md`). Expect these paths in bump commits; +`knowledge/_agent-context/context.md`). Expect these paths in bump commits; they are not worktree drift. Skipping this regeneration leaves `main` stale and fails the `Audit SDK Parity` / `Test Agent Scripts` clean-worktree checks on every subsequent PR. @@ -131,9 +131,9 @@ For a multi-package release train, use this order when affected: version, so it does not participate in the `spec = min(google, apple)` invariant. 10. `npm run deploy`; run `release.yml` with `version=current` only when the - native-derived `spec` advanced. If a Docs GitHub Release is requested while - `spec` is unchanged, stop and explain that the immutable `docs-{spec}` tag - cannot represent a new release. + native-derived `spec` advanced. If a Docs GitHub Release is requested while + `spec` is unchanged, stop and explain that the immutable `docs-{spec}` tag + cannot represent a new release. Train rules (mistake guards): diff --git a/.claude/commands/review-pr.md b/.claude/commands/review-pr.md index f3a2b4b28..24b463b3b 100644 --- a/.claude/commands/review-pr.md +++ b/.claude/commands/review-pr.md @@ -37,7 +37,7 @@ When reviewing, check these project-specific rules: - **Android functions in packages/google**: NO `Android` suffix (it's Android-only) - **Generated files**: Do NOT edit `packages/apple/Sources/Models/Types.swift` or `packages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt` -See [CLAUDE.md](../../CLAUDE.md) and [knowledge/internal/](../../knowledge/internal/) for full conventions. +See [AGENTS.md](../../AGENTS.md) and [knowledge/internal/](../../knowledge/internal/) for full conventions. ## Public GitHub Language Guard diff --git a/.claude/commands/verify-all.md b/.claude/commands/verify-all.md index 2b7178b94..75574b723 100644 --- a/.claude/commands/verify-all.md +++ b/.claude/commands/verify-all.md @@ -295,8 +295,8 @@ ruby -e 'require "yaml"; Dir[".github/workflows/*.yml"].each { |f| YAML.safe_loa ### 8. Agent instructions -- Root AGENTS.md lists all framework library CLAUDE.md files -- Root CLAUDE.md and GEMINI.md are symlinks to AGENTS.md +- Root AGENTS.md lists all framework library AGENTS.md files +- Root and framework-library CLAUDE.md/GEMINI.md files are symlinks to AGENTS.md - `knowledge/internal/02-architecture.md` includes `libraries/` in structure - Auto-generated files list includes library types diff --git a/.claude/guides/01-overview.md b/.claude/guides/01-overview.md index 74f3ab23b..f5e6b0930 100644 --- a/.claude/guides/01-overview.md +++ b/.claude/guides/01-overview.md @@ -14,7 +14,7 @@ openiap/ │ └── kit/ # Hosted receipt-validation SaaS (kit.openiap.dev) ├── scripts/ # Monorepo-wide automation ├── .github/workflows/ # CI/CD workflows -├── CLAUDE.md # Main agent guidelines +├── AGENTS.md # Canonical shared agent guidelines └── openiap-versions.json # Version management ``` diff --git a/.claude/guides/03-deprecations.md b/.claude/guides/03-deprecations.md index e3a4651cf..61d55c776 100644 --- a/.claude/guides/03-deprecations.md +++ b/.claude/guides/03-deprecations.md @@ -68,4 +68,4 @@ When deprecating APIs: ``` 4. **Update documentation** - Add migration guide in `docs/updates/releases.tsx` -5. **Update CLAUDE.md** - Add to deprecated functions list +5. **Update AGENTS.md** - Add to deprecated functions list diff --git a/.claude/skills/openiap-workflows/SKILL.md b/.claude/skills/openiap-workflows/SKILL.md index 92054accc..532d57266 100644 --- a/.claude/skills/openiap-workflows/SKILL.md +++ b/.claude/skills/openiap-workflows/SKILL.md @@ -1,6 +1,6 @@ --- name: openiap-workflows -description: Use for OpenIAP monorepo work that should follow the repository's slash-command workflows when the user asks in natural language instead of typing a slash command, including review-pr, audit-code, compile-knowledge, verify-all, e2e-tests, stable or prerelease package releases, resolve-issue, commit/push/PR, generated type sync, package-specific checks, GitHub review threads, and project conventions from AGENTS.md/CLAUDE.md/GEMINI.md. +description: Use for OpenIAP monorepo work that should follow the repository's slash-command workflows when the user asks in natural language instead of typing a slash command, including review-pr, audit-code, compile-knowledge, verify-all, e2e-tests, stable or prerelease package releases, resolve-issue, commit/push/PR, generated type sync, package-specific checks, GitHub review threads, and project conventions from AGENTS.md. --- # OpenIAP Workflows (Claude Code) diff --git a/.codex/skills/iapkit-e2e-martie/SKILL.md b/.codex/skills/iapkit-e2e-martie/SKILL.md index bf05dd367..1bff62833 100644 --- a/.codex/skills/iapkit-e2e-martie/SKILL.md +++ b/.codex/skills/iapkit-e2e-martie/SKILL.md @@ -85,7 +85,7 @@ satisfied. ## Preflight 1. Read `$OPENIAP_REPO/AGENTS.md`, `packages/kit/CONVENTION.md`, the selected - framework's `CLAUDE.md`, and the `Local (IAPKit) Receipt Vertical` section of + framework's `AGENTS.md`, and the `Local (IAPKit) Receipt Vertical` section of `.claude/commands/e2e-tests.md`. 2. Run `git status --short --branch` and preserve all existing changes. 3. Confirm port `3100` is free and identify the device: diff --git a/.codex/skills/openiap-workflows/SKILL.md b/.codex/skills/openiap-workflows/SKILL.md index a947ee168..5f07bdfdb 100644 --- a/.codex/skills/openiap-workflows/SKILL.md +++ b/.codex/skills/openiap-workflows/SKILL.md @@ -1,6 +1,6 @@ --- name: openiap-workflows -description: Use for OpenIAP monorepo work that should follow the repository's Claude slash-command workflows, including review-pr, audit-code, compile-knowledge, verify-all, e2e-tests, stable or prerelease package releases, resolve-issue, commit/push/PR, generated type sync, package-specific checks, GitHub review threads, and project conventions from AGENTS.md/CLAUDE.md/GEMINI.md. +description: Use for OpenIAP monorepo work that should follow the repository's shared agent workflows, including review-pr, audit-code, compile-knowledge, verify-all, e2e-tests, stable or prerelease package releases, resolve-issue, commit/push/PR, generated type sync, package-specific checks, GitHub review threads, and project conventions from AGENTS.md. --- # OpenIAP Workflows @@ -13,11 +13,12 @@ verifying the monorepo, or committing and opening a PR. ## Source Of Truth Before changing code, read the root `AGENTS.md`; `CLAUDE.md` and `GEMINI.md` -are symlinks to it in this repo. Then read the relevant detailed files: +are symlinks to it in this repo, while Grok and Codex consume `AGENTS.md` +directly. Then read the relevant detailed files: - Package and library rules: `knowledge/internal/*.md` - Package conventions: `packages/*/CONVENTION.md` -- Library conventions: `libraries/*/CLAUDE.md` +- Library conventions: `libraries/*/AGENTS.md` - Workflow details: `.claude/commands/*.md` Do not duplicate or reinterpret those rules when a file already covers the diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 62b8a8395..b4b7dc833 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,6 +31,9 @@ jobs: with: node-version: 20 + - name: Audit repository layout + run: npm run audit:layout + - name: Reject prerelease metadata on main run: node scripts/release-branch-policy.mjs audit diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 966e6b399..b2256a93f 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -424,6 +424,8 @@ jobs: - name: Build Flutter Swift wrappers if: matrix.component == 'flutter' working-directory: libraries/flutter_inapp_purchase + env: + EXPECTED_XCODE_MAJOR: ${{ github.event_name == 'pull_request' && '26' || '27' }} run: bash scripts/verify-apple-swiftpm-consumer-build.sh - name: Build Godot Swift wrapper diff --git a/.github/workflows/deploy-kit.yml b/.github/workflows/deploy-kit.yml index b58b5619b..d1c921ec1 100644 --- a/.github/workflows/deploy-kit.yml +++ b/.github/workflows/deploy-kit.yml @@ -175,6 +175,7 @@ jobs: "$RUNNER_TEMP/trivy" image openiap-kit:security-scan --scanners vuln --severity HIGH,CRITICAL + --ignorefile packages/kit/.trivyignore.yaml --exit-code 1 --exit-on-eol 1 diff --git a/.github/workflows/security-rescan.yml b/.github/workflows/security-rescan.yml index 076647ffa..c1c82e769 100644 --- a/.github/workflows/security-rescan.yml +++ b/.github/workflows/security-rescan.yml @@ -149,6 +149,7 @@ jobs: "$RUNNER_TEMP/trivy" image openiap-kit:security-scan --scanners vuln --severity HIGH,CRITICAL + --ignorefile packages/kit/.trivyignore.yaml --exit-code 1 --exit-on-eol 1 --format json diff --git a/.husky/pre-commit b/.husky/pre-commit index b3840f324..c837dcda0 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -52,6 +52,10 @@ fi echo "🔎 SDK parity audit — running CI mirror…" node scripts/audit-non-godot-parity.mjs +# Canonical project directories must not be duplicated at repository root. +echo "🧭 repository layout audit…" +bun run audit:layout + # Unconditional: either side of the kit/spec contract can move. echo "🔎 IAPKit spec contract audit — running CI mirror…" node --test scripts/audit-kit-spec-contract.test.mjs diff --git a/.vscode/settings.json b/.vscode/settings.json index c58eeca10..dd33559ca 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,11 +1,16 @@ { "cSpell.words": [ + "apollographql", + "codegen", + "gradlew", "hyodotdev", "Iapkit", + "JsonSlurper", "openiap", + "preorder", + "pubspec", "Skus", - "Slurper", - "JsonSlurper" + "Slurper" ], "files.associations": { "*.podspec": "ruby" @@ -47,4 +52,4 @@ "java.configuration.updateBuildConfiguration": "automatic", "gradle.nestedProjects": false, "eslint.workingDirectories": [{ "mode": "auto" }] -} \ No newline at end of file +} diff --git a/AGENTS.md b/AGENTS.md index 15c766369..a1ed985c5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -21,11 +21,12 @@ This document provides an overview for AI agents working across the OpenIAP mono ```text openiap/ ├── packages/ +│ ├── conformance/ # Behavioral conformance spec, runner, and reports │ ├── docs/ # Documentation site (React/Vite/Vercel) │ ├── gql/ # GraphQL schema & type generation │ ├── google/ # Android library │ ├── apple/ # iOS/macOS library -│ ├── kit/ # Hosted receipt-validation SaaS (Fly.io app) +│ ├── kit/ # Purchase validation + entitlement infrastructure (Fly.io app) │ └── mcp-server/ # IAPKit MCP server (hosted at kit.openiap.dev/mcp) ├── plugins/ │ └── openiap/ # Codex + Claude Code plugin (skills + MCP config) @@ -39,7 +40,8 @@ openiap/ ├── knowledge/ # Shared knowledge base (SSOT) │ ├── internal/ # Project philosophy (HIGHEST PRIORITY) │ ├── external/ # External API reference -│ └── _claude-context/ # Compiled context for Claude Code +│ ├── _agent-context/ # Compiled context shared by AI assistants +│ └── _claude-context/ # Compatibility link to _agent-context ├── scripts/ # Monorepo-wide automation └── .github/workflows/ # CI/CD workflows ``` @@ -56,13 +58,13 @@ openiap/ - [`packages/apple/CONVENTION.md`](packages/apple/CONVENTION.md) - [`packages/docs/CONVENTION.md`](packages/docs/CONVENTION.md) - [`packages/kit/CONVENTION.md`](packages/kit/CONVENTION.md) — kit is a deployable SaaS (not a library); has its own Convex schema and isn't part of the GQL type-sync chain. Its `/v1` responses are still a published contract that shipped SDKs decode: read the `/v1` response contract section and run `bun audit:kit-contract` before changing a response enum, `isValidState`, or a purchase-state mapping -3. **For framework libraries, read the library-specific CLAUDE.md**: - - [`libraries/react-native-iap/CLAUDE.md`](libraries/react-native-iap/CLAUDE.md) — Yarn 3, Nitro Modules, useIAP hook semantics, error handling - - [`libraries/expo-iap/CLAUDE.md`](libraries/expo-iap/CLAUDE.md) — Bun, Expo Modules, iOS podspec 13.4 workaround, tvOS 16.0 requirement - - [`libraries/flutter_inapp_purchase/CLAUDE.md`](libraries/flutter_inapp_purchase/CLAUDE.md) — Flutter/Dart, generated types.dart, fetchProducts generic API - - [`libraries/godot-iap/CLAUDE.md`](libraries/godot-iap/CLAUDE.md) — GDScript conventions, GDExtension (iOS), AAR plugin (Android) - - [`libraries/kmp-iap/CLAUDE.md`](libraries/kmp-iap/CLAUDE.md) — Kotlin Multiplatform, Flow-based API, CocoaPods iOS integration - - [`libraries/maui-iap/CLAUDE.md`](libraries/maui-iap/CLAUDE.md) — .NET MAUI / C# 12, generated Types.cs, Android/iOS bindings +3. **For framework libraries, read the library-specific AGENTS.md**: + - [`libraries/react-native-iap/AGENTS.md`](libraries/react-native-iap/AGENTS.md) — Yarn 3, Nitro Modules, useIAP hook semantics, error handling + - [`libraries/expo-iap/AGENTS.md`](libraries/expo-iap/AGENTS.md) — Bun, Expo Modules, iOS podspec 13.4 workaround, tvOS 16.0 requirement + - [`libraries/flutter_inapp_purchase/AGENTS.md`](libraries/flutter_inapp_purchase/AGENTS.md) — Flutter/Dart, generated types.dart, fetchProducts generic API + - [`libraries/godot-iap/AGENTS.md`](libraries/godot-iap/AGENTS.md) — GDScript conventions, GDExtension (iOS), AAR plugin (Android) + - [`libraries/kmp-iap/AGENTS.md`](libraries/kmp-iap/AGENTS.md) — Kotlin Multiplatform, Flow-based API, CocoaPods iOS integration + - [`libraries/maui-iap/AGENTS.md`](libraries/maui-iap/AGENTS.md) — .NET MAUI / C# 12, generated Types.cs, Android/iOS bindings ## Key Rules Summary @@ -79,6 +81,13 @@ KISS and SSOT are mandatory release criteria. The canonical rules live in [`knowledge/internal/03-coding-style.md`](knowledge/internal/03-coding-style.md#0-kiss-and-ssot-are-release-requirements). Apply that section before implementation and during every review. +### Repository Layout + +Treat the directory ownership rules in +[`knowledge/internal/02-architecture.md`](knowledge/internal/02-architecture.md#directory-ownership-guardrail) +as mandatory. Extend the existing owner instead of creating a parallel root +directory, and run `bun run audit:layout` after adding or moving directories. + ### Comment Style Keep comments short — default to one line. AI-authored comments over-explain by @@ -188,27 +197,36 @@ GraphQL Schema ─┬─► graphql-codegen + AST guards ─► TypeScript `main` using the bump type relative to its stable metadata. - Read `.claude/commands/release.md` before any package deployment. -## Using Claude Code with Context +## Shared Agent Context ```bash cd scripts/agent -# Compile for AI assistants (no Ollama required) +# Compile shared context for AI assistants (no Ollama required) bun run compile:ai -# Or compile for both Claude Code + Local RAG +# Or compile for both AI assistants + Local RAG bun run compile - -# Use with Claude Code -claude --context knowledge/_claude-context/context.md ``` -## Codex Compatibility +## Shared Agent Configuration + +`AGENTS.md` is the root project instruction SSOT. Codex and Grok read it +directly; `CLAUDE.md` and `GEMINI.md` are compatibility symlinks to the same +file. Every framework library follows the same pattern with a local canonical +`AGENTS.md`. The `.claude/commands/`, `.claude/skills/`, `.codex/skills/`, and +`.cursor/rules/` files remain thin tool-discovery adapters where their host +formats genuinely differ; they must route back to the shared instructions and +workflow sources instead of copying project policy. -`AGENTS.md` is the root project instruction SSOT. `CLAUDE.md` and `GEMINI.md` -are symlinks to `AGENTS.md`, so Claude Code, Gemini, and Codex read the same -root instructions. The `.claude/commands/` files remain the workflow SSOT for -slash-command-style tasks. +The canonical compiled reference is +`knowledge/_agent-context/context.md`. It supports audits, local RAG, and +on-demand reading; assistant project rules are discovered through the root +instruction files above. The legacy `knowledge/_claude-context` path is a +compatibility symlink, so existing paths continue to work without creating a +second generated copy. + +## Codex Compatibility Codex supports Skills through `SKILL.md` folders. This repo provides Codex-compatible local skills in `.codex/skills/`, including @@ -231,6 +249,13 @@ Keep `$review-self` and `$loop-review` repo-local. Their review, merge, and release-safety policies are project-specific; globally linking them could apply the wrong repository workflow elsewhere. +## Grok Compatibility + +Grok Build reads the repository's `AGENTS.md` hierarchy directly and supports +the Claude Code command, skill, plugin, and marketplace layout. Do not add a +parallel `GROK.md`; keep shared rules in `AGENTS.md` and tool-specific adapters +thin. See the [xAI skills and plugins documentation](https://docs.x.ai/build/features/skills-plugins-marketplaces). + ## Claude Code Compatibility Claude Code gets the same workflow surface without any install step: @@ -278,7 +303,7 @@ Cursor-specific files. | `/review-pr` | Review PR comments, fix issues, resolve threads | `/review-pr 65` or `/review-pr ` | | `/audit-code` | Audit code against knowledge rules and latest APIs | `/audit-code` | | `/audit-security` | Audit SBOM, provenance, and supply-chain posture | `/audit-security` | -| `/compile-knowledge` | Compile knowledge base for Claude context | `/compile-knowledge` | +| `/compile-knowledge` | Compile the shared AI agent context | `/compile-knowledge` | | `/resolve-issue` | Analyze an issue, label it, and fix/comment | `/resolve-issue 88` | | `/verify-all` | Run the full monorepo health check | `/verify-all` | | `/e2e-tests` | Run device-backed OpenIAP regression tests | `/e2e-tests PR 162` | diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 55dee543a..a626eb95b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -85,14 +85,14 @@ second type-copy command or maintain another target list. ### Working on a Specific Library -Each library has its own `CLAUDE.md` with detailed conventions and development instructions: - -- `libraries/react-native-iap/CLAUDE.md` -- Nitro Modules, useIAP hook, error handling -- `libraries/expo-iap/CLAUDE.md` -- Expo Modules, iOS podspec workaround, tvOS support -- `libraries/flutter_inapp_purchase/CLAUDE.md` -- Generated types.dart, fetchProducts generic API -- `libraries/godot-iap/CLAUDE.md` -- GDExtension (iOS), AAR plugin (Android) -- `libraries/kmp-iap/CLAUDE.md` -- Flow-based API, CocoaPods iOS integration -- `libraries/maui-iap/CLAUDE.md` -- .NET MAUI / C#, generated Types.cs, native bindings +Each library has its own canonical `AGENTS.md` with detailed conventions and development instructions. `CLAUDE.md` and `GEMINI.md` are compatibility links to it: + +- `libraries/react-native-iap/AGENTS.md` -- Nitro Modules, useIAP hook, error handling +- `libraries/expo-iap/AGENTS.md` -- Expo Modules, iOS podspec workaround, tvOS support +- `libraries/flutter_inapp_purchase/AGENTS.md` -- Generated types.dart, fetchProducts generic API +- `libraries/godot-iap/AGENTS.md` -- GDExtension (iOS), AAR plugin (Android) +- `libraries/kmp-iap/AGENTS.md` -- Flow-based API, CocoaPods iOS integration +- `libraries/maui-iap/AGENTS.md` -- .NET MAUI / C#, generated Types.cs, native bindings Libraries reference local `packages/apple` and `packages/google` source during development. Published packages use CocoaPods/Maven Central for native dependencies. diff --git a/README.md b/README.md index accc23d18..b0112306c 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ This monorepo contains all OpenIAP packages: - **[spec](packages/gql)** - OpenIAP specification and type generation [![Spec Release](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2Fhyodotdev%2Fopeniap%2Fmain%2Fopeniap-versions.json&query=%24.spec&label=version&logo=graphql&color=purple&prefix=v)](https://github.com/hyodotdev/openiap/blob/main/openiap-versions.json) - **[google](packages/google)** - Android library [![Maven Central (Play)](https://img.shields.io/maven-central/v/io.github.hyochan.openiap/openiap-google?label=Play%20Store)](https://central.sonatype.com/artifact/io.github.hyochan.openiap/openiap-google) [![Maven Central (Horizon)](https://img.shields.io/maven-central/v/io.github.hyochan.openiap/openiap-google-horizon?label=Meta%20Horizon)](https://central.sonatype.com/artifact/io.github.hyochan.openiap/openiap-google-horizon) [![CI](https://github.com/hyodotdev/openiap/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/hyodotdev/openiap/actions/workflows/ci.yml?query=branch%3Amain) - **[apple](packages/apple)** - iOS/macOS library [![Swift Package](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2Fhyodotdev%2Fopeniap%2Fmain%2Fopeniap-versions.json&query=%24.apple&label=version&logo=swift&color=orange&prefix=v)](https://github.com/hyodotdev/openiap/releases?q=Apple&expanded=true) [![CocoaPods](https://img.shields.io/cocoapods/v/openiap?color=E35A5F&logo=cocoapods)](https://cocoapods.org/pods/openiap) [![CI](https://github.com/hyodotdev/openiap/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/hyodotdev/openiap/actions/workflows/ci.yml?query=branch%3Amain) -- **[kit](packages/kit)** - Hosted receipt-validation backend (SaaS + dashboard at [kit.openiap.dev](https://kit.openiap.dev)). Free for every developer under hosted fair-use safeguards. [![Kit CI](https://github.com/hyodotdev/openiap/actions/workflows/deploy-kit.yml/badge.svg?branch=main)](https://github.com/hyodotdev/openiap/actions/workflows/deploy-kit.yml?query=branch%3Amain) +- **[kit](packages/kit)** - Open-source purchase validation and entitlement infrastructure for the OpenIAP ecosystem, with a hosted service and dashboard at [kit.openiap.dev](https://kit.openiap.dev). Free for every developer under hosted fair-use safeguards. [![Kit CI](https://github.com/hyodotdev/openiap/actions/workflows/deploy-kit.yml/badge.svg?branch=main)](https://github.com/hyodotdev/openiap/actions/workflows/deploy-kit.yml?query=branch%3Amain) - **[mcp-server](packages/mcp-server)** - IAPKit MCP server, hosted at [kit.openiap.dev/mcp](https://kit.openiap.dev/mcp) for AI coding agents ## Libraries @@ -85,7 +85,14 @@ For bug reports, please [open an issue](https://github.com/hyodotdev/openiap/iss

- Meta + Meta + +        + + + + Amazon Developer +

diff --git a/bun.lock b/bun.lock index a379f8c0d..a5f2c9a5c 100644 --- a/bun.lock +++ b/bun.lock @@ -145,7 +145,7 @@ "eslint-plugin-react-hooks": "^5.1.0", "eslint-plugin-react-refresh": "^0.5.2", "globals": "^15.15.0", - "jsdom": "^30", + "jsdom": "29.1.1", "lint-staged": "^16.1.5", "npm-run-all": "^4.1.5", "postcss": "~8.5.26", @@ -213,9 +213,13 @@ "@ardatan/relay-compiler": ["@ardatan/relay-compiler@13.0.2", "", { "dependencies": { "@babel/runtime": "^8.0.0", "immutable": "^5.1.9", "invariant": "^2.2.4" }, "peerDependencies": { "graphql": "*" } }, "sha512-VFpv9UP820SiwDUPYtq7PmD3jifzZlevkQ26bhbSzFeruSTys0eHzQCZyKg+IhgmZzwPI9AFjPe26ABNjGeIKg=="], - "@asamuzakjp/css-color": ["@asamuzakjp/css-color@6.0.7", "", { "dependencies": { "@csstools/css-calc": "^3.3.0", "@csstools/css-color-parser": "^4.1.10", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "lru-cache": "^11.5.2" } }, "sha512-vC/bk1Lz7Tn/EfU9/apOTBk80/8dyGyWMowPoV1tJ52muDGsDqt2HPT2klrFUiY60MQmQv9q8yIht15JnBgDGw=="], + "@asamuzakjp/css-color": ["@asamuzakjp/css-color@5.1.11", "", { "dependencies": { "@asamuzakjp/generational-cache": "^1.0.1", "@csstools/css-calc": "^3.2.0", "@csstools/css-color-parser": "^4.1.0", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" } }, "sha512-KVw6qIiCTUQhByfTd78h2yD1/00waTmm9uy/R7Ck/ctUyAPj+AEDLkQIdJW0T8+qGgj3j5bpNKK7Q3G+LedJWg=="], - "@asamuzakjp/dom-selector": ["@asamuzakjp/dom-selector@8.3.2", "", { "dependencies": { "bidi-js": "^1.0.3", "css-tree": "^3.2.1", "is-potential-custom-element-name": "^1.0.1", "lru-cache": "^11.5.2" } }, "sha512-93Z1N+BQNXysodoicpOIyNh2drHfz/CTf9nnT0FEx72GJcIiwgydD7tGAr78j41LsYn3hlRn+LdGPuBLn1Bl8Q=="], + "@asamuzakjp/dom-selector": ["@asamuzakjp/dom-selector@7.1.1", "", { "dependencies": { "@asamuzakjp/generational-cache": "^1.0.1", "@asamuzakjp/nwsapi": "^2.3.9", "bidi-js": "^1.0.3", "css-tree": "^3.2.1", "is-potential-custom-element-name": "^1.0.1" } }, "sha512-67RZDnYRc8H/8MLDgQCDE//zoqVFwajkepHZgmXrbwybzXOEwOWGPYGmALYl9J2DOLfFPPs6kKCqmbzV895hTQ=="], + + "@asamuzakjp/generational-cache": ["@asamuzakjp/generational-cache@1.0.1", "", {}, "sha512-wajfB8KqzMCN2KGNFdLkReeHncd0AslUSrvHVvvYWuU8ghncRJoA50kT3zP9MVL0+9g4/67H+cdvBskj9THPzg=="], + + "@asamuzakjp/nwsapi": ["@asamuzakjp/nwsapi@2.3.9", "", {}, "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q=="], "@auth/core": ["@auth/core@0.41.3", "", { "dependencies": { "@panva/hkdf": "^1.2.1", "jose": "^6.0.6", "oauth4webapi": "^3.3.0", "preact": "10.24.3", "preact-render-to-string": "6.5.11" }, "peerDependencies": { "@simplewebauthn/browser": "^9.0.1", "@simplewebauthn/server": "^9.0.2", "nodemailer": "^7.0.7 || ^8.0.5" }, "optionalPeers": ["@simplewebauthn/browser", "@simplewebauthn/server", "nodemailer"] }, "sha512-sJ3JMHHkXMD3aOjopv7mOBTO1Ocw4b0fAEXJBz6k7YHLpYQI6C40jCUPc5fNvUKxXRXNE1/sRISA15UrwWJBTw=="], @@ -1667,7 +1671,7 @@ "js-yaml": ["js-yaml@4.3.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ=="], - "jsdom": ["jsdom@30.0.1", "", { "dependencies": { "@asamuzakjp/css-color": "^6.0.5", "@asamuzakjp/dom-selector": "^8.3.0", "@bramus/specificity": "^2.4.2", "@csstools/css-syntax-patches-for-csstree": "^1.1.7", "@exodus/bytes": "^1.15.1", "css-tree": "^3.2.1", "data-urls": "^7.0.0", "decimal.js": "^10.6.0", "html-encoding-sniffer": "^6.0.0", "is-potential-custom-element-name": "^1.0.1", "lru-cache": "^11.5.2", "parse5": "^8.0.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^6.0.2", "undici": "^8.9.0", "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^8.0.1", "whatwg-mimetype": "^5.0.0", "whatwg-url": "^17.1.0", "xml-name-validator": "^5.0.0" }, "peerDependencies": { "canvas": "^3.2.3" }, "optionalPeers": ["canvas"] }, "sha512-52v7mUVUfNQVYYqE1lcdaymWL0njO7lTLUog6ZvW2U5KsbiLk/GnZlVJ+qx0xfNJZ6Gn+KSpPNE52vurbxZwrA=="], + "jsdom": ["jsdom@29.1.1", "", { "dependencies": { "@asamuzakjp/css-color": "^5.1.11", "@asamuzakjp/dom-selector": "^7.1.1", "@bramus/specificity": "^2.4.2", "@csstools/css-syntax-patches-for-csstree": "^1.1.3", "@exodus/bytes": "^1.15.0", "css-tree": "^3.2.1", "data-urls": "^7.0.0", "decimal.js": "^10.6.0", "html-encoding-sniffer": "^6.0.0", "is-potential-custom-element-name": "^1.0.1", "lru-cache": "^11.3.5", "parse5": "^8.0.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^6.0.1", "undici": "^7.25.0", "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^8.0.1", "whatwg-mimetype": "^5.0.0", "whatwg-url": "^16.0.1", "xml-name-validator": "^5.0.0" }, "peerDependencies": { "canvas": "^3.0.0" }, "optionalPeers": ["canvas"] }, "sha512-ECi4Fi2f7BdJtUKTflYRTiaMxIB0O6zfR1fX0GXpUrf6flp8QIYn1UT20YQqdSOfk2dfkCwS8LAFoJDEppNK5Q=="], "jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="], @@ -2361,7 +2365,7 @@ "unc-path-regex": ["unc-path-regex@0.1.2", "", {}, "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg=="], - "undici": ["undici@8.10.0", "", {}, "sha512-HvltHd7avK13QIw/oLe4qoOLyoVSoafqJ2jYOrtMRBkbYT31eiBQ8O0ehRKZiEZCMEyLFQNIADpgCWC5fALvYQ=="], + "undici": ["undici@7.29.0", "", {}, "sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw=="], "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], @@ -2419,7 +2423,7 @@ "whatwg-mimetype": ["whatwg-mimetype@5.0.0", "", {}, "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw=="], - "whatwg-url": ["whatwg-url@17.1.0", "", { "dependencies": { "@exodus/bytes": "^1.15.1", "tr46": "^6.0.0", "webidl-conversions": "^8.0.1" } }, "sha512-3GeworPmc2ZfEEHP7lEbUfBX/L75wdEsi0rLNhXcXxnoN5jyq0SL5gCy06SGW2cyTIZdTvWIDQNQoza++vKeaw=="], + "whatwg-url": ["whatwg-url@16.0.1", "", { "dependencies": { "@exodus/bytes": "^1.11.0", "tr46": "^6.0.0", "webidl-conversions": "^8.0.1" } }, "sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw=="], "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], @@ -2585,8 +2589,6 @@ "convex/esbuild": ["esbuild@0.27.0", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.0", "@esbuild/android-arm": "0.27.0", "@esbuild/android-arm64": "0.27.0", "@esbuild/android-x64": "0.27.0", "@esbuild/darwin-arm64": "0.27.0", "@esbuild/darwin-x64": "0.27.0", "@esbuild/freebsd-arm64": "0.27.0", "@esbuild/freebsd-x64": "0.27.0", "@esbuild/linux-arm": "0.27.0", "@esbuild/linux-arm64": "0.27.0", "@esbuild/linux-ia32": "0.27.0", "@esbuild/linux-loong64": "0.27.0", "@esbuild/linux-mips64el": "0.27.0", "@esbuild/linux-ppc64": "0.27.0", "@esbuild/linux-riscv64": "0.27.0", "@esbuild/linux-s390x": "0.27.0", "@esbuild/linux-x64": "0.27.0", "@esbuild/netbsd-arm64": "0.27.0", "@esbuild/netbsd-x64": "0.27.0", "@esbuild/openbsd-arm64": "0.27.0", "@esbuild/openbsd-x64": "0.27.0", "@esbuild/openharmony-arm64": "0.27.0", "@esbuild/sunos-x64": "0.27.0", "@esbuild/win32-arm64": "0.27.0", "@esbuild/win32-ia32": "0.27.0", "@esbuild/win32-x64": "0.27.0" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-jd0f4NHbD6cALCyGElNpGAOtWxSq46l9X/sWB0Nzd5er4Kz2YTm+Vl0qKFT9KUJvD8+fiO8AvoHhFvEatfVixA=="], - "data-urls/whatwg-url": ["whatwg-url@16.0.1", "", { "dependencies": { "@exodus/bytes": "^1.11.0", "tr46": "^6.0.0", "webidl-conversions": "^8.0.1" } }, "sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw=="], - "dir-glob/path-type": ["path-type@4.0.0", "", {}, "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="], "dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], diff --git a/gql/.vscode/settings.json b/gql/.vscode/settings.json deleted file mode 100644 index c1659144e..000000000 --- a/gql/.vscode/settings.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "cSpell.words": [ - "apollographql", - "codegen", - "gradlew", - "openiap", - "preorder", - "pubspec", - "skus" - ] -} \ No newline at end of file diff --git a/knowledge/README.md b/knowledge/README.md index 2ccf1eaff..745ddd14e 100644 --- a/knowledge/README.md +++ b/knowledge/README.md @@ -2,7 +2,7 @@ This is the **Single Source of Truth (SSOT)** for all AI agents working on this project. -## Architecture: "Shared Brain, Dual Body" +## Architecture: One Shared Brain ``` ┌─────────────────────────────────────────────────────────────────────────────┐ @@ -10,7 +10,7 @@ This is the **Single Source of Truth (SSOT)** for all AI agents working on this │ /knowledge/ │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ -│ /internal/ /external/ /_claude-context/ │ +│ /internal/ /external/ /_agent-context/ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ Project │ │ StoreKit 2 │ │ context.md │ │ │ │ Philosophy │ │ Google │ │ (compiled) │ │ @@ -21,11 +21,11 @@ This is the **Single Source of Truth (SSOT)** for all AI agents working on this │ │ │ ▼ ▼ ▼ ┌─────────────────────────────────┐ ┌─────────────────────┐ - │ LOCAL RAG AGENT │ │ CLAUDE CODE │ + │ LOCAL RAG AGENT │ │ AI ASSISTANTS │ │ ┌─────────────────────────┐ │ │ │ - │ │ LanceDB │ │ │ claude --context │ - │ │ • internal_rule │ │ │ context.md │ - │ │ • external_api │ │ │ │ + │ │ LanceDB │ │ │ AGENTS.md (SSOT) │ + │ │ • internal_rule │ │ │ CLAUDE.md symlink │ + │ │ • external_api │ │ │ GEMINI.md symlink │ │ │ • code_map │ │ │ │ │ └─────────────────────────┘ │ │ │ │ │ │ │ │ @@ -62,8 +62,9 @@ knowledge/ ├── archive/ # Historical references; not indexed │ ├── expo-iap-api.md # Archived legacy expo-iap API │ └── react-native-iap-api.md # Archived legacy react-native-iap API -└── _claude-context/ # COMPILED - For Claude Code CLI - └── context.md # Auto-generated combined context +├── _agent-context/ # COMPILED - Shared agent context +│ └── context.md # Auto-generated combined context +└── _claude-context -> _agent-context # Backward-compatible alias ``` ## Usage @@ -73,23 +74,21 @@ knowledge/ ```bash cd scripts/agent -# Compile for both Claude Code + Local RAG +# Compile for AI assistants + Local RAG bun run compile ``` -### For Claude Code Only +### For AI Assistants ```bash cd scripts/agent -# Compile context.md for Claude Code +# Compile the shared context.md bun run compile:ai -# Use with Claude Code -claude --context knowledge/_claude-context/context.md - -# Or in an existing session -/context add knowledge/_claude-context/context.md +# Repository-aware assistants discover the root instruction files: +# AGENTS.md (Codex and Grok), CLAUDE.md, and GEMINI.md. +# CLAUDE.md and GEMINI.md are symlinks to the AGENTS.md SSOT. ``` ### For Local RAG Agent (Challenger) @@ -108,19 +107,21 @@ bun run benchmark --prompt "Add iOS subscription validation" ## Knowledge Priority -| Priority | Type | Source | Purpose | -|----------|------|--------|---------| -| 1 (Highest) | `internal_rule` | `/internal/` | MUST follow exactly | -| 2 | `code_map` | Project scan | Code structure reference | -| 3 | `external_api` | `/external/` | API reference (adapt to internal rules) | +| Priority | Type | Source | Purpose | +| ----------- | --------------- | ------------ | --------------------------------------- | +| 1 (Highest) | `internal_rule` | `/internal/` | MUST follow exactly | +| 2 | `code_map` | Project scan | Code structure reference | +| 3 | `external_api` | `/external/` | API reference (adapt to internal rules) | ## Workflow: Hybrid Mode Testing 1. **Define Task**: Write the feature request 2. **Run Both**: - - Claude Code with `--context knowledge/_claude-context/context.md` + - Any repository-aware assistant from the repository root. Codex and Grok + discover `AGENTS.md`; Claude Code and Gemini follow the compatibility + symlinks to the same SSOT. - Local Agent: `bun run benchmark --prompt "..."` -3. **Compare**: Check `_generated/` vs Claude Code's output +3. **Compare**: Check `_generated/` against the selected assistant's output 4. **Evaluate**: Does local agent follow all `internal_rule`? 5. **Iterate**: Improve knowledge files if needed @@ -135,6 +136,6 @@ cd scripts/agent bun run compile # Or individually: -bun run compile:ai # Claude Code context.md +bun run compile:ai # Shared agent context.md bun run compile:local # Local RAG LanceDB index ``` diff --git a/knowledge/_claude-context/context.md b/knowledge/_agent-context/context.md similarity index 99% rename from knowledge/_claude-context/context.md rename to knowledge/_agent-context/context.md index cd1f62154..23cc2b3df 100644 --- a/knowledge/_claude-context/context.md +++ b/knowledge/_agent-context/context.md @@ -1,9 +1,9 @@ # OpenIAP Project Context -> **Auto-generated for Claude Code** -> Last updated: 2026-08-13T01:31:14.251Z +> **Auto-generated shared context for AI assistants** +> Last updated: 2026-08-18T17:50:47.669Z > -> Usage: `claude --context knowledge/_claude-context/context.md` +> Canonical file: `knowledge/_agent-context/context.md` --- @@ -287,11 +287,12 @@ const IsSubscription: boolean; // No PascalCase for variables ``` openiap/ ├── packages/ +│ ├── conformance/ # Behavioral conformance spec, runner, and reports │ ├── docs/ # Documentation (React/Vite/Vercel) │ ├── gql/ # GraphQL schema & type generation │ ├── google/ # Android library (Kotlin) │ ├── apple/ # iOS/macOS library (Swift) -│ ├── kit/ # Hosted receipt-validation SaaS (Fly.io app) +│ ├── kit/ # Purchase validation + entitlement infrastructure (Fly.io app) │ └── mcp-server/ # IAPKit MCP server (hosted at kit.openiap.dev/mcp) ├── plugins/ │ └── openiap/ # Codex + Claude Code plugin (skills + MCP config) @@ -305,7 +306,8 @@ openiap/ ├── knowledge/ # Shared knowledge base (SSOT) │ ├── internal/ # Project philosophy (HIGHEST PRIORITY) │ ├── external/ # External API reference -│ └── _claude-context/ # Compiled context for Claude Code +│ ├── _agent-context/ # Compiled context shared by AI assistants +│ └── _claude-context/ # Compatibility link to _agent-context ├── scripts/ │ └── agent/ # RAG Agent scripts └── .github/workflows/ # CI/CD workflows @@ -313,6 +315,31 @@ openiap/ Libraries reference local `packages/apple` and `packages/google` source directly (not published CocoaPods/Maven artifacts), enabling immediate development without waiting for native releases. +## Directory Ownership Guardrail + +Keep each project surface under its canonical owner: + +| Content | Canonical location | +| ------------------------------------------------ | ----------------------- | +| Deployable packages and native implementations | `packages//` | +| Framework SDKs | `libraries//` | +| Agent integrations distributed to users | `plugins//` | +| Behavioral conformance spec, runner, and reports | `packages/conformance/` | +| Repository knowledge | `knowledge/` | +| Repository-wide automation | `scripts/` | +| Shared editor settings | `.vscode/` | + +- Never create a root directory that duplicates a child of `packages/`, + `libraries/`, or `plugins/`. For example, use `packages/docs/` and + `packages/gql/`, never root `docs/` or `gql/`. +- Before adding a top-level directory, search for an existing owner and extend + it. Add a new root only when no canonical owner fits, and document that owner + in this section in the same change. +- Keep shared editor settings in root `.vscode/`. Package-specific settings are + allowed only when they apply exclusively to that package's toolchain. +- Run `bun run audit:layout` after directory changes. Pre-commit and CI enforce + the same audit; do not weaken it to permit a duplicate owner. + ## Package Responsibilities ### packages/gql diff --git a/knowledge/_claude-context b/knowledge/_claude-context new file mode 120000 index 000000000..407a1fc34 --- /dev/null +++ b/knowledge/_claude-context @@ -0,0 +1 @@ +_agent-context \ No newline at end of file diff --git a/knowledge/internal/02-architecture.md b/knowledge/internal/02-architecture.md index af4ca15e3..b3535ec22 100644 --- a/knowledge/internal/02-architecture.md +++ b/knowledge/internal/02-architecture.md @@ -8,11 +8,12 @@ ``` openiap/ ├── packages/ +│ ├── conformance/ # Behavioral conformance spec, runner, and reports │ ├── docs/ # Documentation (React/Vite/Vercel) │ ├── gql/ # GraphQL schema & type generation │ ├── google/ # Android library (Kotlin) │ ├── apple/ # iOS/macOS library (Swift) -│ ├── kit/ # Hosted receipt-validation SaaS (Fly.io app) +│ ├── kit/ # Purchase validation + entitlement infrastructure (Fly.io app) │ └── mcp-server/ # IAPKit MCP server (hosted at kit.openiap.dev/mcp) ├── plugins/ │ └── openiap/ # Codex + Claude Code plugin (skills + MCP config) @@ -26,7 +27,8 @@ openiap/ ├── knowledge/ # Shared knowledge base (SSOT) │ ├── internal/ # Project philosophy (HIGHEST PRIORITY) │ ├── external/ # External API reference -│ └── _claude-context/ # Compiled context for Claude Code +│ ├── _agent-context/ # Compiled context shared by AI assistants +│ └── _claude-context/ # Compatibility link to _agent-context ├── scripts/ │ └── agent/ # RAG Agent scripts └── .github/workflows/ # CI/CD workflows @@ -34,6 +36,31 @@ openiap/ Libraries reference local `packages/apple` and `packages/google` source directly (not published CocoaPods/Maven artifacts), enabling immediate development without waiting for native releases. +## Directory Ownership Guardrail + +Keep each project surface under its canonical owner: + +| Content | Canonical location | +| ------------------------------------------------ | ----------------------- | +| Deployable packages and native implementations | `packages//` | +| Framework SDKs | `libraries//` | +| Agent integrations distributed to users | `plugins//` | +| Behavioral conformance spec, runner, and reports | `packages/conformance/` | +| Repository knowledge | `knowledge/` | +| Repository-wide automation | `scripts/` | +| Shared editor settings | `.vscode/` | + +- Never create a root directory that duplicates a child of `packages/`, + `libraries/`, or `plugins/`. For example, use `packages/docs/` and + `packages/gql/`, never root `docs/` or `gql/`. +- Before adding a top-level directory, search for an existing owner and extend + it. Add a new root only when no canonical owner fits, and document that owner + in this section in the same change. +- Keep shared editor settings in root `.vscode/`. Package-specific settings are + allowed only when they apply exclusively to that package's toolchain. +- Run `bun run audit:layout` after directory changes. Pre-commit and CI enforce + the same audit; do not weaken it to permit a duplicate owner. + ## Package Responsibilities ### packages/gql diff --git a/libraries/expo-iap/AGENTS.md b/libraries/expo-iap/AGENTS.md deleted file mode 120000 index 681311eb9..000000000 --- a/libraries/expo-iap/AGENTS.md +++ /dev/null @@ -1 +0,0 @@ -CLAUDE.md \ No newline at end of file diff --git a/libraries/expo-iap/AGENTS.md b/libraries/expo-iap/AGENTS.md new file mode 100644 index 000000000..f05608dd4 --- /dev/null +++ b/libraries/expo-iap/AGENTS.md @@ -0,0 +1,259 @@ +# Implementation Guidelines + +## Commit Message Convention + +- Follow the Angular Conventional Commits format: `(): ` +- Allowed types: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `chore` +- Scope is optional but recommended (for example: `auth`, `api`, `ui`) +- Subject must be imperative, lowercase, without a trailing period, and roughly 50 characters +- Wrap commit body lines near 72 characters and include footers such as `BREAKING CHANGE:` or `Closes #123` when needed + +## Tooling & Package Management + +- **Use Bun exclusively.** Run installs with `bun install`, scripts with `bun run