diff --git a/src/renderer/src/components/settings/LinearAgentSkillPane.test.tsx b/src/renderer/src/components/settings/LinearAgentSkillPane.test.tsx
index 57395b7b28d..fac6db03bba 100644
--- a/src/renderer/src/components/settings/LinearAgentSkillPane.test.tsx
+++ b/src/renderer/src/components/settings/LinearAgentSkillPane.test.tsx
@@ -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}}')
}
})
diff --git a/src/renderer/src/components/settings/LinearAgentSkillPane.tsx b/src/renderer/src/components/settings/LinearAgentSkillPane.tsx
index c7146370c88..38dd9dd62de 100644
--- a/src/renderer/src/components/settings/LinearAgentSkillPane.tsx
+++ b/src/renderer/src/components/settings/LinearAgentSkillPane.tsx
@@ -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}
diff --git a/src/renderer/src/components/settings/SkillUsageExamplesSection.tsx b/src/renderer/src/components/settings/SkillUsageExamplesSection.tsx
index f4d615cf6bf..ecadbb44b6f 100644
--- a/src/renderer/src/components/settings/SkillUsageExamplesSection.tsx
+++ b/src/renderer/src/components/settings/SkillUsageExamplesSection.tsx
@@ -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 (
-
+
)
})}
diff --git a/src/renderer/src/hooks/useLinearProviderConnected.test.tsx b/src/renderer/src/hooks/useLinearProviderConnected.test.tsx
new file mode 100644
index 00000000000..c10afed44c5
--- /dev/null
+++ b/src/renderer/src/hooks/useLinearProviderConnected.test.tsx
@@ -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())
+
+ 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())
+
+ expect(connected).toBe(false)
+ })
+})
diff --git a/src/renderer/src/hooks/useLinearProviderConnected.ts b/src/renderer/src/hooks/useLinearProviderConnected.ts
index 52735e755dc..01896987a83 100644
--- a/src/renderer/src/hooks/useLinearProviderConnected.ts
+++ b/src/renderer/src/hooks/useLinearProviderConnected.ts
@@ -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
+ )
}
diff --git a/src/renderer/src/i18n/locales/en.json b/src/renderer/src/i18n/locales/en.json
index ea864c13e70..6b5a097d673 100644
--- a/src/renderer/src/i18n/locales/en.json
+++ b/src/renderer/src/i18n/locales/en.json
@@ -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": {
diff --git a/src/renderer/src/i18n/locales/es.json b/src/renderer/src/i18n/locales/es.json
index c198d05d8fe..e533ee41e64 100644
--- a/src/renderer/src/i18n/locales/es.json
+++ b/src/renderer/src/i18n/locales/es.json
@@ -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": {
diff --git a/src/renderer/src/i18n/locales/ja.json b/src/renderer/src/i18n/locales/ja.json
index ae240e364fe..d322e01b8e4 100644
--- a/src/renderer/src/i18n/locales/ja.json
+++ b/src/renderer/src/i18n/locales/ja.json
@@ -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": {
diff --git a/src/renderer/src/i18n/locales/ko.json b/src/renderer/src/i18n/locales/ko.json
index 8d2bb9ac40b..2f6cda47452 100644
--- a/src/renderer/src/i18n/locales/ko.json
+++ b/src/renderer/src/i18n/locales/ko.json
@@ -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": {
diff --git a/src/renderer/src/i18n/locales/zh.json b/src/renderer/src/i18n/locales/zh.json
index e14e205c838..1de024b5958 100644
--- a/src/renderer/src/i18n/locales/zh.json
+++ b/src/renderer/src/i18n/locales/zh.json
@@ -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": {
diff --git a/src/renderer/src/lib/linear-usage-examples.ts b/src/renderer/src/lib/linear-usage-examples.ts
index f5f77e33936..af6b0a5f1e8 100644
--- a/src/renderer/src/lib/linear-usage-examples.ts
+++ b/src/renderer/src/lib/linear-usage-examples.ts
@@ -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 }
+ )
}
])