Repository navigation
dist added for devDependancies #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,5 @@ | ||
| node_modules | ||
| dist | ||
| .ci-artifacts | ||
| .git | ||
| .old | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| # Guards the committed build output. Because dist/ is checked in (so consumers | ||
| # of the git dependency get prebuilt JS with no install-time build), it can | ||
| # drift from src/ if someone edits source without rebuilding. This job rebuilds | ||
| # and fails if the committed dist/ doesn't match. | ||
| name: CI | ||
|
|
||
| on: | ||
| pull_request: | ||
| push: | ||
| branches: [main] | ||
|
|
||
| jobs: | ||
| dist-fresh: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v6 | ||
|
|
||
| - uses: pnpm/action-setup@v6 | ||
|
|
||
| - uses: actions/setup-node@v6 | ||
| with: | ||
| node-version: 24 | ||
| cache: pnpm | ||
|
|
||
| - run: pnpm install --frozen-lockfile | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The CI workflow uses There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The CI workflow uses There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The CI workflow uses There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The CI workflow uses --frozen-lockfile but no pnpm.lock file appears in this diff. The install step will fail unless a lockfile is committed. Either commit a lockfile generated by pnpm install or change to --no-frozen-lockfile.
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The CI workflow uses |
||
|
|
||
| - run: pnpm typecheck | ||
|
|
||
| - name: Rebuild dist and check it matches what's committed | ||
| run: | | ||
| pnpm build | ||
| if ! git diff --exit-code -- dist; then | ||
| echo "::error::dist/ is stale — run 'pnpm build' and commit the result." >&2 | ||
| exit 1 | ||
| fi | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,118 @@ | ||
| #!/usr/bin/env node | ||
| // Reviewer CLI. | ||
| // | ||
| // Subcommands: | ||
| // run — fetch → reconcile (if unresolved bot threads) → review → summarize | ||
| // fetch — fetch only | ||
| // reconcile — fetch + reconcile | ||
| // review — fetch + review (skips reconcile) | ||
| // summarize — fetch + summarize (skips review and reconcile; existing | ||
| // unresolved bot threads count as unaddressed) | ||
| // | ||
| // Flags: | ||
| // --pr <url> required (or set PR_URL env). A real PR URL (github/ | ||
| // gitlab/bitbucket), `mock://<scenario>` for tests, or | ||
| // `local://<base>` to review the current checkout's | ||
| // branch against <base> (default main) with no VCS — | ||
| // findings print to the console (comments + verdict) | ||
| // instead of posting. Must run inside a container. | ||
| // --llm-url <url> overrides LLM_URL | ||
| // --llm-key <key> overrides LLM_KEY | ||
| // --llm-model <name> overrides LLM_MODEL (otherwise auto-detected) | ||
| import { buildCtx } from "./ctx.js"; | ||
| import { runFetch } from "./stages/fetch/index.js"; | ||
| import { runReconcile } from "./stages/reconcile/index.js"; | ||
| import { runReview } from "./stages/review/index.js"; | ||
| import { runSummarize } from "./stages/summarize/index.js"; | ||
| const FLAG_ALIASES = { | ||
| "--pr": "pr", | ||
| "--llm-url": "llmUrl", | ||
| "--llm-key": "llmKey", | ||
| "--llm-model": "llmModel", | ||
| }; | ||
| function parseArgs(argv) { | ||
| const command = argv[2]; | ||
| if (!command || command === "--help" || command === "-h") | ||
| usageAndExit(); | ||
| const flags = {}; | ||
| for (let i = 3; i < argv.length; i++) { | ||
| const a = argv[i]; | ||
| const key = FLAG_ALIASES[a]; | ||
| if (!key) | ||
| die(`unknown flag: ${a}`); | ||
| const val = argv[i + 1]; | ||
| if (val === undefined || val.startsWith("--")) | ||
| die(`flag ${a} requires a value`); | ||
| flags[key] = val; | ||
| i++; | ||
| } | ||
| return { command, flags }; | ||
| } | ||
| function usageAndExit() { | ||
| process.stderr.write("usage: reviewer <run|fetch|reconcile|review|summarize> --pr <url|local://[base]> [--llm-url <u>] [--llm-key <k>] [--llm-model <m>]\n"); | ||
| process.exit(2); | ||
| } | ||
| function die(msg) { | ||
| process.stderr.write(`error: ${msg}\n`); | ||
| process.exit(2); | ||
| } | ||
| function buildOverrides(flags) { | ||
| const prUrl = flags.pr ?? process.env.PR_URL ?? ""; | ||
| if (!prUrl) | ||
| die("missing --pr (or PR_URL env)"); | ||
| return { | ||
| prUrl, | ||
| llmUrl: flags.llmUrl, | ||
| llmKey: flags.llmKey, | ||
| llmModel: flags.llmModel, | ||
| }; | ||
| } | ||
| // ---- Pipeline orchestration -------------------------------------------- | ||
| function hasUnresolvedBotThreads(state) { | ||
| return state.comments.some((c) => c.by === "bot" && c.inline && !c.resolved && !c.parentId); | ||
| } | ||
| async function runCommand(command, ctx) { | ||
| switch (command) { | ||
| case "run": { | ||
| let state = await runFetch(ctx); | ||
| if (hasUnresolvedBotThreads(state)) { | ||
| ctx.logger.info("pipeline.followup", { reason: "unresolved_bot_threads" }); | ||
| state = await runReconcile(ctx, state); | ||
| } | ||
| else { | ||
| ctx.logger.info("pipeline.initial"); | ||
| } | ||
| state = await runReview(ctx, state); | ||
| return runSummarize(ctx, state); | ||
| } | ||
| case "fetch": { | ||
| return runFetch(ctx); | ||
| } | ||
| case "reconcile": { | ||
| const state = await runFetch(ctx); | ||
| return runReconcile(ctx, state); | ||
| } | ||
| case "review": { | ||
| const state = await runFetch(ctx); | ||
| return runReview(ctx, state); | ||
| } | ||
| case "summarize": { | ||
| const state = await runFetch(ctx); | ||
| return runSummarize(ctx, state); | ||
| } | ||
| default: | ||
| die(`unknown command: ${command}`); | ||
| } | ||
| } | ||
| // ---- Entry -------------------------------------------------------------- | ||
| const { command, flags } = parseArgs(process.argv); | ||
| const ctx = await buildCtx(buildOverrides(flags)); | ||
| try { | ||
| const state = await runCommand(command, ctx); | ||
| if (state.verdict?.fatal) | ||
| process.exit(1); | ||
| } | ||
| catch (e) { | ||
| ctx.logger.error("cli.fatal", { error: e.message }); | ||
| process.exit(1); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The CI installs dependencies with
--frozen-lockfile, but there's nopnpm.lockfile visible in the diff. If the lockfile doesn't exist, this step will fail. Either commit a lockfile or use--no-frozen-lockfilefor the CI install step.