Commit Graph
7 Commits
Author SHA1 Message Date
Jinjing dba35c7bfd Keep cached linkedIssue when metadata is unavailable
Return undefined from getWorktreeLinkedIssue when live metadata cannot be read
(store not ready), distinguishing it from null (unlinked). The caller now falls
back to the cached worktree value instead of treating unavailable as unlinked.

Also extract the linked-issue echo generator as a shared e2e test helper.
2026-07-25 19:31:30 -07:00
Jinjing f17c509be4 fix(source-control-ai): make the {linkedIssue} e2e guard and dialog test falsifiable
The e2e unlinked case extracted the echoed issue with `ORCA_E2E_ISSUE=(\d*)`,
which matches zero digits in front of an unexpanded `{linkedIssue}` and reported
it as `empty` — so the case that exists to catch a literal token surviving into
a prompt passed on exactly that regression. Capture the whole line instead: a
literal now arrives as `saw-issue:{linkedIssue}` and fails, verified by dropping
the substitution key for unlinked contexts and watching the case go red.

Also drop the inert `not.toContain('Command input is empty.')` assertion — that
copy is click-driven `generationError` state and this suite renders statically,
so it could never fail; the claim it reached for is carried by the plan test.
Rename two plan tests off the "plan preview" framing the design now rejects.

Local review artifacts (design doc, implementation notes, final review) were
swept to match the tree in the same pass; they are gitignored here.
2026-07-25 14:34:32 -07:00
Jinjing 0d9eeed7a9 fix(source-control-ai): resolve {linkedIssue} adversarial re-review findings
Addresses all 8 findings from the {linkedIssue} code re-review
(2 minor, 6 nit, 0 critical, 0 major); none deferred.

Behavior:
- Revert the variableOverrides parameter on planSourceControlTextGeneration.
  Its result is a Save/Generate gate, not a preview, and the recipe it
  validates is saved repo- or globally scoped -- so rendering it against the
  active workspace disabled both buttons with "Command input is empty." for a
  {linkedIssue}-only template on any unlinked workspace, blocking a global
  settings write. Validation is synthetic again; chip previews are unchanged.
- Make the chip hover card additive instead of either/or. A supplied preview
  now appends a "This workspace" sample below the description and Example
  rather than replacing them, so the GitLab-empty and dangling `Fixes #`
  warning survives on the two dialogs where recipes are actually authored.
  basePrompt keeps its preview-only shape, where the preview is the content.

Structure:
- Drop the registry re-export from source-control-ai-actions.ts and move the
  last two consumers onto source-control-ai-action-variables, so one import
  path per symbol keeps a grep of the registry's consumers complete.
- Split the registry/helper suites into source-control-ai-action-variables.test.ts
  so each test file mirrors its module.

Tests:
- Cover the Save/Generate gate at the canRunGeneration level for a bare
  {linkedIssue} recipe on linked and unlinked workspaces, with a negative
  control proving the buttons can still be disabled.
- Cover the chip hover card directly; the dialog tests mock it away.
- Guard the PR mismatched-id test with toHaveLength(1) so it cannot pass
  vacuously on an unrelated early return.
- Add an unlinked-workspace e2e case (saw-issue:empty), which is what
  distinguishes a real resolver from one that always returns a number.
  Spec now runs green: 3 passed.
- Rename the dialog test that claimed a synthetic-fallback assertion it did
  not make, and route its renders through one shared helper.

