Skip to content

Scenarios

Claude with a Model from Vertex AI

This scenario demonstrates how to configure Claude Code to use a model hosted on Google Cloud Vertex AI instead of the default Anthropic API. This is useful when you need to use Claude through your Google Cloud organization's billing or compliance setup.

Prerequisites:

  • A Google Cloud project with the Vertex AI API enabled and Claude models available
  • Google Cloud credentials configured on your host machine (via gcloud auth application-default login)

Step 1: Configure Claude agent settings

Create or edit ~/.kdn/config/agents.json to add the required environment variables and mount your Google Cloud credentials into the workspace:

{
  "claude": {
    "environment": [
      {
        "name": "CLAUDE_CODE_USE_VERTEX",
        "value": "1"
      },
      {
        "name": "ANTHROPIC_VERTEX_PROJECT_ID",
        "value": "my-gcp-project-id"
      },
      {
        "name": "CLOUD_ML_REGION",
        "value": "my-region"
      }
    ],
    "mounts": [
      {"host": "$HOME/.config/gcloud", "target": "$HOME/.config/gcloud", "ro": true}
    ]
  }
}

Fields:

  • CLAUDE_CODE_USE_VERTEX - Set to 1 to instruct Claude Code to use Vertex AI instead of the Anthropic API
  • ANTHROPIC_VERTEX_PROJECT_ID - Your Google Cloud project ID where Vertex AI is configured
  • CLOUD_ML_REGION - The region where Claude is available on Vertex AI (e.g., us-east5)
  • $HOME/.config/gcloud mounted read-only - Provides the workspace access to your application default credentials

Step 2: Register and start the workspace

# Register a workspace with the Podman runtime and Claude agent
kdn init /path/to/project --runtime podman --agent claude

# Start the workspace (using name or ID)
kdn start my-project

# Connect to the workspace — Claude Code will use Vertex AI automatically
kdn terminal my-project

When Claude Code starts, it detects ANTHROPIC_VERTEX_PROJECT_ID and CLOUD_ML_REGION and routes all requests to Vertex AI using the mounted application default credentials.

Sharing local Claude settings (optional)

To reuse your host Claude Code settings (preferences, custom instructions, etc.) inside the workspace, add ~/.claude and ~/.claude.json to the mounts:

{
  "claude": {
    "environment": [
      {
        "name": "CLAUDE_CODE_USE_VERTEX",
        "value": "1"
      },
      {
        "name": "ANTHROPIC_VERTEX_PROJECT_ID",
        "value": "my-gcp-project-id"
      },
      {
        "name": "CLOUD_ML_REGION",
        "value": "my-region"
      }
    ],
    "mounts": [
      {"host": "$HOME/.config/gcloud", "target": "$HOME/.config/gcloud", "ro": true},
      {"host": "$HOME/.claude", "target": "$HOME/.claude"},
      {"host": "$HOME/.claude.json", "target": "$HOME/.claude.json"}
    ]
  }
}

~/.claude contains your Claude Code configuration directory (skills, settings) and ~/.claude.json stores your account and preferences. These are mounted read-write so that changes made inside the workspace (e.g., updated preferences) are persisted back to your host.

Notes:

  • Run gcloud auth application-default login on your host machine before starting the workspace to ensure valid credentials are available
  • The $HOME/.config/gcloud mount is read-only to prevent the workspace from modifying your host credentials
  • No ANTHROPIC_API_KEY is needed when using Vertex AI — credentials are provided via the mounted gcloud configuration
  • To pin a specific Claude model, use --model flag during init (e.g., --model claude-sonnet-4-20250514), which takes precedence over any model in default settings, or add an ANTHROPIC_MODEL environment variable (e.g., "claude-opus-4-5")

Starting Claude with Default Settings

This scenario demonstrates how to pre-configure Claude Code's settings so that when it starts inside a workspace, it skips the interactive onboarding flow and uses your preferred defaults. kdn automatically handles the onboarding flags, and you can optionally customize other settings like theme preferences.

Automatic Onboarding Skip

When you register a workspace with the Claude agent, kdn automatically: - Sets hasCompletedOnboarding: true to skip the first-run wizard - Sets hasTrustDialogAccepted: true for the workspace sources directory (the exact path is determined by the runtime)

This happens automatically for every Claude workspace — no manual configuration required.

Optional: Customize Theme and Other Settings

If you want to customize Claude's theme or other preferences, create default settings:

Step 1: Create the agent settings directory

