Documentation
¶
Overview ¶
Package project manages per-project configuration and lifecycle state.
Each island is represented by a project: (name, repo, agent, resources, desired state). Config persists to ~/.dejima/projects/<name>/config.toml.
Index ¶
- Constants
- Variables
- func Delete(name string) error
- func DeriveNameFromRepo(repo string) string
- func EnsureProjectSubdirs(name string) error
- func Exists(name string) bool
- func HostOwner() string
- func PrimaryAgentID(name string) string
- func ResolveAgentRef[T AgentRef](agents []T, ref string) (string, error)
- func ValidateCapabilityTarget(target string) error
- func ValidateName(name string) error
- type AgentRef
- type AgentSpec
- type CapabilityGrant
- type HostGitHubGrant
- type Identity
- type MCPGrant
- type PortScope
- type Project
- func (p *Project) AddAgent(spec AgentSpec)
- func (p *Project) AddCapabilityGrant(g CapabilityGrant) (CapabilityGrant, error)
- func (p *Project) AddLinkAction(action string) bool
- func (p *Project) AddPortScope(s PortScope) (PortScope, error)
- func (p *Project) AddSchedule(s WakeSchedule) WakeSchedule
- func (p *Project) AgentByID(id string) (*AgentSpec, bool)
- func (p *Project) BackfillAgentLabels() (changed bool)
- func (p *Project) CapabilityGrantByTarget(target string) (CapabilityGrant, bool)
- func (p *Project) ContainerName() string
- func (p *Project) DefaultAgentLabel(spec AgentSpec, excludeID string) string
- func (p *Project) DisplayName() string
- func (p *Project) EnsureAgents()
- func (p *Project) ExposesAction(action string) bool
- func (p *Project) GrantHostGitHub(by string, now time.Time) *HostGitHubGrant
- func (p *Project) HomeVolume() string
- func (p *Project) HostGitHubAllowed() bool
- func (p *Project) IsHome() bool
- func (p *Project) IsHostOwned() bool
- func (p *Project) MoveAgent(id string, delta int) bool
- func (p *Project) NetworkName() string
- func (p *Project) NextAgentID() string
- func (p *Project) NextScheduleID() string
- func (p *Project) PortScopeByHostPath(hostPath string) (*PortScope, bool)
- func (p *Project) PortScopeByName(name string) (*PortScope, bool)
- func (p *Project) PrimaryAgent() *AgentSpec
- func (p *Project) RemoveAgent(id string) bool
- func (p *Project) RemoveCapabilityGrant(target string) (CapabilityGrant, bool)
- func (p *Project) RemoveLinkAction(action string) bool
- func (p *Project) RemovePortScope(key string) (PortScope, bool)
- func (p *Project) RemoveSchedule(id string) bool
- func (p *Project) ResolveAgentRef(ref string) (*AgentSpec, error)
- func (p *Project) RevokeHostGitHub() (*HostGitHubGrant, bool)
- func (p *Project) Save() error
- func (p *Project) SetPrimaryID(id string)
- func (p *Project) StampVersion() string
- func (p *Project) UniqueAgentLabel(desired, excludeID string) string
- func (p *Project) WorkspaceVolume() string
- type Resources
- type State
- type WakeSchedule
Constants ¶
const ( PortModeRO = "ro" PortModeRW = "rw" )
Port access modes. V1 grants are read-only; "rw" is reserved for the read-write milestone (docs/port-island-spec.md §6) and rejected at grant time until then.
const ( RoleProject = "" RoleHome = "home" )
Island roles. Empty (RoleProject) is the default work/coding island. RoleHome marks a persistent "Home Island" that hosts an always-on assistant orchestrator (the brain), which reaches host content only through the Port and spawns work islands via the API. See docs/port-island-spec.md §3.2.
Variables ¶
var ( // ErrNoSuchAgent: the ref matched neither an id nor any label. ErrNoSuchAgent = errors.New("no such agent") // ErrAmbiguousAgent: the ref matched more than one agent's label. ErrAmbiguousAgent = errors.New("ambiguous agent") )
Sentinel error kinds for agent-ref resolution, so callers can branch on the failure mode (e.g. the mailbox treats "no match" as a permissive pass-through but rejects "ambiguous"). Wrapped errors carry the human-readable detail.
Functions ¶
func DeriveNameFromRepo ¶
DeriveNameFromRepo extracts a reasonable default name from a repo URL or path.
func EnsureProjectSubdirs ¶
EnsureProjectSubdirs creates intake/, exports/, logs/ for a project.
func HostOwner ¶ added in v0.8.3
func HostOwner() string
HostOwner is the tenant id attributed to the host operator: the owner of islands created via the trusted local socket or a RoleOwner token, and the backfill value for islands that predate ownership. Configurable via DEJIMA_HOST_OWNER; defaults to "aoos".
func PrimaryAgentID ¶
PrimaryAgentID is the id a brand-new island's primary agent gets: the island's mnemonic letter + "1" (e.g. "Port" → "p1"), matching the scheme NextAgentID uses for added agents. Legacy islands migrated by EnsureAgents keep "a1" so a live attached session isn't renamed out from under the user.
func ResolveAgentRef ¶ added in v0.6.9
ResolveAgentRef maps a user-supplied agent reference to a concrete agent id, over an arbitrary set of agents. Resolution order (id always wins, for back-compat — every place that took an id keeps working):
- exact id match → that id.
- else case-insensitive label match → the matched agent's id.
- multiple label matches → an "ambiguous" error listing each id(label), directing the user to the id.
- no match → a "no such agent" error.
ref is trimmed of surrounding whitespace first. An empty ref returns an error (callers that mean "the primary" should not route through here).
func ValidateCapabilityTarget ¶
ValidateCapabilityTarget checks a capability target name — a macOS Shortcut name or a ~/.dejima/capabilities/ script basename. It is intentionally more permissive than ValidateName (real Shortcut names carry spaces and mixed case) but stays safe as a single filename component: no path separators or traversal, no control characters, bounded length. The strict mode/ownership checks for the Linux script adapter happen at execution time, not here.
func ValidateName ¶
ValidateName ensures a name is safe to use in container/volume names.
Types ¶
type AgentRef ¶ added in v0.6.9
AgentRef is the minimal (id, label) view the agent-ref resolver needs. Both an AgentSpec (daemon-side) and the CLI's api.AgentInfo satisfy it, so ONE resolver backs every "address an agent by name" path. The resolver never reads anything else off an agent, keeping it usable from either trust domain.
type AgentSpec ¶
type AgentSpec struct {
ID string `toml:"id"` // stable per-island handle: "a1", "a2", …
Type string `toml:"type"` // handler id: "claude-code", "codex", "headless"
// Label is a user-facing, renamable name (e.g. "frontend"). Cosmetic.
Label string `toml:"label,omitempty"`
// Cmd is the entrypoint for headless agents; empty for the CLI agents.
Cmd string `toml:"cmd,omitempty"`
// Tmux is the in-container tmux session name for interactive agents. Empty
// for headless. The migrated primary keeps "dejima" so a live attached
// session survives a daemon upgrade; new agents use "agent-<id>".
Tmux string `toml:"tmux,omitempty"`
// Branch is the git branch backing this agent's worktree.
Branch string `toml:"branch,omitempty"`
// Worktree is the container path the agent works in: "/workspace" for the
// primary, "/workspace/.agents/<id>" for the rest.
Worktree string `toml:"worktree,omitempty"`
// Restart enables supervise-and-restart-on-crash for co-located headless agents.
Restart bool `toml:"restart,omitempty"`
// Provider names which daemon LLM-provider credential this agent uses (see
// internal/providercreds), e.g. "anthropic". Empty → the store default. Only
// meaningful when the handler RequiresProviderKey.
Provider string `toml:"provider,omitempty"`
// Model is the "provider/model" string handed to the framework (via the
// DEJIMA_MODEL env the per-agent shim translates). Empty → unset (the user
// picks explicitly; there is no baked-in default).
Model string `toml:"model,omitempty"`
// Ephemeral marks an agent-spawned sub-agent (orchestrator pattern): it's
// reaped automatically (on exit/TTL/parent-removal/revoke) and counts against
// the island's spawn budget. SpawnedBy is the id of the agent that spawned it
// (lineage; "" for operator-created agents). Co-located sub-agents share this
// island's sandbox — they are NOT isolated from the parent.
Ephemeral bool `toml:"ephemeral,omitempty"`
SpawnedBy string `toml:"spawned_by,omitempty"`
// CreatedAt has no omitempty: go-toml/v2 omits a non-zero time.Time under
// omitempty, which silently dropped this field on every save — so it must be
// written unconditionally. The spawn reaper's TTL check depends on it surviving
// a daemon reload.
CreatedAt time.Time `toml:"created_at"`
}
AgentSpec is one agent running inside an island. An island hosts one or more agents; the first is the "primary" (the attach target for legacy clients).
type CapabilityGrant ¶
type CapabilityGrant struct {
Target string `toml:"target"`
GrantedAt time.Time `toml:"granted_at"`
}
CapabilityGrant is an island's permission to invoke one named host capability target — a macOS Shortcut, or an executable in ~/.dejima/capabilities/ on Linux. Deny-all is the default: an island may invoke only the targets granted here. The adapter that runs a target is chosen by host OS at execution time, not stored per grant. See docs/capability-broker-spec.md.
type HostGitHubGrant ¶ added in v0.8.66
type HostGitHubGrant struct {
GrantedAt time.Time `toml:"granted_at"`
// GrantedBy is the actor label from the API identity, when known. Empty for
// the trusted local socket (the host operator, unauthenticated by design).
GrantedBy string `toml:"granted_by,omitempty"`
// Grandfathered marks a grant written by the deny-by-default migration
// rather than chosen by an operator. It behaves identically — the point is
// that it can be TOLD APART, so "islands still carrying the old inherited
// credential" is a question with an answer, and so surfaces can nag about it
// without nagging about deliberate grants.
Grandfathered bool `toml:"grandfathered,omitempty"`
}
HostGitHubGrant records a decision to let one island use the HOST operator's own ~/.config/gh. Its presence IS the grant; nil means denied.
type Identity ¶ added in v0.6.0
type Identity struct {
Color string `toml:"color,omitempty"`
Glyph string `toml:"glyph,omitempty"`
}
Identity is a per-island visual override: a hex color (#rgb or #rrggbb) and a single-rune glyph. The zero value (both empty) means unset. Validation lives in the api layer (PUT /v1/islands/{name}/identity); project stays a pure data struct.
type MCPGrant ¶
MCPGrant is an island's permission to invoke one named, host-curated MCP server (an entry in ~/.dejima/mcp/servers.toml — see internal/mcpbroker). The transport and command behind the name are chosen host-side, not stored per grant; the grant is only the island↦server-name permission.
func AddMCPGrant ¶
AddMCPGrant records a grant, rejecting a duplicate server name. The server name is validated by the caller (mcpbroker.ValidateServerName).
func MCPGrantByServer ¶
MCPGrantByServer returns the grant for server, or ok=false.
func MCPGrantsFor ¶
MCPGrantsFor returns an island's MCP-server grants (empty ⇒ deny-all). A missing sidecar is the deny-all default, not an error.
type PortScope ¶
type PortScope struct {
// Name is the short, slug handle used to address the scope in Trades and the
// Ledger (e.g. "vault"). Derived from the host path's basename; unique within
// the island.
Name string `toml:"name"`
// HostPath is the absolute host directory granted. The broker never serves
// anything outside it.
HostPath string `toml:"host_path"`
// Mode is "ro" or "rw".
Mode string `toml:"mode"`
GrantedAt time.Time `toml:"granted_at"`
}
PortScope is a single brokered host-filesystem grant for an island: a host directory the Port broker may Trade files from/to, and the policy on it.
Access is deny-all by default — an island reaches host content only through an explicit scope. Scopes live in the island's host-side config (0600) and are never writable from inside the island, so an island cannot widen its own grant.
type Project ¶
type Project struct {
Name string `toml:"name"`
// Title is a cosmetic, freely-editable display name. Name stays the durable
// infra handle (container/volume/network/config-dir identity, and the slug
// addressed by the CLI); Title is what the user reads. Empty → show Name.
Title string `toml:"title,omitempty"`
RepoURL string `toml:"repo"`
// NoRepo records that this island was created deliberately WITHOUT a repo:
// an empty /workspace and no origin. It exists so every surface that assumes
// a checkout can tell "there is no repo, by design" apart from "the clone
// hasn't finished, or failed" — an empty RepoURL alone cannot, and reading it
// as a failure is what makes a working island look broken (a workspace-ready
// poll that never succeeds, a git pane that reports an error, a purge guard
// that can't verify work it was never given).
NoRepo bool `toml:"no_repo,omitempty"`
// Agent and Cmd are the pre-multi-agent scalar fields. They are retained for
// backward compatibility (older daemons read them) and mirror Agents[0]. New
// code should read Agents; PrimaryAgent() is the accessor.
Agent string `toml:"agent"`
Image string `toml:"image"`
// Cmd is the command to run inside the island when Agent is "headless".
// It is ignored for the built-in CLI agents (claude-code, codex), which
// have a baked-in command. Persisted so reset/reprovision can reuse it.
Cmd string `toml:"cmd,omitempty"`
Resources Resources `toml:"resources,omitempty"`
CreatedAt time.Time `toml:"created_at"`
LastUsedAt time.Time `toml:"last_used_at"`
DesiredState State `toml:"state"`
Agents []AgentSpec `toml:"agents,omitempty"`
// NoHibernate pins the island awake: when true it is exempt from idle
// auto-hibernate (it can still be hibernated manually). For a persistent
// ambient agent — a watchtower / monitor that must keep running between bursts
// of work — so an idle window doesn't shut it off. Default false.
NoHibernate bool `toml:"no_hibernate,omitempty"`
// Schedules are durable per-island scheduled wakes (see schedule.go). The
// daemon's scheduler fires each when due, waking the island (and optionally
// running a task) — surviving restart and `dejima upgrade`.
Schedules []WakeSchedule `toml:"schedules,omitempty"`
// Role is the island's purpose: "" (a work island) or "home" (a Home Island
// hosting an assistant brain). Empty for islands created before roles existed.
Role string `toml:"role,omitempty"`
// GitHubIdentity names which of the daemon's GitHub identities this island
// clones and pushes as (see internal/githubid). Empty means the daemon's
// default identity, or — when the store is empty — the host's ~/.config/gh.
GitHubIdentity string `toml:"github_identity,omitempty"`
// Ports are brokered host-filesystem grants for this island (see ports.go).
// Empty means deny-all: the island reaches no host content outside its repo.
Ports []PortScope `toml:"ports,omitempty"`
// Capabilities are brokered host-action grants for this island (see
// capabilities.go and docs/capability-broker-spec.md). Empty means deny-all:
// the island may invoke no host capabilities.
Capabilities []CapabilityGrant `toml:"capabilities,omitempty"`
// LinkActions are the named, typed action types THIS island exposes for
// cross-island delegation (Lane 5, Phase 3). Another island may invoke one of
// these only if it ALSO holds a link grant authorizing it (or an operator
// approves ad hoc). Empty means deny-all: this island exposes no actions.
LinkActions []string `toml:"link_actions,omitempty"`
// Owner is a free-form creator label (e.g. "alice@laptop"), captured at
// create time. Purely informational — there is no auth model yet — but it
// lets wrapper dashboards attribute islands per person/team. Empty for
// islands created before ownership existed.
Owner string `toml:"owner,omitempty"`
// Tags are free-form key=value labels (e.g. team=web, env=staging) for
// grouping and per-team rollups in wrapper tooling. Empty when untagged.
Tags map[string]string `toml:"tags,omitempty"`
// BuiltVersion is the daemon version (version.Version) this island's container
// was first created against, and UpgradedVersion is the version of the most
// recent `dejima upgrade` recreate. They are the version-skew stamp: an island
// whose UpgradedVersion (falling back to BuiltVersion) is behind the running
// daemon was built from an older image and may carry stale /opt shims (the
// socket→TCP heartbeat-break class of bug). The api layer sets these from
// version.Version at create/upgrade; project stays a pure data struct. Empty
// for islands created before this stamp existed ("unknown" provenance).
BuiltVersion string `toml:"built_version,omitempty"`
UpgradedVersion string `toml:"upgraded_version,omitempty"`
// Identity is the operator-chosen visual identity (color + glyph) override for
// this island, persisted in config.toml. Nil/zero means no override — the TUI
// then falls back to its deterministic per-name default. Set/cleared by the
// operator via PUT/DELETE /v1/islands/{name}/identity. Cosmetic only.
Identity Identity `toml:"identity,omitempty"`
// HostGitHubGrant, when set, lets this island mount the HOST operator's own
// ~/.config/gh — a credential whose read scope is the operator's entire
// account. Nil means denied, which is the default for every island created
// under the grant model. See github_host.go.
HostGitHubGrant *HostGitHubGrant `toml:"host_github_grant,omitempty"`
// HostGitHubReviewed records that the deny-by-default decision has been made
// for this island — by creation under the grant model, by an operator
// grant/revoke, or by the one-time migration. It is what stops a revoke from
// being undone by re-grandfathering on the next Load.
HostGitHubReviewed bool `toml:"host_github_reviewed,omitempty"`
}
Project is the persisted record for a single island.
func (*Project) AddCapabilityGrant ¶
func (p *Project) AddCapabilityGrant(g CapabilityGrant) (CapabilityGrant, error)
AddCapabilityGrant records a grant, rejecting a duplicate target. The target is validated by the caller (see ValidateCapabilityTarget).
func (*Project) AddLinkAction ¶
AddLinkAction exposes action (idempotent). Returns false if already exposed.
func (*Project) AddPortScope ¶
AddPortScope cleans the host path, assigns a unique Name, and appends the scope. It errors if the host path is already granted. Returns the stored scope (with its assigned Name).
func (*Project) AddSchedule ¶ added in v0.8.3
func (p *Project) AddSchedule(s WakeSchedule) WakeSchedule
AddSchedule appends s (assigning an id if empty) and returns the stored value.
func (*Project) BackfillAgentLabels ¶ added in v0.6.9
BackfillAgentLabels assigns a derived default label to every agent whose Label is blank (empty or all-whitespace), so islands created before default labels existed get readable names with no manual step. It is:
- idempotent: agents that already have a label are left untouched, so a second run is a no-op (it never re-derives or appends "-2" to a settled label);
- order-stable: it walks Agents in slice order and derives each label against the labels already present (including ones it just assigned), so the same island always yields the same names; and
- collision-safe within the island: two blank "claude-code" agents become "claude" and "claude-2", never two "claude".
It mutates in place and returns whether it changed anything, so callers can persist (Save) only when needed and avoid a write storm on already-backfilled islands.
func (*Project) CapabilityGrantByTarget ¶
func (p *Project) CapabilityGrantByTarget(target string) (CapabilityGrant, bool)
CapabilityGrantByTarget returns the grant for target, or ok=false.
func (*Project) ContainerName ¶
ContainerName returns the deterministic container name for this project.
func (*Project) DefaultAgentLabel ¶ added in v0.6.9
DefaultAgentLabel derives the unique, non-blank label an agent should get when it is created (or backfilled) WITHOUT an explicit label. It maps the agent's Type to a readable base (e.g. "claude-code" → "claude", unknown → "agent") and runs that base through UniqueAgentLabel so the stored default never collides with an existing agent ("claude", "claude-2", …). It NEVER returns blank. exclude lets a caller ignore one agent (e.g. the one being (re)labeled) when checking for collisions; pass "" at create time.
func (*Project) DisplayName ¶
DisplayName is the user-facing name: the Title if set, else the Name slug.
func (*Project) EnsureAgents ¶
func (p *Project) EnsureAgents()
EnsureAgents back-fills Agents from the legacy scalar Agent field for projects persisted under the pre-multi-agent schema. Idempotent: a no-op once Agents is populated. Called on Load and at provision time.
func (*Project) ExposesAction ¶
ExposesAction reports whether this island exposes the named action type for cross-island delegation (Lane 5, Phase 3). Deny-all: an unexposed action can never be invoked, even with a link grant.
func (*Project) GrantHostGitHub ¶ added in v0.8.66
func (p *Project) GrantHostGitHub(by string, now time.Time) *HostGitHubGrant
GrantHostGitHub records an explicit operator grant, replacing any existing one (which also clears the Grandfathered marker — an operator re-granting is a deliberate decision, and should stop being reported as leftover migration state). Returns the stored grant.
func (*Project) HomeVolume ¶
HomeVolume returns the per-island home-state volume, mounted at /home/dejima and shared by every agent in the island. Persisting the whole home means tool auth set once by any agent (Claude/Codex creds, ~/.npmrc, gh, eas/expo) survives restarts and is shared — the "collective permissioning" goal.
func (*Project) HostGitHubAllowed ¶ added in v0.8.66
HostGitHubAllowed reports whether this island may mount the host operator's own gh credential. Deny-by-default: no grant, no credential.
func (*Project) IsHome ¶
IsHome reports whether this island is a Home Island (hosts an assistant brain).
func (*Project) IsHostOwned ¶ added in v0.8.66
IsHostOwned reports whether this island belongs to the host operator rather than a tenant. Ownership is backfilled on Load, so an empty owner only occurs on a Project that hasn't been through it yet.
func (*Project) MoveAgent ¶ added in v0.6.0
MoveAgent shifts the agent with the given id by delta positions within the list (negative = toward the front), clamping to the ends. Reports whether the agent was found and actually moved. Order is cosmetic — the dashboard and CLI no longer key off position — except that Agents[0] still seeds the container entrypoint on the next recreate (see docs/island-pid1-unification.md).
func (*Project) NetworkName ¶
NetworkName returns the per-island Docker network name.
func (*Project) NextAgentID ¶
NextAgentID returns the next monotonic "<letter><N>" id not currently in use. The letter is the island's mnemonic prefix (see agentIDPrefix), so an island named "Port" yields p1, p2, …. Ids are scoped per island and never reused within an island's life, so a removed agent's id stays retired. Numbering is monotonic across whatever prefixes already exist, so a legacy island that holds a1/a2 simply continues at the new prefix (p3).
func (*Project) NextScheduleID ¶ added in v0.8.3
NextScheduleID returns an island-unique schedule id ("sched-1", "sched-2", …), mirroring NextAgentID.
func (*Project) PortScopeByHostPath ¶
PortScopeByHostPath returns the scope for the given (cleaned) host path.
func (*Project) PortScopeByName ¶
PortScopeByName returns the scope with the given handle.
func (*Project) PrimaryAgent ¶
PrimaryAgent returns the island's first/primary agent (the attach target for legacy clients), or nil if the island has no agents.
func (*Project) RemoveAgent ¶
RemoveAgent drops the agent with the given id. Reports whether it was found.
func (*Project) RemoveCapabilityGrant ¶
func (p *Project) RemoveCapabilityGrant(target string) (CapabilityGrant, bool)
RemoveCapabilityGrant removes the grant for target; ok=false if not present.
func (*Project) RemoveLinkAction ¶
RemoveLinkAction unexposes action. Returns false if it wasn't exposed.
func (*Project) RemovePortScope ¶
RemovePortScope drops the scope identified by key, which may be either its Name or its (cleaned) host path. Reports the removed scope and whether found.
func (*Project) RemoveSchedule ¶ added in v0.8.3
RemoveSchedule drops the schedule with the given id, reporting whether one was found and removed.
func (*Project) ResolveAgentRef ¶ added in v0.6.9
ResolveAgentRef resolves a user-supplied ref (an id or a label) against this island's agents and returns the matching AgentSpec. See the package-level ResolveAgentRef for the resolution rules (id-wins, case-insensitive label, ambiguity and no-match errors).
func (*Project) RevokeHostGitHub ¶ added in v0.8.66
func (p *Project) RevokeHostGitHub() (*HostGitHubGrant, bool)
RevokeHostGitHub drops the grant. Returns the removed grant and whether there was one. The island keeps working; it just falls back to having no GitHub credential, which surfaces the same way it does for a tenant island.
func (*Project) SetPrimaryID ¶
SetPrimaryID renames the primary agent's id and the tmux session derived from it. Intended for fresh provision only — before any container or session exists — so it deliberately does not migrate a running session.
func (*Project) StampVersion ¶ added in v0.6.0
StampVersion returns the most authoritative version this island was last built or upgraded against: the upgrade stamp if present, else the build stamp. Empty when the island predates version stamping (provenance unknown).
func (*Project) UniqueAgentLabel ¶ added in v0.6.7
UniqueAgentLabel returns a label not in use by any existing agent in this island, deduping case-insensitively on the trimmed value. If desired is empty (or all whitespace) it is returned as-is — empty labels are allowed and never deduped. Otherwise, on a collision it appends "-2", "-3", … skipping any variant already taken ("build" → "build-2" → "build-3"), mirroring the spirit of NextAgentID. exclude lets a rename ignore the agent being renamed so renaming to its own current label is a no-op (not "build-2"); pass "" at create time when there is nothing to exclude.
func (*Project) WorkspaceVolume ¶
WorkspaceVolume returns the workspace volume name.
type Resources ¶
type Resources struct {
Memory string `toml:"memory,omitempty"` // e.g. "4G"
CPUs string `toml:"cpus,omitempty"` // e.g. "2.0"
Disk string `toml:"disk,omitempty"` // e.g. "20G" — maps to --storage-opt size=
// OOMPriority stack-ranks islands for the kernel OOM killer: higher = more
// protected (killed later). nil = unset → resolved to a smart default at
// create (headless brains start expendable). Mapped to docker --oom-score-adj
// (inverted) in the api layer. Set-at-create only; a change needs a recreate.
OOMPriority *int `toml:"oom_priority,omitempty"`
}
Resources captures the docker resource caps applied to the container. All fields optional; zero/empty means unlimited.
type WakeSchedule ¶ added in v0.8.3
type WakeSchedule struct {
ID string `toml:"id"`
// Every is a Go duration string ("720h") for a recurring wake; "" = one-shot.
Every string `toml:"every,omitempty"`
// Task is an optional prompt/command injected into the agent on wake; "" just
// wakes the island (what then runs is the agent's own business).
Task string `toml:"task,omitempty"`
// Agent selects which agent runs Task (id or label); "" = the island's primary.
Agent string `toml:"agent,omitempty"`
// NextDue is when the scheduler should next fire this (UTC).
NextDue time.Time `toml:"next_due"`
// LastRun is the last time it fired (UTC); zero until the first fire. No
// omitempty: go-toml/v2's omitempty drops a non-zero time.Time, which would
// silently lose the last-run stamp across a save/load.
LastRun time.Time `toml:"last_run"`
CreatedAt time.Time `toml:"created_at"`
}
WakeSchedule is a durable, daemon-owned instruction to wake an island on a cadence (or once), optionally running a task on the agent. Stored in the island's config.toml so it survives daemon restart AND `dejima upgrade` — the whole point versus an in-island cron, which dies on container recreate.
func (*WakeSchedule) AdvanceAfterFire ¶ added in v0.8.3
func (w *WakeSchedule) AdvanceAfterFire(now time.Time) bool
AdvanceAfterFire moves a recurring schedule's NextDue forward FROM now (catch-up, not stack: anchor to now+Every rather than replaying every missed interval). Returns false for a one-shot — the caller deletes it after firing.
func (WakeSchedule) Due ¶ added in v0.8.3
func (w WakeSchedule) Due(now time.Time) bool
Due reports whether the schedule should fire at now.
func (WakeSchedule) EveryDuration ¶ added in v0.8.3
func (w WakeSchedule) EveryDuration() (time.Duration, bool)
EveryDuration parses Every into a positive duration; ok=false for a one-shot (empty or unparseable Every).
func (WakeSchedule) Recurring ¶ added in v0.8.3
func (w WakeSchedule) Recurring() bool
Recurring reports whether this schedule repeats.