mirror of
https://gitee.com/zhangsken/opencode.git
synced 2026-10-16 10:30:01 +08:00
refactor(protocol): remove current project endpoint
This commit is contained in:
@@ -0,0 +1,261 @@
|
||||
# V2 HTTP API audit checklist
|
||||
|
||||
**Source:** `packages/protocol/openapi.json`
|
||||
**Current endpoint count:** 143
|
||||
**Last regenerated:** 2026-09-13
|
||||
|
||||
## How to use this checklist
|
||||
|
||||
Review endpoints in document order. For each endpoint, select one disposition and capture rationale or follow-up work in Notes. Mark **Reviewed** only after the disposition is agreed.
|
||||
|
||||
### Review criteria
|
||||
|
||||
- Resource and operation naming
|
||||
- HTTP method and idempotency
|
||||
- Request parameters and location scope
|
||||
- Response shape and error taxonomy
|
||||
- Authentication and authorization
|
||||
- Current production consumers
|
||||
- Stability level: public, experimental, or internal
|
||||
- Whether the generated client API is intuitive
|
||||
|
||||
### Disposition legend
|
||||
|
||||
- **Keep:** ship unchanged as a supported V2 API
|
||||
- **Change:** retain after a defined contract change
|
||||
- **Remove:** exclude from the official V2 API
|
||||
- **Experimental-only:** retain outside the stable API commitment
|
||||
|
||||
## Progress
|
||||
|
||||
- [ ] Group 1: Foundation and placement (7)
|
||||
- [ ] Group 2: Configuration and capability catalogs (17)
|
||||
- [ ] Group 3: Credentials, integrations, MCP, and web search (22)
|
||||
- [ ] Group 4: Session lifecycle (12)
|
||||
- [ ] Group 5: Session execution and inputs (11)
|
||||
- [ ] Group 6: Session history and recovery (13)
|
||||
- [ ] Group 7: Inbox, permissions, and forms (19)
|
||||
- [ ] Group 8: Filesystem, worktrees, and VCS (12)
|
||||
- [ ] Group 9: PTYs, persistent terminals, and shells (24)
|
||||
- [ ] Group 10: Events, RPC, and experimental operations (6)
|
||||
|
||||
## Resolved during audit
|
||||
|
||||
### [x] `GET /api/project/current`
|
||||
|
||||
- **Decision:** Remove
|
||||
- **Replacement:** `GET /api/location`, using `project` from the response.
|
||||
- **Notes:** The endpoint duplicated `Location.Info.project`; production callers were migrated.
|
||||
|
||||
## Group 1: Foundation and placement
|
||||
|
||||
**Endpoints:** 7
|
||||
|
||||
| Done | Method | Path | Operation ID | Decision | Notes |
|
||||
|---|---|---|---|---|---|
|
||||
| [ ] 001 | `GET` | `/api/health` | `v2.health.get` | | |
|
||||
| [ ] 002 | `GET` | `/api/server` | `v2.server.get` | | |
|
||||
| [ ] 003 | `GET` | `/api/location` | `v2.location.get` | | |
|
||||
| [ ] 004 | `GET` | `/api/project` | `v2.project.list` | | |
|
||||
| [ ] 005 | `PATCH` | `/api/project/{projectID}` | `v2.project.update` | | |
|
||||
| [ ] 006 | `POST` | `/api/workspace` | `v2.workspace.create` | Proposed remove | Awaiting feedback in `#core`. |
|
||||
| [ ] 007 | `DELETE` | `/api/workspace/{workspaceID}` | `v2.workspace.destroy` | Proposed remove | Awaiting feedback in `#core`. |
|
||||
|
||||
## Group 2: Configuration and capability catalogs
|
||||
|
||||
**Endpoints:** 17
|
||||
|
||||
| Done | Method | Path | Operation ID | Decision | Notes |
|
||||
|---|---|---|---|---|---|
|
||||
| [ ] 008 | `GET` | `/api/agent` | `v2.agent.list` | | |
|
||||
| [ ] 009 | `GET` | `/api/agent/{agentID}` | `v2.agent.get` | | |
|
||||
| [ ] 010 | `GET` | `/api/plugin` | `v2.plugin.list` | | |
|
||||
| [ ] 011 | `POST` | `/api/plugin/await-activation` | `v2.plugin.awaitActivation` | | |
|
||||
| [ ] 012 | `POST` | `/api/plugin/check` | `v2.plugin.check` | | |
|
||||
| [ ] 013 | `POST` | `/api/plugin/update` | `v2.plugin.update` | | |
|
||||
| [ ] 014 | `GET` | `/api/model` | `v2.model.list` | | |
|
||||
| [ ] 015 | `GET` | `/api/model/default` | `v2.model.default` | | |
|
||||
| [ ] 016 | `GET` | `/api/provider` | `v2.provider.list` | | |
|
||||
| [ ] 017 | `GET` | `/api/provider/{providerID}` | `v2.provider.get` | | |
|
||||
| [ ] 018 | `GET` | `/api/command` | `v2.command.list` | | |
|
||||
| [ ] 019 | `GET` | `/api/skill` | `v2.skill.list` | | |
|
||||
| [ ] 020 | `GET` | `/api/reference` | `v2.reference.list` | | |
|
||||
| [ ] 021 | `GET` | `/api/config` | `v2.config.get` | | |
|
||||
| [ ] 022 | `GET` | `/api/config/preferences` | `v2.config.preferences` | | |
|
||||
| [ ] 023 | `PATCH` | `/api/config/preferences` | `v2.config.updatePreferences` | | |
|
||||
| [ ] 024 | `GET` | `/api/config/shell` | `v2.config.shells` | | |
|
||||
|
||||
## Group 3: Credentials, integrations, MCP, and web search
|
||||
|
||||
**Endpoints:** 22
|
||||
|
||||
| Done | Method | Path | Operation ID | Decision | Notes |
|
||||
|---|---|---|---|---|---|
|
||||
| [ ] 025 | `GET` | `/api/integration` | `v2.integration.list` | | |
|
||||
| [ ] 026 | `GET` | `/api/integration/{integrationID}` | `v2.integration.get` | | |
|
||||
| [ ] 027 | `POST` | `/api/experimental/integration/wellknown` | `v2.experimental.integration.wellknown.add` | | |
|
||||
| [ ] 028 | `POST` | `/api/integration/{integrationID}/connect/key` | `v2.integration.connect.key` | | |
|
||||
| [ ] 029 | `POST` | `/api/integration/{integrationID}/connect/oauth` | `v2.integration.oauth.connect` | | |
|
||||
| [ ] 030 | `GET` | `/api/integration/{integrationID}/connect/oauth/{attemptID}` | `v2.integration.oauth.status` | | |
|
||||
| [ ] 031 | `DELETE` | `/api/integration/{integrationID}/connect/oauth/{attemptID}` | `v2.integration.oauth.cancel` | | |
|
||||
| [ ] 032 | `POST` | `/api/integration/{integrationID}/connect/oauth/{attemptID}/complete` | `v2.integration.oauth.complete` | | |
|
||||
| [ ] 033 | `POST` | `/api/integration/{integrationID}/connect/command` | `v2.integration.command.connect` | | |
|
||||
| [ ] 034 | `GET` | `/api/integration/{integrationID}/connect/command/{attemptID}` | `v2.integration.command.status` | | |
|
||||
| [ ] 035 | `DELETE` | `/api/integration/{integrationID}/connect/command/{attemptID}` | `v2.integration.command.cancel` | | |
|
||||
| [ ] 036 | `GET` | `/api/mcp` | `v2.mcp.list` | | |
|
||||
| [ ] 037 | `PUT` | `/api/mcp/{server}` | `v2.mcp.add` | | |
|
||||
| [ ] 038 | `DELETE` | `/api/mcp/{server}` | `v2.mcp.remove` | | |
|
||||
| [ ] 039 | `POST` | `/api/mcp/{server}/connect` | `v2.mcp.connect` | | |
|
||||
| [ ] 040 | `POST` | `/api/mcp/{server}/disconnect` | `v2.mcp.disconnect` | | |
|
||||
| [ ] 041 | `GET` | `/api/mcp/resource` | `v2.mcp.resource.catalog` | | |
|
||||
| [ ] 042 | `PATCH` | `/api/credential/{credentialID}` | `v2.credential.update` | | |
|
||||
| [ ] 043 | `DELETE` | `/api/credential/{credentialID}` | `v2.credential.remove` | | |
|
||||
| [ ] 044 | `POST` | `/api/credential/{credentialID}/activate` | `v2.credential.activate` | | |
|
||||
| [ ] 045 | `GET` | `/api/websearch/provider` | `v2.websearch.providers` | | |
|
||||
| [ ] 046 | `POST` | `/api/websearch` | `v2.websearch.query` | | |
|
||||
|
||||
## Group 4: Session lifecycle
|
||||
|
||||
**Endpoints:** 12
|
||||
|
||||
| Done | Method | Path | Operation ID | Decision | Notes |
|
||||
|---|---|---|---|---|---|
|
||||
| [ ] 047 | `GET` | `/api/session` | `v2.session.list` | | |
|
||||
| [ ] 048 | `POST` | `/api/session` | `v2.session.create` | | |
|
||||
| [ ] 049 | `GET` | `/api/session/stats` | `v2.session.stats` | | |
|
||||
| [ ] 050 | `GET` | `/api/session/active` | `v2.session.active` | | |
|
||||
| [ ] 051 | `GET` | `/api/session/{sessionID}` | `v2.session.get` | | |
|
||||
| [ ] 052 | `DELETE` | `/api/session/{sessionID}` | `v2.session.remove` | | |
|
||||
| [ ] 053 | `POST` | `/api/session/{sessionID}/fork` | `v2.session.fork` | | |
|
||||
| [ ] 054 | `POST` | `/api/session/{sessionID}/agent` | `v2.session.switchAgent` | | |
|
||||
| [ ] 055 | `POST` | `/api/session/{sessionID}/model` | `v2.session.switchModel` | | |
|
||||
| [ ] 056 | `POST` | `/api/session/{sessionID}/rename` | `v2.session.rename` | | |
|
||||
| [ ] 057 | `POST` | `/api/session/{sessionID}/move` | `v2.session.move` | | |
|
||||
| [ ] 058 | `POST` | `/api/session/{sessionID}/background` | `v2.session.background` | | |
|
||||
|
||||
## Group 5: Session execution and inputs
|
||||
|
||||
**Endpoints:** 11
|
||||
|
||||
| Done | Method | Path | Operation ID | Decision | Notes |
|
||||
|---|---|---|---|---|---|
|
||||
| [ ] 059 | `POST` | `/api/session/{sessionID}/prompt` | `v2.session.prompt` | | |
|
||||
| [ ] 060 | `POST` | `/api/session/{sessionID}/command` | `v2.session.command` | | |
|
||||
| [ ] 061 | `POST` | `/api/session/{sessionID}/skill` | `v2.session.skill` | | |
|
||||
| [ ] 062 | `POST` | `/api/session/{sessionID}/synthetic` | `v2.session.synthetic` | | |
|
||||
| [ ] 063 | `POST` | `/api/session/{sessionID}/shell` | `v2.session.shell` | | |
|
||||
| [ ] 064 | `POST` | `/api/session/{sessionID}/compact` | `v2.session.compact` | | |
|
||||
| [ ] 065 | `POST` | `/api/session/{sessionID}/wait` | `v2.session.wait` | | |
|
||||
| [ ] 066 | `POST` | `/api/session/{sessionID}/generate` | `v2.session.generate` | | |
|
||||
| [ ] 067 | `POST` | `/api/session/{sessionID}/interrupt` | `v2.session.interrupt` | | |
|
||||
| [ ] 068 | `PUT` | `/api/session/{sessionID}/environment` | `v2.session.environment` | | |
|
||||
| [ ] 069 | `POST` | `/api/session/{sessionID}/view` | `v2.session.view` | | |
|
||||
|
||||
## Group 6: Session history and recovery
|
||||
|
||||
**Endpoints:** 13
|
||||
|
||||
| Done | Method | Path | Operation ID | Decision | Notes |
|
||||
|---|---|---|---|---|---|
|
||||
| [ ] 070 | `POST` | `/api/session/import` | `v2.session.import` | | |
|
||||
| [ ] 071 | `GET` | `/api/session/{sessionID}/export` | `v2.session.export` | | |
|
||||
| [ ] 072 | `POST` | `/api/session/{sessionID}/revert/stage` | `v2.session.revert.stage` | | |
|
||||
| [ ] 073 | `POST` | `/api/session/{sessionID}/revert/clear` | `v2.session.revert.clear` | | |
|
||||
| [ ] 074 | `POST` | `/api/session/{sessionID}/revert/commit` | `v2.session.revert.commit` | | |
|
||||
| [ ] 075 | `GET` | `/api/session/{sessionID}/context` | `v2.session.context` | | |
|
||||
| [ ] 076 | `GET` | `/api/session/{sessionID}/diff` | `v2.session.diff` | | |
|
||||
| [ ] 077 | `GET` | `/api/session/{sessionID}/instructions/entries` | `v2.session.instructions.entry.list` | | |
|
||||
| [ ] 078 | `PUT` | `/api/session/{sessionID}/instructions/entries/{key}` | `v2.session.instructions.entry.put` | | |
|
||||
| [ ] 079 | `DELETE` | `/api/session/{sessionID}/instructions/entries/{key}` | `v2.session.instructions.entry.remove` | | |
|
||||
| [ ] 080 | `GET` | `/api/experimental/session/{sessionID}/log` | `v2.session.log` | | |
|
||||
| [ ] 081 | `GET` | `/api/session/{sessionID}/message/{messageID}` | `v2.session.message` | | |
|
||||
| [ ] 082 | `GET` | `/api/session/{sessionID}/message` | `v2.message.list` | | |
|
||||
|
||||
## Group 7: Inbox, permissions, and forms
|
||||
|
||||
**Endpoints:** 19
|
||||
|
||||
| Done | Method | Path | Operation ID | Decision | Notes |
|
||||
|---|---|---|---|---|---|
|
||||
| [ ] 083 | `GET` | `/api/session/{sessionID}/inbox` | `v2.session.inbox.list` | | |
|
||||
| [ ] 084 | `DELETE` | `/api/session/{sessionID}/inbox/{inboxID}` | `v2.session.inbox.cancel` | | |
|
||||
| [ ] 085 | `POST` | `/api/session/{sessionID}/inbox/{inboxID}/steer` | `v2.session.inbox.steer` | | |
|
||||
| [ ] 086 | `POST` | `/api/session/{sessionID}/inbox/{inboxID}/queue` | `v2.session.inbox.queue` | | |
|
||||
| [ ] 087 | `GET` | `/api/form/request` | `v2.form.request.list` | | |
|
||||
| [ ] 088 | `GET` | `/api/session/{sessionID}/form` | `v2.session.form.list` | | |
|
||||
| [ ] 089 | `POST` | `/api/session/{sessionID}/form` | `v2.session.form.create` | | |
|
||||
| [ ] 090 | `GET` | `/api/session/{sessionID}/form/{formID}` | `v2.session.form.get` | | |
|
||||
| [ ] 091 | `GET` | `/api/session/{sessionID}/form/{formID}/state` | `v2.session.form.state` | | |
|
||||
| [ ] 092 | `POST` | `/api/session/{sessionID}/form/{formID}/reply` | `v2.session.form.reply` | | |
|
||||
| [ ] 093 | `POST` | `/api/session/{sessionID}/form/{formID}/cancel` | `v2.session.form.cancel` | | |
|
||||
| [ ] 094 | `GET` | `/api/permission/request` | `v2.permission.request.list` | | |
|
||||
| [ ] 095 | `GET` | `/api/permission/saved` | `v2.permission.saved.list` | | |
|
||||
| [ ] 096 | `DELETE` | `/api/permission/saved/{id}` | `v2.permission.saved.remove` | | |
|
||||
| [ ] 097 | `POST` | `/api/session/{sessionID}/permission` | `v2.session.permission.create` | | |
|
||||
| [ ] 098 | `GET` | `/api/session/{sessionID}/permission` | `v2.session.permission.list` | | |
|
||||
| [ ] 099 | `GET` | `/api/session/{sessionID}/permission/{requestID}` | `v2.session.permission.get` | | |
|
||||
| [ ] 100 | `POST` | `/api/session/{sessionID}/permission/{requestID}/reply` | `v2.session.permission.reply` | | |
|
||||
| [ ] 101 | `PUT` | `/api/session/{sessionID}/permission/rules` | `v2.session.permission.rules` | | |
|
||||
|
||||
## Group 8: Filesystem, worktrees, and VCS
|
||||
|
||||
**Endpoints:** 12
|
||||
|
||||
| Done | Method | Path | Operation ID | Decision | Notes |
|
||||
|---|---|---|---|---|---|
|
||||
| [ ] 102 | `GET` | `/api/fs/read/*` | `v2.fs.read` | | |
|
||||
| [ ] 103 | `GET` | `/api/fs/list` | `v2.fs.list` | | |
|
||||
| [ ] 104 | `GET` | `/api/fs/find` | `v2.fs.find` | | |
|
||||
| [ ] 105 | `GET` | `/api/worktree` | `v2.worktree.list` | | |
|
||||
| [ ] 106 | `POST` | `/api/worktree` | `v2.worktree.create` | | |
|
||||
| [ ] 107 | `DELETE` | `/api/worktree` | `v2.worktree.remove` | | |
|
||||
| [ ] 108 | `POST` | `/api/worktree/refresh` | `v2.worktree.refresh` | | |
|
||||
| [ ] 109 | `GET` | `/api/vcs` | `v2.vcs.get` | | |
|
||||
| [ ] 110 | `GET` | `/api/vcs/base` | `v2.vcs.base` | | |
|
||||
| [ ] 111 | `GET` | `/api/vcs/status` | `v2.vcs.status` | | |
|
||||
| [ ] 112 | `GET` | `/api/vcs/branches` | `v2.vcs.branches` | | |
|
||||
| [ ] 113 | `GET` | `/api/vcs/diff` | `v2.vcs.diff` | | |
|
||||
|
||||
## Group 9: PTYs, persistent terminals, and shells
|
||||
|
||||
**Endpoints:** 24
|
||||
|
||||
| Done | Method | Path | Operation ID | Decision | Notes |
|
||||
|---|---|---|---|---|---|
|
||||
| [ ] 114 | `GET` | `/api/pty` | `v2.pty.list` | | |
|
||||
| [ ] 115 | `POST` | `/api/pty` | `v2.pty.create` | | |
|
||||
| [ ] 116 | `GET` | `/api/pty/{ptyID}` | `v2.pty.get` | | |
|
||||
| [ ] 117 | `PUT` | `/api/pty/{ptyID}` | `v2.pty.update` | | |
|
||||
| [ ] 118 | `DELETE` | `/api/pty/{ptyID}` | `v2.pty.remove` | | |
|
||||
| [ ] 119 | `POST` | `/api/pty/{ptyID}/connect-token` | `v2.pty.connect.token` | | |
|
||||
| [ ] 120 | `GET` | `/api/pty/{ptyID}/connect` | `v2.pty.connect` | | |
|
||||
| [ ] 121 | `GET` | `/api/experimental/session/{sessionID}/terminal/read` | `server.experimental.persistentPty.read` | | |
|
||||
| [ ] 122 | `GET` | `/api/experimental/session/{sessionID}/terminal` | `server.experimental.persistentPty.list` | | |
|
||||
| [ ] 123 | `POST` | `/api/experimental/session/{sessionID}/terminal` | `server.experimental.persistentPty.create` | | |
|
||||
| [ ] 124 | `POST` | `/api/experimental/persistent-pty/shutdown` | `server.experimental.persistentPty.shutdown` | | |
|
||||
| [ ] 125 | `POST` | `/api/experimental/persistent-pty/handoff` | `server.experimental.persistentPty.handoff` | | |
|
||||
| [ ] 126 | `GET` | `/api/experimental/persistent-pty/{ptyID}` | `server.experimental.persistentPty.get` | | |
|
||||
| [ ] 127 | `PUT` | `/api/experimental/persistent-pty/{ptyID}` | `server.experimental.persistentPty.update` | | |
|
||||
| [ ] 128 | `DELETE` | `/api/experimental/persistent-pty/{ptyID}` | `server.experimental.persistentPty.remove` | | |
|
||||
| [ ] 129 | `GET` | `/api/experimental/persistent-pty/{ptyID}/snapshot` | `server.experimental.persistentPty.snapshot` | | |
|
||||
| [ ] 130 | `POST` | `/api/experimental/persistent-pty/{ptyID}/connect-token` | `server.experimental.persistentPty.connectToken` | | |
|
||||
| [ ] 131 | `GET` | `/api/experimental/persistent-pty/{ptyID}/connect` | `v2.persistentPty.connect` | | |
|
||||
| [ ] 132 | `GET` | `/api/shell` | `v2.shell.list` | | |
|
||||
| [ ] 133 | `POST` | `/api/shell` | `v2.shell.create` | | |
|
||||
| [ ] 134 | `GET` | `/api/shell/{id}` | `v2.shell.get` | | |
|
||||
| [ ] 135 | `DELETE` | `/api/shell/{id}` | `v2.shell.remove` | | |
|
||||
| [ ] 136 | `PATCH` | `/api/shell/{id}/timeout` | `v2.shell.timeout` | | |
|
||||
| [ ] 137 | `GET` | `/api/shell/{id}/output` | `v2.shell.output` | | |
|
||||
|
||||
## Group 10: Events, RPC, and experimental operations
|
||||
|
||||
**Endpoints:** 6
|
||||
|
||||
| Done | Method | Path | Operation ID | Decision | Notes |
|
||||
|---|---|---|---|---|---|
|
||||
| [ ] 138 | `POST` | `/api/generate` | `v2.generate.text` | | |
|
||||
| [ ] 139 | `POST` | `/api/rpc/{rpcID}/{method}` | `v2.rpc.call` | | |
|
||||
| [ ] 140 | `GET` | `/api/event` | `v2.event.subscribe` | | |
|
||||
| [ ] 141 | `GET` | `/api/debug/location` | `v2.debug.location.list` | | |
|
||||
| [ ] 142 | `DELETE` | `/api/debug/location` | `v2.debug.location.evict` | | |
|
||||
| [ ] 143 | `GET` | `/api/experimental/migration/v1` | `v2.experimental.migration.v1.status` | | |
|
||||
@@ -76,7 +76,7 @@ async function mockServers(page: Page, requests: string[]) {
|
||||
if (url.pathname === "/api/mcp") return json(route, { location: { directory: current.directory }, data: [] })
|
||||
if (url.pathname === "/api/mcp/resource")
|
||||
return json(route, { location: { directory: current.directory }, data: { resources: [], templates: [] } })
|
||||
if (url.pathname === "/api/project" || url.pathname === "/api/project/current") {
|
||||
if (url.pathname === "/api/project") {
|
||||
const project = {
|
||||
id: current.projectID,
|
||||
canonical: current.directory,
|
||||
@@ -84,7 +84,7 @@ async function mockServers(page: Page, requests: string[]) {
|
||||
time: { created: 1, updated: 1 },
|
||||
sandboxes: [],
|
||||
}
|
||||
return json(route, url.pathname === "/api/project" ? [project] : { id: project.id, directory: current.directory })
|
||||
return json(route, [project])
|
||||
}
|
||||
if (url.pathname === "/api/location")
|
||||
return json(route, {
|
||||
|
||||
@@ -398,8 +398,6 @@ async function mockServers(
|
||||
},
|
||||
])
|
||||
}
|
||||
if (url.pathname === "/api/project/current")
|
||||
return json(route, { id: remote ? sessionB.projectID : "project-server-a", directory, canonical: directory })
|
||||
if (url.pathname === "/api/session")
|
||||
return json(route, { data: sessions.map((session) => currentSession(session)), cursor: {} })
|
||||
if (url.pathname === "/api/session/active")
|
||||
|
||||
@@ -592,7 +592,7 @@ async function mockServer(page: Page) {
|
||||
if (url.pathname === "/api/mcp") return json(route, { location: { directory: sessionA.directory }, data: [] })
|
||||
if (url.pathname === "/api/mcp/resource")
|
||||
return json(route, { location: { directory: sessionA.directory }, data: { resources: [], templates: [] } })
|
||||
if (url.pathname === "/api/project" || url.pathname === "/api/project/current") {
|
||||
if (url.pathname === "/api/project") {
|
||||
const project = {
|
||||
id: sessionA.projectID,
|
||||
canonical: sessionA.directory,
|
||||
@@ -600,10 +600,7 @@ async function mockServer(page: Page) {
|
||||
time: { created: 1, updated: 1 },
|
||||
sandboxes: [],
|
||||
}
|
||||
return json(
|
||||
route,
|
||||
url.pathname === "/api/project" ? [project] : { id: project.id, directory: sessionA.directory },
|
||||
)
|
||||
return json(route, [project])
|
||||
}
|
||||
if (url.pathname === "/api/location")
|
||||
return json(route, {
|
||||
|
||||
@@ -77,7 +77,6 @@ const Group = HttpApiGroup.make("mock")
|
||||
success: Json,
|
||||
}),
|
||||
)
|
||||
.add(HttpApiEndpoint.get("projectCurrent", "/api/project/current", { success: Json }))
|
||||
.add(HttpApiEndpoint.get("configPreferences", "/api/config/preferences", { success: Json }))
|
||||
.add(
|
||||
HttpApiEndpoint.patch("configUpdatePreferences", "/api/config/preferences", {
|
||||
|
||||
@@ -110,7 +110,7 @@ export function createHomeController() {
|
||||
.list({ path: ".", location })
|
||||
.then(async (files) => {
|
||||
// TODO: Initialize empty directories when V2 exposes a native Git init API.
|
||||
return ctx.sdk.api.project.current({ location })
|
||||
return ctx.sdk.api.location.get({ location }).then((result) => result.project)
|
||||
})
|
||||
.then((project) => ctx.sync.child(item, { bootstrap: false })[1]("project", project.id))
|
||||
.catch(() => undefined)
|
||||
|
||||
@@ -2,8 +2,6 @@ import type { Config, Path, Project, ProviderAuthResponse } from "@/runtime/serv
|
||||
import type {
|
||||
LocationGetInput,
|
||||
LocationGetOutput,
|
||||
ProjectCurrentInput,
|
||||
ProjectCurrentOutput,
|
||||
ProjectListOutput,
|
||||
} from "@opencode/client/promise"
|
||||
import { showToast } from "@/shell/notifications/toast"
|
||||
@@ -61,7 +59,6 @@ export const loadGlobalConfigQuery = (scope: ServerScope) =>
|
||||
|
||||
type ProjectApi = {
|
||||
readonly list: () => Promise<ProjectListOutput>
|
||||
readonly current: (input?: ProjectCurrentInput) => Promise<ProjectCurrentOutput>
|
||||
}
|
||||
type LocationApi = { readonly get: (input?: LocationGetInput) => Promise<LocationGetOutput> }
|
||||
|
||||
@@ -132,6 +129,7 @@ export async function bootstrapDirectory(input: {
|
||||
mcp: boolean
|
||||
api: {
|
||||
readonly project: ProjectApi
|
||||
readonly location: LocationApi
|
||||
}
|
||||
store: Store<State>
|
||||
setStore: SetStoreFunction<State>
|
||||
@@ -155,8 +153,8 @@ export async function bootstrapDirectory(input: {
|
||||
seededProject
|
||||
? undefined
|
||||
: () =>
|
||||
retry(() => input.api.project.current({ location: { directory: input.directory } })).then((project) =>
|
||||
input.setStore("project", project.id),
|
||||
retry(() => input.api.location.get({ location: { directory: input.directory } })).then((location) =>
|
||||
input.setStore("project", location.project.id),
|
||||
),
|
||||
].filter((task): task is () => Promise<void> => !!task)
|
||||
|
||||
|
||||
@@ -1489,16 +1489,9 @@ export type ProjectUpdateInput = {
|
||||
export type ProjectUpdateOutput = Project.Info
|
||||
export type ProjectUpdateOperation<E = never> = (input: ProjectUpdateInput) => Effect.Effect<ProjectUpdateOutput, E>
|
||||
|
||||
export type ProjectCurrentInput = {
|
||||
readonly location?: { readonly directory?: string | undefined; readonly workspace?: string | undefined } | undefined
|
||||
}
|
||||
export type ProjectCurrentOutput = Project.Current
|
||||
export type ProjectCurrentOperation<E = never> = (input?: ProjectCurrentInput) => Effect.Effect<ProjectCurrentOutput, E>
|
||||
|
||||
export interface ProjectApi<E = never> {
|
||||
readonly list: ProjectListOperation<E>
|
||||
readonly update: ProjectUpdateOperation<E>
|
||||
readonly current: ProjectCurrentOperation<E>
|
||||
}
|
||||
|
||||
export type FormRequestListInput = {
|
||||
|
||||
@@ -153,8 +153,6 @@ import type {
|
||||
ProjectListOutput,
|
||||
ProjectUpdateInput,
|
||||
ProjectUpdateOutput,
|
||||
ProjectCurrentInput,
|
||||
ProjectCurrentOutput,
|
||||
FormRequestListInput,
|
||||
FormRequestListOutput,
|
||||
FormListInput,
|
||||
@@ -1029,15 +1027,9 @@ const EndpointProjectUpdate = (raw: RawClient["server.project"]) => (input: Proj
|
||||
}).pipe(Effect.mapError(mapClientError)),
|
||||
)
|
||||
|
||||
const EndpointProjectCurrent = (raw: RawClient["server.project"]) => (input?: ProjectCurrentInput) =>
|
||||
preserveEffect<ProjectCurrentOutput>()(
|
||||
raw["project.current"]({ query: { location: input?.["location"] } }).pipe(Effect.mapError(mapClientError)),
|
||||
)
|
||||
|
||||
const adaptGroupProject = (raw: RawClient["server.project"]) => ({
|
||||
list: EndpointProjectList(raw),
|
||||
update: EndpointProjectUpdate(raw),
|
||||
current: EndpointProjectCurrent(raw),
|
||||
})
|
||||
|
||||
const EndpointFormRequestList = (raw: RawClient["server.form"]) => (input?: FormRequestListInput) =>
|
||||
|
||||
@@ -147,8 +147,6 @@ import type {
|
||||
ProjectListOutput,
|
||||
ProjectUpdateInput,
|
||||
ProjectUpdateOutput,
|
||||
ProjectCurrentInput,
|
||||
ProjectCurrentOutput,
|
||||
FormRequestListInput,
|
||||
FormRequestListOutput,
|
||||
FormListInput,
|
||||
@@ -1396,18 +1394,6 @@ export function make(options: ClientOptions) {
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
current: (input?: ProjectCurrentInput, requestOptions?: RequestOptions) =>
|
||||
request<ProjectCurrentOutput>(
|
||||
{
|
||||
method: "GET",
|
||||
path: `/api/project/current`,
|
||||
query: { location: input?.["location"] },
|
||||
successStatus: 200,
|
||||
declaredStatuses: [400, 401],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
},
|
||||
form: {
|
||||
request: {
|
||||
|
||||
@@ -310,8 +310,6 @@ export type ProjectCommands = { start?: string }
|
||||
|
||||
export type ProjectTime = { created: number; updated: number; initialized?: number }
|
||||
|
||||
export type ProjectCurrent = { id: string; directory: string; canonical: string }
|
||||
|
||||
export type FormMetadata = { [x: string]: JsonValue }
|
||||
|
||||
export type FormValue = string | number | boolean | Array<string>
|
||||
@@ -4912,14 +4910,6 @@ export type ProjectUpdateInput = {
|
||||
|
||||
export type ProjectUpdateOutput = Project
|
||||
|
||||
export type ProjectCurrentInput = {
|
||||
readonly location?: {
|
||||
readonly location?: { readonly directory?: string | undefined; readonly workspace?: string | undefined } | undefined
|
||||
}["location"]
|
||||
}
|
||||
|
||||
export type ProjectCurrentOutput = ProjectCurrent
|
||||
|
||||
export type FormRequestListInput = {
|
||||
readonly location?: {
|
||||
readonly location?: { readonly directory?: string | undefined; readonly workspace?: string | undefined } | undefined
|
||||
|
||||
@@ -5170,89 +5170,6 @@
|
||||
"summary": "List projects"
|
||||
}
|
||||
},
|
||||
"/api/project/current": {
|
||||
"get": {
|
||||
"tags": ["project"],
|
||||
"operationId": "v2.project.current",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "location",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"directory": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"workspace": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"required": false,
|
||||
"style": "deepObject",
|
||||
"explode": true
|
||||
}
|
||||
],
|
||||
"security": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Project.Current",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Project.Current"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "InvalidRequestError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/InvalidRequestError"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "UnauthorizedError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UnauthorizedError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Resolve the project for the requested location.",
|
||||
"summary": "Get current project"
|
||||
}
|
||||
},
|
||||
"/api/project/{projectID}/directories": {
|
||||
"get": {
|
||||
"tags": ["project"],
|
||||
|
||||
+299
-99
@@ -1115,6 +1115,16 @@
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"permissions": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/Permission.Ruleset"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
@@ -7466,89 +7476,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/project/current": {
|
||||
"get": {
|
||||
"tags": ["project"],
|
||||
"operationId": "v2.project.current",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "location",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"directory": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"workspace": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"required": false,
|
||||
"style": "deepObject",
|
||||
"explode": true
|
||||
}
|
||||
],
|
||||
"security": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Project.Current",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Project.Current"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "InvalidRequestError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/InvalidRequestErrorEncoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "UnauthorizedError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UnauthorizedErrorEncoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Resolve the project for the requested location.",
|
||||
"summary": "Get current project"
|
||||
}
|
||||
},
|
||||
"/api/form/request": {
|
||||
"get": {
|
||||
"tags": ["form"],
|
||||
@@ -8783,6 +8710,85 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/session/{sessionID}/permission/rules": {
|
||||
"put": {
|
||||
"tags": ["permission"],
|
||||
"operationId": "v2.session.permission.rules",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "sessionID",
|
||||
"in": "path",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"pattern": "^ses"
|
||||
},
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"security": [],
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "<No Content>"
|
||||
},
|
||||
"400": {
|
||||
"description": "InvalidRequestError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/InvalidRequestErrorEncoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "UnauthorizedError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UnauthorizedErrorEncoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "SessionNotFoundError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/SessionNotFoundErrorEncoded"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/SessionNotFoundErrorEncoded"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Replace the session-scoped permission rules. Rules are evaluated after the agent's rules, and the last matching rule wins.",
|
||||
"summary": "Replace session permission rules",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"permissions": {
|
||||
"$ref": "#/components/schemas/Permission.Ruleset"
|
||||
}
|
||||
},
|
||||
"required": ["permissions"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/fs/read/*": {
|
||||
"get": {
|
||||
"tags": ["filesystem"],
|
||||
@@ -13672,6 +13678,143 @@
|
||||
"description": "Return configuration documents and discovery sources for the requested location, from lowest to highest priority.",
|
||||
"summary": "Get configuration"
|
||||
}
|
||||
},
|
||||
"/api/config/preferences": {
|
||||
"get": {
|
||||
"tags": ["config"],
|
||||
"operationId": "v2.config.preferences",
|
||||
"parameters": [],
|
||||
"security": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Config.Preferences",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Config.Preferences"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "InvalidRequestError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/InvalidRequestErrorEncoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "UnauthorizedError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UnauthorizedErrorEncoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Return preferences from the highest-precedence global configuration document.",
|
||||
"summary": "Get global preferences"
|
||||
},
|
||||
"patch": {
|
||||
"tags": ["config"],
|
||||
"operationId": "v2.config.updatePreferences",
|
||||
"parameters": [],
|
||||
"security": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Config.Preferences",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Config.Preferences"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "InvalidRequestError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/InvalidRequestErrorEncoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "UnauthorizedError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UnauthorizedErrorEncoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Patch preferences in the highest-precedence global configuration document.",
|
||||
"summary": "Update global preferences",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Config.PreferencesPatch"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/config/shell": {
|
||||
"get": {
|
||||
"tags": ["config"],
|
||||
"operationId": "v2.config.shells",
|
||||
"parameters": [],
|
||||
"security": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ConfigShell.Option"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "InvalidRequestError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/InvalidRequestErrorEncoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "UnauthorizedError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UnauthorizedErrorEncoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Return shells available to terminal and agent execution.",
|
||||
"summary": "List available shells"
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
@@ -14532,6 +14675,60 @@
|
||||
"required": ["package"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Config.Preferences": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"shell": {
|
||||
"type": "string"
|
||||
},
|
||||
"websearch": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"enum": [false]
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/ConfigWebSearch.InfoEncoded"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Config.PreferencesPatch": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"shell": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"websearch": {
|
||||
"anyOf": [
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"enum": [false]
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/ConfigWebSearch.InfoEncoded"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Config.ProviderEncoded": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -14637,6 +14834,22 @@
|
||||
"required": ["directory"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"ConfigShell.Option": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"acceptable": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": ["path", "name", "acceptable"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"ConfigWebSearch.InfoEncoded": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -17231,22 +17444,6 @@
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Project.Current": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"directory": {
|
||||
"type": "string"
|
||||
},
|
||||
"canonical": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": ["id", "directory", "canonical"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Project.Icon": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -18151,6 +18348,9 @@
|
||||
"metadata": {
|
||||
"$ref": "#/components/schemas/Session.Metadata"
|
||||
},
|
||||
"permissions": {
|
||||
"$ref": "#/components/schemas/Permission.Ruleset"
|
||||
},
|
||||
"revert": {
|
||||
"$ref": "#/components/schemas/Session.Revert"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { Project } from "@opencode/schema/project"
|
||||
import { Schema, Struct } from "effect"
|
||||
import { HttpApiEndpoint, HttpApiGroup, OpenApi } from "effect/unstable/httpapi"
|
||||
import { LocationQuery, locationQueryOpenApi } from "./location.js"
|
||||
import { ProjectNotFoundError } from "../errors.js"
|
||||
|
||||
const root = "/api/project"
|
||||
@@ -33,20 +32,6 @@ export const ProjectGroup = HttpApiGroup.make("server.project")
|
||||
}),
|
||||
),
|
||||
)
|
||||
.add(
|
||||
HttpApiEndpoint.get("project.current", `${root}/current`, {
|
||||
query: LocationQuery,
|
||||
success: Project.Current,
|
||||
})
|
||||
.annotateMerge(locationQueryOpenApi)
|
||||
.annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "v2.project.current",
|
||||
summary: "Get current project",
|
||||
description: "Resolve the project for the requested location.",
|
||||
}),
|
||||
),
|
||||
)
|
||||
.annotateMerge(
|
||||
OpenApi.annotations({
|
||||
title: "project",
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { Location } from "@opencode/core/location"
|
||||
import { Project } from "@opencode/core/project"
|
||||
import { Effect } from "effect"
|
||||
import { HttpApiBuilder } from "effect/unstable/httpapi"
|
||||
@@ -20,14 +19,5 @@ export const ProjectHandler = HttpApiBuilder.group(Api, "server.project", (handl
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
.handle("project.current", () =>
|
||||
Location.Service.use((location) =>
|
||||
Effect.succeed({
|
||||
id: location.project.id,
|
||||
directory: location.project.directory,
|
||||
canonical: location.project.canonical,
|
||||
}),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -70,9 +70,9 @@ export function DialogWorkspaces(props: DialogWorkspacesProps) {
|
||||
const [loadedProject] = createResource(
|
||||
() => (location()?.project.id === props.projectID ? undefined : props.projectID),
|
||||
(projectID) =>
|
||||
client.api.project
|
||||
.current({ location: { directory: location()?.directory || paths.cwd } })
|
||||
.then((project) => (project.id === projectID ? project.directory : undefined))
|
||||
client.api.location
|
||||
.get({ location: { directory: location()?.directory || paths.cwd } })
|
||||
.then((result) => (result.project.id === projectID ? result.project.directory : undefined))
|
||||
.catch(() => undefined),
|
||||
)
|
||||
const currentCheckout = createMemo(() => {
|
||||
|
||||
@@ -118,9 +118,9 @@ export function usePromptMove(input: { projectID: () => string | undefined; sess
|
||||
const location = homeLocation()
|
||||
const current = data.location.info(location)
|
||||
if (current) return current.project.id
|
||||
return client.api.project
|
||||
.current({ location: { directory: location.directory, workspace: location.workspaceID } })
|
||||
.then((project) => project.id)
|
||||
return client.api.location
|
||||
.get({ location: { directory: location.directory, workspace: location.workspaceID } })
|
||||
.then((result) => result.project.id)
|
||||
.catch(() => undefined)
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ test.each([
|
||||
|
||||
expect(fixture.requests).toEqual([{ payload: { name: "fresh" }, directory: input.directory, workspace: null }])
|
||||
expect(fixture.data.location.info({ directory: created })?.project.canonical).toBe(clone)
|
||||
expect(fixture.reads.locations.filter((directory) => directory === input.directory)).toHaveLength(1)
|
||||
expect(fixture.reads.locations.filter((directory) => directory === input.directory)).toHaveLength(input.home ? 3 : 1)
|
||||
expect(fixture.reads.session).toBe(input.home ? 0 : 1)
|
||||
expect(fixture.moves).toEqual([])
|
||||
if (!input.home) expect(fixture.route.data).toEqual({ type: "home", location: { directory: created } })
|
||||
@@ -149,11 +149,9 @@ test.each([false, true])("Ctrl+M moves only an existing session (home=%s)", asyn
|
||||
test.each([
|
||||
{ name: "session", unavailable: "session" as const },
|
||||
{ name: "location", unavailable: "location" as const },
|
||||
{ name: "selected Home location", unavailable: "location" as const, home: true, launch: main },
|
||||
])("does not create from another clone when $name lookup fails", async (input) => {
|
||||
const fixture = await renderMove({ ...input, directory: `${linked}/packages/tui`, worktree: linked })
|
||||
try {
|
||||
if (input.home) fixture.location.set({ directory: `${linked}/packages/tui` })
|
||||
await fixture.create()
|
||||
|
||||
expect(fixture.requests).toEqual([])
|
||||
@@ -165,6 +163,27 @@ test.each([
|
||||
}
|
||||
})
|
||||
|
||||
test("does not open creation when the selected Home location lookup fails", async () => {
|
||||
const fixture = await renderMove({
|
||||
unavailable: "location",
|
||||
home: true,
|
||||
launch: main,
|
||||
directory: `${linked}/packages/tui`,
|
||||
worktree: linked,
|
||||
})
|
||||
try {
|
||||
fixture.location.set({ directory: `${linked}/packages/tui` })
|
||||
await fixture.move.open()
|
||||
await fixture.app.waitFor(() => fixture.toast.currentToast !== null)
|
||||
|
||||
expect(fixture.requests).toEqual([])
|
||||
expect(fixture.moves).toEqual([])
|
||||
expect(fixture.toast.currentToast).toMatchObject({ message: "Unable to determine current project", variant: "error" })
|
||||
} finally {
|
||||
fixture.app.renderer.destroy()
|
||||
}
|
||||
})
|
||||
|
||||
async function renderMove(input: {
|
||||
directory: string
|
||||
worktree?: string
|
||||
@@ -179,7 +198,7 @@ async function renderMove(input: {
|
||||
const moves: unknown[] = []
|
||||
const reads = { session: 0, locations: [] as string[], worktrees: [] as string[] }
|
||||
const calls = createFetch(async (url, request) => {
|
||||
if (url.pathname === "/api/location" || url.pathname === "/api/project/current") {
|
||||
if (url.pathname === "/api/location") {
|
||||
const directory = url.searchParams.get("location[directory]") ?? launch
|
||||
const project = {
|
||||
id: directory === launch ? (input.launchProjectID ?? "proj_test") : "proj_test",
|
||||
@@ -191,7 +210,6 @@ async function renderMove(input: {
|
||||
? launch
|
||||
: main,
|
||||
}
|
||||
if (url.pathname === "/api/project/current") return json(project)
|
||||
reads.locations.push(directory)
|
||||
if (input.unavailable === "location" && directory === input.directory)
|
||||
return json({ message: "Location unavailable" }, { status: 503 })
|
||||
|
||||
@@ -110,7 +110,6 @@ export function createFetch(override?: FetchHandler, events?: ReturnType<typeof
|
||||
location: { directory, project: { id: "proj_test", directory: worktree, canonical: worktree } },
|
||||
data: [],
|
||||
})
|
||||
if (url.pathname === "/api/project/current") return json({ id: "proj_test", directory: worktree })
|
||||
if (url.pathname === "/api/project") return json([])
|
||||
if (url.pathname === "/api/worktree") {
|
||||
if (request.method === "GET") return json([{ directory: worktree }])
|
||||
|
||||
@@ -244,7 +244,6 @@ const agents = await client.app.agents()
|
||||
| الطريقة | الوصف | الاستجابة |
|
||||
| ------------------- | ------------------ | --------------------------------------------- |
|
||||
| `project.list()` | سرد جميع المشاريع | <a href={typesUrl}><code>Project[]</code></a> |
|
||||
| `project.current()` | جلب المشروع الحالي | <a href={typesUrl}><code>Project</code></a> |
|
||||
|
||||
---
|
||||
|
||||
@@ -254,8 +253,6 @@ const agents = await client.app.agents()
|
||||
// List all projects
|
||||
const projects = await client.project.list()
|
||||
|
||||
// Get current project
|
||||
const currentProject = await client.project.current()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -244,7 +244,6 @@ const agents = await client.app.agents()
|
||||
| Metoda | Opis | Odgovor |
|
||||
| ------------------- | -------------------- | --------------------------------------------- |
|
||||
| `project.list()` | Lista svih projekata | <a href={typesUrl}><code>Project[]</code></a> |
|
||||
| `project.current()` | Trenutni projekat | <a href={typesUrl}><code>Project</code></a> |
|
||||
|
||||
---
|
||||
|
||||
@@ -254,8 +253,6 @@ const agents = await client.app.agents()
|
||||
// List all projects
|
||||
const projects = await client.project.list()
|
||||
|
||||
// Get current project
|
||||
const currentProject = await client.project.current()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -244,7 +244,6 @@ const agents = await client.app.agents()
|
||||
| Metode | Beskrivelse | Svar |
|
||||
| ------------------- | -------------------------- | ---------------------------------------------- |
|
||||
| `project.list()` | Liste over alle prosjekter | <a href={typesUrl}><code>Prosjekt[]</code></a> |
|
||||
| `project.current()` | Få nåværende prosjekt | <a href={typesUrl}><code>Prosjekt</code></a> |
|
||||
|
||||
---
|
||||
|
||||
@@ -254,8 +253,6 @@ const agents = await client.app.agents()
|
||||
// List all projects
|
||||
const projects = await client.project.list()
|
||||
|
||||
// Get current project
|
||||
const currentProject = await client.project.current()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -246,7 +246,6 @@ const agents = await client.app.agents()
|
||||
| Method | Description | Response |
|
||||
| ------------------- | ---------------------------- | --------------------------------------------- |
|
||||
| `project.list()` | Listet alle Projekte | <a href={typesUrl}><code>Project[]</code></a> |
|
||||
| `project.current()` | Ruft das aktuelle Projekt ab | <a href={typesUrl}><code>Project</code></a> |
|
||||
|
||||
---
|
||||
|
||||
@@ -256,8 +255,6 @@ const agents = await client.app.agents()
|
||||
// List all projects
|
||||
const projects = await client.project.list()
|
||||
|
||||
// Get current project
|
||||
const currentProject = await client.project.current()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -244,7 +244,6 @@ const agents = await client.app.agents()
|
||||
| Método | Descripción | Respuesta |
|
||||
| ------------------- | -------------------------- | --------------------------------------------- |
|
||||
| `project.list()` | Listar todos los proyectos | <a href={typesUrl}><code>Project[]</code></a> |
|
||||
| `project.current()` | Obtener proyecto actual | <a href={typesUrl}><code>Project</code></a> |
|
||||
|
||||
---
|
||||
|
||||
@@ -254,8 +253,6 @@ const agents = await client.app.agents()
|
||||
// List all projects
|
||||
const projects = await client.project.list()
|
||||
|
||||
// Get current project
|
||||
const currentProject = await client.project.current()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -244,7 +244,6 @@ const agents = await client.app.agents()
|
||||
| Méthode | Descriptif | Réponse |
|
||||
| ------------------- | -------------------------- | --------------------------------------------- |
|
||||
| `project.list()` | Lister tous les projets | <a href={typesUrl}><code>Project[]</code></a> |
|
||||
| `project.current()` | Obtenir le projet en cours | <a href={typesUrl}><code>Project</code></a> |
|
||||
|
||||
---
|
||||
|
||||
@@ -254,8 +253,6 @@ const agents = await client.app.agents()
|
||||
// List all projects
|
||||
const projects = await client.project.list()
|
||||
|
||||
// Get current project
|
||||
const currentProject = await client.project.current()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -244,7 +244,6 @@ const agents = await client.app.agents()
|
||||
| Metodo | Descrizione | Risposta |
|
||||
| ------------------- | ----------------- | --------------------------------------------- |
|
||||
| `project.list()` | Elenca i progetti | <a href={typesUrl}><code>Project[]</code></a> |
|
||||
| `project.current()` | Progetto corrente | <a href={typesUrl}><code>Project</code></a> |
|
||||
|
||||
---
|
||||
|
||||
@@ -254,8 +253,6 @@ const agents = await client.app.agents()
|
||||
// List all projects
|
||||
const projects = await client.project.list()
|
||||
|
||||
// Get current project
|
||||
const currentProject = await client.project.current()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -244,7 +244,6 @@ const agents = await client.app.agents()
|
||||
| メソッド | 説明 | 戻り値 |
|
||||
| ------------------- | -------------------------------- | --------------------------------------------- |
|
||||
| `project.list()` | すべてのプロジェクトをリストする | <a href={typesUrl}><code>Project[]</code></a> |
|
||||
| `project.current()` | 現在のプロジェクトを取得 | <a href={typesUrl}><code>Project</code></a> |
|
||||
|
||||
---
|
||||
|
||||
@@ -254,8 +253,6 @@ const agents = await client.app.agents()
|
||||
// List all projects
|
||||
const projects = await client.project.list()
|
||||
|
||||
// Get current project
|
||||
const currentProject = await client.project.current()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -244,7 +244,6 @@ const agents = await client.app.agents()
|
||||
| 방법 | 설명 | 응답 |
|
||||
| ------------------- | ----------------------- | --------------------------------------------- |
|
||||
| `project.list()` | 모든 프로젝트 보기 | <a href={typesUrl}><code>Project[]</code></a> |
|
||||
| `project.current()` | 현재 프로젝트 가져 오기 | <a href={typesUrl}><code>Project</code></a> |
|
||||
|
||||
---
|
||||
|
||||
@@ -254,8 +253,6 @@ const agents = await client.app.agents()
|
||||
// List all projects
|
||||
const projects = await client.project.list()
|
||||
|
||||
// Get current project
|
||||
const currentProject = await client.project.current()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -244,7 +244,6 @@ const agents = await client.app.agents()
|
||||
| Metode | Beskrivelse | Svar |
|
||||
| ------------------- | ----------------------- | --------------------------------------------- |
|
||||
| `project.list()` | List alle prosjekter | <a href={typesUrl}><code>Project[]</code></a> |
|
||||
| `project.current()` | Hent gjeldende prosjekt | <a href={typesUrl}><code>Project</code></a> |
|
||||
|
||||
---
|
||||
|
||||
@@ -254,8 +253,6 @@ const agents = await client.app.agents()
|
||||
// List all projects
|
||||
const projects = await client.project.list()
|
||||
|
||||
// Get current project
|
||||
const currentProject = await client.project.current()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -244,7 +244,6 @@ const agents = await client.app.agents()
|
||||
| Metoda | Opis | Odpowiedź |
|
||||
| ------------------- | -------------------------- | --------------------------------------------- |
|
||||
| `project.list()` | Lista wszystkich projektów | <a href={typesUrl}><code>Project[]</code></a> |
|
||||
| `project.current()` | Pobierz bieżący projekt | <a href={typesUrl}><code>Project</code></a> |
|
||||
|
||||
---
|
||||
|
||||
@@ -254,8 +253,6 @@ const agents = await client.app.agents()
|
||||
// List all projects
|
||||
const projects = await client.project.list()
|
||||
|
||||
// Get current project
|
||||
const currentProject = await client.project.current()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -244,7 +244,6 @@ const agents = await client.app.agents()
|
||||
| Método | Descrição | Resposta |
|
||||
| ------------------- | ------------------------ | --------------------------------------------- |
|
||||
| `project.list()` | Listar todos os projetos | <a href={typesUrl}><code>Project[]</code></a> |
|
||||
| `project.current()` | Obter projeto atual | <a href={typesUrl}><code>Project</code></a> |
|
||||
|
||||
---
|
||||
|
||||
@@ -254,8 +253,6 @@ const agents = await client.app.agents()
|
||||
// List all projects
|
||||
const projects = await client.project.list()
|
||||
|
||||
// Get current project
|
||||
const currentProject = await client.project.current()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -244,7 +244,6 @@ const agents = await client.app.agents()
|
||||
| Метод | Описание | Ответ |
|
||||
| ------------------- | ------------------- | --------------------------------------------- |
|
||||
| `project.list()` | List all projects | <a href={typesUrl}><code>Project[]</code></a> |
|
||||
| `project.current()` | Get current project | <a href={typesUrl}><code>Project</code></a> |
|
||||
|
||||
---
|
||||
|
||||
@@ -254,8 +253,6 @@ const agents = await client.app.agents()
|
||||
// List all projects
|
||||
const projects = await client.project.list()
|
||||
|
||||
// Get current project
|
||||
const currentProject = await client.project.current()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -244,7 +244,6 @@ const agents = await client.app.agents()
|
||||
| Method | Description | Response |
|
||||
| ------------------- | ------------------- | --------------------------------------------- |
|
||||
| `project.list()` | List all projects | <a href={typesUrl}><code>Project[]</code></a> |
|
||||
| `project.current()` | Get current project | <a href={typesUrl}><code>Project</code></a> |
|
||||
|
||||
---
|
||||
|
||||
@@ -254,8 +253,6 @@ const agents = await client.app.agents()
|
||||
// List all projects
|
||||
const projects = await client.project.list()
|
||||
|
||||
// Get current project
|
||||
const currentProject = await client.project.current()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -244,7 +244,6 @@ const agents = await client.app.agents()
|
||||
| Method | คำอธิบาย | การตอบสนอง |
|
||||
| ------------------- | ------------------------ | --------------------------------------------- |
|
||||
| `project.list()` | แสดงรายการโครงการทั้งหมด | <a href={typesUrl}><code>Project[]</code></a> |
|
||||
| `project.current()` | รับโครงการปัจจุบัน | <a href={typesUrl}><code>Project</code></a> |
|
||||
|
||||
---
|
||||
|
||||
@@ -254,8 +253,6 @@ const agents = await client.app.agents()
|
||||
// List all projects
|
||||
const projects = await client.project.list()
|
||||
|
||||
// Get current project
|
||||
const currentProject = await client.project.current()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -244,7 +244,6 @@ const agents = await client.app.agents()
|
||||
| Yöntem | Açıklama | Yanıt |
|
||||
| ------------------- | --------------------- | --------------------------------------------- |
|
||||
| `project.list()` | Tüm projeleri listele | <a href={typesUrl}><code>Project[]</code></a> |
|
||||
| `project.current()` | Mevcut projeyi al | <a href={typesUrl}><code>Project</code></a> |
|
||||
|
||||
---
|
||||
|
||||
@@ -254,8 +253,6 @@ const agents = await client.app.agents()
|
||||
// List all projects
|
||||
const projects = await client.project.list()
|
||||
|
||||
// Get current project
|
||||
const currentProject = await client.project.current()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -244,7 +244,6 @@ const agents = await client.app.agents()
|
||||
| 方法 | 描述 | 响应 |
|
||||
| ------------------- | ------------ | --------------------------------------------- |
|
||||
| `project.list()` | 列出所有项目 | <a href={typesUrl}><code>Project[]</code></a> |
|
||||
| `project.current()` | 获取当前项目 | <a href={typesUrl}><code>Project</code></a> |
|
||||
|
||||
---
|
||||
|
||||
@@ -254,8 +253,6 @@ const agents = await client.app.agents()
|
||||
// List all projects
|
||||
const projects = await client.project.list()
|
||||
|
||||
// Get current project
|
||||
const currentProject = await client.project.current()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -244,7 +244,6 @@ const agents = await client.app.agents()
|
||||
| 方法 | 描述 | 回應 |
|
||||
| ------------------- | ------------ | --------------------------------------------- |
|
||||
| `project.list()` | 列出所有專案 | <a href={typesUrl}><code>Project[]</code></a> |
|
||||
| `project.current()` | 取得當前專案 | <a href={typesUrl}><code>Project</code></a> |
|
||||
|
||||
---
|
||||
|
||||
@@ -254,8 +253,6 @@ const agents = await client.app.agents()
|
||||
// List all projects
|
||||
const projects = await client.project.list()
|
||||
|
||||
// Get current project
|
||||
const currentProject = await client.project.current()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
+299
-99
@@ -1115,6 +1115,16 @@
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"permissions": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/Permission.Ruleset"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
@@ -7466,89 +7476,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/project/current": {
|
||||
"get": {
|
||||
"tags": ["project"],
|
||||
"operationId": "v2.project.current",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "location",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"directory": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"workspace": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"required": false,
|
||||
"style": "deepObject",
|
||||
"explode": true
|
||||
}
|
||||
],
|
||||
"security": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Project.Current",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Project.Current"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "InvalidRequestError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/InvalidRequestErrorEncoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "UnauthorizedError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UnauthorizedErrorEncoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Resolve the project for the requested location.",
|
||||
"summary": "Get current project"
|
||||
}
|
||||
},
|
||||
"/api/form/request": {
|
||||
"get": {
|
||||
"tags": ["form"],
|
||||
@@ -8783,6 +8710,85 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/session/{sessionID}/permission/rules": {
|
||||
"put": {
|
||||
"tags": ["permission"],
|
||||
"operationId": "v2.session.permission.rules",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "sessionID",
|
||||
"in": "path",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"pattern": "^ses"
|
||||
},
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"security": [],
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "<No Content>"
|
||||
},
|
||||
"400": {
|
||||
"description": "InvalidRequestError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/InvalidRequestErrorEncoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "UnauthorizedError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UnauthorizedErrorEncoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "SessionNotFoundError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/SessionNotFoundErrorEncoded"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/SessionNotFoundErrorEncoded"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Replace the session-scoped permission rules. Rules are evaluated after the agent's rules, and the last matching rule wins.",
|
||||
"summary": "Replace session permission rules",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"permissions": {
|
||||
"$ref": "#/components/schemas/Permission.Ruleset"
|
||||
}
|
||||
},
|
||||
"required": ["permissions"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/fs/read/*": {
|
||||
"get": {
|
||||
"tags": ["filesystem"],
|
||||
@@ -13672,6 +13678,143 @@
|
||||
"description": "Return configuration documents and discovery sources for the requested location, from lowest to highest priority.",
|
||||
"summary": "Get configuration"
|
||||
}
|
||||
},
|
||||
"/api/config/preferences": {
|
||||
"get": {
|
||||
"tags": ["config"],
|
||||
"operationId": "v2.config.preferences",
|
||||
"parameters": [],
|
||||
"security": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Config.Preferences",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Config.Preferences"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "InvalidRequestError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/InvalidRequestErrorEncoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "UnauthorizedError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UnauthorizedErrorEncoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Return preferences from the highest-precedence global configuration document.",
|
||||
"summary": "Get global preferences"
|
||||
},
|
||||
"patch": {
|
||||
"tags": ["config"],
|
||||
"operationId": "v2.config.updatePreferences",
|
||||
"parameters": [],
|
||||
"security": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Config.Preferences",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Config.Preferences"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "InvalidRequestError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/InvalidRequestErrorEncoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "UnauthorizedError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UnauthorizedErrorEncoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Patch preferences in the highest-precedence global configuration document.",
|
||||
"summary": "Update global preferences",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Config.PreferencesPatch"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/config/shell": {
|
||||
"get": {
|
||||
"tags": ["config"],
|
||||
"operationId": "v2.config.shells",
|
||||
"parameters": [],
|
||||
"security": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ConfigShell.Option"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "InvalidRequestError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/InvalidRequestErrorEncoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "UnauthorizedError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UnauthorizedErrorEncoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Return shells available to terminal and agent execution.",
|
||||
"summary": "List available shells"
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
@@ -14532,6 +14675,60 @@
|
||||
"required": ["package"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Config.Preferences": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"shell": {
|
||||
"type": "string"
|
||||
},
|
||||
"websearch": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"enum": [false]
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/ConfigWebSearch.InfoEncoded"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Config.PreferencesPatch": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"shell": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"websearch": {
|
||||
"anyOf": [
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"enum": [false]
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/ConfigWebSearch.InfoEncoded"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Config.ProviderEncoded": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -14637,6 +14834,22 @@
|
||||
"required": ["directory"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"ConfigShell.Option": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"acceptable": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": ["path", "name", "acceptable"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"ConfigWebSearch.InfoEncoded": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -17231,22 +17444,6 @@
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Project.Current": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"directory": {
|
||||
"type": "string"
|
||||
},
|
||||
"canonical": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": ["id", "directory", "canonical"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Project.Icon": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -18151,6 +18348,9 @@
|
||||
"metadata": {
|
||||
"$ref": "#/components/schemas/Session.Metadata"
|
||||
},
|
||||
"permissions": {
|
||||
"$ref": "#/components/schemas/Permission.Ruleset"
|
||||
},
|
||||
"revert": {
|
||||
"$ref": "#/components/schemas/Session.Revert"
|
||||
}
|
||||
|
||||
@@ -1115,6 +1115,16 @@
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"permissions": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/Permission.Ruleset"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
@@ -7466,89 +7476,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/project/current": {
|
||||
"get": {
|
||||
"tags": ["project"],
|
||||
"operationId": "v2.project.current",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "location",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"directory": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"workspace": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"required": false,
|
||||
"style": "deepObject",
|
||||
"explode": true
|
||||
}
|
||||
],
|
||||
"security": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Project.Current",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Project.Current"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "InvalidRequestError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/InvalidRequestErrorEncoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "UnauthorizedError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UnauthorizedErrorEncoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Resolve the project for the requested location.",
|
||||
"summary": "Get current project"
|
||||
}
|
||||
},
|
||||
"/api/form/request": {
|
||||
"get": {
|
||||
"tags": ["form"],
|
||||
@@ -8783,6 +8710,85 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/session/{sessionID}/permission/rules": {
|
||||
"put": {
|
||||
"tags": ["permission"],
|
||||
"operationId": "v2.session.permission.rules",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "sessionID",
|
||||
"in": "path",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"pattern": "^ses"
|
||||
},
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"security": [],
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "<No Content>"
|
||||
},
|
||||
"400": {
|
||||
"description": "InvalidRequestError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/InvalidRequestErrorEncoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "UnauthorizedError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UnauthorizedErrorEncoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "SessionNotFoundError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/SessionNotFoundErrorEncoded"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/SessionNotFoundErrorEncoded"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Replace the session-scoped permission rules. Rules are evaluated after the agent's rules, and the last matching rule wins.",
|
||||
"summary": "Replace session permission rules",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"permissions": {
|
||||
"$ref": "#/components/schemas/Permission.Ruleset"
|
||||
}
|
||||
},
|
||||
"required": ["permissions"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/fs/read/*": {
|
||||
"get": {
|
||||
"tags": ["filesystem"],
|
||||
@@ -13672,6 +13678,143 @@
|
||||
"description": "Return configuration documents and discovery sources for the requested location, from lowest to highest priority.",
|
||||
"summary": "Get configuration"
|
||||
}
|
||||
},
|
||||
"/api/config/preferences": {
|
||||
"get": {
|
||||
"tags": ["config"],
|
||||
"operationId": "v2.config.preferences",
|
||||
"parameters": [],
|
||||
"security": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Config.Preferences",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Config.Preferences"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "InvalidRequestError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/InvalidRequestErrorEncoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "UnauthorizedError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UnauthorizedErrorEncoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Return preferences from the highest-precedence global configuration document.",
|
||||
"summary": "Get global preferences"
|
||||
},
|
||||
"patch": {
|
||||
"tags": ["config"],
|
||||
"operationId": "v2.config.updatePreferences",
|
||||
"parameters": [],
|
||||
"security": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Config.Preferences",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Config.Preferences"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "InvalidRequestError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/InvalidRequestErrorEncoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "UnauthorizedError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UnauthorizedErrorEncoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Patch preferences in the highest-precedence global configuration document.",
|
||||
"summary": "Update global preferences",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Config.PreferencesPatch"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/config/shell": {
|
||||
"get": {
|
||||
"tags": ["config"],
|
||||
"operationId": "v2.config.shells",
|
||||
"parameters": [],
|
||||
"security": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ConfigShell.Option"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "InvalidRequestError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/InvalidRequestErrorEncoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "UnauthorizedError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UnauthorizedErrorEncoded"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Return shells available to terminal and agent execution.",
|
||||
"summary": "List available shells"
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
@@ -14532,6 +14675,60 @@
|
||||
"required": ["package"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Config.Preferences": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"shell": {
|
||||
"type": "string"
|
||||
},
|
||||
"websearch": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"enum": [false]
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/ConfigWebSearch.InfoEncoded"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Config.PreferencesPatch": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"shell": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"websearch": {
|
||||
"anyOf": [
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"enum": [false]
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/ConfigWebSearch.InfoEncoded"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Config.ProviderEncoded": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -14637,6 +14834,22 @@
|
||||
"required": ["directory"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"ConfigShell.Option": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"acceptable": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": ["path", "name", "acceptable"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"ConfigWebSearch.InfoEncoded": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -17231,22 +17444,6 @@
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Project.Current": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"directory": {
|
||||
"type": "string"
|
||||
},
|
||||
"canonical": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": ["id", "directory", "canonical"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Project.Icon": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -18151,6 +18348,9 @@
|
||||
"metadata": {
|
||||
"$ref": "#/components/schemas/Session.Metadata"
|
||||
},
|
||||
"permissions": {
|
||||
"$ref": "#/components/schemas/Permission.Ruleset"
|
||||
},
|
||||
"revert": {
|
||||
"$ref": "#/components/schemas/Session.Revert"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user