Workspace Lifecycle
This document defines the lifecycle operations for Morphir workspaces: creation, opening, closing, and configuration management.
Overview
Workspace lifecycle operations manage the overall state of a workspace session. A workspace must be opened before any project operations can be performed.
State Machine
┌─────────────────┐
│ (none) │
└────────┬────────┘
│ create / open
▼
┌─────────────────┐
│ initializing │
└────────┬────────┘
│
┌──────────────┴──────────────┐
│ success │ failure
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ open │ │ error │
└────────┬────────┘ └────────┬────────┘
│ close │ close
└──────────────┬──────────────┘
▼
┌─────────────────┐
│ closed │
└─────────────────┘
Types
WorkspaceState
/// Workspace lifecycle state
pub type WorkspaceState {
/// Workspace is not active
Closed
/// Workspace is being initialized
Initializing
/// Workspace is ready for operations
Open
/// Workspace has unrecoverable errors
Error
}
WorkspaceInfo
/// Complete workspace information
pub type WorkspaceInfo {
WorkspaceInfo(
/// Absolute path to workspace root
root: String,
/// Workspace name (from config or derived from root)
name: String,
/// Current lifecycle state
state: WorkspaceState,
/// Projects in this workspace
projects: List(ProjectInfo),
/// Workspace-level configuration
config: Option(Document),
)
}
WorkspaceError
/// Errors that can occur during workspace operations
pub type WorkspaceError {
/// Workspace directory not found
NotFound(path: String)
/// Workspace already exists at path
AlreadyExists(path: String)
/// No workspace is currently open
NotOpen
/// Invalid workspace configuration
InvalidConfig(message: String)
/// IO error during operation
IoError(message: String)
}
Operations
Create Workspace
Creates a new workspace at the specified path.
Behavior
- Verify path does not already contain a workspace
- Create
morphir.tomlwith initial configuration - Create
.morphir/directory for cache and state - Transition to
Openstate - Return workspace info
WIT Interface
/// Create a new workspace
create-workspace: func(
/// Workspace root path (must not exist or be empty)
root: string,
/// Initial configuration (optional)
config: option<document-value>,
) -> result<workspace-info, workspace-error>;
JSON-RPC
Request:
{
"method": "workspace/create",
"params": {
"root": "/path/to/workspace",
"config": {
"name": "my-workspace"
}
}
}
Response:
{
"result": {
"root": "/path/to/workspace",
"name": "my-workspace",
"state": "open",
"projects": []
}
}
CLI
morphir workspace init [path]
morphir workspace init --name my-workspace
Open Workspace
Opens an existing workspace for operations.
Behavior
- Locate
morphir.toml(search upward if needed) - Parse workspace configuration
- Discover projects in workspace
- Load project metadata (not full IR)
- Transition to
Openstate - Return workspace info
WIT Interface
/// Open an existing workspace
open-workspace: func(
/// Workspace root path
root: string,
) -> result<workspace-info, workspace-error>;
JSON-RPC
Request:
{
"method": "workspace/open",
"params": {
"root": "/path/to/workspace"
}
}
Response:
{
"result": {
"root": "/path/to/workspace",
"name": "my-workspace",
"state": "open",
"projects": [
{
"name": "my-org/core",
"version": "1.0.0",
"path": "packages/core",
"state": "unloaded",
"sourceDir": "src"
}
]
}
}
CLI
morphir workspace open [path]
cd /path/to/workspace && morphir workspace open
Close Workspace
Closes the current workspace, releasing resources.
Behavior
- Stop file watching if active
- Unload all projects
- Flush any pending state
- Transition to
Closedstate
WIT Interface
/// Close the current workspace
close-workspace: func() -> result<_, workspace-error>;
JSON-RPC
Request:
{
"method": "workspace/close",
"params": {}
}
Response:
{
"result": null
}
Get Workspace Info
Returns current workspace state and information.
WIT Interface
/// Get current workspace info
get-workspace-info: func() -> result<workspace-info, workspace-error>;
JSON-RPC
Request:
{
"method": "workspace/info",
"params": {}
}
Update Configuration
Updates workspace-level configuration.
Behavior
- Validate new configuration
- Merge with existing configuration
- Write updated
morphir.toml - Notify affected projects if needed
WIT Interface
/// Update workspace configuration
update-workspace-config: func(
config: document-value,
) -> result<_, workspace-error>;
JSON-RPC
Request:
{
"method": "workspace/updateConfig",
"params": {
"config": {
"defaultSourceDir": "lib",
"outputDir": "dist"
}
}
}
Configuration
See Configuration System for full configuration documentation.
morphir.toml
[morphir]
version = "^4.0.0"
[workspace]
# Output directory for workspace-level artifacts
output_dir = ".morphir"
# Glob patterns for discovering member projects
members = ["packages/*"]
# Patterns to exclude from discovery
exclude = ["packages/deprecated-*"]
# Default member when no project specified
default_member = "packages/core"
# Shared dependencies (resolved once for all projects)
[workspace.dependencies]
"morphir/sdk" = "3.0.0"
# Default settings inherited by all projects
[ir]
format_version = 4
[codegen]
targets = ["typescript"]
Error Handling
| Error | Cause | Recovery |
|---|---|---|
NotFound | Path doesn't exist or has no workspace | Use create instead |
AlreadyExists | Workspace already at path | Use open instead |
NotOpen | Operation requires open workspace | Call open first |
InvalidConfig | Malformed configuration file | Fix configuration |
IoError | File system error | Check permissions |
Best Practices
- Single Active Workspace: Only one workspace should be open per daemon instance
- Workspace Discovery: Search upward for
morphir.tomlto support nested directories - Graceful Degradation: If workspace config is missing, treat directory as single-project workspace
- State Persistence: Save workspace state to
.morphir/state.jsonfor session recovery