@jaimevalasek/aioson 1.30.0 → 1.30.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [1.30.1] - 2026-06-23
6
+
7
+ ### Added
8
+ - **AIOSON Play app compatibility docs.** Added curated `.aioson/docs/play/` guidance for agents building apps that target AIOSON Play, shipped through the install/update template. It covers manifest/runtime behavior, ports, ProductBridge, `/api/aioson-play`, LLM env injection, app-owned databases, Data Bindings, auth, services, and local testing.
9
+ - **Framework integration docs surface.** Added `.aioson/docs/integrations/dashboard-app-form-publish-mapping.md` as a framework-managed integration reference and shipped it through the install/update template.
10
+
11
+ ### Fixed
12
+ - **Preservative integration docs update.** `update` now has regression coverage proving official framework integration docs are refreshed while project-owned files in `.aioson/docs/integrations/` remain untouched.
13
+
5
14
  ## [1.30.0] - 2026-06-22
6
15
 
7
16
  ### Added
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jaimevalasek/aioson",
3
- "version": "1.30.0",
3
+ "version": "1.30.1",
4
4
  "description": "AI operating framework for hyper-personalized software.",
5
5
  "keywords": [
6
6
  "ai",
package/src/constants.js CHANGED
@@ -53,9 +53,17 @@ const MANAGED_FILES = [
53
53
  '.aioson/docs/deyvin/continuity-recovery.md',
54
54
  '.aioson/docs/deyvin/pair-execution.md',
55
55
  '.aioson/docs/deyvin/runtime-handoffs.md',
56
- '.aioson/docs/deyvin/debugging-escalation.md',
57
- '.aioson/docs/handoff-persistence.md',
58
- '.aioson/docs/sheldon/research-loop.md',
56
+ '.aioson/docs/deyvin/debugging-escalation.md',
57
+ '.aioson/docs/handoff-persistence.md',
58
+ '.aioson/docs/integrations/dashboard-app-form-publish-mapping.md',
59
+ '.aioson/docs/play/README.md',
60
+ '.aioson/docs/play/agent-usage-guide.md',
61
+ '.aioson/docs/play/app-compatibility-guide.md',
62
+ '.aioson/docs/play/auth-services-and-testing.md',
63
+ '.aioson/docs/play/llm-data-and-bindings.md',
64
+ '.aioson/docs/play/manifest-and-runtime.md',
65
+ '.aioson/docs/play/source-map.md',
66
+ '.aioson/docs/sheldon/research-loop.md',
59
67
  '.aioson/docs/sheldon/web-intelligence.md',
60
68
  '.aioson/docs/sheldon/quality-lens.md',
61
69
  '.aioson/docs/sheldon/enrichment-paths.md',
@@ -0,0 +1,183 @@
1
+ ---
2
+ description: "Mapping between the aioson.com dashboard app edit form and aioson system:publish --build listing fields."
3
+ scope: "global"
4
+ agents: [dev, architect, product, qa]
5
+ triggers: [system publish, marketplace app, dashboard app form, integrations, app listing]
6
+ ---
7
+
8
+ # Integração — Formulário "Editar app" (dashboard) × `aioson system:publish --build`
9
+
10
+ > Objetivo: mapear **cada campo do formulário de edição de app** no dashboard do
11
+ > aioson.com aos dados que o `aioson system:publish --build` já captura (ou
12
+ > poderia capturar) do app em desenvolvimento, para que a publicação preencha o
13
+ > cadastro da loja de forma mais completa e o dev não tenha que digitar à mão.
14
+
15
+ Doc-irmã: [`apps-publish-marketplace.md`](../../../docs/integrations/apps-publish-marketplace.md)
16
+ (fluxo geral do publish). Aqui o foco é o **mapeamento campo-a-campo** do form.
17
+
18
+ ---
19
+
20
+ ## Onde fica cada peça
21
+
22
+ | Peça | Caminho (repo) |
23
+ |------|----------------|
24
+ | Rota do form | `aioson-com/app/dashboard/ws/apps/[id]/edit/page.tsx` (ex.: `…/apps/cmqe2pnvw0005koa7ak5mbkge/edit`) |
25
+ | Componente do form | `aioson-com/app/admin/services/service-app-form.tsx` (`ServiceAppForm`) |
26
+ | Server action | `aioson-com/app/dashboard/ws/apps/actions.ts` → `updateWorkspaceAppAction` |
27
+ | Modelo de dados do form | `ServiceApp` em `aioson-com/prisma/schema.prisma` |
28
+ | Comando de publish (CLI) | `aioson/src/commands/store-system.js` → `runSystemPublish` |
29
+ | Validação do manifest (CLI) | `store-system.js` → `validateListingFields` |
30
+ | Recepção no servidor | `aioson-com/lib/store.ts` → `storePublishSystem` |
31
+ | Extração de listing → `System` | `lib/store.ts` → `extractListingFields` |
32
+ | Sync `System` → `ServiceApp` | `lib/store.ts` → `ensureServiceAppForSystemRecord` |
33
+
34
+ ---
35
+
36
+ ## Arquitetura: dois modelos, duas superfícies
37
+
38
+ O publish e o formulário **não escrevem no mesmo registro**:
39
+
40
+ - `aioson system:publish` envia o `system.json` inteiro como `manifest` e grava em
41
+ **`System` / `SystemVersion`**. Os campos de listing da loja
42
+ (`summary`, `category`, `tags`, `screenshots`, `purpose`, `iconUrl`,
43
+ `homepageUrl`, `supportEmail`, `supportUrl`, `privacyUrl`, `permissionsNote`)
44
+ são extraídos do manifest por `extractListingFields` e gravados em **`System`**.
45
+ - O **formulário de "Editar app"** edita **`ServiceApp`** — outro modelo, com
46
+ outro conjunto de campos (descrição longa, features, emoji, SEO, vídeo, etc.).
47
+ - Na publicação de app **não-privado**, `ensureServiceAppForSystemRecord` cria/atualiza
48
+ um `ServiceApp` espelhando o `System`, **mas só copia 5–7 campos**
49
+ (`name`, `description`, `price`, `visibility`, `ownerId`, `ownerProjectId`,
50
+ `trialDays`, `requiresLicense`). Todo o resto do form fica **manual**.
51
+
52
+ > Resultado prático: hoje o dev publica via CLI e depois ainda precisa abrir o
53
+ > form e preencher descrição longa, features, ícone, SEO e links na mão. É essa
54
+ > lacuna que o "preenchimento via harness" fecha.
55
+
56
+ ---
57
+
58
+ ## Mapeamento campo-a-campo do formulário
59
+
60
+ Legenda da coluna **Auto hoje?**: ✅ já preenchido na publicação · ⚠️ parcial · ❌ manual.
61
+
62
+ | Campo do form | `name=` | Coluna `ServiceApp` | Limite | Obrig. | Auto hoje? | Origem de captura sugerida (harness / manifest) |
63
+ |---|---|---|---|---|---|---|
64
+ | Nome | `name` | `name` | 120 | sim | ✅ | `manifest.name` (já obrigatório) |
65
+ | Slug | `slug` | `slug` | 140 (`[a-z0-9-]+`) | sim | ✅ | `manifest.slug` (já obrigatório) |
66
+ | Descrição curta | `description` | `description` | 280 | sim | ✅ | `manifest.description` (ou `manifest.summary`) |
67
+ | Descrição longa | `longDescription` | `longDescription` (Text) | — | não | ❌ | corpo do `README.md` (sem o 1º heading) · `manifest.long_description` · bootstrap `what-it-does.md` |
68
+ | Features | `features` | `features` (Text) | — | não | ❌ | `manifest.features[]` (lista) · seção `## Features`/`## Funcionalidades` do README |
69
+ | Preço | `price` | `price` (Decimal) | ≥ 0 | sim | ✅ | `System.priceInCents/100` ← `manifest.priceInCents`/`price` |
70
+ | Ordem | `sortOrder` | `sortOrder` (Int) | — | não (0) | ❌ | manual (sem sinal confiável no app) — manter default 0 |
71
+ | Ícone (emoji) | `icon` | `icon` VarChar(**8**) | 8 | não | ❌ | `manifest.icon_emoji` — **emoji**, NÃO a URL de ícone (essa é `System.iconUrl` ← `manifest.icon`) |
72
+ | Status | `status` | `status` (enum) | active/coming_soon/inactive | não | ⚠️ | derivado da `visibility`; geralmente manual — default `active` |
73
+ | Caminho do dashboard | `dashboardPath` | `dashboardPath` VarChar(255) | 255 | não | ❌ | `manifest.dashboard_path` · detectar rota admin do app (presença de `dashboard/`) |
74
+ | Vídeo demo | `urlVideoDemo` | `urlVideoDemo` VarChar(512) | 512 | não | ❌ | `manifest.url_video_demo` (manual — não dá pra inferir do código) |
75
+ | Storefront | `storefrontUrl` | `storefrontUrl` VarChar(**512**) | form aceita 1024 ⚠️ | não | ❌ | `manifest.storefront_url` (manual) |
76
+ | SEO título | `seoTitle` | `seoTitle` VarChar(70) | 70 | não | ❌ | `manifest.seo_title` · derivar `${name} — ${summary}` truncado em 70 |
77
+ | SEO descrição | `seoDescription` | `seoDescription` VarChar(160) | 160 | não | ❌ | `manifest.seo_description` · `manifest.summary` truncado em 160 |
78
+
79
+ **Lacunas reais (❌) a fechar:** `longDescription`, `features`, `icon` (emoji),
80
+ `dashboardPath`, `urlVideoDemo`, `storefrontUrl`, `seoTitle`, `seoDescription`.
81
+ (`sortOrder` e `status` ficam manuais por design.)
82
+
83
+ **Já capturado, mas em `System` (não neste form):** `summary`, `category`, `tags`,
84
+ `screenshots`, `purpose`, `iconUrl`, `homepageUrl`, `supportEmail`, `supportUrl`,
85
+ `privacyUrl`, `permissionsNote` — via `extractListingFields`. Reaproveitáveis:
86
+ `summary`→`seoDescription`, `iconUrl` já existe (o form usa emoji separado).
87
+
88
+ ⚠️ **Inconsistência a anotar:** o input `storefrontUrl` no form aceita
89
+ `maxLength=1024`, mas a coluna é `VarChar(512)`. Truncar/alinhar ao gravar.
90
+
91
+ ---
92
+
93
+ ## Chaves de `system.json` propostas (fonte única)
94
+
95
+ O publish já envia o `manifest` inteiro, então **basta o harness escrever estas
96
+ chaves no `system.json`** e o servidor mapeá-las no `ServiceApp`. Todas opcionais
97
+ (apps antigos seguem publicando):
98
+
99
+ ```jsonc
100
+ {
101
+ "slug": "meu-app",
102
+ "name": "Meu App",
103
+ "version": "1.0.0",
104
+ // — listing já suportado (vai pra System) —
105
+ "summary": "Resumo até 160 chars",
106
+ "category": "atendimento",
107
+ "tags": ["whatsapp", "crm"],
108
+ "icon": "https://.../icon.png", // URL → System.iconUrl
109
+ "screenshots": ["https://.../1.png"],
110
+ // — novas chaves p/ preencher o form ServiceApp —
111
+ "long_description": "Texto longo (markdown ok).",
112
+ "features": ["Recurso A", "Recurso B"], // → join em ServiceApp.features
113
+ "icon_emoji": "💬", // → ServiceApp.icon (≤8)
114
+ "dashboard_path": "/dashboard/atendimento",
115
+ "url_video_demo": "https://youtube.com/watch?v=...",
116
+ "storefront_url": "https://minha-loja.com",
117
+ "seo_title": "Meu App — atendimento no WhatsApp",
118
+ "seo_description": "Descrição SEO até 160 chars"
119
+ }
120
+ ```
121
+
122
+ ---
123
+
124
+ ## O que faltaria implementar (3 pontos) — NÃO feito ainda
125
+
126
+ Isto é o plano de fechamento da lacuna; **este doc só mapeia, não altera código**.
127
+
128
+ 1. **CLI — `validateListingFields`** (`store-system.js`): aceitar/validar as novas
129
+ chaves opcionais (`long_description`, `features[]`, `icon_emoji` ≤8,
130
+ `dashboard_path`, `url_video_demo`, `storefront_url`, `seo_title` ≤70,
131
+ `seo_description` ≤160). O envio em si já acontece (manifest viaja inteiro).
132
+ 2. **Servidor — `ensureServiceAppForSystemRecord`** (`lib/store.ts`): estender o
133
+ objeto `data` para mapear essas chaves do manifest nas colunas do `ServiceApp`
134
+ (respeitando "não sobrescrever edição manual" se desejado — ex.: só preencher
135
+ quando o campo no `ServiceApp` estiver vazio).
136
+ 3. **Harness — montagem do `system.json` antes do publish**: popular as chaves a
137
+ partir das fontes da tabela (README, rotas, living-memory). Candidato natural:
138
+ um passo de "enriquecer manifest" dentro de `runSystemPublish` (modo `--build`)
139
+ ou um agente/skill que rode antes do publish.
140
+
141
+ ### Estratégia de captura pelo harness (resumo)
142
+
143
+ - `long_description` ← corpo do `README.md` (remover 1º heading) ou bootstrap `what-it-does.md`.
144
+ - `features` ← bullets da seção `## Features`/`## Funcionalidades` do README.
145
+ - `dashboard_path` ← detecção de rota admin (presença de `dashboard/`, `app/admin`, etc.).
146
+ - `seo_title`/`seo_description` ← derivar de `name` + `summary` com truncamento.
147
+ - `icon_emoji`, `url_video_demo`, `storefront_url` ← declarados pelo dev (manual no manifest).
148
+
149
+ ### ⚠️ Pré-condições e pegadinhas (descobertas na investigação)
150
+
151
+ Antes de implementar, dois fatos do código atual que mudam o "quando" e o "onde":
152
+
153
+ 1. **`ServiceApp` só nasce em `status=PUBLISHED` + `FREE/PAID`.**
154
+ `ensureServiceAppForSystemRecord` retorna `null` se `status !== "PUBLISHED"` ou
155
+ `visibility === "PRIVATE"` (e também ignora `DEV/PRO/BUSINESS` — só FREE/PAID).
156
+ Para **publisher novo**, a 1ª publicação é quarentenada (`createStatus = "DRAFT"`),
157
+ então o `ServiceApp` **não é criado na primeira vez** — só quando o app sai da
158
+ quarentena e vira `PUBLISHED`. ⇒ O preenchimento precisa acontecer **no momento
159
+ da criação do `ServiceApp`** (que pode ser uma publicação posterior), não
160
+ necessariamente na 1ª chamada de `system:publish`.
161
+
162
+ 2. **`ownerProjectId` está `null` hardcoded no publish (linha ~1037 de `store.ts`).**
163
+ O CLI manda `workspaceSlug` (lido de `.aioson/workspace.json`), mas
164
+ `storePublishSystem` **não** o usa para vincular o app a um workspace: tanto o
165
+ `System` quanto o `ServiceApp` são criados com `ownerProjectId: null`.
166
+ ⇒ App publicado via CLI **não aparece** no form WS-scoped
167
+ (`/dashboard/ws/apps/[id]/edit` filtra por `app.ownerProjectId === ws.id`).
168
+ Apps que aparecem lá foram criados pelo form "novo app" (`createWorkspaceAppAction`),
169
+ que seta `ownerProjectId = ws.id`. **Não existe "workspace default" no publish hoje.**
170
+
171
+ Para o publish alimentar esse form, falta um **4º ponto de implementação**:
172
+ resolver `workspaceSlug → project.id` no servidor e setar `ownerProjectId`
173
+ (no `System` e no `ServiceApp`) em vez de `null`.
174
+
175
+ ---
176
+
177
+ ## Como verificar (quando implementado)
178
+
179
+ 1. `aioson system:publish ./app --dry-run` deve listar o manifest com as novas chaves.
180
+ 2. Após publish de app **não-privado**, abrir `…/apps/<id>/edit` e conferir que
181
+ `longDescription`, `features`, `icon`, SEO e links vieram preenchidos.
182
+ 3. App **privado** não gera `ServiceApp` (`ensureServiceAppForSystemRecord` só roda
183
+ para `visibility !== PRIVATE`) — não esperar preenchimento nesse caso.
@@ -0,0 +1,72 @@
1
+ ---
2
+ description: "Entry point for AIOSON agents implementing apps compatible with AIOSON Play runtime, integrations, data bindings, LLM connections, auth, services, ports, and local testing."
3
+ scope: "global"
4
+ agents: [dev, deyvin, architect, analyst, qa, tester, product, sheldon]
5
+ task_types: [aioson-play-app, app-compatibility, integration]
6
+ triggers: [AIOSON Play, Play runtime, app compatible with Play, Play integrations, data bindings, ProductBridge]
7
+ ---
8
+
9
+ # AIOSON Play App Compatibility
10
+
11
+ Use this folder when the user says the app will run inside AIOSON Play, will be installed by AIOSON Play, is being built in a Play draft, or must consume Play integrations.
12
+
13
+ These docs are an AIOSON-side operational layer. They do not replace the canonical Play contracts in:
14
+
15
+ ```text
16
+ C:\dev\aioson-play\.aioson\docs\integrations\
17
+ ```
18
+
19
+ If that source repo exists and the task touches a precise Play contract, read the canonical doc listed in `source-map.md`. If it is not available, this folder is the stable fallback for agents.
20
+
21
+ ## Installed Play docs are not a harness contract
22
+
23
+ Do not assume a harness working in a random app project can access docs embedded in a user's installed AIOSON Play. A desktop install may package resources differently, may not expose `.aioson/docs/integrations/` as a normal source path, and the harness may be running in another cwd.
24
+
25
+ For AIOSON agents, the stable contract is:
26
+
27
+ 1. Load this folder when the task is Play-targeted.
28
+ 2. Use `source-map.md` to know which canonical Play document owns each topic.
29
+ 3. Only read `C:\dev\aioson-play\.aioson\docs\integrations\...` when the repo is locally available and exact contract detail matters.
30
+
31
+ ## Loading order
32
+
33
+ For implementation:
34
+
35
+ 1. `agent-usage-guide.md`
36
+ 2. `app-compatibility-guide.md`
37
+ 3. `manifest-and-runtime.md`
38
+ 4. `llm-data-and-bindings.md` if the app touches LLM, app DB, external data, Global Connectors, MCPI, REST connectors, MCP tools, or `app-config.yaml`
39
+ 5. `auth-services-and-testing.md` if the app touches auth, billing/trial, Play Services, dev-link, local installation, or smoke testing
40
+ 6. `source-map.md` when a canonical source must be checked
41
+
42
+ For QA/review:
43
+
44
+ 1. `app-compatibility-guide.md`
45
+ 2. `manifest-and-runtime.md`
46
+ 3. Topic-specific docs for touched surfaces
47
+
48
+ ## Core rule
49
+
50
+ AIOSON can build any kind of app. Apply this Play compatibility layer only when the user explicitly or clearly targets AIOSON Play.
51
+
52
+ ## Covered surfaces
53
+
54
+ - App identity and `manifest.json`
55
+ - Runtime selection, scripts, `pnpm`, Next.js, Vite, Node, split-stack processes
56
+ - Dynamic ports and ProductBridge at `http://localhost:5180`
57
+ - `GET /api/aioson-play` capability declaration
58
+ - LLM connections and fallback chain expectations
59
+ - App operational database via `DATABASE_URL`
60
+ - Data Bindings and Global Connectors via `app-config.yaml`
61
+ - MCPI/API/MCP connector execution through the Play registry
62
+ - Local operator auth via `aioson-auth` and `@aioson/auth-sdk`
63
+ - Cloud owner/trial auth via `AIOSON_COM_TOKEN`
64
+ - Play Services via `service.json` and `requires_services`
65
+ - Dev-link and local smoke testing
66
+
67
+ ## Non-goals
68
+
69
+ - Do not copy the whole Play integration directory into app projects.
70
+ - Do not make apps depend on source-repo-only files from `aioson-play`.
71
+ - Do not invent Play env vars, port ranges, manifest fields, or connector APIs.
72
+ - Do not treat `llm-chain.json` or `aioson-models.json` in the app cwd as the primary credential contract for installed apps.
@@ -0,0 +1,106 @@
1
+ ---
2
+ description: "How AIOSON agents should decide when and how to apply AIOSON Play app compatibility docs during product, architecture, implementation, QA, and review work."
3
+ scope: "global"
4
+ agents: [dev, deyvin, architect, analyst, qa, tester, product, sheldon]
5
+ task_types: [aioson-play-app, app-compatibility, integration]
6
+ triggers: [AIOSON Play, Play app, Play-compatible app, Play integrations, ProductBridge, data_bindings]
7
+ ---
8
+
9
+ # Agent Usage Guide
10
+
11
+ ## Trigger phrases
12
+
13
+ Load this folder when the user mentions:
14
+
15
+ - "AIOSON Play"
16
+ - "play"
17
+ - "draft"
18
+ - "app compativel com o Play"
19
+ - "runtime do Play"
20
+ - "instalar no Play"
21
+ - "marketplace do Play"
22
+ - "Global Connector"
23
+ - "Data Binding"
24
+ - "MCPI"
25
+ - "ProductBridge"
26
+ - `manifest.json` for Play apps
27
+ - `app-config.yaml`
28
+ - `requires_services`
29
+ - `/api/aioson-play`
30
+
31
+ Do not load it for generic web apps unless the user connects the app to Play.
32
+
33
+ ## First decision
34
+
35
+ Before coding, classify the work:
36
+
37
+ | User intent | Agent behavior |
38
+ |---|---|
39
+ | New app for Play | Use all docs in this folder. Start from `app-compatibility-guide.md`. |
40
+ | Existing app should become Play-compatible | Audit `manifest.json`, scripts, port usage, `app-config.yaml`, auth and test path. |
41
+ | App only needs Play data connectors | Load `llm-data-and-bindings.md`; do not redesign auth/runtime. |
42
+ | App only needs Play auth | Load `auth-services-and-testing.md`; do not add data bindings unless needed. |
43
+ | App only runs as standalone | Do not apply Play constraints unless user asks. |
44
+ | Play runtime itself is being changed | Read canonical docs in `C:\dev\aioson-play\.aioson\docs\integrations\` if available. |
45
+
46
+ ## Four questions before implementation
47
+
48
+ For a Play-targeted app, answer these before creating files:
49
+
50
+ 1. Does the app have a visual UI?
51
+ - Yes: it needs a webview-facing process, usually Vite/Next or split-stack.
52
+ - No: it may be a CLI/sidecar-style app.
53
+
54
+ 2. Does the app expose an HTTP API?
55
+ - Yes: `manifest.json` needs `has_api: true`, the app must read `PORT`, and it should expose `GET /api/aioson-play`.
56
+ - No: skip `/api/aioson-play` unless another Play feature requires endpoint discovery.
57
+
58
+ 3. Does the app need external domain data?
59
+ - Yes: declare `data_bindings` in `app-config.yaml` and consume Global Connectors through ProductBridge.
60
+ - No: do not create connector UI or fake bindings.
61
+
62
+ 4. Does the app need users/operators?
63
+ - Owner/trial/billing: use `AIOSON_COM_TOKEN` and backend proxy routes.
64
+ - Local operators/RBAC: use `aioson-auth` as Play Service and `@aioson/auth-sdk`.
65
+ - No auth: do not add login just because it is a Play app.
66
+
67
+ ## Source priority
68
+
69
+ Use this priority order:
70
+
71
+ 1. Project rule `.aioson/rules/aioson-play-conventions.md` for AIOSON-authored Play drafts.
72
+ 2. These `.aioson/docs/play/` docs for AIOSON agents implementing apps.
73
+ 3. Canonical Play docs in `C:\dev\aioson-play\.aioson\docs\integrations\` for exact or current runtime contracts.
74
+ 4. Existing app code patterns, only when they do not violate the above.
75
+
76
+ ## What agents must not infer
77
+
78
+ - Do not infer fixed app ports.
79
+ - Do not invent env vars.
80
+ - Do not expose Database Connection creation inside the app UI.
81
+ - Do not put provider API keys in `llm-chain.json`, `tools.json`, manifest, app docs, or frontend code.
82
+ - Do not make browser code call `https://aioson.com` directly with a token.
83
+ - Do not treat `aioson-auth` and `aioson.com` auth as the same system.
84
+ - Do not add `@tauri-apps/api` to Play Services. Services are standalone background processes.
85
+ - Do not assume SSO operator token injection is implemented unless the canonical Play docs and code confirm it.
86
+
87
+ ## Expected agent output
88
+
89
+ For implementation, produce or verify:
90
+
91
+ - `manifest.json`
92
+ - `package.json` scripts that work under Play spawn
93
+ - `app-config.yaml` when the app has database config or data bindings
94
+ - `/api/aioson-play` when `has_api: true`
95
+ - Lazy LLM client initialization when the app uses LLM providers
96
+ - Degraded state when required bindings are absent
97
+ - Local smoke steps through dev-link or standalone `PORT=...` run
98
+
99
+ For QA, verify:
100
+
101
+ - No hardcoded Play-managed port
102
+ - No invented `VITE_AIOSON_*` env var
103
+ - No secret in frontend or package artifact
104
+ - Data bindings use alias names that match `app-config.yaml`
105
+ - Auth path uses the right system: `aioson-auth` for operators, `aioson.com` for owner/trial
106
+ - `manifest.compatibility` exists for publishable apps
@@ -0,0 +1,112 @@
1
+ ---
2
+ description: "Operational checklist and implementation path for making an app compatible with AIOSON Play."
3
+ scope: "global"
4
+ agents: [dev, deyvin, architect, analyst, qa, tester, product, sheldon]
5
+ task_types: [aioson-play-app, app-compatibility, implementation]
6
+ triggers: [AIOSON Play, compatible app, app manifest, /api/aioson-play, Play draft, Play install]
7
+ ---
8
+
9
+ # App Compatibility Guide
10
+
11
+ ## Mental model
12
+
13
+ An AIOSON Play app is a child process managed by Play. It can be a frontend, backend, split-stack app, CLI/sidecar app, or app with Play Services. Play owns process launch, ports, registry, installed app lifecycle, and shared integration surfaces.
14
+
15
+ The app owns its domain behavior, UI, operational database, migrations, API routes, and degraded mode.
16
+
17
+ ## Minimum app contract
18
+
19
+ Every Play-compatible app should have:
20
+
21
+ ```text
22
+ app/
23
+ manifest.json
24
+ package.json
25
+ app-config.yaml # when it has database config or data bindings
26
+ ```
27
+
28
+ If `has_api: true`, also expose:
29
+
30
+ ```text
31
+ GET /api/aioson-play
32
+ GET /api/health # strongly recommended for debug/loading states
33
+ ```
34
+
35
+ If the app has a UI, the Play webview must be able to load the UI from the process selected by the manifest.
36
+
37
+ ## Required behavior
38
+
39
+ - Read `process.env.PORT` for the main Play-managed process.
40
+ - In split-stack, read the configured env names such as `PORT` and `BACKEND_PORT`.
41
+ - Keep browser-facing calls same-origin where possible. For split Vite apps, proxy `/api` and websocket routes through the frontend dev server instead of calling the backend port directly from browser code.
42
+ - Use `http://localhost:5180` or `VITE_AIOSON_PLAY_URL` for ProductBridge calls.
43
+ - Use `GET /api/registry` when discovering other apps or services dynamically.
44
+ - Use `requires_services` for Play Service dependencies.
45
+ - Keep app-local operational DB separate from Play Global Connectors.
46
+ - Fail clearly or degrade gracefully when optional Play integrations are absent.
47
+
48
+ ## Do not do
49
+
50
+ - Do not hardcode app runtime ports.
51
+ - Do not assume `localhost:3000`, `5173`, `3301`, or any other port is stable for this app.
52
+ - Do not use `npm install` in Play drafts. Use `pnpm` per the AIOSON Play draft convention.
53
+ - Do not create a UI inside the app for creating global Database Connections or Data Connectors. Those live in Play Settings.
54
+ - Do not put LLM provider secrets in files shipped with the app.
55
+ - Do not call cloud APIs from browser code with `AIOSON_COM_TOKEN`.
56
+
57
+ ## Implementation sequence
58
+
59
+ 1. Add or audit `manifest.json`.
60
+ 2. Add or audit `package.json` scripts.
61
+ 3. Make every server listen on Play-injected env ports.
62
+ 4. Add `GET /api/aioson-play` if the app exposes API capabilities.
63
+ 5. Add `app-config.yaml` for operational DB defaults and/or `data_bindings`.
64
+ 6. Add Play auth only if the app needs it.
65
+ 7. Add local smoke tests and dev-link run instructions.
66
+
67
+ ## Ready-for-Play checklist
68
+
69
+ - [ ] `manifest.json` has stable `slug`, `name`, `version`.
70
+ - [ ] Runtime fields match actual stack.
71
+ - [ ] `has_api` matches reality.
72
+ - [ ] `package.json` has a Play-compatible `dev` script.
73
+ - [ ] No app code hardcodes a Play-managed port.
74
+ - [ ] `GET /api/aioson-play` returns existing endpoints only.
75
+ - [ ] `app-config.yaml` declares `data_bindings` if the app needs external domain data.
76
+ - [ ] `app-config.yaml` declares `database.default_url` and `supported_drivers` if the app owns an operational DB.
77
+ - [ ] App handles missing bindings with degraded UI or a clear blocking state.
78
+ - [ ] LLM clients are lazy-initialized and read credentials from app config or injected env vars.
79
+ - [ ] Auth uses the correct path: `aioson-auth` for operators/RBAC, `aioson.com` for owner/trial/billing.
80
+ - [ ] Publishable apps declare `manifest.compatibility`.
81
+ - [ ] Dev-link smoke was run inside Play or the app was manually started with a test `PORT`.
82
+
83
+ ## Smoke commands
84
+
85
+ For an API app, run a standalone smoke before dev-link:
86
+
87
+ ```bash
88
+ PORT=3399 pnpm dev
89
+ curl http://localhost:3399/api/aioson-play
90
+ curl http://localhost:3399/api/health
91
+ ```
92
+
93
+ On Windows PowerShell:
94
+
95
+ ```powershell
96
+ $env:PORT = "3399"
97
+ pnpm dev
98
+ ```
99
+
100
+ Then install through Play:
101
+
102
+ ```text
103
+ AIOSON Play -> Instalar App -> Linkar pasta (dev) -> select app folder
104
+ ```
105
+
106
+ Validate:
107
+
108
+ - App appears with DEV badge.
109
+ - Webview renders.
110
+ - API endpoint responds.
111
+ - ProductBridge calls to `http://localhost:5180` work when Play is running.
112
+ - Missing connectors/auth produce clear degraded states.
@@ -0,0 +1,220 @@
1
+ ---
2
+ description: "AIOSON Play auth, cloud owner token, local operator auth, Play Services, requires_services, dev-link, symlink installs, and smoke testing."
3
+ scope: "global"
4
+ agents: [dev, deyvin, architect, qa, tester, pentester]
5
+ task_types: [aioson-play-app, auth, service-integration, testing]
6
+ triggers: [aioson-auth, AIOSON_COM_TOKEN, requires_services, service.json, dev-link, Play Services, smoke test]
7
+ ---
8
+
9
+ # Auth, Services, And Testing
10
+
11
+ ## Auth systems
12
+
13
+ AIOSON Play has two different auth surfaces:
14
+
15
+ | Surface | Purpose | App receives |
16
+ |---|---|---|
17
+ | `aioson.com` cloud auth | Owner identity, trial, billing, license/status | `AIOSON_COM_TOKEN` |
18
+ | `aioson-auth` Play Service | Local operators, login, RBAC, permissions | service URL and binding id |
19
+
20
+ Do not mix them.
21
+
22
+ Use `aioson.com` when the app needs subscription/trial/license state.
23
+ Use `aioson-auth` when the app needs operators, roles, permissions, 2FA, or local RBAC.
24
+
25
+ ## Cloud owner/trial auth
26
+
27
+ When the owner is logged into AIOSON Play, Play can inject:
28
+
29
+ ```text
30
+ AIOSON_COM_TOKEN=<bearer token>
31
+ ```
32
+
33
+ The app should read it on backend startup and persist it in local settings if needed. If absent, the app should fall back to manual login or a disconnected state.
34
+
35
+ Do not call `https://aioson.com` directly from browser code with this token. Use backend proxy routes.
36
+
37
+ Recommended backend proxy routes:
38
+
39
+ | App route | Purpose |
40
+ |---|---|
41
+ | `GET /api/aioson/connection` | Check local token state |
42
+ | `GET /api/aioson/status?projectId={id}` | Proxy app subscription/trial status |
43
+ | `POST /api/aioson/login` | Manual cloud login fallback |
44
+ | `DELETE /api/aioson/logout` | Clear local token |
45
+
46
+ Cloud endpoints the backend may call:
47
+
48
+ | Endpoint | Purpose |
49
+ |---|---|
50
+ | `POST /api/app-auth/token` | Manual token acquisition |
51
+ | `POST /api/apps/{slug}/install` | Idempotent install/trial registration |
52
+ | `GET /api/apps/{slug}/status?projectId={id}` | Subscription/trial status |
53
+
54
+ ## Local operator auth and RBAC
55
+
56
+ For operator login and RBAC, depend on `aioson-auth`:
57
+
58
+ ```json
59
+ {
60
+ "requires_services": ["aioson-auth"]
61
+ }
62
+ ```
63
+
64
+ Use `@aioson/auth-sdk` as the client layer when available. Avoid handwritten calls to auth endpoints unless the SDK cannot cover the specific case.
65
+
66
+ Env vars Play injects for auth (only these exist):
67
+
68
+ ```text
69
+ VITE_AIOSON_AUTH_URL=http://localhost:3001
70
+ VITE_AIOSON_AUTH_BINDING_ID=<binding-id>
71
+ ```
72
+
73
+ Play injects only the `VITE_`-prefixed auth vars. There is no `AIOSON_AUTH_URL` or `AIOSON_AUTH_BINDING_ID` without the prefix — do not read those, they will be `undefined`. Backend Node code reads the same injected vars through `process.env.VITE_AIOSON_AUTH_URL` and `process.env.VITE_AIOSON_AUTH_BINDING_ID`; the `VITE_` prefix does not stop Node from reading them at runtime. The app slug is the only auth-relevant value injected in both forms: `AIOSON_APP_SLUG` and `VITE_AIOSON_APP_SLUG`.
74
+
75
+ Bearer header is preferred for auth calls:
76
+
77
+ ```http
78
+ Authorization: Bearer <jwt>
79
+ ```
80
+
81
+ Legacy `?token=` may still work in older paths, but new app code should prefer Bearer.
82
+
83
+ Current implemented auth expectations from the Play docs:
84
+
85
+ - JWT can include `binding_id` and `permissions`.
86
+ - `/me/permissions` exists in `aioson-auth`.
87
+ - `@aioson/auth-sdk` MVP exists.
88
+ - Operator SSO token injection from Play keyring is planned in docs, not safe to rely on unless the local code confirms it.
89
+
90
+ ## Owner bypass
91
+
92
+ Some flows allow owner-implicit behavior through the owner cloud identity. Do not use that as a replacement for operator RBAC when the app has real multi-user operator roles.
93
+
94
+ ## Play Services
95
+
96
+ A Play Service is infrastructure, not an app webview.
97
+
98
+ Service shape:
99
+
100
+ ```text
101
+ service/
102
+ service.json
103
+ package.json
104
+ dist/
105
+ ```
106
+
107
+ `service.json`:
108
+
109
+ ```json
110
+ {
111
+ "slug": "aioson-auth",
112
+ "name": "AIOSON Auth",
113
+ "version": "1.0.0",
114
+ "description": "Servico de autenticacao para apps do AIOSON Play.",
115
+ "port": 3001,
116
+ "autostart": true,
117
+ "dev_command": "node dist/server.js",
118
+ "health_check": "/health"
119
+ }
120
+ ```
121
+
122
+ Rules:
123
+
124
+ - Use ports in `3001-3099`.
125
+ - Read `process.env.PORT` in the service.
126
+ - Implement `GET /health`.
127
+ - Configure CORS for localhost app origins.
128
+ - Do not depend on Tauri APIs inside a Play Service.
129
+ - Build to `dist/` before publishing or local symlink service testing.
130
+
131
+ ## Dev-link install
132
+
133
+ Use dev-link for active app development:
134
+
135
+ ```text
136
+ AIOSON Play -> Instalar App -> Linkar pasta (dev) -> select app folder with manifest.json
137
+ ```
138
+
139
+ Dev-link creates a symlink from Play's app data directory to the source folder. It allows fast iteration, but it is not a production publish validation.
140
+
141
+ Windows note: symlink creation normally needs Developer Mode enabled or elevated privileges.
142
+
143
+ When `manifest.json` changes during dev-link, stop and reopen the app in Play to force manifest reload.
144
+
145
+ ## Local symlink layout
146
+
147
+ Common Play data locations:
148
+
149
+ ```text
150
+ Windows: %LOCALAPPDATA%\com.aioson.play\
151
+ Linux: ~/.local/share/com.aioson.play/
152
+ ```
153
+
154
+ Inside:
155
+
156
+ ```text
157
+ apps/{slug}/
158
+ services/{slug}/
159
+ ```
160
+
161
+ For manual local testing, symlink app or service folders there. Prefer the Play UI dev-link flow when available.
162
+
163
+ ## Testing an app
164
+
165
+ Standalone smoke:
166
+
167
+ ```bash
168
+ PORT=3399 pnpm dev
169
+ curl http://localhost:3399/api/health
170
+ curl http://localhost:3399/api/aioson-play
171
+ ```
172
+
173
+ Play smoke:
174
+
175
+ ```text
176
+ 1. Start AIOSON Play.
177
+ 2. Dev-link the app folder.
178
+ 3. Open the app from the Play shell.
179
+ 4. Confirm badge/running state.
180
+ 5. Confirm webview renders.
181
+ 6. Confirm ProductBridge calls to :5180 work.
182
+ 7. Confirm missing auth/bindings show clear degraded states.
183
+ ```
184
+
185
+ Data binding smoke:
186
+
187
+ ```bash
188
+ curl http://localhost:5180/api/registry
189
+ curl http://localhost:5180/api/connectors
190
+ curl http://localhost:5180/api/bindings/meu-app
191
+ ```
192
+
193
+ Service smoke:
194
+
195
+ ```bash
196
+ curl http://localhost:3001/health
197
+ ```
198
+
199
+ ## QA checklist
200
+
201
+ - [ ] `requires_services` matches actual service use.
202
+ - [ ] Missing service does not produce a confusing crash.
203
+ - [ ] `AIOSON_COM_TOKEN` is never exposed to frontend code.
204
+ - [ ] Operator auth uses SDK or Bearer-compatible client.
205
+ - [ ] `VITE_AIOSON_AUTH_BINDING_ID` absence is handled.
206
+ - [ ] Service uses `process.env.PORT`.
207
+ - [ ] Service has `/health`.
208
+ - [ ] App dev-link reload was tested after manifest changes.
209
+ - [ ] ProductBridge `:5180` endpoints are called only when Play is running or with a fallback/degraded path.
210
+
211
+ ## Source docs
212
+
213
+ Canonical sources:
214
+
215
+ - `app-cloud-auth.md`
216
+ - `auth-integration-gaps.md`
217
+ - `play-service-protocol.md`
218
+ - `dev-link-install.md`
219
+ - `local-dev-testing.md`
220
+ - `platform-architecture.md`
@@ -0,0 +1,238 @@
1
+ ---
2
+ description: "How AIOSON Play apps should consume LLM connections, app-owned databases, Data Bindings, Global Connectors, MCPI, REST connectors, MCP tools, and ProductBridge."
3
+ scope: "global"
4
+ agents: [dev, deyvin, architect, analyst, qa, tester]
5
+ task_types: [aioson-play-app, data-integration, llm-integration]
6
+ triggers: [LLM connections, DATABASE_URL, data_bindings, Global Connectors, MCPI, MCP tools, ProductBridge]
7
+ ---
8
+
9
+ # LLM, Data, And Bindings
10
+
11
+ ## Three separate surfaces
12
+
13
+ Do not mix these:
14
+
15
+ | Surface | Owner | App does |
16
+ |---|---|---|
17
+ | LLM connections | AIOSON Play Settings | Reads injected env vars or metadata and lazy-inits clients |
18
+ | Operational app DB | The app | Reads `DATABASE_URL`, runs migrations, owns data |
19
+ | External/domain data | Play Global Connectors | Declares `data_bindings`, binds aliases, calls ProductBridge |
20
+
21
+ ## LLM connections
22
+
23
+ Play manages global LLM connections in Settings:
24
+
25
+ - one API key per provider
26
+ - models validated by operation
27
+ - fallback order by operation
28
+ - capabilities such as vision/audio inferred from validated models
29
+
30
+ Apps should not store Play LLM secrets in repository files or frontend code.
31
+
32
+ Expected app behavior:
33
+
34
+ - Prefer app-local explicit config only when the app intentionally lets the user override provider settings.
35
+ - Otherwise read provider API keys injected by Play during spawn, such as `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, or `OPENROUTER_API_KEY`.
36
+ - Lazy-initialize LLM clients. Do not instantiate SDK clients at module load, because missing keys can crash the backend before the app can render a degraded state.
37
+ - Treat `llm-chain.json` as metadata/order only when present. It must not contain API keys.
38
+ - Treat `aioson-models.json` or `llm-chain.json` in the app cwd as optional/legacy for installed apps, not the primary credential contract.
39
+
40
+ Recommended lazy pattern:
41
+
42
+ ```ts
43
+ let client: OpenAI | null = null;
44
+
45
+ function getOpenAiClient() {
46
+ const apiKey = process.env.OPENAI_API_KEY;
47
+ if (!apiKey) return null;
48
+ client ??= new OpenAI({ apiKey });
49
+ return client;
50
+ }
51
+ ```
52
+
53
+ Supported operation names in current Play docs include:
54
+
55
+ - `text_generation`
56
+ - `code_generation`
57
+ - `image_understanding`
58
+ - `image_generation`
59
+ - `video_understanding`
60
+ - `video_generation`
61
+ - `speech_to_text`
62
+ - `text_to_speech`
63
+ - `audio_understanding`
64
+ - `realtime_voice`
65
+
66
+ ## Operational database of the app
67
+
68
+ The app owns its own operational database. Play does not provide a shared app database.
69
+
70
+ Default recommendation:
71
+
72
+ - SQLite with WAL mode for most local-first apps.
73
+ - Read `DATABASE_URL` from env with fallback to `app-config.yaml`.
74
+ - Declare supported drivers from day 1 even if only SQLite is used.
75
+
76
+ `app-config.yaml` pattern:
77
+
78
+ ```yaml
79
+ database:
80
+ default_url: "sqlite://./data/app.db?mode=rwc"
81
+ supported_drivers: ["sqlite", "postgres"]
82
+ sqlite_pragmas:
83
+ journal_mode: "WAL"
84
+ synchronous: "NORMAL"
85
+ busy_timeout: 5000
86
+ ```
87
+
88
+ App code pattern:
89
+
90
+ ```ts
91
+ const url = process.env.DATABASE_URL ?? config.database.default_url;
92
+ const driver = url.startsWith("postgres://") ? "postgres" : "sqlite";
93
+ const db = await connect(url, driver);
94
+
95
+ if (driver === "sqlite") {
96
+ await db.exec("PRAGMA journal_mode=WAL");
97
+ await db.exec("PRAGMA synchronous=NORMAL");
98
+ await db.exec("PRAGMA busy_timeout=5000");
99
+ }
100
+ ```
101
+
102
+ Only move beyond SQLite when there is an objective need, such as:
103
+
104
+ - persistent `SQLITE_BUSY` after WAL and `busy_timeout`
105
+ - `pgvector`
106
+ - serious JSONB indexing
107
+ - full-text ranking beyond SQLite FTS5
108
+ - multiple app processes writing to the same database
109
+ - pre-existing customer Postgres infrastructure
110
+ - multi-device sync or online-first architecture
111
+
112
+ ## External data through Data Bindings
113
+
114
+ External domain data belongs to Play Global Connectors, not to app-specific connection UIs.
115
+
116
+ The app declares slots in `app-config.yaml`:
117
+
118
+ ```yaml
119
+ data_bindings:
120
+ - id: "busca-produtos"
121
+ description: "Busca produtos no catalogo por nome ou principio ativo"
122
+ accepted_types: ["mcpi", "api", "mcp"]
123
+ required_params:
124
+ - "search"
125
+
126
+ - id: "webhook-pedido"
127
+ description: "Notifica sistema externo quando um pedido e confirmado"
128
+ accepted_types: ["api"]
129
+ required_params:
130
+ - "pedido_json"
131
+ ```
132
+
133
+ Fields:
134
+
135
+ | Field | Meaning |
136
+ |---|---|
137
+ | `id` | Slot slug. Also the binding alias. Prefer kebab-case. |
138
+ | `description` | Human-readable text for the app/admin UI. |
139
+ | `accepted_types` | Canonical array: `mcpi`, `api`, `mcp`. |
140
+ | `required_params` | Placeholder names expected by the connector. |
141
+
142
+ `expected_type` is legacy. Prefer `accepted_types` in new apps.
143
+
144
+ ## What Play owns
145
+
146
+ Play Settings owns:
147
+
148
+ - Database Connections
149
+ - Data Connectors
150
+ - credential/keyring storage for connector auth
151
+ - connector validation status
152
+ - global admin view of App Data Sources
153
+
154
+ For MCPI connectors, only validated Database Connections should be selectable when the driver supports validation.
155
+
156
+ ## What the app owns
157
+
158
+ The app should expose a "Fontes de Dados" or equivalent in-app view when it has `data_bindings`.
159
+
160
+ The app consumes ProductBridge:
161
+
162
+ ```ts
163
+ const PLAY_BASE = import.meta.env.VITE_AIOSON_PLAY_URL || "http://localhost:5180";
164
+ const APP_SLUG = import.meta.env.VITE_AIOSON_APP_SLUG || "meu-app";
165
+
166
+ const connectors = await fetch(`${PLAY_BASE}/api/connectors?type=mcpi`).then(r => r.json());
167
+ const bindings = await fetch(`${PLAY_BASE}/api/bindings/${APP_SLUG}`).then(r => r.json());
168
+
169
+ await fetch(`${PLAY_BASE}/api/bindings/${APP_SLUG}`, {
170
+ method: "POST",
171
+ headers: { "Content-Type": "application/json" },
172
+ body: JSON.stringify({
173
+ connector_id: "<uuid-do-connector>",
174
+ alias: "busca-produtos"
175
+ })
176
+ });
177
+ ```
178
+
179
+ ## Executing connectors
180
+
181
+ After binding, execute through ProductBridge by alias:
182
+
183
+ ```http
184
+ POST http://localhost:5180/api/mcp/execute
185
+ Content-Type: application/json
186
+
187
+ {
188
+ "alias": "busca-produtos",
189
+ "params": {
190
+ "search": "dipirona"
191
+ }
192
+ }
193
+ ```
194
+
195
+ The alias must match both:
196
+
197
+ - `data_bindings[].id`
198
+ - the active binding alias
199
+
200
+ ## Degraded state
201
+
202
+ If a declared binding is absent:
203
+
204
+ - Do not crash.
205
+ - Show a clear degraded state.
206
+ - Link the user to the app's data-source binding UI when possible.
207
+ - For non-optional connectors, block only the affected workflow, not the whole app unless the app cannot function.
208
+
209
+ Boot check:
210
+
211
+ ```ts
212
+ async function getMissingBindings(appSlug: string) {
213
+ const playBase = import.meta.env.VITE_AIOSON_PLAY_URL || "http://localhost:5180";
214
+ const bindings = await fetch(`${playBase}/api/bindings/${appSlug}`).then(r => r.json());
215
+ const activeAliases = new Set(bindings.map((b: { alias: string }) => b.alias));
216
+ return declaredBindings.filter(binding => !activeAliases.has(binding.id));
217
+ }
218
+ ```
219
+
220
+ ## LLM tool injection
221
+
222
+ Global Connectors are only useful to the LLM after they are bound to the app. Play can generate tool metadata from bindings, and the sidecar/orchestrator can use it in LLM payloads.
223
+
224
+ Agent rule:
225
+
226
+ - Keep connector names and descriptions accurate.
227
+ - Do not advertise tools/endpoints that are not implemented.
228
+ - Use prepared statements or connector-side parameterization for MCPI. The LLM must not assemble raw SQL.
229
+
230
+ ## Source docs
231
+
232
+ Canonical sources:
233
+
234
+ - `app-data-bindings.md`
235
+ - `app-database-choice.md`
236
+ - `integration-manual.md`
237
+ - `ai-app-integration.md`
238
+ - `platform-architecture.md`
@@ -0,0 +1,244 @@
1
+ ---
2
+ description: "AIOSON Play app manifest, runtime, package manager, scripts, ports, endpoint declaration, split-stack, and compatibility contract."
3
+ scope: "global"
4
+ agents: [dev, deyvin, architect, qa, tester]
5
+ task_types: [aioson-play-app, runtime, manifest]
6
+ triggers: [manifest.json, Play runtime, PORT, pnpm, ProductBridge, /api/aioson-play, requires_services]
7
+ ---
8
+
9
+ # Manifest And Runtime
10
+
11
+ ## Manifest basics
12
+
13
+ `manifest.json` is the app identity and runtime contract for Play.
14
+
15
+ Minimum shape:
16
+
17
+ ```json
18
+ {
19
+ "slug": "meu-app",
20
+ "name": "Meu App",
21
+ "version": "0.1.0",
22
+ "runtime": "vite",
23
+ "has_api": true
24
+ }
25
+ ```
26
+
27
+ Use stable lowercase slugs. The same slug is reused by Play registry, `VITE_AIOSON_APP_SLUG`, auth binding, cloud app status, package/update metadata, and data bindings.
28
+
29
+ ## Runtime detection
30
+
31
+ Play can detect common Node stacks from `package.json`, but explicit manifest fields are allowed when autodetect is not enough.
32
+
33
+ Supported Node runtime families in current docs:
34
+
35
+ | Stack | Signal |
36
+ |---|---|
37
+ | Next.js | `next` dependency |
38
+ | Vite | `vite` dependency or devDependency |
39
+ | Generic Node | `scripts.dev` |
40
+
41
+ For Play drafts and AIOSON-authored app work, use `pnpm`:
42
+
43
+ - `pnpm install`
44
+ - `pnpm add <pkg>`
45
+ - `pnpm add -D <pkg>`
46
+ - canonical lockfile: `pnpm-lock.yaml`
47
+
48
+ Do not create or preserve `package-lock.json` or `yarn.lock` in Play draft work unless an existing non-Play app explicitly requires it.
49
+
50
+ ## Scripts
51
+
52
+ `package.json` should provide a single Play entrypoint:
53
+
54
+ ```json
55
+ {
56
+ "scripts": {
57
+ "dev": "node src/server.js",
58
+ "start": "node dist/server.js"
59
+ }
60
+ }
61
+ ```
62
+
63
+ Rules:
64
+
65
+ - `dev` must work when Play injects `PORT`.
66
+ - `start` should work for published/build output when source is absent.
67
+ - Do not put fixed app ports in scripts.
68
+ - Do not run production build as the dev command.
69
+ - In Play drafts, do not fight the Play-injected cache env vars for Next/Vite/SWC.
70
+
71
+ ## Ports
72
+
73
+ Reserved ranges:
74
+
75
+ | Range | Purpose |
76
+ |---|---|
77
+ | `3001-3099` | Play Services, fixed in `service.json` |
78
+ | `3100-3299` | Internal Play systems, do not use |
79
+ | `3300-3499` | Marketplace-installed apps |
80
+ | `3500-3999` | Draft/dev-link apps |
81
+ | `4000-4099` | External curated apps, compatibility range |
82
+ | `5173` | Vite dev default, not a Play app contract |
83
+ | `5180` | ProductBridge HTTP server |
84
+
85
+ Rule: the app reads its own port from env; it discovers other ports through ProductBridge or service env vars.
86
+
87
+ Generic Node server:
88
+
89
+ ```js
90
+ const port = Number(process.env.PORT) || 3000;
91
+ app.listen(port, "0.0.0.0");
92
+ ```
93
+
94
+ Split-stack backend:
95
+
96
+ ```js
97
+ const port = Number(process.env.BACKEND_PORT) || 3301;
98
+ server.listen(port, "0.0.0.0");
99
+ ```
100
+
101
+ ## Split-stack apps
102
+
103
+ Use split-stack when the app has separate frontend and backend processes.
104
+
105
+ Manifest pattern:
106
+
107
+ ```json
108
+ {
109
+ "slug": "meu-app",
110
+ "name": "Meu App",
111
+ "version": "0.1.0",
112
+ "stack": "split",
113
+ "processes": {
114
+ "frontend": { "port_env": "PORT", "framework": "vite" },
115
+ "backend": { "port_env": "BACKEND_PORT", "framework": "node" }
116
+ },
117
+ "webview_target": "frontend"
118
+ }
119
+ ```
120
+
121
+ Rules:
122
+
123
+ - `webview_target` must match a key under `processes`.
124
+ - The frontend port is for the Play webview.
125
+ - Browser code should call `/api` same-origin and let Vite/Next proxy to the backend.
126
+ - The backend should use `BACKEND_PORT`.
127
+ - Do not hardcode `BACKEND_PORT` in scripts.
128
+
129
+ ## Next.js and Vite notes
130
+
131
+ For Next.js in Play drafts, include `allowedDevOrigins` with explicit loopback hosts. Next 16+ does not accept a wildcard for this case.
132
+
133
+ ```ts
134
+ const nextConfig = {
135
+ allowedDevOrigins: ["127.0.0.1", "localhost", "::1", "0.0.0.0"]
136
+ };
137
+
138
+ export default nextConfig;
139
+ ```
140
+
141
+ For Vite in Play drafts, prefer the current AIOSON Play draft convention: let Play pass the port through its spawn command and avoid declaring a fixed `server.port` unless the existing app contract explicitly uses env-driven split-stack config.
142
+
143
+ ## ProductBridge
144
+
145
+ ProductBridge is fixed at:
146
+
147
+ ```text
148
+ http://localhost:5180
149
+ ```
150
+
151
+ In browser/frontend code:
152
+
153
+ ```ts
154
+ const PLAY_URL = import.meta.env.VITE_AIOSON_PLAY_URL || "http://localhost:5180";
155
+ ```
156
+
157
+ Useful endpoints:
158
+
159
+ | Endpoint | Purpose |
160
+ |---|---|
161
+ | `GET /api/registry` | Discover running apps and Play Services |
162
+ | `GET /api/connectors` | List Global Connectors |
163
+ | `GET /api/bindings/:app_slug` | List app bindings |
164
+ | `POST /api/bindings/:app_slug` | Bind connector to app slot |
165
+ | `POST /api/mcp/execute` | Execute connector by alias |
166
+
167
+ ## Capability endpoint
168
+
169
+ If `has_api: true`, expose:
170
+
171
+ ```text
172
+ GET /api/aioson-play
173
+ ```
174
+
175
+ It declares identity, API base URL, endpoints, auth metadata, and events for Play, Bridge Apps, and LLM orchestration.
176
+
177
+ Minimum response shape:
178
+
179
+ ```json
180
+ {
181
+ "name": "Meu App",
182
+ "slug": "meu-app",
183
+ "version": "0.1.0",
184
+ "api_base_url": "http://localhost:3399",
185
+ "endpoints": [
186
+ {
187
+ "path": "/api/items",
188
+ "method": "GET",
189
+ "description": "Lista itens visiveis ao usuario",
190
+ "params": [],
191
+ "auth": false
192
+ }
193
+ ],
194
+ "events": []
195
+ }
196
+ ```
197
+
198
+ Only list endpoints that exist. The orchestrator may try to call what this endpoint advertises.
199
+
200
+ ## Services dependency
201
+
202
+ When an app requires a Play Service:
203
+
204
+ ```json
205
+ {
206
+ "requires_services": ["aioson-auth"]
207
+ }
208
+ ```
209
+
210
+ Play uses this to show onboarding requirements, check service install/runtime state, and block or degrade app launch when the required service is missing.
211
+
212
+ ## Publish compatibility
213
+
214
+ Publishable apps should declare compatibility:
215
+
216
+ ```json
217
+ {
218
+ "compatibility": {
219
+ "min_play_version": "0.2.0",
220
+ "min_runtime_version": "1.0.0",
221
+ "max_runtime_version": "1.x",
222
+ "sidecar_contract": "ndjson-v1",
223
+ "schema_version": 1,
224
+ "requires_migration": false
225
+ }
226
+ }
227
+ ```
228
+
229
+ If local data schema changes:
230
+
231
+ - Increment `schema_version`.
232
+ - Provide idempotent migrations where possible.
233
+ - Never delete user data as the default migration strategy.
234
+ - Use backup before destructive or risky migration.
235
+
236
+ ## Source docs
237
+
238
+ Canonical sources:
239
+
240
+ - `ai-app-integration.md`
241
+ - `aioson-endpoint-protocol.md`
242
+ - `port-management.md`
243
+ - `software-update-compatibility.md`
244
+ - `.aioson/rules/aioson-play-conventions.md` in this repo
@@ -0,0 +1,104 @@
1
+ ---
2
+ description: "Map from AIOSON Play app compatibility topics to canonical source docs in the aioson-play repository."
3
+ scope: "global"
4
+ agents: [dev, deyvin, architect, analyst, qa, tester, product, sheldon, pentester]
5
+ task_types: [aioson-play-app, source-map, integration]
6
+ triggers: [AIOSON Play source docs, canonical Play docs, integration docs, ProductBridge, data bindings]
7
+ ---
8
+
9
+ # Source Map
10
+
11
+ Canonical source directory:
12
+
13
+ ```text
14
+ C:\dev\aioson-play\.aioson\docs\integrations\
15
+ ```
16
+
17
+ This AIOSON folder is a curated operational layer. When exact Play runtime behavior matters and the source repo is present, read the canonical file below.
18
+
19
+ ## Entry points
20
+
21
+ | Need | Canonical doc |
22
+ |---|---|
23
+ | Build or modify a Play-compatible app | `ai-app-integration.md` |
24
+ | Cross-cutting Play/platform fix | `platform-architecture.md` |
25
+ | Auth roadmap/gaps and delivered slices | `auth-integration-gaps.md` |
26
+
27
+ ## Topic map
28
+
29
+ | Topic | Canonical doc |
30
+ |---|---|
31
+ | App developer overview | `aioson-app-developer-guide.md` |
32
+ | `/api/aioson-play` capability endpoint | `aioson-endpoint-protocol.md` |
33
+ | ProductBridge and port registry | `port-management.md` |
34
+ | Play Services and `service.json` | `play-service-protocol.md` |
35
+ | Cloud owner/trial auth | `app-cloud-auth.md` |
36
+ | Data Bindings and Global Connectors | `app-data-bindings.md` |
37
+ | App operational database choice | `app-database-choice.md` |
38
+ | External systems, MCPI/API/MCP connector manual | `integration-manual.md` |
39
+ | Dev-link install | `dev-link-install.md` |
40
+ | Local symlink testing | `local-dev-testing.md` |
41
+ | App update and compatibility fields | `software-update-compatibility.md` |
42
+ | Atendimento reference integration | `atendimento-squad-integration.md` |
43
+ | Farmacia implementation review | `farmacia-implementation-review.md` |
44
+
45
+ ## Current source docs observed
46
+
47
+ As of 2026-06-23, the Play integration source directory contains:
48
+
49
+ ```text
50
+ ai-app-integration.md
51
+ aioson-app-developer-guide.md
52
+ aioson-endpoint-protocol.md
53
+ app-cloud-auth.md
54
+ app-data-bindings.md
55
+ app-database-choice.md
56
+ atendimento-squad-integration.md
57
+ auth-integration-gaps.md
58
+ dev-link-install.md
59
+ farmacia-implementation-review.md
60
+ integration-manual.md
61
+ local-dev-testing.md
62
+ platform-architecture.md
63
+ play-service-protocol.md
64
+ port-management.md
65
+ README.md
66
+ software-update-compatibility.md
67
+ ```
68
+
69
+ ## Embedded contract stamped into apps
70
+
71
+ Play stamps a canonical contract directly into each app, between
72
+ `AIOSON-PLAY-CONTRACT:START` / `AIOSON-PLAY-CONTRACT:END` markers. Source:
73
+
74
+ ```text
75
+ C:\dev\aioson-play\src-tauri\src\resources\play_app_contract.md
76
+ ```
77
+
78
+ This is the most authoritative single-file contract for an installed app. It carries:
79
+
80
+ - The closed whitelist of env vars Play injects at spawn, including `AIOSON_APP_DIR` (absolute app dir) and the auth vars in `VITE_`-only form.
81
+ - `.aioson/preview.json` — written by Play at runtime with `{ running, url, port }`; read it on demand to learn the live preview URL/port instead of guessing.
82
+ - The "ready-for-Play" gate the app must pass before being declared done.
83
+
84
+ When an app project already contains this stamped block, treat it as primary and do not contradict it. The docs in this folder are the AIOSON-side fallback when the stamped contract or the `aioson-play` repo is not available.
85
+
86
+ ## Known priority notes
87
+
88
+ - `.aioson/rules/aioson-play-conventions.md` in this AIOSON repo overrides older examples when working inside Play drafts, especially package manager and draft runtime behavior.
89
+ - Older Play docs may show `npm` examples. In AIOSON-authored Play draft work, use `pnpm`.
90
+ - Some canonical docs describe planned behavior. Check wording before implementing: "planejado", "futuro", "pendente", or "nao implementado" means do not rely on it as shipped runtime behavior.
91
+ - If a canonical doc and local Play source code disagree, inspect code and update the canonical Play doc before relying on the changed behavior.
92
+
93
+ ## Suggested human-facing Play Guide page
94
+
95
+ If AIOSON Play exposes a "Guia" tab for human users, it should not dump these agent docs. It should present a short human path:
96
+
97
+ 1. Create an app folder with `manifest.json`.
98
+ 2. Use `pnpm`.
99
+ 3. Make the app read `PORT`.
100
+ 4. Add `app-config.yaml` only when using database config or data sources.
101
+ 5. Link the folder through "Instalar App -> Linkar pasta (dev)".
102
+ 6. Test inside the Play webview.
103
+
104
+ The detailed implementation contract should remain here for AIOSON agents and in the canonical `aioson-play` integration docs.