{
  "schema": "kb.plugin/3",
  "id": "@kb-labs/workflow",
  "version": "1.0.0",
  "display": {
    "name": "Workflow CLI",
    "description": "CLI commands for interacting with KB Labs Workflow Daemon",
    "tags": [
      "workflow",
      "daemon",
      "jobs",
      "orchestration"
    ]
  },
  "platform": {
    "requires": [],
    "optional": []
  },
  "cli": {
    "groupMeta": [
      {
        "path": "workflow",
        "describe": "Workflow daemon commands"
      },
      {
        "path": "workflow runs",
        "describe": "Workflow run management (list, view, watch, rerun)"
      },
      {
        "path": "workflow job",
        "describe": "Raw job execution"
      }
    ],
    "commands": [
      {
        "path": "workflow health",
        "category": "Daemon",
        "operationType": "read",
        "describe": "Check workflow daemon health status.",
        "longDescription": "Performs a health check on the workflow daemon by making an HTTP request to /health endpoint. Use this to verify the daemon is running and responding.",
        "handler": "./commands/health.js#default",
        "flags": [
          {
            "name": "json",
            "type": "boolean",
            "default": false,
            "description": "Output result as JSON"
          }
        ],
        "examples": [
          "kb workflow health",
          "kb workflow health --json"
        ]
      },
      {
        "path": "workflow metrics",
        "category": "Daemon",
        "operationType": "read",
        "describe": "Get workflow daemon metrics.",
        "longDescription": "Fetches comprehensive metrics from the workflow daemon including total runs, queued jobs, running jobs, completed jobs, and failure counts.",
        "handler": "./commands/metrics.js#default",
        "flags": [
          {
            "name": "json",
            "type": "boolean",
            "default": false,
            "description": "Output result as JSON"
          }
        ],
        "examples": [
          "kb workflow metrics",
          "kb workflow metrics --json"
        ]
      },
      {
        "path": "workflow lint",
        "category": "Daemon",
        "operationType": "read",
        "describe": "Validate workflow files against the schema.",
        "longDescription": "Statically validates workflow files under .kb/workflows (or a given --path) against WorkflowSpecSchema, reporting per-file issues with their JSON-path. Runs locally without the daemon. Exits non-zero if any file is invalid (or, with --strict, has warnings).",
        "handler": "./commands/lint.js#default",
        "flags": [
          {
            "name": "path",
            "type": "string",
            "description": "File or directory to lint (default: .kb/workflows)"
          },
          {
            "name": "json",
            "type": "boolean",
            "default": false,
            "description": "Output result as JSON"
          },
          {
            "name": "strict",
            "type": "boolean",
            "default": false,
            "description": "Treat warnings as errors"
          }
        ],
        "examples": [
          "kb workflow lint",
          "kb workflow lint --path .kb/workflows/03-dev-cycle.yml",
          "kb workflow lint --json",
          "kb workflow lint --strict"
        ]
      },
      {
        "path": "workflow status",
        "category": "Jobs",
        "operationType": "read",
        "describe": "(Deprecated) Get job status. Use: kb workflow runs status <runId>",
        "longDescription": "Retrieves detailed status information for a specific job by ID, including current state, start time, and completion time if finished. DEPRECATED: use \"kb workflow runs status <runId>\" for run-level status.",
        "handler": "./commands/status.js#default",
        "flags": [
          {
            "name": "json",
            "type": "boolean",
            "default": false,
            "description": "Output result as JSON"
          },
          {
            "name": "job-id",
            "type": "string",
            "description": "Job ID to get status for"
          }
        ],
        "examples": [
          "kb workflow status --job-id=abc123",
          "kb workflow status --job-id=abc123 --json"
        ]
      },
      {
        "path": "workflow logs",
        "category": "Jobs",
        "operationType": "read",
        "describe": "(Deprecated) Get job/run logs. Use: kb workflow runs logs <runId>",
        "longDescription": "Fetches execution logs for a specific job or run by ID. DEPRECATED: use \"kb workflow runs logs <runId>\" for run-level logs.",
        "handler": "./commands/logs.js#default",
        "flags": [
          {
            "name": "json",
            "type": "boolean",
            "default": false,
            "description": "Output result as JSON"
          },
          {
            "name": "job-id",
            "type": "string",
            "description": "Job ID to get logs for (required)"
          },
          {
            "name": "follow",
            "type": "boolean",
            "default": false,
            "description": "Follow log output (stream new logs)"
          }
        ],
        "examples": [
          "kb workflow logs --job-id=abc123",
          "kb workflow logs --job-id=abc123 --json",
          "kb workflow logs --job-id=abc123 --follow"
        ]
      },
      {
        "path": "workflow list",
        "category": "Jobs",
        "operationType": "read",
        "describe": "(Deprecated) List active executions. Use: kb workflow runs list",
        "longDescription": "Lists all currently active workflow executions or cron jobs. Can be filtered by status (running, queued, completed, failed, cancelled) or type (runs, cron). DEPRECATED: use \"kb workflow runs list\" for run listing.",
        "handler": "./commands/list.js#default",
        "flags": [
          {
            "name": "json",
            "type": "boolean",
            "default": false,
            "description": "Output result as JSON"
          },
          {
            "name": "status",
            "type": "string",
            "description": "Filter by status (running, completed, failed)"
          },
          {
            "name": "type",
            "type": "string",
            "description": "Filter by type: \"runs\" (active executions), \"cron\" (scheduled jobs)"
          }
        ],
        "examples": [
          "kb workflow list",
          "kb workflow list --status=running",
          "kb workflow list --type=cron",
          "kb workflow list --json"
        ]
      },
      {
        "path": "workflow job run",
        "category": "Jobs",
        "operationType": "execute",
        "describe": "Submit a raw job for execution.",
        "longDescription": "Submits a job to the workflow daemon for execution. Requires a handler (plugin command) and optionally accepts input parameters as JSON. Can wait for job completion with --wait flag.",
        "handler": "./commands/run.js#default",
        "flags": [
          {
            "name": "json",
            "type": "boolean",
            "default": false,
            "description": "Output result as JSON"
          },
          {
            "name": "handler",
            "type": "string",
            "description": "Plugin handler to run (e.g., \"mind:rag-query\")"
          },
          {
            "name": "input",
            "type": "string",
            "description": "JSON string of input parameters"
          },
          {
            "name": "priority",
            "type": "number",
            "description": "Job priority (1-10, default: 5)"
          },
          {
            "name": "wait",
            "type": "boolean",
            "default": false,
            "description": "Wait for job completion"
          }
        ],
        "examples": [
          "kb workflow job run --handler=mind:search --input='{\"text\":\"test\"}'",
          "kb workflow job run --handler=mind:search --input='{\"text\":\"test\"}' --wait",
          "kb workflow job run --handler=mind:search --input='{\"text\":\"test\"}' --priority=8",
          "kb workflow job run --handler=mind:search --input='{\"text\":\"test\"}' --json"
        ]
      },
      {
        "path": "workflow runs list",
        "category": "Runs",
        "operationType": "read",
        "describe": "List workflow runs.",
        "longDescription": "Lists workflow runs with status, trigger, and duration. Filter by status (failed, running, success) or workflow ID. Use --json for machine-readable output.",
        "handler": "./commands/runs-list.js#default",
        "flags": [
          {
            "name": "json",
            "type": "boolean",
            "default": false,
            "description": "Output result as JSON"
          },
          {
            "name": "status",
            "type": "string",
            "description": "Filter by status: failed, running, success, queued, cancelled"
          },
          {
            "name": "limit",
            "type": "number",
            "default": 20,
            "description": "Maximum number of runs to show (default: 20)"
          },
          {
            "name": "workflow",
            "type": "string",
            "description": "Filter by workflow ID or name"
          }
        ],
        "examples": [
          "kb workflow runs list",
          "kb workflow runs list --status=failed",
          "kb workflow runs list --status=failed --limit=5",
          "kb workflow runs list --workflow=my-workflow --json"
        ]
      },
      {
        "path": "workflow runs view",
        "category": "Runs",
        "operationType": "read",
        "describe": "View run details for incident investigation.",
        "longDescription": "Shows full run details: jobs, steps, resolvedInputs, gate decisions, errors. Without a run ID shows the latest run (like gh run view). Use --log-failed to see only the logs from failed steps (fastest path to root cause). Use --json=status,jobs for selective JSON output.",
        "handler": "./commands/runs-view.js#default",
        "flags": [
          {
            "name": "run-id",
            "type": "string",
            "description": "Run ID to inspect (alias for positional argument)"
          },
          {
            "name": "json",
            "type": "string",
            "description": "Output specific fields as JSON. Use --json (no value) or --json=all for full output, or --json=field1,field2 for selective fields."
          },
          {
            "name": "log",
            "type": "boolean",
            "default": false,
            "description": "Show full run logs"
          },
          {
            "name": "log-failed",
            "type": "boolean",
            "default": false,
            "description": "Show logs only from failed steps (most useful for investigation)"
          },
          {
            "name": "step",
            "type": "string",
            "description": "Filter logs to a specific step name"
          }
        ],
        "examples": [
          "kb workflow runs view",
          "kb workflow runs view <runId>",
          "kb workflow runs view --run-id=<runId>",
          "kb workflow runs view <runId> --log-failed",
          "kb workflow runs view <runId> --log",
          "kb workflow runs view <runId> --json=status,jobs",
          "kb workflow runs view <runId> --json=all"
        ]
      },
      {
        "path": "workflow runs watch",
        "category": "Runs",
        "operationType": "execute",
        "describe": "Stream workflow run events in real-time.",
        "longDescription": "Connects to the run event stream via SSE and prints events as they happen. Without a run ID watches the latest run (like gh run watch). Automatically exits when the run finishes.",
        "handler": "./commands/runs-watch.js#default",
        "flags": [
          {
            "name": "run-id",
            "type": "string",
            "description": "Run ID to watch (alias for positional argument)"
          },
          {
            "name": "json",
            "type": "boolean",
            "default": false,
            "description": "Output events as JSON"
          }
        ],
        "examples": [
          "kb workflow runs watch",
          "kb workflow runs watch <runId>",
          "kb workflow runs watch --run-id=<runId>",
          "kb workflow runs watch <runId> --json"
        ]
      },
      {
        "path": "workflow runs rerun",
        "category": "Runs",
        "operationType": "mutate",
        "describe": "Rerun a workflow run.",
        "longDescription": "Reruns a workflow by re-submitting it with the same inputs. Use --failed-only to requeue only jobs that failed or were interrupted.",
        "handler": "./commands/runs-rerun.js#default",
        "flags": [
          {
            "name": "run-id",
            "type": "string",
            "description": "Run ID to rerun (alias for positional argument)"
          },
          {
            "name": "json",
            "type": "boolean",
            "default": false,
            "description": "Output result as JSON"
          },
          {
            "name": "failed-only",
            "type": "boolean",
            "default": false,
            "description": "Rerun only jobs that failed or were interrupted"
          }
        ],
        "examples": [
          "kb workflow runs rerun <runId>",
          "kb workflow runs rerun --run-id=<runId>",
          "kb workflow runs rerun <runId> --failed-only",
          "kb workflow runs rerun <runId> --json"
        ]
      },
      {
        "path": "workflow runs restart",
        "category": "Runs",
        "operationType": "mutate",
        "describe": "Restart a run from a specific step.",
        "longDescription": "Restores the run from a snapshot and re-executes from the given step. All preceding steps inherit their stored outputs without being re-run. Omitting --from-step restarts from step 1 using the snapshot env.",
        "handler": "./commands/runs-restart.js#default",
        "flags": [
          {
            "name": "run-id",
            "type": "string",
            "description": "Run ID to restart (alias for positional argument)"
          },
          {
            "name": "from-step",
            "type": "string",
            "description": "Step ID to restart from; all preceding steps inherit their stored outputs"
          },
          {
            "name": "json",
            "type": "boolean",
            "default": false,
            "description": "Output result as JSON"
          }
        ],
        "examples": [
          "kb workflow runs restart <runId>",
          "kb workflow runs restart <runId> --from-step=<stepId>",
          "kb workflow runs restart <runId> --from-step=<stepId> --json"
        ]
      },
      {
        "path": "workflow runs cancel",
        "category": "Runs",
        "operationType": "mutate",
        "describe": "Cancel a workflow run.",
        "longDescription": "Cancels an active workflow run. If the run is not found or already finished, prints a clear error.",
        "handler": "./commands/runs-cancel.js#default",
        "flags": [
          {
            "name": "run-id",
            "type": "string",
            "description": "Run ID to cancel (alias for positional argument)"
          },
          {
            "name": "json",
            "type": "boolean",
            "default": false,
            "description": "Output result as JSON"
          }
        ],
        "examples": [
          "kb workflow runs cancel <runId>",
          "kb workflow runs cancel --run-id=<runId>",
          "kb workflow runs cancel <runId> --json"
        ]
      },
      {
        "path": "workflow runs logs",
        "category": "Runs",
        "operationType": "read",
        "describe": "Fetch logs for a workflow run.",
        "longDescription": "Fetches execution logs for a run. Use --log-failed to show only failed-step logs. Use --step to filter to a specific step. Accepts a positional run ID or --run-id flag.",
        "handler": "./commands/runs-logs.js#default",
        "flags": [
          {
            "name": "run-id",
            "type": "string",
            "description": "Run ID (alias for positional argument)"
          },
          {
            "name": "json",
            "type": "boolean",
            "default": false,
            "description": "Output result as JSON"
          },
          {
            "name": "step",
            "type": "string",
            "description": "Filter logs to a specific step name"
          },
          {
            "name": "log-failed",
            "type": "boolean",
            "default": false,
            "description": "Show only logs from failed steps"
          }
        ],
        "examples": [
          "kb workflow runs logs <runId>",
          "kb workflow runs logs <runId> --log-failed",
          "kb workflow runs logs <runId> --step=build",
          "kb workflow runs logs <runId> --json"
        ]
      },
      {
        "path": "workflow runs status",
        "category": "Runs",
        "operationType": "read",
        "describe": "Show status summary for a workflow run.",
        "longDescription": "Displays the status of a run including jobs and steps. Accepts a positional run ID or --run-id flag.",
        "handler": "./commands/runs-status.js#default",
        "flags": [
          {
            "name": "run-id",
            "type": "string",
            "description": "Run ID (alias for positional argument)"
          },
          {
            "name": "json",
            "type": "boolean",
            "default": false,
            "description": "Output result as JSON"
          }
        ],
        "examples": [
          "kb workflow runs status <runId>",
          "kb workflow runs status --run-id=<runId>",
          "kb workflow runs status <runId> --json"
        ]
      },
      {
        "path": "workflow runs approve",
        "category": "Runs",
        "operationType": "mutate",
        "describe": "Approve or reject a pending approval step in a workflow run.",
        "longDescription": "Resolves a human-gate (approval) step that is waiting for a decision. If the run has exactly one pending approval, it is resolved automatically. If there are multiple, specify --job-id and --step-id to target the right one. Use --action=reject to reject instead of approve (default: approve). Use --comment to attach a note to the decision.",
        "handler": "./commands/runs-approve.js#default",
        "flags": [
          {
            "name": "run-id",
            "type": "string",
            "description": "Run ID to approve/reject (alias for positional argument)"
          },
          {
            "name": "job-id",
            "type": "string",
            "description": "Job ID containing the approval step"
          },
          {
            "name": "step-id",
            "type": "string",
            "description": "Step ID to approve or reject"
          },
          {
            "name": "action",
            "type": "string",
            "default": "approve",
            "description": "Action to take: \"approve\" or \"reject\" (default: approve)"
          },
          {
            "name": "comment",
            "type": "string",
            "description": "Optional comment to attach to the approval decision"
          },
          {
            "name": "json",
            "type": "boolean",
            "default": false,
            "description": "Output result as JSON"
          }
        ],
        "examples": [
          "kb workflow runs approve <runId>",
          "kb workflow runs approve <runId> --action=reject --comment=\"Needs rework\"",
          "kb workflow runs approve <runId> --job-id=<jobId> --step-id=<stepId>",
          "kb workflow runs approve <runId> --json"
        ]
      },
      {
        "path": "workflow run",
        "category": "Runs",
        "operationType": "execute",
        "describe": "Run workflow by ID.",
        "longDescription": "Runs a workflow definition by workflow ID via /api/v1/workflows/:id/run endpoint. Supports request-level target and isolation overrides.",
        "handler": "./commands/workflow-run.js#default",
        "flags": [
          {
            "name": "json",
            "type": "boolean",
            "default": false,
            "description": "Output result as JSON"
          },
          {
            "name": "workflow-id",
            "type": "string",
            "description": "Workflow ID to run (e.g., \"release-manager/create-release\")"
          },
          {
            "name": "input",
            "type": "string",
            "description": "JSON string of workflow input payload"
          },
          {
            "name": "inputs",
            "type": "string",
            "description": "Deprecated alias for --input. Use --input instead."
          },
          {
            "name": "isolation",
            "type": "string",
            "description": "Isolation profile: strict, balanced, or relaxed"
          },
          {
            "name": "target-namespace",
            "type": "string",
            "description": "Execution target namespace"
          },
          {
            "name": "target-environment-id",
            "type": "string",
            "description": "Execution target environment ID"
          },
          {
            "name": "target-workspace-id",
            "type": "string",
            "description": "Execution target workspace ID"
          },
          {
            "name": "target-workdir",
            "type": "string",
            "description": "Execution target workdir override"
          },
          {
            "name": "trigger-type",
            "type": "string",
            "description": "Trigger type: manual, api, or cron"
          },
          {
            "name": "trigger-user",
            "type": "string",
            "description": "Trigger user"
          }
        ],
        "examples": [
          "kb workflow run --workflow-id=release-manager/create-release",
          "kb workflow run --workflow-id=release-manager/create-release --isolation=strict --target-namespace=team-a/prod",
          "kb workflow run --workflow-id=release-manager/create-release --target-environment-id=env-123 --json"
        ]
      }
    ]
  },
  "rest": {
    "basePath": "/plugins/workflow",
    "routes": [
      {
        "method": "GET",
        "path": "/stats",
        "handler": "./rest/stats-handler.js#default",
        "describe": "Get dashboard statistics",
        "output": {
          "zod": "@kb-labs/workflow-contracts#DashboardStatsResponseSchema"
        }
      },
      {
        "method": "GET",
        "path": "/workflows",
        "handler": "./rest/workflows-list-handler.js#default",
        "describe": "List all workflow definitions",
        "output": {
          "zod": "@kb-labs/workflow-contracts#WorkflowListResponseSchema"
        }
      },
      {
        "method": "GET",
        "path": "/workflows/:id",
        "handler": "./rest/workflow-detail-handler.js#default",
        "describe": "Get workflow definition details",
        "output": {
          "zod": "@kb-labs/workflow-contracts#WorkflowInfoSchema"
        }
      },
      {
        "method": "POST",
        "path": "/workflows/:id/run",
        "handler": "./rest/workflow-run-handler.js#default",
        "describe": "Run a workflow",
        "input": {
          "zod": "@kb-labs/workflow-contracts#WorkflowRunRequestSchema"
        }
      },
      {
        "method": "GET",
        "path": "/workflows/:id/runs",
        "handler": "./rest/workflow-runs-handler.js#default",
        "describe": "Get workflow run history with pagination",
        "output": {
          "zod": "@kb-labs/workflow-contracts#WorkflowRunHistoryResponseSchema"
        }
      },
      {
        "method": "POST",
        "path": "/workflows/runs/:runId/cancel",
        "handler": "./rest/workflow-run-cancel-handler.js#default",
        "describe": "Cancel a running or queued workflow run"
      },
      {
        "method": "GET",
        "path": "/runs",
        "handler": "./rest/runs-list-handler.js#default",
        "describe": "List all workflow runs across all workflows"
      },
      {
        "method": "GET",
        "path": "/runs/:runId",
        "handler": "./rest/run-detail-handler.js#default",
        "describe": "Get detailed information about a specific workflow run"
      },
      {
        "method": "GET",
        "path": "/jobs",
        "handler": "./rest/jobs-list-handler.js#default",
        "describe": "List workflow jobs with optional filters",
        "output": {
          "zod": "@kb-labs/workflow-contracts#JobListResponseSchema"
        }
      },
      {
        "method": "GET",
        "path": "/jobs/:jobId",
        "handler": "./rest/job-detail-handler.js#default",
        "describe": "Get detailed information about a specific job",
        "output": {
          "zod": "@kb-labs/workflow-contracts#JobStatusInfoSchema"
        }
      },
      {
        "method": "GET",
        "path": "/jobs/:jobId/logs",
        "handler": "./rest/job-logs-handler.js#default",
        "describe": "Get execution logs for a specific job",
        "output": {
          "zod": "@kb-labs/workflow-contracts#JobLogsResponseSchema"
        }
      },
      {
        "method": "GET",
        "path": "/jobs/:jobId/steps",
        "handler": "./rest/job-steps-handler.js#default",
        "describe": "Get execution steps and progress for a specific job",
        "output": {
          "zod": "@kb-labs/workflow-contracts#JobStepsResponseSchema"
        }
      },
      {
        "method": "POST",
        "path": "/jobs/:jobId/cancel",
        "handler": "./rest/job-cancel-handler.js#default",
        "describe": "Cancel a running or pending job",
        "output": {
          "zod": "@kb-labs/workflow-contracts#JobCancelResponseSchema"
        }
      },
      {
        "method": "GET",
        "path": "/cron",
        "handler": "./rest/cron-list-handler.js#default",
        "describe": "List all registered cron jobs",
        "output": {
          "zod": "@kb-labs/workflow-contracts#CronListResponseSchema"
        }
      },
      {
        "method": "GET",
        "path": "/runs/:runId/pending-approvals",
        "handler": "./rest/pending-approvals-handler.js#default",
        "describe": "List steps waiting for approval in a workflow run"
      },
      {
        "method": "POST",
        "path": "/runs/:runId/approve",
        "handler": "./rest/resolve-approval-handler.js#default",
        "describe": "Approve or reject a pending approval step"
      }
    ]
  },
  "ws": {
    "basePath": "/v1/ws/plugins/workflow",
    "defaults": {
      "timeoutMs": 600000,
      "maxMessageSize": 1048576,
      "auth": "none",
      "idleTimeoutMs": 300000
    },
    "channels": [
      {
        "path": "/logs/:jobId",
        "handler": "./ws/logs-channel.js#default",
        "description": "Real-time job logs streaming"
      },
      {
        "path": "/progress/:jobId",
        "handler": "./ws/progress-channel.js#default",
        "description": "Real-time job progress updates"
      }
    ]
  },
  "studio": {
    "version": 2,
    "remoteName": "workflowPlugin",
    "pages": [
      {
        "id": "workflow.dashboard",
        "title": "Dashboard",
        "icon": "DashboardOutlined",
        "route": "/p/workflows",
        "entry": "./Dashboard",
        "order": 1
      },
      {
        "id": "workflow.runs",
        "title": "Runs",
        "icon": "PlayCircleOutlined",
        "route": "/p/workflows/runs",
        "entry": "./Runs",
        "order": 2
      },
      {
        "id": "workflow.run",
        "title": "Run Detail",
        "icon": "PlayCircleOutlined",
        "route": "/p/workflows/runs/:runId",
        "entry": "./RunDetail",
        "order": 3
      },
      {
        "id": "workflow.defs",
        "title": "Definitions",
        "icon": "AppstoreOutlined",
        "route": "/p/workflows/definitions",
        "entry": "./Definitions",
        "order": 4
      },
      {
        "id": "workflow.def",
        "title": "Definition Detail",
        "icon": "AppstoreOutlined",
        "route": "/p/workflows/definitions/:workflowId",
        "entry": "./DefinitionDetail",
        "order": 5
      },
      {
        "id": "workflow.jobs",
        "title": "Jobs",
        "icon": "UnorderedListOutlined",
        "route": "/p/workflows/jobs",
        "entry": "./Jobs",
        "order": 6
      },
      {
        "id": "workflow.crons",
        "title": "Crons",
        "icon": "ClockCircleOutlined",
        "route": "/p/workflows/crons",
        "entry": "./Crons",
        "order": 7
      }
    ],
    "menus": [
      {
        "id": "workflows",
        "label": "Workflows",
        "icon": "ThunderboltOutlined",
        "target": "workflow.dashboard",
        "order": 10
      },
      {
        "id": "workflows.runs",
        "label": "Runs",
        "icon": "PlayCircleOutlined",
        "target": "workflow.runs",
        "parentId": "workflows",
        "order": 1
      },
      {
        "id": "workflows.defs",
        "label": "Definitions",
        "icon": "AppstoreOutlined",
        "target": "workflow.defs",
        "parentId": "workflows",
        "order": 2
      },
      {
        "id": "workflows.jobs",
        "label": "Jobs",
        "icon": "UnorderedListOutlined",
        "target": "workflow.jobs",
        "parentId": "workflows",
        "order": 3
      },
      {
        "id": "workflows.crons",
        "label": "Crons",
        "icon": "ClockCircleOutlined",
        "target": "workflow.crons",
        "parentId": "workflows",
        "order": 4
      }
    ]
  },
  "permissions": {
    "env": {
      "read": [
        "WORKFLOW_DAEMON_URL"
      ]
    },
    "network": {
      "fetch": [
        "http://localhost:*",
        "http://127.0.0.1:*"
      ]
    },
    "quotas": {
      "timeoutMs": 30000,
      "memoryMb": 128
    }
  }
}