mkdir -p ~/.kdn/config/claude

Step 2: Write the default Claude settings file

cat > ~/.kdn/config/claude/.claude.json << 'EOF'
{
  "theme": "dark-daltonized"
}
EOF

Fields:

  • theme - The UI theme for Claude Code (e.g., "dark", "light", "dark-daltonized")

You don't need to set hasCompletedOnboarding or hasTrustDialogAccepted — kdn adds these automatically when creating the workspace.

Step 3: Register and start the workspace

# Register a workspace — the settings file is embedded in the container image
kdn init /path/to/project --runtime podman --agent claude

# Start the workspace (using name or ID)
kdn start my-project

# Connect — Claude Code starts directly without onboarding
kdn terminal my-project

When init runs, kdn: 1. Reads all files from ~/.kdn/config/claude/ (e.g., your theme preferences) 2. Automatically adds hasCompletedOnboarding: true and marks the workspace sources directory as trusted (the path is determined by the runtime) 3. Copies the final merged settings into the container image at /home/agent/.claude.json

Claude Code finds this file on startup and skips onboarding.

Notes:

  • Onboarding is skipped automatically — even if you don't create any settings files, kdn ensures Claude starts without prompts
  • The settings are baked into the container image at init time, not mounted at runtime — changes to the files on the host require re-registering the workspace to take effect
  • Any file placed under ~/.kdn/config/claude/ is copied into the container home directory, preserving the directory structure (e.g., ~/.kdn/config/claude/.some-tool/config becomes /home/agent/.some-tool/config inside the container)
  • This approach keeps your workspace self-contained — other developers using the same project are not affected, and your local ~/.claude directory is not exposed inside the container
  • To apply changes to the settings, remove and re-register the workspace: kdn remove <workspace-id> then kdn init again

Using Goose Agent with a Model from Vertex AI

This scenario demonstrates how to configure the Goose agent in a kdn workspace using Vertex AI as the backend, covering credential injection, sharing your local gcloud configuration, and pre-configuring the default model.

Authenticating with Vertex AI

Goose can use Google Cloud Vertex AI as its backend. Authentication relies on Application Default Credentials (ADC) provided by the gcloud CLI. Mount your local ~/.config/gcloud directory to make your host credentials available inside the workspace, and set the GCP_PROJECT_ID, GCP_LOCATION, and GOOSE_PROVIDER environment variables to tell Goose which project and region to use.

Create or edit ~/.kdn/config/agents.json:

{
  "goose": {
    "environment": [
      {
        "name": "GOOSE_PROVIDER",
        "value": "gcp_vertex_ai"
      },
      {
        "name": "GCP_PROJECT_ID",
        "value": "my-gcp-project"
      },
      {
        "name": "GCP_LOCATION",
        "value": "my-region"
      }
    ],
    "mounts": [
      {"host": "$HOME/.config/gcloud", "target": "$HOME/.config/gcloud", "ro": true}
    ]
  }
}

The ~/.config/gcloud directory contains your Application Default Credentials and active account configuration. It is mounted read-only so that credentials are available inside the workspace while the host configuration remains unmodified.

Then register and start the workspace:

# Register a workspace with the Podman runtime and Goose agent
kdn init /path/to/project --runtime podman --agent goose

# Start the workspace
kdn start my-project

# Connect — Goose starts with Vertex AI configured
kdn terminal my-project

Sharing Local Goose Settings

To reuse your host Goose settings (model preferences, provider configuration, etc.) inside the workspace, mount the ~/.config/goose directory.

Edit ~/.kdn/config/agents.json to add the mount alongside the Vertex AI configuration:

{
  "goose": {
    "environment": [
      {
        "name": "GOOSE_PROVIDER",
        "value": "gcp_vertex_ai"
      },
      {
        "name": "GCP_PROJECT_ID",
        "value": "my-gcp-project"
      },
      {
        "name": "GCP_LOCATION",
        "value": "my-region"
      }
    ],
    "mounts": [
      {"host": "$HOME/.config/gcloud", "target": "$HOME/.config/gcloud", "ro": true},
      {"host": "$HOME/.config/goose", "target": "$HOME/.config/goose"}
    ]
  }
}

The ~/.config/goose directory contains your Goose configuration (settings, model preferences, etc.). It is mounted read-write so that changes made inside the workspace are persisted back to your host.

Using Default Settings

