initial public release
This commit is contained in:
+1586
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,135 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/cobr-ai/apex/internal/scan"
|
||||
"github.com/cobr-ai/apex/internal/tui"
|
||||
)
|
||||
|
||||
// main dispatches on the first argv: no subcommand → TUI; "discover" →
|
||||
// resolve a careers URL into a Workday adapter snippet (useful during
|
||||
// portal-curation). Keeping the dispatcher tiny avoids pulling in cobra just
|
||||
// for one flag path.
|
||||
func main() {
|
||||
if len(os.Args) > 1 {
|
||||
switch os.Args[1] {
|
||||
case "discover":
|
||||
os.Exit(runDiscover(os.Args[2:]))
|
||||
case "scan":
|
||||
os.Exit(runScan(os.Args[2:]))
|
||||
case "eval":
|
||||
os.Exit(runEval(os.Args[2:]))
|
||||
case "ingest":
|
||||
os.Exit(runIngest(os.Args[2:]))
|
||||
case "offers":
|
||||
os.Exit(runOffers(os.Args[2:]))
|
||||
case "linkedin":
|
||||
os.Exit(runLinkedIn(os.Args[2:]))
|
||||
case "cv":
|
||||
os.Exit(runCV(os.Args[2:]))
|
||||
case "patterns":
|
||||
os.Exit(runPatterns(os.Args[2:]))
|
||||
case "followup":
|
||||
os.Exit(runFollowup(os.Args[2:]))
|
||||
case "stories":
|
||||
os.Exit(runStories(os.Args[2:]))
|
||||
case "pipeline":
|
||||
if len(os.Args) < 3 {
|
||||
fmt.Fprintln(os.Stderr, "usage: apex pipeline <add|list|run> ...")
|
||||
os.Exit(2)
|
||||
}
|
||||
switch os.Args[2] {
|
||||
case "add":
|
||||
os.Exit(runPipelineAdd(os.Args[3:]))
|
||||
case "list":
|
||||
os.Exit(runPipelineList(os.Args[3:]))
|
||||
case "run":
|
||||
os.Exit(runPipelineRun(os.Args[3:]))
|
||||
default:
|
||||
fmt.Fprintf(os.Stderr, "unknown pipeline subcommand: %s\n", os.Args[2])
|
||||
os.Exit(2)
|
||||
}
|
||||
case "apply":
|
||||
os.Exit(runApply(os.Args[2:]))
|
||||
case "compare":
|
||||
os.Exit(runCompare(os.Args[2:]))
|
||||
case "deep":
|
||||
os.Exit(runDeep(os.Args[2:]))
|
||||
case "training":
|
||||
os.Exit(runTraining(os.Args[2:]))
|
||||
case "project":
|
||||
os.Exit(runProject(os.Args[2:]))
|
||||
case "negotiate":
|
||||
os.Exit(runNegotiate(os.Args[2:]))
|
||||
case "contacto":
|
||||
os.Exit(runContacto(os.Args[2:]))
|
||||
case "intake":
|
||||
os.Exit(runIntake(os.Args[2:]))
|
||||
case "-h", "--help", "help":
|
||||
printUsage()
|
||||
return
|
||||
}
|
||||
}
|
||||
app := tui.NewApp()
|
||||
if err := app.Run(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func printUsage() {
|
||||
fmt.Println("apex — TUI-first AI job search platform")
|
||||
fmt.Println()
|
||||
fmt.Println("Usage:")
|
||||
fmt.Println(" apex launch the TUI (default)")
|
||||
fmt.Println(" apex discover <url> resolve Workday host/tenant/site for a careers URL")
|
||||
fmt.Println(" apex scan headless scan of all enabled adapters; writes new jobs to ~/.apex/apex.db")
|
||||
fmt.Println(" apex ingest <file.docx> parse DOCX resume into cv.md with writing style extraction")
|
||||
fmt.Println(" apex eval [--limit N] [--min-score F] [--workers N] evaluate pending jobs via Claude CLI; reports under ~/.apex/reports/")
|
||||
fmt.Println(" apex offers <url> <url> [url...] compare evaluated jobs side-by-side with Claude ranking")
|
||||
fmt.Println(" apex pipeline <add|list|run> manage pipeline queue (add/list/run jobs)")
|
||||
fmt.Println(" apex apply <url> mark a job as applied (interactive confirmation)")
|
||||
fmt.Println(" apex compare [url] compare job eval against senior engineer benchmark")
|
||||
fmt.Println(" apex deep [url] deep company/culture/red-flag analysis")
|
||||
fmt.Println(" apex training [url] personal development roadmap from job eval")
|
||||
fmt.Println(" apex project [url] portfolio projects to address job gaps")
|
||||
fmt.Println(" apex negotiate [url] salary negotiation strategy")
|
||||
fmt.Println(" apex contacto [url] draft LinkedIn outreach messages for hiring team")
|
||||
fmt.Println(" apex cv [--job-url URL] generate tailored HTML CV + PDF for a job (or generic CV if no job given)")
|
||||
fmt.Println(" apex patterns show application pattern analysis (ghost rate, score distribution, etc)")
|
||||
fmt.Println(" apex followup show pending follow-ups based on status cadence")
|
||||
fmt.Println(" apex stories [--limit N] show STAR stories extracted from recent evaluations")
|
||||
fmt.Println(" apex intake [--synthesize] interactive 8-phase intake interview → cv.md + profile.yml")
|
||||
fmt.Println(" apex linkedin <subcommand> LinkedIn browser automation (messages/thread/reply/invite/jobs/contacts/test)")
|
||||
fmt.Println(" apex help show this message")
|
||||
fmt.Println()
|
||||
fmt.Println("Environment:")
|
||||
fmt.Println(" APEX_DISCOVER_SCRIPT absolute path to career-ops/discover-workday.mjs")
|
||||
fmt.Println(" (used when the input URL isn't directly *.myworkdayjobs.com)")
|
||||
fmt.Println(" APEX_MIN_SCORE eval score threshold; below = status Discarded")
|
||||
}
|
||||
|
||||
func runDiscover(args []string) int {
|
||||
if len(args) == 0 {
|
||||
fmt.Fprintln(os.Stderr, "usage: apex discover <careers-url>")
|
||||
return 2
|
||||
}
|
||||
d := &scan.Discoverer{
|
||||
DiscoverScript: os.Getenv("APEX_DISCOVER_SCRIPT"),
|
||||
Timeout: 90 * time.Second,
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||
defer cancel()
|
||||
out, err := d.Discover(ctx, args[0])
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "discover: %v\n", err)
|
||||
return 1
|
||||
}
|
||||
fmt.Printf("# Source: %s Input: %s\n", out.Source, out.Input)
|
||||
fmt.Println(out.YAMLSnippet(""))
|
||||
return 0
|
||||
}
|
||||
Reference in New Issue
Block a user