Skip to content

Default bare hunk to diff startup#157

Open
tanvesh01 wants to merge 4 commits intomodem-dev:mainfrom
tanvesh01:tanvesh01/issue-116-fix
Open

Default bare hunk to diff startup#157
tanvesh01 wants to merge 4 commits intomodem-dev:mainfrom
tanvesh01:tanvesh01/issue-116-fix

Conversation

@tanvesh01
Copy link
Copy Markdown
Contributor

Summary

  • default bare hunk to the interactive diff flow in TTY sessions
  • preserve piped stdin pager/patch detection and fall back to help for empty non-interactive bare runs
  • update help/docs and CLI/startup tests to encode the new behavior

Closes #116.

Validation

  • bun run typecheck
  • bun test test/cli.test.ts
  • bun test test/startup.test.ts
  • bun test test/help-output.test.ts
  • bun run src/main.tsx -- --help
  • bun test (Bun crashed with a segmentation fault mid-suite; focused tests above passed)

@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Apr 1, 2026

Greptile Summary

This PR implements the long-requested ergonomic default for bare hunk invocations (closes #116): rather than printing help text, a bare hunk in an interactive TTY now launches the working-tree diff UI (hunk diff), while piped/non-interactive invocations still detect patch stdin or fall back to help when stdin is empty.

Key changes:

  • New BareCommandInput type (src/core/types.ts): a dedicated { kind: \"bare\" } shape separates the "no subcommand given" case from the explicit --help case in the ParsedCliInput union.
  • parseCli split (src/core/cli.ts): bare invocation now returns { kind: \"bare\" } instead of the help text; --help / -h / help continue to return the full help. renderCliHelp is exported for reuse in startup.ts. requireReloadableCliInput correctly rejects bare as a reload target.
  • prepareStartupPlan routing (src/core/startup.ts): the bare kind is resolved at startup time via a stdinIsTTY dep-injectable flag — TTY → default git diff startup; non-TTY → pager stdin read, with an empty-stdin fallback to help.
  • Tests (test/cli.test.ts, test/startup.test.ts): all four new scenarios (TTY interactive, non-TTY empty, non-TTY plain text, non-TTY patch) are exercised with injected deps; existing tests updated to reflect the changed bare behavior.
  • README updated to document the new default UX.

Confidence Score: 5/5

Safe to merge — all remaining findings are minor style/consistency suggestions that do not affect runtime behaviour.

The logic is correct across all four bare-invocation paths and is well-covered by new tests. Both flagged items are P2: a redundant branch that compiles and runs identically, and a dep-injection inconsistency that doesn't affect any current test or production path. No correctness, security, or data-integrity issues were found.

src/core/startup.ts — minor redundant branch and one direct call to renderCliHelp() that bypasses the injection pattern used everywhere else.

Important Files Changed

Filename Overview
src/core/startup.ts Core startup routing updated to handle new bare kind — TTY-check correctly gates the git-diff vs pager path; minor redundant branch and one dep-injection inconsistency noted.
src/core/cli.ts No-command path now returns { kind: "bare" } instead of help; requireReloadableCliInput correctly guards the bare kind; renderCliHelp exported for use in startup.
src/core/types.ts New BareCommandInput interface and its inclusion in ParsedCliInput union — minimal and correct.
test/startup.test.ts Comprehensive new tests cover TTY interactive, non-TTY empty stdin (help fallback), and non-TTY patch stdin paths for bare invocations.
test/cli.test.ts Tests updated to assert bare invocation returns { kind: "bare" } and that --help still produces full help text with all expected sections.
README.md Quick-start docs updated to reflect new bare-hunk → diff-UI default; --help added as explicit entry point for help text.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[argv] --> B[parseCli]
    B --> C{kind}
    C -- "--help / -h / help" --> D[kind: help]
    C -- "no command" --> E[kind: bare]
    C -- "diff / show / patch / ..." --> F[CliInput]
    C -- pager --> G[kind: pager]

    D --> H[StartupPlan: help]
    F --> N[resolveRuntime -> resolveConfig -> loadBootstrap]

    E --> I{stdinIsTTY?}
    I -- yes --> J["appCliInput = git, staged:false"]
    I -- no --> K[appCliInput = pager]

    J --> N

    G --> K
    K --> L[readStdin]
    L --> M{stdinText?}
    M -- "empty + bare" --> H
    M -- not patch --> O[StartupPlan: plain-text-pager]
    M -- patch --> P["appCliInput = patch, pager:true"]
    P --> N
    N --> Q[StartupPlan: app]
Loading

Reviews (1): Last reviewed commit: "Default bare hunk to diff startup" | Re-trigger Greptile

Comment on lines +104 to +108
} else if (parsedCliInput.kind === "pager") {
appCliInput = parsedCliInput;
} else {
appCliInput = parsedCliInput;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Redundant else if and else branches

Both the else if (parsedCliInput.kind === "pager") and the final else branch do exactly the same thing (appCliInput = parsedCliInput). Since help, mcp-serve, session, and bare have all been handled above, the only remaining shapes are CliInput | PagerCommandInput, making the distinction between the two branches meaningless.

Suggested change
} else if (parsedCliInput.kind === "pager") {
appCliInput = parsedCliInput;
} else {
appCliInput = parsedCliInput;
}
} else {
appCliInput = parsedCliInput;
}

Comment on lines +113 to +118
if (stdinText.length === 0 && bareInvocation) {
return {
kind: "help",
text: renderCliHelp(),
};
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 renderCliHelp bypasses dependency injection

Every other side-effectful operation in prepareStartupPlan is routed through an injectable dep (e.g. parseCliImpl, readStdinText). Here renderCliHelp() is called directly, so tests that inject a custom parseCliImpl returning { kind: "bare" } cannot control the help text produced by the bare + empty-stdin path. This is fine for the current test suite (the real renderCliHelp works fine), but it breaks the otherwise-consistent injection pattern. Consider adding an optional renderCliHelpImpl dep, or accepting a pre-rendered helpText string alongside the bare input.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Run the app on bare hunk

1 participant