diff --git a/cloudflare-worker/bsky-feedgen.js b/cloudflare-worker/bsky-feedgen.js
index 1e8b7a0..c492651 100644
--- a/cloudflare-worker/bsky-feedgen.js
+++ b/cloudflare-worker/bsky-feedgen.js
@@ -48,7 +48,7 @@ function fromPost(response) {
   return docs;
 }
 
-function fromUser(queryIdx, response, params) {
+function fromUser(query, queryIdx, response, params) {
   let docs = [];
   let feed = response.feed;
   if (Array.isArray(feed)) {
@@ -57,12 +57,10 @@ function fromUser(queryIdx, response, params) {
     for (let itemIdx = 0; itemIdx < feed.length; itemIdx++) {
       let feedItem = feed[itemIdx];
       if (feedItem.post !== undefined && feedItem.post.record !== undefined) {
-        // TODO allow replies
-        if (feedItem.reply !== undefined) {
+        if (feedItem.reply !== undefined && query.includeReplies !== true) {
           continue;
         }
-        // TODO allow reposts
-        if (feedItem.reason !== undefined) {
+        if (feedItem.reason !== undefined && query.includeReposts !== true) {
           continue;
         }
         filteredFeed.push(feedItem);
@@ -74,10 +72,21 @@ function fromUser(queryIdx, response, params) {
     let nextCursor = response.cursor;
     for (let itemIdx = 0; itemIdx < feed.length; itemIdx++) {
       let feedItem = feed[itemIdx];
+      let postReason = null;
       if (feedItem.post !== undefined && feedItem.post.record !== undefined) {
-        let timestampStr = feedItem.post.record.createdAt;
-        let timestamp = new Date(timestampStr).valueOf() * 1000000;
         let atURL = feedItem.post.uri;
+        let timestamp = null;
+        if (feedItem.reason !== undefined) {
+          let timestampStr = feedItem.reason.indexedAt;
+          timestamp = new Date(timestampStr).valueOf() * 1000000;
+          postReason = {
+            $type: "app.bsky.feed.defs#skeletonReasonRepost",
+            // TODO: add repost URI field
+          };
+        } else {
+          let timestampStr = feedItem.post.record.createdAt;
+          timestamp = new Date(timestampStr).valueOf() * 1000000;
+        }
 
         docs.push({
           type: "user",
@@ -88,6 +97,7 @@ function fromUser(queryIdx, response, params) {
           total: feed.length,
           cursor: cursor,
           nextCursor: nextCursor,
+          postReason: postReason,
         });
       }
     }
@@ -285,7 +295,7 @@ export async function getFeedSkeleton(request, env) {
       let cursor = objSafeGet(queryCursor, "cursor", null);
       let response = await fetchUser(session, query.value, cursor);
       if (response !== null) {
-        items.push(...fromUser(queryIdx, response, { cursor: cursor }));
+        items.push(...fromUser(query, queryIdx, response, { cursor: cursor }));
       }
     } else if (query.type === "post") {
       if (showPins) {
@@ -307,7 +317,12 @@ export async function getFeedSkeleton(request, env) {
 
   let feed = [];
   for (let item of items) {
-    feed.push({ post: item.atURL });
+    let postReason = item.postReason;
+    let feedItem = { post: item.atURL };
+    if (postReason !== null) {
+      // TODO add feedItem["reason"]
+    }
+    feed.push(feedItem);
   }
 
   let cursor = saveCursor(items, numQueries);
@@ -361,11 +376,25 @@ function buildQueries(allTerms, cursorParam = null) {
           value: term,
         });
       } else {
-        let userDid = term.replace("at://", "");
+        let userDid = null;
+        let includeReplies = false;
+        let includeReposts = false;
+        let words = term.split(" ");
+        for (let word of words) {
+          if (word.indexOf("at://") > -1) {
+            userDid = word.replace("at://", "");
+          } else if (word === "+replies") {
+            includeReplies = true;
+          } else if (word === "+reposts") {
+            includeReposts = true;
+          }
+        }
         queries.push({
           type: "user",
           value: userDid,
           cursor: cursor,
+          includeReplies: includeReplies,
+          includeReposts: includeReposts,
         });
       }
     } else {
diff --git a/render-configs.py b/render-configs.py
index 95f7917..7858f0e 100755
--- a/render-configs.py
+++ b/render-configs.py
@@ -9,7 +9,7 @@
 
 LIST_ITEM_REGEX = re.compile(r"^- ")
 POST_REGEX = re.compile(r"^.*[\./]bsky\.app/profile/(.+?)/post/([a-z0-9]+)")
-PROFILE_REGEX = re.compile(r"^.*[\./]bsky\.app/profile/([^/]+)")
+PROFILE_REGEX = re.compile(r"^.*[\./]bsky\.app/profile/([^/ ]+)( .+)?$")
 
 
 def resolve_handles(handles):
@@ -30,16 +30,36 @@ def render_search_terms(search_terms):
     # strip out list item markers
     terms = [re.compile(LIST_ITEM_REGEX).sub("", term) for term in search_terms]
 
+    all_handles = {}
+
     # collect handles and pins
     for term in terms:
         post_matches = POST_REGEX.match(term)
         profile_matches = PROFILE_REGEX.match(term)
         if post_matches:
-            handle = post_matches.group(1)
+            handle = post_matches.group(1).lower()
             handles.add(handle)
         if profile_matches:
-            handle = profile_matches.group(1)
+            handle = profile_matches.group(1).lower()
             handles.add(handle)
+            if handle not in all_handles:
+                all_handles[handle] = {
+                    "handle": handle,
+                    "replies": False,
+                    "reposts": False,
+                }
+            flags = profile_matches.group(2)
+            if flags is not None:
+                words = flags.split(" ")
+                for word in words:
+                    word = word.strip().lower()
+                    if word:
+                        if word == "+replies":
+                            all_handles[handle]["replies"] = True
+                        elif word == "+reposts":
+                            all_handles[handle]["reposts"] = True
+                        else:
+                            print(f"WARN: Unknown flag {word}", file=sys.stderr)
 
     # resolve handles
     dids = resolve_handles(handles)
@@ -62,7 +82,14 @@ def render_search_terms(search_terms):
             did = dids[handle]
             if did:
                 at_url = f"at://{did}"
-                rendered_terms.append(at_url)
+                words = [at_url]
+                flags = all_handles[handle]
+                if flags["replies"]:
+                    words.append("+replies")
+                if flags["reposts"]:
+                    words.append("+reposts")
+                flat = " ".join(words)
+                rendered_terms.append(flat)
             else:
                 print(f"WARN: Failed to resolve handle {handle}", file=sys.stderr)
         else: