project

package
v0.28.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 7, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package project manages on-disk project entries at `<BaseDir>/projects/<id>/` (managed) or any user-supplied absolute path (custom).

A Project is a bundle of: 1 folder (the agent cwd), defaults (preset/provider/system_addon), pinned sessions, icon, and display name. Sessions reference a project via Meta.ProjectID.

Storage layout:

projects/<id>/
  meta.json        — project meta (this package owns it)
  files/           — managed cwd (only when CustomPath is empty)

Index

Constants

View Source
const DefaultName = "default"

DefaultName is the name of the built-in project that ships with every fresh install.

View Source
const PersonalTag = "personal"

PersonalTag marks the project auto-created for a user as their permanent default. It's the explicit, self-documenting flag used by IsProtected to keep the project undeletable — clearer than inferring "personal" from the owner field or the 👤 icon (which a user could change).

Variables

This section is empty.

Functions

func CanAccess added in v0.25.0

func CanAccess(meta Meta, acc Access) bool

CanAccess reports whether meta is visible to acc. Mirrors the Service.CanAccessTool rule (admin bypass, untagged = open, otherwise tag match) and adds the project owner rule. Checked in order:

  • admins/owners see every project
  • a project with no owner and no tags is shared (everyone)
  • the owner sees their own project
  • a user carrying any of the project's tags sees it (tag share)

func Delete

func Delete(layout config.Layout, id string) error

Delete removes the project metadata folder. For managed projects: also removes projects/<id>/ (including files/). For custom projects: the external folder is NOT touched.

Two projects are protected from deletion:

  • the built-in "default" project (matched by name)
  • any personal project (one carrying the PersonalTag) — the project auto-created for a user is their permanent default and cannot be removed. Use IsProtected to check this without attempting a delete.

func EnsureDefault

func EnsureDefault(layout config.Layout, newID func() string) error

EnsureDefault creates the "default" project if no projects exist yet. Called from Bootstrap after migration so fresh installs always have a usable project.

func Exists

func Exists(layout config.Layout, id string) bool

Exists reports whether a project with the given id exists on disk.

func FindPersonalProject added in v0.17.0

func FindPersonalProject(layout config.Layout, userID string) (string, error)

FindPersonalProject returns the project ID owned by userID, or "" if none exists. It scans all projects on disk looking for a matching OwnerUserID field.

func IsProtected added in v0.28.2

func IsProtected(meta Meta) bool

IsProtected reports whether meta names a project that cannot be deleted: the built-in "default" project (matched by name), or a personal project (one carrying PersonalTag — the auto-created per-user default). The UI uses this to hide/disable the delete control.

func List

func List(layout config.Layout) ([]string, error)

List returns every project ID found on disk (sorted).

func ListVisibleTo added in v0.25.0

func ListVisibleTo(layout config.Layout, acc Access) ([]string, error)

ListVisibleTo returns the IDs of projects acc may see, sorted like List. Use this for every user-facing project enumeration (channel default dropdown, pickers) instead of List, which returns all projects on disk.

func MigrateWorkspacesToProjects

func MigrateWorkspacesToProjects(layout config.Layout, newID func() string, relink func(wsName, projectID string) error) error

MigrateWorkspacesToProjects is idempotent: it is a no-op when any project already exists on disk. Converts each workspace into a project with the same name, folder, and defaults, then relinks all sessions from workspace name to project_id.

Safety:

  • Skips entirely if projects/ is non-empty.
  • os.Rename is used for managed files/ — atomic on same-FS.
  • Session meta is written only after the project is created.
  • Legacy workspaces/ dir is kept on disk (not deleted) for safety.

func RelinkSessions

func RelinkSessions(layout config.Layout, wsName, projectID string) error

RelinkSessions is the concrete relink callback used at boot: scans all session dirs and updates meta.project_id for sessions that reference the old workspace name. Uses a raw map round-trip to preserve all existing fields.

func ResolvePath

func ResolvePath(layout config.Layout, id string) (string, error)

ResolvePath returns the cwd for agent subprocesses bound to this project. Custom paths win; managed falls back to projects/<id>/files/.

func RewriteProvider added in v0.28.1

func RewriteProvider(layout config.Layout, oldKey, newKey string) (int, error)

RewriteProvider re-points every project whose Defaults.Provider equals oldKey to newKey, persisting each change. Used when a provider instance is renamed so project defaults follow the new "type/name" automatically (live sessions are intentionally left alone — they keep the old key and must be re-pointed by the user). Returns the number of projects updated. A best-effort op: a single project's load/save failure is logged via the returned error only if EVERY candidate failed; partial success still returns the count of those that saved.

func SaveMeta

func SaveMeta(layout config.Layout, id string, meta Meta) error

SaveMeta atomically rewrites projects/<id>/meta.json and bumps UpdatedAt.

Types

type Access added in v0.25.0

type Access struct {
	UserID  string
	TagIDs  []string
	IsAdmin bool
}

Access carries the caller identity used to filter project visibility. Build it in the handler from the request context so this package keeps no login/http imports:

project.Access{
    UserID:  user.ID,
    TagIDs:  login.GetUserTagIDs(ctx),
    IsAdmin: user.IsAdmin(),
}

type CreateOptions

type CreateOptions struct {
	ID          string // pre-assigned UUID; generated if empty
	Name        string
	Icon        string
	Description string
	CustomPath  string
	Defaults    Defaults
	Tags        []string
	OwnerUserID string
}

CreateOptions describes a new project.

func PersonalProjectOptions added in v0.17.0

func PersonalProjectOptions(newID, userID, displayName string) CreateOptions

PersonalProjectOptions returns CreateOptions pre-filled for a personal project owned by userID. The caller is responsible for generating a unique ID and calling Create (or the registry manager's CreateProject) with the result.

type Defaults

type Defaults struct {
	Preset      string `json:"preset,omitempty"`
	Provider    string `json:"provider,omitempty"`
	SystemAddon string `json:"system_addon,omitempty"`
}

Defaults holds the preset/provider/system_addon that new sessions in this project inherit when not explicitly overridden.

type Meta

type Meta struct {
	ID             string    `json:"id"`
	Name           string    `json:"name"`
	Icon           string    `json:"icon,omitempty"`
	Description    string    `json:"description,omitempty"`
	CustomPath     string    `json:"custom_path,omitempty"`
	Defaults       Defaults  `json:"defaults"`
	PinnedSessions []string  `json:"pinned_sessions,omitempty"`
	Tags           []string  `json:"tags,omitempty"`
	OwnerUserID    string    `json:"owner_user_id,omitempty"`
	CreatedAt      time.Time `json:"created_at"`
	UpdatedAt      time.Time `json:"updated_at"`
}

Meta is the persisted shape of a project.

type Project

type Project struct {
	Meta Meta `json:"meta"`
}

Project is the in-memory view: meta only (no session list — that lives in the registry).

func Create

func Create(layout config.Layout, opt CreateOptions) (Project, error)

Create materialises the on-disk project entry. For managed projects (CustomPath=="") it also creates projects/<id>/files/. Custom paths are not created — they must already exist.

func Load

func Load(layout config.Layout, id string) (Project, error)

Load reads projects/<id>/meta.json.

func (Project) ID

func (p Project) ID() string

ID returns the project's UUID.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL