first commit

This commit is contained in:
npc0-hue
2026-07-11 14:56:10 +08:00
commit 7e05d0a4e7
660 changed files with 78119 additions and 0 deletions
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-07-03
@@ -0,0 +1,83 @@
## Context
The registry change added a validated game plugin manifest and marketplace-ready plugin metadata, but plugin pages still have only documentation-level bridge notes. The next backlog item needs a concrete contract that lets plugin UI request platform abilities without learning platform credentials, run connection details, host paths, storage backends, or AI provider keys.
The implementation spans three roots:
- `plugins/` owns the author-facing TypeScript SDK, manifest bridge declarations, and example plugin usage.
- `platform_web/` owns the browser host-side bridge contracts and utility checks used by future plugin pages.
- `platform/` owns the authoritative permission/session validation before privileged bridge requests are accepted.
## Goals / Non-Goals
**Goals:**
- Define a typed bridge request/response contract for plugin pages.
- Enforce bridge actions against manifest-declared plugin permissions and AI purposes.
- Provide SDK helpers for plugin authors to check permissions and build safe bridge requests.
- Add platform validators/services/API routes for bridge session and action authorization.
- Keep plugin pages mediated by platform APIs instead of direct run, socket, host path, credential, artifact storage, or AI provider access.
- Add tests proving forbidden bridge actions fail and allowed scoped actions pass.
**Non-Goals:**
- Do not implement plugin iframe loading or a complete marketplace UI in this change.
- Do not execute plugin lifecycle actions or server workflows end to end.
- Do not expose raw AI provider keys, run credentials, direct sockets, raw host paths, or storage backend endpoints.
- Do not add billing, cloud host sales, provider marketplace, or unrelated SaaS marketplace behavior.
- Do not introduce cross-root runtime imports; mirrored contracts remain explicit at ownership boundaries.
## Decisions
### Decision 1: Bridge permissions are evaluated from manifest metadata
The platform will authorize bridge actions from the installed plugin metadata produced by manifest registration. Requests include plugin ID, route key, optional server instance ID, action name, and purpose-specific payload metadata. The platform checks that the requested action maps to declared plugin permissions and AI purposes before returning an allowed decision.
Alternative considered: trust the browser SDK to decide permission outcomes. Rejected because plugin UI code is not a security boundary and can be modified by authors or users.
### Decision 2: Use narrow bridge action names instead of generic RPC
The bridge contract will model first-party action names such as `server.instances.read`, `jobs.dispatch`, `logs.query`, `artifacts.open`, `files.request`, and `ai.invoke`. Each action maps to specific permission requirements.
Alternative considered: expose a generic `api.request` bridge that proxies arbitrary platform paths. Rejected because arbitrary request forwarding makes permission reviews harder and risks exposing unrelated platform APIs to plugin pages.
### Decision 3: SDK helpers create typed envelopes, not direct transport
The SDK will provide types, permission helpers, request builders, and runtime guards. It will not own network transport or platform authentication. `platform_web/` host code can later use the same envelopes to communicate with embedded plugin pages.
Alternative considered: ship a full SDK client that calls platform APIs directly from plugin page code. Rejected because plugin pages must remain behind the platform host bridge and must not receive raw auth storage.
### Decision 4: Duplicate root-owned contract shapes deliberately
`plugins/`, `platform_web/`, and `platform/` will each own local contract definitions that mirror the bridge surface they need. Tests and OpenSpec requirements keep the shapes aligned until a future generated contract package exists.
Alternative considered: import TypeScript SDK types directly into the frontend or backend. Rejected because the repository rules require explicit contract packages or copied/generated contracts instead of casual cross-root imports.
### Decision 5: AI bridge requests carry purposes, not provider configuration
`ai.invoke` bridge requests will include an AI purpose and bounded input metadata. Platform validation confirms the purpose is allowed by the plugin manifest. Provider base URLs, API keys, model routing, and raw responses remain controlled by platform services.
Alternative considered: let plugin pages choose provider IDs or submit provider credentials. Rejected because AI provider keys and routing policy belong to `platform/`.
## Risks / Trade-offs
- [Risk] Mirrored TypeScript and Go action constants can drift. Mitigation: add focused tests and keep the action/permission matrix small until generated contracts are introduced.
- [Risk] Early bridge action names may be too coarse for later workflows. Mitigation: keep request payloads metadata-only where possible and add new actions through explicit OpenSpec changes.
- [Risk] Browser host work may need iframe lifecycle decisions later. Mitigation: this change establishes only host-side contracts/utilities, leaving page loading to the console-shell change.
- [Risk] Permission checks can become duplicated between platform and host utilities. Mitigation: platform remains authoritative; host checks are UX preflight only.
## Migration Plan
1. Add the bridge contract and permission matrix in OpenSpec.
2. Extend plugin manifest schema/types and the development example with bridge page requirements.
3. Add SDK helpers and tests for typed bridge envelopes and local permission checks.
4. Add platform bridge DTO/domain/validator/service/API route with tests for authorization decisions.
5. Add platform_web bridge host types/utilities and tests for safe context construction.
6. Validate with plugin tests, frontend tests, platform tests, `scripts/check-structure.sh`, and strict OpenSpec validation.
Rollback is straightforward before downstream UI depends on it: remove the bridge API route, SDK helpers, frontend host utilities, manifest bridge fields, and this change's OpenSpec artifacts.
## Open Questions
- Whether future plugin page loading should use iframe `postMessage`, module federation, static asset hosting, or another sandbox strategy.
- Whether a later generated contract package should replace copied bridge action constants across roots.
@@ -0,0 +1,28 @@
## Why
Validated plugin manifests can now register game management plugins, but plugin pages still lack a safe runtime bridge and authors lack a typed SDK for calling platform-mediated abilities. This change establishes the browser-side plugin boundary needed before the plugin marketplace and server workflows can host real plugin UI.
## What Changes
- Add a plugin page bridge contract that exposes only scoped platform abilities to plugin UI code.
- Add a TypeScript plugin SDK with bridge message types, permission checks, request/response helpers, and safe error handling.
- Add platform API support for validating plugin bridge sessions and evaluating requested actions against manifest permissions.
- Update the example development plugin to declare bridge requirements and exercise the SDK without direct run, host path, socket, credential, or raw AI key access.
- Add focused tests for bridge permission decisions, SDK type/runtime behavior, and platform validators.
## Capabilities
### New Capabilities
- `plugin-bridge-and-sdk`: Defines the platform-mediated plugin page bridge, SDK contract, permission enforcement, and safe capability surface for game management plugin pages.
### Modified Capabilities
- None.
## Impact
- `plugins/`: SDK source, bridge contracts, manifest/schema additions, example plugin declarations, and TypeScript tests.
- `platform/`: bridge session/action DTOs, domain types, validators, service logic, API route, and Go tests.
- `platform_web/`: bridge host contracts/utilities and tests that can later be used by plugin marketplace pages.
- OpenSpec artifacts and validation for the new `plugin-bridge-and-sdk` capability.
@@ -0,0 +1,76 @@
## ADDED Requirements
### Requirement: Plugin bridge exposes only platform-mediated actions
The system SHALL define a plugin page bridge with narrow action names for server context reads, job dispatch, log queries, artifact references, scoped file requests, and platform-mediated AI invocation.
#### Scenario: Plugin page requests allowed bridge action
- **WHEN** a plugin page requests a bridge action declared by the bridge contract and permitted by its manifest metadata
- **THEN** the platform authorizes the request without exposing run credentials, raw host paths, direct sockets, storage backend credentials, platform auth storage, or AI provider keys
#### Scenario: Plugin page requests unsupported bridge action
- **WHEN** a plugin page requests an action outside the bridge contract
- **THEN** the platform rejects the request with a validation error before dispatching any run, file, log, artifact, or AI work
### Requirement: Bridge permissions are enforced from manifest metadata
The system SHALL evaluate each bridge action against the installed plugin's declared permissions, page permissions, and AI purposes before allowing the action.
#### Scenario: Missing permission denies bridge action
- **WHEN** a plugin page requests `files.request` without the required file permission in its manifest or page permissions
- **THEN** the platform returns a denied bridge authorization decision and does not create a file job
#### Scenario: Allowed AI purpose authorizes AI request
- **WHEN** a plugin page requests `ai.invoke` with an AI purpose declared by the plugin manifest and the plugin has `ai.invoke` permission
- **THEN** the platform returns an allowed bridge authorization decision without exposing provider base URLs or API keys
#### Scenario: Undeclared AI purpose denies AI request
- **WHEN** a plugin page requests `ai.invoke` with a purpose not declared by the plugin manifest
- **THEN** the platform rejects or denies the request before invoking any AI provider
### Requirement: Plugin SDK provides typed bridge helpers
The plugin SDK SHALL provide TypeScript types and helpers for bridge context, bridge action names, bridge request envelopes, bridge responses, permission checks, and safe errors.
#### Scenario: SDK builds typed bridge request
- **WHEN** plugin author code builds a request for a supported bridge action through SDK helpers
- **THEN** the request envelope includes plugin ID, route key, action, request ID, and scoped payload fields that can be validated by the platform host
#### Scenario: SDK detects missing local permission
- **WHEN** plugin author code checks a bridge context for a missing permission
- **THEN** the SDK helper returns a negative result without performing transport or privileged work
### Requirement: Browser host creates safe bridge context
The frontend host SHALL construct plugin bridge context from installed plugin metadata, current route, selected server instance, safe theme tokens, and effective permissions only.
#### Scenario: Host context omits secrets
- **WHEN** the browser host creates bridge context for a plugin page
- **THEN** the context excludes raw AI keys, platform auth storage, run credentials, direct sockets, raw host paths, and storage backend credentials
#### Scenario: Host filters page permissions
- **WHEN** a plugin page declares route-specific permissions
- **THEN** the host context contains only permissions allowed by both the plugin manifest and the current page declaration
### Requirement: Bridge implementation respects root ownership boundaries
The system SHALL keep plugin SDK, frontend host utilities, and platform authorization logic in their owning roots without casual cross-root imports.
#### Scenario: Contracts are copied through explicit root files
- **WHEN** bridge action or permission contracts are needed in multiple roots
- **THEN** each root owns an explicit local contract file or generated/copy artifact instead of importing implementation code from another root
#### Scenario: Structure validation passes after bridge implementation
- **WHEN** the bridge and SDK implementation is complete
- **THEN** repository structure validation passes without placing implementation code outside `plugins/`, `platform_web/`, or `platform/`
@@ -0,0 +1,38 @@
## 1. Plugin SDK and Manifest Contract
- [x] 1.1 Extend plugin manifest schema, SDK types, and the development example with bridge action/page declarations.
- [x] 1.2 Add SDK bridge action, request envelope, response, safe error, and permission helper types.
- [x] 1.3 Add plugin SDK tests for request builders, local permission checks, and forbidden transport assumptions.
## 2. Platform Bridge Authorization
- [x] 2.1 Add platform domain and DTO types for plugin bridge sessions, actions, requests, and authorization decisions.
- [x] 2.2 Add platform validators that map bridge actions to required permissions and AI purposes.
- [x] 2.3 Add platform service logic and API route for bridge action authorization.
- [x] 2.4 Add Go tests for allowed actions, missing permissions, unsupported actions, and undeclared AI purposes.
## 3. Frontend Host Bridge Utilities
- [x] 3.1 Add frontend bridge host contract/types for safe plugin page context.
- [x] 3.2 Add frontend utilities that filter page permissions against manifest permissions and exclude secret-bearing fields.
- [x] 3.3 Add frontend tests for safe context creation and page permission filtering.
## 4. Verification
- [x] 4.1 Run plugin SDK/schema tests.
- [x] 4.2 Run platform bridge authorization tests.
- [x] 4.3 Run platform_web bridge utility tests.
- [x] 4.4 Run `scripts/check-structure.sh`.
- [x] 4.5 Run `openspec validate implement-plugin-bridge-and-sdk --strict`.
- [x] 4.6 Record verification evidence in this task file and only then mark verification tasks complete.
## Evidence
- `cd platform && go test ./...`: passed.
- `cd plugins && npm test`: passed, 1 file / 7 tests.
- `cd plugins && npm run typecheck`: passed.
- `cd plugins && npm run validate:manifest`: passed for `examples/dev-game-plugin/manifest.json`.
- `cd platform_web && npm test`: passed, 4 files / 7 tests.
- `cd platform_web && npm run typecheck`: passed.
- `scripts/check-structure.sh`: passed.
- `openspec validate implement-plugin-bridge-and-sdk --strict`: passed.