Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/docs-health.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
name: Documentation health

on:
pull_request:
schedule:
- cron: '17 9 * * 1'
workflow_dispatch:
Expand Down Expand Up @@ -29,12 +30,13 @@ jobs:
run: npm run validate

- name: Compare docs with the latest PAM release
if: github.event_name != 'pull_request'
env:
GITHUB_TOKEN: ${{ github.token }}
run: npm run check:freshness

- name: Open or update a maintenance issue
if: failure()
if: failure() && github.event_name == 'schedule'
uses: actions/github-script@v8
with:
script: |
Expand Down
24 changes: 9 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,35 +23,29 @@ every public component contract—documented in one place.**

---

PAM is not one binary with a few side projects. It is a coherent PHP
application platform spanning persistent servers, Laravel production
operations, real native mobile interfaces, secure desktop applications, and a
PAM-first package ecosystem that remains fully compatible with Composer.
PAM itself is the small persistent PHP runtime and process boundary. HTTP,
Laravel, Native, Desktop, UI and integrations are independent Composer
products built on top of that runtime—like packages around Node.js.

## Source repositories

- [PAM runtime](https://github.com/push-in/pam)
- [PAM Native core](https://github.com/push-in/pam-native)
- [PAM Mobile UI](https://github.com/push-in/pam-mobile-ui)
- [PAM Native UI](https://github.com/push-in/pam-native-ui)
- [PAM Native Nitro](https://github.com/push-in/pam-native-nitro)
- [PAM Desktop](https://github.com/push-in/pam-desktop)
- [Laravel on PAM](https://github.com/push-in/pam-laravel)

Official capabilities are installed through the PAM CLI:
Install PAM once, then use Composer through its bundled PHP runtime:

```bash
pam packages
pam add auth
pam add maps
pam add observability
curl -fsSL https://push-in.github.io/pam/install.sh | sh
pam doctor
pam composer require pushinbr/pam-native-auth
```

PAM performs package metadata lookup, dependency compatibility preflight,
updates the normal Composer manifest and lockfile, and refreshes native
integration where required. Package authors and advanced interoperability flows
can still use `pam composer`; application documentation should lead with
`pam add <capability>` whenever an official alias exists.
`pam composer` is the canonical ecosystem workflow. Packages use the normal
`composer.json`, `composer.lock`, Packagist metadata and `vendor/bin` tools.

This repository explains that platform without hiding the hard parts. The
documentation records public APIs, architectural ownership, lifecycle,
Expand Down
6 changes: 3 additions & 3 deletions astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -202,11 +202,11 @@ export default defineConfig({
label: 'Packages',
items: [
{ label: 'Package ecosystem', slug: 'packages/overview' },
{ label: 'pushinbr/pam-api', slug: 'packages/api' },
{ label: 'pushinbr/pam-http', slug: 'packages/http' },
{ label: 'pushinbr/pam-socket', slug: 'packages/socket' },
{ label: 'pushinbr/pam-psr-bridge', slug: 'packages/psr-bridge' },
{ label: 'pushinbr/pam-psr', slug: 'packages/psr' },
{ label: 'pushinbr/pam-testing', slug: 'packages/testing' },
{ label: 'pushinbr/pam-core-api', slug: 'packages/core-api' },
{ label: 'pushinbr/pam-contracts', slug: 'packages/contracts' },
{ label: 'PAM Native Nitro', slug: 'packages/native-nitro' },
{ label: 'Application skeleton', slug: 'packages/skeleton' },
{ label: 'Distribution mirrors', slug: 'packages/distribution-mirrors' },
Expand Down
17 changes: 13 additions & 4 deletions public/schemas/pam.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,19 @@
{
"type": "object",
"additionalProperties": false,
"required": ["script"],
"properties": {
"script": {"type": "string", "minLength": 1},
"description": {"type": "string", "maxLength": 240}
"oneOf": [
{"required": ["script"]},
{"required": ["bin"]}
],
"properties": {
"script": {"type": "string", "minLength": 1},
"bin": {"type": "string", "minLength": 1},
"arguments": {
"type": "array",
"maxItems": 32,
"items": {"type": "string", "maxLength": 4096}
},
"description": {"type": "string", "maxLength": 240}
}
}
]
Expand Down
29 changes: 20 additions & 9 deletions scripts/check-repository-coverage.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ const root = resolve(import.meta.dirname, '..');
const docs = join(root, 'src', 'content', 'docs');
const requiredRepositories = [
'pam',
'pam-api',
'pam-core-api',
'pam-http',
'pam-contracts',
'pam-desktop',
'pam-docs',
'pam-laravel',
'pam-mobile-ui',
'pam-mobile-ui-php',
'pam-native-ui',
'pam-native-ui-php',
'pam-native',
'pam-native-auth',
'pam-native-background-transfer',
Expand All @@ -21,7 +21,7 @@ const requiredRepositories = [
'pam-native-firebase',
'pam-native-health',
'pam-native-intents',
'pam-native-laravel-sync',
'pam-native-sync-laravel',
'pam-native-live-activities',
'pam-native-maps',
'pam-native-media',
Expand All @@ -39,19 +39,30 @@ const requiredRepositories = [
'pam-native-testing',
'pam-native-video',
'pam-native-widgets',
'pam-psr-bridge',
'pam-psr',
'pam-skeleton',
'pam-socket',
'pam-testing',
];
const compatibilityRepositories = [
'pam-api',
'pam-core-api',
'pam-mobile-ui',
'pam-native-laravel-sync',
'pam-psr-bridge',
];
const documentedRepositories = [
...requiredRepositories,
...compatibilityRepositories,
];

const mapPath = join(docs, 'project', 'repository-map.mdx');
if (!existsSync(mapPath)) {
throw new Error('The public repository map is missing.');
}

const map = readFileSync(mapPath, 'utf8');
const missing = requiredRepositories.filter(
const missing = documentedRepositories.filter(
(repository) => !map.includes(`\`${repository}\``),
);

Expand All @@ -65,7 +76,7 @@ const allDocs = walk(docs)
.map((path) => readFileSync(path, 'utf8'))
.join('\n');

const undocumented = requiredRepositories.filter(
const undocumented = documentedRepositories.filter(
(repository) => !allDocs.includes(repository),
);

Expand All @@ -74,7 +85,7 @@ if (undocumented.length > 0) {
process.exit(1);
}

console.log(`${requiredRepositories.length} public PAM repositories have documentation ownership.`);
console.log(`${requiredRepositories.length} canonical and ${compatibilityRepositories.length} compatibility repositories have documentation ownership.`);

function walk(directory) {
return readdirSync(directory, { withFileTypes: true }).flatMap((entry) => {
Expand Down
14 changes: 6 additions & 8 deletions src/components/PamEcosystem.astro
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ const capabilities = [
['firebase', 'Platform services', 'Analytics, Crashlytics, Remote Config, Messaging, and Installations.', 'pam-native-firebase'],
['health', 'Health', 'Health Connect and HealthKit authorization, reads, and writes.', 'pam-native-health'],
['intents', 'Platform integration', 'Android shortcuts and Apple App Intents for named routes.', 'pam-native-intents'],
['laravel-sync', 'Data & offline', 'Authenticated Laravel delta and mutation APIs for PAM Native Sync.', 'pam-native-laravel-sync'],
['laravel-sync', 'Data & offline', 'Authenticated Laravel delta and mutation APIs for PAM Native Sync.', 'pam-native-sync-laravel'],
['live-activities', 'Platform integration', 'ActivityKit Live Activities and Android ongoing notifications.', 'pam-native-live-activities'],
['maps', 'Location', 'Declarative Google Maps and MapKit cameras, markers, and overlays.', 'pam-native-maps'],
['media', 'Media', 'Native media inspection, thumbnails, and embedded camera capture.', 'pam-native-media'],
['mobile-ui', 'Interface', 'Retained Material Design 3 components for Android and iOS.', 'pam-mobile-ui'],
['mobile-ui', 'Interface', 'Retained Material Design 3 components for Android and iOS.', 'pam-native-ui'],
['nfc', 'Hardware', 'Lifecycle-safe NDEF reading and writing on Android and iOS.', 'pam-native-nfc'],
['nitro', 'Data & offline', 'Typed, reactive, offline-first data built for native workloads.', 'pam-native-nitro'],
['observability', 'Operations', 'Vendor-neutral spans, logs, metrics, crash context, and export.', 'pam-native-observability'],
Expand Down Expand Up @@ -40,10 +40,8 @@ const categories = [...new Map(
<h2>One command between idea and native capability.</h2>
<p>Choose what the product needs. PAM resolves compatibility, updates the project, and refreshes native integration through one predictable workflow.</p>
</div>
<pre aria-label="Install a PAM capability"><code><span>$</span> pam packages
<span>$</span> pam add observability
<pre aria-label="Install a PAM capability"><code><span>$</span> pam composer require pushinbr/pam-native-observability
<strong>✓</strong> Compatibility preflight passed
<strong>✓</strong> Native integration refreshed
<span>$</span> pam doctor</code></pre>
</div>

Expand All @@ -67,7 +65,7 @@ const categories = [...new Map(
<h3>{alias}</h3>
<p>{description}</p>
</div>
<code>pam add {alias}</code>
<code>pam composer require pushinbr/{repository}</code>
<div class="pam-catalog-links">
<a href={`https://github.com/push-in/${repository}`}>README <span aria-hidden="true">↗</span></a>
<a href={`https://github.com/push-in/${repository}/issues`}>Support <span aria-hidden="true">↗</span></a>
Expand All @@ -77,6 +75,6 @@ const categories = [...new Map(
</div>

<aside class="pam-catalog-note">
<strong>Remove safely.</strong>
<p>Use <code>pam remove &lt;capability&gt;</code>. PAM performs a dry-run dependency check, updates the project, refreshes native integration, and leaves diagnostics to <code>pam doctor</code>.</p>
<strong>Composer remains Composer.</strong>
<p>Use <code>pam composer remove vendor/package</code>. The normal Composer manifest and lockfile remain the only dependency authority.</p>
</aside>
32 changes: 16 additions & 16 deletions src/components/PamHome.astro
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const path = (value: string) => `${base}${value}`;
<em>ready</em>
</div>
<div class="pam-terminal-body">
<p><span>$</span> pam init orbit --template mobile</p>
<p><span>$</span> pam init orbit --template native</p>
<p class="pam-terminal-success"><span>✓</span> Project created</p>
<p class="pam-terminal-success"><span>✓</span> Native runtime ready</p>
<p><span>$</span> cd orbit &amp;&amp; pam dev</p>
Expand Down Expand Up @@ -80,7 +80,7 @@ const path = (value: string) => `${base}${value}`;
<path d="m0 35 155-56 155 56-155 56Z" fill="#fff4f1" stroke="#1e1e1e" stroke-width="2"/>
<path d="m0 35 155 56v92L0 127Z" fill="#ffc9c1" stroke="#1e1e1e" stroke-width="2"/>
<path d="m310 35-155 56v92l155-56Z" fill="#ff806f" stroke="#1e1e1e" stroke-width="2"/>
<text x="155" y="53" text-anchor="middle" fill="#ff2d20" font-size="28" font-weight="800">PHP 8.4</text>
<text x="155" y="53" text-anchor="middle" fill="#ff2d20" font-size="28" font-weight="800">PHP 8.5</text>
</g>
<g transform="translate(254 363)">
<path d="m0 35 155-56 155 56-155 56Z" fill="#ff493d" stroke="#1e1e1e" stroke-width="2"/>
Expand Down Expand Up @@ -127,7 +127,7 @@ const path = (value: string) => `${base}${value}`;
<a href={path('/runtime/http/')}>
<span>Server</span>
<strong>Persistent APIs &amp; realtime</strong>
<code>pam init app --template api</code>
<code>pam init app --template http</code>
<em>HTTP · WebSockets · async I/O <b aria-hidden="true">→</b></em>
</a>
<a href={path('/laravel/overview/')}>
Expand All @@ -139,7 +139,7 @@ const path = (value: string) => `${base}${value}`;
<a class="pam-path-featured" href={path('/native/overview/')}>
<span>Native mobile</span>
<strong>Real Android &amp; iOS UI from PHP</strong>
<code>pam init app --template mobile</code>
<code>pam init app --template native</code>
<em>UIKit · Android Views · no JS runtime <b aria-hidden="true">→</b></em>
</a>
<a href={path('/desktop/overview/')}>
Expand All @@ -155,19 +155,19 @@ const path = (value: string) => `${base}${value}`;
<div class="pam-ecosystem-copy">
<p class="pam-home-kicker">The capability shelf</p>
<h2 id="pam-ecosystem-title">Add the hard parts.<br/>Keep building the product.</h2>
<p>Every official capability installs through PAM, passes compatibility preflight, and keeps the normal Composer contract underneath.</p>
<p>Every official and community capability uses the same Composer contract and the same package-command extension model.</p>
<a class="pam-button pam-button-primary" href={path('/ecosystem/')}>Explore all 27 capabilities <span aria-hidden="true">→</span></a>
</div>
<div class="pam-capability-cloud" aria-label="Popular PAM Native capabilities">
<a href={path('/ecosystem/#auth')}><strong>auth</strong><code>pam add auth</code></a>
<a href={path('/ecosystem/#maps')}><strong>maps</strong><code>pam add maps</code></a>
<a href={path('/ecosystem/#observability')}><strong>observability</strong><code>pam add observability</code></a>
<a href={path('/ecosystem/#sync')}><strong>sync</strong><code>pam add sync</code></a>
<a href={path('/ecosystem/#video')}><strong>video</strong><code>pam add video</code></a>
<a href={path('/ecosystem/#payments')}><strong>payments</strong><code>pam add payments</code></a>
<a href={path('/ecosystem/#firebase')}><strong>firebase</strong><code>pam add firebase</code></a>
<a href={path('/ecosystem/#bluetooth')}><strong>bluetooth</strong><code>pam add bluetooth</code></a>
<a href={path('/ecosystem/#widgets')}><strong>widgets</strong><code>pam add widgets</code></a>
<a href={path('/ecosystem/#auth')}><strong>auth</strong><code>pushinbr/pam-native-auth</code></a>
<a href={path('/ecosystem/#maps')}><strong>maps</strong><code>pushinbr/pam-native-maps</code></a>
<a href={path('/ecosystem/#observability')}><strong>observability</strong><code>pushinbr/pam-native-observability</code></a>
<a href={path('/ecosystem/#sync')}><strong>sync</strong><code>pushinbr/pam-native-sync</code></a>
<a href={path('/ecosystem/#video')}><strong>video</strong><code>pushinbr/pam-native-video</code></a>
<a href={path('/ecosystem/#payments')}><strong>payments</strong><code>pushinbr/pam-native-payments</code></a>
<a href={path('/ecosystem/#firebase')}><strong>firebase</strong><code>pushinbr/pam-native-firebase</code></a>
<a href={path('/ecosystem/#bluetooth')}><strong>bluetooth</strong><code>pushinbr/pam-native-bluetooth</code></a>
<a href={path('/ecosystem/#widgets')}><strong>widgets</strong><code>pushinbr/pam-native-widgets</code></a>
</div>
</section>

Expand All @@ -178,7 +178,7 @@ const path = (value: string) => `${base}${value}`;
</div>
<div>
<p>
PAM embeds PHP 8.4 through the official Embed SAPI and keeps your application alive.
PAM embeds PHP 8.5 through the official Embed SAPI and keeps your application alive.
Composer stays familiar while Rust and Tokio own scheduling, native I/O, and process supervision.
It is not a workaround for PHP's past — it is a platform for what PHP can build next.
</p>
Expand Down Expand Up @@ -281,7 +281,7 @@ const path = (value: string) => `${base}${value}`;
</div>
</div>

<div class="pam-api-throughput">
<div class="pam-http-throughput">
<div>
<span>Persistent API hot path</span>
<strong>404,150.56 <small>req/s</small></strong>
Expand Down
5 changes: 3 additions & 2 deletions src/content/docs/community/security.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ Security reports should be handled privately so maintainers can investigate and

Until PAM reaches `1.0`, security fixes are released only for the latest tagged version.

PHP itself must remain on an upstream-supported PHP 8.4 patch release. A PAM bundle fixes the Embed runtime and extension set, but applications still need a release process for new PAM and PHP security updates.
PHP itself must remain on an upstream-supported PHP 8.5 patch release by
default. A PAM bundle fixes the Embed runtime and extension set, but applications
still need a release process for new PAM and PHP security updates.

## Report a vulnerability

Expand Down Expand Up @@ -67,4 +69,3 @@ PAM Desktop is alpha. Broader public distribution still requires product-specifi
## Dependencies

Run locked dependency audits and the release gates for the relevant repository. An audit result is evidence about known advisories in the exact dependency graph; it is not proof that the application contains no vulnerability.

20 changes: 16 additions & 4 deletions src/content/docs/desktop/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,35 @@ collects native effects, and returns the result.
<div><strong>Linux x86-64</strong><span>supported target</span></div>
</div>

## From zero to a real window
## Start here

PAM Desktop is a Composer ecosystem product running on the PAM runtime. Install
the runtime first; then create the project and install the desktop package with
PAM's Composer passthrough.

<Steps>
1. Create the application.
1. Install and verify PAM.

```bash
curl -fsSL https://push-in.github.io/pam/install.sh | sh
pam doctor
```

2. Create the application and install PAM Desktop.

```bash
pam init notes --template desktop
cd notes
pam composer require pushinbr/pam-desktop
```

2. Validate the machine and project contract.
3. Validate the machine and project contract.

```bash
pam desktop doctor
```

3. Start the persistent development session.
4. Start the persistent development session.

```bash
pam desktop dev
Expand Down
2 changes: 1 addition & 1 deletion src/content/docs/desktop/stability.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ verification and public artifact attestation.

- Linux x86-64;
- glibc baseline from Ubuntu 22.04;
- PHP 8.4 workers;
- PHP 8.5 workers by default, with PHP 8.4 compatibility certification;
- Rust 1.88 for rebuilding the host and SDK;
- supported X11 or Wayland environments in the pinned Winit/Servo stack.

Expand Down
4 changes: 2 additions & 2 deletions src/content/docs/getting-started/choose-a-target.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ not by fear that PHP can only live behind a request-response server.

| You want to build | Start with | Current boundary |
| --- | --- | --- |
| API or web service | `pam init my-api --template api` | PAM 1.0 on Linux x86_64/ARM64 |
| HTTP service | `pam init my-api --template http` | PAM 1.0 on Linux x86_64/ARM64 |
| Laravel application | `pam init my-app --template laravel` | Laravel 12 and 13 executable matrix |
| Real-time server | Add `--socket` to API or Laravel | Native RFC 6455 transport |
| Native application, low-level UI | `pam init my-app --template mobile` | Android API 26–36; generated iOS host and simulator certification |
| Native application, low-level UI | `pam init my-app --template native` | Android API 26–36; generated iOS host and simulator certification |
| Desktop application | `pam init my-app --template desktop` | Linux experimental; macOS/Windows planned |

## Server runtime
Expand Down
Loading