diff --git a/src/renderer/src/components/automations/AutomationDestinationField.test.tsx b/src/renderer/src/components/automations/AutomationDestinationField.test.tsx
index 48eff9cc900..cc46c81873f 100644
--- a/src/renderer/src/components/automations/AutomationDestinationField.test.tsx
+++ b/src/renderer/src/components/automations/AutomationDestinationField.test.tsx
@@ -61,12 +61,10 @@ const LEGACY_ENTRY: AutomationHostCatalogEntry = {
function control(
projects: Repo[],
- entries: AutomationHostCatalogEntry[] = [ENTRY],
- note?: string
+ entries: AutomationHostCatalogEntry[] = [ENTRY]
): AutomationCreateDestinationControl {
return {
entries,
- note,
resolution: {
status: 'ready',
authority: OWNER.authority,
@@ -78,11 +76,11 @@ function control(
}
}
-function render(projects: Repo[], entries?: AutomationHostCatalogEntry[], note?: string): void {
+function render(projects: Repo[], entries?: AutomationHostCatalogEntry[]): void {
act(() => {
root.render(
-
+
)
})
@@ -119,16 +117,6 @@ describe('AutomationDestinationField', () => {
expect(container.querySelector('[data-testid="automation-create-update-required"]')).toBeNull()
})
- it('states a move in place of the host it would otherwise just name', () => {
- render([{ id: 'repo-1' } as Repo], undefined, 'Saving creates this automation on GPU box.')
-
- // Both lines name the same host; the one that mentions the delete wins.
- expect(container.querySelector('[data-testid="automation-host-move"]')?.textContent).toContain(
- 'GPU box'
- )
- expect(container.textContent).not.toContain('Stored and scheduled by')
- })
-
it('names the host without a tense, so editing reads as a move', () => {
render([{ id: 'repo-1' } as Repo])
diff --git a/src/renderer/src/components/automations/AutomationDestinationField.tsx b/src/renderer/src/components/automations/AutomationDestinationField.tsx
index 0f222f1dd5f..f7956e55c0d 100644
--- a/src/renderer/src/components/automations/AutomationDestinationField.tsx
+++ b/src/renderer/src/components/automations/AutomationDestinationField.tsx
@@ -20,8 +20,7 @@ import { groupAutomationHostEntriesByAuthority } from './automation-host-picker-
import type { AutomationCreateDestinationControl } from './use-automation-create-destination'
// The host that stores and schedules the automation, not the workspace's
-// execution host — the two routinely differ. Serves create and edit alike; on an
-// existing record a save that lands elsewhere is a move.
+// execution host — the two routinely differ.
export function AutomationDestinationField({
control,
@@ -79,12 +78,6 @@ export function AutomationDestinationField({
'No projects are set up on {host}. Add one there, or choose another host.'
).replace('{host}', selected.label)}
- ) : control.note ? (
- // Replaces the storedOn line: both name the same host, and the move is
- // the consequential half.
-
- {control.note}
-
) : (
{selected
diff --git a/src/renderer/src/components/automations/AutomationsPage.create-destination.test.tsx b/src/renderer/src/components/automations/AutomationsPage.create-destination.test.tsx
index d10a6441c98..fb9b359ec1d 100644
--- a/src/renderer/src/components/automations/AutomationsPage.create-destination.test.tsx
+++ b/src/renderer/src/components/automations/AutomationsPage.create-destination.test.tsx
@@ -414,7 +414,7 @@ describe('AutomationsPage edit dialog projects', () => {
})
describe('AutomationsPage edit destination', () => {
- it('names the edited row’s own host, and offers every host it could move to', async () => {
+ it('names the edited row’s own host, and only its authority’s hosts', async () => {
const automation = makeAutomation({ id: 'a-1' })
api.automations.list.mockResolvedValue([])
scopedList([automation])
@@ -430,84 +430,11 @@ describe('AutomationsPage edit destination', () => {
const resolution = mocks.editorDialog?.editDestination?.resolution
expect(resolution?.status === 'ready' && resolution.entry.stableKey).toBe(DESKTOP_SELF_KEY)
- // Another authority is a legal destination — reached by a create there and a
- // delete here — so restricting the list to this one would hide a real move.
- expect(mocks.editorDialog?.editDestination?.entries.map((entry) => entry.stableKey)).toContain(
- RUNTIME_SELF_KEY
- )
- expect(mocks.editorDialog?.editDestination?.note).toBeFalsy()
- })
-
- it('moves the record across authorities by creating there and deleting here', async () => {
- const automation = makeAutomation({ id: 'a-1' })
- api.automations.list.mockResolvedValue([])
- scopedList([automation])
- runtimeHost([], [])
- addRuntimeProject()
- runtimeCreateReturns(makeAutomation({ id: 'a-moved', projectId: RUNTIME_REPO_ID }))
-
- await renderPage()
- await settleHostQueries()
- await act(async () => {
- void mocks.listPanel?.openEditDialog(listedRow(automation.id))
- })
- await act(async () => {
- mocks.editorDialog?.editDestination?.onSelect(RUNTIME_SELF_KEY)
- })
-
- // The move is stated before it happens: the record is deleted from here.
- expect(mocks.editorDialog?.editDestination?.note).toBeTruthy()
-
- await act(async () => {
- mocks.editorDialog?.onDraftChange((current) => ({
- ...(current as Record),
- projectId: RUNTIME_REPO_ID,
- workspaceMode: 'existing',
- workspaceId: RUNTIME_WORKSPACE_ID
- }))
- })
- await save()
-
- // `update` reaches only the authority already holding the record, so a move
- // is the pair — and leaving the original behind would run it twice.
- expect(api.automations.update).not.toHaveBeenCalled()
- expect(runtimeCreateCalls()).toHaveLength(1)
- expect(runtimeCreateCalls()[0]?.[2]).toMatchObject({ repo: `id:${RUNTIME_REPO_ID}` })
- expect(api.automations.delete).toHaveBeenCalledWith(expect.objectContaining({ id: 'a-1' }))
- })
-
- it('reports a kept original as two live copies, never as a completed move', async () => {
- const automation = makeAutomation({ id: 'a-1' })
- api.automations.list.mockResolvedValue([])
- scopedList([automation])
- runtimeHost([], [])
- addRuntimeProject()
- runtimeCreateReturns(makeAutomation({ id: 'a-moved', projectId: RUNTIME_REPO_ID }))
- api.automations.delete.mockRejectedValue(new Error('gone away'))
-
- await renderPage()
- await settleHostQueries()
- await act(async () => {
- void mocks.listPanel?.openEditDialog(listedRow(automation.id))
- })
- await act(async () => {
- mocks.editorDialog?.editDestination?.onSelect(RUNTIME_SELF_KEY)
- })
- await act(async () => {
- mocks.editorDialog?.onDraftChange((current) => ({
- ...(current as Record),
- projectId: RUNTIME_REPO_ID,
- workspaceMode: 'existing',
- workspaceId: RUNTIME_WORKSPACE_ID
- }))
- })
- await save()
-
- // The new copy is live and the old one still runs; "moved" would hide that.
- expect(runtimeCreateCalls()).toHaveLength(1)
- expect(api.automations.delete).toHaveBeenCalled()
- expect(mocks.toastError).toHaveBeenCalledWith(expect.stringContaining('could not be deleted'))
- expect(mocks.toastSuccess).not.toHaveBeenCalled()
+ // A record cannot move between authorities, so the runtime is not offered.
+ expect(mocks.editorDialog?.editDestination?.entries.map((entry) => entry.stableKey)).toEqual([
+ DESKTOP_SELF_KEY,
+ SSH_HOST_KEY
+ ])
})
it('moves the record to the host the user picks, clearing the stranded project', async () => {
diff --git a/src/renderer/src/components/automations/AutomationsPage.tsx b/src/renderer/src/components/automations/AutomationsPage.tsx
index 9fae9cdf407..f82eee32cdd 100644
--- a/src/renderer/src/components/automations/AutomationsPage.tsx
+++ b/src/renderer/src/components/automations/AutomationsPage.tsx
@@ -75,7 +75,6 @@ import {
import {
deleteAutomationForTarget,
type AutomationHostTarget,
- getAutomationAuthorityTarget,
getAutomationHostTargetFromKey,
getAutomationHostTargetKey,
getAutomationListTarget,
@@ -1025,36 +1024,25 @@ export default function AutomationsPage(): React.JSX.Element {
})()
const isOrcaForm = createTarget === 'orca' && editingExternalTarget === null
const dialogAuthorityRepos = getAutomationCreateRepos(repos, automationDialogTarget)
- // The authority storing the edited record; a save landing on another one is a move.
+ // An update moves the record's execution target, never the authority that
+ // stores it, so the edit picker offers only that authority's own hosts.
const dialogAuthorityKey = automationAuthorityCatalogKey(
automationDialogTarget.kind === 'environment'
? { kind: 'runtime', environmentId: automationDialogTarget.environmentId }
: { kind: 'desktop' }
)
- const editHostEntries = hostCatalog.entries
+ const editHostEntries = hostCatalog.entries.filter(
+ (entry) => automationAuthorityCatalogKey(entry.stableRef.authority) === dialogAuthorityKey
+ )
const editHostResolution = resolveAutomationCreateDestination(
editingHostStableKey
? editHostEntries.find((entry) => entry.stableKey === editingHostStableKey)
: null
)
- // Projects follow the picked host's authority, not the record's: a move offers
- // what the target stores, and nothing on the old authority is reachable there.
const editHostProjects =
editHostResolution.status === 'ready'
- ? automationCreateEligibleProjects(
- repoTables,
- editHostResolution,
- getAutomationCreateRepos(
- repos,
- getAutomationAuthorityTarget(editHostResolution.authority)
- )
- )
+ ? automationCreateEligibleProjects(repoTables, editHostResolution, dialogAuthorityRepos)
: dialogAuthorityRepos
- const editMoveTargetEntry =
- editHostResolution.status === 'ready' &&
- automationAuthorityCatalogKey(editHostResolution.authority) !== dialogAuthorityKey
- ? editHostResolution.entry
- : null
// Picking a host strands a project that lives on another one; clearing it here
// states the move instead of deferring the same refusal to submit.
const handleEditHostChange = (stableKey: string): void => {
@@ -1077,14 +1065,7 @@ export default function AutomationsPage(): React.JSX.Element {
entries: editHostEntries,
resolution: editHostResolution,
onSelect: handleEditHostChange,
- projects: editHostProjects,
- // Replacer fn: a literal replacement would expand `$` patterns in host labels.
- note: editMoveTargetEntry
- ? translate(
- 'auto.components.automations.createDestination.move',
- 'Saving creates this automation on {host} and deletes the original. Its run history stays on the old host.'
- ).replace('{host}', () => editMoveTargetEntry.authorityLabel)
- : null
+ projects: editHostProjects
}
const dialogRepos = isOrcaForm
? editingAutomationId !== null
@@ -1751,7 +1732,6 @@ export default function AutomationsPage(): React.JSX.Element {
currentAutomation = (reread.ok ? reread.value : null) ?? currentAutomation
}
let editDestination: AutomationDestination | undefined
- let moveTarget: AutomationCreateDestination | null = null
const destinationChanged =
currentAutomation &&
(currentAutomation.projectId !== draft.projectId ||
@@ -1796,11 +1776,6 @@ export default function AutomationsPage(): React.JSX.Element {
return
}
editDestination = revalidated.destination
- // `update` reaches only the authority already holding the record, so a
- // save landing on another one is a create there plus a delete here.
- if (automationAuthorityCatalogKey(revalidated.authority) !== dialogAuthorityKey) {
- moveTarget = revalidated
- }
}
const updates: AutomationUpdateInput = {
name: draft.name,
@@ -1836,39 +1811,29 @@ export default function AutomationsPage(): React.JSX.Element {
reuseSession: draft.workspaceMode === 'existing' && draft.reuseSession,
timezone,
rrule,
- dtstart: updates.dtstart ?? currentAutomation?.dtstart ?? now,
+ dtstart: now,
missedRunGraceMinutes
}
const editSource = currentAutomation
- const move = moveTarget
- ? await moveAutomationToDestination(editSource, moveTarget, {
- ...createInput,
- // A move carries the record across; it does not resume a paused one.
- enabled: editSource?.enabled ?? true,
- sourceContext: editSource?.sourceContext ?? null
- })
- : null
- const saved = move
- ? move.saved
- : editingAutomationId
- ? await dispatchAutomationUpdate(
- automationDispatchContext,
- { rowKey: editingRowKey ?? '', automationId: editingAutomationId },
- updates,
- () => {
- // Nothing names a host: no captured owner and no record to read one
- // from, so the save is refused rather than sent unfenced.
- if (!editSource) {
- throw new Error(
- automationOwnerConflictMessage(AUTOMATION_OWNER_CONFLICT_CODES.ownerChanged)
- )
- }
- return updateAutomationForTarget(editSource, updates, automationHostTarget)
- },
- 'save',
- editDestination
- )
- : await createDraftAutomation(createInput)
+ const saved = editingAutomationId
+ ? await dispatchAutomationUpdate(
+ automationDispatchContext,
+ { rowKey: editingRowKey ?? '', automationId: editingAutomationId },
+ updates,
+ () => {
+ // Nothing names a host: no captured owner and no record to read one
+ // from, so the save is refused rather than sent unfenced.
+ if (!editSource) {
+ throw new Error(
+ automationOwnerConflictMessage(AUTOMATION_OWNER_CONFLICT_CODES.ownerChanged)
+ )
+ }
+ return updateAutomationForTarget(editSource, updates, automationHostTarget)
+ },
+ 'save',
+ editDestination
+ )
+ : await createDraftAutomation(createInput)
if (!saved.ok) {
setEditorNotice(saved.notice)
return
@@ -1887,9 +1852,7 @@ export default function AutomationsPage(): React.JSX.Element {
})
setDraft((current) => ({ ...current, name: '', prompt: '' }))
await refresh()
- // A move leaves the edited row behind: the record it selects is a new one
- // on another host, so its key is found rather than restored.
- if (editingAutomationId && editingRowKey && !moveTarget) {
+ if (editingAutomationId && editingRowKey) {
setSelectedAutomationRunPageId(null)
setSelectedRowKey(editingRowKey)
setSelectedId(automation.id)
@@ -1900,25 +1863,13 @@ export default function AutomationsPage(): React.JSX.Element {
if (!editingAutomationId) {
useAppStore.getState().recordFeatureInteraction('automation-created')
}
- // A kept original already raised its own toast; "moved" would contradict it.
- if (move && !move.originalRemoved) {
- return
- }
toast.success(
- moveTarget
+ editingAutomationId
? translate(
- 'auto.components.automations.AutomationsPage.moved',
- 'Automation moved to {host}.'
- ).replace('{host}', () => moveTarget.entry.authorityLabel)
- : editingAutomationId
- ? translate(
- 'auto.components.automations.AutomationsPage.244727e655',
- 'Automation updated.'
- )
- : translate(
- 'auto.components.automations.AutomationsPage.2a20596d6b',
- 'Automation saved.'
- )
+ 'auto.components.automations.AutomationsPage.244727e655',
+ 'Automation updated.'
+ )
+ : translate('auto.components.automations.AutomationsPage.2a20596d6b', 'Automation saved.')
)
} catch (error) {
if (isHermesSave) {
@@ -1937,55 +1888,6 @@ export default function AutomationsPage(): React.JSX.Element {
}
}
- /**
- * A record cannot change the authority that stores it, so a save aimed at
- * another one creates the automation there and deletes the original. A failed
- * delete leaves two live copies, which is said rather than reported as a move.
- */
- const moveAutomationToDestination = async (
- source: Automation | null,
- target: AutomationCreateDestination,
- input: AutomationCreateInput
- ): Promise<{ saved: AutomationDispatchResult; originalRemoved: boolean }> => {
- if (!source) {
- return {
- saved: {
- ok: false,
- notice: {
- message: automationOwnerConflictMessage(AUTOMATION_OWNER_CONFLICT_CODES.ownerChanged),
- recovery: 'retry',
- severity: 'owner'
- }
- },
- originalRemoved: false
- }
- }
- const created = toDispatchResult(
- await createAutomationAtDestination(target.authority, input, target.destination)
- )
- if (!created.ok) {
- return { saved: created, originalRemoved: false }
- }
- invalidateWrittenHost(target.entry.stableRef, 'definition')
- const removed = await dispatchAutomationDelete(
- automationDispatchContext,
- { rowKey: editingRowKey ?? '', automationId: source.id },
- // The dialog's own target, which names the edited row's host even when no
- // owner was captured to fence the delete with.
- () => deleteAutomationForTarget(source, automationDialogTarget)
- )
- if (!removed.ok) {
- // Both copies are live; said as such rather than reported as a move.
- toast.error(
- translate(
- 'auto.components.automations.AutomationsPage.moveOriginalKept',
- 'Created on {host}, but the original could not be deleted. Remove it on the old host.'
- ).replace('{host}', () => target.entry.authorityLabel)
- )
- }
- return { saved: created, originalRemoved: removed.ok }
- }
-
/** Creation states its destination and re-checks it at submit; it never infers one. */
const createDraftAutomation = async (
input: AutomationCreateInput
diff --git a/src/renderer/src/components/automations/automation-host-client.ts b/src/renderer/src/components/automations/automation-host-client.ts
index e7ef5a44770..2b7c3b7c102 100644
--- a/src/renderer/src/components/automations/automation-host-client.ts
+++ b/src/renderer/src/components/automations/automation-host-client.ts
@@ -5,7 +5,6 @@ import type {
AutomationRun,
AutomationUpdateInput
} from '../../../../shared/automations-types'
-import type { AutomationAuthorityRef } from '../../../../shared/automation-owner-ref'
import { parseExecutionHostId } from '../../../../shared/execution-host'
import type { GlobalSettings } from '../../../../shared/global-settings-types'
@@ -50,14 +49,6 @@ export function getAutomationTargetFromHostId(
: { kind: 'local' }
}
-export function getAutomationAuthorityTarget(
- authority: AutomationAuthorityRef
-): AutomationHostTarget {
- return authority.kind === 'runtime'
- ? { kind: 'environment', environmentId: authority.environmentId }
- : { kind: 'local' }
-}
-
export function getAutomationListTarget(
settings: Pick | null | undefined
): AutomationHostTarget {
diff --git a/src/renderer/src/components/automations/use-automation-create-destination.ts b/src/renderer/src/components/automations/use-automation-create-destination.ts
index 9ae52aa6729..72175fb1f1e 100644
--- a/src/renderer/src/components/automations/use-automation-create-destination.ts
+++ b/src/renderer/src/components/automations/use-automation-create-destination.ts
@@ -35,8 +35,6 @@ export type AutomationCreateDestinationControl = {
onSelect: (stableKey: string) => void
/** Projects the resolved destination can hold; the whole list until one resolves. */
projects: readonly Repo[]
- /** Stated consequence of saving here, when it is not the plain one. */
- note?: string | null
}
export type AutomationCreateDestinationCheck =
diff --git a/src/renderer/src/i18n/locales/en.json b/src/renderer/src/i18n/locales/en.json
index 86ed852cc78..e8be1452f02 100644
--- a/src/renderer/src/i18n/locales/en.json
+++ b/src/renderer/src/i18n/locales/en.json
@@ -15376,8 +15376,6 @@
"b11170a008": "Failed to save automation.",
"2a20596d6b": "Automation saved.",
"244727e655": "Automation updated.",
- "moved": "Automation moved to {host}.",
- "moveOriginalKept": "Created on {host}, but the original could not be deleted. Remove it on the old host.",
"77b81bc4ac": "Hermes automation created.",
"08efc3ae12": "Hermes automation updated.",
"e431bb85d4": "Choose a workspace on the same host as this Hermes automation.",
@@ -15692,8 +15690,7 @@
"stale": "{host} changed while this form was open. Choose it again before saving.",
"projectMismatch": "That project is not on {host}. Choose a project on that host, or another host.",
"noProjects": "No projects are set up on {host}. Add one there, or choose another host.",
- "updateRequired": "Update the Orca server on {hosts} to store automations there.",
- "move": "Saving creates this automation on {host} and deletes the original. Its run history stays on the old host."
+ "updateRequired": "Update the Orca server on {hosts} to store automations there."
}
},
"agent": {
diff --git a/src/renderer/src/i18n/locales/es.json b/src/renderer/src/i18n/locales/es.json
index a00e1bdd24e..d3198f1700f 100644
--- a/src/renderer/src/i18n/locales/es.json
+++ b/src/renderer/src/i18n/locales/es.json
@@ -13888,8 +13888,6 @@
"b11170a008": "No se pudo guardar la automatización.",
"2a20596d6b": "Automatización guardada.",
"244727e655": "Automatización actualizada.",
- "moved": "Automatización movida a {host}.",
- "moveOriginalKept": "Se creó en {host}, pero no se pudo eliminar la original. Elimínela en el host anterior.",
"77b81bc4ac": "Se crea la automatización de Hermes.",
"08efc3ae12": "Automatización Hermes actualizada.",
"e431bb85d4": "Elija un espacio de trabajo en el mismo host que esta automatización de Hermes.",
@@ -14097,8 +14095,7 @@
"stale": "{host} cambió mientras este formulario estaba abierto. Elíjalo de nuevo antes de guardar.",
"projectMismatch": "Ese proyecto no está en {host}. Elija un proyecto en ese host, u otro host.",
"noProjects": "No hay proyectos configurados en {host}. Agregue uno allí o elija otro host.",
- "updateRequired": "Actualice el servidor de Orca en {hosts} para almacenar automatizaciones allí.",
- "move": "Al guardar se crea esta automatización en {host} y se elimina la original. Su historial de ejecuciones permanece en el host anterior."
+ "updateRequired": "Actualice el servidor de Orca en {hosts} para almacenar automatizaciones allí."
}
},
"agent": {
diff --git a/src/renderer/src/i18n/locales/ja.json b/src/renderer/src/i18n/locales/ja.json
index 1c0f8a9a748..f000f02561b 100644
--- a/src/renderer/src/i18n/locales/ja.json
+++ b/src/renderer/src/i18n/locales/ja.json
@@ -13879,8 +13879,6 @@
"b11170a008": "オートメーションを保存できませんでした。",
"2a20596d6b": "オートメーションが保存されました。",
"244727e655": "自動化が更新されました。",
- "moved": "自動化を {host} に移動しました。",
- "moveOriginalKept": "{host} に作成しましたが、元の自動化を削除できませんでした。元のホストで削除してください。",
"77b81bc4ac": "Hermes オートメーションが作成されました。",
"08efc3ae12": "Hermes オートメーションが更新されました。",
"e431bb85d4": "この Hermes オートメーションと同じホスト上のワークスペースを選択します。",
@@ -14088,8 +14086,7 @@
"stale": "このフォームを開いている間に {host} が変更されました。保存する前にもう一度選択してください。",
"projectMismatch": "そのプロジェクトは {host} にありません。そのホスト上のプロジェクト、または別のホストを選択してください。",
"noProjects": "{host} にはプロジェクトが設定されていません。そこに追加するか、別のホストを選択してください。",
- "updateRequired": "{hosts} の Orca サーバーを更新すると、そこに自動化を保存できます。",
- "move": "保存すると、この自動化は {host} に作成され、元の自動化は削除されます。実行履歴は元のホストに残ります。"
+ "updateRequired": "{hosts} の Orca サーバーを更新すると、そこに自動化を保存できます。"
}
},
"agent": {
diff --git a/src/renderer/src/i18n/locales/ko.json b/src/renderer/src/i18n/locales/ko.json
index 175735ba5e5..421c6770464 100644
--- a/src/renderer/src/i18n/locales/ko.json
+++ b/src/renderer/src/i18n/locales/ko.json
@@ -13911,8 +13911,6 @@
"b11170a008": "자동화를 저장하지 못했습니다.",
"2a20596d6b": "자동화가 저장되었습니다.",
"244727e655": "자동화가 업데이트되었습니다.",
- "moved": "자동화를 {host}(으)로 이동했습니다.",
- "moveOriginalKept": "{host}에 생성했지만 원본을 삭제하지 못했습니다. 이전 호스트에서 삭제하세요.",
"77b81bc4ac": "Hermes 자동화가 생성되었습니다.",
"08efc3ae12": "Hermes 자동화가 업데이트되었습니다.",
"e431bb85d4": "이 Hermes 자동화와 동일한 호스트에서 워크스페이스를 선택하세요.",
@@ -14120,8 +14118,7 @@
"stale": "이 양식이 열려 있는 동안 {host}이(가) 변경되었습니다. 저장하기 전에 다시 선택하세요.",
"projectMismatch": "해당 프로젝트는 {host}에 없습니다. 그 호스트의 프로젝트를 선택하거나 다른 호스트를 선택하세요.",
"noProjects": "{host}에 설정된 프로젝트가 없습니다. 거기에 추가하거나 다른 호스트를 선택하세요.",
- "updateRequired": "{hosts}의 Orca 서버를 업데이트하면 거기에 자동화를 저장할 수 있습니다.",
- "move": "저장하면 이 자동화가 {host}에 생성되고 원본은 삭제됩니다. 실행 기록은 이전 호스트에 남습니다."
+ "updateRequired": "{hosts}의 Orca 서버를 업데이트하면 거기에 자동화를 저장할 수 있습니다."
}
},
"agent": {
diff --git a/src/renderer/src/i18n/locales/zh.json b/src/renderer/src/i18n/locales/zh.json
index 2ad8a4a2b99..ceb26968d58 100644
--- a/src/renderer/src/i18n/locales/zh.json
+++ b/src/renderer/src/i18n/locales/zh.json
@@ -13935,8 +13935,6 @@
"b11170a008": "无法保存自动化。",
"2a20596d6b": "自动化已保存。",
"244727e655": "自动化已更新。",
- "moved": "自动化已移动到 {host}。",
- "moveOriginalKept": "已在 {host} 上创建,但无法删除原有自动化。请在原主机上删除它。",
"77b81bc4ac": "Hermes 自动化创建。",
"08efc3ae12": "Hermes 自动化已更新。",
"e431bb85d4": "选择与此 Hermes 自动化位于同一主机上的工作区。",
@@ -14144,8 +14142,7 @@
"stale": "此表单打开期间 {host} 已更改。保存前请重新选择。",
"projectMismatch": "该项目不在 {host} 上。请选择该主机上的项目,或选择另一台主机。",
"noProjects": "{host} 上未设置任何项目。请在该主机上添加一个,或选择另一台主机。",
- "updateRequired": "更新 {hosts} 上的 Orca 服务器即可在其中存储自动化。",
- "move": "保存后会在 {host} 上创建此自动化并删除原有自动化。运行历史仍保留在原主机上。"
+ "updateRequired": "更新 {hosts} 上的 Orca 服务器即可在其中存储自动化。"
}
},
"agent": {