If you want to pre-configure Goose with default settings without exposing your local ~/.config/goose directory inside the container, create default settings files that are baked into the container image at workspace registration time. This is an alternative to mounting your local Goose settings — use one approach or the other, not both.

Automatic Onboarding Skip

When you register a workspace with the Goose agent, kdn automatically sets GOOSE_TELEMETRY_ENABLED to false in the Goose config file if it is not already defined, so Goose skips its telemetry prompt on first launch.

Step 1: Create the agent settings directory

mkdir -p ~/.kdn/config/goose/.config/goose

Step 2: Write the default Goose settings file

As an example, you can configure the model and enable telemetry:

cat > ~/.kdn/config/goose/.config/goose/config.yaml << 'EOF'
GOOSE_MODEL: "claude-sonnet-4-6"
GOOSE_TELEMETRY_ENABLED: true
EOF

Fields:

  • GOOSE_MODEL - The model identifier Goose uses for its AI interactions. Alternatively, use --model flag during init to set this (the flag takes precedence over this setting)
  • GOOSE_TELEMETRY_ENABLED - Whether Goose sends usage telemetry; set to true to opt in, or omit to have kdn default it to false

Step 3: Register and start the workspace

# Register a workspace — the settings file is embedded in the container image
kdn init /path/to/project --runtime podman --agent goose

# Start the workspace
kdn start my-project

# Connect — Goose starts with the configured provider and model
kdn terminal my-project

When init runs, kdn: 1. Reads all files from ~/.kdn/config/goose/ (e.g., your provider and model settings) 2. Automatically sets GOOSE_TELEMETRY_ENABLED: false in .config/goose/config.yaml if the key is not already defined 3. Copies the final settings into the container image at /home/agent/.config/goose/config.yaml

Goose finds this file on startup and uses the pre-configured settings without prompting.

Notes:

  • Telemetry is disabled automatically — even if you don't create any settings files, kdn ensures Goose starts without the telemetry prompt
  • If you prefer to enable telemetry, set GOOSE_TELEMETRY_ENABLED: true in ~/.kdn/config/goose/.config/goose/config.yaml
  • The settings are baked into the container image at init time, not mounted at runtime — changes to the files on the host require re-registering the workspace to take effect
  • Any file placed under ~/.kdn/config/goose/ is copied into the container home directory, preserving the directory structure (e.g., ~/.kdn/config/goose/.config/goose/config.yaml becomes /home/agent/.config/goose/config.yaml inside the container)
  • This approach keeps your workspace self-contained — other developers using the same project are not affected, and your local ~/.config/goose directory is not exposed inside the container
  • To apply changes to the settings, remove and re-register the workspace: kdn remove <workspace-id> then kdn init again

Using Cursor CLI Agent

This scenario demonstrates how to configure the Cursor agent in a kdn workspace, covering API key injection, sharing your local Cursor settings, and pre-configuring the default model.

Defining the Cursor API Key via a Secret

Cursor requires a CURSOR_API_KEY environment variable to authenticate with the Cursor service. Rather than embedding the key as plain text, use the secret mechanism to keep credentials out of your configuration files.

Step 1: Create the secret

For the Podman runtime, create the secret once on your host machine using podman secret create:

echo "$CURSOR_API_KEY" | podman secret create cursor-api-key -

Step 2: Reference the secret in agent configuration

Create or edit ~/.kdn/config/agents.json to inject the secret as an environment variable for the cursor agent:

{
  "cursor": {
    "environment": [
      {
        "name": "CURSOR_API_KEY",
        "secret": "cursor-api-key"
      }
    ]
  }
}

Step 3: Register and start the workspace

# Register a workspace with the Podman runtime and Cursor agent
kdn init /path/to/project --runtime podman --agent cursor

# Start the workspace
kdn start my-project

# Connect — Cursor starts with the API key available
kdn terminal my-project

The secret name (cursor-api-key) must match the secret field value in your configuration. At workspace creation time, kdn passes the secret to Podman, which injects it as the CURSOR_API_KEY environment variable inside the container.

Sharing Local Cursor Settings

To reuse your host Cursor settings (preferences, keybindings, extensions configuration, etc.) inside the workspace, mount the ~/.cursor directory.

Edit ~/.kdn/config/agents.json to add the mount:

{
  "cursor": {
    "environment": [
      {
        "name": "CURSOR_API_KEY",
        "secret": "cursor-api-key"
      }
    ],
    "mounts": [
      {"host": "$HOME/.cursor", "target": "$HOME/.cursor"}
    ]
  }
}

