Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
7e1d22f
feat: add workspace-scoped user access
yohamta0 Apr 20, 2026
445ad95
feat: separate aggregate and no-workspace scopes
yohamta0 Apr 20, 2026
21c6267
fix: harden workspace scope handling
yohamta0 Apr 20, 2026
72f8182
fix: harden document workspace lookups
yohamta0 Apr 20, 2026
8a2e4bb
fix: avoid sync polling stale repair
yohamta0 Apr 20, 2026
a13bb64
fix: constrain workspace match scopes
yohamta0 Apr 20, 2026
820d896
Merge branch 'main' into workspace-scoped-access
yohamta0 Apr 20, 2026
68bec8f
fix: address workspace review feedback
yohamta0 Apr 20, 2026
4dcd6de
test: select no-workspace scope for dag creation e2e
yohamta0 Apr 20, 2026
7ae60d7
fix: expose workspace targets on exact endpoints
yohamta0 Apr 20, 2026
6fe7395
test: use no-workspace scope for dag crud e2e
yohamta0 Apr 20, 2026
e07640d
test: attach proc heartbeat to abort handler runs
yohamta0 Apr 20, 2026
ee18d82
fix: repair distributed status from heartbeat
yohamta0 Apr 20, 2026
4bf4bdd
fix: refine workspace scope labels
yohamta0 Apr 21, 2026
0cfbaa5
fix: refine workspace selector follow-ups
yohamta0 Apr 21, 2026
5e3a7b1
fix: address docs url review feedback
yohamta0 Apr 21, 2026
84004bc
fix: address remaining review feedback
yohamta0 Apr 21, 2026
3bae537
fix: use all for aggregate workspace scope
yohamta0 Apr 21, 2026
8d73894
fix: harden workspace scoped access
yohamta0 Apr 21, 2026
6abb5ef
fix: address workspace review hardening
yohamta0 Apr 21, 2026
4c0e3e4
test: improve workspace helper coverage
yohamta0 Apr 21, 2026
a93deb3
fix: use default workspace scope
yohamta0 Apr 21, 2026
89361be
fix: address workspace review feedback
yohamta0 Apr 21, 2026
8776029
fix: use default workspace in e2e tests
yohamta0 Apr 21, 2026
5772ebc
fix: scope document tab mutations by workspace
yohamta0 Apr 21, 2026
243c5e1
fix: keep navigation role based
yohamta0 Apr 21, 2026
cadd5d4
fix: guard design actions by workspace access
yohamta0 Apr 21, 2026
ef75a7c
fix: scope dag run live updates by workspace
yohamta0 Apr 21, 2026
f072546
fix: complete dag run workspace guards
yohamta0 Apr 21, 2026
7a1509b
fix: scope agent context pickers by workspace
yohamta0 Apr 21, 2026
cea1e02
fix: keep resource editors writable in all workspace
yohamta0 Apr 21, 2026
2406276
refactor: remove workspace scope from target APIs
yohamta0 Apr 21, 2026
a36f44a
docs: clarify workspace API parameters
yohamta0 Apr 21, 2026
8b48834
test: stabilize distributed cancellation test
yohamta0 Apr 21, 2026
e71141f
fix: preserve workspace scope for DAG search matches
yohamta0 Apr 21, 2026
5c95456
refactor: use workspace query parameter consistently
yohamta0 Apr 21, 2026
c416907
fix: address workspace review gaps
yohamta0 Apr 21, 2026
152b679
fix: simplify workspace storage naming
yohamta0 Apr 21, 2026
250d66c
refactor: simplify workspace selection state
yohamta0 Apr 21, 2026
ee4e488
test: stabilize local queue FIFO assertion
yohamta0 Apr 21, 2026
f80686a
fix: preserve workspace cache state
yohamta0 Apr 21, 2026
58cde5d
fix: revalidate workspace target caches
yohamta0 Apr 21, 2026
7109f2f
test: cover default workspace scoped role
yohamta0 Apr 22, 2026
c2e1909
test: stabilize agent running assertion
yohamta0 Apr 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,345 changes: 740 additions & 605 deletions api/v1/api.gen.go

Large diffs are not rendered by default.

