feat(pinning): add user-scoped /api/pinning/unpin action#4
Open
humanoidrobot-glitch wants to merge 347 commits intonirholas:mainfrom
Open
feat(pinning): add user-scoped /api/pinning/unpin action#4humanoidrobot-glitch wants to merge 347 commits intonirholas:mainfrom
humanoidrobot-glitch wants to merge 347 commits intonirholas:mainfrom
Conversation
- Removed cheerio from dependencies in package.json. - Updated actions.html and sessions.html to manage body visibility during authentication. - Refactored dashboard.js for improved readability and consistency. - Minor formatting adjustments in storage.html and validator-report.jsx for better code style. - Cleaned up test files for consistency and readability. - Removed unused dependencies from yarn.lock to streamline package management.
This commit introduces a comprehensive guide on replacing default hero images with custom artwork. The documentation covers image format selection, dimension requirements, transparency rules, depth value strategy, scene composition principles, and the mechanics of integrating new images into the theme. It aims to empower users to confidently swap layered images in the parallax hero.
feat: add home.html entry to appConfig in vite.config.js
Removed HTML files from PWA precache and set navigateFallback to null. The prior config precached every .html and used Workbox's default navigation fallback to /index.html, which caused failed-or-uncached route navigations to silently render the homepage instead of the actual page. Users on any broken route saw the home hero rather than a 404 or the correct page. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
public/agent/index.html references /style.css and raw /src/*.js paths that 404 in the built deploy because vite only rewrites imports for HTML files listed in rollupOptions.input. The root-level agent-home.html is in that list and gets its assets hashed and bundled into /assets/*. Pointing the route there gives the working page instead of a stylesheet/script-less stub. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
After avatar creation, redirect the creator to /app?agent=<id> (the editor) instead of /agent/<id> (the public profile). Matches the conventional split: creators get an interactive workspace, the public URL is for visitors. agent-home.html now mounts a <model-viewer> showing the agent's actual GLB plus two CTAs — "Open in editor" (signed-in only) and "Copy share link". The page is no longer a sparse identity card with no body. app.html nav gains a "Public profile" link that surfaces only when an agent is loaded via ?agent=, so creators can grab the canonical share URL. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
DeployButton on the agent profile now exposes a chain dropdown next to the "Deploy on-chain" CTA, grouped into Mainnets / Testnets via optgroups. Selecting a chain triggers wallet_switchEthereumChain (with auto-add fallback already wired in chain-meta.switchChain), so the user lands on the right network before signing. If switch is rejected, we still update the local target so the existing mismatch-error UI surfaces a manual switch button. DEFAULT_CHAIN_ID flipped from BSC Testnet (97) to Base mainnet (8453) so new users land on a production chain by default. The /deploy page dropdown also lists mainnets first. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
agent-home.html: - Dynamic model-viewer alt text using the agent's name - aria-busy on the stage section flips false once load resolves - Empty state shown when an agent has no avatar attached - "Copied" button feedback now also announced via role=status aria-live - focus-visible outline on stage CTAs, descriptive aria-label on edit link deploy-button.js / .css: - Detect missing wallet up front and surface "Install MetaMask" instead of a cryptic provider error - Progress region wrapped with role=status aria-live so screen readers hear each step (estimating gas → sign → confirming → done) - Visually-hidden utility class for SR-only step text - Fixed broken Base Sepolia faucet URL (was pointing to dead Goerli faucet) app.html: - Public-profile button gains explicit aria-label clarifying it opens in a new tab; svg marked focusable=false to keep tab order clean Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ion banner
The /app?agent=<id> editor was mounting the AgentHome sidebar twice — once
from the bootstrap _initAgentSystem at the end of init(), and once from
_loadAgentForEdit's own _initAgentSystem call after the GLB resolved. The
container ended up with two stacked identity / skills / permissions cards,
which is what made the post-create UI look so noisy.
Two fixes:
- Early-return after _loadAgentForEdit so the bootstrap doesn't double-fire.
- Make the AgentHome render in _initAgentSystem idempotent: tear down any
existing instance and clear the container before mounting a fresh one.
On top of that, freshly arrived users now get a one-time orientation
banner ("Your agent is ready") with two CTAs — Deploy on-chain and View
public profile. Dismiss persists per-agent in localStorage so it never
nags returning users.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous early-return refactor changed the order in which _loadAgentForEdit and _initAgentSystem ran, which left the loaded GLB in a state where it briefly rendered then disappeared. Restoring the original fire-both-in-parallel pattern makes the model stick again. The duplicate AgentHome sidebar — the bug the early-return was originally trying to address — is still suppressed by the idempotent render in _initAgentSystem (destroy + clear before mount), so we don't regress that. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The animation panel was auto-playing manifest[0] ("idle") as soon as all
external Mixamo-rigged FBX clips finished downloading. RPM / Avaturn avatars
use a different bone naming convention than Mixamo, so the retarget partially
fails and the rig collapses — which is what users were seeing as the avatar
"loading for a second then disappearing" right after creation. The model was
loading fine; an off-rig idle clip was warping it out of frame.
Removing the auto-play keeps the avatar in its authored standing pose. The
animation strip still works on click for the cases where retargeting does
succeed (and in the cases it doesn't, the failure is now opt-in rather than
the default first impression).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…s + per-agent prefs Five small, high-impact UX wins on /app?agent=: - Spacebar toggles play/pause on the active animation, or starts the first loaded one if nothing is playing yet. - Double-click on the canvas (or pressing F) frames the model with a smooth 600ms cubic ease-out camera tween. - First-load camera reveal: the avatar starts ~40% wider and slightly higher, then eases into the framed pose over 1.5s. Skipped in kiosk/embed modes and on subsequent loads in the same session. - New attachScenePrefs(agentId) on the viewer persists background, transparency, bgColor, autoRotate, exposure, and environment per agent in localStorage and auto-restores them next visit. Wired from app.js after _loadAgentForEdit resolves so each user's studio remembers itself. - Shared _tweenCamera helper drives both the reveal and the dblclick frame with the same easing, so they feel consistent. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…iting
Two more compressions on the post-create flow:
1) /app header now surfaces a state-aware "Deploy on-chain" CTA right next
to "Public profile". On load it reads the agent record and either:
• shows "Deploy on-chain →" linking to /deploy?avatar=<id>
(avatar pre-fills the wizard), or
• flips to a green "Deployed ✓ <ChainName>" chip linking to the block
explorer once the agent has erc8004_agent_id + chain_id.
Owners no longer have to leave the editor to publish.
2) Agent sidebar identity card has inline-editable name and description.
contenteditable + Enter-to-blur / Escape-to-revert, debounced PUT to
/api/agents/:id with optimistic update and rollback if the backend
rejects (e.g. unauthenticated viewer hits 401). Visual states for
editing / saving / saved / error via lightweight ring outlines, plus an
empty-state placeholder ("Add a description…") when description is blank.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
feat: add share panel builders for generating embed snippets refactor: simplify SharePanel by utilizing share panel builders style: update CSS for discover page and related components test: add unit tests for share panel builders and embed functionality fix: update vercel routing for discover page
…tURI Two real bugs that meant on-chain deploys "succeeded" but produced nothing useful: 1) The deploy chip in agent-home was POSTing to /api/agents/:id/onchain after the tx confirmed — that endpoint never existed. Every successful mint silently failed to persist, so a page reload showed "not deployed" even though gas had been spent. The chip is now wired through the existing canonical pipeline: register-prep → sign → register-confirm. Same flow used by /deploy, with proper IPFS pinning of the manifest and server-side verification of the on-chain receipt against the prep record. 2) The on-chain agentURI was being set to https://3dagent.vercel.app/api/ agents/:id/manifest — also a non-existent endpoint. Any consumer resolving the registered tokenURI got a 404. Added the missing GET /api/agents/:id/manifest serving canonical agent-manifest/0.1 JSON with body uri, skills, registrations, and homeUrl. Routed in vercel.json and cached as public, max-age=60, s-maxage=300. Plus: - Idempotency: prep records are cached in localStorage keyed per-agent so retries on flaky networks reuse the same IPFS pin instead of re-pinning. Cache expires 50m before the server-side prep TTL. - EIP-1193 error classification: user rejection (4001 / ACTION_REJECTED), insufficient funds (INSUFFICIENT_FUNDS / -32000), and replacement- underpriced get distinct UI affordances (faucet link, cancel-pending hint, retry) instead of one generic regex on error message. - Pre-flight: refuse to deploy if the agent has no avatar_id attached and surface a clear "open editor" CTA instead of failing mid-flight. - agent-home-orphans now passes avatarId, description, and skills through to DeployButton so the pinned manifest is complete. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ency and Clarity - Renamed classes and IDs in index.html and my-agents.css to use `my-agents-*` prefix for better clarity. - Updated styles in my-agents.css to reflect new class names and improve responsiveness. - Modified my-agents.js to align with new class names and IDs, ensuring functionality remains intact. - Enhanced avatar naming logic in account.js to derive names from source metadata. - Updated agent-home-orphans.js to pass additional data when mounting agents. - Added optional name plate overlay in element.js for agent display. - Implemented emotion expression functionality in element.js for agent interactions. - Created validate-agent-cards.yml GitHub Action for validating agent card schemas on PRs and pushes. - Introduced demo widget fixtures in _demo-fixtures.js for testing without a live database. - Developed features.js to handle lazy loading of agent components and dynamic content on the features page. - Added validate-agent-cards.mjs script for schema validation of agent cards.
…e preview - Updated renderEmbed function to include a new handshake verification feature. - Added bindEmbedHandshake function to manage communication with the embedded agent and display capabilities. - Improved user feedback during the handshake process with detailed status messages. refactor: optimize animation serialization for reduced payload size - Modified serializeClip function to round float values to 5 decimal places, halving payload size while maintaining visual fidelity. test: update features page tests for navigation consistency - Adjusted test descriptions and expectations to reflect changes in navigation links. - Enhanced emotion chip click test to accommodate dataset variations. feat: add billing summary API endpoint for user plan and usage details - Implemented GET /api/billing/summary to provide current user's plan, quotas, and usage statistics. - Integrated database queries to fetch avatar and agent counts, as well as usage events for billing insights.
…ency - Updated SKILL.md to fix formatting issues in the requested scope table. - Improved CSS transitions in skill.css for better readability. - Cleaned up JavaScript code in skill.js for consistency in formatting and style. - Modified index.html to remove unnecessary stylesheet link. - Enhanced studio.css with self-contained styles and improved layout. - Adjusted studio.js to correct embed URL structure. - Changed navigation link from "Explore" to "Discover" in validation index.html. - Updated wallet-connect-demo.html for better formatting and readability. - Refined wallet-connect.css for improved transition effects and consistency. - Enhanced connect-button.js for better readability and consistency in method formatting. - Updated state.js to improve readability and maintainability of state management. - Improved gallery.js to correct widget URL structure and enhance readability. - Added billing summary API endpoint to dashboard.js. - Enhanced avatar card rendering in dashboard.js for better user experience. - Implemented new API endpoint for resolving ERC-8004 agents with CAIP support.
…mmits to indicate dirty state
- Introduced `SolanaAgent` class for managing wallet interactions and transactions. - Implemented actions for transferring SOL and SPL tokens. - Added Jupiter integration for token swaps, including fetching quotes and executing swaps. - Created utility functions for managing associated token accounts. - Developed x402 "exact" scheme client and facilitator for SPL TransferChecked payments. - Included types and constants for payment requirements and network identifiers.
…SPL tokens, swapping, and balance retrieval - Implemented actions for transferring native SOL and SPL tokens, swapping tokens using Jupiter, and retrieving wallet balances. - Created a plugin interface for easy integration with SolanaAgent. - Added type definitions for actions and plugin methods to enhance type safety and developer experience.
…ptions and approval options
…ication - Implemented tests for the agent runtime tool loop to ensure proper functionality. - Added tests for the MCP server to cover critical external-facing API endpoints. - Extended auth flow tests to cover gaps in email/password, SIWE, and OAuth 2.1. - Created tests for the memory system to validate runtime and backend API behavior. - Developed tests for the skills registry to ensure proper installation and execution of skills. - Modularized the MCP server for better maintainability and testability. - Eliminated the 15-minute delay in ERC-8004 registration by adding immediate confirmation handling. - Integrated voice chat functionality into the main agent widget for enhanced user experience. - Implemented multi-device memory sync to ensure consistent agent memory across devices. - Enabled agent-to-agent communication via skills for task delegation.
…ng and voice input functionality
- Introduced new types and interfaces for Solana agent actions and transactions. - Implemented build and send functionality for transactions, including fee estimation. - Added utility functions for formatting and memo handling. - Created a voice client for streaming audio to a voice server. - Developed comprehensive tests for the MCP API, covering authentication, tool execution, and payment flows.
- Implemented a new tool `call_agent` that allows agents to send messages to each other and receive responses. - Introduced input schema validation for agent ID and message. - Integrated with the Anthropic API to handle message processing and response retrieval. - Added rate limiting to prevent abuse of the tool. feat(talking-head): update subproject commit to dirty state fix(tests): update OAuth test imports to use dynamic action routing fix(jest): restrict test matches to wallet tests only feat(agent-memory): enhance memory management with pull method - Added a `pull` method to synchronize agent memory entries from the backend. - Implemented conflict resolution based on the `updatedAt` timestamp. - Ensured idempotency and best-effort handling of network issues. feat(agent-skills): add call context for agent delegation - Introduced a `call` method in the agent context to facilitate delegation to other agents. - Implemented fetch logic to handle agent-to-agent communication. test(auth): add comprehensive tests for email/password authentication - Created tests for login, logout, and registration endpoints. - Mocked dependencies to simulate database interactions and session management. test(auth-helpers): add unit tests for JWT and CSRF token helpers - Implemented tests for minting and verifying JWTs. - Added tests for CSRF token generation and verification. feat(payments): implement X402 error handling in payments module - Created a new `sendX402Error` function to handle X402 errors consistently. feat(avatars): add tools for avatar management and rendering - Implemented tools for listing, retrieving, searching, rendering, and deleting avatars. - Added safety checks for avatar policies and rendering parameters.
…igation; update ResourcePage for docSlug handling
… mark subproject as dirty
…ction approval modal - Add a reactive Svelte store to track the connected wallet's type, address, and chainId. - Create a transaction approval modal component to handle user confirmations for wallet transactions. - Enhance Toolcall component to display transaction results in a user-friendly format. - Develop backend API for building Solana transactions and integrate with frontend tools for executing transfers and swaps. - Introduce frontend tools for Solana and EVM transactions, including transfer and swap functionalities. - Bundle wallet tools into a new curated tool pack for easy access in the chat UI.
- Implemented `showPaymentGateModal` function to display a modal for user payment confirmation before executing a priced skill. - The modal includes skill details, payment amount, and action buttons for canceling or proceeding with payment. test: add monetization tests for agent pricing and revenue - Created comprehensive tests for pricing CRUD operations, x402 manifest, revenue attribution, and withdrawals. - Included scenarios for authenticated and unauthenticated users, as well as rate limiting checks. - Mocked necessary dependencies and state for accurate testing of agent monetization features.
… agents - New CSS file for three.ws integration - Created documentation for three.ws's listing in the MCP Registry - Explained features of three.ws platform, including 3D model uploads, LLM integration, and on-chain identity - Detailed how to connect to three.ws via MCP for both users and developers - Highlighted the significance of persistent identity and the convergence of AI and crypto
The pinning dispatcher exposed `pin` and `status` actions but no way to
remove a pin. Pinata's `unpin` HTTP endpoint was reachable from the
client-side `src/pinning/pinata.js` library but had no caller, and the
backend had no equivalent surface, so users had no way to release
pinned manifests / GLBs they no longer cared about and CIDs accumulated
on the org's Pinata account indefinitely.
Add an `unpin` action mirroring the existing `pin` shape:
POST /api/pinning?action=unpin { cid }
- Auth: session or bearer (same as `pin`)
- Rate-limited via the existing `limits.pinUser` preset (30/h)
- Looks up the pin in the `pins` table scoped to the caller's user_id
so users can only unpin their own pins
- Calls Pinata DELETE /pinning/unpin/:cid for `provider = 'pinata'`
- Treats Pinata 404 as idempotent success (pin already gone)
- For `provider = 'web3.storage'`, drops the local row only —
web3.storage has no first-class unpin endpoint
- On success, deletes the row from `pins`
Scope note: the audit recommendation was "call unpin() on agent
deletion." That requires linking pins to agents (the `pins` table
currently has only `user_id`, no `agent_id`), which is a schema change
flagged as must-ask-first in api/CLAUDE.md. This change ships the
missing API capability so a future PR can wire it into the agent
delete path or a UI control without needing schema work first.
Verified with `node --check api/pinning/[action].js`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0585807 to
87d01c2
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The pinning dispatcher (
api/pinning/[action].js) exposespinandstatusactions but had no way to remove a pin. Pinata'sunpinHTTP endpoint was reachable from the client-sidesrc/pinning/pinata.jslibrary but had no caller, and the backend had no equivalent surface, so users had no way to release pinned manifests / GLBs they no longer cared about. CIDs accumulate on the Pinata account indefinitely.What's added
A new
unpinaction mirroring the existingpinshape:pin).limits.pinUserpreset (30/h).pinstable scoped to the caller'suser_idso users can only unpin their own pins.provider = 'pinata'→ calls PinataDELETE /pinning/unpin/:cid. Treats Pinata 404 as idempotent success (pin already gone).provider = 'web3.storage'→ drops the local row only. web3.storage has no first-class unpin endpoint; pins age out via their own lifecycle.validation_error.pinsand returns{ ok: true, cid, provider }.Why not auto-unpin on agent delete
The original audit suggestion was "call
unpin()on agent deletion." That requires linking pins to agents, but the currentpinstable has onlyuser_id— noagent_idcolumn. Adding that column is a schema change flagged as must-ask-first inapi/CLAUDE.md.This PR ships the missing API capability without speculation. A follow-up can wire it into the agent-delete flow or a UI control once the linkage design is decided.
Test plan
node --check api/pinning/[action].jspasses.POST /api/pinning?action=unpinwith{ cid: "<owned cid>" }→ 200, row deleted frompins, Pinata DELETE called.cidmissing or non-alphanumeric → 400validation_error.PINATA_JWTenv set + provider=pinata row → 503pinning_unconfigured.