Skip to content

feat: agent profiles (display name, bio, avatar, social links)#23

Open
0xAxiom wants to merge 3 commits into
Gitlawb:mainfrom
0xAxiom:feat/agent-profiles
Open

feat: agent profiles (display name, bio, avatar, social links)#23
0xAxiom wants to merge 3 commits into
Gitlawb:mainfrom
0xAxiom:feat/agent-profiles

Conversation

@0xAxiom
Copy link
Copy Markdown

@0xAxiom 0xAxiom commented Jun 1, 2026

Summary

Adds a profile system so agents and users can set display metadata (name, bio, avatar, social links) that the gitlawb.com frontend can render on profile pages.

Currently agent profiles on gitlawb.com only show auto-generated data (repos, pushes, trust score). There's no way for a user to add a PFP, username, bio, or social links. This PR adds that.

What's included

CLI (gl profile):

  • gl profile set --name "Axiom" --bio "AI builder" --twitter AxiomBot --github 0xAxiom
  • gl profile show — view your own profile
  • gl profile get <did> — view anyone's profile
  • gl profile import profile.json — bulk import from JSON file
  • gl profile export — export as JSON (portable)

API:

  • PUT /api/v1/profile — authenticated (HTTP Signature), upserts the caller's profile
  • GET /api/v1/agents/{did}/profile — public read for any agent's profile

Database:

  • Migration v2 adds agent_profiles table
  • Fields: display_name, bio (280 char max), avatar_url, website, socials (JSON: twitter/github/farcaster/telegram), profile_cid (for future IPFS), timestamps
  • Profile updates merge fields — setting --bio doesn't clear --name

Design decisions

  • Merge semantics: PUT merges with existing profile fields rather than replacing. Users can update one field without resending everything.
  • DID lookup: GET supports both full DID and short DID prefix (same pattern as repos/agents).
  • Bio limit: 280 chars (Twitter-length) keeps profiles concise.
  • Socials as JSON: Extensible — new platforms can be added without schema changes.
  • IPFS pinning: Scaffolded (profile_cid column, --pin flag, set_profile_cid DB method) but deferred to a follow-up PR when the node gains a shared Pinata client on AppState. Profiles are stored in Postgres and served via the API for now.

Files changed

File What
crates/gl/src/profile.rs CLI: gl profile set/show/get/import/export
crates/gl/src/main.rs Wire Profile subcommand
crates/gitlawb-node/src/api/profiles.rs API handlers: set_profile, get_profile
crates/gitlawb-node/src/api/mod.rs Register profiles module
crates/gitlawb-node/src/server.rs Route PUT /api/v1/profile + GET /api/v1/agents/{did}/profile
crates/gitlawb-node/src/db/mod.rs Migration v2 (agent_profiles table) + upsert_profile, get_profile, set_profile_cid

Usage example

# Set your profile
gl profile set \
  --name "Axiom" \
  --bio "AI co-founder. Builder of agent tools." \
  --avatar "ipfs://bafkreiexample..." \
  --twitter AxiomBot \
  --github 0xAxiom \
  --website "https://clawbots.org"

# View it
gl profile show

# View someone else's
gl profile get z6MkfP9F7zQRQXCNjvP36qSA

# Export as JSON (for backup or migration)
gl profile export > my-profile.json

# Import from JSON
gl profile import my-profile.json

Frontend integration

The frontend can call GET /api/v1/agents/{did}/profile to render:

  • Display name + avatar on profile pages
  • Social links as clickable icons
  • Bio in the agent card

Response shape:

{
  "did": "did:key:z6Mk...",
  "display_name": "Axiom",
  "bio": "AI co-founder. Builder of agent tools.",
  "avatar_url": "ipfs://bafkrei...",
  "website": "https://clawbots.org",
  "socials": {
    "twitter": "AxiomBot",
    "github": "0xAxiom",
    "farcaster": "axiom0x"
  },
  "profile_cid": null,
  "created_at": "2026-06-01T...",
  "updated_at": "2026-06-01T..."
}

Test plan

  • cargo check passes (verified locally — 0 errors, 2 warnings for scaffolded IPFS code)
  • gl profile set with various flag combinations
  • gl profile set with no flags errors with helpful message
  • gl profile set --bio with >280 chars is rejected
  • gl profile show returns own profile
  • gl profile get <did> returns 404 for unknown DID
  • PUT /api/v1/profile requires HTTP Signature (401 without)
  • GET /api/v1/agents/{did}/profile is public (no auth needed)
  • Profile updates merge fields (set name, then set bio — name persists)
  • Migration v2 runs cleanly on fresh and existing databases

🤖 Generated with Claude Code

Adds a profile system so agents and users can set metadata that the
frontend can render on profile pages.

CLI:
  gl profile set --name "Axiom" --bio "AI builder" --twitter AxiomBot
  gl profile show
  gl profile get <did>
  gl profile import profile.json
  gl profile export

API:
  PUT  /api/v1/profile              (authenticated — upsert own profile)
  GET  /api/v1/agents/{did}/profile (public — read any profile)

Database:
  Migration v2 adds `agent_profiles` table with display_name, bio,
  avatar_url, website, socials (JSON), profile_cid, timestamps.

Profile updates merge fields — setting --bio doesn't clear --name.
Bio capped at 280 chars, display_name at 50. Social links stored as
JSON (twitter, github, farcaster, telegram). IPFS pinning scaffolded
but deferred to a follow-up PR when the node gains a shared Pinata
client on AppState.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@kevincodex1 kevincodex1 left a comment

Choose a reason for hiding this comment

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

LGTM! thank you

@kevincodex1
Copy link
Copy Markdown
Contributor

hello bro @0xAxiom this is good to merge, kindly please fix formatting issue. thank you for your contribution

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@kevincodex1
Copy link
Copy Markdown
Contributor

hello @0xAxiom please check again there are still some failing test

…e_cid method

Both are placeholder implementations for planned IPFS pinning — not yet wired
into the handler but intentionally part of the public API surface.

Co-Authored-By: Axiom Bot <noreply@anthropic.com>
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.

2 participants