diff --git a/CHANGELOG.md b/CHANGELOG.md index dae2831..d487db6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,15 @@ and this project follows semantic versioning for tagged releases. ### Added +- Repo-local GitHub pipeline skill set for lead generation, lead + qualification, closing drafts, and monitoring, with Airtable handoffs and + approval-gated external actions enforced by tests. +- Repo-local `github-lead-gen` skill for GitHub candidate discovery, with + Airtable-only intake boundaries and search-lane references. +- Airtable-first GitHub lead workflow instructions for the outreach agent, + including repository-first qualification, ICP/truthfulness gates, + approval-gated external actions, pipeline views, and a regression test that + keeps `agent.md` aligned with the workflow. - Additional install channels: a `curl | sh` installer (`install.sh`, fetches the latest release into `~/.local/bin`), a Nix flake (`nix run github:Ducksss/codex-profiles`), and an AUR `PKGBUILD` under diff --git a/LAUNCH.md b/LAUNCH.md index ee23532..d3fbb2f 100644 --- a/LAUNCH.md +++ b/LAUNCH.md @@ -12,6 +12,12 @@ public feedback loops. Prefer issue-first unless the target is Codex-specific, explicitly requests Codex CLI/Desktop workflow tooling, or has a structured registry/package format. +- Lead qualification gate: treat `codex-profiles` as an open-source developer + CLI/Codex workflow tool, not a startup. Startup maps, founder directories, + accelerator databases, investor networks, regional startup ecosystems, and + generic launch boards stay out of active outreach unless they have a concrete + developer-tool category that fits without unsupported company, geography, or + funding claims. - Before any PR or issue-to-PR conversion, follow the template-compliance gate below and record the inspected paths/checks in this ledger. - Treat every "last ledger status" row as stale until reverified with GitHub @@ -203,6 +209,11 @@ Update rule: ### Current Policy Gates +- Airtable is the source of truth. `LAUNCH.md` is a compact handoff after the + Airtable `Targets` and append-only `Log` records are current. +- Before any outreach, record an ICP decision. Keep `Backlog` only for clear + `ICP: yes` targets, use `Deferred` for temporary blockers or strong + `ICP: maybe` targets, and use `Dead` for permanent non-ICP mismatches. - Broad awesome-list PRs remain paused after Taskade declined PR #22 on 2026-06-02 and cited the pattern of near-identical `Add codex-profiles` PRs. - Direct PRs are allowed only when the target is Codex-specific, explicitly @@ -222,18 +233,47 @@ Update rule: | Priority | Target | Last ledger status | Link | Next action | | - | - | - | - | - | -| P0 | Awesome Codex CLI | Replacement PR open on 2026-06-02 | | Monitor; respond only to maintainer feedback. | -| P0 | CLIhub | PR open on 2026-06-02 | | Monitor registry review; preserve schema/tests if changes are requested. | -| P0 | Awesome Agentic Coding CLI | PR open on 2026-06-02 | | Monitor; do not use this as a template for broad list PRs. | -| P0 | Awesome CLI Apps in a CSV | PR open on 2026-06-02 | | Monitor structured CSV submission. | +| P0 | Awesome Codex CLI | PR open and clean on 2026-07-06 after 2026-07-01 bump | | Monitor; respond only to maintainer feedback. | +| P0 | CLIhub | PR open and clean on 2026-07-06 | | Monitor registry review; no bump without maintainer activity. | +| P0 | Awesome Agentic Coding CLI | PR open and clean on 2026-07-06 after 2026-07-01 bump | | Monitor; do not use this as a template for broad list PRs. | +| P0 | Awesome CLI Apps in a CSV | PR open and clean on 2026-07-06 after conflict fix | | Monitor structured CSV submission. | | P0 | OpenAI Developer Community | Existing Codex / Codex CLI topic reverified by forum search on 2026-06-11 | | Monitor replies; do not repost duplicate topic. | | P1 | Hacker News Show HN | Submit attempt and same-day retry reached HN temporary Show HN restriction page on 2026-06-11 | | Retry only after account/community readiness; do not bypass restriction. | | P1 | Product Hunt | Launch draft fully prepared on 2026-06-23; scheduling the Jun 24 launch returned a Product Hunt 403 after confirmation | | Finish scheduling manually in the open browser tab or retry once Product Hunt clears the 403; avoid duplicate listing. | -| P1 | Unikorn.vn | Product submitted on 2026-06-24; Unikorn shows `codex-profiles` pending AI/manual review after accepting logo, screenshots, category, tags, tech stack, and GitHub link | | Monitor approval notification or profile page; publish the public link after approval. | +| P1 | Unikorn.vn | Listed on 2026-07-02; URL redirected to site maintenance on 2026-07-06 | | Recheck after maintenance clears; do not resubmit blindly. | | P1 | OpenAgent.bot | No exact-name listing found in sitemap on 2026-06-22 after 2026-06-02 submission | | Wait for editorial review or contact response; do not resubmit blindly. | | P1 | CLIHunt | No exact-name listing found on homepage on 2026-06-22 after 2026-06-02 submission | | Wait or contact before duplicate submission. | | P2 | ToolHunter | Draft deferred on 2026-06-02 | | Resume only with an approved project contact email. | +### 2026-07-08 Issue-First Outreach Wave + +These scope-check issues were opened from approved Airtable drafts on +2026-07-08. Airtable remains the source of truth; monitor only, and do not open +PRs unless maintainers explicitly confirm fit. + +| Target | Status | Link | Next action | +| - | - | - | - | +| Eva-Dengyh/awesome-cli | Issue open | | Monitor for maintainer scope response. | +| asdfgh12345123/awesome-ai-tools | Issue open | | Monitor for maintainer scope response. | +| linsa-io/command-line-tools | Issue open | | Monitor for maintainer scope response. | +| sudharsan-007/Awesome-DevTerminal | Issue open | | Monitor for maintainer scope response. | +| thegdsks/awesome-modern-cli | Issue open | | Monitor for maintainer scope response. | +| AlexKuchkov/awesome-ai-tools | Issue open | | Monitor for maintainer scope response. | +| dr-mushtaq/Awesome-AI-Tools-Resources | Issue open | | Monitor for maintainer scope response. | +| sepsoh/awesome-bash-scripts | Issue open | | Monitor for maintainer scope response. | +| aliammari1/awesome-ai-tools | Issue open | | Monitor for maintainer scope response. | +| ad-si/awesome-command-line-tools | Issue open | | Monitor for maintainer scope response. | +| starryrbs/awesome-ai-tools | Issue open | | Monitor for maintainer scope response. | +| awesome-lists/awesome-bash | Issue open | | Monitor for maintainer scope response. | +| Museon-AI/awesome-skills | Issue open | | Monitor for maintainer scope response. | +| xiaohou2503687-design/awesome-indie-dev-tools | Issue open | | Monitor for maintainer scope response. | +| spaceCabbage/Awesome-Cli | Issue open | | Monitor for maintainer scope response. | +| michielhdoteth/awesome-ai-agent-tools | Issue open | | Monitor for maintainer scope response. | +| Correia-jpv/fucking-awesome-cli-apps | Issue open | | Monitor for maintainer scope response. | +| agarrharr/awesome-cli-apps | Declined on 2026-07-08 as out of scope | | No action. | +| wlemuel/awesome-ai-client | Issue open | | Monitor for maintainer scope response. | +| pegaltier/awesome-utils-dev | Issue open | | Monitor for maintainer scope response. | + ### Broad Open PR Backlog These PRs are historical submissions from before the broad-list pause. Reverify @@ -335,6 +375,8 @@ No current action unless a listed link breaks or a maintainer requests changes. , and . The related yeaight7 issue #8 and adriannoes issue #3 are closed as completed. +- Verified accepted/listed on 2026-07-06: + . - Closed or declined items, skipped targets, rejected fits, and detailed validation logs are archived in [`archive/launch-ledger-history.md`](archive/launch-ledger-history.md). @@ -366,6 +408,24 @@ Current backlog posture: Keep this list compact. Full dated notes are archived. +- 2026-07-06, lead-qualification cleanup: Airtable moved 95 startup, venture, + accelerator, regional ecosystem, funding/media, and generic startup/listing + surfaces to `Dead` with `ICP: no` notes, `Last Checked = 2026-07-06`, and 95 + matching `lead-qualification` log records. P0/P1 `Backlog` is now 0. The + remaining P0/P1 `Deferred` rows are not active outreach; they require a + confirmed developer-tool category, useful technical content, owner login, a + free path, or maintainer/admin approval before any action. Open monitoring + remains 45 PRs and 71 issues in Airtable. New PRs, issues, listings, + comments, emails, social posts, payments, and account creations: 0. +- 2026-07-06, Airtable-ledger reconciliation: updated 19 target rows and + appended 19 log records in Airtable. Rechecked 7 P0/P1 PRs, moved + to + listed after merge, kept 2 issue-first rows open, found no exact public + listings yet for Terminal Trove, Changelog News, CLIHunt, or OpenAgent.bot, + and deferred the top 5 startup-profile backlog candidates because they + require truthful startup/company or geography claims not supplied here. + External submissions, comments, social posts, emails, payments, and account + creations: 0. - 2026-06-22, 15-repo issue-first outreach wave: opened scope-check issues with no PRs and no directory submissions. Targets had issues enabled, no visible issue templates, and no duplicate `codex-profile(s)` issue/PR history diff --git a/Makefile b/Makefile index 79ab73e..896c17d 100644 --- a/Makefile +++ b/Makefile @@ -18,6 +18,8 @@ test: bash -n test/codex-profile-test.sh sh -n install.sh node test/geo-site-test.mjs + node test/github-pipeline-skills-test.mjs + node test/outreach-agent-test.mjs bin/codex-profile help >/dev/null bash test/codex-profile-test.sh tmp_home="$$(mktemp -d)"; \ diff --git a/agent.md b/agent.md index 3c79e20..0573725 100644 --- a/agent.md +++ b/agent.md @@ -6,9 +6,10 @@ Run a developer-cred distribution pass for . Find genuinely relevant GitHub repositories, curated lists, directories, and -developer-tool catalogs where `codex-profiles` belongs. Open high-quality PRs, -issues, listing requests, or maintainer requests whenever the fit is clear and -the target's contribution rules allow it. +developer-tool catalogs where `codex-profiles` belongs. Qualify repository-first +leads, keep Airtable current, and draft high-quality PRs, issues, listing +requests, or maintainer requests whenever the fit is clear and the target's +contribution rules allow it. ## Project Context @@ -31,7 +32,7 @@ closed PR that needs a replacement. ## Run Preconditions -Before researching or submitting anything: +Before researching or drafting anything: - Verify `agent.md`, `README.md`, and `LAUNCH.md` exist in the repository root. - Run `git status --porcelain=v1 --branch` and record the branch in the final @@ -44,6 +45,111 @@ Before researching or submitting anything: - Reconcile existing `LAUNCH.md` PR and issue links before discovering new targets. +## Airtable Source Of Truth + +Use the existing `Codex Profile` Airtable base as the durable operating ledger. +Do not create a new base, table, CRM, spreadsheet, or side ledger for this +workflow. + +- Targets stays the main pipeline table. +- Log stays append-only history. +- Merge Queue handles dedupe conflicts. +- Bots coordinates automation claims. + +Primary lead unit: repository. +Primary close: accepted listing/PR. + +Automation may research, score, dedupe, update Airtable, and draft artifacts. +Do not submit, open, post, comment, email, DM, or otherwise contact externally +without explicit approval for that exact action. + +For every meaningful outreach change, update the existing target row instead of +creating a duplicate. Keep `Status`, `Last Checked`, `Next Action`, and `Notes` +current, then append a `Log` record with the exact outcome, blocker or reason, +and relevant URL. Preserve records even when a target is blocked, skipped, +submitted, or later needs a major update. + +## Airtable Field Contract + +- `Targets.Key`: deterministic slug such as `gh-owner-repo`, + `awesome-owner-repo`, or `if-owner-repo`. +- `Targets.Channel`: reuse existing choices, including `Awesome-List PR`, + `Issue-First`, `Directory`, `Forum`, `Web`, and `Manual/Gated`. +- `Targets.Status`: use `Backlog -> Issue Open/PR Open -> Pending Review -> + Listed`, or terminal `Declined`, `Deferred`, or `Dead`. +- `Targets.Priority`: `P0` for direct Codex, agent, or CLI listing fit; `P1` + for likely Codex or `CODEX_HOME` workflow fit; `P2` for broader devtool + visibility. +- `Log.Workflow`: use stable labels such as `lead-qualification`, + `github-lead-gen`, `closing`, and `monitoring`. + +## Lead Qualification Gate + +Treat `codex-profiles` as an open-source developer CLI and Codex workflow tool, +not a startup, company, SaaS launch, accelerator applicant, or fundraising +story. Use the repo-local GitHub Lead Qualification skill at +`skills/github-lead-qualification` for ICP fit, Maybe ICP, Not ICP, and +Truthfulness gate decisions. + +Truthfulness gate: + +- Skip anything requiring claims about funding, incorporation, traction, + geography, team/company status, customer counts, founder identity, regional + eligibility, or paid sponsorship unless those claims are already documented. +- Do not invent a company, startup, region, market, customer story, or use case + to force a listing fit. + +No closing draft or external action may start until Airtable records an +`ICP: yes` decision from the qualification phase. Keep Airtable as the handoff; +chat context is disposable. + +## GitHub Lead Workflow + +Run the GitHub pipeline as four small phase contexts. Each phase writes its +handoff to Airtable through `Targets.Next Action` and an append-only `Log` +record. + +- Use the repo-local GitHub Lead Gen skill at `skills/github-lead-gen` for + candidate discovery and shallow Airtable intake. +- Use the repo-local GitHub Lead Qualification skill at + `skills/github-lead-qualification` for ICP, status, priority, evidence, and + next-action decisions. +- Use the repo-local GitHub Closing Draft skill at `skills/github-closing-draft` + for PR, issue, listing, forum, or maintainer-request drafts. +- Use the repo-local GitHub Monitoring skill at `skills/github-monitoring` for + existing PR, issue, listing, and submitted-target rechecks. + +Do not collapse phases into one long context unless the user explicitly asks. +Do not skip Airtable handoffs between phases. + +## Pipeline Views + +Use these operational views when triaging Airtable: + +- Today: `P0` or `P1` targets in `Backlog` or `Active` with a concrete next + action. +- Waiting: `Issue Open`, `PR Open`, and `Pending Review`, sorted by oldest + `Last Checked`. +- Wins: `Listed` or `Owned?` checked. +- Suppressed: `Deferred`, `Declined`, and `Dead`. +- Dedupe: pending `Merge Queue` records. + +## Workflow Checks + +Every run must satisfy these scenarios: + +- Duplicate repo discovered: no new `Target`; append `Log` or route to + `Merge Queue`. +- Existing open PR found outside Airtable: reconcile to one `Target`, set + status `PR Open`, and log the source. +- Awesome list has a matching section and contribution pattern: mark `P0` and + draft the PR. +- Repo scope is ambiguous: use `Issue-First`; no PR until maintainer confirms. +- Directory rejects CLIs/scripts: mark `Deferred` with a source note. +- Forum or social target: draft only; no external post. +- PR merged/listing accepted: status `Listed`, log `Listed`, and clear the next + action unless follow-up is required. + ## Monthly Operating Mode This automation runs monthly. Treat each run as a quality and follow-up pass, @@ -54,33 +160,25 @@ At the start of every run: - Check the state of all PRs and issues already recorded in `LAUNCH.md`. - Update merged, closed, stale, replied-to, or blocked entries before looking for new targets. -- If 15 or more submitted PRs are still open, do not open more than one new - PR or issue unless the new target is Codex-specific and clearly high-signal. -- Otherwise, cap new PRs/issues/listing requests at three per run. +- If 15 or more submitted PRs are still open, do not draft more than one new PR + or issue unless the new target is Codex-specific and clearly high-signal. +- Otherwise, cap new draft PRs, issues, or listing requests at three per run. - Prefer maintainer follow-up, status cleanup, and eligibility revisits over expanding into weak directories. -## Autonomy +## Automation Authority -You have full execution authority for this distribution pass. Do not ask the -project owner for permission before opening PRs, issues, listing requests, or -similar submissions that satisfy this file's quality bar. +You have full internal execution authority for this distribution pass: research, +read repositories, inspect rules, score fit, dedupe, draft artifacts, and update +Airtable or repo-local ledgers. Use available authenticated GitHub CLI access, GitHub API access, browser sessions, local credentials, and repository permissions that are already -configured in the environment. Do not print, copy, or expose secrets. +configured in the environment for read-only research and drafting. Do not print, +copy, or expose secrets. Use subagents freely for parallel repository discovery, fit checks, -contribution-rule review, implementation, validation, and final reporting. - -Act without waiting for manual approval when: - -- The repository is clearly relevant. -- The contribution rules allow a direct PR or issue. -- The edit is small, truthful, and consistent with the target repository. -- Any required validation can be run locally. -- A listing, issue, PR, or request can be submitted through already available - authenticated access. +contribution-rule review, drafting, validation, and final reporting. Defer when: @@ -95,8 +193,8 @@ Defer when: authenticated session. When contribution rules are ambiguous but the repository is relevant, make a -best-effort judgment. Prefer opening an issue over a PR for borderline cases, -and document the rationale in `LAUNCH.md`. +best-effort judgment. Prefer drafting an issue over drafting a PR for borderline +cases, and document the rationale in Airtable and `LAUNCH.md`. ## Candidate Priorities @@ -110,6 +208,9 @@ Prioritize: Avoid: +- Startup, founder, venture, accelerator, investor, funding, regional ecosystem, + and generic launch-board surfaces unless they have a concrete developer-tool + category that fits without unsupported claims. - Generic or low-quality lists submitted only for backlinks. - Unmaintained repositories unless they are highly relevant and still accept submissions. @@ -118,14 +219,18 @@ Avoid: ## Submission Rules -- Only open a PR when `codex-profiles` clearly fits the repository scope and +- Only draft a PR when `codex-profiles` clearly fits the repository scope and contribution rules. -- If contribution rules ask for an issue first, open an issue instead of a PR. +- If contribution rules ask for an issue first, draft an issue instead of a PR. - If eligibility is not met, skip it and document why in `LAUNCH.md`. - Keep every edit minimal and consistent with the target repository's style. -- Validate structured files before opening a PR, especially CSV, JSON, YAML, +- Follow the target repository's contribution, branch, commit, PR title, + template, ordering, and validation conventions over this repository's + conventions. +- Validate structured files before preparing a PR, especially CSV, JSON, YAML, Markdown tables, or generated indexes. -- Use GitHub CLI if available to fork, branch, push, and open PRs. +- Use GitHub CLI if available to prepare forks, branches, commits, and PR drafts + after approval. Do not push or open external PRs before approval. - Use branch name `pinzheng/add-codex-profiles` unless a collision requires a suffix. - Use direct PR titles, usually `Add codex-profiles`. @@ -190,7 +295,8 @@ Repo: https://github.com/Ducksss/codex-profiles ## Required Logging -For every candidate considered, update `LAUNCH.md` with: +For every candidate considered, update Airtable first. `LAUNCH.md` is only a +compact handoff after Airtable is current. The final handoff should include: - Repository or channel URL. - Status: `PR opened`, `issue opened`, `merged`, `closed`, `not eligible`, @@ -205,18 +311,6 @@ For every candidate considered, update `LAUNCH.md` with: Preserve existing `LAUNCH.md` history. Add new entries under the most relevant section, and do not remove prior notes. -## Airtable Ledger - -When Airtable records exist for outreach targets, treat Airtable as the durable -ledger. Preserve platform records even when a target is blocked, skipped, -submitted, or later needs a major update. - -For every meaningful outreach change, update the existing target row instead of -creating a duplicate. Keep `Status`, `Last Checked`, `Next Action`, and `Notes` -current, and append a log entry with the exact outcome, blocker or reason, and -relevant URL. If payment, login, CAPTCHA, OAuth, policy mismatch, or broken site -behavior blocks a submission, leave the record in place and log that reason. - ## Durable State Before finishing: diff --git a/skills/github-closing-draft/SKILL.md b/skills/github-closing-draft/SKILL.md new file mode 100644 index 0000000..d7f1b39 --- /dev/null +++ b/skills/github-closing-draft/SKILL.md @@ -0,0 +1,53 @@ +--- +name: github-closing-draft +description: Use when drafting GitHub PRs, issues, listing copy, or maintainer requests for qualified codex-profiles Airtable targets. Not for discovery, qualification, monitoring, outreach, or submission. +--- + +# GitHub Closing Draft + +## Purpose + +Create target-specific draft artifacts for qualified `codex-profiles` leads and +leave them approval-gated in Airtable. This skill drafts only; it never opens, +posts, submits, comments, emails, or sends anything externally. + +## Required Context + +Read `README.md`, `LAUNCH.md`, the Airtable target, and the target's +contribution rules or submission guidelines. Load `references/draft-rules.md` +before writing copy. + +## Boundaries + +- Consume only Airtable targets with `ICP: yes`. +- Use `Log.Workflow = closing` for every meaningful draft decision. +- Update Airtable with the draft, evidence, and approval blocker. +- Set `Next Action = Await approval to submit draft` after a draft is ready. +- Follow the target repository's conventions over `codex-profiles` conventions. +- Do not perform lead discovery. +- Do not qualify `ICP: maybe` or `ICP: no` targets; route unclear fit back to + lead qualification. +- Do not submit, open, post, comment, email, DM, or otherwise contact externally. + +## Workflow + +1. Select Airtable targets marked `ICP: yes` with `Next Action = Run closing draft`. +2. Recheck duplicate PRs, issues, or existing listings before drafting. +3. Read contribution rules, templates, accepted examples, and target scope. +4. Identify the target repository's file ordering, wording, commit conventions, + branch conventions, PR title format, validation commands, and maintainer + preference for issue-first vs PR-first. +5. Choose the draft route: + - Clear awesome-list fit: prepare a PR diff and PR body draft. + - Ambiguous scope: prepare an issue-first draft. + - Directory: prepare listing copy only when guidelines allow CLI or devtool + projects. + - Forum, social, or manual-gated target: prepare copy only and hold. +6. Keep claims narrow and source-backed using `references/draft-rules.md`. +7. Update Airtable with the draft artifact location or text, set the approval + next action, and append a `closing` log entry. + +## Output + +Return drafts grouped by target, the exact approval action needed, and any +targets routed back to qualification or monitoring. diff --git a/skills/github-closing-draft/agents/openai.yaml b/skills/github-closing-draft/agents/openai.yaml new file mode 100644 index 0000000..9847dd9 --- /dev/null +++ b/skills/github-closing-draft/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "GitHub Closing Draft" + short_description: "Draft approved GitHub outreach assets" + default_prompt: "Use $github-closing-draft to draft PRs, issues, or listing copy for qualified codex-profiles leads." diff --git a/skills/github-closing-draft/references/draft-rules.md b/skills/github-closing-draft/references/draft-rules.md new file mode 100644 index 0000000..a531a23 --- /dev/null +++ b/skills/github-closing-draft/references/draft-rules.md @@ -0,0 +1,41 @@ +# GitHub Closing Draft Rules + +Draft only. Never open a PR, submit a form, create an issue, post a comment, +send an email, DM, forum post, listing submission, or maintainer reply from +this skill. + +## Required checks + +- Confirm the Airtable target is `ICP: yes` and the next action is closing + draft. +- Recheck the target's contribution rules, templates, accepted examples, and + duplicate PRs or issues. +- Follow target repository conventions over `codex-profiles` conventions, + including file location, section ordering, alphabetical rules, entry format, + branch names, commit conventions, PR title format, PR body template, issue + template, and validation commands. +- If scope is ambiguous, draft an issue-first question rather than a PR. +- If a directory rejects CLIs, scripts, or open-source tools, do not draft a + submission; route the target back with a blocker. + +## Copy rules + +- Explain one target-specific reason `codex-profiles` belongs. +- Keep unsupported claims out of every draft: no company status, funding, + traction, geography, sponsorship, customer counts, founder story, or official + OpenAI affiliation. +- Describe the real value: isolated `CODEX_HOME` profiles, multiple Codex + accounts or contexts, CLI/Desktop support, no auth-token copying, and a + dependency-free Bash implementation. +- Include the repository URL and install path only when the target format + naturally supports them. +- Match the target's tone and ordering; do not use generic promotional copy. +- Do not reuse this repo's branch, commit, PR title, or checklist conventions + when the target repository shows a different convention. + +## Airtable handoff + +- Store the draft text or artifact link in the target notes or draft field. +- Set `Next Action = Await approval to submit draft`. +- Append a `closing` log entry with the route, draft location, and exact + approval needed. diff --git a/skills/github-lead-gen/SKILL.md b/skills/github-lead-gen/SKILL.md new file mode 100644 index 0000000..a96d476 --- /dev/null +++ b/skills/github-lead-gen/SKILL.md @@ -0,0 +1,61 @@ +--- +name: github-lead-gen +description: Use when running GitHub lead generation for codex-profiles. Finds repository candidates and performs shallow Airtable intake before lead qualification. Not for drafting, outreach, or monitoring. +--- + +# GitHub Lead Gen + +## Purpose + +Find GitHub repository candidates for `codex-profiles`, dedupe them against +Airtable, and hand them off for later qualification. This skill only handles +candidate discovery and shallow intake. + +## Required Context + +Before searching, read the local project positioning from `README.md` and the +current distribution state from `LAUNCH.md`. Load +`references/search-patterns.md` for approved search lanes and example queries. + +## Boundaries + +- Create or update Airtable `Targets` only. +- Dedupe against existing Airtable targets before creating records. +- Use `Log.Workflow = github-lead-gen` for every meaningful intake decision. +- Set `Next Action = Run lead qualification` on every accepted candidate. +- Record only a shallow candidate reason; do not assign final ICP. +- Do not draft PRs, issues, comments, emails, DMs, forum posts, or listing submissions. +- Do not contact externally. +- Do not change `LAUNCH.md` unless the user explicitly asks for a repo-local handoff. + +## Workflow + +1. Search GitHub using the approved lanes in `references/search-patterns.md`. +2. Keep repository-first candidates only; ignore startup, funding, event, and + social-only surfaces. +3. For each candidate, capture the repository URL, likely channel, shallow + reason, evidence URL, and duplicate key. +4. Search Airtable `Targets` by deterministic key and repository URL. +5. If an existing target is found, update only stale lead-gen fields and append + a `github-lead-gen` log entry. +6. If no target exists, create a `Targets` record with: + - `Key`: deterministic slug such as `gh-owner-repo`, + `awesome-owner-repo`, or `if-owner-repo`. + - `Channel`: best existing lead-gen channel, usually `Awesome-List PR`, + `Issue-First`, `Directory`, `Web`, or `Manual/Gated`. + - `Status`: `Backlog` only for plausible repository leads awaiting + qualification; otherwise skip. + - `Priority`: leave blank unless the repository is obviously Codex-specific. + - `Next Action`: `Run lead qualification`. + - `Notes`: shallow candidate reason and source query. +7. Stop after Airtable intake. The next workflow is lead qualification. + +## Output + +Return a concise handoff: + +- Candidates added. +- Existing targets updated. +- Duplicates skipped. +- Search lanes tried. +- Any Airtable or GitHub access blockers. diff --git a/skills/github-lead-gen/agents/openai.yaml b/skills/github-lead-gen/agents/openai.yaml new file mode 100644 index 0000000..182c905 --- /dev/null +++ b/skills/github-lead-gen/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "GitHub Lead Gen" + short_description: "Find GitHub leads for codex-profiles" + default_prompt: "Use $github-lead-gen to find repository-first GitHub leads for codex-profiles." diff --git a/skills/github-lead-gen/references/search-patterns.md b/skills/github-lead-gen/references/search-patterns.md new file mode 100644 index 0000000..7d47fd0 --- /dev/null +++ b/skills/github-lead-gen/references/search-patterns.md @@ -0,0 +1,44 @@ +# GitHub Lead Gen Search Patterns + +Use these lanes for `codex-profiles` candidate discovery. Keep searches +repository-first and skip results that cannot become a useful Airtable target. + +## Codex/Codex CLI/CODEX_HOME repositories + +- `"CODEX_HOME" codex` +- `"Codex CLI" profile` +- `"codex" "auth.json" "CODEX_HOME"` +- `"codex" "multiple accounts"` +- `"codex" "profile" "CLI"` + +## AI coding agent CLI lists + +- `"awesome" "coding agents" CLI` +- `"awesome" "agent cli"` +- `"AI coding" "CLI" "awesome"` +- `"terminal agents" "awesome"` +- `"vibe coding" "CLI"` + +## Awesome lists for Codex, terminal agents, CLI tools, and devtools + +- `"awesome codex"` +- `"awesome openai codex"` +- `"awesome codex cli"` +- `"awesome terminal" "AI"` +- `"awesome cli apps"` +- `"awesome devtools" "AI"` + +## Repos discussing multi-account/profile workflow tooling + +- `"multiple accounts" "codex"` +- `"profile switching" "codex"` +- `"account switcher" "codex"` +- `"CODEX_HOME" "profile"` +- `"codex" "work personal"` + +## Reject Quickly + +- Startup, funding, accelerator, venture, event, and regional ecosystem lists. +- Social-only channels with no repository, listing, or structured catalog. +- Paid placement, CAPTCHA-only, or OAuth-only submissions. +- Broad AI directories with no CLI, developer-tool, Codex, or open-source angle. diff --git a/skills/github-lead-qualification/SKILL.md b/skills/github-lead-qualification/SKILL.md new file mode 100644 index 0000000..9f81039 --- /dev/null +++ b/skills/github-lead-qualification/SKILL.md @@ -0,0 +1,53 @@ +--- +name: github-lead-qualification +description: Use when qualifying Airtable GitHub lead candidates for codex-profiles after lead generation and before any closing draft. Not for discovery, drafting, outreach, submission, or monitoring. +--- + +# GitHub Lead Qualification + +## Purpose + +Decide whether GitHub lead-gen candidates are real fits for `codex-profiles`, +then update Airtable with evidence and a next phase. This skill consumes +Airtable targets whose `Next Action = Run lead qualification`. + +## Required Context + +Read `README.md` for current product positioning and `LAUNCH.md` for prior +outreach state. Load `references/icp-rules.md` before scoring. + +## Boundaries + +- Update Airtable `Targets` and append `Log` entries only. +- Consume Airtable targets whose `Next Action = Run lead qualification`. +- Use `Log.Workflow = lead-qualification` for every meaningful decision. +- Assign exactly one of `ICP: yes`, `ICP: maybe`, or `ICP: no`. +- Set `Priority`, `Status`, `Last Checked`, `Next Action`, and evidence. +- Do not discover new leads. +- Do not draft PRs, issues, comments, emails, DMs, forum posts, listing submissions, or maintainer replies. +- Do not contact externally. + +## Workflow + +1. Select unqualified GitHub targets whose next action is lead qualification. +2. Read the target repository, list, directory, or guidelines enough to judge + fit and contribution route. +3. Apply `references/icp-rules.md`; record evidence links and the truthful-fit + rationale. +4. Set `Status`: + - `Backlog` only for `ICP: yes` with a valid route, no duplicate open PR or + issue, and a concrete next action. + - `Deferred` for `ICP: maybe`, temporary blockers, gated flows, or + issue-first-only cases. + - `Dead` for permanent `ICP: no` mismatches. +5. Set `Priority`: `P0` for direct Codex, agent, or CLI listing fit; `P1` for + likely Codex or `CODEX_HOME` workflow fit; `P2` for broader devtool + visibility. +6. Set `Next Action = Run closing draft` only for `ICP: yes` targets ready for + drafting. Otherwise set a specific recheck, blocker, or terminal note. +7. Append a `Log` entry with the decision, reason, evidence URL, and next step. + +## Output + +Return a concise Airtable handoff: targets qualified, ICP counts, blockers, +targets ready for closing draft, and any records that need dedupe cleanup. diff --git a/skills/github-lead-qualification/agents/openai.yaml b/skills/github-lead-qualification/agents/openai.yaml new file mode 100644 index 0000000..0df29cb --- /dev/null +++ b/skills/github-lead-qualification/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "GitHub Lead Qualification" + short_description: "Qualify GitHub leads for codex-profiles" + default_prompt: "Use $github-lead-qualification to qualify Airtable GitHub leads for codex-profiles." diff --git a/skills/github-lead-qualification/references/icp-rules.md b/skills/github-lead-qualification/references/icp-rules.md new file mode 100644 index 0000000..e40124a --- /dev/null +++ b/skills/github-lead-qualification/references/icp-rules.md @@ -0,0 +1,48 @@ +# GitHub Lead Qualification ICP Rules + +Use these rules to score `codex-profiles` candidates. The product is an +open-source developer CLI for isolated `CODEX_HOME` profiles across Codex CLI +and Codex Desktop. It is not an official OpenAI project and does not provide +full operating-system isolation. + +## ICP: yes + +- Codex, OpenAI Codex, AI coding agent, CLI, terminal, package, shell, + developer workflow, and open-source devtool catalogs. +- Awesome lists or directories with a maintained section for CLI tools, + terminal agents, AI coding tools, local developer workflow tools, or Codex + resources. +- Targets with a clear contribution route and enough evidence to explain why + `codex-profiles` helps the target audience. + +## ICP: maybe + +- Broad AI, productivity, or developer-tool directories with a free structured + category that may truthfully list an open-source CLI. +- Ambiguous awesome lists where an issue-first scope check is safer than a PR. +- Account-gated, OAuth-gated, CAPTCHA-gated, paid, or unclear submission flows. + +## ICP: no + +- Startup maps, founder directories, accelerators, incubators, investor + networks, funding or venture media, regional startup ecosystems, startup + events, and generic launch boards without a developer-tool category. +- Social-post-only channels with no durable repository, listing, or catalog. +- Targets that require company, funding, traction, geography, sponsorship, or + customer claims not already documented in the repository. + +## Truthfulness gate + +- Do not invent a company, startup, region, market, customer story, customer + count, founder identity, or paid sponsorship angle. +- State only what the repo supports: isolated `CODEX_HOME` directories, + multiple Codex accounts or contexts, CLI/Desktop support, no auth-token + copying, and dependency-free Bash. +- If the target would require unsupported claims, mark `ICP: no` or + `ICP: maybe` with the blocker instead of forcing a fit. + +## Priority + +- `P0`: direct Codex, agent, CLI, or maintained awesome-list fit. +- `P1`: likely Codex, `CODEX_HOME`, AI agent CLI, or developer workflow fit. +- `P2`: broader devtool visibility with a real but less direct audience match. diff --git a/skills/github-monitoring/SKILL.md b/skills/github-monitoring/SKILL.md new file mode 100644 index 0000000..f2df92c --- /dev/null +++ b/skills/github-monitoring/SKILL.md @@ -0,0 +1,50 @@ +--- +name: github-monitoring +description: Use when reconciling existing GitHub PRs, issues, listings, or Airtable outreach targets for codex-profiles after submission or review. Not for lead discovery, qualification, drafting, or outreach. +--- + +# GitHub Monitoring + +## Purpose + +Recheck existing GitHub outreach work, reconcile Airtable, and route any new +work back to the correct phase. This skill does not create leads or drafts. + +## Required Context + +Read `LAUNCH.md`, the relevant Airtable target, and the existing PR, issue, +listing, or submission URL. Load `references/status-map.md` before updating +status. + +## Boundaries + +- Recheck existing PRs, issues, listings, and Airtable target links. +- Update Airtable `Targets` and append `Log` entries only. +- Use `Log.Workflow = monitoring` for every meaningful recheck. +- Do not discover new leads. +- Do not draft PRs, issues, comments, emails, DMs, forum posts, listing submissions, or maintainer replies. +- Do not submit, open, post, comment, email, DM, or otherwise contact externally. + +## Workflow + +1. Select existing targets in `Issue Open`, `PR Open`, or `Pending Review`, + oldest `Last Checked` first. +2. Open the recorded PR, issue, listing, directory entry, or submission status. +3. Apply `references/status-map.md` to map the external state to Airtable. +4. Update `Status`, `Last Checked`, `Next Action`, and `Notes`: + - Merged or accepted listing: set `Listed` and clear next action unless a + follow-up is required. + - Still open with no new information: keep `PR Open` or `Issue Open` and + set a future recheck. + - Maintainer asks for changes or new copy: set `Pending Review`; Set + `Next Action = Run closing draft` when new drafting is needed. + - Scope, eligibility, or fit changed: Set `Next Action = Run lead qualification` + when fit must be rechecked. + - Rejected or closed: set `Declined`, `Deferred`, or `Dead` using the status + map. +5. Append a `monitoring` log entry with the observed state and source URL. + +## Output + +Return targets checked, status changes, stale blockers, wins, and handoffs to +lead qualification or closing draft. diff --git a/skills/github-monitoring/agents/openai.yaml b/skills/github-monitoring/agents/openai.yaml new file mode 100644 index 0000000..4bb8929 --- /dev/null +++ b/skills/github-monitoring/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "GitHub Monitoring" + short_description: "Monitor GitHub outreach outcomes" + default_prompt: "Use $github-monitoring to reconcile open GitHub PRs and issues for codex-profiles." diff --git a/skills/github-monitoring/references/status-map.md b/skills/github-monitoring/references/status-map.md new file mode 100644 index 0000000..f1c181d --- /dev/null +++ b/skills/github-monitoring/references/status-map.md @@ -0,0 +1,27 @@ +# GitHub Monitoring Status Map + +Use this map when rechecking existing outreach links. Record the source URL and +the observed state in the Airtable log. + +## External state to Airtable + +| External state | Airtable status | Next action | +| --- | --- | --- | +| PR open, no new maintainer response | `PR Open` | Recheck on a dated cadence | +| Issue open, no new maintainer response | `Issue Open` | Recheck on a dated cadence | +| PR or issue has maintainer questions | `Pending Review` | `Run closing draft` if a reply or revision draft is needed | +| PR merged or listing accepted | `Listed` | Clear unless follow-up is required | +| Listing visible outside GitHub | `Listed` | Clear unless follow-up is required | +| PR or issue closed as not a fit | `Declined` | Clear, with reason | +| Target rules now reject CLIs/scripts | `Deferred` or `Dead` | Use `Dead` for permanent mismatch | +| Link missing, inaccessible, or gated | `Deferred` | Recheck only if access can change | +| Scope or eligibility changed | Keep current or `Deferred` | `Run lead qualification` when fit must be rechecked | + +## Recheck rules + +- Do not leave `Last Checked` blank after opening a recorded link. +- Do not duplicate comments just to ask for status. +- Do not create replacement targets for the same repository; use `Merge Queue` + only when a real dedupe conflict exists. +- If a maintainer asks for new copy, route to closing draft rather than + drafting inside monitoring. diff --git a/test/github-pipeline-skills-test.mjs b/test/github-pipeline-skills-test.mjs new file mode 100644 index 0000000..57c81a3 --- /dev/null +++ b/test/github-pipeline-skills-test.mjs @@ -0,0 +1,150 @@ +#!/usr/bin/env node + +import assert from 'node:assert/strict'; +import { readFileSync, statSync } from 'node:fs'; +import { join } from 'node:path'; + +const root = new URL('..', import.meta.url).pathname; +const read = (path) => readFileSync(join(root, path), 'utf8'); +const exists = (path) => { + try { + return statSync(join(root, path)).isFile(); + } catch { + return false; + } +}; +const normalized = (text) => text.replace(/\s+/g, ' '); + +const skills = [ + { + name: 'github-lead-gen', + displayName: 'GitHub Lead Gen', + reference: 'references/search-patterns.md', + required: [ + 'Create or update Airtable `Targets` only', + '`Log.Workflow = github-lead-gen`', + '`Next Action = Run lead qualification`', + 'Do not draft PRs, issues, comments, emails, DMs, forum posts, or listing submissions', + 'Do not contact externally', + 'Dedupe against existing Airtable targets', + 'Load `references/search-patterns.md`', + 'The next workflow is lead qualification', + ], + }, + { + name: 'github-lead-qualification', + displayName: 'GitHub Lead Qualification', + reference: 'references/icp-rules.md', + required: [ + 'Consume Airtable targets whose `Next Action = Run lead qualification`', + '`Log.Workflow = lead-qualification`', + '`ICP: yes`', + '`ICP: maybe`', + '`ICP: no`', + 'Set `Priority`', + 'Set `Next Action = Run closing draft`', + 'Do not discover new leads', + 'Do not draft PRs, issues, comments, emails, DMs, forum posts, listing submissions, or maintainer replies', + 'Do not contact externally', + 'Load `references/icp-rules.md`', + ], + }, + { + name: 'github-closing-draft', + displayName: 'GitHub Closing Draft', + reference: 'references/draft-rules.md', + required: [ + 'Consume only Airtable targets with `ICP: yes`', + '`Log.Workflow = closing`', + 'Set `Next Action = Await approval to submit draft`', + 'Do not perform lead discovery', + 'Do not qualify `ICP: maybe` or `ICP: no` targets', + 'Do not submit, open, post, comment, email, DM, or otherwise contact externally', + "Follow the target repository's conventions over `codex-profiles` conventions", + 'Load `references/draft-rules.md`', + ], + }, + { + name: 'github-monitoring', + displayName: 'GitHub Monitoring', + reference: 'references/status-map.md', + required: [ + 'Recheck existing PRs, issues, listings, and Airtable target links', + '`Log.Workflow = monitoring`', + 'Set `Next Action = Run closing draft` when new drafting is needed', + 'Set `Next Action = Run lead qualification` when fit must be rechecked', + 'Do not discover new leads', + 'Do not draft PRs, issues, comments, emails, DMs, forum posts, listing submissions, or maintainer replies', + 'Do not submit, open, post, comment, email, DM, or otherwise contact externally', + 'Load `references/status-map.md`', + ], + }, +]; + +for (const config of skills) { + const skillPath = `skills/${config.name}/SKILL.md`; + const metadataPath = `skills/${config.name}/agents/openai.yaml`; + const referencePath = `skills/${config.name}/${config.reference}`; + + assert.ok(exists(skillPath), `${config.name} skill should exist`); + assert.ok(exists(metadataPath), `${config.name} UI metadata should exist`); + assert.ok(exists(referencePath), `${config.name} reference should exist`); + + const skill = read(skillPath); + const skillText = normalized(skill); + const frontmatter = skill.match(/^---\n([\s\S]*?)\n---/); + assert.ok(frontmatter, `${config.name} should have YAML frontmatter`); + assert.match(frontmatter[1], new RegExp(`^name:\\s*${config.name}$`, 'm')); + assert.match(frontmatter[1], /^description:\s*Use when .+/m); + + for (const required of config.required) { + assert.ok(skillText.includes(required), `${config.name} should contain: ${required}`); + } + + const metadata = read(metadataPath); + assert.ok(metadata.includes(`display_name: "${config.displayName}"`)); + assert.ok(metadata.includes(`$${config.name}`)); +} + +const patterns = read('skills/github-lead-gen/references/search-patterns.md'); +for (const required of [ + 'Codex/Codex CLI/CODEX_HOME repositories', + 'AI coding agent CLI lists', + 'Awesome lists for Codex, terminal agents, CLI tools, and devtools', + 'Repos discussing multi-account/profile workflow tooling', +]) { + assert.ok(patterns.includes(required), `search patterns should contain: ${required}`); +} + +const qualification = read('skills/github-lead-qualification/references/icp-rules.md'); +for (const required of ['ICP: yes', 'ICP: maybe', 'ICP: no', 'Truthfulness gate']) { + assert.ok(qualification.includes(required), `qualification rules should contain: ${required}`); +} + +const closing = read('skills/github-closing-draft/references/draft-rules.md'); +for (const required of [ + 'Draft only', + 'approval', + 'unsupported claims', + 'commit conventions', + 'PR title format', +]) { + assert.ok(closing.includes(required), `draft rules should contain: ${required}`); +} + +const monitoring = read('skills/github-monitoring/references/status-map.md'); +for (const required of ['PR Open', 'Issue Open', 'Pending Review', 'Listed', 'Declined']) { + assert.ok(monitoring.includes(required), `status map should contain: ${required}`); +} + +const agent = read('agent.md'); +for (const config of skills) { + assert.ok( + normalized(agent).includes(`Use the repo-local ${config.displayName} skill at \`skills/${config.name}\``), + `agent.md should point ${config.name} runs at the repo-local skill` + ); +} + +for (const file of ['skills/github-lead-gen/.DS_Store']) { + assert.ok(!exists(file), `${file} should not be present`); +} diff --git a/test/outreach-agent-test.mjs b/test/outreach-agent-test.mjs new file mode 100644 index 0000000..7b8d197 --- /dev/null +++ b/test/outreach-agent-test.mjs @@ -0,0 +1,69 @@ +#!/usr/bin/env node + +import assert from 'node:assert/strict'; +import { readFileSync } from 'node:fs'; +import { join } from 'node:path'; + +const root = new URL('..', import.meta.url).pathname; +const agent = readFileSync(join(root, 'agent.md'), 'utf8'); +const normalizedAgent = agent.replace(/\s+/g, ' '); + +const mustContain = [ + 'Targets stays the main pipeline table', + 'Log stays append-only history', + 'Merge Queue handles dedupe conflicts', + 'Bots coordinates automation claims', + 'Primary lead unit: repository', + 'Primary close: accepted listing/PR', + 'Do not submit, open, post, comment, email, DM, or otherwise contact externally without explicit approval', + '`Targets.Key`', + '`Targets.Channel`', + '`Targets.Status`', + '`Targets.Priority`', + '`Log.Workflow`', + 'github-lead-gen', + 'lead-qualification', + 'closing', + 'monitoring', + 'Use the repo-local GitHub Lead Gen skill at `skills/github-lead-gen`', + 'Use the repo-local GitHub Lead Qualification skill at `skills/github-lead-qualification`', + 'Use the repo-local GitHub Closing Draft skill at `skills/github-closing-draft`', + 'Use the repo-local GitHub Monitoring skill at `skills/github-monitoring`', + 'Lead Qualification Gate', + 'not a startup, company, SaaS launch, accelerator applicant, or fundraising story', + 'ICP fit', + 'Maybe ICP', + 'Not ICP', + 'Truthfulness gate', + 'No closing draft or external action may start until Airtable records an `ICP: yes` decision', + 'Do not invent a company, startup, region, market, customer story, or use case', + 'Backlog -> Issue Open/PR Open -> Pending Review -> Listed', + 'candidate discovery and shallow Airtable intake', + 'ICP, status, priority, evidence, and next-action decisions', + 'PR, issue, listing, forum, or maintainer-request drafts', + 'existing PR, issue, listing, and submitted-target rechecks', + 'Do not collapse phases into one long context', + 'Do not skip Airtable handoffs between phases', + 'Today', + 'Waiting', + 'Wins', + 'Suppressed', + 'Dedupe', + 'Duplicate repo discovered', + 'Existing open PR found outside Airtable', + 'Directory rejects CLIs/scripts', + 'PR merged/listing accepted', +]; + +for (const text of mustContain) { + assert.ok(normalizedAgent.includes(text), `agent.md should contain: ${text}`); +} + +const forbidden = [ + 'Do not ask the project owner for permission before opening PRs', + 'Act without waiting for manual approval', +]; + +for (const text of forbidden) { + assert.ok(!agent.includes(text), `agent.md should not contain: ${text}`); +}