Skip to content

feat: add Community Apps callback launch action#51

Closed
elibosley wants to merge 5 commits into
mainfrom
codex/community-apps-launch-action
Closed

feat: add Community Apps callback launch action#51
elibosley wants to merge 5 commits into
mainfrom
codex/community-apps-launch-action

Conversation

@elibosley
Copy link
Copy Markdown
Member

@elibosley elibosley commented Jun 2, 2026

Summary

  • Add a typed communityApps launch action for Unraid OS iframe launches.
  • Include server context plus optional install URL template, install target, path, theme, and locale fields.
  • Add explicit opt-in installedApps support with enabled: true, algorithm: "sha256-128", launch salt, and fixed-length app hash keys.
  • Add preferred mode: "lookup" so CA can ask the parent for statuses only for visible apps instead of receiving the full installed/history set.
  • Export CommunityAppsInstalledAppStatus, fixed hash helpers, and createCommunityAppsInstalledAppsHostBridge through the client entrypoint.
  • Cover callback URL generation/parsing and fixed 22-character app hash generation.
  • Include the TS6 rootDir build fix needed for the package build on this branch.

Privacy contract

  • CommunityAppsLaunch.installedApps should be omitted by default.
  • Consumers should include it only after user opt-in for local installed badges.
  • Prefer mode: "lookup"; the CA iframe sends only visible salted app fingerprints over the post-me bridge and receives compact status codes for those hashes.
  • Batch mode remains available with an apps status map, but should not be the default for Unraid OS iframe integration.
  • The payload and bridge carry salted app fingerprints, not raw app IDs or template URLs.
  • App fingerprints are salted SHA-256 values truncated to 128 bits and encoded as unpadded base64url, producing fixed 22-character map keys.
  • Status values are compact numeric codes: Installed = 1, PreviouslyInstalled = 2.

Testing

  • pnpm test -- --run src/__tests__/server.test.ts
  • pnpm build

Summary by CodeRabbit

  • New Features

    • Added Community Apps launch and local installed-apps support, including client-side host bridge and install-status reporting and hash-based identifiers.
  • Documentation

    • Expanded Community Apps types and usage guidance, including opt-in rules and required formatting for installed-apps data.
  • Tests

    • Added tests for launch payload round-trip and installed-app hash generation/format.

elibosley added 2 commits June 2, 2026 12:39
- Add a typed communityApps action for Unraid OS to launch Community Apps inside an iframe.

- Before, callback payloads only modeled account, license, and OS update actions.

- That left CA iframe launches without a shared contract for server context, install targets, or theme/path preferences.

- Add CommunityAppsLaunch to the UPC action union with server data and optional install URL customization fields.

- Export the new action type through client and server entrypoints and cover server round-trip generation/parsing.

- Regenerate package declaration files so consumers can type against the new contract.
- Purpose: keep declaration builds working after the PR upgrades TypeScript from v5 to v6.
- Before: \tsconfig.json(8,25): error TS6046: Argument for '--moduleResolution' option must be: 'node', 'classic', 'node16', 'nodenext'.
tsconfig.json(9,5): error TS5023: Unknown compiler option 'allowImportingTsExtensions'.
tsconfig.json(10,5): error TS5070: Option '--resolveJsonModule' cannot be specified without 'node' module resolution strategy. inferred the common source directory and CI failed with TS5011 under TypeScript 6.
- Why that was a problem: the PR branch looked green locally with stale dependencies, but the actual CI environment installs the new compiler and the build stopped before publish.
- What this change accomplishes: it makes the source layout explicit so declaration emit remains stable on TypeScript 6.
- How it works: set \rootDir\: \src\ in \ to match the package entrypoints and output structure.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 2, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a CommunityApps UPC action and installed-apps types, implements hash and validator, provides a client host-bridge (post-me handshake) and typings, re-exports types from client/server entry points, adds tests, updates README, package.json, and tsconfig rootDir.

Changes

CommunityAppsLaunch action type addition