The ~/.cursor directory contains your Cursor configuration (settings, model preferences, etc.). It is mounted read-write so that changes made inside the workspace are persisted back to your host.

Using Default Settings

If you want to pre-configure Cursor with default settings without exposing your local ~/.cursor directory inside the container, create default settings files that are baked into the container image at workspace registration time. This is an alternative to mounting your local Cursor settings — use one approach or the other, not both.

Automatic Onboarding Skip

When you register a workspace with the Cursor agent, kdn automatically creates a .workspace-trusted file in the Cursor projects directory for the workspace sources path, so Cursor skips its workspace trust dialog on first launch.

Step 1: Configure the agent environment

Create or edit ~/.kdn/config/agents.json to inject the API key. No mount is needed since settings are baked in:

{
  "cursor": {
    "environment": [
      {
        "name": "CURSOR_API_KEY",
        "secret": "cursor-api-key"
      }
    ]
  }
}

Step 2: Create the agent settings directory

mkdir -p ~/.kdn/config/cursor/.cursor

Step 3: Write the default Cursor settings file (optional)

You can optionally pre-configure Cursor with additional settings by creating a cli-config.json file:

cat > ~/.kdn/config/cursor/.cursor/cli-config.json << 'EOF'
{
  "model": {
    "modelId": "my-preferred-model",
    "displayModelId": "my-preferred-model",
    "displayName": "My Preferred Model",
    "displayNameShort": "My Model",
    "maxMode": false
  },
  "hasChangedDefaultModel": true
}
EOF

Fields:

  • model.modelId - The model identifier used internally by Cursor
  • model.displayName / model.displayNameShort - Human-readable model names shown in the UI
  • model.maxMode - Whether to enable max mode for this model
  • hasChangedDefaultModel - Tells Cursor that the model selection is intentional and should not prompt the user to choose a model

Note: Using the --model flag during init is the preferred way to configure the model, as it automatically sets all model fields correctly.

Step 4: Register and start the workspace

# Register a workspace with a specific model using the --model flag (recommended)
kdn init /path/to/project --runtime podman --agent cursor --model my-model-id

# Or register without --model to use settings from cli-config.json
kdn init /path/to/project --runtime podman --agent cursor

# Start the workspace
kdn start my-project

# Connect — Cursor starts with the configured model
kdn terminal my-project

When init runs, kdn: 1. Reads all files from ~/.kdn/config/cursor/ (e.g., your settings) 2. If --model is specified, updates cli-config.json with the model configuration (takes precedence over any existing model in settings files) 3. Automatically creates the workspace trust file so Cursor skips its trust dialog 4. Copies the final settings into the container image at /home/agent/.cursor/cli-config.json

Cursor finds this file on startup and uses the pre-configured model without prompting.

Notes:

  • Model configuration: Use --model flag during init to set the model (e.g., --model my-model-id). This takes precedence over any model defined in settings files
  • The settings are baked into the container image at init time, not mounted at runtime — changes to the files on the host require re-registering the workspace to take effect
  • Any file placed under ~/.kdn/config/cursor/ is copied into the container home directory, preserving the directory structure (e.g., ~/.kdn/config/cursor/.cursor/cli-config.json becomes /home/agent/.cursor/cli-config.json inside the container)
  • To apply changes to the settings, remove and re-register the workspace: kdn remove <workspace-id> then kdn init again
  • This approach keeps your workspace self-contained — other developers using the same project are not affected, and your local ~/.cursor directory is not exposed inside the container
  • Do not combine this approach with the ~/.cursor mount from the previous section — the mounted directory would override the baked-in defaults at runtime

Sharing a GitHub Token

This scenario demonstrates how to make a GitHub token available inside workspaces using the multi-level configuration system — either globally for all projects or scoped to a specific project.

For all projects

Edit ~/.kdn/config/projects.json and add the token and your git configuration under the global "" key:

{
  "": {
    "environment": [
      {
        "name": "GH_TOKEN",
        "secret": "github-token"
      }
    ],
    "mounts": [
      {"host": "$HOME/.gitconfig", "target": "$HOME/.gitconfig", "ro": true}
    ]
  }
}

The GH_TOKEN variable is automatically picked up by the gh CLI and other GitHub-aware tools running inside the workspace. The $HOME/.gitconfig mount makes your git identity (name, email, aliases, etc.) available to git commands run by the agent.

For a specific project

Use the project identifier as the key instead. The identifier is the git remote URL (without .git) as detected by kdn during init:

