feat(tinyplace): resolve feed post media as web-only (#4924) - #5295
Conversation
Post images/GIFs have no backend contract on tiny.place — neither the write-side PostCreate nor the read-side Post/GqlPost in the pinned SDK submodule carries a media field, and the backend serves none. An in-app upload would round-trip to nothing and render nowhere. Mirror the identity-marketplace seller resolution (tinyhumansai#4920 / PR tinyhumansai#5193): add a small note + CTA at the bottom of the feed composer that opens tiny.place via openUrl() instead of dead-ending, and record the web-only scope in the FeedSection header and tinyplace/mod.rs doc comments. Additive UI only — no SDK, core, or submodule pointer change. - FeedSection.tsx: ADD_MEDIA_ON_WEB_URL note + CTA in FeedComposer - FeedSection.test.tsx: note renders + CTA calls openUrl (mocked) - tinyplace/mod.rs: 'Feed scope (post media is web-only)' doc note - docs/superpowers: design spec + implementation plan
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThe feed composer now identifies media as web-only, provides a CTA to ChangesFeed media web-only flow
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Suggested labels: Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6b37d31f27
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // prod URL, matching the `SELL_ON_WEB_URL` precedent in IdentitiesSection.tsx and | ||
| // `FUND_PAGE_URL` in X402ConfirmDialog.tsx (the tiny.place web app has no per-env | ||
| // base). tiny.place's home page is the feed, where the media composer lives. | ||
| const ADD_MEDIA_ON_WEB_URL = 'https://tiny.place'; |
There was a problem hiding this comment.
Route the media CTA to the active tiny.place network
In staging builds, or installations using TINYPLACE_API_BASE_URL, feed requests intentionally use the configured relay (src/openhuman/tinyplace/state.rs lines 37–45), but this constant always opens the production web app. A media post created after following this CTA therefore belongs to production and cannot appear in the staging/custom feed the user just left. Derive the web destination from the exposed relay/network, or suppress the CTA when no matching web frontend exists.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Thanks — real product nuance, but declining after checking the codebase convention: it rests on a premise that doesn't hold here.
There is no per-network tiny.place web frontend to derive from or route to. Only the API host varies by environment (api.tiny.place vs staging-api.tiny.place, resolved server-side in tinyplace/state.rs via TINYPLACE_API_BASE_URL / app-env). The human-facing website is a single origin — https://tiny.place — used unconditionally everywhere for exactly this reason, as the core documents:
src/openhuman/tinyplace/agent_tools/flows_write.rs:532-537— "The SDK base URL points at the backend API (e.g.api.tiny.place); the human/council-facing site istiny.place(same origin the wallet fund page uses)." →const TINYPLACE_WEB_ORIGIN = "https://tiny.place";
Same hardcoded origin in X402ConfirmDialog.tsx (FUND_PAGE_URL) and IdentitiesSection.tsx (SELL_ON_WEB_URL, the sibling #4920/#5193 resolution this PR mirrors). Deriving-from-relay isn't possible (the exposed relay base is the API host, not a web host, and no staging.tiny.place web app exists), and suppressing only this CTA on non-prod would make it the one tiny.place web link in the app that behaves differently from post permalinks / fund / sell.
I've added a code comment at the constant spelling this out so it doesn't get re-flagged (48b0341). If we ever want per-env web origins, that's a single shared helper covering all four links — out of scope for this pointer note.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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.
Inline comments:
In `@docs/superpowers/plans/2026-07-30-tinyplace-feed-post-media-web-only.md`:
- Around line 37-39: The Task 4 checkbox conflicts with its “Done via gh”
completion claim. Verify the external GitHub bookkeeping; if complete, change
Task 4 to [x], otherwise keep it unchecked and remove the completion claim until
the work is finished.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 0e1dc21d-ac4d-4149-b1ac-8729cdc85ab9
📒 Files selected for processing (5)
app/src/agentworld/pages/FeedSection.test.tsxapp/src/agentworld/pages/FeedSection.tsxdocs/superpowers/plans/2026-07-30-tinyplace-feed-post-media-web-only.mddocs/superpowers/specs/2026-07-30-tinyplace-feed-post-media-web-only-design.mdsrc/openhuman/tinyplace/mod.rs
|
| Filename | Overview |
|---|---|
| app/src/agentworld/pages/FeedSection.tsx | Adds ADD_MEDIA_ON_WEB_URL constant, openUrl import, and a persistent media note + CTA button inside FeedComposer; note is correctly wallet+feed gated and follows existing hardcoded-URL precedents. No logic changes to existing code paths. |
| app/src/agentworld/pages/FeedSection.test.tsx | Two new tests added inside the existing 'post composer' describe block: note rendering assertion and CTA click → openUrl call assertion. openUrl is mocked via vi.mock at module level with a default Promise.resolve() impl; vi.mocked reference is used correctly for assertion. |
| docs/superpowers/plans/2026-07-30-tinyplace-feed-post-media-web-only.md | New implementation plan doc recording the web-only decision, constraints (no i18n, hardcoded prod URL, openUrl-only external links), and task checklist. Documentation only. |
| docs/superpowers/specs/2026-07-30-tinyplace-feed-post-media-web-only-design.md | New design spec explaining the problem (SDK and backend lack post-media fields), the decision to resolve web-only, and the follow-up path for genuine in-app support. Documentation only. |
| src/openhuman/tinyplace/mod.rs | Doc-comment-only change: adds a 'Feed scope (post media is web-only)' section next to the existing marketplace web-only note. No executable code changed. |
Sequence Diagram
sequenceDiagram
participant User
participant FeedComposer
participant openUrl
participant TinyPlaceWeb as tiny.place (web)
Note over FeedComposer: Rendered only when<br/>myAgentId && feedState.status === 'ok'
User->>FeedComposer: Views composer
FeedComposer-->>User: "Shows textarea + Post button<br/>+ note + CTA"
User->>FeedComposer: Clicks "Open tiny.place" CTA
FeedComposer->>openUrl: openUrl('https://tiny.place')
openUrl->>TinyPlaceWeb: Opens in OS default browser
TinyPlaceWeb-->>User: tiny.place feed (media composer available)
Reviews (1): Last reviewed commit: "feat(tinyplace): resolve feed post media..." | Re-trigger Greptile
…kkeeping done (tinyhumansai#4924) Address PR tinyhumansai#5295 review: - Codex P2 (env-aware CTA): document in-code that tiny.place has a single human-facing web origin by design (the API host varies by env, the website does not) — matching TINYPLACE_WEB_ORIGIN / FUND_PAGE_URL / SELL_ON_WEB_URL. No per-network web frontend exists to route to, so the constant stays prod. - CodeRabbit: resolve the plan Task 4 checkbox/'done' contradiction (marked [x] now that the GitHub bookkeeping is complete).
There was a problem hiding this comment.
CodeGhost21 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
Summary
https://tiny.placeviaopenUrl()instead of dead-ending, so a user who wants to attach media is pointed to where they can.FeedSection.tsxheader docstring andsrc/openhuman/tinyplace/mod.rs(next to the existing marketplace web-only note).invokeApiClient, orvendor/tinyplacesubmodule-pointer change.Problem
The audit item "Images / media in posts" (#4776 §2 Feed) fails at the contract level, not just the UI:
tinyplaceSDK carries no media field on the write side (PostCreate={ body, content_type, post_id }) or the read side (Post/GqlPost).main(d2545054— the commit openhuman already pins): the SDK structs there still have noimage/media/giffield.vendor/tinyplaceis a pinned git submodule; openhuman can only bump the pointer to a commit on the tiny.place remote — it cannot add the contract.An in-app upload would therefore round-trip to nothing and render nowhere. (A prior WIP branch pinned the submodule to a local-only SDK commit to make it build; that is unmergeable and, being SDK-only, still wouldn't render media because the backend serves none.)
Solution
Follow the #4920 / #5193 pattern: point users to the web app rather than ship UI against a non-existent contract. A persistent note in
FeedComposer(data-testid="add-media-on-web") with a CTA (data-testid="add-media-on-web-cta",data-analytics-id="feed.addMediaOnWeb") openshttps://tiny.place(home page = feed) through the existingopenUrl()helper — mirroring theSELL_ON_WEB_URL(IdentitiesSection) andFUND_PAGE_URL(X402ConfirmDialog) precedents. New strings are hardcoded English to matchFeedComposer, which uses nouseT()(same rationale as #5193). Design spec + plan underdocs/superpowers/.Submission Checklist
openUrl('https://tiny.place')(mocked). The composer's failure/edge cases (locked wallet hides composer, disabled Post button) remain covered by existing tests.## Related.openUrlis the existing OS-browser opener; unit test mocks it.Closes #4924in## Related.Impact
git diff vendor/tinyplaceis empty) — safe for all clones/CI.Related
PostCreate.image+ read-sidePost/GqlPostmedia → openhuman bumps the submodule + wires composer upload/renderer.AI Authored PR Metadata
Linear Issue
Commit & Branch
fix/4924-feed-media-web-onlyValidation Run
pnpm --filter openhuman-app format:check— clean on changed files (prettier --check)pnpm typecheck—tsc --noEmitcleanFeedSection.test.tsx— 56 passed (incl. 2 new); full app suite 520 passedcargo fmt --checkclean ontinyplace/mod.rs(doc-comment-only change)Validation Blocked
command:pnpm rust:check(pre-push hook) / fullcargo checkon the core crateerror:fresh worktree has uninitialized git submodules (vendor/tinyagents,app/src-tauri/vendor/tauri-cef, …);rust:checkcompiles the Tauri shell crate, which needs the large CEF submodule not set up hereimpact:none for this change — it edits only frontend TS (typecheck passed) and a core-crate doc comment (cargo fmt --checkvalidated); the Tauri shell and core executable code are untouched. Pushed with--no-verifyper the repo's "unrelated pre-existing breakage" allowance.Behavior Changes
Summary by CodeRabbit
New Features
Documentation
Tests