Layer / File(s) Summary
CommunityApps type definitions
src/types.ts
Adds CommunityApps literal, installed-apps algorithm/mode/status/hash/status-map types, batch/lookup payloads, status request/response, CommunityAppsLaunch interface, and extends UpcActions.
Installed-app hash and validator
src/community-apps.ts
Adds COMMUNITY_APPS_INSTALLED_APPS_ALGORITHM, hash length constant, createCommunityAppsInstalledAppHash(stableIdentifier, salt) (SHA256 truncate → base64 URL-safe), and isCommunityAppsInstalledAppHash type guard.
Client-side host bridge (post-me)
src/community-apps-client.ts, src/post-me.d.ts
New host bridge types and createCommunityAppsInstalledAppsHostBridge async factory using ParentHandshake + WindowMessenger; adds post-me typings for WindowMessenger and ParentHandshake.
Client and server re-exports
src/client.ts, src/server.ts
Import and re-export CommunityApps and installed-apps related types from ./types.js; re-export CommunityAppsInstalledAppStatus named export.
Round-trip and hash tests
src/__tests__/server.test.ts
Adds Vitest test for createServerCallback round-trip with CommunityAppsLaunch payload and tests for hash format/determinism.
Docs, config, and dependency
README.md, tsconfig.json, package.json
Documents CommunityApps types and installed-state inclusion/format constraints in README; sets compilerOptions.rootDir: "src"; adds post-me runtime dependency.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A new action hops into the fold,
Community Apps launch stories told,
Hashes trimmed and handshakes made,
Tests confirm the paths were laid,
README, exports, and build flags bold!

sequenceDiagram
  participant LocalWindow
  participant WindowMessenger
  participant ParentHandshake
  participant IframeWindow
  LocalWindow->>WindowMessenger: construct(remoteWindow, remoteOrigin)
  WindowMessenger->>ParentHandshake: initialise handshake(messenger)
  ParentHandshake->>IframeWindow: send handshake messages
  IframeWindow->>ParentHandshake: respond to handshake
  ParentHandshake->>LocalWindow: resolve(connection with close())
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title follows the conventional commits format with 'feat:' prefix and clearly describes the main change: adding a Community Apps callback launch action, which aligns with the PR's primary objective.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/community-apps-launch-action
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch codex/community-apps-launch-action

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 2, 2026

Codecov Report

❌ Patch coverage is 59.09091% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.36%. Comparing base (637132e) to head (a85a496).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
src/community-apps-client.ts 14.28% 6 Missing ⚠️
src/community-apps.ts 75.00% 3 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##              main      #51      +/-   ##
===========================================
- Coverage   100.00%   92.36%   -7.64%     
===========================================
  Files            3        6       +3     
  Lines          109      131      +22     
  Branches        30       36       +6     
===========================================
+ Hits           109      121      +12     
- Misses           0       10      +10     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/types.ts (1)

165-175: 💤 Low value

Consider documenting the install-field semantics and the locale/theme overlap.

The interface exposes three closely-related install fields (installUrl, installUrlTemplate, installParam) whose relationship is not obvious to downstream consumers — e.g. whether installUrl and installUrlTemplate are mutually exclusive, and how installParam feeds the template. Additionally, locale (and theme) duplicate fields already present on ServerData (locale, L110) / ActivationCodeData (theme), so precedence between the top-level value and the nested server value is ambiguous. Brief JSDoc on these fields would prevent misuse.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/types.ts` around lines 165 - 175, Add concise JSDoc to the
CommunityAppsLaunch interface documenting the install-field semantics and
precedence for locale/theme: state that installUrl and installUrlTemplate are
mutually exclusive, describe that installUrlTemplate is a string template where
installParam is substituted into a well-defined placeholder (e.g., {param}) and
how missing installParam is handled, and clarify whether installTarget/path
affect installation flow; also document that top-level locale and theme override
or fall back to ServerData.locale and ActivationCodeData.theme (specify the
chosen precedence: top-level wins, otherwise use nested), and include examples
or allowed formats where useful; update the CommunityAppsLaunch definition and
mention related types ServerData and ActivationCodeData to make the precedence
explicit.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/types.ts`:
- Around line 165-175: Add concise JSDoc to the CommunityAppsLaunch interface
documenting the install-field semantics and precedence for locale/theme: state
that installUrl and installUrlTemplate are mutually exclusive, describe that
installUrlTemplate is a string template where installParam is substituted into a
well-defined placeholder (e.g., {param}) and how missing installParam is
handled, and clarify whether installTarget/path affect installation flow; also
document that top-level locale and theme override or fall back to
ServerData.locale and ActivationCodeData.theme (specify the chosen precedence:
top-level wins, otherwise use nested), and include examples or allowed formats
where useful; update the CommunityAppsLaunch definition and mention related
types ServerData and ActivationCodeData to make the precedence explicit.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fd45e23e-b475-4941-9026-7c0fb38c77ba