{
  "https://github.com/my-org/my-repo/": {
    "environment": [
      {
        "name": "GH_TOKEN",
        "secret": "github-token"
      }
    ]
  }
}

This injects the token only when working on workspaces that belong to https://github.com/my-org/my-repo/, leaving other projects unaffected.

Both at once

You can combine global and project-specific entries in the same file. The project-specific value takes precedence over the global one if both define the same variable:

{
  "": {
    "environment": [
      {
        "name": "GH_TOKEN",
        "secret": "github-token-default"
      }
    ]
  },
  "https://github.com/my-org/my-private-repo/": {
    "environment": [
      {
        "name": "GH_TOKEN",
        "secret": "github-token-private"
      }
    ]
  }
}

Creating the secret

How secrets are created depends on the runtime being used. The secret field value is the name under which the secret is registered with that runtime.

For the Podman runtime, create the secret once on your host machine using podman secret create before registering the workspace:

# Create the secret from an environment variable
echo "$GITHUB_TOKEN" | podman secret create github-token -

# Or create it from a file
podman secret create github-token /path/to/token-file

The secret name (github-token here) must match the secret field value in your configuration. At workspace creation time, kdn passes --secret github-token,type=env,target=GH_TOKEN to Podman, which injects the secret value as the GH_TOKEN environment variable inside the container.

Podman secrets are stored locally on the host and never written to the container image.

Notes:

  • The secret field references a secret by name rather than embedding the token value directly, keeping credentials out of the configuration file
  • The project identifier used as the key must match what kdn detected during init — run kdn list -o json to see the project field for each registered workspace
  • Configuration changes in projects.json take effect the next time you run kdn init for that workspace; already-registered workspaces need to be removed and re-registered

Working with Git Worktrees

This scenario demonstrates how to run multiple agents in parallel, each working on a different branch of the same repository. Git worktrees allow each branch to live in its own directory, so each agent gets its own isolated workspace.

Step 1: Clone the repository

git clone https://github.com/my-org/my-repo.git /path/to/my-project/main

Step 2: Create a worktree for each feature branch

cd /path/to/my-project/main

git worktree add ../feature-a feature-a
git worktree add ../feature-b feature-b

This results in the following layout:

/path/to/my-project/
├── main/       ← main branch (original clone)
├── feature-a/  ← feature-a branch (worktree)
└── feature-b/  ← feature-b branch (worktree)

Step 3: Configure the main branch mount in your local project config

If you want the agents to have access to the main branch (e.g., to compare changes), add the mount in ~/.kdn/config/projects.json under the project identifier. This keeps the configuration on your machine only — not all developers of the project may use worktrees, so it does not belong in the repository's .kaiden/workspace.json.

{
  "https://github.com/my-org/my-repo/": {
    "mounts": [
      {"host": "$SOURCES/../main", "target": "$SOURCES/../main"}
    ]
  }
}

$SOURCES expands to the workspace sources directory (e.g., /path/to/my-project/feature-a), so $SOURCES/../main resolves to /path/to/my-project/main on both the host and inside the container.

Step 4: Register a workspace for each worktree

kdn init /path/to/my-project/feature-a --runtime podman --agent claude
kdn init /path/to/my-project/feature-b --runtime podman --agent claude

Step 5: Start and connect to each workspace independently

# Start both workspaces (using names or IDs)
kdn start feature-a
kdn start feature-b

# Connect to each agent in separate terminals
kdn terminal feature-a
kdn terminal feature-b

Each agent runs independently in its own container, operating on its own branch without interfering with the other.

Notes:

  • Each worktree shares the same .git directory, so agents can run git commands that are branch-aware
  • Workspaces for different worktrees of the same repository share the same project identifier (derived from the git remote URL), so the mount defined in projects.json automatically applies to all of them

Managing Workspaces from a UI or Programmatically

This scenario demonstrates how to manage workspaces programmatically using JSON output, which is ideal for UIs, scripts, or automation tools. All commands support the --output json (or -o json) flag for machine-readable output.

Step 1: Check existing workspaces

$ kdn workspace list -o json
{
  "items": []
}

Exit code: 0 (success, but no workspaces registered)

Step 2: Register a new workspace

$ kdn init /path/to/project --runtime podman --agent claude -o json
{
  "id": "2c5f16046476be368fcada501ac6cdc6bbd34ea80eb9ceb635530c0af64681ea"
}

Exit code: 0 (success)

Step 3: Register with verbose output to get full details

