mirror of
https://github.com/MadsLorentzen/ai-job-search.git
synced 2026-09-17 08:36:25 +00:00
Silently discarded flags produced silently wrong results: jobdanmark with --query (its real flag is --text) returned all 13,862 jobs as if they matched, exit 0, empty stderr - indistinguishable from a real result set. The four bunli CLIs get an argv preflight built from each command's own options object; linkedin and freehire validate parsed flags against per-command known sets. help/version still pass, and add-portal.md's existing bogus-flag-exits-1 contract now holds for the reference implementations contributors copy. One linkedin pin updated: "--jobage-minutes -5" now fails as UNKNOWN_FLAG (the stray -5 token) rather than BAD_ARG - same loud-failure invariant, earlier gate. Review finding F13 (2026-08-19), decision approved by Mads. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
46 lines
1.5 KiB
TypeScript
46 lines
1.5 KiB
TypeScript
import { createCLI } from "@bunli/core"
|
|
import { writeError } from "./helpers.js"
|
|
import { search } from "./commands/search.js"
|
|
import { detail } from "./commands/detail.js"
|
|
|
|
const cli = await createCLI({
|
|
name: "jobindex-cli",
|
|
version: "0.1.0",
|
|
description: "CLI for searching jobs on Jobindex.dk",
|
|
})
|
|
|
|
const commands = [search, detail]
|
|
for (const command of commands) {
|
|
cli.command(command)
|
|
}
|
|
|
|
// Reject unknown --flags before dispatch. bunli silently discards them, and a
|
|
// silently discarded filter changes what the search returns without any error
|
|
// (a wrong flag name once returned an entire portal's database as if it
|
|
// matched the query). add-portal.md's contract requires a bogus flag to exit 1
|
|
// with a JSON error on stderr; this enforces it for the reference CLIs too.
|
|
const argv = process.argv.slice(2)
|
|
const invoked = commands.find((c) => (c as { name?: string }).name === argv[0])
|
|
if (invoked) {
|
|
const known = new Set([
|
|
...Object.keys((invoked as { options?: Record<string, unknown> }).options ?? {}),
|
|
"help",
|
|
"version",
|
|
])
|
|
for (const token of argv.slice(1)) {
|
|
if (token === "--") break
|
|
if (token.startsWith("--")) {
|
|
const flag = token.slice(2).split("=")[0]
|
|
if (!known.has(flag)) {
|
|
writeError(
|
|
`unknown flag --${flag} for '${argv[0]}' - flags are never silently ignored, because a discarded filter changes what the search returns; see --help for the supported flags`,
|
|
"UNKNOWN_FLAG",
|
|
)
|
|
process.exit(1)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
await cli.run()
|