90 changes: 85 additions & 5 deletions api/v1/api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,7 @@ paths:
- $ref: "#/components/parameters/Page"
- $ref: "#/components/parameters/PerPage"
- $ref: "#/components/parameters/RemoteNode"
- $ref: "#/components/parameters/Workspace"
- name: "name"
in: "query"
required: false
Expand Down Expand Up @@ -1654,7 +1655,6 @@ paths:
parameters:
- $ref: "#/components/parameters/DAGFileName"
- $ref: "#/components/parameters/RemoteNode"
- $ref: "#/components/parameters/Workspace"
- name: "q"
in: "query"
required: true
Expand All @@ -1667,6 +1667,7 @@ paths:
schema:
type: "string"
description: "Filter DAG matches by labels (comma-separated). Returns matches only when the DAG has ALL specified labels."
- $ref: "#/components/parameters/Workspace"
- $ref: "#/components/parameters/SearchCursor"
- $ref: "#/components/parameters/SearchMatchLimit"
responses:
Expand Down Expand Up @@ -1754,6 +1755,7 @@ paths:
- "dags"
parameters:
- $ref: "#/components/parameters/RemoteNode"
- $ref: "#/components/parameters/Workspace"
responses:
"200":
description: "A successful response"
Expand All @@ -1778,6 +1780,7 @@ paths:
- "dags"
parameters:
- $ref: "#/components/parameters/RemoteNode"
- $ref: "#/components/parameters/Workspace"
responses:
"200":
description: "A successful response"
Expand Down Expand Up @@ -1807,6 +1810,7 @@ paths:
- $ref: "#/components/parameters/DAGRunListLimit"
- $ref: "#/components/parameters/DAGRunListCursor"
- $ref: "#/components/parameters/RemoteNode"
- $ref: "#/components/parameters/Workspace"
- name: "name"
in: "query"
required: false
Expand Down Expand Up @@ -2016,6 +2020,7 @@ paths:
- $ref: "#/components/parameters/DAGRunListLimit"
- $ref: "#/components/parameters/DAGRunListCursor"
- $ref: "#/components/parameters/RemoteNode"
- $ref: "#/components/parameters/Workspace"
responses:
"200":
description: "A successful response"
Expand Down Expand Up @@ -6977,10 +6982,12 @@ components:
Workspace:
name: workspace
in: query
description: selected workspace scope
description: "Workspace selector. For list and search APIs, use all, default, or a workspace name. Omitted means all. For document target APIs, use default or a workspace name; omitted means default."
required: false
schema:
type: string
minLength: 1
maxLength: 64
pattern: "^[A-Za-z0-9_-]+$"

SearchCursor:
Expand Down Expand Up @@ -7974,6 +7981,9 @@ components:
name:
type: string
description: "Logical name of the DAG"
workspace:
type: string
description: "Workspace label value for the DAG. Omitted for default DAGs and invalid workspace labels."
schedule:
type: array
description: "List of scheduling expressions defining when DAG-runs should be created from this DAG"
Expand Down Expand Up @@ -8489,6 +8499,9 @@ components:
$ref: "#/components/schemas/DAGRunId"
name:
$ref: "#/components/schemas/DAGName"
workspace:
type: string
description: "Workspace label value for the DAG-run. Omitted for default DAG-runs and invalid workspace labels."
status:
$ref: "#/components/schemas/Status"
statusLabel:
Expand Down Expand Up @@ -9007,6 +9020,9 @@ components:
name:
type: string
description: "Display label for the DAG result; file-backed search currently mirrors fileName"
workspace:
type: string
description: "Workspace label value for the matching DAG. Omitted for default DAGs and invalid workspace labels."
hasMoreMatches:
type: boolean
description: "Whether additional snippets are available beyond the preview"
Expand Down Expand Up @@ -9048,6 +9064,9 @@ components:
type: string
title:
type: string
workspace:
type: string
description: "Workspace that owns this document. Omitted for default documents."
hasMoreMatches:
type: boolean
description: "Whether additional snippets are available beyond the preview"
Expand Down Expand Up @@ -9504,6 +9523,41 @@ components:
- operator
- viewer

WorkspaceName:
type: string
description: "Workspace name. The reserved names all and default are not allowed."
minLength: 1
maxLength: 64
pattern: "^[A-Za-z0-9_-]+$"

WorkspaceGrant:
type: object
description: "Role granted for a specific workspace"
properties:
workspace:
$ref: "#/components/schemas/WorkspaceName"
role:
$ref: "#/components/schemas/UserRole"
required:
- workspace
- role

