mirror of
https://github.com/stablyai/orca.git
synced 2026-10-19 16:03:26 +00:00
Add project host setup delete API
Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
@@ -498,12 +498,14 @@ Already partially landed:
|
||||
compatibility rows from repos
|
||||
- first-class `projectHostSetup.update` mutation through local IPC, preload,
|
||||
runtime RPC, and CLI for setup-owned metadata
|
||||
- first-class `projectHostSetup.delete` mutation through local IPC, preload,
|
||||
runtime RPC, and CLI
|
||||
|
||||
Not complete yet:
|
||||
|
||||
- SSH clone streamed-progress parity and provisioning flows
|
||||
- first-class independent project-host setup creation/delete APIs beyond the
|
||||
current repo-backed import/clone compatibility paths
|
||||
- first-class independent project-host setup creation/provisioning APIs beyond
|
||||
the current repo-backed import/clone compatibility paths
|
||||
- bulk setup flows and setup for hosts that are not already known to the client
|
||||
- project settings split into global and host-specific ownership
|
||||
- host settings/capability UI aligned with project setup
|
||||
|
||||
@@ -502,11 +502,13 @@ Already partially landed:
|
||||
compatibility rows from repos
|
||||
- first-class `projectHostSetup.update` mutation through local IPC, preload,
|
||||
runtime RPC, and CLI for setup-owned metadata
|
||||
- first-class `projectHostSetup.delete` mutation through local IPC, preload,
|
||||
runtime RPC, and CLI
|
||||
|
||||
Not complete yet:
|
||||
|
||||
- first-class independent project-host setup creation/delete APIs beyond the
|
||||
current repo-backed import/clone compatibility paths
|
||||
- first-class independent project-host setup creation/provisioning APIs beyond
|
||||
the current repo-backed import/clone compatibility paths
|
||||
- bulk setup flows and setup for hosts that are not already known to the client
|
||||
- SSH streamed clone progress parity
|
||||
- full project settings split into global and host-specific ownership
|
||||
@@ -536,7 +538,7 @@ tests, and version-skew handling.
|
||||
|
||||
The largest remaining areas are:
|
||||
|
||||
1. independent `ProjectHostSetup` creation/delete APIs
|
||||
1. independent `ProjectHostSetup` creation/provisioning APIs
|
||||
2. project-first creation/setup UI completion
|
||||
3. project and host settings ownership split
|
||||
4. cache/request ownership audit
|
||||
|
||||
@@ -420,12 +420,14 @@ Already partially landed:
|
||||
compatibility rows from repos
|
||||
- first-class `projectHostSetup.update` mutation through local IPC, preload,
|
||||
runtime RPC, and CLI for setup-owned metadata
|
||||
- first-class `projectHostSetup.delete` mutation through local IPC, preload,
|
||||
runtime RPC, and CLI
|
||||
|
||||
Still needed:
|
||||
|
||||
- finish SSH clone streamed-progress parity and provisioning flows
|
||||
- first-class independent project-host setup creation/delete APIs beyond the
|
||||
current repo-backed import/clone compatibility paths
|
||||
- first-class independent project-host setup creation/provisioning APIs beyond
|
||||
the current repo-backed import/clone compatibility paths
|
||||
- bulk setup flows and setup for newly added hosts
|
||||
- project settings split into global and host-specific ownership
|
||||
- host settings/capability UI aligned with project setup
|
||||
|
||||
@@ -774,6 +774,10 @@ Landed so far:
|
||||
preload, runtime RPC, and CLI. Independent setup rows can update setup-owned
|
||||
metadata directly, while repo-backed setup rows mirror safe fields onto the
|
||||
existing repo record and reject path/state changes that require re-import.
|
||||
- Added a first-class `projectHostSetup.delete` mutation through local IPC,
|
||||
preload, runtime RPC, and CLI. Independent setup rows are removed directly,
|
||||
while repo-backed setup rows remove the existing repo compatibility record so
|
||||
legacy cleanup semantics stay centralized.
|
||||
- Added tests for local repos, SSH repos, same-provider multi-host grouping,
|
||||
no-identity same-name non-grouping, selector cache behavior, persistence
|
||||
backfill, repo mutation synchronization, renderer hydration, runtime RPC
|
||||
@@ -803,15 +807,16 @@ Important limitation:
|
||||
compatibility records. Independently persisted setup records are now preserved
|
||||
across load and repo mutations, but the UI/API still mostly creates setups
|
||||
through repo-backed import/clone paths. First-class setup update now exists,
|
||||
but independent setup create/delete and full UI flows are still future work.
|
||||
and first-class setup delete now exists, but independent setup creation,
|
||||
provisioning, and full UI flows are still future work.
|
||||
|
||||
Remaining end-to-end work:
|
||||
|
||||
- broaden setup-on-host flows beyond known local, SSH, and active runtime hosts
|
||||
- finish SSH clone streamed-progress parity, provisioning, and bulk setup-on-host
|
||||
flows
|
||||
- add first-class independent project-host setup creation/delete APIs instead of
|
||||
routing most setup changes through repo import/update compatibility
|
||||
- add first-class independent project-host setup creation and provisioning APIs
|
||||
instead of routing most setup changes through repo import/update compatibility
|
||||
- split settings into explicit client, host, project, and project-host setup
|
||||
scopes
|
||||
- validate the default project-first sidebar view in Electron and continue
|
||||
|
||||
@@ -23,6 +23,7 @@ export {
|
||||
} from './computer-format'
|
||||
export type { ComputerActionFollowUpTarget } from './computer-format'
|
||||
export {
|
||||
formatProjectHostSetupDeleteResult,
|
||||
formatProjectHostSetupList,
|
||||
formatProjectHostSetupResult,
|
||||
formatProjectHostSetupUpdateResult,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type {
|
||||
Project,
|
||||
ProjectHostSetup,
|
||||
ProjectHostSetupDeleteResult,
|
||||
ProjectHostSetupExistingFolderArgs,
|
||||
ProjectHostSetupResult,
|
||||
ProjectHostSetupUpdateArgs,
|
||||
@@ -9,6 +10,7 @@ import type {
|
||||
} from '../../shared/types'
|
||||
import type { CommandHandler } from '../dispatch'
|
||||
import {
|
||||
formatProjectHostSetupDeleteResult,
|
||||
formatProjectHostSetupList,
|
||||
formatProjectHostSetupResult,
|
||||
formatProjectHostSetupUpdateResult,
|
||||
@@ -83,6 +85,15 @@ export const PROJECT_HANDLERS: Record<string, CommandHandler> = {
|
||||
args
|
||||
)
|
||||
printResult(result, json, formatProjectHostSetupUpdateResult)
|
||||
},
|
||||
'project setup-delete': async ({ flags, client, json }) => {
|
||||
const result = await client.call<{ result: ProjectHostSetupDeleteResult }>(
|
||||
'projectHostSetup.delete',
|
||||
{
|
||||
setupId: getRequiredStringFlag(flags, 'setup')
|
||||
}
|
||||
)
|
||||
printResult(result, json, formatProjectHostSetupDeleteResult)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ Projects:
|
||||
project setups List project host setups
|
||||
project setup-existing-folder Make a project available on a host by importing an existing folder
|
||||
project setup-update Update project host setup metadata
|
||||
project setup-delete Remove a project host setup
|
||||
|
||||
Repos:
|
||||
repo list List repos registered in Orca
|
||||
@@ -211,6 +212,7 @@ Common Commands:
|
||||
orca project setups [--project <id>] [--host <host-id>] [--json]
|
||||
orca project setup-existing-folder --project <id> --host <host-id> --path <path> [--kind git|folder] [--display-name <name>] [--json]
|
||||
orca project setup-update --setup <setup-id> [--display-name <name>] [--path <path>] [--worktree-base-path <path>] [--git-username <name>] [--kind git|folder] [--state ready|not-set-up|setting-up|error|unsupported] [--method legacy-repo|imported-existing-folder|cloned] [--json]
|
||||
orca project setup-delete --setup <setup-id> [--json]
|
||||
orca repo list [--json]
|
||||
orca repo add --path <path> [--json]
|
||||
orca repo show --repo <selector> [--json]
|
||||
|
||||
@@ -147,6 +147,9 @@ describe('orca root help', () => {
|
||||
expect(logSpy.mock.calls[0][0]).toContain(
|
||||
'project setup-update Update project host setup metadata'
|
||||
)
|
||||
expect(logSpy.mock.calls[0][0]).toContain(
|
||||
'project setup-delete Remove a project host setup'
|
||||
)
|
||||
expect(callMock).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
@@ -3136,4 +3139,41 @@ describe('orca cli worktree awareness', () => {
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it('deletes project host setup metadata through the project-first runtime API', async () => {
|
||||
queueFixtures(
|
||||
callMock,
|
||||
okFixture('req_project_setup_delete', {
|
||||
result: {
|
||||
project: {
|
||||
id: 'github:stablyai/orca',
|
||||
displayName: 'Orca',
|
||||
badgeColor: '#7c3aed',
|
||||
sourceRepoIds: [],
|
||||
createdAt: 1,
|
||||
updatedAt: 1
|
||||
},
|
||||
setup: {
|
||||
id: 'setup-gpu',
|
||||
projectId: 'github:stablyai/orca',
|
||||
hostId: 'runtime:gpu',
|
||||
repoId: '',
|
||||
path: '/srv/orca',
|
||||
displayName: 'GPU VM',
|
||||
setupState: 'ready',
|
||||
setupMethod: 'imported-existing-folder',
|
||||
createdAt: 1,
|
||||
updatedAt: 2
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
vi.spyOn(console, 'log').mockImplementation(() => {})
|
||||
|
||||
await main(['project', 'setup-delete', '--setup', 'setup-gpu', '--json'], '/tmp/repo')
|
||||
|
||||
expect(callMock).toHaveBeenCalledWith('projectHostSetup.delete', {
|
||||
setupId: 'setup-gpu'
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type {
|
||||
Project,
|
||||
ProjectHostSetup,
|
||||
ProjectHostSetupDeleteResult,
|
||||
ProjectHostSetupResult,
|
||||
ProjectHostSetupUpdateResult
|
||||
} from '../shared/types'
|
||||
@@ -43,6 +44,16 @@ export function formatProjectHostSetupUpdateResult(result: {
|
||||
return formatProjectHostSetupResultFields(project, setup, repo?.id)
|
||||
}
|
||||
|
||||
export function formatProjectHostSetupDeleteResult(result: {
|
||||
result: ProjectHostSetupDeleteResult
|
||||
}): string {
|
||||
const { project, setup, repo } = result.result
|
||||
return [
|
||||
`deleted: ${setup.id}`,
|
||||
formatProjectHostSetupResultFields(project, setup, repo?.id)
|
||||
].join('\n')
|
||||
}
|
||||
|
||||
function formatProjectHostSetupResultFields(
|
||||
project: Project,
|
||||
setup: ProjectHostSetup,
|
||||
|
||||
@@ -57,5 +57,16 @@ export const PROJECT_COMMAND_SPECS: CommandSpec[] = [
|
||||
'orca project setup-update --setup github:stablyai/orca::gpu --display-name "GPU VM"',
|
||||
'orca project setup-update --setup github:stablyai/orca::gpu --path /srv/orca --state ready --json'
|
||||
]
|
||||
},
|
||||
{
|
||||
path: ['project', 'setup-delete'],
|
||||
summary: 'Remove a project host setup',
|
||||
usage: 'orca project setup-delete --setup <setup-id> [--json]',
|
||||
allowedFlags: [...GLOBAL_FLAGS, 'setup'],
|
||||
notes: [
|
||||
'Independent setups are removed directly.',
|
||||
'Repo-backed setups remove the registered repo compatibility record.'
|
||||
],
|
||||
examples: ['orca project setup-delete --setup github:stablyai/orca::gpu --json']
|
||||
}
|
||||
]
|
||||
|
||||
@@ -11,6 +11,8 @@ import type {
|
||||
Repo,
|
||||
ProjectGroup,
|
||||
ProjectGroupImportResult,
|
||||
ProjectHostSetupDeleteArgs,
|
||||
ProjectHostSetupDeleteResult,
|
||||
ProjectHostSetupExistingFolderArgs,
|
||||
ProjectHostSetupResult,
|
||||
ProjectHostSetupUpdateArgs,
|
||||
@@ -468,6 +470,10 @@ const ProjectHostSetupUpdateIpcArgs = z.object({
|
||||
})
|
||||
})
|
||||
|
||||
const ProjectHostSetupDeleteIpcArgs = z.object({
|
||||
setupId: z.string().min(1)
|
||||
})
|
||||
|
||||
const ProjectGroupScanNestedArgs = z.object({
|
||||
path: z.string().min(1),
|
||||
connectionId: z.string().min(1).optional(),
|
||||
@@ -758,6 +764,7 @@ export function registerRepoHandlers(mainWindow: BrowserWindow, store: Store): v
|
||||
ipcMain.removeHandler('projectHostSetups:list')
|
||||
ipcMain.removeHandler('projectHostSetups:setupExistingFolder')
|
||||
ipcMain.removeHandler('projectHostSetups:update')
|
||||
ipcMain.removeHandler('projectHostSetups:delete')
|
||||
ipcMain.removeHandler('projectGroups:list')
|
||||
ipcMain.removeHandler('projectGroups:create')
|
||||
ipcMain.removeHandler('projectGroups:update')
|
||||
@@ -806,6 +813,23 @@ export function registerRepoHandlers(mainWindow: BrowserWindow, store: Store): v
|
||||
}
|
||||
)
|
||||
|
||||
ipcMain.handle(
|
||||
'projectHostSetups:delete',
|
||||
(_event, rawArgs: ProjectHostSetupDeleteArgs): ProjectHostSetupDeleteResult => {
|
||||
const args = parseProjectGroupIpcArgs(
|
||||
ProjectHostSetupDeleteIpcArgs,
|
||||
rawArgs,
|
||||
'project_host_setup_delete_invalid_args'
|
||||
)
|
||||
const result = store.deleteProjectHostSetup(args)
|
||||
if (!result) {
|
||||
throw new Error(`Project host setup not found: ${args.setupId}`)
|
||||
}
|
||||
notifyReposChanged(mainWindow)
|
||||
return result
|
||||
}
|
||||
)
|
||||
|
||||
ipcMain.handle(
|
||||
'projectHostSetups:setupExistingFolder',
|
||||
async (
|
||||
|
||||
@@ -2512,6 +2512,49 @@ describe('Store', () => {
|
||||
).toThrow('Repo-backed project host setup paths must be changed by re-importing the project.')
|
||||
})
|
||||
|
||||
it('deletes independent project host setup records without deleting the project', async () => {
|
||||
const independentProject = makeProject({
|
||||
id: 'cloud-project',
|
||||
displayName: 'Cloud Project'
|
||||
})
|
||||
const independentSetup = makeProjectHostSetup({
|
||||
id: 'cloud-project::gpu-vm',
|
||||
projectId: independentProject.id,
|
||||
hostId: 'runtime:gpu-vm',
|
||||
repoId: '',
|
||||
path: '/srv/cloud-project',
|
||||
displayName: 'GPU VM'
|
||||
})
|
||||
writeDataFile({
|
||||
...getDefaultPersistedState(testState.dir),
|
||||
projects: [independentProject],
|
||||
projectHostSetups: [independentSetup]
|
||||
})
|
||||
const store = await createStore()
|
||||
|
||||
const result = store.deleteProjectHostSetup({ setupId: independentSetup.id })
|
||||
|
||||
expect(result).toEqual({ project: independentProject, setup: independentSetup })
|
||||
expect(store.getProjects()).toEqual([independentProject])
|
||||
expect(store.getProjectHostSetups()).toEqual([])
|
||||
})
|
||||
|
||||
it('deletes repo-backed project host setups by removing the compatibility repo', async () => {
|
||||
const store = await createStore()
|
||||
store.addRepo(makeRepo({ id: 'r1', path: '/repo' }))
|
||||
store.setWorktreeMeta('r1::/path/wt1', { displayName: 'wt1' })
|
||||
|
||||
const result = store.deleteProjectHostSetup({ setupId: 'r1' })
|
||||
|
||||
expect(result?.project).toMatchObject({ id: 'repo:r1' })
|
||||
expect(result?.setup).toMatchObject({ id: 'r1', repoId: 'r1' })
|
||||
expect(result?.repo).toMatchObject({ id: 'r1' })
|
||||
expect(store.getRepo('r1')).toBeUndefined()
|
||||
expect(store.getProjects()).toEqual([])
|
||||
expect(store.getProjectHostSetups()).toEqual([])
|
||||
expect(store.getWorktreeMeta('r1::/path/wt1')).toBeUndefined()
|
||||
})
|
||||
|
||||
it('updateRepo preserves repo-backed project host setup method', async () => {
|
||||
const store = await createStore()
|
||||
store.addRepo(makeRepo())
|
||||
|
||||
@@ -36,6 +36,8 @@ import type {
|
||||
PersistedState,
|
||||
Project,
|
||||
ProjectHostSetup,
|
||||
ProjectHostSetupDeleteArgs,
|
||||
ProjectHostSetupDeleteResult,
|
||||
ProjectHostSetupUpdateArgs,
|
||||
ProjectHostSetupUpdateResult,
|
||||
ProjectHostSetupMethod,
|
||||
@@ -2588,6 +2590,29 @@ export class Store {
|
||||
return { project, setup: updatedSetup }
|
||||
}
|
||||
|
||||
deleteProjectHostSetup(args: ProjectHostSetupDeleteArgs): ProjectHostSetupDeleteResult | null {
|
||||
const setup = this.state.projectHostSetups.find((entry) => entry.id === args.setupId)
|
||||
if (!setup) {
|
||||
return null
|
||||
}
|
||||
const project = this.state.projects.find((entry) => entry.id === setup.projectId)
|
||||
if (!project) {
|
||||
return null
|
||||
}
|
||||
const repo = setup.repoId
|
||||
? this.state.repos.find((entry) => entry.id === setup.repoId)
|
||||
: undefined
|
||||
if (repo) {
|
||||
this.removeProject(repo.id)
|
||||
return { project, setup, repo: this.hydrateRepo(repo) }
|
||||
}
|
||||
this.state.projectHostSetups = this.state.projectHostSetups.filter(
|
||||
(entry) => entry.id !== setup.id
|
||||
)
|
||||
this.scheduleSave()
|
||||
return { project, setup }
|
||||
}
|
||||
|
||||
/**
|
||||
* O(1) read of the persisted repo count. Use this when you only need the
|
||||
* count (e.g. cohort-classifier) — `getRepos()` hydrates each repo and
|
||||
|
||||
@@ -52,6 +52,8 @@ import type {
|
||||
PersistedUIState,
|
||||
Project,
|
||||
ProjectHostSetup,
|
||||
ProjectHostSetupDeleteArgs,
|
||||
ProjectHostSetupDeleteResult,
|
||||
ProjectHostSetupExistingFolderArgs,
|
||||
ProjectHostSetupResult,
|
||||
ProjectHostSetupUpdateArgs,
|
||||
@@ -532,6 +534,7 @@ type RuntimeStore = {
|
||||
getProjects?: Store['getProjects']
|
||||
getProjectHostSetups?: Store['getProjectHostSetups']
|
||||
updateProjectHostSetup?: Store['updateProjectHostSetup']
|
||||
deleteProjectHostSetup?: Store['deleteProjectHostSetup']
|
||||
getProjectGroups?: Store['getProjectGroups']
|
||||
createProjectGroup?: Store['createProjectGroup']
|
||||
updateProjectGroup?: Store['updateProjectGroup']
|
||||
@@ -6514,6 +6517,17 @@ export class OrcaRuntimeService {
|
||||
return result
|
||||
}
|
||||
|
||||
deleteProjectHostSetup(args: ProjectHostSetupDeleteArgs): ProjectHostSetupDeleteResult {
|
||||
if (!this.store?.deleteProjectHostSetup) {
|
||||
throw new Error('runtime_unavailable')
|
||||
}
|
||||
const result = this.store.deleteProjectHostSetup(args)
|
||||
if (!result) {
|
||||
throw new Error(`Project host setup not found: ${args.setupId}`)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
listProjectGroups(): ProjectGroup[] {
|
||||
return this.store?.getProjectGroups?.() ?? []
|
||||
}
|
||||
|
||||
@@ -32,6 +32,10 @@ const ProjectHostSetupUpdate = z.object({
|
||||
})
|
||||
})
|
||||
|
||||
const ProjectHostSetupDelete = z.object({
|
||||
setupId: requiredString('Missing setup ID')
|
||||
})
|
||||
|
||||
export const PROJECT_RUNTIME_METHODS: RpcMethod[] = [
|
||||
defineMethod({
|
||||
name: 'project.list',
|
||||
@@ -56,5 +60,12 @@ export const PROJECT_RUNTIME_METHODS: RpcMethod[] = [
|
||||
handler: (params, { runtime }) => ({
|
||||
result: runtime.updateProjectHostSetup(params)
|
||||
})
|
||||
}),
|
||||
defineMethod({
|
||||
name: 'projectHostSetup.delete',
|
||||
params: ProjectHostSetupDelete,
|
||||
handler: (params, { runtime }) => ({
|
||||
result: runtime.deleteProjectHostSetup(params)
|
||||
})
|
||||
})
|
||||
]
|
||||
|
||||
@@ -454,6 +454,45 @@ describe('repo RPC methods', () => {
|
||||
expect(response).toMatchObject({ ok: true, result: { result } })
|
||||
})
|
||||
|
||||
it('routes project-host setup deletes to the runtime server', async () => {
|
||||
const result = {
|
||||
project: {
|
||||
id: 'project-1',
|
||||
displayName: 'Project',
|
||||
badgeColor: '#737373',
|
||||
sourceRepoIds: [],
|
||||
createdAt: 1,
|
||||
updatedAt: 1
|
||||
},
|
||||
setup: {
|
||||
id: 'setup-1',
|
||||
projectId: 'project-1',
|
||||
hostId: 'runtime:env-1',
|
||||
repoId: '',
|
||||
path: '/srv/project',
|
||||
displayName: 'GPU VM',
|
||||
setupState: 'ready',
|
||||
setupMethod: 'imported-existing-folder',
|
||||
createdAt: 1,
|
||||
updatedAt: 2
|
||||
}
|
||||
}
|
||||
const runtime = {
|
||||
getRuntimeId: () => 'test-runtime',
|
||||
deleteProjectHostSetup: vi.fn().mockReturnValue(result)
|
||||
} as unknown as OrcaRuntimeService
|
||||
const dispatcher = new RpcDispatcher({ runtime, methods: REPO_METHODS })
|
||||
|
||||
const response = await dispatcher.dispatch(
|
||||
makeRequest('projectHostSetup.delete', {
|
||||
setupId: 'setup-1'
|
||||
})
|
||||
)
|
||||
|
||||
expect(runtime.deleteProjectHostSetup).toHaveBeenCalledWith({ setupId: 'setup-1' })
|
||||
expect(response).toMatchObject({ ok: true, result: { result } })
|
||||
})
|
||||
|
||||
it('allows separate nested-repo imports without a group name', async () => {
|
||||
const runtime = {
|
||||
getRuntimeId: () => 'test-runtime',
|
||||
|
||||
@@ -124,6 +124,8 @@ import type {
|
||||
Repo,
|
||||
ProjectGroup,
|
||||
ProjectHostSetup,
|
||||
ProjectHostSetupDeleteArgs,
|
||||
ProjectHostSetupDeleteResult,
|
||||
ProjectHostSetupExistingFolderArgs,
|
||||
ProjectHostSetupResult,
|
||||
ProjectHostSetupUpdateArgs,
|
||||
@@ -786,6 +788,7 @@ export type PreloadApi = {
|
||||
args: ProjectHostSetupExistingFolderArgs
|
||||
) => Promise<ProjectHostSetupResult>
|
||||
updateHostSetup: (args: ProjectHostSetupUpdateArgs) => Promise<ProjectHostSetupUpdateResult>
|
||||
deleteHostSetup: (args: ProjectHostSetupDeleteArgs) => Promise<ProjectHostSetupDeleteResult>
|
||||
}
|
||||
projectGroups: {
|
||||
list: () => Promise<ProjectGroup[]>
|
||||
|
||||
@@ -510,7 +510,8 @@ const api = {
|
||||
listHostSetups: () => ipcRenderer.invoke('projectHostSetups:list'),
|
||||
setupExistingFolder: (args) =>
|
||||
ipcRenderer.invoke('projectHostSetups:setupExistingFolder', args),
|
||||
updateHostSetup: (args) => ipcRenderer.invoke('projectHostSetups:update', args)
|
||||
updateHostSetup: (args) => ipcRenderer.invoke('projectHostSetups:update', args),
|
||||
deleteHostSetup: (args) => ipcRenderer.invoke('projectHostSetups:delete', args)
|
||||
} satisfies PreloadApi['projects'],
|
||||
|
||||
projectGroups: {
|
||||
|
||||
@@ -158,6 +158,10 @@ export type ProjectHostSetupUpdateArgs = {
|
||||
>
|
||||
}
|
||||
|
||||
export type ProjectHostSetupDeleteArgs = {
|
||||
setupId: string
|
||||
}
|
||||
|
||||
export type ProjectHostSetupResult = {
|
||||
project: Project
|
||||
setup: ProjectHostSetup
|
||||
@@ -170,6 +174,12 @@ export type ProjectHostSetupUpdateResult = {
|
||||
repo?: Repo
|
||||
}
|
||||
|
||||
export type ProjectHostSetupDeleteResult = {
|
||||
project: Project
|
||||
setup: ProjectHostSetup
|
||||
repo?: Repo
|
||||
}
|
||||
|
||||
export type Repo = {
|
||||
id: string
|
||||
path: string
|
||||
|
||||
Reference in New Issue
Block a user