mirror of
https://github.com/stablyai/orca.git
synced 2026-10-27 16:02:42 +00:00
Merge remote-tracking branch 'origin/main' into nwparker/guard-add-repo-nested-import-state
# Conflicts: # src/renderer/src/components/sidebar/AddRepoDialog.tsx
This commit is contained in:
@@ -213,6 +213,18 @@ function Settings(): React.JSX.Element {
|
||||
const repoHooksRuntimeIdentityRef = useRef<string>('local')
|
||||
const shortcutsEscapeConfirmUntilRef = useRef(0)
|
||||
|
||||
const setSettingsRootNode = useCallback(
|
||||
(node: HTMLDivElement | null): void => {
|
||||
if (node) {
|
||||
return
|
||||
}
|
||||
// Why: the settings search is a transient in-page filter. Leaving it behind makes the next
|
||||
// visit look partially broken because whole sections stay hidden before the user types again.
|
||||
setSettingsSearchQuery('')
|
||||
},
|
||||
[setSettingsSearchQuery]
|
||||
)
|
||||
|
||||
const confirmDiscardCommitPromptChanges = useCallback(async (): Promise<boolean> => {
|
||||
if (!hasUnsavedCommitPromptChanges) {
|
||||
return true
|
||||
@@ -339,15 +351,6 @@ function Settings(): React.JSX.Element {
|
||||
return () => document.removeEventListener('keydown', handleFindShortcut)
|
||||
}, [keybindings])
|
||||
|
||||
useEffect(
|
||||
() => () => {
|
||||
// Why: the settings search is a transient in-page filter. Leaving it behind makes the next
|
||||
// visit look partially broken because whole sections stay hidden before the user types again.
|
||||
setSettingsSearchQuery('')
|
||||
},
|
||||
[setSettingsSearchQuery]
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (!settings || !settingsNavigationTarget) {
|
||||
return
|
||||
@@ -694,8 +697,13 @@ function Settings(): React.JSX.Element {
|
||||
|
||||
if (!settings) {
|
||||
return (
|
||||
<div className="flex flex-1 items-center justify-center text-muted-foreground">
|
||||
Loading settings...
|
||||
<div
|
||||
ref={setSettingsRootNode}
|
||||
className="settings-view-shell flex min-h-0 flex-1 overflow-hidden bg-background"
|
||||
>
|
||||
<div className="flex flex-1 items-center justify-center text-muted-foreground">
|
||||
Loading settings...
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -721,7 +729,10 @@ function Settings(): React.JSX.Element {
|
||||
activeSectionId === 'shortcuts' && settingsSearchQuery.trim() === ''
|
||||
|
||||
return (
|
||||
<div className="settings-view-shell flex min-h-0 flex-1 overflow-hidden bg-background">
|
||||
<div
|
||||
ref={setSettingsRootNode}
|
||||
className="settings-view-shell flex min-h-0 flex-1 overflow-hidden bg-background"
|
||||
>
|
||||
<SettingsSidebar
|
||||
activeSectionId={activeSectionId}
|
||||
generalGroups={generalNavGroups}
|
||||
|
||||
@@ -118,6 +118,9 @@ const AddRepoDialog = React.memo(function AddRepoDialog() {
|
||||
// Why: nested group import can create many repos; resetState must prevent
|
||||
// stale import completions from reopening setup UI after Back/close.
|
||||
const nestedImportGenRef = useRef(0)
|
||||
// Why: setup actions can await settings/worktree refreshes; resetState
|
||||
// cancels stale continuations when the setup step is dismissed.
|
||||
const setupActionGenRef = useRef(0)
|
||||
// Why: a dropped path is modal data, so ordinary state updates must not
|
||||
// re-run the import while the Add Project dialog advances through steps.
|
||||
const droppedLocalPathHandledRef = useRef<string | null>(null)
|
||||
@@ -252,6 +255,7 @@ const AddRepoDialog = React.memo(function AddRepoDialog() {
|
||||
localAddGenRef.current++
|
||||
serverAddGenRef.current++
|
||||
nestedImportGenRef.current++
|
||||
setupActionGenRef.current++
|
||||
// Why: kill the git clone process if one is running, so backing out
|
||||
// or closing the dialog doesn't leave a clone running on disk.
|
||||
void window.api.repos.cloneAbort()
|
||||
@@ -736,13 +740,20 @@ const AddRepoDialog = React.memo(function AddRepoDialog() {
|
||||
if (!projectId) {
|
||||
return
|
||||
}
|
||||
const gen = ++setupActionGenRef.current
|
||||
trackSetupAction('open_existing')
|
||||
if (!otherWorktreesVisible) {
|
||||
const updated = await updateRepo(projectId, { externalWorktreeVisibility: 'show' })
|
||||
if (gen !== setupActionGenRef.current) {
|
||||
return
|
||||
}
|
||||
if (updated && addedRepo) {
|
||||
setAddedRepo({ ...addedRepo, externalWorktreeVisibility: 'show' })
|
||||
}
|
||||
await fetchWorktrees(projectId)
|
||||
if (gen !== setupActionGenRef.current) {
|
||||
return
|
||||
}
|
||||
}
|
||||
await finishImportedRepoWithoutOpening()
|
||||
}, [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { renderToStaticMarkup } from 'react-dom/server'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import CommentMarkdown from './CommentMarkdown'
|
||||
import CommentMarkdown, { remarkGitHubReferences } from './CommentMarkdown'
|
||||
|
||||
describe('CommentMarkdown', () => {
|
||||
it('autolinks same-repo GitHub issue references when repo context is provided', () => {
|
||||
@@ -42,6 +42,33 @@ describe('CommentMarkdown', () => {
|
||||
expect(markup).not.toContain('href="https://github.com/stablyai/orca/issues/2317"')
|
||||
})
|
||||
|
||||
it('autolinks very large generated GitHub reference comments', () => {
|
||||
const referenceCount = 130_000
|
||||
const tree = {
|
||||
type: 'root',
|
||||
children: [
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
value: Array.from({ length: referenceCount }, (_, index) => `#${index + 1}`).join(' ')
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
const transform = remarkGitHubReferences({ owner: 'stablyai', repo: 'orca' })()
|
||||
|
||||
expect(() => transform(tree)).not.toThrow()
|
||||
expect(tree.children[0]?.children).toHaveLength(referenceCount * 2 - 1)
|
||||
expect(tree.children[0]?.children[0]).toMatchObject({
|
||||
type: 'link',
|
||||
url: 'https://github.com/stablyai/orca/issues/1'
|
||||
})
|
||||
})
|
||||
|
||||
it('contains long PR body markdown inside its available width', () => {
|
||||
const markup = renderToStaticMarkup(
|
||||
<CommentMarkdown
|
||||
|
||||
@@ -265,7 +265,11 @@ function transformGitHubReferenceChildren(
|
||||
const nextChildren: MarkdownNode[] = []
|
||||
for (const child of node.children) {
|
||||
if (child.type === 'text' && child.value !== undefined) {
|
||||
nextChildren.push(...splitGitHubReferenceText(child.value, defaultRepo))
|
||||
// Why: generated agent comments can contain thousands of issue refs;
|
||||
// appending iteratively avoids V8's argument-list limit.
|
||||
for (const part of splitGitHubReferenceText(child.value, defaultRepo)) {
|
||||
nextChildren.push(part)
|
||||
}
|
||||
} else {
|
||||
transformGitHubReferenceChildren(child, defaultRepo)
|
||||
nextChildren.push(child)
|
||||
|
||||
Reference in New Issue
Block a user