mirror of
https://github.com/stablyai/orca.git
synced 2026-10-21 16:03:26 +00:00
feat(skills): install bundles on another machine
This commit is contained in:
@@ -889,9 +889,8 @@ does not mean the surrounding phase is complete.
|
||||
- [x] Show whether a package came from Orca Cloud and its accessible version history.
|
||||
- [x] Refresh discovery and installation state after local or remote actions.
|
||||
- [x] Keep Cloud deletion, share revocation, and local removal clearly separate.
|
||||
- [ ] Add installed-bundle update, rollback, install-on-another-machine, inspect, and remove actions.
|
||||
Grouped inspection, selective update/rollback, and one-surface safe removal are implemented;
|
||||
install-on-another-machine remains.
|
||||
- [x] Add installed-bundle update, rollback, install-on-another-machine, inspect, and remove actions.
|
||||
An active unlisted link opens the existing destination-aware installer for another machine.
|
||||
- [x] Add shared-bundle copy-link, access, revoke, publish-version, and Cloud-delete actions. Exact
|
||||
full-bundle version publishing reuses its package; ambiguous or partial managed-bundle
|
||||
selections create a new package rather than mutating the wrong history.
|
||||
|
||||
@@ -165,7 +165,8 @@ beforeEach(() => {
|
||||
useAppStore.setState({
|
||||
runtimeEnvironments: [],
|
||||
sshConnectionStates: new Map(),
|
||||
sshTargetLabels: new Map()
|
||||
sshTargetLabels: new Map(),
|
||||
pendingSkillShareId: null
|
||||
})
|
||||
})
|
||||
|
||||
@@ -344,6 +345,33 @@ describe('SkillInstallManagementDialog', () => {
|
||||
expect(skills.installPackageVersion).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('opens an active bundle link in the existing machine installer', async () => {
|
||||
const installed = [bundleInstall('alpha-skill'), bundleInstall('beta-skill')]
|
||||
const versions = [bundleVersion('ver_1', ['alpha-skill', 'beta-skill'])]
|
||||
const details = {
|
||||
...packageDetails(versions),
|
||||
management: {
|
||||
shares: [
|
||||
{
|
||||
id: 'share_bundle',
|
||||
url: 'https://app.orca.dev/skills/share/share_bundle',
|
||||
createdAt: '2026-08-12T00:00:00.000Z'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
const skills = skillsApi(installed, versions, details)
|
||||
const onOpenChange = vi.fn()
|
||||
Object.defineProperty(window, 'api', { configurable: true, value: { skills } })
|
||||
render(<SkillInstallManagementDialog open onOpenChange={onOpenChange} />)
|
||||
|
||||
fireEvent.click(await screen.findByRole('button', { name: /2 skill bundle.*ver_1/ }))
|
||||
fireEvent.click(await screen.findByRole('button', { name: 'Install on another machine' }))
|
||||
|
||||
expect(onOpenChange).toHaveBeenCalledWith(false)
|
||||
expect(useAppStore.getState().pendingSkillShareId).toBe('share_bundle')
|
||||
})
|
||||
|
||||
it('removes a bundle with one confirmation and preserves modified skills', async () => {
|
||||
const installed = [bundleInstall('alpha-skill'), bundleInstall('beta-skill', 'modified')]
|
||||
const skills = skillsApi(installed, [bundleVersion('ver_1', ['alpha-skill', 'beta-skill'])])
|
||||
|
||||
@@ -310,8 +310,6 @@ export function SkillInstallManagementDialog({
|
||||
setError(null)
|
||||
setNotice(null)
|
||||
setResult(null)
|
||||
setBundleResult(null)
|
||||
setConfirmRemove(false)
|
||||
onOpenChange(false)
|
||||
}
|
||||
|
||||
@@ -377,6 +375,10 @@ export function SkillInstallManagementDialog({
|
||||
onVersionChange={setVersionId}
|
||||
onInstall={(discardLocal) => void installVersion(discardLocal)}
|
||||
onCancelInstall={() => void cancelInstall()}
|
||||
onInstallAnotherMachine={(shareId) => {
|
||||
close()
|
||||
useAppStore.getState().openSkillShare(shareId)
|
||||
}}
|
||||
onRemove={(discardLocal) => void remove(discardLocal)}
|
||||
onCloudChanged={refreshPackageDetails}
|
||||
onPackageDeleted={packageDeleted}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AlertTriangle, Loader2, RotateCcw, Trash2 } from 'lucide-react'
|
||||
import { AlertTriangle, Loader2, MonitorUp, RotateCcw, Trash2 } from 'lucide-react'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import {
|
||||
Select,
|
||||
@@ -30,6 +30,7 @@ export function SkillManagedInstallDetails({
|
||||
onVersionChange,
|
||||
onInstall,
|
||||
onCancelInstall,
|
||||
onInstallAnotherMachine,
|
||||
onRemove,
|
||||
onCloudChanged,
|
||||
onPackageDeleted
|
||||
@@ -47,6 +48,7 @@ export function SkillManagedInstallDetails({
|
||||
onVersionChange: (versionId: string) => void
|
||||
onInstall: (discardLocal?: boolean) => void
|
||||
onCancelInstall: () => void
|
||||
onInstallAnotherMachine: (shareId: string) => void
|
||||
onRemove: (discardLocal?: boolean) => void
|
||||
onCloudChanged: () => Promise<void>
|
||||
onPackageDeleted: () => void
|
||||
@@ -56,6 +58,7 @@ export function SkillManagedInstallDetails({
|
||||
selectedVersion?.manifest && 'skills' in selectedVersion.manifest
|
||||
? selectedVersion.manifest
|
||||
: null
|
||||
const activeShare = details.management?.shares[0]
|
||||
return (
|
||||
<section className="space-y-3 rounded-md border border-border p-3">
|
||||
<div>
|
||||
@@ -125,6 +128,16 @@ export function SkillManagedInstallDetails({
|
||||
{copy.cancelInstall}
|
||||
</Button>
|
||||
) : null}
|
||||
{activeShare ? (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
disabled={busy}
|
||||
onClick={() => onInstallAnotherMachine(activeShare.id)}
|
||||
>
|
||||
<MonitorUp className="size-4" /> {copy.installAnotherMachine}
|
||||
</Button>
|
||||
) : null}
|
||||
<Button
|
||||
variant={confirmRemove ? 'destructive' : 'outline'}
|
||||
size="sm"
|
||||
|
||||
@@ -55,6 +55,10 @@ export function skillInstallManagementCopy() {
|
||||
'auto.components.skills.SkillInstallManagementDialog.561e49ccd1',
|
||||
'Install selected version'
|
||||
),
|
||||
installAnotherMachine: translate(
|
||||
'auto.components.skills.SkillInstallManagementDialog.installAnotherMachine',
|
||||
'Install on another machine'
|
||||
),
|
||||
cancelInstall: translate(
|
||||
'auto.components.skills.SkillInstallManagementDialog.c1d03ee50d',
|
||||
'Cancel installation'
|
||||
|
||||
@@ -4208,7 +4208,8 @@
|
||||
"34c2ef9e71": "Install {{count}} skills",
|
||||
"a0cab67c2f": "Remove {{count}} skills",
|
||||
"f970d8088d": "Confirm remove {{count}} skills",
|
||||
"dab29e4b54": "{{installed}} installed · {{updated}} updated · {{keptLocal}} kept local"
|
||||
"dab29e4b54": "{{installed}} installed · {{updated}} updated · {{keptLocal}} kept local",
|
||||
"installAnotherMachine": "Install on another machine"
|
||||
},
|
||||
"SkillInstallReviewContent": {
|
||||
"89e2601162": "Discard and replace",
|
||||
|
||||
Reference in New Issue
Block a user