Commit Graph

6 Commits

Author SHA1 Message Date
prateek a34094e7d8
refactor: simplify session lifecycle and zellij runtime (#62)
* refactor: remove canonical lifecycle state

* refactor: move sqlite stores into subpackage (#62)

* refactor: strengthen sqlite generated model types (#62)

* refactor: remove lifecycle notifications (#62)

* docs: remove notification cleanup leftovers (#62)

* refactor: narrow lifecycle manager scope (#62)

* refactor: keep PR nudges in lifecycle (#62)

* refactor: trim unused storage and lifecycle contracts (#62)

* refactor: align storage and runtime observation surfaces (#62)

* refactor: remove stale daemon and adapter bloat (#62)

* test: fix terminal ring race assertion (#62)

* refactor: trim lifecycle and http boilerplate (#62)

* refactor: expose sqlite CDC source directly (#62)

* refactor: share process liveness checks (#62)

* test: trim lifecycle store fake surface (#62)

* refactor: separate PR observations from storage rows (#62)

* refactor: trim remaining cleanup surfaces (#62)

* refactor: narrow observation and PR display APIs (#62)

* refactor: move PR write DTOs out of domain (#62)

* refactor: normalize PR domain storage types (#62)

* refactor: remove unused session port interface (#62)

* fix: reject unexpected CLI arguments (#62)

* refactor: use session metadata for spawn completion (#62)

* refactor: narrow session runtime dependency (#62)

* fix: validate zellij version in doctor (#62)

* refactor: split observation port DTOs (#62)

* chore: add sqlc generation script (#62)

* refactor: clarify terminal mux naming (#62)

* fix: tolerate nil loggers (#62)

---------

Co-authored-by: itrytoohard <ayetrytoohard@gmail.com>
2026-06-01 08:42:49 +05:30
prateek 8df074b1c9 chore(backend): add golangci-lint with a strong ruleset and clear the tree
Introduces backend/.golangci.yml (27 linters across correctness, dead-code/
boilerplate, style, and security), wires it into CI as a blocking job, and
fixes every finding so the tree starts at zero.

Config:
- 27 linters: errcheck, govet, staticcheck, errorlint, bodyclose,
  sqlclosecheck, rowserrcheck, nilerr, makezero, unused, unparam, unconvert,
  wastedassign, copyloopvar, prealloc, dupl, revive (incl. exported-symbol doc
  comments), gocritic, misspell, usestdlibvars, predeclared, nakedret, gosec, …
- Tuned for signal over noise: govet/shadow and gocritic hugeParam/rangeValCopy/
  unnamedResult disabled (idiomatic-Go false positives); sqlc-generated code and
  tests get scoped exclusions; gosec G304 excluded (paths are config/run-file/
  worktree-derived, not user input); nilerr excluded in cli/status.go (probe
  failures are the reported status, not a command error).

CI:
- New blocking lint job (golangci-lint-action, latest binary for Go-version
  compatibility).
- go-version now read from go.mod (was pinned 1.22 while go.mod declares 1.25).

Cleanup to reach zero (no behavior change):
- errcheck: wrap deferred/inline Close()/Remove()/Rollback() with `_ =`.
- gosec: tighten dir/file perms (0755->0750, 0644->0600).
- unparam: drop always-nil error return from startLifecycle; drop unused
  shellPath param (zellij PowerShell) and always-500 fallbackStatus param
  (writeProjectError).
- gocritic: regexp \d, s != "", switch->if, combined appends.
- revive: doc comments on all exported symbols; rename project.ProjectRow ->
  project.Row (stutter); rename `max` locals shadowing the builtin.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 04:58:41 +05:30
harshitsinghbhandari a0020e06be refactor(tracker): address code-review findings
Six fixes from the second code review pass — none load-bearing but all
improve the contract honesty or prevent future churn. Tests pass with
-race (49 in package, 299 across the backend).

1. Preflight: atomic.Bool fast-path before the mutex so cached-success
   calls don't contend on the lock. Double-checked locking on the
   mutex side so concurrent first-callers still serialize the single
   GET /user request.

2. Preflight godoc: tighten to say it verifies token validity, not
   repo authorization — Get/List against a specific repo may still
   return ErrAuthFailed after a green Preflight if the token lacks
   the scope or the repo isn't visible.

3. domain.ListFilter.Limit godoc: explicitly note that exceeding the
   provider per-page max is SILENTLY capped (no error, no truncation
   signal) and that auto-pagination is deferred to #35.

4. Extract issueFromGH helper. Get and List were duplicating the
   identical ghIssue -> domain.Issue projection; consolidating now
   prevents a 3-way merge when #40 (Comment/Transition) lands.

5. parseGitHubRepo: reject whitespace and # in both owner and repo
   segments. Leading dots stay legal (the "owner/.github" repo
   convention). New test cases cover the rejections plus a positive
   guard for the leading-dot case.

6. fakeGH test helper: lock the handlers map on both read and write,
   so future tests registering handlers from goroutines won't trip
   -race.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 22:32:45 +05:30
harshitsinghbhandari d6cd245833 feat(tracker): add List + Preflight to the port and GitHub adapter
Brings the read-side surface up to parity with the legacy TS impl's
useful read methods. Closes a gap flagged during scope review.

Port additions:
  - List(ctx, repo, filter) ([]Issue, error)
  - Preflight(ctx) error

Domain additions: TrackerRepo, ListStateFilter (open/closed/""=all),
ListFilter (State, Labels, Assignee, Limit).

GitHub adapter:
  - List hits GET /repos/{o}/{r}/issues with query-encoded filter.
    Defaults: state=all, per_page=30; per_page is capped at 100.
    PRs are filtered out client-side (GitHub conflates them with
    issues on that endpoint).
  - Preflight hits GET /user. Success is cached for the Tracker's
    lifetime via sync.Mutex + bool; failures are intentionally NOT
    cached so a transient startup glitch is recoverable.
  - New ErrAuthFailed sentinel. classifyError now maps 401, and 403
    without rate-limit signals, to ErrAuthFailed instead of an opaque
    error — so Preflight callers can distinguish bad-token from other
    failures.

Pagination beyond the first page is intentionally out of scope for v1
(see doc.go); the observer/polling work in #35 will own that.

Tests: 43 pass (was 25). Adds Preflight cache + recovery, List query
encoding, PR filtering, repo parser rejection, and ErrAuthFailed
classification.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 22:04:58 +05:30
harshitsinghbhandari 6e4ec499fb refactor(tracker): drop Comment + Transition; v1 is read-only Get
Scope correction: mirroring agent lifecycle onto the tracker (status
comments, label/state updates) is not wanted in the current rewrite.
That work is now tracked as issue #40 and will land once we decide on
the opt-out knob, label setup, and Linear's workflow-state fit.

Removes from the port and the GitHub adapter:
  - Comment(ctx, id, body) and ErrEmptyBody
  - Transition(ctx, id, state) and ErrUnknownState
  - planForState / transitionPlan and the forward state mapping
  - reasonComplete constant (only the Get reverse mapping is kept)
  - 11 tests + the transitionCall normalization helpers

Kept (still load-bearing for Get):
  - All 5 NormalizedIssueState values — Get reports them faithfully
    when a repo carries the in-progress / in-review labels.
  - The reverse mapping in mapStateFromGitHub.
  - RateLimitError with ResetAt + RetryAfter (#35 will use it).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 21:53:44 +05:30
harshitsinghbhandari e5919c7998 feat(tracker): Tracker port + GitHub adapter
Reference implementation; GitLab and Linear follow in separate PRs.
Issue observer loop (poll + ApplyTrackerFacts) is deferred to #35.

Three-layer split mirrors the SCM layout adil is landing in PR #28:
- domain/tracker.go   — value types (TrackerProvider, TrackerID,
  NormalizedIssueState, Issue)
- ports/tracker.go    — the Tracker interface
- adapters/tracker/github/ — REST-backed adapter

v1 is write-mostly: Get, Comment, Transition. No cache, no inflight
dedup, no polling. State mapping is documented in the package doc and
exercised by table-driven tests against an httptest fake — no real
GitHub traffic from CI.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 13:11:15 +05:30