WorkspaceAccess:
type: object
description: "Workspace access policy. all=true grants the top-level role in every workspace. all=false requires explicit workspace grants and a top-level viewer role."
properties:
all:
type: boolean
description: "Whether this identity can access all workspaces"
grants:
type: array
description: "Workspace-specific grants used when all=false"
items:
$ref: "#/components/schemas/WorkspaceGrant"
required:
- all
- grants

SetupRequest:
type: object
description: "Request body for initial admin account setup"
Expand Down Expand Up @@ -9596,6 +9650,8 @@ components:
minLength: 8
role:
$ref: "#/components/schemas/UserRole"
workspaceAccess:
$ref: "#/components/schemas/WorkspaceAccess"
required:
- username
- password
Expand All @@ -9612,6 +9668,8 @@ components:
maxLength: 64
role:
$ref: "#/components/schemas/UserRole"
workspaceAccess:
$ref: "#/components/schemas/WorkspaceAccess"
isDisabled:
type: boolean
description: "Whether to disable the user account"
Expand All @@ -9628,6 +9686,8 @@ components:
description: "User's username"
role:
$ref: "#/components/schemas/UserRole"
workspaceAccess:
$ref: "#/components/schemas/WorkspaceAccess"
authProvider:
type: string
enum: [builtin, oidc]
Expand All @@ -9647,6 +9707,7 @@ components:
- id
- username
- role
- workspaceAccess
- createdAt
- updatedAt

Expand Down Expand Up @@ -9685,6 +9746,8 @@ components:
description: "Purpose description"
role:
$ref: "#/components/schemas/UserRole"
workspaceAccess:
$ref: "#/components/schemas/WorkspaceAccess"
keyPrefix:
type: string
description: "First 8 characters for identification"
Expand All @@ -9708,6 +9771,7 @@ components:
- id
- name
- role
- workspaceAccess
- keyPrefix
- createdAt
- updatedAt
Expand Down Expand Up @@ -9748,6 +9812,8 @@ components:
description: "Purpose description"
role:
$ref: "#/components/schemas/UserRole"
workspaceAccess:
$ref: "#/components/schemas/WorkspaceAccess"
required:
- name
- role
Expand Down Expand Up @@ -9780,6 +9846,8 @@ components:
description: "New description"
role:
$ref: "#/components/schemas/UserRole"
workspaceAccess:
$ref: "#/components/schemas/WorkspaceAccess"

SuccessResponse:
type: object
Expand Down Expand Up @@ -10591,6 +10659,9 @@ components:
type: string
title:
type: string
workspace:
type: string
description: "Workspace that owns this document. Omitted for default documents."
content:
type: string
description: "Full file content including YAML frontmatter"
Expand All @@ -10617,6 +10688,9 @@ components:
type: string
title:
type: string
workspace:
type: string
description: "Workspace that owns this document. Omitted for default documents."
modifiedAt:
type: string
format: date-time
Expand All @@ -10636,6 +10710,9 @@ components:
type: string
title:
type: string
workspace:
type: string
description: "Workspace that owns this node. Omitted for default nodes."
type:
type: string
enum:
Expand Down Expand Up @@ -10678,6 +10755,9 @@ components:
type: string
title:
type: string
workspace:
type: string
description: "Workspace that owns this document. Omitted for default documents."
matches:
type: array
items:
Expand Down Expand Up @@ -11372,15 +11452,15 @@ components:
- name
properties:
name:
type: string
$ref: "#/components/schemas/WorkspaceName"
description:
type: string

UpdateWorkspaceRequest:
type: object
properties:
name:
type: string
$ref: "#/components/schemas/WorkspaceName"
description:
type: string

Expand All @@ -11393,7 +11473,7 @@ components:
id:
type: string
name:
type: string
$ref: "#/components/schemas/WorkspaceName"
description:
type: string
createdAt:
Expand Down
22 changes: 12 additions & 10 deletions internal/agent/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,20 +66,22 @@ const (

// ListDocsOptions holds parameters for listing documents.
type ListDocsOptions struct {
Page int
PerPage int
Sort DocSortField
Order DocSortOrder
PathPrefix string
Page int
PerPage int
Sort DocSortField
Order DocSortOrder
PathPrefix string
ExcludePathRoots []string
}

// SearchDocsOptions configures a paginated document search query.
type SearchDocsOptions struct {
Cursor string
Limit int
Query string
MatchLimit int
PathPrefix string
Cursor string
Limit int
Query string
MatchLimit int
PathPrefix string
ExcludePathRoots []string
}

// SearchDocMatchesOptions configures cursor-based snippet loading for one document.
Expand Down
Loading