mirror of
https://github.com/stablyai/orca.git
synced 2026-10-18 16:03:17 +00:00
fix(settings): tighten Linear skill section behavior
This commit is contained in:
@@ -101,6 +101,8 @@ describe('LinearAgentSkillPane', () => {
|
||||
expect(examples).toHaveLength(5)
|
||||
for (const example of examples) {
|
||||
expect(markup).toContain(example.title)
|
||||
expect(example.prompt).toContain('/orca-linear')
|
||||
expect(example.prompt).not.toContain('{{value0}}')
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -102,8 +102,14 @@ export function LinearAgentSkillPane(): React.JSX.Element {
|
||||
)}
|
||||
command={installCommand}
|
||||
installedCommand={updateCommand}
|
||||
terminalTitle="Linear skill setup"
|
||||
terminalAriaLabel="Linear skill install terminal"
|
||||
terminalTitle={translate(
|
||||
'auto.components.settings.LinearAgentSkillPane.terminalTitle',
|
||||
'Linear skill setup'
|
||||
)}
|
||||
terminalAriaLabel={translate(
|
||||
'auto.components.settings.LinearAgentSkillPane.terminalAriaLabel',
|
||||
'Linear skill install terminal'
|
||||
)}
|
||||
terminalWorktreeId="settings-linear-skill-terminal"
|
||||
terminalShellOverride={activeSkillRuntime.terminalShellOverride}
|
||||
installed={linearSkillInstalled}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useState } from 'react'
|
||||
import type { LucideIcon } from 'lucide-react'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import type { SkillUsageExample } from '@/lib/skill-usage-example'
|
||||
import { SkillUsageExampleDialog } from './SkillUsageExampleDialog'
|
||||
|
||||
@@ -31,10 +32,11 @@ export function SkillUsageExamplesSection({
|
||||
{examples.map((example) => {
|
||||
const Icon = resolveIcon(example)
|
||||
return (
|
||||
<button
|
||||
<Button
|
||||
key={example.id}
|
||||
type="button"
|
||||
className="rounded-md border border-border/60 bg-muted/20 px-4 py-3 text-left transition-colors hover:bg-muted/35 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50"
|
||||
variant="ghost"
|
||||
className="h-auto w-full justify-start whitespace-normal rounded-md border border-border/60 bg-muted/20 px-4 py-3 text-left hover:bg-muted/35 hover:text-foreground"
|
||||
onClick={() => setSelectedExampleId(example.id)}
|
||||
>
|
||||
<div className="flex items-start gap-3">
|
||||
@@ -46,7 +48,7 @@ export function SkillUsageExamplesSection({
|
||||
<p className="text-xs leading-relaxed text-muted-foreground">{example.summary}</p>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</Button>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
// @vitest-environment happy-dom
|
||||
|
||||
import { act } from 'react'
|
||||
import { createRoot, type Root } from 'react-dom/client'
|
||||
import { afterEach, describe, expect, it } from 'vitest'
|
||||
import type { LinearConnectionStatus } from '../../../shared/types'
|
||||
import { getProviderRuntimeContextKey } from '@/lib/provider-runtime-context'
|
||||
import { useAppStore } from '@/store'
|
||||
import { useLinearProviderConnected } from './useLinearProviderConnected'
|
||||
|
||||
let root: Root | null = null
|
||||
let container: HTMLDivElement | null = null
|
||||
|
||||
describe('useLinearProviderConnected', () => {
|
||||
afterEach(() => {
|
||||
if (root) {
|
||||
act(() => root?.unmount())
|
||||
}
|
||||
root = null
|
||||
container?.remove()
|
||||
container = null
|
||||
useAppStore.setState({
|
||||
linearStatus: { connected: false, viewer: null },
|
||||
linearStatusContextKey: null
|
||||
})
|
||||
})
|
||||
|
||||
it('does not rerender for Linear metadata changes that preserve section visibility', () => {
|
||||
const settings = useAppStore.getState().settings
|
||||
useAppStore.setState({
|
||||
linearStatus: { connected: true, viewer: null },
|
||||
linearStatusContextKey: getProviderRuntimeContextKey(settings)
|
||||
})
|
||||
let renders = 0
|
||||
let connected = false
|
||||
|
||||
function Probe(): null {
|
||||
renders += 1
|
||||
connected = useLinearProviderConnected()
|
||||
return null
|
||||
}
|
||||
|
||||
container = document.createElement('div')
|
||||
document.body.appendChild(container)
|
||||
root = createRoot(container)
|
||||
act(() => root?.render(<Probe />))
|
||||
|
||||
expect(connected).toBe(true)
|
||||
expect(renders).toBe(1)
|
||||
|
||||
act(() => {
|
||||
useAppStore.setState({
|
||||
linearStatus: {
|
||||
...useAppStore.getState().linearStatus,
|
||||
selectedWorkspaceId: 'workspace-2'
|
||||
} satisfies LinearConnectionStatus
|
||||
})
|
||||
})
|
||||
|
||||
expect(connected).toBe(true)
|
||||
expect(renders).toBe(1)
|
||||
|
||||
act(() => {
|
||||
useAppStore.setState({ linearStatus: { connected: false, viewer: null } })
|
||||
})
|
||||
|
||||
expect(connected).toBe(false)
|
||||
expect(renders).toBe(2)
|
||||
})
|
||||
|
||||
it('rejects a connected status from a different runtime context', () => {
|
||||
useAppStore.setState({
|
||||
linearStatus: { connected: true, viewer: null },
|
||||
linearStatusContextKey: 'stale-runtime-context'
|
||||
})
|
||||
let connected = true
|
||||
|
||||
function Probe(): null {
|
||||
connected = useLinearProviderConnected()
|
||||
return null
|
||||
}
|
||||
|
||||
container = document.createElement('div')
|
||||
document.body.appendChild(container)
|
||||
root = createRoot(container)
|
||||
act(() => root?.render(<Probe />))
|
||||
|
||||
expect(connected).toBe(false)
|
||||
})
|
||||
})
|
||||
@@ -6,8 +6,11 @@ import { useAppStore } from '@/store'
|
||||
// the rendered section from drifting. The context-key guard rejects a status
|
||||
// fetched for a different runtime environment than the active one.
|
||||
export function useLinearProviderConnected(): boolean {
|
||||
const linearStatus = useAppStore((s) => s.linearStatus)
|
||||
const linearStatusContextKey = useAppStore((s) => s.linearStatusContextKey)
|
||||
const settings = useAppStore((s) => s.settings)
|
||||
return linearStatusContextKey === getProviderRuntimeContextKey(settings) && linearStatus.connected
|
||||
// Why: Cmd+J keeps this hook mounted globally; project to the visibility bit so
|
||||
// unrelated Linear metadata and settings updates do not rerender the palette.
|
||||
return useAppStore(
|
||||
(state) =>
|
||||
state.linearStatusContextKey === getProviderRuntimeContextKey(state.settings) &&
|
||||
state.linearStatus.connected
|
||||
)
|
||||
}
|
||||
|
||||
@@ -619,7 +619,17 @@
|
||||
"postUpdate": "Post a progress update",
|
||||
"moveState": "Move the ticket forward",
|
||||
"attachPr": "Attach the PR link",
|
||||
"triageFollowups": "Triage and create follow-ups"
|
||||
"triageFollowups": "Triage and create follow-ups",
|
||||
"readTicketSummary": "Pull the linked Linear issue's full context before starting work.",
|
||||
"readTicketPrompt": "Use {{value0}} to read the linked Linear issue for this worktree, then summarize the goal and acceptance criteria before you start.",
|
||||
"postUpdateSummary": "Comment progress or a completion summary back to the Linear issue.",
|
||||
"postUpdatePrompt": "Use {{value0}} to post a completion update on the linked Linear issue with what changed and how it was verified.",
|
||||
"moveStateSummary": "Advance the Linear workflow state as the work progresses.",
|
||||
"moveStatePrompt": "Use {{value0}} to move the linked Linear issue to In Review now that the change is ready.",
|
||||
"attachPrSummary": "Link the pull request to the Linear issue when you open it.",
|
||||
"attachPrPrompt": "Use {{value0}} to attach this PR to the linked Linear issue with a PR link.",
|
||||
"triageFollowupsSummary": "Set assignee, priority, or estimate, and file parented follow-up tickets.",
|
||||
"triageFollowupsPrompt": "Use {{value0}} to triage the linked Linear issue — set priority and estimate — and create a parented follow-up ticket for the deferred cleanup."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9217,7 +9227,9 @@
|
||||
"skillTitle": "Linear skill",
|
||||
"skillDescription": "Enables agents to read linked tickets and post updates to Linear through Orca.",
|
||||
"howToUse": "How to use it",
|
||||
"howToUseDescription": "Ask an agent working a Linear-linked worktree to read context, post updates, move the ticket, or attach the PR."
|
||||
"howToUseDescription": "Ask an agent working a Linear-linked worktree to read context, post updates, move the ticket, or attach the PR.",
|
||||
"terminalTitle": "Linear skill setup",
|
||||
"terminalAriaLabel": "Linear skill install terminal"
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
|
||||
@@ -596,7 +596,17 @@
|
||||
"postUpdate": "Post a progress update",
|
||||
"moveState": "Move the ticket forward",
|
||||
"attachPr": "Attach the PR link",
|
||||
"triageFollowups": "Triage and create follow-ups"
|
||||
"triageFollowups": "Triage and create follow-ups",
|
||||
"readTicketSummary": "Pull the linked Linear issue's full context before starting work.",
|
||||
"readTicketPrompt": "Use {{value0}} to read the linked Linear issue for this worktree, then summarize the goal and acceptance criteria before you start.",
|
||||
"postUpdateSummary": "Comment progress or a completion summary back to the Linear issue.",
|
||||
"postUpdatePrompt": "Use {{value0}} to post a completion update on the linked Linear issue with what changed and how it was verified.",
|
||||
"moveStateSummary": "Advance the Linear workflow state as the work progresses.",
|
||||
"moveStatePrompt": "Use {{value0}} to move the linked Linear issue to In Review now that the change is ready.",
|
||||
"attachPrSummary": "Link the pull request to the Linear issue when you open it.",
|
||||
"attachPrPrompt": "Use {{value0}} to attach this PR to the linked Linear issue with a PR link.",
|
||||
"triageFollowupsSummary": "Set assignee, priority, or estimate, and file parented follow-up tickets.",
|
||||
"triageFollowupsPrompt": "Use {{value0}} to triage the linked Linear issue — set priority and estimate — and create a parented follow-up ticket for the deferred cleanup."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9194,7 +9204,9 @@
|
||||
"skillTitle": "Linear skill",
|
||||
"skillDescription": "Enables agents to read linked tickets and post updates to Linear through Orca.",
|
||||
"howToUse": "How to use it",
|
||||
"howToUseDescription": "Ask an agent working a Linear-linked worktree to read context, post updates, move the ticket, or attach the PR."
|
||||
"howToUseDescription": "Ask an agent working a Linear-linked worktree to read context, post updates, move the ticket, or attach the PR.",
|
||||
"terminalTitle": "Linear skill setup",
|
||||
"terminalAriaLabel": "Linear skill install terminal"
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
|
||||
@@ -596,7 +596,17 @@
|
||||
"postUpdate": "Post a progress update",
|
||||
"moveState": "Move the ticket forward",
|
||||
"attachPr": "Attach the PR link",
|
||||
"triageFollowups": "Triage and create follow-ups"
|
||||
"triageFollowups": "Triage and create follow-ups",
|
||||
"readTicketSummary": "Pull the linked Linear issue's full context before starting work.",
|
||||
"readTicketPrompt": "Use {{value0}} to read the linked Linear issue for this worktree, then summarize the goal and acceptance criteria before you start.",
|
||||
"postUpdateSummary": "Comment progress or a completion summary back to the Linear issue.",
|
||||
"postUpdatePrompt": "Use {{value0}} to post a completion update on the linked Linear issue with what changed and how it was verified.",
|
||||
"moveStateSummary": "Advance the Linear workflow state as the work progresses.",
|
||||
"moveStatePrompt": "Use {{value0}} to move the linked Linear issue to In Review now that the change is ready.",
|
||||
"attachPrSummary": "Link the pull request to the Linear issue when you open it.",
|
||||
"attachPrPrompt": "Use {{value0}} to attach this PR to the linked Linear issue with a PR link.",
|
||||
"triageFollowupsSummary": "Set assignee, priority, or estimate, and file parented follow-up tickets.",
|
||||
"triageFollowupsPrompt": "Use {{value0}} to triage the linked Linear issue — set priority and estimate — and create a parented follow-up ticket for the deferred cleanup."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9194,7 +9204,9 @@
|
||||
"skillTitle": "Linear skill",
|
||||
"skillDescription": "Enables agents to read linked tickets and post updates to Linear through Orca.",
|
||||
"howToUse": "How to use it",
|
||||
"howToUseDescription": "Ask an agent working a Linear-linked worktree to read context, post updates, move the ticket, or attach the PR."
|
||||
"howToUseDescription": "Ask an agent working a Linear-linked worktree to read context, post updates, move the ticket, or attach the PR.",
|
||||
"terminalTitle": "Linear skill setup",
|
||||
"terminalAriaLabel": "Linear skill install terminal"
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
|
||||
@@ -596,7 +596,17 @@
|
||||
"postUpdate": "Post a progress update",
|
||||
"moveState": "Move the ticket forward",
|
||||
"attachPr": "Attach the PR link",
|
||||
"triageFollowups": "Triage and create follow-ups"
|
||||
"triageFollowups": "Triage and create follow-ups",
|
||||
"readTicketSummary": "Pull the linked Linear issue's full context before starting work.",
|
||||
"readTicketPrompt": "Use {{value0}} to read the linked Linear issue for this worktree, then summarize the goal and acceptance criteria before you start.",
|
||||
"postUpdateSummary": "Comment progress or a completion summary back to the Linear issue.",
|
||||
"postUpdatePrompt": "Use {{value0}} to post a completion update on the linked Linear issue with what changed and how it was verified.",
|
||||
"moveStateSummary": "Advance the Linear workflow state as the work progresses.",
|
||||
"moveStatePrompt": "Use {{value0}} to move the linked Linear issue to In Review now that the change is ready.",
|
||||
"attachPrSummary": "Link the pull request to the Linear issue when you open it.",
|
||||
"attachPrPrompt": "Use {{value0}} to attach this PR to the linked Linear issue with a PR link.",
|
||||
"triageFollowupsSummary": "Set assignee, priority, or estimate, and file parented follow-up tickets.",
|
||||
"triageFollowupsPrompt": "Use {{value0}} to triage the linked Linear issue — set priority and estimate — and create a parented follow-up ticket for the deferred cleanup."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9194,7 +9204,9 @@
|
||||
"skillTitle": "Linear skill",
|
||||
"skillDescription": "Enables agents to read linked tickets and post updates to Linear through Orca.",
|
||||
"howToUse": "How to use it",
|
||||
"howToUseDescription": "Ask an agent working a Linear-linked worktree to read context, post updates, move the ticket, or attach the PR."
|
||||
"howToUseDescription": "Ask an agent working a Linear-linked worktree to read context, post updates, move the ticket, or attach the PR.",
|
||||
"terminalTitle": "Linear skill setup",
|
||||
"terminalAriaLabel": "Linear skill install terminal"
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
|
||||
@@ -596,7 +596,17 @@
|
||||
"postUpdate": "Post a progress update",
|
||||
"moveState": "Move the ticket forward",
|
||||
"attachPr": "Attach the PR link",
|
||||
"triageFollowups": "Triage and create follow-ups"
|
||||
"triageFollowups": "Triage and create follow-ups",
|
||||
"readTicketSummary": "Pull the linked Linear issue's full context before starting work.",
|
||||
"readTicketPrompt": "Use {{value0}} to read the linked Linear issue for this worktree, then summarize the goal and acceptance criteria before you start.",
|
||||
"postUpdateSummary": "Comment progress or a completion summary back to the Linear issue.",
|
||||
"postUpdatePrompt": "Use {{value0}} to post a completion update on the linked Linear issue with what changed and how it was verified.",
|
||||
"moveStateSummary": "Advance the Linear workflow state as the work progresses.",
|
||||
"moveStatePrompt": "Use {{value0}} to move the linked Linear issue to In Review now that the change is ready.",
|
||||
"attachPrSummary": "Link the pull request to the Linear issue when you open it.",
|
||||
"attachPrPrompt": "Use {{value0}} to attach this PR to the linked Linear issue with a PR link.",
|
||||
"triageFollowupsSummary": "Set assignee, priority, or estimate, and file parented follow-up tickets.",
|
||||
"triageFollowupsPrompt": "Use {{value0}} to triage the linked Linear issue — set priority and estimate — and create a parented follow-up ticket for the deferred cleanup."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9194,7 +9204,9 @@
|
||||
"skillTitle": "Linear skill",
|
||||
"skillDescription": "Enables agents to read linked tickets and post updates to Linear through Orca.",
|
||||
"howToUse": "How to use it",
|
||||
"howToUseDescription": "Ask an agent working a Linear-linked worktree to read context, post updates, move the ticket, or attach the PR."
|
||||
"howToUseDescription": "Ask an agent working a Linear-linked worktree to read context, post updates, move the ticket, or attach the PR.",
|
||||
"terminalTitle": "Linear skill setup",
|
||||
"terminalAriaLabel": "Linear skill install terminal"
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
|
||||
@@ -1,34 +1,62 @@
|
||||
import { translate } from '@/i18n/i18n'
|
||||
import { createLocalizedCatalog } from '@/i18n/localized-catalog'
|
||||
import { ORCA_LINEAR_SKILL_NAME } from './agent-feature-install-commands'
|
||||
import type { SkillUsageExample } from './skill-usage-example'
|
||||
|
||||
const LINEAR_SLASH_COMMAND = `/${ORCA_LINEAR_SKILL_NAME}`
|
||||
|
||||
export const getLinearUsageExamples = createLocalizedCatalog((): SkillUsageExample[] => [
|
||||
{
|
||||
id: 'read-ticket',
|
||||
title: translate('auto.lib.linear.usage.examples.readTicket', 'Read the linked ticket'),
|
||||
summary: "Pull the linked Linear issue's full context before starting work.",
|
||||
prompt:
|
||||
'Use /orca-linear to read the linked Linear issue for this worktree, then summarize the goal and acceptance criteria before you start.'
|
||||
summary: translate(
|
||||
'auto.lib.linear.usage.examples.readTicketSummary',
|
||||
"Pull the linked Linear issue's full context before starting work."
|
||||
),
|
||||
prompt: translate(
|
||||
'auto.lib.linear.usage.examples.readTicketPrompt',
|
||||
'Use {{value0}} to read the linked Linear issue for this worktree, then summarize the goal and acceptance criteria before you start.',
|
||||
{ value0: LINEAR_SLASH_COMMAND }
|
||||
)
|
||||
},
|
||||
{
|
||||
id: 'post-update',
|
||||
title: translate('auto.lib.linear.usage.examples.postUpdate', 'Post a progress update'),
|
||||
summary: 'Comment progress or a completion summary back to the Linear issue.',
|
||||
prompt:
|
||||
'Use /orca-linear to post a completion update on the linked Linear issue with what changed and how it was verified.'
|
||||
summary: translate(
|
||||
'auto.lib.linear.usage.examples.postUpdateSummary',
|
||||
'Comment progress or a completion summary back to the Linear issue.'
|
||||
),
|
||||
prompt: translate(
|
||||
'auto.lib.linear.usage.examples.postUpdatePrompt',
|
||||
'Use {{value0}} to post a completion update on the linked Linear issue with what changed and how it was verified.',
|
||||
{ value0: LINEAR_SLASH_COMMAND }
|
||||
)
|
||||
},
|
||||
{
|
||||
id: 'move-state',
|
||||
title: translate('auto.lib.linear.usage.examples.moveState', 'Move the ticket forward'),
|
||||
summary: 'Advance the Linear workflow state as the work progresses.',
|
||||
prompt:
|
||||
'Use /orca-linear to move the linked Linear issue to In Review now that the change is ready.'
|
||||
summary: translate(
|
||||
'auto.lib.linear.usage.examples.moveStateSummary',
|
||||
'Advance the Linear workflow state as the work progresses.'
|
||||
),
|
||||
prompt: translate(
|
||||
'auto.lib.linear.usage.examples.moveStatePrompt',
|
||||
'Use {{value0}} to move the linked Linear issue to In Review now that the change is ready.',
|
||||
{ value0: LINEAR_SLASH_COMMAND }
|
||||
)
|
||||
},
|
||||
{
|
||||
id: 'attach-pr',
|
||||
title: translate('auto.lib.linear.usage.examples.attachPr', 'Attach the PR link'),
|
||||
summary: 'Link the pull request to the Linear issue when you open it.',
|
||||
prompt: 'Use /orca-linear to attach this PR to the linked Linear issue with a PR link.'
|
||||
summary: translate(
|
||||
'auto.lib.linear.usage.examples.attachPrSummary',
|
||||
'Link the pull request to the Linear issue when you open it.'
|
||||
),
|
||||
prompt: translate(
|
||||
'auto.lib.linear.usage.examples.attachPrPrompt',
|
||||
'Use {{value0}} to attach this PR to the linked Linear issue with a PR link.',
|
||||
{ value0: LINEAR_SLASH_COMMAND }
|
||||
)
|
||||
},
|
||||
{
|
||||
id: 'triage-followups',
|
||||
@@ -36,8 +64,14 @@ export const getLinearUsageExamples = createLocalizedCatalog((): SkillUsageExamp
|
||||
'auto.lib.linear.usage.examples.triageFollowups',
|
||||
'Triage and create follow-ups'
|
||||
),
|
||||
summary: 'Set assignee, priority, or estimate, and file parented follow-up tickets.',
|
||||
prompt:
|
||||
'Use /orca-linear to triage the linked Linear issue — set priority and estimate — and create a parented follow-up ticket for the deferred cleanup.'
|
||||
summary: translate(
|
||||
'auto.lib.linear.usage.examples.triageFollowupsSummary',
|
||||
'Set assignee, priority, or estimate, and file parented follow-up tickets.'
|
||||
),
|
||||
prompt: translate(
|
||||
'auto.lib.linear.usage.examples.triageFollowupsPrompt',
|
||||
'Use {{value0}} to triage the linked Linear issue — set priority and estimate — and create a parented follow-up ticket for the deferred cleanup.',
|
||||
{ value0: LINEAR_SLASH_COMMAND }
|
||||
)
|
||||
}
|
||||
])
|
||||
|
||||
Reference in New Issue
Block a user