Docs are worktree-local (.gitignore:84 ignores docs/**): the design doc's
plan-preview and chip-surface claims, the manual QA rows, and both reviews'
statements about pre-existing PR-handler tests are corrected there.
2026-07-25 14:06:19 -07:00
JinjingandOrca d9d09f2eae fix(source-control-ai): resolve {linkedIssue} adversarial review findings
Addresses 13 of the 14 findings from the {linkedIssue} code review
(6 minor, 8 nit, 0 critical, 0 major); Issue 5 (GitLab provider naming)
is deferred to design Open Question 3 as product expansion.

Behavior:
- Dialog previews the workspace's real linked issue instead of the
  synthetic 123, in both the chip hover card and the plan preview, so an
  unlinked workspace previews the `Fixes #` it will actually generate.
  Settings dry-runs stay fully synthetic.
- Reject non-positive, fractional and unsafe-integer issue numbers at the
  IPC resolver via a shared isLinkedIssueNumber predicate, so corrupt meta
  never reaches a draft context (previously -7 rendered `Fixes #-7` and
  1e21 rendered `Fixes #1e+21`).
- Fail closed on an empty-string repoId instead of skipping the cross-check.

Structure:
- Split the variable registry into source-control-ai-action-variables.ts
  and re-export it, restoring max-lines headroom with no consumer churn
  and no lint disable.
- Constrain withLinkedIssueDraftContext to contexts declaring linkedIssue.
- Move the misplaced shared imports into their import group.

Docs and tests:
- Document that the IPC id/path validator guards relay/CLI/future callers,
  not the renderer (whose path is id-derived), and rename the three tests
  that read as proof of a protection that cannot fire.
- Add PR-side coverage that was missing: three git:generatePullRequestFields
  handler tests, a built-in PR prompt no-leak guard, and the runtime PR
  unlinked case.
- Replace the coincidental '42' assertion with a fixture-unique sentinel.
- Type the runtime worktree fixture with satisfies, which surfaced and
  fixed pre-existing drift in its git sub-object.
- Add an e2e case covering the preload -> main -> meta -> template chain.

Co-authored-by: Orca <help@stably.ai>
2026-07-25 13:30:30 -07:00
Brennan BensonandOrca b58c0a42da Fix stale and race-prone E2E test failures (#7468)
Co-authored-by: Orca <help@stably.ai>
2026-07-05 19:46:49 -07:00
NeilandOrca 46646d7ff1 chore(lint): upgrade oxlint to 1.71 + enable 7 new rules (autofixed backlog) (#6841)
* chore(lint): upgrade oxlint to 1.71 and enable 7 new rules

Upgrade oxlint 1.67.0 -> 1.71.0 (1.72 was blocked by the repo's 3-day
minimum-release-age supply-chain guard; nothing here needs it). The
bump is a no-op on the existing config.

Enable 3 error rules (backlog autofixed to zero in this commit) and
4 warn rules (surface signal without gating CI):

error (autofixed, behavior-preserving):
- unicorn/prefer-node-protocol        (~1531 sites: bare builtin -> node:)
- typescript/no-import-type-side-effects (~36: all-inline-type -> import type)
- unicorn/no-array-reverse            (19: copy-then-reverse -> toReversed)

warn (real signal, current fires are test-only/correct):
- unicorn/no-array-fill-with-reference-type  (aliasing footgun guard)
- typescript/no-unsafe-function-type         (bans bare Function type)
- unicorn/prefer-array-flat-map              (map().flat() -> flatMap())
- unicorn/prefer-regexp-test                 (.match() in bool ctx -> .test())

mobile/.oxlintrc.json extends root, so it inherits all 7; the autofix
ran from root and covered mobile/ too.

Verification (all green): oxlint 0 errors (root+mobile+aux configs),
oxfmt clean, typecheck (node+cli+web), vitest 22795 passed / 0 failed,
builds (electron-vite + web + cli) succeed. node: rewrites confirmed to
skip embedded SSH/CLI string payloads (AST-only); all toReversed sites
verified to operate on fresh copies or write-once locals.

* chore(lint): bump mobile oxlint to 1.71 so inherited rules parse

mobile/ is a standalone pnpm project pinning its own oxlint@1.67, which
lacks unicorn/no-array-fill-with-reference-type (needs >=1.70). Since
mobile/.oxlintrc.json extends the root config, mobile CI's 'cd mobile &&
oxlint' failed to parse the new rule. Bump mobile to match root (1.71).

Verified in mobile/: oxlint 0 errors, oxfmt --check clean, tsc --noEmit
pass, vitest 978 passed / 0 failed.

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
2026-06-29 22:38:29 -07:00
b030257c3b feat(source-control): AI commit message generation (#1487)
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: brennanb2025 <brennankbenson@gmail.com>
2026-05-15 02:18:46 -07:00