feat(core): project copying and tracking directories (#30139)

This commit is contained in:
James Long 2026-06-02 23:26:10 -04:00 committed by GitHub
commit 147c6c4d51
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
28 changed files with 3638 additions and 10 deletions

View file

@ -34,6 +34,12 @@ import type {
ExperimentalConsoleListOrgsErrors,
ExperimentalConsoleListOrgsResponses,
ExperimentalConsoleSwitchOrgResponses,
ExperimentalProjectCopyCreateErrors,
ExperimentalProjectCopyCreateResponses,
ExperimentalProjectCopyRefreshErrors,
ExperimentalProjectCopyRefreshResponses,
ExperimentalProjectCopyRemoveErrors,
ExperimentalProjectCopyRemoveResponses,
ExperimentalResourceListErrors,
ExperimentalResourceListResponses,
ExperimentalSessionListErrors,
@ -120,6 +126,8 @@ import type {
PermissionV2Reply,
ProjectCurrentErrors,
ProjectCurrentResponses,
ProjectDirectoriesErrors,
ProjectDirectoriesResponses,
ProjectInitGitErrors,
ProjectInitGitResponses,
ProjectListErrors,
@ -937,6 +945,148 @@ export class Resource extends HeyApiClient {
}
}
export class ProjectCopy extends HeyApiClient {
/**
* Remove project copy
*
* Remove a local physical copy of a project using the selected strategy.
*/
public remove<ThrowOnError extends boolean = false>(
parameters: {
projectID: string
query_directory?: string
workspace?: string
body_directory?: string
},
options?: Options<never, ThrowOnError>,
) {
const params = buildClientParams(
[parameters],
[
{
args: [
{ in: "path", key: "projectID" },
{
in: "query",
key: "query_directory",
map: "directory",
},
{ in: "query", key: "workspace" },
{
in: "body",
key: "body_directory",
map: "directory",
},
],
},
],
)
return (options?.client ?? this.client).delete<
ExperimentalProjectCopyRemoveResponses,
ExperimentalProjectCopyRemoveErrors,
ThrowOnError
>({
url: "/experimental/project/{projectID}/copy",
...options,
...params,
headers: {
"Content-Type": "application/json",
...options?.headers,
...params.headers,
},
})
}
/**
* Create project copy
*
* Create a local physical copy of a project using the selected strategy.
*/
public create<ThrowOnError extends boolean = false>(
parameters: {
projectID: string
query_directory?: string
workspace?: string
strategy?: "git_worktree"
body_directory?: string
},
options?: Options<never, ThrowOnError>,
) {
const params = buildClientParams(
[parameters],
[
{
args: [
{ in: "path", key: "projectID" },
{
in: "query",
key: "query_directory",
map: "directory",
},
{ in: "query", key: "workspace" },
{ in: "body", key: "strategy" },
{
in: "body",
key: "body_directory",
map: "directory",
},
],
},
],
)
return (options?.client ?? this.client).post<
ExperimentalProjectCopyCreateResponses,
ExperimentalProjectCopyCreateErrors,
ThrowOnError
>({
url: "/experimental/project/{projectID}/copy",
...options,
...params,
headers: {
"Content-Type": "application/json",
...options?.headers,
...params.headers,
},
})
}
/**
* Refresh project copies
*
* Discover local project copies using one or all configured strategies.
*/
public refresh<ThrowOnError extends boolean = false>(
parameters: {
projectID: string
directory?: string
workspace?: string
},
options?: Options<never, ThrowOnError>,
) {
const params = buildClientParams(
[parameters],
[
{
args: [
{ in: "path", key: "projectID" },
{ in: "query", key: "directory" },
{ in: "query", key: "workspace" },
],
},
],
)
return (options?.client ?? this.client).post<
ExperimentalProjectCopyRefreshResponses,
ExperimentalProjectCopyRefreshErrors,
ThrowOnError
>({
url: "/experimental/project/{projectID}/copy/refresh",
...options,
...params,
})
}
}
export class Adapter extends HeyApiClient {
/**
* List workspace adapters
@ -1226,6 +1376,11 @@ export class Experimental extends HeyApiClient {
return (this._resource ??= new Resource({ client: this.client }))
}
private _projectCopy?: ProjectCopy
get projectCopy(): ProjectCopy {
return (this._projectCopy ??= new ProjectCopy({ client: this.client }))
}
private _workspace?: Workspace
get workspace(): Workspace {
return (this._workspace ??= new Workspace({ client: this.client }))
@ -2388,6 +2543,38 @@ export class Project extends HeyApiClient {
},
})
}
/**
* List project directories
*
* List known local absolute directories for a project.
*/
public directories<ThrowOnError extends boolean = false>(
parameters: {
projectID: string
directory?: string
workspace?: string
},
options?: Options<never, ThrowOnError>,
) {
const params = buildClientParams(
[parameters],
[
{
args: [
{ in: "path", key: "projectID" },
{ in: "query", key: "directory" },
{ in: "query", key: "workspace" },
],
},
],
)
return (options?.client ?? this.client).get<ProjectDirectoriesResponses, ProjectDirectoriesErrors, ThrowOnError>({
url: "/project/{projectID}/directories",
...options,
...params,
})
}
}
export class Pty extends HeyApiClient {

View file

@ -63,6 +63,7 @@ export type Event =
| EventMcpToolsChanged
| EventMcpBrowserOpenFailed
| EventCommandExecuted
| EventProjectDirectoriesUpdated
| EventProjectUpdated
| EventPtyCreated
| EventPtyUpdated
@ -1300,6 +1301,13 @@ export type GlobalEvent = {
messageID: string
}
}
| {
id: string
type: "project.directories.updated"
properties: {
projectID: string
}
}
| {
id: string
type: "project.updated"
@ -3366,6 +3374,12 @@ export type ConfigV2ExperimentalPolicy = {
resource: string
}
export type ProjectDirectories = Array<string>
export type ProjectCopyCopy = {
directory: string
}
export type LocationRef = {
directory: string
workspaceID?: string
@ -4406,6 +4420,14 @@ export type EventCommandExecuted = {
}
}
export type EventProjectDirectoriesUpdated = {
id: string
type: "project.directories.updated"
properties: {
projectID: string
}
}
export type EventProjectUpdated = {
id: string
type: "project.updated"
@ -6254,6 +6276,137 @@ export type ProjectUpdateResponses = {
export type ProjectUpdateResponse = ProjectUpdateResponses[keyof ProjectUpdateResponses]
export type ProjectDirectoriesData = {
body?: never
path: {
projectID: string
}
query?: {
directory?: string
workspace?: string
}
url: "/project/{projectID}/directories"
}
export type ProjectDirectoriesErrors = {
/**
* Bad request
*/
400: BadRequestError
}
export type ProjectDirectoriesError = ProjectDirectoriesErrors[keyof ProjectDirectoriesErrors]
export type ProjectDirectoriesResponses = {
/**
* Project directories
*/
200: ProjectDirectories
}
export type ProjectDirectoriesResponse = ProjectDirectoriesResponses[keyof ProjectDirectoriesResponses]
export type ExperimentalProjectCopyRemoveData = {
body?: {
directory: string
}
path: {
projectID: string
}
query?: {
directory?: string
workspace?: string
}
url: "/experimental/project/{projectID}/copy"
}
export type ExperimentalProjectCopyRemoveErrors = {
/**
* BadRequest | InvalidRequestError
*/
400: EffectHttpApiErrorBadRequest | InvalidRequestError
}
export type ExperimentalProjectCopyRemoveError =
ExperimentalProjectCopyRemoveErrors[keyof ExperimentalProjectCopyRemoveErrors]
export type ExperimentalProjectCopyRemoveResponses = {
/**
* Project copy removed
*/
204: void
}
export type ExperimentalProjectCopyRemoveResponse =
ExperimentalProjectCopyRemoveResponses[keyof ExperimentalProjectCopyRemoveResponses]
export type ExperimentalProjectCopyCreateData = {
body?: {
strategy: "git_worktree"
directory: string
}
path: {
projectID: string
}
query?: {
directory?: string
workspace?: string
}
url: "/experimental/project/{projectID}/copy"
}
export type ExperimentalProjectCopyCreateErrors = {
/**
* BadRequest | InvalidRequestError
*/
400: EffectHttpApiErrorBadRequest | InvalidRequestError
}
export type ExperimentalProjectCopyCreateError =
ExperimentalProjectCopyCreateErrors[keyof ExperimentalProjectCopyCreateErrors]
export type ExperimentalProjectCopyCreateResponses = {
/**
* Project copy created
*/
200: ProjectCopyCopy
}
export type ExperimentalProjectCopyCreateResponse =
ExperimentalProjectCopyCreateResponses[keyof ExperimentalProjectCopyCreateResponses]
export type ExperimentalProjectCopyRefreshData = {
body?: never
path: {
projectID: string
}
query?: {
directory?: string
workspace?: string
}
url: "/experimental/project/{projectID}/copy/refresh"
}
export type ExperimentalProjectCopyRefreshErrors = {
/**
* BadRequest | InvalidRequestError
*/
400: EffectHttpApiErrorBadRequest | InvalidRequestError
}
export type ExperimentalProjectCopyRefreshError =
ExperimentalProjectCopyRefreshErrors[keyof ExperimentalProjectCopyRefreshErrors]
export type ExperimentalProjectCopyRefreshResponses = {
/**
* Project copies refreshed
*/
204: void
}
export type ExperimentalProjectCopyRefreshResponse =
ExperimentalProjectCopyRefreshResponses[keyof ExperimentalProjectCopyRefreshResponses]
export type PtyShellsData = {
body?: never
path?: never