tutti-app-release
Set up, review, run, or debug external repositories that publish a Tutti workspace app through the reusable Tutti App Release GitHub Actions workflow. Use for caller workflows, tutti.app.json manifests, @tutti-os/app-release-tools, S3/CloudFront release hosting, latest.json, versions.json, catalog.json, catalog-only repairs, and App Center visibility issues.
git clone --depth 1 https://github.com/tutti-os/tutti /tmp/tutti-app-release && cp -r /tmp/tutti-app-release/.codex/skills/tutti-app-release ~/.claude/skills/tutti-app-releaseSKILL.md
# Tutti App Release
Use this skill when an external app repository publishes a remote Tutti workspace app into App Center release metadata.
The external repository calls the reusable workflow from the Tutti/Tutti repository:
```yaml
uses: tutti-os/tutti/.github/workflows/publish-tutti-app-release.yml@main
```
That workflow builds one app package, runs `@tutti-os/app-release-tools`, uploads immutable release files plus mutable `latest.json` and `versions.json`, and can optionally merge that app into the shared `catalog.json`.
## Operating Rules
Inspect before acting:
- Read the caller workflow, `tutti.app.json`, package script, and recent GitHub Actions runs.
- Confirm whether the user wants a new app release, a catalog refresh, or CI debugging. Do not rerun a release just to repair catalog state.
For catalog publication:
- There are three valid modes. Explain them explicitly when helping a user choose.
- Release only: `publish_catalog: false`. This uploads a new app version and updates `apps/<appId>/latest.json` and `versions.json`; App Center will see it the next time `catalog.json` is published.
- Release and catalog: `publish_catalog: true`. This uploads the app release, then immediately merges that release into `catalog.json`.
- Catalog only: `catalog_only: true`. Use this after a release already succeeded when the user forgot to publish catalog, wants to validate first, or wants to refresh catalog without bumping or uploading a new version.
- Do not rerun a full app release just to repair catalog state.
- If the app caller workflow exposes `catalog_only`, use that. If it does not, use the Tutti catalog workflow directly or add the caller input when the user wants that repo to support catalog-only dispatch.
For versioning:
- Production releases should be workflow-driven. Run the production caller workflow with `release_bump` (`patch`, `minor`, or `major`); the reusable workflow calculates the next version from the greater of the packaged manifest version and existing release tags, then creates the tag after the S3 release verifies.
- The workflow never bumps or commits app manifest versions. Do not add caller-side release PRs or manifest bump commits to work around protected branches.
- Staging releases should leave `release_bump` empty. The workflow uses `manifest.version+<short git sha>` from the packaged manifest and does not create a release tag.
For reusable workflow changes:
- Keep long-lived release behavior in the Tutti reusable workflows and app release tools.
- Keep caller workflows small and stable: app id, package command/dir, runner/tool versions when needed, and environment-specific AWS/CDN values.
- Require callers to declare `min_tutti_version` explicitly. Use `0.0.0` only for releases that are safe for every legacy Tutti client.
- Avoid requiring app repositories to change for catalog repair behavior. Use an existing catalog-only path for that.
## Release Contract
The caller repository must be compatible with pnpm. The reusable workflow runs `pnpm install --frozen-lockfile` before `package_command`, so the repository should commit `pnpm-lock.yaml` and define the package script used by `package_command`.
The caller repository must commit a source manifest:
```text
tutti.app.json
```
The generated package directory must contain:
- `tutti.app.json`
- `bootstrap.sh`
- `AGENTS.md`
- the manifest icon asset, such as `icon.png` or `icon.svg`
- all runtime files and assets
The source and package manifests must use `schemaVersion: "tutti.app.manifest.v1"`. `appId` must match the workflow `app_id` input.
The workflow writes release objects under:
```text
apps/<appId>/<version>/
apps/<appId>/latest.json
apps/<appId>/versions.json
```
For production, the workflow derives the next release version by fetching
existing stable semver tags with the configured `release_tag_prefix` (default
`<appId>-v`), reading the packaged manifest version, and applying
`release_bump` to the greater version. It creates the annotated release tag after
the S3 release has been uploaded and verified. If `release_bump` is empty, the
workflow uses `manifest.version+<short git sha>` from the packaged manifest,
which is intended for staging.
## Reference Caller Workflow
Use this as the default single-app production caller. Production releases should
be workflow-driven so publishing does not need to write version bump commits back
to the protected source branch. Keep new app repositories as close to this
reference as their package command allows.
```yaml
name: Publish Tutti App Production
on:
workflow_dispatch:
inputs:
release_bump:
description: Semver bump to publish.
required: true
type: choice
default: patch
options:
- patch
- minor
- major
publish_catalog:
description: Whether to publish the production App Center catalog after this release.
required: false
type: boolean
default: true
catalog_only:
description: Whether to skip app release upload and only publish the existing latest release to catalog.
required: false
type: boolean
default: false
permissions:
contents: write
id-token: write
jobs:
publish:
uses: tutti-os/tutti/.github/workflows/publish-tutti-app-release.yml@main
with:
app_id: your-app-id
min_tutti_version: "REQUIRED_MIN_TUTTI_VERSION"
package_command: pnpm package:tutti
package_dir: build/tutti-app/package
icon_path: build/tutti-app/package/icon.png
release_tag_prefix: your-app-id-v
release_bump: ${{ inputs.release_bump }}
create_release_tag: ${{ !inputs.catalog_only }}
publish_catalog: ${{ inputs.publish_catalog }}
catalog_only: ${{ inputs.catalog_only }}
aws_region: ${{ vars.TUTTI_APP_RELEASES_PRODUCTION_AWS_REGION || vars.TUTTI_APP_RELEASES_AWS_REGION }}
aws_role_arn: ${{ vars.TUTTI_APP_RELEASES_PRODUCTION_AWS_ROLE_ARN |Analyze Chrome, Chromium, Electron, React DevTools, or Perfetto-compatible JSON traces and audit user-reported profiling findings without loading large artifacts into context; prove trigger-to-render/layout chains, separate measured facts from source inference, find exact code choke points, classify forced layout and render fanout, implement semantically safe fixes, and verify behavior plus repository budgets. Use for trace files, reported profiling durations or call chains, dropped frames, long tasks, resize or scroll jank, render storms, layout thrashing, selector hot paths, interaction latency, or requests to locate exact source-level bottlenecks.
Review tutti git diffs for project structure, layering, module ownership, and duplicate event-center infrastructure by planning focused architecture review tasks, then having the main agent orchestrate sub-agents for only the changed areas.
>-
Audit, design, write, materially revise, or remove Tutti tests. Use whenever Codex changes or reviews unit, component, conformance, integration, regression, platform, or repository tests; enforce a protected product contract, credible failure, correct owning boundary, negative-control evidence, overlap review, deterministic setup, and an executing CI lane.
Use when working with @tutti-os/ui-system components, replacing local UI with shared components, querying component ids or metadata, promoting UI into shared base or business components, or maintaining UI-system storyboard inventory.
Build or evolve a complex agent-enabled Tutti workspace app repository. Use for Tutti apps with web/server/shared monorepos, @tutti-os/agent-acp-kit local agent runtimes, kit-owned TUTTI_CLI agent/composer discovery, dynamic agent catalogs, run-scoped MCP tool gateways, app-owned package builders, web-first debugging, i18n harnesses, and production package validation. For simple package creation or repair, use tutti-workspace-app-factory instead.
Create, convert, or repair one Tutti workspace app as either a self-contained publishable package under package/ or a Chrome-style local debug app under .tutti/dev-app/. Use for mention://workspace-app-factory/create handoffs, mention://workspace-app-factory handoffs, standalone app generation, adapting existing repositories, Load unpacked repair flows for invalid local project directories, tutti.app.json and tutti.cli.json manifests, bootstrap.sh scripts, package-local AGENTS.md, local HTTP runtimes, TUTTI_APP_* host/port/storage rules, healthchecks, app assets, i18n, validation, and optional Tutti CLI integration.