$ kdn init /path/to/another-project --runtime podman --agent claude -o json -v
{
  "id": "f6e5d4c3b2a1098765432109876543210987654321098765432109876543210a",
  "name": "another-project",
  "agent": "claude",
  "project": "/absolute/path/to/another-project",
  "state": "stopped",
  "paths": {
    "source": "/absolute/path/to/another-project",
    "configuration": "/absolute/path/to/another-project/.kaiden"
  }
}

Exit code: 0 (success)

Step 3a: Register and start immediately with auto-start flag

$ kdn init /path/to/third-project --runtime podman --agent claude -o json --start
{
  "id": "3c4d5e6f7a8b9098765432109876543210987654321098765432109876543210b"
}

Exit code: 0 (success, workspace is running)

Step 4: List all workspaces

$ kdn workspace list -o json
{
  "items": [
    {
      "id": "2c5f16046476be368fcada501ac6cdc6bbd34ea80eb9ceb635530c0af64681ea",
      "name": "project",
      "agent": "claude",
      "project": "/absolute/path/to/project",
      "state": "running",
      "paths": {
        "source": "/absolute/path/to/project",
        "configuration": "/absolute/path/to/project/.kaiden"
      }
    },
    {
      "id": "f6e5d4c3b2a1098765432109876543210987654321098765432109876543210a",
      "name": "another-project",
      "agent": "claude",
      "project": "/absolute/path/to/another-project",
      "state": "stopped",
      "paths": {
        "source": "/absolute/path/to/another-project",
        "configuration": "/absolute/path/to/another-project/.kaiden"
      }
    }
  ]
}

Exit code: 0 (success)

Step 5: Start a workspace

$ kdn workspace start 2c5f16046476be368fcada501ac6cdc6bbd34ea80eb9ceb635530c0af64681ea -o json
{
  "id": "2c5f16046476be368fcada501ac6cdc6bbd34ea80eb9ceb635530c0af64681ea"
}

Exit code: 0 (success)

Step 6: Stop a workspace

$ kdn workspace stop 2c5f16046476be368fcada501ac6cdc6bbd34ea80eb9ceb635530c0af64681ea -o json
{
  "id": "2c5f16046476be368fcada501ac6cdc6bbd34ea80eb9ceb635530c0af64681ea"
}

Exit code: 0 (success)

Step 7: Remove a workspace

$ kdn workspace remove 2c5f16046476be368fcada501ac6cdc6bbd34ea80eb9ceb635530c0af64681ea -o json
{
  "id": "2c5f16046476be368fcada501ac6cdc6bbd34ea80eb9ceb635530c0af64681ea"
}

Exit code: 0 (success)

Step 8: Verify removal

$ kdn workspace list -o json
{
  "items": [
    {
      "id": "f6e5d4c3b2a1098765432109876543210987654321098765432109876543210a",
      "name": "another-project",
      "agent": "claude",
      "project": "/absolute/path/to/another-project",
      "state": "stopped",
      "paths": {
        "source": "/absolute/path/to/another-project",
        "configuration": "/absolute/path/to/another-project/.kaiden"
      }
    }
  ]
}

Exit code: 0 (success)

Error Handling

All errors are returned in JSON format when using --output json, with the error written to stdout (not stderr) and a non-zero exit code.

Error: Non-existent directory

$ kdn init /tmp/no-exist --runtime podman --agent claude -o json
{
  "error": "sources directory does not exist: /tmp/no-exist"
}

Exit code: 1 (error)

Error: Workspace not found

$ kdn workspace remove unknown-id -o json
{
  "error": "workspace not found: unknown-id"
}

Exit code: 1 (error)

Best Practices for Programmatic Usage

  1. Always check the exit code to determine success (0) or failure (non-zero)
  2. Parse stdout for JSON output in both success and error cases
  3. Use verbose mode with init (-v) when you need full workspace details immediately after creation
  4. Handle both success and error JSON structures in your code:
  5. Success responses have specific fields (e.g., id, items, name, paths)
  6. Error responses always have an error field

Example script pattern:

#!/bin/bash

# Register a workspace
output=$(kdn init /path/to/project --runtime podman --agent claude -o json)
exit_code=$?

if [ $exit_code -eq 0 ]; then
    workspace_id=$(echo "$output" | jq -r '.id')
    echo "Workspace created: $workspace_id"
else
    error_msg=$(echo "$output" | jq -r '.error')
    echo "Error: $error_msg"
    exit 1
fi