Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

builtwithcodex

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

builtwithcodex - npm Package Compare versions

Comparing version
0.1.1
to
0.1.3
+1
-1
bin/launchboard-publish.js

@@ -10,3 +10,3 @@ #!/usr/bin/env node

if (!existsSync(script)) {
console.error("Missing bundled Launchboard publish script.");
console.error("Missing bundled Built with Codex publish script.");
process.exit(1);

@@ -13,0 +13,0 @@ }

{
"name": "builtwithcodex",
"version": "0.1.1",
"description": "Publish repos, SaaS products, Codex skills, agents, games, and devtools to Launchboard from Codex or the terminal.",
"version": "0.1.3",
"description": "Publish Codex skills to Built with Codex from Codex or the terminal.",
"bin": {

@@ -19,5 +19,4 @@ "builtwithcodex": "bin/launchboard-publish.js",

"marketplace",
"product-hunt",
"launchboard",
"developer-tools"
"codex-skill"
],

@@ -24,0 +23,0 @@ "author": "Francesco Mistero",

+19
-14
# builtwithcodex
Publish a repo, SaaS URL, Codex skill, agent, game, experiment, or devtool to Launchboard from Codex or the terminal.
Publish a Codex skill to Built with Codex from Codex or the terminal.
## Usage
Publish the current repo:
Publish the current skill repo:

@@ -13,18 +13,18 @@ ```bash

Publish a live SaaS/app URL:
Attach docs/demo URL:
```bash
npx builtwithcodex \
--url "https://your-app.com" \
--repo-url "https://github.com/you/your-app"
--url "https://github.com/you/your-skill#readme" \
--repo-url "https://github.com/you/your-skill"
```
Publish from a GitHub repo URL:
Publish from a GitHub skill repo URL:
```bash
npx builtwithcodex \
--repo-url "https://github.com/you/your-project"
--repo-url "https://github.com/you/your-skill"
```
Use a custom Launchboard instance:
Use a custom Built with Codex instance:

@@ -42,6 +42,5 @@ ```bash

--path "$PWD" \
--category Apps \
--demo-url "https://your-app.com" \
--screenshot-url "https://your-app.com/og.png" \
--codex-skill-url "https://your-app.com/skills/my-skill.zip"
--demo-url "https://github.com/you/your-skill#readme" \
--screenshot-url "https://raw.githubusercontent.com/you/your-skill/main/screenshot.png" \
--codex-skill-url "https://github.com/you/your-skill"
```

@@ -60,7 +59,13 @@

```text
Use the builtwithcodex npm package to publish this project to Launchboard.
Use the builtwithcodex npm package to publish this Codex skill.
```
The package opens a prefilled Launchboard submit page. The user still signs in with GitHub and confirms publish, so ownership, limits, and payments stay enforced by Launchboard.
The package opens a prefilled Built with Codex submit page. The user still signs in with GitHub and confirms publish, so ownership, limits, and payments stay enforced by the marketplace.
By default, the package opens:
```text
https://codex-marketplace.vercel.app
```
## Bundled Codex Skill

@@ -67,0 +72,0 @@

@@ -14,7 +14,8 @@ #!/usr/bin/env python3

from urllib.request import Request, urlopen
from urllib.parse import urlencode
from urllib.parse import urlencode, urljoin
CATEGORIES = {"Apps", "Skills", "DevTools", "Games", "Agents", "Experiments"}
CATEGORIES = {"Skills"}
IMAGE_EXTENSIONS = {".png", ".jpg", ".jpeg", ".webp", ".gif"}
DEFAULT_MARKETPLACE_URL = "https://codex-marketplace.vercel.app"

@@ -78,2 +79,13 @@

def github_owner(url: str) -> str:
normalized = normalize_github_url(url)
match = re.match(r"https://github\.com/([^/]+)/", normalized)
return match.group(1) if match else ""
def github_avatar_url(repo_url: str) -> str:
owner = github_owner(repo_url)
return f"https://github.com/{owner}.png" if owner else ""
def clone_repo(repo_url: str) -> Path:

@@ -164,21 +176,12 @@ normalized = normalize_github_url(repo_url)

}
def infer_category(path: Path, package: dict, readme: str) -> str:
focused_readme = "\n".join(readme.splitlines()[:20])
text = " ".join([str(package.get("name", "")), str(package.get("description", "")), focused_readme]).lower()
if "marketplace" in text or "saas" in text or "web app" in text:
return "Apps"
if "skill.md" in text or (path / "SKILL.md").exists():
return "Skills"
if "phaser" in text or "game" in text:
return "Games"
if "cli" in text or "devtool" in text or "developer" in text:
return "DevTools"
if "agent" in text:
return "Agents"
if "experiment" in text or "prototype" in text:
return "Experiments"
return "Apps"
def infer_category(path: Path, package: dict, readme: str, repo_url: str = "") -> str:
return "Skills"
def install_command(package: dict, path: Path) -> str:
readme = read(path / "README.md")
readme_command = infer_install_command_from_readme(readme)
if readme_command:
return readme_command
if package:

@@ -205,4 +208,38 @@ manager = "npm"

def infer_install_command_from_readme(readme: str) -> str:
if not readme:
return ""
commands = re.findall(r"```(?:bash|sh|shell|zsh)?\n(.*?)```", readme, re.DOTALL | re.IGNORECASE)
flattened = []
for block in commands:
for line in block.splitlines():
value = line.strip()
if value and not value.startswith("#"):
flattened.append(value)
preferred_patterns = (
r"^npx\s+.*",
r"^npm\s+(?:i|install)\s+-g\s+.*",
r"^npm\s+(?:i|install)\s+.*@",
r"^pnpm\s+dlx\s+.*",
r"^bunx\s+.*",
r"^uvx\s+.*",
r"^pipx\s+install\s+.*",
)
for pattern in preferred_patterns:
for command in flattened:
if re.match(pattern, command):
return command
for command in flattened:
if "install" in command.lower() and not command.startswith(("mkdir ", "cp ", "ls ")):
return command
return ""
def infer_tags(path: Path, package: dict, category: str) -> list[str]:
tags = ["codex", category.lower()]
tags = ["codex", "skill"]
dependencies = {}

@@ -255,2 +292,4 @@ for key in ("dependencies", "devDependencies"):

value = match.group(0)
if "github.com" in value.lower():
return ""
return "" if is_badge_url(value) else value

@@ -301,11 +340,13 @@

or first_paragraph(skill_md)
or f"{name} is ready to launch."
or f"{name} is a Codex skill ready to launch."
)
description = clean(description, 1200)
tagline = clean(description.split(".")[0], 140)
category = category_override if category_override in CATEGORIES else infer_category(path, package, readme)
repo_url = git_remote(path)
category = "Skills"
inferred_demo_url = demo_url or infer_demo_url(package, readme)
inferred_screenshot_url = screenshot_url or infer_screenshot_url(path, readme)
inferred_skill_url = codex_skill_url or (repo_url if category == "Skills" and repo_url else "")
inferred_skill_url = codex_skill_url or repo_url
if inferred_demo_url.startswith("https://github.com/"):
inferred_demo_url = ""

@@ -315,4 +356,4 @@ return {

"tagline": tagline if len(tagline) >= 8 else f"{name} is ready to launch",
"description": description if len(description) >= 20 else f"{name} is a project published on Launchboard.",
"category": category if category in CATEGORIES else "Apps",
"description": description if len(description) >= 20 else f"{name} is a Codex skill published on Built with Codex.",
"category": "Skills",
"tags": infer_tags(path, package, category),

@@ -344,4 +385,6 @@ "repoUrl": repo_url,

prefill["repoUrl"] = normalize_github_url(repo_url)
if prefill["category"] == "Skills" and not prefill.get("codexSkillUrl"):
if not prefill.get("codexSkillUrl"):
prefill["codexSkillUrl"] = normalize_github_url(repo_url)
if not prefill.get("screenshotUrl"):
prefill["screenshotUrl"] = github_avatar_url(repo_url)
return prefill

@@ -365,10 +408,10 @@ finally:

image = parser.meta.get("og:image") or parser.meta.get("twitter:image") or ""
category = category_override if category_override in CATEGORIES else "Apps"
if image:
image = urljoin(url, image)
return {
"name": title,
"tagline": clean(description.split(".")[0], 140),
"description": description if len(description) >= 20 else f"{title} is a SaaS product published on Launchboard.",
"category": category,
"tags": ["codex", category.lower(), "saas"],
"description": description if len(description) >= 20 else f"{title} is a Codex skill published on Built with Codex.",
"category": "Skills",
"tags": ["codex", "skill"],
"repoUrl": repo_url,

@@ -383,3 +426,3 @@ "demoUrl": url,

def print_preview(prefill: dict, url: str) -> None:
print("Launchboard prefill")
print("Built with Codex skill prefill")
print(f"Name: {prefill.get('name', '')}")

@@ -401,5 +444,6 @@ print(f"Tagline: {prefill.get('tagline', '')}")

parser.add_argument("--path", default=os.getcwd())
parser.add_argument("--url", default="", help="Live SaaS/app URL to launch instead of a local path")
parser.add_argument("--repo-url", default="", help="GitHub repo URL to inspect, or to attach when launching a live URL")
parser.add_argument("--marketplace-url", default="http://localhost:3007")
parser.add_argument("--url", default="", help="Docs or demo URL to attach instead of inspecting a local path")
parser.add_argument("--repo-url", default="", help="GitHub skill repo URL to inspect, or to attach when using --url")
parser.add_argument("--repo", default="", help=argparse.SUPPRESS)
parser.add_argument("--marketplace-url", default=DEFAULT_MARKETPLACE_URL)
parser.add_argument("--demo-url", default="")

@@ -411,3 +455,6 @@ parser.add_argument("--screenshot-url", default="")

parser.add_argument("--no-open", action="store_true")
parser.add_argument("--open", action="store_true", help=argparse.SUPPRESS)
parser.add_argument("--prefill-url", action="store_true", help=argparse.SUPPRESS)
args = parser.parse_args()
repo_url = args.repo_url or args.repo

@@ -417,9 +464,9 @@ if args.url:

args.url,
repo_url=args.repo_url,
repo_url=repo_url,
category_override=args.category,
codex_skill_url=args.codex_skill_url,
)
elif args.repo_url:
elif repo_url:
prefill = build_prefill_from_repo_url(
args.repo_url,
repo_url,
demo_url=args.demo_url,

@@ -426,0 +473,0 @@ screenshot_url=args.screenshot_url,

---
name: builtwithcodex
description: Inspect the current project and open a prefilled Launchboard marketplace submission page.
description: Inspect the current Codex skill repo and open a prefilled Built with Codex marketplace submission page.
---

@@ -8,3 +8,3 @@

Use this skill when the user wants to publish the current repo, app, Codex skill, agent, game, experiment, or devtool to the marketplace.
Use this skill when the user wants to publish a Codex skill from the current repo, a GitHub repo URL, or an attached docs/demo URL to the marketplace.

@@ -23,11 +23,11 @@ ## Workflow

- tagline
- category
- category, always `Skills`
- tags
- description
- GitHub repo URL
- demo URL
- Codex skill download/install URL when the project itself is a skill
- docs/demo URL
- Codex skill source or install URL
- screenshot URL if present in README or common asset folders
- install command
3. Open the marketplace submit page with a `prefill` query parameter.
3. Open the Built with Codex submit page with a `prefill` query parameter.
4. The user must sign in with GitHub before publishing. Do not bypass marketplace authentication or limits.

@@ -38,3 +38,3 @@

```bash
python3 scripts/submit_project.py --path "$PWD" --marketplace-url "http://localhost:3007"
python3 scripts/submit_project.py --path "$PWD"
```

@@ -47,15 +47,13 @@

--path "$PWD" \
--marketplace-url "http://localhost:3007" \
--demo-url "https://your-app.vercel.app" \
--screenshot-url "https://your-app.vercel.app/og.png" \
--codex-skill-url "https://your-domain.com/skills/my-skill.zip" \
--category Apps
--demo-url "https://your-docs-or-demo.com" \
--screenshot-url "https://your-docs-or-demo.com/og.png" \
--codex-skill-url "https://github.com/you/your-skill"
```
Launch a live SaaS URL:
Attach a docs/demo URL:
```bash
python3 scripts/submit_project.py \
--url "https://your-app.vercel.app" \
--repo-url "https://github.com/you/your-app"
--url "https://your-docs-or-demo.com" \
--repo-url "https://github.com/you/your-skill"
```

@@ -67,3 +65,3 @@

python3 scripts/submit_project.py \
--repo-url "https://github.com/you/your-project"
--repo-url "https://github.com/you/your-skill"
```

@@ -80,3 +78,3 @@

```bash
python3 scripts/submit_project.py --path "$PWD" --marketplace-url "https://YOUR_DOMAIN"
python3 scripts/submit_project.py --path "$PWD"
```