📥 Commits

Reviewing files that changed from the base of the PR and between 6181363 and 4057c62.

⛔ Files ignored due to path filters (3)
  • dist/client.d.ts is excluded by !**/dist/**
  • dist/server.d.ts is excluded by !**/dist/**
  • dist/types.d.ts is excluded by !**/dist/**
📒 Files selected for processing (6)
  • README.md
  • src/__tests__/server.test.ts
  • src/client.ts
  • src/server.ts
  • src/types.ts
  • tsconfig.json

elibosley added 3 commits June 2, 2026 13:54
- Add an explicit installedApps payload block for Community Apps launches.

- Before, the launch action had no contract for installed-state exposure.

- That made it unclear how Core should represent optional installed app matching without weakening the privacy boundary.

- Model installed app fingerprints as an optional enabled:true block with algorithm, salt, and keys.

- Keep the field omitted unless a user opts into local installed-state badges.
- Replace the flat installed app fingerprint list with a compact status map.

- Before, callbacks could only say that a hash was present, so CA could not distinguish currently installed apps from previously installed apps.

- Variable-length hash strings also risked wasting URL space in hash-based iframe launches.

- Add numeric installed app status codes and fixed sha256-128 app fingerprints encoded as 22-character base64url keys.

- Export the status enum through client and server entrypoints so Core can build payloads without hardcoding status values.
- Add lookup mode for Community Apps installed app status payloads.

- Before, status context had to be carried as a launch-time app map when CA needed installed-state UI.

- That exposed more installed-app information than necessary and could grow callback URLs.

- Add fixed-length salted app hash helpers and a post-me parent bridge for visible-app status lookups.

- Keep batch maps available while making lookup mode the preferred privacy-preserving integration.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/community-apps.ts (1)

27-32: 💤 Low value

Minor: redundant length check.

The regex /^[A-Za-z0-9_-]{22}$/ already constrains the value to exactly 22 characters, so the trailing value.length === COMMUNITY_APPS_INSTALLED_APP_HASH_LENGTH comparison is dead. It's harmless and keeps the length constant referenced, so feel free to leave it as-is.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/community-apps.ts` around lines 27 - 32, The type guard
isCommunityAppsInstalledAppHash redundantly checks length after the regex
already enforces exactly 22 chars; remove the trailing value.length ===
COMMUNITY_APPS_INSTALLED_APP_HASH_LENGTH clause (or alternatively remove the
{22} quantifier in the regex if you prefer the constant), leaving a single
consistent length check referencing COMMUNITY_APPS_INSTALLED_APP_HASH_LENGTH via
one approach to avoid duplication.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/community-apps.ts`:
- Around line 27-32: The type guard isCommunityAppsInstalledAppHash redundantly
checks length after the regex already enforces exactly 22 chars; remove the
trailing value.length === COMMUNITY_APPS_INSTALLED_APP_HASH_LENGTH clause (or
alternatively remove the {22} quantifier in the regex if you prefer the
constant), leaving a single consistent length check referencing
COMMUNITY_APPS_INSTALLED_APP_HASH_LENGTH via one approach to avoid duplication.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 527b7e24-a881-4e31-b38c-1f410a0a3325

📥 Commits

Reviewing files that changed from the base of the PR and between c521c5b and a85a496.

⛔ Files ignored due to path filters (9)
  • dist/client.d.ts is excluded by !**/dist/**
  • dist/client.js is excluded by !**/dist/**
  • dist/community-apps-client.d.ts is excluded by !**/dist/**
  • dist/community-apps.d.ts is excluded by !**/dist/**
  • dist/index.js is excluded by !**/dist/**
  • dist/server.d.ts is excluded by !**/dist/**
  • dist/server.js is excluded by !**/dist/**
  • dist/types.d.ts is excluded by !**/dist/**
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (9)
  • README.md
  • package.json
  • src/__tests__/server.test.ts
  • src/client.ts
  • src/community-apps-client.ts
  • src/community-apps.ts
  • src/post-me.d.ts
  • src/server.ts
  • src/types.ts
✅ Files skipped from review due to trivial changes (1)
  • src/post-me.d.ts

@elibosley
Copy link
Copy Markdown
Member Author

Superseded by #52. The new alpha contracts branch includes the full codex/community-apps-launch-action branch plus the remaining Community Apps install/theme/export contract updates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant