lua-cli 3.39.3 → 3.40.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -626,11 +626,12 @@ __export(constants_exports, {
626
626
  PREFERRED_AGENT_TYPES: () => PREFERRED_AGENT_TYPES,
627
627
  SANDBOX_STORAGE_FILE: () => SANDBOX_STORAGE_FILE,
628
628
  TELEMETRY_FILE: () => TELEMETRY_FILE,
629
- VERSION_CHECK_FILE: () => VERSION_CHECK_FILE
629
+ VERSION_CHECK_FILE: () => VERSION_CHECK_FILE,
630
+ WEBHOOK_TRIGGER_BASE_URL: () => WEBHOOK_TRIGGER_BASE_URL
630
631
  });
631
632
  import { join } from "path";
632
633
  import { homedir } from "os";
633
- var CLI_CONFIG_DIR, VERSION_CHECK_FILE, TELEMETRY_FILE, CLI_CACHE_FILE, BASE_URLS, CREDENTIALS_FILE, FIREBASE_WEB_API_KEY, PREFERRED_AGENT_TYPES, SANDBOX_STORAGE_FILE, AUTH_STORAGE_FILE, POSTHOG_API_KEY, POSTHOG_HOST;
634
+ var CLI_CONFIG_DIR, VERSION_CHECK_FILE, TELEMETRY_FILE, CLI_CACHE_FILE, BASE_URLS, WEBHOOK_TRIGGER_BASE_URL, CREDENTIALS_FILE, FIREBASE_WEB_API_KEY, PREFERRED_AGENT_TYPES, SANDBOX_STORAGE_FILE, AUTH_STORAGE_FILE, POSTHOG_API_KEY, POSTHOG_HOST;
634
635
  var init_constants = __esm({
635
636
  "src/config/constants.ts"() {
636
637
  "use strict";
@@ -644,6 +645,7 @@ var init_constants = __esm({
644
645
  CHAT: process.env.LUA_API_URL || "https://api.heylua.ai",
645
646
  CDN: "https://cdn.heylua.ai"
646
647
  };
648
+ WEBHOOK_TRIGGER_BASE_URL = "https://webhook.heylua.ai";
647
649
  CREDENTIALS_FILE = join(CLI_CONFIG_DIR, "credentials");
648
650
  FIREBASE_WEB_API_KEY = process.env.LUA_FIREBASE_WEB_API_KEY || "AIzaSyAGI0AxOz6UmtJgwFIA_UNTuYUEgQRRGhw";
649
651
  PREFERRED_AGENT_TYPES = [
@@ -909,6 +911,15 @@ function aiGenerateInputFromSimplified(prompt, content) {
909
911
  ]
910
912
  };
911
913
  }
914
+ function isPlatformInvocationCaller(v) {
915
+ return typeof v === "string" && PLATFORM_INVOCATION_CALLERS.includes(v);
916
+ }
917
+ function supervisionSubjectId(agentId) {
918
+ return `agent:${agentId}`;
919
+ }
920
+ function isSupervisionOp(op) {
921
+ return typeof op === "string" && Object.prototype.hasOwnProperty.call(SUPERVISION_OPS, op);
922
+ }
912
923
  function isAllowedReviewableExecuteTool(tool) {
913
924
  return REVIEWABLE_ACTION_EXECUTE_TOOL_ALLOWLIST.includes(tool);
914
925
  }
@@ -957,6 +968,9 @@ function isInteractiveTurn(turn) {
957
968
  function removeNavigateBlock(input) {
958
969
  return input.replace(/::: navigate[\s\S]*?:::/g, "").trim();
959
970
  }
971
+ function removeHiddenBlocks(input) {
972
+ return input.replace(/::: hide\b[\s\S]*?:::/gi, "").replace(/::: hide\b[\s\S]*$/gi, "").trim();
973
+ }
960
974
  function transformChatHistoryContentParts(parts) {
961
975
  const content = [];
962
976
  for (const rawPart of parts ?? []) {
@@ -2502,6 +2516,180 @@ function scheduledTimeKey(scheduledTime) {
2502
2516
  function scheduledWorkflowRunIdForTime(jobId, scheduledTime) {
2503
2517
  return scheduledWorkflowRunId(jobId, scheduledTime);
2504
2518
  }
2519
+ function isInt(v) {
2520
+ return typeof v === "number" && Number.isInteger(v);
2521
+ }
2522
+ function validateScheduleHealth(health, opts) {
2523
+ const base = opts.path ?? "health";
2524
+ const issues = [];
2525
+ if (health === null || typeof health !== "object" || Array.isArray(health)) {
2526
+ return [
2527
+ {
2528
+ code: "health-not-object",
2529
+ path: base,
2530
+ message: `${base} must be an object`
2531
+ }
2532
+ ];
2533
+ }
2534
+ const h = health;
2535
+ for (const key of Object.keys(h)) {
2536
+ if (!KNOWN_KEYS.has(key)) {
2537
+ issues.push({
2538
+ code: "health-unknown-field",
2539
+ path: `${base}.${key}`,
2540
+ message: `${base}.${key} is not a health field (maxSilenceMinutes, alertAfterConsecutiveFailures, notify)`
2541
+ });
2542
+ }
2543
+ }
2544
+ const silence = h.maxSilenceMinutes;
2545
+ const failures = h.alertAfterConsecutiveFailures;
2546
+ if (silence === void 0 && failures === void 0) {
2547
+ issues.push({
2548
+ code: "health-empty",
2549
+ path: base,
2550
+ message: `${base} needs maxSilenceMinutes and/or alertAfterConsecutiveFailures`
2551
+ });
2552
+ }
2553
+ const { min: sMin, max: sMax } = SCHEDULE_HEALTH_LIMITS.maxSilenceMinutes;
2554
+ if (silence !== void 0 && (!isInt(silence) || silence < sMin || silence > sMax)) {
2555
+ issues.push({
2556
+ code: "health-silence-invalid",
2557
+ path: `${base}.maxSilenceMinutes`,
2558
+ message: `${base}.maxSilenceMinutes must be an integer in ${sMin}..${sMax}`
2559
+ });
2560
+ }
2561
+ const fMin = SCHEDULE_HEALTH_LIMITS.alertAfterConsecutiveFailures.min;
2562
+ const fMax = opts.target === "workflow" ? SCHEDULE_HEALTH_LIMITS.parkedKindsMaxFailures : SCHEDULE_HEALTH_LIMITS.alertAfterConsecutiveFailures.max;
2563
+ if (failures !== void 0) {
2564
+ if (!isInt(failures) || failures < fMin) {
2565
+ issues.push({
2566
+ code: "health-failures-invalid",
2567
+ path: `${base}.alertAfterConsecutiveFailures`,
2568
+ message: `${base}.alertAfterConsecutiveFailures must be an integer in ${fMin}..${fMax}`
2569
+ });
2570
+ } else if (failures > fMax) {
2571
+ issues.push({
2572
+ code: opts.target === "workflow" ? "health-failures-unreachable" : "health-failures-invalid",
2573
+ path: `${base}.alertAfterConsecutiveFailures`,
2574
+ message: opts.target === "workflow" ? `${base}.alertAfterConsecutiveFailures must be \u2264 ${fMax}: a workflow schedule is turned off after ${fMax} consecutive failures, so a longer streak can never happen (the turn-off itself always alerts)` : `${base}.alertAfterConsecutiveFailures must be an integer in ${fMin}..${fMax}`
2575
+ });
2576
+ }
2577
+ }
2578
+ if (h.notify !== void 0 && !SCHEDULE_HEALTH_NOTIFY_CHANNELS.includes(h.notify)) {
2579
+ issues.push({
2580
+ code: "health-notify-invalid",
2581
+ path: `${base}.notify`,
2582
+ message: `${base}.notify must be one of ${SCHEDULE_HEALTH_NOTIFY_CHANNELS.join(", ")}`
2583
+ });
2584
+ }
2585
+ const triggers = (opts.triggers ?? []).filter((t) => !!t && typeof t === "object");
2586
+ if (opts.triggers !== void 0 && triggers.length === 0) {
2587
+ issues.push({
2588
+ code: "health-requires-schedule",
2589
+ path: base,
2590
+ message: `${base} needs a schedule to watch`
2591
+ });
2592
+ }
2593
+ if (isInt(silence) && triggers.length > 0) {
2594
+ if (triggers.every((t) => t.type === "once")) {
2595
+ issues.push({
2596
+ code: "health-silence-on-once",
2597
+ path: `${base}.maxSilenceMinutes`,
2598
+ message: `${base}.maxSilenceMinutes needs a recurring schedule; a one-time schedule has no cadence to fall silent against`
2599
+ });
2600
+ } else {
2601
+ const intervals = triggers.filter((t) => t.type === "interval" && isInt(t.seconds)).map((t) => t.seconds);
2602
+ const onlyIntervals = intervals.length === triggers.filter((t) => t.type !== "once").length;
2603
+ if (onlyIntervals && intervals.length > 0) {
2604
+ const fastest = Math.min(...intervals);
2605
+ if (silence * 60 <= fastest) {
2606
+ issues.push({
2607
+ code: "health-silence-shorter-than-interval",
2608
+ path: `${base}.maxSilenceMinutes`,
2609
+ message: `${base}.maxSilenceMinutes (${silence} min) must be longer than the schedule's interval (${fastest}s), or every healthy gap alerts`
2610
+ });
2611
+ }
2612
+ }
2613
+ }
2614
+ }
2615
+ return issues;
2616
+ }
2617
+ function normalizeScheduleHealth(health) {
2618
+ return {
2619
+ ...health.maxSilenceMinutes !== void 0 ? {
2620
+ maxSilenceMinutes: health.maxSilenceMinutes
2621
+ } : {},
2622
+ ...health.alertAfterConsecutiveFailures !== void 0 ? {
2623
+ alertAfterConsecutiveFailures: health.alertAfterConsecutiveFailures
2624
+ } : {},
2625
+ notify: health.notify ?? SCHEDULE_HEALTH_DEFAULT_NOTIFY
2626
+ };
2627
+ }
2628
+ function evaluateScheduleHealth(subject, now) {
2629
+ const parked = subject.status === "failed";
2630
+ if (parked) return {
2631
+ watched: true,
2632
+ condition: "auto_disabled"
2633
+ };
2634
+ if (subject.active === false || subject.status !== "active") return {
2635
+ watched: false,
2636
+ condition: null
2637
+ };
2638
+ const threshold = subject.health.alertAfterConsecutiveFailures;
2639
+ if (threshold !== void 0 && subject.consecutiveFailures >= threshold) {
2640
+ return {
2641
+ watched: true,
2642
+ condition: "failures"
2643
+ };
2644
+ }
2645
+ const window = subject.health.maxSilenceMinutes;
2646
+ if (window !== void 0) {
2647
+ const baseline = Math.max(subject.lastSucceededAt ?? 0, subject.state?.watchFrom ?? now);
2648
+ const silentMs = now - baseline;
2649
+ if (silentMs > window * 6e4) {
2650
+ return {
2651
+ watched: true,
2652
+ condition: "silence",
2653
+ silentForMinutes: Math.floor(silentMs / 6e4)
2654
+ };
2655
+ }
2656
+ }
2657
+ return {
2658
+ watched: true,
2659
+ condition: null
2660
+ };
2661
+ }
2662
+ function scheduleHealthView(health, state3) {
2663
+ if (!health) return void 0;
2664
+ const incident = state3?.incident;
2665
+ return {
2666
+ config: {
2667
+ ...health.maxSilenceMinutes !== void 0 ? {
2668
+ maxSilenceMinutes: health.maxSilenceMinutes
2669
+ } : {},
2670
+ ...health.alertAfterConsecutiveFailures !== void 0 ? {
2671
+ alertAfterConsecutiveFailures: health.alertAfterConsecutiveFailures
2672
+ } : {},
2673
+ ...health.notify ? {
2674
+ notify: health.notify
2675
+ } : {}
2676
+ },
2677
+ state: incident ? "alerting" : state3?.watchFrom !== void 0 ? "ok" : "unwatched",
2678
+ ...incident ? {
2679
+ condition: incident.condition,
2680
+ since: incident.openedAt
2681
+ } : {},
2682
+ ...state3?.lastSucceededAt !== void 0 ? {
2683
+ lastSucceededAt: state3.lastSucceededAt
2684
+ } : {},
2685
+ ...state3?.checkedAt !== void 0 ? {
2686
+ checkedAt: state3.checkedAt
2687
+ } : {}
2688
+ };
2689
+ }
2690
+ function scheduleHealthSourceId(agentId, jobId) {
2691
+ return `schedule-health:${agentId}:${jobId}`;
2692
+ }
2505
2693
  function workflowGoalJudgeKind(judge) {
2506
2694
  return judge && typeof judge === "object" && judge.predicate !== void 0 ? "predicate" : "agent";
2507
2695
  }
@@ -2812,7 +3000,344 @@ function parseOnboardingFlow(value3) {
2812
3000
  function parsePublishedOnboardingResponse(value3) {
2813
3001
  return getPublishedOnboardingResponseSchema.parse(value3);
2814
3002
  }
2815
- var __defProp2, __name2, PLUMBING_THREAD_CHANNELS, CHANNEL_CONVERSATION_CHANNELS, HIDDEN_THREAD_CHANNELS, REVIEWABLE_ACTION_EXECUTE_TOOL_ALLOWLIST, REVIEWABLE_STANDING_START_TOOLS, REVIEWABLE_MCP_SEND_TOOL_SUFFIX, MCP_TOOL_READ_VERB_RE, MCP_DRAFT_CREATE_VERBS, NON_INTERACTIVE_CHANNELS, RICH_PARTS_MESSAGE_ID_PREFIX, SCREENSHOT_MESSAGE_ID_PREFIX, BROWSER_COMMANDS, BROWSER_COMMAND_NAMES, LOG_FIELDS_MAX_KEYS, LOG_FIELD_MAX_VALUE_BYTES, LOG_FIELDS_MAX_BYTES, LOG_FIELD_KEY_PATTERN, LOG_FIELD_SECRET_SHAPED_KEY_PATTERNS, LOG_FIELDS_CLAMPED_KEY, LOG_FIELD_ARRAY_COUNT_SUFFIX, LuaLogFieldsError, DESKTOP_FILE_COMMANDS, DESKTOP_FILE_COMMAND_SET, WORKFLOW_RETRY_BACKOFFS, WORKFLOW_RETRY_MIN_ATTEMPTS, WORKFLOW_RETRY_POLICY_KEYS, WORKFLOW_RETRY_MAX_ATTEMPTS, WORKFLOW_RETRY_ENGINE_KEYS, WORKFLOW_JOB_RESOURCES, WORKFLOW_SIDE_EFFECTS, WORKFLOW_AGENT_EFFORTS, WORKFLOW_MODEL_CLASSES, WORKFLOW_TASK_CLASSES, WORKFLOW_MODEL_TRAITS, WORKFLOW_MODEL_REASON_MAX_LENGTH, WORKFLOW_MODELS_COMPOSE_MODES, WORKFLOW_MODELS_PIN_MODES, WORKFLOW_MODELS_FALLBACK_MODES, WORKFLOW_MODELS_CONSENT_ACTIONS_MIN, WORKFLOW_DEFAULT_TASK_CLASS_MAP, WORKFLOW_MODELS_MAX_CLASS_DEFAULT, WORKFLOW_AUTONOMY_FORMS, WORKFLOW_AUTONOMY_NUMERIC_KEYS, WORKFLOW_AUTONOMY_ENVELOPE_KEYS, WORKFLOW_AUTONOMY_ENABLED_DEFAULT, WORKFLOW_AUTONOMY_DEFAULTS, WORKFLOW_AUTONOMY_CEILINGS, WORKFLOW_AUTONOMY_MAX_RUNS_PER_HOUR_ENV, WORKFLOW_AUTONOMY_MAX_RUNS_PER_HOUR_CEILING, WORKFLOW_AUTONOMY_FORMS_DEFAULT, WORKFLOW_AUTONOMY_MIN_VALUE, WORKFLOW_JOB_RANGES, WORKFLOW_JOB_RANGE_MEMBERS, WORKFLOW_SINGLE_STEP_TYPES, WORKFLOW_HITL_ENTRY_TYPES, WORKFLOW_ARM_ENTRY_TYPES, WORKFLOW_HITL_ARM_CONTAINERS, WORKFLOW_GRAPH_ENTRY_STEP_KINDS, WORKFLOW_ARM_ENTRY_STEP_KINDS, WORKFLOW_BUDGET_MAX_DURATION_SECONDS, MODEL_ID_BYOK_PROVIDERS, MODEL_CLASS_REF_PREFIX, MODEL_SNAPSHOT_SUFFIX, REASONING_EFFORT_VALUES, IMPLICIT_MODEL_SELECTION_SOURCES, PLATFORM_FALLBACK_MODEL_SOURCE, AGENT_NAME_TOKEN, DEFAULT_PERSONA_GUIDE, PERSONAL_SPACE_STARTING_PERSONA, AGENT_LOG_SOURCES, AGENT_LOG_ENVIRONMENTS, AGENT_LOG_FIELDS_MAX_WIRE_KEYS, LOG_DRAIN_TYPES_PHASE1, LOG_DRAIN_TYPES_PHASE2, LOG_DRAIN_TYPES_IMPLEMENTED, LOG_DRAIN_FORMATS, LOG_DRAIN_SEVERITIES, LOG_DRAIN_SOURCES, LOG_DRAIN_CONTENT_SOURCES, LOG_DRAIN_DEFAULT_SOURCES, LOG_DRAIN_MAX_PER_ORG, LOG_DRAIN_MAX_PER_ORG_ENTERPRISE, LOG_DRAIN_DATADOG_SITES, LOG_DRAIN_NEWRELIC_SITES, LOG_DRAIN_ENDPOINT_TEMPLATES, LOG_DRAIN_PRESET_SITES, LOG_DRAIN_BUCKET_NAME_PATTERN, LOG_DRAIN_BUCKET_HOST_PATTERNS, LOG_DRAIN_PRESET_HOST_SUFFIXES, DRAIN_CONTENT_ACK_ERROR_CODE, DRAIN_CONTENT_ACK_FIELD, DrainContentAckRequiredError, LOG_DRAIN_PRESET_PATHS, PRESET_SEGMENT_RE, LOG_DRAIN_QUOTAS, LOG_DRAIN_QUOTA_WARN_RATIO, LOG_DRAIN_QUOTA_DROP_DEBUG_RATIO, LOG_DRAIN_QUOTA_DROP_INFO_RATIO, LOG_DRAIN_QUOTA_PAUSE_RATIO, LOG_EXPORT_SOURCES, LOG_EXPORT_MAX_WINDOW_DAYS, LOG_EXPORT_MAX_WINDOW_MS, LOG_EXPORT_URL_TTL_SECONDS, LOG_EXPORT_FILE_RETENTION_DAYS, LOG_EXPORT_FILE_RETENTION_MS, LOG_EXPORT_PART_MAX_BYTES, LOG_DRAIN_NOTICE_RATE_LIMIT_MS, LOG_DRAIN_VERIFICATION_STALE_MS, LOG_DRAIN_DIGEST_INTERVAL_MS, LOG_DRAIN_DIGEST_MAX_ENTRIES, LOG_DRAIN_NOTICE_ERROR_MAX_CHARS, LOG_DRAIN_USAGE_LINE_ITEM, LOG_DRAIN_BYTES_PER_GIB, DEFAULT_LOG_DRAIN_PLAN_CONFIG, TIERS, LOG_CURSOR_MAX_LENGTH, LOG_CURSOR_MAX_ID_LENGTH, LOG_RELATIVE_TIME_PATTERN, LOG_ISO_TIME_PATTERN, RELATIVE_UNIT_MS, CORE_DRAINING_CODE, CORE_DRAINING_DEFAULT_RETRY_MS, CORE_DRAINING_MAX_RETRY_MS, VoiceNameSchema, PluginProviderSchema, RealtimeProviderSchema, PluginClassSchema, ModelDescriptorSchema, InferenceModelSchema, PluginModelSchema, RealtimeModelSchema, LuaVoiceModelSchema, TurnDetectionSchema, InterruptionSchema, BuiltinAudioClipSchema, AudioConfigSchema, BackgroundAudioEntrySchema, BackgroundAudioSchema, LuaVoiceConfigInnerSchema, LuaVoiceConfigSchema, LuaVoiceRefSchema, EventType, LUA_JOB_DEFAULT_TIMEOUT_SECONDS, LUA_JOB_MIN_TIMEOUT_SECONDS, LUA_JOB_MAX_TIMEOUT_SECONDS, KEYS, MAX_BODY_BYTES, MAX_ID_LENGTH, UTC_ISO, TEMPLATE_TRIGGER_URL_ENV_PREFIX, TEMPLATE_INSTALL_POLICY_PER_WORKSPACE_VALUES, SUBJECT_TYPES, SubjectTypeSchema, CREDENTIAL_TYPES, CredentialTypeSchema, DEVICE_OPERATIONS, DeviceOperationSchema, DEVICE_SCOPE_BY_OPERATION, DeviceBindingSchema, TYPED_API_KEY, IdSchema, SESSION_AUTH_TIME_MAX_S, PrincipalDescriptorSchema, ActorDescriptorSchema, PrincipalOwnerSchema, CredentialLifecycleSchema, GeneralCredentialDescriptorSchema, DeviceCredentialDescriptorSchema, GeneralPrincipalContextSchema, DeviceCredentialPrincipalContextSchema, RawPrincipalContextSchema, PrincipalContextSchema, DeviceCredentialClaimSchema, LUA_CLIENT_HEADER, LUA_CLIENT_APPS, SEMVER_PATTERN, WEB_RELEASE_PATTERN, CLIENT_HEADER_PATTERN, LUA_SESSION_ID_CLAIM, SESSION_REVOKED_CODE, AUTHZ_PROJECTION_VERSION, ProjectedScopeSchema, DisplayRoleSchema, AuthorizationPrincipalSchema, CredentialContextSchema, ProjectionAnomalySchema, ProjectedOrgSchema, ProjectedResourceSchema, CapabilityProfilesSchema, RoleCatalogSchema, EffectiveAuthorizationSchema, ResourcePageSchema, SYSTEM_USER_PREFIX, WORKFLOW_RUN_IN_FLIGHT, WORKFLOW_RUN_IDLE, WORKFLOW_RUN_TERMINAL, WORKFLOW_RUN_STATUSES, WORKFLOW_RUN_GATE_KINDS, WORKFLOW_STEP_STATUSES, WORKFLOW_STEP_IN_FLIGHT, WORKFLOW_SIGNAL_EVENT_SITES, ARCHIVE_WINDOW_MARGIN_DAYS, WORKFLOW_ORG_PURGING_TTL_S, WORKFLOW_ORG_PURGE_FORCE_AFTER_MS, IDEMPOTENCY_HOLDING_STATUSES, WORKFLOW_SCHEDULED_RUN_ID_PREFIX, CLOUD_TASK_RUN_ID_PREFIX, WORKFLOW_SCHEDULE_KEY_MAX, WORKFLOW_SCHEDULE_IDEMPOTENCY_KEY_PREFIX, WORKFLOW_OPERATION_ID_PREFIX, WORKFLOW_JOURNAL_PROTOCOL_VERSION, WORKFLOW_CONNECTION_KEY_RE, WORKFLOW_JOB_MODEL_SOURCE_LABELS, WORKFLOW_SUSPEND_KINDS, WORKFLOW_RUN_NOTIFICATION_SUSPENDED_KINDS, WORKFLOW_SIGNAL_PAYLOAD_MAX_BYTES, WORKFLOW_RESOLVE_OUTPUT_MAX_BYTES, WORKFLOW_GOAL_JUDGE_SELF, REDACTED_PLACEHOLDER, PROVIDER_MESSAGE_MAX_CHARS, ERROR_MESSAGE_MAX_CHARS, SECRET_LITERAL_PATTERNS, SECRET_NAME, SECRET_PAIR_PATTERNS, GROUP_COUNT, WORKFLOW_SECRET_KEY_RE, WORKFLOW_RESERVED_SECRET_KEYS, SCRUB_INPUT_MAX_CHARS, SCRUB_CUT_BACKOFF_CHARS, WORKFLOW_AUDIT_EVENTS, WORKFLOW_AUDIT_METADATA_MAX_BYTES, INDENT, WRAP_WIDTH, NOUNS, GET_TOOL_NAMES, PREAMBLE, WORKFLOW_APPROVAL_OUTPUT_DECISIONS, WORKFLOW_APPROVAL_OUTPUT_SCHEMA, JSON_FENCE_RE, DEFAULT_ON_AGENT_FEATURES, SUBAGENT_PER_KEY_FLAG_ENV, PER_KEY_FLAG_VALUES, ONBOARDING_FLOW_KEY, ONBOARDING_SCHEMA_VERSION, id, copy, onboardingHeadingSchema, onboardingRichTextInlineSchema, onboardingRichTextSchema, onboardingDestinationSchema, onboardingArtworkSchema, onboardingAnswerSchema, onboardingQuestionSchema, onboardingTemplateSectionSchema, onboardingTemplateContentSchema, onboardingUnavailableOutcomeSchema, onboardingFlowSchema, onboardingActorSchema, onboardingEditorSchema, onboardingPublicationSummarySchema, onboardingValidationIssueSchema, onboardingValidationResponseSchema, onboardingAssetSchema, onboardingPublicAssetSchema, getOnboardingConfigResponseSchema, saveOnboardingDraftRequestSchema, validateOnboardingRequestSchema, publishOnboardingRequestSchema, rollbackOnboardingRequestSchema, onboardingTemplateCatalogItemSchema, getPublishedOnboardingResponseSchema;
3003
+ function isForwardableWebRouteRequestHeader(name) {
3004
+ const n2 = name.toLowerCase();
3005
+ return WEB_ROUTE_REQUEST_HEADER_ALLOWLIST.includes(n2) || n2.startsWith("x-lua-");
3006
+ }
3007
+ function isForwardableWebRouteResponseHeader(name) {
3008
+ const n2 = name.toLowerCase();
3009
+ if (n2 === "set-cookie") return false;
3010
+ return WEB_ROUTE_RESPONSE_HEADER_ALLOWLIST.includes(n2) || n2.startsWith("x-lua-");
3011
+ }
3012
+ function isWebRouteBody(value3) {
3013
+ if (!value3 || typeof value3 !== "object") return false;
3014
+ const b = value3;
3015
+ if (b.kind === "json") return "value" in b;
3016
+ if (b.kind === "text" || b.kind === "base64") return typeof b.value === "string";
3017
+ return false;
3018
+ }
3019
+ function isStringRecord(value3) {
3020
+ if (!value3 || typeof value3 !== "object" || Array.isArray(value3)) return false;
3021
+ return Object.values(value3).every((v) => typeof v === "string");
3022
+ }
3023
+ function isQueryRecord(value3) {
3024
+ if (!value3 || typeof value3 !== "object" || Array.isArray(value3)) return false;
3025
+ return Object.values(value3).every((v) => typeof v === "string" || Array.isArray(v) && v.every((one) => typeof one === "string"));
3026
+ }
3027
+ function isWebRouteInput(value3) {
3028
+ if (!value3 || typeof value3 !== "object") return false;
3029
+ const v = value3;
3030
+ if (v.v !== WEB_ROUTE_PROTOCOL_VERSION) return false;
3031
+ const r = v.request;
3032
+ if (!r || typeof r !== "object") return false;
3033
+ if (!WEB_ROUTE_METHODS.includes(String(r.method))) return false;
3034
+ if (typeof r.path !== "string" || !r.path.startsWith("/")) return false;
3035
+ if (!isStringRecord(r.params)) return false;
3036
+ if (!isQueryRecord(r.query)) return false;
3037
+ if (!isStringRecord(r.headers)) return false;
3038
+ if (r.body !== void 0) {
3039
+ if (r.method === "GET") return false;
3040
+ if (!isWebRouteBody(r.body)) return false;
3041
+ }
3042
+ const a = v.auth;
3043
+ if (!a || typeof a.userId !== "string" || typeof a.orgId !== "string" || typeof a.agentId !== "string") return false;
3044
+ const app = v.app;
3045
+ if (!app || typeof app.id !== "string" || typeof app.name !== "string" || typeof app.origin !== "string") return false;
3046
+ return true;
3047
+ }
3048
+ function evidenceDisplayText(text) {
3049
+ const raw = typeof text === "string" ? text : "";
3050
+ if (!raw.trim()) return "";
3051
+ const lines = removeHiddenBlocks(raw).split(/\r?\n/).map((line) => {
3052
+ const t = line.trim();
3053
+ for (const [re, label2] of ATTACHMENT_LINES) {
3054
+ const m = t.match(re);
3055
+ if (m) return label2(m);
3056
+ }
3057
+ return t.replace(/https?:\/\/cdn\.heylua\.ai\/\S+/gi, "[attachment]");
3058
+ }).filter(Boolean);
3059
+ const out = lines.join(" ").replace(/\s+/g, " ").trim();
3060
+ return out || "[Attachment]";
3061
+ }
3062
+ function evidenceSnippet(text) {
3063
+ const flat = evidenceDisplayText(text);
3064
+ return flat.length <= EVIDENCE_SNIPPET_MAX_CHARS ? flat : `${flat.slice(0, EVIDENCE_SNIPPET_MAX_CHARS - 1)}\u2026`;
3065
+ }
3066
+ function evidenceWordCount(text) {
3067
+ if (typeof text !== "string") return 0;
3068
+ const t = text.trim();
3069
+ return t ? t.split(/\s+/).length : 0;
3070
+ }
3071
+ function evidenceKey(label2) {
3072
+ return label2.toLowerCase().replace(/[_\-\s]+/g, " ").trim();
3073
+ }
3074
+ function evidenceOpaqueKey(text) {
3075
+ let h = 0xcbf29ce484222325n;
3076
+ const prime = 0x100000001b3n;
3077
+ for (const ch of evidenceKey(text)) {
3078
+ h ^= BigInt(ch.codePointAt(0) ?? 0);
3079
+ h = h * prime & 0xffffffffffffffffn;
3080
+ }
3081
+ return `q_${h.toString(16).padStart(16, "0")}`;
3082
+ }
3083
+ function evidenceToolKey(name) {
3084
+ const i = name.indexOf("__");
3085
+ return (i >= 0 ? name.slice(i + 2) : name).toLowerCase();
3086
+ }
3087
+ function evidenceToolSlug(name) {
3088
+ const i = name.indexOf("__");
3089
+ return i >= 0 ? name.slice(0, i).toLowerCase() : "";
3090
+ }
3091
+ function skillSlugBase(skill) {
3092
+ return skill.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
3093
+ }
3094
+ function matchDefinedTool(calledName, defined2) {
3095
+ const key = evidenceToolKey(calledName);
3096
+ const candidates = [];
3097
+ defined2.forEach((d, i) => {
3098
+ if (d.name.toLowerCase() === key) candidates.push(i);
3099
+ });
3100
+ if (candidates.length <= 1) return candidates[0] ?? -1;
3101
+ const slug = evidenceToolSlug(calledName);
3102
+ const bySkill = candidates.find((i) => {
3103
+ const base = skillSlugBase(defined2[i].skill);
3104
+ return base !== "" && (slug === base || slug.startsWith(`${base}_`) || base.startsWith(slug));
3105
+ });
3106
+ return bySkill ?? candidates[0];
3107
+ }
3108
+ function isMisunderstoodReason(reason) {
3109
+ return typeof reason === "string" && /misunderst/i.test(reason);
3110
+ }
3111
+ function emptyHistogram(bounds) {
3112
+ return {
3113
+ count: 0,
3114
+ sum: 0,
3115
+ buckets: new Array(bounds.length + 1).fill(0)
3116
+ };
3117
+ }
3118
+ function addToHistogram(h, bounds, value3) {
3119
+ if (!Number.isFinite(value3) || value3 < 0) return;
3120
+ let i = bounds.findIndex((b) => value3 <= b);
3121
+ if (i < 0) i = bounds.length;
3122
+ h.buckets[i] += 1;
3123
+ h.count += 1;
3124
+ h.sum += value3;
3125
+ }
3126
+ function mergeHistograms(hs, bounds) {
3127
+ if (hs.length === 0) return null;
3128
+ const out = emptyHistogram(bounds);
3129
+ for (const h of hs) {
3130
+ out.count += h.count;
3131
+ out.sum += h.sum;
3132
+ for (let i = 0; i < out.buckets.length; i++) out.buckets[i] += h.buckets[i] ?? 0;
3133
+ }
3134
+ return out.count > 0 ? out : null;
3135
+ }
3136
+ function histogramQuantile(h, bounds, q) {
3137
+ if (h.count === 0) return 0;
3138
+ const target = q * h.count;
3139
+ let seen = 0;
3140
+ for (let i = 0; i < h.buckets.length; i++) {
3141
+ const n2 = h.buckets[i];
3142
+ if (n2 > 0 && seen + n2 >= target) {
3143
+ const lo = i === 0 ? 0 : bounds[i - 1];
3144
+ if (i >= bounds.length) return lo;
3145
+ const hi = bounds[i];
3146
+ return lo + (target - seen) / n2 * (hi - lo);
3147
+ }
3148
+ seen += n2;
3149
+ }
3150
+ return bounds[bounds.length - 1];
3151
+ }
3152
+ function mergeCounted(lists) {
3153
+ const byKey = /* @__PURE__ */ new Map();
3154
+ for (const list of [
3155
+ ...lists
3156
+ ].reverse()) {
3157
+ for (const item of list) {
3158
+ const cur = byKey.get(item.key);
3159
+ if (!cur) {
3160
+ byKey.set(item.key, {
3161
+ ...item,
3162
+ examples: item.examples.slice(0, EVIDENCE_EXAMPLES_PER_ITEM)
3163
+ });
3164
+ } else {
3165
+ cur.count += item.count;
3166
+ if (cur.examples.length < EVIDENCE_EXAMPLES_PER_ITEM) {
3167
+ cur.examples.push(...item.examples.slice(0, EVIDENCE_EXAMPLES_PER_ITEM - cur.examples.length));
3168
+ }
3169
+ }
3170
+ }
3171
+ }
3172
+ return [
3173
+ ...byKey.values()
3174
+ ].sort((a, b) => b.count - a.count || a.key.localeCompare(b.key));
3175
+ }
3176
+ function recentRefs(lists) {
3177
+ return lists.flat().sort((a, b) => b.createdAt - a.createdAt).slice(0, EVIDENCE_EXAMPLES_PER_ITEM);
3178
+ }
3179
+ function confidenceOf(n2) {
3180
+ return n2 < EVIDENCE_LOW_CONFIDENCE_N ? "low" : "ok";
3181
+ }
3182
+ function rateOf(count, conversations) {
3183
+ return {
3184
+ count,
3185
+ rate: conversations > 0 ? count / conversations : null,
3186
+ confidence: confidenceOf(count)
3187
+ };
3188
+ }
3189
+ function evidenceDays(from, to) {
3190
+ const out = [];
3191
+ const end = Date.parse(`${to}T00:00:00Z`);
3192
+ for (let t = Date.parse(`${from}T00:00:00Z`); t <= end; t += 864e5) {
3193
+ out.push(new Date(t).toISOString().slice(0, 10));
3194
+ }
3195
+ return out;
3196
+ }
3197
+ function summarizeEvidence(input) {
3198
+ const { agentId, from, to } = input;
3199
+ const windowDays = evidenceDays(from, to);
3200
+ const readable = /* @__PURE__ */ __name2((s) => s === "ok" || s === "empty", "readable");
3201
+ const covered = /* @__PURE__ */ __name2((d) => readable(d.sources?.messages) && readable(d.sources?.analyses), "covered");
3202
+ const inWindow = input.days.filter((d) => d.date >= from && d.date <= to && covered(d)).sort((a, b) => a.date.localeCompare(b.date));
3203
+ const trackedSince = [
3204
+ ...input.days,
3205
+ ...input.previous ?? []
3206
+ ].filter(covered).map((d) => d.date).sort()[0] ?? null;
3207
+ const sum = /* @__PURE__ */ __name2((f) => inWindow.reduce((acc, d) => acc + (f(d) || 0), 0), "sum");
3208
+ const conversations = sum((d) => d.conversations);
3209
+ const byReason = Object.fromEntries(BAD_CONVERSATION_REASONS.map((r) => [
3210
+ r,
3211
+ sum((d) => d.bad.byReason[r])
3212
+ ]));
3213
+ const badTotal = sum((d) => d.bad.total);
3214
+ const prevDays = (input.previous ?? []).filter(covered);
3215
+ const comparable = prevDays.length > 0;
3216
+ const prevReasons = mergeCounted(prevDays.map((d) => d.themes.failureReasons));
3217
+ const prevTopics = mergeCounted(prevDays.map((d) => d.themes.topics));
3218
+ const toThemes = /* @__PURE__ */ __name2((lists, prev) => mergeCounted(lists).slice(0, EVIDENCE_SHOWN_ITEMS).map((t) => ({
3219
+ ...t,
3220
+ share: badTotal > 0 ? t.count / badTotal : 0,
3221
+ previousCount: comparable ? prev.find((p) => p.key === t.key)?.count ?? 0 : null,
3222
+ confidence: confidenceOf(t.count)
3223
+ })), "toThemes");
3224
+ const usage = /* @__PURE__ */ new Map();
3225
+ for (const d of inWindow) {
3226
+ for (const t of d.tools) {
3227
+ const cur = usage.get(t.name) ?? {
3228
+ name: t.name,
3229
+ calls: 0,
3230
+ conversations: 0,
3231
+ errors: 0
3232
+ };
3233
+ cur.calls += t.calls;
3234
+ cur.conversations += t.conversations;
3235
+ cur.errors += t.errors;
3236
+ usage.set(t.name, cur);
3237
+ }
3238
+ }
3239
+ const latestDefined = [
3240
+ ...inWindow
3241
+ ].reverse().find((d) => d.definedTools)?.definedTools ?? null;
3242
+ const defined2 = input.definedTools !== void 0 ? input.definedTools : latestDefined;
3243
+ const definedKnown = Array.isArray(defined2);
3244
+ const enoughData = conversations >= EVIDENCE_MIN_CONVERSATIONS;
3245
+ const definedList = defined2 ?? [];
3246
+ const definedRows = definedList.map((dt) => ({
3247
+ name: dt.name,
3248
+ skill: dt.skill,
3249
+ calls: 0,
3250
+ conversations: 0,
3251
+ errors: 0
3252
+ }));
3253
+ const matched = /* @__PURE__ */ new Set();
3254
+ for (const u of usage.values()) {
3255
+ const i = matchDefinedTool(u.name, definedList);
3256
+ if (i < 0) continue;
3257
+ matched.add(u.name);
3258
+ definedRows[i].calls += u.calls;
3259
+ definedRows[i].conversations += u.conversations;
3260
+ definedRows[i].errors += u.errors;
3261
+ }
3262
+ definedRows.sort((a, b) => b.calls - a.calls || a.name.localeCompare(b.name));
3263
+ const other = [
3264
+ ...usage.values()
3265
+ ].filter((u) => !matched.has(u.name)).sort((a, b) => b.calls - a.calls);
3266
+ const rt = mergeHistograms(inWindow.map((d) => d.responseTimeMs).filter((h) => !!h), EVIDENCE_LATENCY_BOUNDS_MS);
3267
+ const wordRows = inWindow.map((d) => d.responseWords).filter((h) => !!h);
3268
+ const rw = mergeHistograms(wordRows, EVIDENCE_WORD_BOUNDS);
3269
+ const short = wordRows.reduce((a, h) => a + h.short, 0);
3270
+ const long = wordRows.reduce((a, h) => a + h.long, 0);
3271
+ return {
3272
+ agentId,
3273
+ window: {
3274
+ from,
3275
+ to,
3276
+ days: windowDays.length
3277
+ },
3278
+ coverage: {
3279
+ daysWithData: inWindow.length,
3280
+ trackedSince,
3281
+ complete: inWindow.length === windowDays.length
3282
+ },
3283
+ conversations,
3284
+ exchanges: sum((d) => d.exchanges),
3285
+ bad: {
3286
+ ...rateOf(badTotal, conversations),
3287
+ byReason,
3288
+ examples: recentRefs(inWindow.map((d) => d.examples.bad))
3289
+ },
3290
+ misunderstood: {
3291
+ ...rateOf(sum((d) => d.misunderstood), conversations),
3292
+ examples: recentRefs(inWindow.map((d) => d.examples.misunderstood))
3293
+ },
3294
+ unmetIntent: {
3295
+ ...rateOf(sum((d) => d.unmetIntent), conversations),
3296
+ questions: mergeCounted(inWindow.map((d) => d.unmetQuestions)).slice(0, EVIDENCE_SHOWN_ITEMS)
3297
+ },
3298
+ loops: {
3299
+ ...rateOf(sum((d) => d.loops), conversations),
3300
+ examples: recentRefs(inWindow.map((d) => d.examples.loops))
3301
+ },
3302
+ themes: {
3303
+ failureReasons: toThemes(inWindow.map((d) => d.themes.failureReasons), prevReasons),
3304
+ topics: toThemes(inWindow.map((d) => d.themes.topics), prevTopics),
3305
+ comparable
3306
+ },
3307
+ tools: {
3308
+ enoughData,
3309
+ definedKnown,
3310
+ definedCount: definedRows.length,
3311
+ usedDefinedCount: definedRows.filter((r) => r.calls > 0).length,
3312
+ calledCount: definedRows.filter((r) => r.calls > 0).length + other.filter((u) => u.calls > 0).length,
3313
+ defined: definedRows,
3314
+ unused: enoughData && definedKnown ? definedRows.filter((r) => r.calls === 0).map(({ name, skill }) => ({
3315
+ name,
3316
+ skill
3317
+ })) : [],
3318
+ other
3319
+ },
3320
+ responseTime: rt ? {
3321
+ count: rt.count,
3322
+ avgMs: Math.round(rt.sum / rt.count),
3323
+ medianMs: Math.round(histogramQuantile(rt, EVIDENCE_LATENCY_BOUNDS_MS, 0.5)),
3324
+ p90Ms: Math.round(histogramQuantile(rt, EVIDENCE_LATENCY_BOUNDS_MS, 0.9))
3325
+ } : null,
3326
+ responseLength: rw ? {
3327
+ count: rw.count,
3328
+ avgWords: Math.round(rw.sum / rw.count),
3329
+ medianWords: Math.round(histogramQuantile(rw, EVIDENCE_WORD_BOUNDS, 0.5)),
3330
+ shortRate: short / rw.count,
3331
+ longRate: long / rw.count
3332
+ } : null
3333
+ };
3334
+ }
3335
+ function sortVerdictReasons(reasons) {
3336
+ return [
3337
+ ...reasons
3338
+ ].sort((a, b) => REVIEW_VERDICT_REASON_ORDER.indexOf(a.kind) - REVIEW_VERDICT_REASON_ORDER.indexOf(b.kind));
3339
+ }
3340
+ var __defProp2, __name2, PLUMBING_THREAD_CHANNELS, CHANNEL_CONVERSATION_CHANNELS, HIDDEN_THREAD_CHANNELS, PLATFORM_INVOCATION_CALLERS, SUPERVISION_OPS, REVIEWABLE_ACTION_EXECUTE_TOOL_ALLOWLIST, REVIEWABLE_STANDING_START_TOOLS, REVIEWABLE_MCP_SEND_TOOL_SUFFIX, MCP_TOOL_READ_VERB_RE, MCP_DRAFT_CREATE_VERBS, NON_INTERACTIVE_CHANNELS, RICH_PARTS_MESSAGE_ID_PREFIX, SCREENSHOT_MESSAGE_ID_PREFIX, BROWSER_COMMANDS, BROWSER_COMMAND_NAMES, LOG_FIELDS_MAX_KEYS, LOG_FIELD_MAX_VALUE_BYTES, LOG_FIELDS_MAX_BYTES, LOG_FIELD_KEY_PATTERN, LOG_FIELD_SECRET_SHAPED_KEY_PATTERNS, LOG_FIELDS_CLAMPED_KEY, LOG_FIELD_ARRAY_COUNT_SUFFIX, LuaLogFieldsError, DESKTOP_FILE_COMMANDS, DESKTOP_FILE_COMMAND_SET, WORKFLOW_RETRY_BACKOFFS, WORKFLOW_RETRY_MIN_ATTEMPTS, WORKFLOW_RETRY_POLICY_KEYS, WORKFLOW_RETRY_MAX_ATTEMPTS, WORKFLOW_RETRY_ENGINE_KEYS, WORKFLOW_JOB_RESOURCES, WORKFLOW_SIDE_EFFECTS, WORKFLOW_AGENT_EFFORTS, WORKFLOW_MODEL_CLASSES, WORKFLOW_TASK_CLASSES, WORKFLOW_MODEL_TRAITS, WORKFLOW_MODEL_REASON_MAX_LENGTH, WORKFLOW_MODELS_COMPOSE_MODES, WORKFLOW_MODELS_PIN_MODES, WORKFLOW_MODELS_FALLBACK_MODES, WORKFLOW_MODELS_CONSENT_ACTIONS_MIN, WORKFLOW_DEFAULT_TASK_CLASS_MAP, WORKFLOW_MODELS_MAX_CLASS_DEFAULT, WORKFLOW_AUTONOMY_FORMS, WORKFLOW_AUTONOMY_NUMERIC_KEYS, WORKFLOW_AUTONOMY_ENVELOPE_KEYS, WORKFLOW_AUTONOMY_ENABLED_DEFAULT, WORKFLOW_AUTONOMY_DEFAULTS, WORKFLOW_AUTONOMY_CEILINGS, WORKFLOW_AUTONOMY_MAX_RUNS_PER_HOUR_ENV, WORKFLOW_AUTONOMY_MAX_RUNS_PER_HOUR_CEILING, WORKFLOW_AUTONOMY_FORMS_DEFAULT, WORKFLOW_AUTONOMY_MIN_VALUE, WORKFLOW_JOB_RANGES, WORKFLOW_JOB_RANGE_MEMBERS, WORKFLOW_SINGLE_STEP_TYPES, WORKFLOW_HITL_ENTRY_TYPES, WORKFLOW_ARM_ENTRY_TYPES, WORKFLOW_HITL_ARM_CONTAINERS, WORKFLOW_GRAPH_ENTRY_STEP_KINDS, WORKFLOW_ARM_ENTRY_STEP_KINDS, WORKFLOW_BUDGET_MAX_DURATION_SECONDS, MODEL_ID_BYOK_PROVIDERS, MODEL_CLASS_REF_PREFIX, MODEL_SNAPSHOT_SUFFIX, REASONING_EFFORT_VALUES, IMPLICIT_MODEL_SELECTION_SOURCES, PLATFORM_FALLBACK_MODEL_SOURCE, AGENT_NAME_TOKEN, DEFAULT_PERSONA_GUIDE, PERSONAL_SPACE_STARTING_PERSONA, AGENT_LOG_SOURCES, AGENT_LOG_ENVIRONMENTS, AGENT_LOG_FIELDS_MAX_WIRE_KEYS, LOG_DRAIN_TYPES_PHASE1, LOG_DRAIN_TYPES_PHASE2, LOG_DRAIN_TYPES_IMPLEMENTED, LOG_DRAIN_FORMATS, LOG_DRAIN_SEVERITIES, LOG_DRAIN_SOURCES, LOG_DRAIN_CONTENT_SOURCES, LOG_DRAIN_DEFAULT_SOURCES, LOG_DRAIN_MAX_PER_ORG, LOG_DRAIN_MAX_PER_ORG_ENTERPRISE, LOG_DRAIN_DATADOG_SITES, LOG_DRAIN_NEWRELIC_SITES, LOG_DRAIN_ENDPOINT_TEMPLATES, LOG_DRAIN_PRESET_SITES, LOG_DRAIN_BUCKET_NAME_PATTERN, LOG_DRAIN_BUCKET_HOST_PATTERNS, LOG_DRAIN_PRESET_HOST_SUFFIXES, DRAIN_CONTENT_ACK_ERROR_CODE, DRAIN_CONTENT_ACK_FIELD, DrainContentAckRequiredError, LOG_DRAIN_PRESET_PATHS, PRESET_SEGMENT_RE, LOG_DRAIN_QUOTAS, LOG_DRAIN_QUOTA_WARN_RATIO, LOG_DRAIN_QUOTA_DROP_DEBUG_RATIO, LOG_DRAIN_QUOTA_DROP_INFO_RATIO, LOG_DRAIN_QUOTA_PAUSE_RATIO, LOG_EXPORT_SOURCES, LOG_EXPORT_MAX_WINDOW_DAYS, LOG_EXPORT_MAX_WINDOW_MS, LOG_EXPORT_URL_TTL_SECONDS, LOG_EXPORT_FILE_RETENTION_DAYS, LOG_EXPORT_FILE_RETENTION_MS, LOG_EXPORT_PART_MAX_BYTES, LOG_DRAIN_NOTICE_RATE_LIMIT_MS, LOG_DRAIN_VERIFICATION_STALE_MS, LOG_DRAIN_DIGEST_INTERVAL_MS, LOG_DRAIN_DIGEST_MAX_ENTRIES, LOG_DRAIN_NOTICE_ERROR_MAX_CHARS, LOG_DRAIN_USAGE_LINE_ITEM, LOG_DRAIN_BYTES_PER_GIB, DEFAULT_LOG_DRAIN_PLAN_CONFIG, TIERS, LOG_CURSOR_MAX_LENGTH, LOG_CURSOR_MAX_ID_LENGTH, LOG_RELATIVE_TIME_PATTERN, LOG_ISO_TIME_PATTERN, RELATIVE_UNIT_MS, CORE_DRAINING_CODE, CORE_DRAINING_DEFAULT_RETRY_MS, CORE_DRAINING_MAX_RETRY_MS, VoiceNameSchema, PluginProviderSchema, RealtimeProviderSchema, PluginClassSchema, ModelDescriptorSchema, InferenceModelSchema, PluginModelSchema, RealtimeModelSchema, LuaVoiceModelSchema, TurnDetectionSchema, InterruptionSchema, BuiltinAudioClipSchema, AudioConfigSchema, BackgroundAudioEntrySchema, BackgroundAudioSchema, LuaVoiceConfigInnerSchema, LuaVoiceConfigSchema, LuaVoiceRefSchema, EventType, LUA_JOB_DEFAULT_TIMEOUT_SECONDS, LUA_JOB_MIN_TIMEOUT_SECONDS, LUA_JOB_MAX_TIMEOUT_SECONDS, KEYS, MAX_BODY_BYTES, MAX_ID_LENGTH, UTC_ISO, TEMPLATE_TRIGGER_URL_ENV_PREFIX, TEMPLATE_INSTALL_POLICY_PER_WORKSPACE_VALUES, SUBJECT_TYPES, SubjectTypeSchema, CREDENTIAL_TYPES, CredentialTypeSchema, DEVICE_OPERATIONS, DeviceOperationSchema, DEVICE_SCOPE_BY_OPERATION, DeviceBindingSchema, TYPED_API_KEY, IdSchema, SESSION_AUTH_TIME_MAX_S, PrincipalDescriptorSchema, ActorDescriptorSchema, PrincipalOwnerSchema, CredentialLifecycleSchema, GeneralCredentialDescriptorSchema, DeviceCredentialDescriptorSchema, GeneralPrincipalContextSchema, DeviceCredentialPrincipalContextSchema, RawPrincipalContextSchema, PrincipalContextSchema, DeviceCredentialClaimSchema, LUA_CLIENT_HEADER, LUA_CLIENT_APPS, SEMVER_PATTERN, WEB_RELEASE_PATTERN, CLIENT_HEADER_PATTERN, LUA_SESSION_ID_CLAIM, SESSION_REVOKED_CODE, AUTHZ_PROJECTION_VERSION, ProjectedScopeSchema, DisplayRoleSchema, AuthorizationPrincipalSchema, CredentialContextSchema, ProjectionAnomalySchema, ProjectedOrgSchema, ProjectedResourceSchema, CapabilityProfilesSchema, RoleCatalogSchema, EffectiveAuthorizationSchema, ResourcePageSchema, SYSTEM_USER_PREFIX, WORKFLOW_RUN_IN_FLIGHT, WORKFLOW_RUN_IDLE, WORKFLOW_RUN_TERMINAL, WORKFLOW_RUN_STATUSES, WORKFLOW_RUN_GATE_KINDS, WORKFLOW_STEP_STATUSES, WORKFLOW_STEP_IN_FLIGHT, WORKFLOW_SIGNAL_EVENT_SITES, ARCHIVE_WINDOW_MARGIN_DAYS, WORKFLOW_ORG_PURGING_TTL_S, WORKFLOW_ORG_PURGE_FORCE_AFTER_MS, IDEMPOTENCY_HOLDING_STATUSES, WORKFLOW_SCHEDULED_RUN_ID_PREFIX, CLOUD_TASK_RUN_ID_PREFIX, WORKFLOW_SCHEDULE_KEY_MAX, WORKFLOW_SCHEDULE_IDEMPOTENCY_KEY_PREFIX, WORKFLOW_OPERATION_ID_PREFIX, WORKFLOW_JOURNAL_PROTOCOL_VERSION, WORKFLOW_CONNECTION_KEY_RE, WORKFLOW_JOB_MODEL_SOURCE_LABELS, WORKFLOW_SUSPEND_KINDS, WORKFLOW_RUN_NOTIFICATION_SUSPENDED_KINDS, WORKFLOW_SIGNAL_PAYLOAD_MAX_BYTES, WORKFLOW_RESOLVE_OUTPUT_MAX_BYTES, SCHEDULE_HEALTH_NOTIFY_CHANNELS, SCHEDULE_HEALTH_DEFAULT_NOTIFY, SCHEDULE_HEALTH_LIMITS, KNOWN_KEYS, WORKFLOW_GOAL_JUDGE_SELF, REDACTED_PLACEHOLDER, PROVIDER_MESSAGE_MAX_CHARS, ERROR_MESSAGE_MAX_CHARS, SECRET_LITERAL_PATTERNS, SECRET_NAME, SECRET_PAIR_PATTERNS, GROUP_COUNT, WORKFLOW_SECRET_KEY_RE, WORKFLOW_RESERVED_SECRET_KEYS, SCRUB_INPUT_MAX_CHARS, SCRUB_CUT_BACKOFF_CHARS, WORKFLOW_AUDIT_EVENTS, WORKFLOW_AUDIT_METADATA_MAX_BYTES, INDENT, WRAP_WIDTH, NOUNS, GET_TOOL_NAMES, PREAMBLE, WORKFLOW_APPROVAL_OUTPUT_DECISIONS, WORKFLOW_APPROVAL_OUTPUT_SCHEMA, JSON_FENCE_RE, DEFAULT_ON_AGENT_FEATURES, SUBAGENT_PER_KEY_FLAG_ENV, PER_KEY_FLAG_VALUES, ONBOARDING_FLOW_KEY, ONBOARDING_SCHEMA_VERSION, id, copy, onboardingHeadingSchema, onboardingRichTextInlineSchema, onboardingRichTextSchema, onboardingDestinationSchema, onboardingArtworkSchema, onboardingAnswerSchema, onboardingQuestionSchema, onboardingTemplateSectionSchema, onboardingTemplateContentSchema, onboardingUnavailableOutcomeSchema, onboardingFlowSchema, onboardingActorSchema, onboardingEditorSchema, onboardingPublicationSummarySchema, onboardingValidationIssueSchema, onboardingValidationResponseSchema, onboardingAssetSchema, onboardingPublicAssetSchema, getOnboardingConfigResponseSchema, saveOnboardingDraftRequestSchema, validateOnboardingRequestSchema, publishOnboardingRequestSchema, rollbackOnboardingRequestSchema, onboardingTemplateCatalogItemSchema, getPublishedOnboardingResponseSchema, WEB_ROUTE_PROTOCOL_VERSION, WEB_ROUTE_METHODS, WEB_ROUTE_REQUEST_HEADER_ALLOWLIST, WEB_ROUTE_RESPONSE_HEADER_ALLOWLIST, WEB_ROUTE_MAX_REQUEST_BODY_BYTES, WEB_ROUTE_MAX_RESPONSE_BYTES, EVIDENCE_SESSION_IDLE_MS, EVIDENCE_MIN_CONVERSATIONS, EVIDENCE_LOW_CONFIDENCE_N, EVIDENCE_SNIPPET_MAX_CHARS, EVIDENCE_EXAMPLES_PER_ITEM, EVIDENCE_SHOWN_ITEMS, EVIDENCE_LATENCY_BOUNDS_MS, EVIDENCE_WORD_BOUNDS, BAD_CONVERSATION_REASONS, ATTACHMENT_LINES, REVIEW_VERDICT_REASON_ORDER;
2816
3341
  var init_dist = __esm({
2817
3342
  "../shared-types/dist/index.mjs"() {
2818
3343
  "use strict";
@@ -2857,6 +3382,35 @@ var init_dist = __esm({
2857
3382
  __name2(personaToLiteral, "personaToLiteral");
2858
3383
  __name(aiGenerateInputFromSimplified, "aiGenerateInputFromSimplified");
2859
3384
  __name2(aiGenerateInputFromSimplified, "aiGenerateInputFromSimplified");
3385
+ PLATFORM_INVOCATION_CALLERS = [
3386
+ "workflow-step",
3387
+ "supervision-preview"
3388
+ ];
3389
+ __name(isPlatformInvocationCaller, "isPlatformInvocationCaller");
3390
+ __name2(isPlatformInvocationCaller, "isPlatformInvocationCaller");
3391
+ __name(supervisionSubjectId, "supervisionSubjectId");
3392
+ __name2(supervisionSubjectId, "supervisionSubjectId");
3393
+ SUPERVISION_OPS = {
3394
+ "agents.list": "discover",
3395
+ "agents.get": "discover",
3396
+ logs: "observe",
3397
+ "runs.list": "observe",
3398
+ "runs.get": "observe",
3399
+ "data.get": "observe",
3400
+ "data.query": "observe",
3401
+ "versions.list": "observe",
3402
+ "versions.get": "observe",
3403
+ "versions.diff": "observe",
3404
+ "versions.preview": "preview",
3405
+ "versions.promote": "release",
3406
+ "persona.versions": "observe",
3407
+ "persona.activate": "release",
3408
+ "source.list": "observe",
3409
+ "source.get": "observe",
3410
+ "env.keys": "observe"
3411
+ };
3412
+ __name(isSupervisionOp, "isSupervisionOp");
3413
+ __name2(isSupervisionOp, "isSupervisionOp");
2860
3414
  REVIEWABLE_ACTION_EXECUTE_TOOL_ALLOWLIST = [
2861
3415
  "sendChannelMessage",
2862
3416
  "sendWhatsappTemplate",
@@ -2912,6 +3466,8 @@ var init_dist = __esm({
2912
3466
  __name2(isInteractiveTurn, "isInteractiveTurn");
2913
3467
  __name(removeNavigateBlock, "removeNavigateBlock");
2914
3468
  __name2(removeNavigateBlock, "removeNavigateBlock");
3469
+ __name(removeHiddenBlocks, "removeHiddenBlocks");
3470
+ __name2(removeHiddenBlocks, "removeHiddenBlocks");
2915
3471
  __name(transformChatHistoryContentParts, "transformChatHistoryContentParts");
2916
3472
  __name2(transformChatHistoryContentParts, "transformChatHistoryContentParts");
2917
3473
  RICH_PARTS_MESSAGE_ID_PREFIX = "rich-parts:";
@@ -3544,6 +4100,7 @@ This text is who you are for this person. As you learn them, their name, their w
3544
4100
  "skill",
3545
4101
  "job",
3546
4102
  "webhook",
4103
+ "web-route",
3547
4104
  "trigger",
3548
4105
  "preprocessor",
3549
4106
  "postprocessor",
@@ -3558,7 +4115,8 @@ This text is who you are for this person. As you learn them, their name, their w
3558
4115
  "model-resolver",
3559
4116
  "workflow-step",
3560
4117
  "workflow-script",
3561
- "workflow"
4118
+ "workflow",
4119
+ "supervision"
3562
4120
  ];
3563
4121
  AGENT_LOG_ENVIRONMENTS = [
3564
4122
  "production",
@@ -4702,6 +5260,41 @@ This text is who you are for this person. As you learn them, their name, their w
4702
5260
  ];
4703
5261
  WORKFLOW_SIGNAL_PAYLOAD_MAX_BYTES = 64 * 1024;
4704
5262
  WORKFLOW_RESOLVE_OUTPUT_MAX_BYTES = 256 * 1024;
5263
+ SCHEDULE_HEALTH_NOTIFY_CHANNELS = [
5264
+ "app",
5265
+ "email",
5266
+ "emailApp"
5267
+ ];
5268
+ SCHEDULE_HEALTH_DEFAULT_NOTIFY = "emailApp";
5269
+ SCHEDULE_HEALTH_LIMITS = {
5270
+ maxSilenceMinutes: {
5271
+ min: 5,
5272
+ max: 43200
5273
+ },
5274
+ alertAfterConsecutiveFailures: {
5275
+ min: 1,
5276
+ max: 50
5277
+ },
5278
+ /** The platform's auto-disable trip (PRO-726 / 07 §7.1.6): a streak can never pass it on these kinds. */
5279
+ parkedKindsMaxFailures: 3
5280
+ };
5281
+ KNOWN_KEYS = /* @__PURE__ */ new Set([
5282
+ "maxSilenceMinutes",
5283
+ "alertAfterConsecutiveFailures",
5284
+ "notify"
5285
+ ]);
5286
+ __name(isInt, "isInt");
5287
+ __name2(isInt, "isInt");
5288
+ __name(validateScheduleHealth, "validateScheduleHealth");
5289
+ __name2(validateScheduleHealth, "validateScheduleHealth");
5290
+ __name(normalizeScheduleHealth, "normalizeScheduleHealth");
5291
+ __name2(normalizeScheduleHealth, "normalizeScheduleHealth");
5292
+ __name(evaluateScheduleHealth, "evaluateScheduleHealth");
5293
+ __name2(evaluateScheduleHealth, "evaluateScheduleHealth");
5294
+ __name(scheduleHealthView, "scheduleHealthView");
5295
+ __name2(scheduleHealthView, "scheduleHealthView");
5296
+ __name(scheduleHealthSourceId, "scheduleHealthSourceId");
5297
+ __name2(scheduleHealthSourceId, "scheduleHealthSourceId");
4705
5298
  WORKFLOW_GOAL_JUDGE_SELF = "$self";
4706
5299
  __name(workflowGoalJudgeKind, "workflowGoalJudgeKind");
4707
5300
  __name2(workflowGoalJudgeKind, "workflowGoalJudgeKind");
@@ -5309,6 +5902,150 @@ listed here; never invent a target.`;
5309
5902
  __name2(parseOnboardingFlow, "parseOnboardingFlow");
5310
5903
  __name(parsePublishedOnboardingResponse, "parsePublishedOnboardingResponse");
5311
5904
  __name2(parsePublishedOnboardingResponse, "parsePublishedOnboardingResponse");
5905
+ WEB_ROUTE_PROTOCOL_VERSION = 1;
5906
+ WEB_ROUTE_METHODS = [
5907
+ "GET",
5908
+ "POST",
5909
+ "PUT",
5910
+ "PATCH",
5911
+ "DELETE"
5912
+ ];
5913
+ WEB_ROUTE_REQUEST_HEADER_ALLOWLIST = [
5914
+ "accept",
5915
+ "accept-language",
5916
+ "content-type",
5917
+ "if-none-match",
5918
+ "idempotency-key"
5919
+ ];
5920
+ WEB_ROUTE_RESPONSE_HEADER_ALLOWLIST = [
5921
+ "content-type",
5922
+ "cache-control",
5923
+ "etag",
5924
+ "location",
5925
+ "content-disposition",
5926
+ "content-language"
5927
+ ];
5928
+ __name(isForwardableWebRouteRequestHeader, "isForwardableWebRouteRequestHeader");
5929
+ __name2(isForwardableWebRouteRequestHeader, "isForwardableWebRouteRequestHeader");
5930
+ __name(isForwardableWebRouteResponseHeader, "isForwardableWebRouteResponseHeader");
5931
+ __name2(isForwardableWebRouteResponseHeader, "isForwardableWebRouteResponseHeader");
5932
+ WEB_ROUTE_MAX_REQUEST_BODY_BYTES = 1 * 1024 * 1024;
5933
+ WEB_ROUTE_MAX_RESPONSE_BYTES = 4 * 1024 * 1024;
5934
+ __name(isWebRouteBody, "isWebRouteBody");
5935
+ __name2(isWebRouteBody, "isWebRouteBody");
5936
+ __name(isStringRecord, "isStringRecord");
5937
+ __name2(isStringRecord, "isStringRecord");
5938
+ __name(isQueryRecord, "isQueryRecord");
5939
+ __name2(isQueryRecord, "isQueryRecord");
5940
+ __name(isWebRouteInput, "isWebRouteInput");
5941
+ __name2(isWebRouteInput, "isWebRouteInput");
5942
+ EVIDENCE_SESSION_IDLE_MS = 30 * 6e4;
5943
+ EVIDENCE_MIN_CONVERSATIONS = 20;
5944
+ EVIDENCE_LOW_CONFIDENCE_N = 5;
5945
+ EVIDENCE_SNIPPET_MAX_CHARS = 160;
5946
+ EVIDENCE_EXAMPLES_PER_ITEM = 5;
5947
+ EVIDENCE_SHOWN_ITEMS = 5;
5948
+ EVIDENCE_LATENCY_BOUNDS_MS = [
5949
+ 500,
5950
+ 1e3,
5951
+ 2e3,
5952
+ 3e3,
5953
+ 5e3,
5954
+ 8e3,
5955
+ 13e3,
5956
+ 2e4,
5957
+ 3e4,
5958
+ 6e4,
5959
+ 12e4
5960
+ ];
5961
+ EVIDENCE_WORD_BOUNDS = [
5962
+ 4,
5963
+ 10,
5964
+ 20,
5965
+ 40,
5966
+ 80,
5967
+ 150,
5968
+ 300,
5969
+ 600
5970
+ ];
5971
+ BAD_CONVERSATION_REASONS = [
5972
+ "thumbs_down",
5973
+ "unfinished",
5974
+ "asked_for_human"
5975
+ ];
5976
+ ATTACHMENT_LINES = [
5977
+ // Audio / video / document lines carry a URL; a reply like "Audio: terrible" is the user's words.
5978
+ [
5979
+ /^\[?audio:\s*https?:\/\/\S+\]?$/i,
5980
+ () => "[Voice message]"
5981
+ ],
5982
+ [
5983
+ /^\[?video:\s*https?:\/\/\S+\]?$/i,
5984
+ () => "[Video]"
5985
+ ],
5986
+ [
5987
+ /^\[?document:\s*https?:\/\/\S+\]?$/i,
5988
+ () => "[Document]"
5989
+ ],
5990
+ // Image lines carry a file name with an extension (spaces allowed): "Image: my photo.jpg".
5991
+ [
5992
+ /^\[?image:\s*(?:https?:\/\/\S+|[^\s][^\n]{0,200}\.[a-z0-9]{2,5})\]?$/i,
5993
+ () => "[Image]"
5994
+ ],
5995
+ // "File: name (url)" — bounded classes, no backtracking between the name and the URL.
5996
+ [
5997
+ /^file:\s*([^()]{1,200}?)\s*\(https?:\/\/[^\s)]+\)$/i,
5998
+ (m) => `[File: ${m[1]}]`
5999
+ ]
6000
+ ];
6001
+ __name(evidenceDisplayText, "evidenceDisplayText");
6002
+ __name2(evidenceDisplayText, "evidenceDisplayText");
6003
+ __name(evidenceSnippet, "evidenceSnippet");
6004
+ __name2(evidenceSnippet, "evidenceSnippet");
6005
+ __name(evidenceWordCount, "evidenceWordCount");
6006
+ __name2(evidenceWordCount, "evidenceWordCount");
6007
+ __name(evidenceKey, "evidenceKey");
6008
+ __name2(evidenceKey, "evidenceKey");
6009
+ __name(evidenceOpaqueKey, "evidenceOpaqueKey");
6010
+ __name2(evidenceOpaqueKey, "evidenceOpaqueKey");
6011
+ __name(evidenceToolKey, "evidenceToolKey");
6012
+ __name2(evidenceToolKey, "evidenceToolKey");
6013
+ __name(evidenceToolSlug, "evidenceToolSlug");
6014
+ __name2(evidenceToolSlug, "evidenceToolSlug");
6015
+ __name(skillSlugBase, "skillSlugBase");
6016
+ __name2(skillSlugBase, "skillSlugBase");
6017
+ __name(matchDefinedTool, "matchDefinedTool");
6018
+ __name2(matchDefinedTool, "matchDefinedTool");
6019
+ __name(isMisunderstoodReason, "isMisunderstoodReason");
6020
+ __name2(isMisunderstoodReason, "isMisunderstoodReason");
6021
+ __name(emptyHistogram, "emptyHistogram");
6022
+ __name2(emptyHistogram, "emptyHistogram");
6023
+ __name(addToHistogram, "addToHistogram");
6024
+ __name2(addToHistogram, "addToHistogram");
6025
+ __name(mergeHistograms, "mergeHistograms");
6026
+ __name2(mergeHistograms, "mergeHistograms");
6027
+ __name(histogramQuantile, "histogramQuantile");
6028
+ __name2(histogramQuantile, "histogramQuantile");
6029
+ __name(mergeCounted, "mergeCounted");
6030
+ __name2(mergeCounted, "mergeCounted");
6031
+ __name(recentRefs, "recentRefs");
6032
+ __name2(recentRefs, "recentRefs");
6033
+ __name(confidenceOf, "confidenceOf");
6034
+ __name2(confidenceOf, "confidenceOf");
6035
+ __name(rateOf, "rateOf");
6036
+ __name2(rateOf, "rateOf");
6037
+ __name(evidenceDays, "evidenceDays");
6038
+ __name2(evidenceDays, "evidenceDays");
6039
+ __name(summarizeEvidence, "summarizeEvidence");
6040
+ __name2(summarizeEvidence, "summarizeEvidence");
6041
+ REVIEW_VERDICT_REASON_ORDER = [
6042
+ "overall_below",
6043
+ "dimension_below",
6044
+ "critical_issues",
6045
+ "issue_count"
6046
+ ];
6047
+ __name(sortVerdictReasons, "sortVerdictReasons");
6048
+ __name2(sortVerdictReasons, "sortVerdictReasons");
5312
6049
  }
5313
6050
  });
5314
6051
 
@@ -5923,7 +6660,31 @@ function effectiveJobTools(jobTools, readOnly) {
5923
6660
  }
5924
6661
  return out;
5925
6662
  }
5926
- var __defProp3, __name3, WORKFLOW_JOB_TOOLS, WORKFLOW_JOB_READ_ONLY_DROPPED, WORKFLOW_JOB_DEFAULT_TOOLS;
6663
+ function isWorkflowJobPluginId(id2) {
6664
+ return typeof id2 === "string" && WORKFLOW_JOB_PLUGINS.includes(id2);
6665
+ }
6666
+ function workflowJobPluginDir(id2) {
6667
+ return `${WORKFLOW_JOB_PLUGIN_ROOT}/${id2}`;
6668
+ }
6669
+ function workflowJobPluginsProblem(plugins) {
6670
+ if (plugins === void 0) return null;
6671
+ if (!Array.isArray(plugins)) return "plugins must be an array of plugin ids";
6672
+ if (plugins.length > WORKFLOW_JOB_PLUGINS_MAX) return `at most ${WORKFLOW_JOB_PLUGINS_MAX} plugins per step`;
6673
+ const unknown = plugins.filter((p) => !isWorkflowJobPluginId(p));
6674
+ if (unknown.length) return `unknown plugin ${unknown.map((u) => JSON.stringify(u)).join(", ")} (allowed: ${WORKFLOW_JOB_PLUGINS.join(", ")})`;
6675
+ if (new Set(plugins).size !== plugins.length) return "plugins must not repeat";
6676
+ return null;
6677
+ }
6678
+ function workflowJobTargetProblem(target, plugins) {
6679
+ if (target === void 0) return null;
6680
+ if (!target || typeof target !== "object" || Array.isArray(target)) return "target must be { agentId }";
6681
+ const keys = Object.keys(target);
6682
+ const agentId = target.agentId;
6683
+ if (keys.length !== 1 || typeof agentId !== "string" || !agentId.trim() || agentId.length > 256) return "target must be exactly { agentId: <non-empty string> }";
6684
+ if (!Array.isArray(plugins) || plugins.length === 0) return "`target` is legal only beside `plugins`";
6685
+ return null;
6686
+ }
6687
+ var __defProp3, __name3, WORKFLOW_JOB_TOOLS, WORKFLOW_JOB_READ_ONLY_DROPPED, WORKFLOW_JOB_DEFAULT_TOOLS, WORKFLOW_JOB_PLUGINS, WORKFLOW_JOB_PLUGIN_ROOT, WORKFLOW_JOB_PLUGINS_MAX;
5927
6688
  var init_workflow_job_tools = __esm({
5928
6689
  "../shared-types/dist/workflow-job-tools.mjs"() {
5929
6690
  "use strict";
@@ -5958,6 +6719,19 @@ var init_workflow_job_tools = __esm({
5958
6719
  ];
5959
6720
  __name(effectiveJobTools, "effectiveJobTools");
5960
6721
  __name3(effectiveJobTools, "effectiveJobTools");
6722
+ WORKFLOW_JOB_PLUGINS = [
6723
+ "lua-agent-builder"
6724
+ ];
6725
+ WORKFLOW_JOB_PLUGIN_ROOT = "/opt/lua/plugins";
6726
+ WORKFLOW_JOB_PLUGINS_MAX = 4;
6727
+ __name(isWorkflowJobPluginId, "isWorkflowJobPluginId");
6728
+ __name3(isWorkflowJobPluginId, "isWorkflowJobPluginId");
6729
+ __name(workflowJobPluginDir, "workflowJobPluginDir");
6730
+ __name3(workflowJobPluginDir, "workflowJobPluginDir");
6731
+ __name(workflowJobPluginsProblem, "workflowJobPluginsProblem");
6732
+ __name3(workflowJobPluginsProblem, "workflowJobPluginsProblem");
6733
+ __name(workflowJobTargetProblem, "workflowJobTargetProblem");
6734
+ __name3(workflowJobTargetProblem, "workflowJobTargetProblem");
5961
6735
  }
5962
6736
  });
5963
6737
 
@@ -6908,6 +7682,26 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
6908
7682
  warn("gh-on-coding-turn", `"${id2}" grants the gh tool on a coding turn \u2014 the pod can open/merge PRs on the workspace repo (purpose:'gh' token, pull_requests:write + contents:write)`, `${path26}.jobTools`, id2);
6909
7683
  }
6910
7684
  }
7685
+ const plugins = node.plugins;
7686
+ const target = node.target;
7687
+ if (target !== void 0) {
7688
+ const problem = workflowJobTargetProblem(target, plugins);
7689
+ if (problem) err("target-invalid", problem, `${path26}.target`, id2);
7690
+ }
7691
+ if (plugins !== void 0) {
7692
+ const problem = workflowJobPluginsProblem(plugins);
7693
+ if (problem) err("plugins-invalid", problem, `${path26}.plugins`, id2);
7694
+ if (node.type !== "agent") err("plugins-invalid", "`plugins` is legal on agent steps only", `${path26}.plugins`, id2);
7695
+ else {
7696
+ if (!isJobTier(node)) err("plugins-invalid", "`plugins` needs tier:'job'", `${path26}.plugins`, id2);
7697
+ const provider = classifyModelProvider(jobClassifiablePin(node.model));
7698
+ if (node.harness === "generic" || provider !== null && provider !== "anthropic") err("plugins-invalid", "`plugins` run on the claude-code harness only (an Anthropic model, no `harness:'generic'`)", `${path26}.plugins`, id2);
7699
+ const w = workspaceOf(node);
7700
+ const ro = w !== void 0 && w !== "inherit" && w.mount === "ro";
7701
+ const declared = Array.isArray(tools) ? tools : void 0;
7702
+ if (!effectiveJobTools(declared, ro).includes("shell")) err("plugins-invalid", "`plugins` need the `shell` job tool (the plugin drives lua-cli) \u2014 keep it in jobTools and mount rw", `${path26}.plugins`, id2);
7703
+ }
7704
+ }
6911
7705
  if (node.type === "agent" && ws && ws !== "inherit" && ws.mount === "ro" && Array.isArray(tools) && effectiveJobTools(tools, true).length === 0) {
6912
7706
  warn("ro-step-has-no-tools", `"${id2}" mounts the workspace read-only and every jobTool it declares (${JSON.stringify(tools)}) is one the ro mount drops [${WORKFLOW_JOB_READ_ONLY_DROPPED.join(", ")}] \u2014 the coding turn would run with no tools at all; keep a read-only tool (read/glob/grep, gh) or mount rw`, `${path26}.jobTools`, id2);
6913
7707
  }
@@ -10376,6 +11170,15 @@ function createWorkflow(cfg) {
10376
11170
  const n2 = cfg.backfillOnEnable.maxOccurrences;
10377
11171
  if (!Number.isInteger(n2) || n2 < 1 || n2 > 200) throw new LuaWorkflowBuildError("invalid-envelope", "backfillOnEnable.maxOccurrences must be an integer in 1..200 (backfill-max-occurrences-out-of-range; the org maxBatchItems twin is checked at publish/R56)");
10378
11172
  }
11173
+ if (cfg.health !== void 0) {
11174
+ const issues = validateScheduleHealth(cfg.health, {
11175
+ target: "workflow",
11176
+ triggers: cfg.schedule && typeof cfg.schedule === "object" ? [
11177
+ cfg.schedule
11178
+ ] : []
11179
+ });
11180
+ if (issues.length > 0) throw new LuaWorkflowBuildError("invalid-envelope", issues.map((i) => `${i.message} (${i.code})`).join("; "));
11181
+ }
10379
11182
  const keys = /* @__PURE__ */ new Set();
10380
11183
  envRefKeys(cfg.schedule, keys);
10381
11184
  envRefKeys(cfg.workspace, keys);
@@ -10400,6 +11203,7 @@ var init2, state2, lit2, eq2, ne2, gt2, gte2, lt2, lte2, inSet2, notIn2, exists2
10400
11203
  var init_workflow = __esm({
10401
11204
  "src/types/workflow.ts"() {
10402
11205
  "use strict";
11206
+ init_workflow_job_tools();
10403
11207
  init_dist();
10404
11208
  init_dist2();
10405
11209
  __name(createStep, "createStep");
@@ -10898,6 +11702,15 @@ var init_workflow = __esm({
10898
11702
  throw new LuaWorkflowBuildError("max-turns-invalid", `"${id2}": ${m} must be an integer ${min}..${max}`);
10899
11703
  }
10900
11704
  }
11705
+ if (opts.plugins !== void 0) {
11706
+ if (tier !== "job") throw new LuaWorkflowBuildError("plugins-invalid", `"${id2}": plugins are only legal on a tier:'job' agent step`);
11707
+ const problem = workflowJobPluginsProblem(opts.plugins);
11708
+ if (problem) throw new LuaWorkflowBuildError("plugins-invalid", `"${id2}": ${problem}`);
11709
+ }
11710
+ if (opts.target !== void 0) {
11711
+ const problem = workflowJobTargetProblem(opts.target, opts.plugins);
11712
+ if (problem) throw new LuaWorkflowBuildError("plugins-invalid", `"${id2}": ${problem}`);
11713
+ }
10901
11714
  assertTimeout({
10902
11715
  id: id2,
10903
11716
  timeoutSeconds: opts.timeoutSeconds,
@@ -10930,7 +11743,9 @@ var init_workflow = __esm({
10930
11743
  harness: opts.harness,
10931
11744
  maxTurns: opts.maxTurns,
10932
11745
  maxMessages: opts.maxMessages,
10933
- maxInputTokens: opts.maxInputTokens
11746
+ maxInputTokens: opts.maxInputTokens,
11747
+ plugins: opts.plugins,
11748
+ target: opts.target
10934
11749
  });
10935
11750
  return this.push({
10936
11751
  kind: "declare",
@@ -11723,18 +12538,18 @@ var init_http_client = __esm({
11723
12538
  * Use this only when a successful response contains a one-time secret that
11724
12539
  * cannot be recovered after an ambiguous network or server failure.
11725
12540
  */
11726
- async httpPostOnce(url, data, headers) {
12541
+ async httpPostOnce(url, data, headers, overrides) {
11727
12542
  return this.retryableRequest(this.baseUrl + url, {
11728
12543
  method: "POST",
11729
12544
  body: data ? JSON.stringify(data) : void 0,
11730
12545
  headers
11731
- }, 0);
12546
+ }, 0, overrides);
11732
12547
  }
11733
- async httpPostCoreDrainRetry(url, data, headers) {
11734
- const first = await this.httpPostOnce(url, data, headers);
12548
+ async httpPostCoreDrainRetry(url, data, headers, overrides) {
12549
+ const first = await this.httpPostOnce(url, data, headers, overrides);
11735
12550
  if (!isCoreDrainApiError(first.error)) return first;
11736
12551
  await new Promise((resolve7) => setTimeout(resolve7, coreDrainApiRetryDelayMs(first.error)));
11737
- return this.httpPostOnce(url, data, headers);
12552
+ return this.httpPostOnce(url, data, headers, overrides);
11738
12553
  }
11739
12554
  /**
11740
12555
  * Performs an HTTP PUT request
@@ -13312,7 +14127,7 @@ var init_base_handler = __esm({
13312
14127
  if (syncVersions && Array.isArray(versions) && versions.length > 0) {
13313
14128
  const activeVersion = this.getActiveVersion(serverItem);
13314
14129
  const currentVersion = item.version;
13315
- if (activeVersion && activeVersion !== currentVersion) {
14130
+ if (activeVersion && compareVersions(activeVersion, currentVersion) > 0) {
13316
14131
  const msg = `\u{1F4DD} Updated "${item.name}" ${this.displayName} version: ${currentVersion} \u2192 ${activeVersion}`;
13317
14132
  msgs.push(msg);
13318
14133
  console.log(msg);
@@ -15857,6 +16672,7 @@ var init_job_plugin = __esm({
15857
16672
  "src/compiler/plugins/job.plugin.ts"() {
15858
16673
  "use strict";
15859
16674
  init_base();
16675
+ init_dist();
15860
16676
  init_ast_helpers();
15861
16677
  init_class_hierarchy();
15862
16678
  JobPlugin = class extends BasePlugin {
@@ -15902,6 +16718,8 @@ var init_job_plugin = __esm({
15902
16718
  maxAttempts: extractNestedProperty(retryObj, "maxAttempts"),
15903
16719
  backoffSeconds: extractNestedProperty(retryObj, "backoffSeconds")
15904
16720
  } : void 0;
16721
+ const healthHit = findClassMember(classDecl, "health", "property");
16722
+ const healthConfig = healthHit && Node5.isPropertyDeclaration(healthHit.node) ? evaluateNodeAsObject(healthHit.node.getInitializer()) : void 0;
15905
16723
  return {
15906
16724
  kind: this.kind,
15907
16725
  name,
@@ -15922,7 +16740,9 @@ var init_job_plugin = __esm({
15922
16740
  hasTimeout: timeoutHit !== void 0,
15923
16741
  hasRetry: retryHit !== void 0,
15924
16742
  timeoutValue,
15925
- retryConfig
16743
+ retryConfig,
16744
+ hasHealth: healthHit !== void 0,
16745
+ healthConfig
15926
16746
  }
15927
16747
  };
15928
16748
  }
@@ -15937,6 +16757,7 @@ var init_job_plugin = __esm({
15937
16757
  schedule: __lua_instance__.schedule,
15938
16758
  timeout: __lua_instance__.timeout,
15939
16759
  retry: __lua_instance__.retry,
16760
+ health: __lua_instance__.health,
15940
16761
  execute: typeof __lua_instance__.execute === 'function' ? __lua_instance__.execute.bind(__lua_instance__) : undefined,
15941
16762
  }`;
15942
16763
  }
@@ -15958,6 +16779,7 @@ var init_job_plugin = __esm({
15958
16779
  maxAttempts: extractNestedProperty(retryObj, "maxAttempts"),
15959
16780
  backoffSeconds: extractNestedProperty(retryObj, "backoffSeconds")
15960
16781
  } : void 0;
16782
+ const healthConfig = extractObjectProperty(config, "health");
15961
16783
  return {
15962
16784
  kind: this.kind,
15963
16785
  ...common,
@@ -15972,7 +16794,9 @@ var init_job_plugin = __esm({
15972
16794
  hasTimeout: config.getProperty("timeout") !== void 0,
15973
16795
  hasRetry: config.getProperty("retry") !== void 0,
15974
16796
  timeoutValue,
15975
- retryConfig
16797
+ retryConfig,
16798
+ hasHealth: config.getProperty("health") !== void 0,
16799
+ healthConfig
15976
16800
  }
15977
16801
  };
15978
16802
  }
@@ -15999,6 +16823,29 @@ var init_job_plugin = __esm({
15999
16823
  line: metadata.line
16000
16824
  }));
16001
16825
  }
16826
+ if (metadata.metadata.hasHealth) {
16827
+ if (!metadata.metadata.healthConfig) {
16828
+ errors.push(validationError("Job `health` must be an object literal the compiler can read", {
16829
+ line: metadata.line,
16830
+ suggestion: "health: { maxSilenceMinutes: 90, alertAfterConsecutiveFailures: 3, notify: 'emailApp' }"
16831
+ }));
16832
+ } else {
16833
+ const schedule = metadata.metadata.scheduleType ? [
16834
+ {
16835
+ type: metadata.metadata.scheduleType,
16836
+ seconds: metadata.metadata.scheduleSeconds
16837
+ }
16838
+ ] : [];
16839
+ for (const issue of validateScheduleHealth(metadata.metadata.healthConfig, {
16840
+ target: "job",
16841
+ triggers: schedule
16842
+ })) {
16843
+ errors.push(validationError(`Job ${issue.path}: ${issue.message} (${issue.code})`, {
16844
+ line: metadata.line
16845
+ }));
16846
+ }
16847
+ }
16848
+ }
16002
16849
  return {
16003
16850
  valid: errors.length === 0,
16004
16851
  errors,
@@ -16026,7 +16873,10 @@ var init_job_plugin = __esm({
16026
16873
  timezone: jobMeta.scheduleTimezone
16027
16874
  } : void 0,
16028
16875
  timeout: jobMeta.timeoutValue,
16029
- retry: jobMeta.retryConfig
16876
+ retry: jobMeta.retryConfig,
16877
+ ...jobMeta.healthConfig ? {
16878
+ health: jobMeta.healthConfig
16879
+ } : {}
16030
16880
  };
16031
16881
  }
16032
16882
  };
@@ -18056,7 +18906,7 @@ function shapeReasoningSetting(value3) {
18056
18906
  return Object.keys(result).length > 0 ? result : void 0;
18057
18907
  }
18058
18908
  function shapeModelSettings(raw) {
18059
- const KNOWN_KEYS = [
18909
+ const KNOWN_KEYS2 = [
18060
18910
  "temperature",
18061
18911
  "topP",
18062
18912
  "topK",
@@ -18068,7 +18918,7 @@ function shapeModelSettings(raw) {
18068
18918
  "reasoning"
18069
18919
  ];
18070
18920
  const result = {};
18071
- for (const key of KNOWN_KEYS) {
18921
+ for (const key of KNOWN_KEYS2) {
18072
18922
  const value3 = raw[key];
18073
18923
  if (value3 === void 0) continue;
18074
18924
  if (key === "stopSequences") {
@@ -22194,6 +23044,8 @@ function metaOf(node, sources) {
22194
23044
  pick("outputSchema", n2.outputSchema);
22195
23045
  const jobTools = n2.toolScope?.jobTools;
22196
23046
  pick("jobTools", jobTools);
23047
+ pick("plugins", n2.plugins);
23048
+ pick("target", n2.target);
22197
23049
  }
22198
23050
  if (n2.type === "approval") {
22199
23051
  pick("editedPayloadSchema", n2.editedPayloadSchema);
@@ -23076,6 +23928,7 @@ ${firstBundleFrame(vmResult.error.stack)}` : ""}`,
23076
23928
  schedule: config.schedule,
23077
23929
  scheduleInput: config.scheduleInput,
23078
23930
  backfillOnEnable: config.backfillOnEnable,
23931
+ health: config.health,
23079
23932
  outputVisibility: config.outputVisibility,
23080
23933
  goal: config.goal
23081
23934
  };
@@ -27086,6 +27939,48 @@ var init_integrations_api_service = __esm({
27086
27939
  });
27087
27940
 
27088
27941
  // src/api/agents.api.service.ts
27942
+ function toInvocationOutput(data, callerThreadId) {
27943
+ const toolNames = /* @__PURE__ */ new Set();
27944
+ for (const step3 of Array.isArray(data.steps) ? data.steps : []) {
27945
+ for (const call of Array.isArray(step3?.toolCalls) ? step3.toolCalls : []) {
27946
+ const name = call?.payload?.toolName;
27947
+ if (name) toolNames.add(name);
27948
+ }
27949
+ }
27950
+ return {
27951
+ text: data.text ?? "",
27952
+ finishReason: data.finishReason,
27953
+ ...data.usage !== void 0 ? {
27954
+ usage: data.usage
27955
+ } : {},
27956
+ ...toolNames.size ? {
27957
+ toolsUsed: [
27958
+ ...toolNames
27959
+ ]
27960
+ } : {},
27961
+ ...callerThreadId !== void 0 ? {
27962
+ threadId: callerThreadId
27963
+ } : {}
27964
+ };
27965
+ }
27966
+ function runSummary(r) {
27967
+ if (!r || typeof r !== "object") return {};
27968
+ const pick = [
27969
+ "workflowId",
27970
+ "workflowName",
27971
+ "status",
27972
+ "reason",
27973
+ "trigger",
27974
+ "createdAt",
27975
+ "startedAt",
27976
+ "completedAt"
27977
+ ];
27978
+ const out = {
27979
+ runId: r.runId ?? r.id
27980
+ };
27981
+ for (const k of pick) if (r[k] !== void 0) out[k] = r[k];
27982
+ return out;
27983
+ }
27089
27984
  var AgentsApiService;
27090
27985
  var init_agents_api_service = __esm({
27091
27986
  "src/api/agents.api.service.ts"() {
@@ -27105,7 +28000,9 @@ var init_agents_api_service = __esm({
27105
28000
  });
27106
28001
  if (body.identifier) query.set("identifier", body.identifier);
27107
28002
  const chatBody = this.toChatGenerateBody(body);
27108
- return this.httpPostCoreDrainRetry(`/chat/generate/${targetAgentId}?${query.toString()}`, chatBody, {});
28003
+ return this.httpPostCoreDrainRetry(`/chat/generate/${targetAgentId}?${query.toString()}`, chatBody, {}, typeof body.timeoutMs === "number" ? {
28004
+ timeoutMs: body.timeoutMs
28005
+ } : void 0);
27109
28006
  }
27110
28007
  /**
27111
28008
  * Sandbox overload: mirrors the `AI.generate` pattern where the simplified
@@ -27123,7 +28020,128 @@ var init_agents_api_service = __esm({
27123
28020
  if (!result.data) {
27124
28021
  throw new Error("Agent invocation failed: empty response");
27125
28022
  }
27126
- return typeof promptOrInput === "string" ? result.data.text ?? "" : result.data;
28023
+ if (typeof promptOrInput === "string") return result.data.text ?? "";
28024
+ const data = result.data;
28025
+ if (data?.type === "preprocessor_blocked") {
28026
+ throw Object.assign(new Error(data.text || "Agent invocation blocked by preprocessor"), {
28027
+ name: "AgentInvocationError",
28028
+ code: "PREPROCESSOR_BLOCKED",
28029
+ stage: "preprocess"
28030
+ });
28031
+ }
28032
+ if (data?.governanceBlock) {
28033
+ throw Object.assign(new Error(data.text || "Agent invocation blocked by governance"), {
28034
+ name: "AgentInvocationError",
28035
+ code: "GOVERNANCE_BLOCKED",
28036
+ stage: data.governanceBlock?.stage
28037
+ });
28038
+ }
28039
+ return toInvocationOutput(data, input.threadId);
28040
+ }
28041
+ /**
28042
+ * EM-WS2 — the offline (`lua test` / `lua dev`) twin of the `Agents.*`
28043
+ * supervision members. Read ops go to the developer REST routes with YOUR
28044
+ * developer credential (so they return what you can see, not what a
28045
+ * supervisor grant allows); the platform's projections are mirrored (env KEYS
28046
+ * only, Data only from the target's declared collections, logs without user
28047
+ * ids). Release ops (`versions.promote`, `persona.activate`) and
28048
+ * `versions.preview` are REFUSED offline: a local test must never change what a
28049
+ * live agent serves.
28050
+ */
28051
+ async superviseForSandbox(op, targetAgentId, args2 = {}) {
28052
+ const refuse = /* @__PURE__ */ __name((code, message) => {
28053
+ throw Object.assign(new Error(message), {
28054
+ name: "SupervisionError",
28055
+ code
28056
+ });
28057
+ }, "refuse");
28058
+ if (op === "versions.promote" || op === "persona.activate") {
28059
+ refuse("supervision_release_offline_refused", `${op} is refused offline: a local test never changes a live agent`);
28060
+ }
28061
+ if (op === "versions.preview" || op === "agents.list" || op === "agents.get" || op === "source.get") {
28062
+ refuse("supervision_unavailable_offline", `${op} is not available offline; run it on the platform`);
28063
+ }
28064
+ const id2 = targetAgentId ? encodeURIComponent(targetAgentId) : refuse("supervision_no_target", "A target agent id is required");
28065
+ const get = /* @__PURE__ */ __name(async (url) => {
28066
+ const res = await this.httpGet(url);
28067
+ if (!res.success) refuse("supervision_offline_error", res.error?.message || `GET ${url} failed`);
28068
+ return res.data;
28069
+ }, "get");
28070
+ const q = /* @__PURE__ */ __name((params) => {
28071
+ const sp = new URLSearchParams();
28072
+ for (const [k, v] of Object.entries(params)) if (v !== void 0 && v !== null && v !== "") sp.set(k, String(v));
28073
+ const s = sp.toString();
28074
+ return s ? `?${s}` : "";
28075
+ }, "q");
28076
+ switch (op) {
28077
+ case "logs": {
28078
+ const page = await get(`/developer/agents/${id2}/logs${q({
28079
+ limit: Math.min(Number(args2.limit) || 50, 100),
28080
+ logSource: args2.logSource
28081
+ })}`);
28082
+ const rows3 = Array.isArray(page?.logs) ? page.logs : [];
28083
+ return rows3.map((r) => ({
28084
+ timestamp: r.timestamp,
28085
+ ...r.subType ? {
28086
+ level: r.subType
28087
+ } : {},
28088
+ ...r.metadata?.logSource ? {
28089
+ logSource: r.metadata.logSource
28090
+ } : {},
28091
+ ...r.metadata?.primitiveName ? {
28092
+ primitiveName: r.metadata.primitiveName
28093
+ } : {},
28094
+ ...r.metadata?.toolName ? {
28095
+ toolName: r.metadata.toolName
28096
+ } : {}
28097
+ }));
28098
+ }
28099
+ case "runs.list": {
28100
+ const page = await get(`/workflows/${id2}/runs${q({
28101
+ limit: Math.min(Number(args2.limit) || 20, 50),
28102
+ status: args2.status
28103
+ })}`);
28104
+ return (Array.isArray(page?.items) ? page.items : []).map(runSummary);
28105
+ }
28106
+ case "runs.get":
28107
+ return runSummary(await get(`/workflows/${id2}/runs/${encodeURIComponent(String(args2.runId ?? ""))}`));
28108
+ case "versions.list":
28109
+ return get(`/developer/agents/${id2}/versions${q({
28110
+ limit: args2.limit
28111
+ })}`);
28112
+ case "versions.get":
28113
+ return get(`/developer/agents/${id2}/versions/${encodeURIComponent(String(args2.version))}`);
28114
+ case "versions.diff":
28115
+ return get(`/developer/agents/${id2}/versions/diff${q({
28116
+ from: args2.from,
28117
+ to: args2.to
28118
+ })}`);
28119
+ case "persona.versions":
28120
+ return get(`/developer/agents/${id2}/persona/versions`);
28121
+ case "source.list": {
28122
+ const manifest = await get(`/developer/agents/${id2}/backup/manifest`);
28123
+ const files = Array.isArray(manifest?.files) ? manifest.files : [];
28124
+ return {
28125
+ files: files.map((f) => ({
28126
+ path: f.relativePath,
28127
+ ...typeof f.size === "number" ? {
28128
+ size: f.size
28129
+ } : {}
28130
+ }))
28131
+ };
28132
+ }
28133
+ case "env.keys": {
28134
+ const env = await get(`/developer/agents/${id2}/env`);
28135
+ return {
28136
+ keys: Object.keys(env?.data ?? {}).sort()
28137
+ };
28138
+ }
28139
+ case "data.get":
28140
+ case "data.query":
28141
+ return refuse("supervision_unavailable_offline", `${op} is not available offline; run it on the platform`);
28142
+ default:
28143
+ return refuse("supervision_unknown_op", `Unknown supervision operation ${String(op)}`);
28144
+ }
27127
28145
  }
27128
28146
  toChatGenerateBody(body) {
27129
28147
  const messages = body.messages ? body.messages : [
@@ -27149,10 +28167,15 @@ var init_agents_api_service = __esm({
27149
28167
  } : {},
27150
28168
  ...body.clientContext !== void 0 ? {
27151
28169
  clientContext: body.clientContext
28170
+ } : {},
28171
+ ...body.model !== void 0 ? {
28172
+ model: body.model
27152
28173
  } : {}
27153
28174
  };
27154
28175
  }
27155
28176
  };
28177
+ __name(toInvocationOutput, "toInvocationOutput");
28178
+ __name(runSummary, "runSummary");
27156
28179
  }
27157
28180
  });
27158
28181
 
@@ -29203,6 +30226,9 @@ var init_mcp_server_handler = __esm({
29203
30226
  name: server.name,
29204
30227
  transport: server.config?.transport || "streamable-http"
29205
30228
  };
30229
+ if (server.description) {
30230
+ result.description = server.description;
30231
+ }
29206
30232
  if (server.config?.url !== void 0) {
29207
30233
  result.url = server.config.url;
29208
30234
  }
@@ -30995,17 +32021,34 @@ var PersonaApi = class extends HttpClient {
30995
32021
  return this.httpGet(`/developer/agents/${this.agentId}/persona/versions${statusParam}`, {});
30996
32022
  }
30997
32023
  /**
30998
- * Creates a new persona version
32024
+ * Creates a new persona version.
32025
+ *
32026
+ * PRO-2170: the route STAGES by default — creating a version does not change
32027
+ * what the agent serves. `options.publish` is sent only when the caller
32028
+ * passes it, so an omitted flag means "whatever the server's default is" and
32029
+ * an explicit `false` pins the stage-only intent on the wire (what `lua push`
32030
+ * sends, so a server that ever flips its default cannot silently publish a
32031
+ * push again). Activation is `deployVersion`.
32032
+ *
30999
32033
  * @param persona - The persona content (string or channel-aware object)
32034
+ * @param options.publish - `true` = create and serve in one call; `false` = stage only
31000
32035
  * @returns Promise resolving to an ApiResponse with the created version
31001
32036
  */
31002
- async createVersion(persona) {
32037
+ async createVersion(persona, options = {}) {
31003
32038
  return this.httpPost(`/developer/agents/${this.agentId}/persona/version`, {
31004
- persona
32039
+ persona,
32040
+ ...options.publish === void 0 ? {} : {
32041
+ publish: options.publish
32042
+ }
31005
32043
  }, {});
31006
32044
  }
31007
32045
  /**
31008
- * Deploys/activates a persona version to production
32046
+ * Deploys/activates a persona version to production.
32047
+ *
32048
+ * PRO-2170: this is the ONLY path that changes the persona the agent serves.
32049
+ * It re-points the agent, marks the version `published` and demotes the
32050
+ * previously-published one to `staged`.
32051
+ *
31009
32052
  * @param version - The version number to deploy
31010
32053
  * @returns Promise resolving to an ApiResponse with confirmation
31011
32054
  */
@@ -31025,9 +32068,15 @@ var PersonaApi = class extends HttpClient {
31025
32068
  return sorted[0];
31026
32069
  }
31027
32070
  /**
31028
- * Gets the latest published persona version (excludes drafts)
31029
- * This is the most recently pushed version, regardless of whether it's currently active.
31030
- * Use this for sync - code should match the latest push, not a rollback.
32071
+ * Gets the latest published persona version.
32072
+ *
32073
+ * PRO-2170 changed what this means. It used to be "the most recently pushed
32074
+ * version", because a push published every version it created. Now a push
32075
+ * STAGES, so `published` is the version production SERVES, and a local
32076
+ * persona ahead of it is genuine drift (`checkPersonaDrift`) — the same
32077
+ * reading as a pushed-but-not-activated skill. Use `getLatestVersion` (all
32078
+ * statuses) when you want the most recent push instead.
32079
+ *
31031
32080
  * @returns Promise resolving to the latest published PersonaVersion or null if none exist
31032
32081
  */
31033
32082
  async getLatestPublishedVersion() {
@@ -31790,7 +32839,9 @@ var AgentHandler = class {
31790
32839
  }
31791
32840
  async pushPersona(ctx, persona) {
31792
32841
  const personaApi = new PersonaApi(BASE_URLS.API, ctx.apiKey, ctx.agentId);
31793
- const result = await personaApi.createVersion(persona);
32842
+ const result = await personaApi.createVersion(persona, {
32843
+ publish: false
32844
+ });
31794
32845
  return {
31795
32846
  success: result.success,
31796
32847
  version: result.data?.version
@@ -33252,7 +34303,7 @@ async function syncCommand(options) {
33252
34303
  try {
33253
34304
  writeProgress("\u{1F504} Compiling to get latest local state...");
33254
34305
  await compileCommand({
33255
- serverSync: true
34306
+ serverSync: !options?.check
33256
34307
  });
33257
34308
  writeProgress("\u{1F504} Checking for drift between server and local code...");
33258
34309
  const { agentId, apiKey } = await initializeCommand({
@@ -33537,6 +34588,7 @@ async function executePushMode(context, drift, primitiveDrift) {
33537
34588
  const result = await agentHandler.pushPersona(context, drift.persona.localPersona);
33538
34589
  if (result.success) {
33539
34590
  writeSuccess(`\u2705 Persona version ${result.version} created on server`);
34591
+ writeInfo(` Staged, NOT activated \u2014 activate it with \`lua deploy persona --set-version ${result.version}\`.`);
33540
34592
  } else {
33541
34593
  console.error("\u274C Failed to push persona");
33542
34594
  syncFullySucceeded = false;
@@ -33745,6 +34797,7 @@ async function handlePersonaDriftInteractive(context, drift) {
33745
34797
  const result = await agentHandler.pushPersona(context, drift.localPersona);
33746
34798
  if (result.success) {
33747
34799
  writeSuccess(`\u2705 Persona version ${result.version} created on server`);
34800
+ writeInfo(` Staged, NOT activated \u2014 activate it with \`lua deploy persona --set-version ${result.version}\`.`);
33748
34801
  } else {
33749
34802
  console.error("\u274C Failed to push persona");
33750
34803
  }
@@ -34358,7 +35411,7 @@ var JobHandler = class extends BaseVersionedHandler {
34358
35411
  };
34359
35412
  }
34360
35413
  /**
34361
- * Override to include schedule, timeout, retry fields in push data.
35414
+ * Override to include schedule, timeout, retry (and, when declared, health) fields in push data.
34362
35415
  */
34363
35416
  buildPushData(primitive, compressedCode, codeS3Hash) {
34364
35417
  const job = primitive;
@@ -34373,7 +35426,11 @@ var JobHandler = class extends BaseVersionedHandler {
34373
35426
  schedule: job.schedule,
34374
35427
  timeout: job.timeout,
34375
35428
  retry: job.retry,
34376
- metadata: job.metadata
35429
+ metadata: job.metadata,
35430
+ // EM-WS10: only when declared, so an undeclared push stays byte-identical.
35431
+ ...job.health ? {
35432
+ health: job.health
35433
+ } : {}
34377
35434
  };
34378
35435
  }
34379
35436
  };
@@ -35028,6 +36085,105 @@ init_workflow_api_service();
35028
36085
  init_artifact_loader();
35029
36086
  init_bundle_upload();
35030
36087
 
36088
+ // ../sandbox-runtime/dist/supervision-api.mjs
36089
+ var __defProp7 = Object.defineProperty;
36090
+ var __name7 = /* @__PURE__ */ __name((target, value3) => __defProp7(target, "name", { value: value3, configurable: true }), "__name");
36091
+ function typedError(code, message) {
36092
+ return Object.assign(new Error(message), {
36093
+ name: "SupervisionError",
36094
+ code
36095
+ });
36096
+ }
36097
+ __name(typedError, "typedError");
36098
+ __name7(typedError, "typedError");
36099
+ function requireExpectActive(opts, what) {
36100
+ const expectActive = opts?.expectActive;
36101
+ if (expectActive === null) return null;
36102
+ if (typeof expectActive === "number" && Number.isInteger(expectActive) && expectActive > 0) return expectActive;
36103
+ throw typedError("supervision_expect_active_required", `${what} requires { expectActive } \u2014 the version you expect to be active now (null = none)`);
36104
+ }
36105
+ __name(requireExpectActive, "requireExpectActive");
36106
+ __name7(requireExpectActive, "requireExpectActive");
36107
+ function buildSupervisionAgentsApi(call) {
36108
+ return {
36109
+ /** Agents of the caller's own organization, with the supervision actions the caller holds on each. */
36110
+ list: /* @__PURE__ */ __name7(() => call("agents.list"), "list"),
36111
+ /** One agent of the caller's organization (not found = other org or no such agent). */
36112
+ get: /* @__PURE__ */ __name7((agentId) => call("agents.get", agentId), "get"),
36113
+ /** Recent execution logs of a supervised agent (metadata + message, no user ids). */
36114
+ logs: /* @__PURE__ */ __name7((agentId, opts = {}) => call("logs", agentId, {
36115
+ ...opts
36116
+ }), "logs"),
36117
+ runs: /* @__PURE__ */ __name7((agentId) => ({
36118
+ list: /* @__PURE__ */ __name7((opts = {}) => call("runs.list", agentId, {
36119
+ ...opts
36120
+ }), "list"),
36121
+ get: /* @__PURE__ */ __name7((runId) => call("runs.get", agentId, {
36122
+ runId
36123
+ }), "get")
36124
+ }), "runs"),
36125
+ /** Read-only, and only the collections the org admin named on the supervision grant. */
36126
+ data: /* @__PURE__ */ __name7((agentId) => ({
36127
+ get: /* @__PURE__ */ __name7((collection, entryId) => call("data.get", agentId, {
36128
+ collection,
36129
+ entryId
36130
+ }), "get"),
36131
+ query: /* @__PURE__ */ __name7((collection, filter, opts = {}) => call("data.query", agentId, {
36132
+ collection,
36133
+ ...filter ? {
36134
+ filter
36135
+ } : {},
36136
+ ...opts
36137
+ }), "query")
36138
+ }), "data"),
36139
+ versions: /* @__PURE__ */ __name7((agentId) => ({
36140
+ list: /* @__PURE__ */ __name7((opts = {}) => call("versions.list", agentId, {
36141
+ ...opts
36142
+ }), "list"),
36143
+ get: /* @__PURE__ */ __name7((version) => call("versions.get", agentId, {
36144
+ version
36145
+ }), "get"),
36146
+ diff: /* @__PURE__ */ __name7((from, to) => call("versions.diff", agentId, {
36147
+ from,
36148
+ to
36149
+ }), "diff"),
36150
+ /** Chat a staged version. No tools run unless `opts.toolScope.skillIds` allowlists them. */
36151
+ preview: /* @__PURE__ */ __name7((version, prompt, opts = {}) => call("versions.preview", agentId, {
36152
+ version,
36153
+ prompt,
36154
+ ...opts.toolScope ? {
36155
+ toolScope: opts.toolScope
36156
+ } : {}
36157
+ }), "preview"),
36158
+ /** Make `version` live. Compare-and-swap: refused unless `expectActive` is the live version. */
36159
+ promote: /* @__PURE__ */ __name7(async (version, opts) => call("versions.promote", agentId, {
36160
+ version,
36161
+ expectActive: requireExpectActive(opts, "versions.promote")
36162
+ }), "promote")
36163
+ }), "versions"),
36164
+ persona: /* @__PURE__ */ __name7((agentId) => ({
36165
+ versions: /* @__PURE__ */ __name7(() => call("persona.versions", agentId), "versions"),
36166
+ /** Serve persona `version`. Compare-and-swap on the served persona version. */
36167
+ activate: /* @__PURE__ */ __name7(async (version, opts) => call("persona.activate", agentId, {
36168
+ version,
36169
+ expectActive: requireExpectActive(opts, "persona.activate")
36170
+ }), "activate")
36171
+ }), "persona"),
36172
+ source: /* @__PURE__ */ __name7((agentId) => ({
36173
+ list: /* @__PURE__ */ __name7(() => call("source.list", agentId), "list"),
36174
+ get: /* @__PURE__ */ __name7((path26) => call("source.get", agentId, {
36175
+ path: path26
36176
+ }), "get")
36177
+ }), "source"),
36178
+ /** Environment variable NAMES only — values are never returned. */
36179
+ env: /* @__PURE__ */ __name7((agentId) => ({
36180
+ keys: /* @__PURE__ */ __name7(() => call("env.keys", agentId), "keys")
36181
+ }), "env")
36182
+ };
36183
+ }
36184
+ __name(buildSupervisionAgentsApi, "buildSupervisionAgentsApi");
36185
+ __name7(buildSupervisionAgentsApi, "buildSupervisionAgentsApi");
36186
+
35031
36187
  // src/utils/sandbox.ts
35032
36188
  init_dist4();
35033
36189
  import vm4 from "vm";
@@ -35148,8 +36304,8 @@ import path19 from "path";
35148
36304
  import { spawn as nodeSpawn } from "child_process";
35149
36305
  import { accessSync, constants as fsConstants, realpathSync, statSync as statSync5 } from "fs";
35150
36306
  import path18 from "path";
35151
- var __defProp7 = Object.defineProperty;
35152
- var __name7 = /* @__PURE__ */ __name((target, value3) => __defProp7(target, "name", { value: value3, configurable: true }), "__name");
36307
+ var __defProp8 = Object.defineProperty;
36308
+ var __name8 = /* @__PURE__ */ __name((target, value3) => __defProp8(target, "name", { value: value3, configurable: true }), "__name");
35153
36309
  var WORKFLOW_EXEC_BINARIES = Object.freeze([
35154
36310
  "git",
35155
36311
  "gh",
@@ -35173,7 +36329,7 @@ var WorkflowExecError = class extends Error {
35173
36329
  __name(this, "WorkflowExecError");
35174
36330
  }
35175
36331
  static {
35176
- __name7(this, "WorkflowExecError");
36332
+ __name8(this, "WorkflowExecError");
35177
36333
  }
35178
36334
  code;
35179
36335
  reason;
@@ -35207,7 +36363,7 @@ function isWorkflowExecError(err) {
35207
36363
  return !!e && typeof e === "object" && e.name === "ExecError" && typeof e.code === "string";
35208
36364
  }
35209
36365
  __name(isWorkflowExecError, "isWorkflowExecError");
35210
- __name7(isWorkflowExecError, "isWorkflowExecError");
36366
+ __name8(isWorkflowExecError, "isWorkflowExecError");
35211
36367
  function workflowExecRefusal(reason, detail, argv) {
35212
36368
  return new WorkflowExecError("EXEC_REFUSED", `[Lua] exec refused: ${detail} (EXEC_REFUSED/${reason})`, {
35213
36369
  reason,
@@ -35217,7 +36373,7 @@ function workflowExecRefusal(reason, detail, argv) {
35217
36373
  });
35218
36374
  }
35219
36375
  __name(workflowExecRefusal, "workflowExecRefusal");
35220
- __name7(workflowExecRefusal, "workflowExecRefusal");
36376
+ __name8(workflowExecRefusal, "workflowExecRefusal");
35221
36377
  var refused = workflowExecRefusal;
35222
36378
  var ALLOWLIST_TEXT = WORKFLOW_EXEC_BINARIES.join(", ");
35223
36379
  function parseCommandTemplate(template3, values) {
@@ -35228,13 +36384,13 @@ function parseCommandTemplate(template3, values) {
35228
36384
  const argv = [];
35229
36385
  let current = null;
35230
36386
  let quote = null;
35231
- const flush = /* @__PURE__ */ __name7(() => {
36387
+ const flush = /* @__PURE__ */ __name8(() => {
35232
36388
  if (current !== null) {
35233
36389
  argv.push(current);
35234
36390
  current = null;
35235
36391
  }
35236
36392
  }, "flush");
35237
- const scalar = /* @__PURE__ */ __name7((v, at) => {
36393
+ const scalar = /* @__PURE__ */ __name8((v, at) => {
35238
36394
  if (typeof v === "string") return v;
35239
36395
  if (typeof v === "number" && Number.isFinite(v)) return String(v);
35240
36396
  if (typeof v === "boolean") return String(v);
@@ -35295,7 +36451,7 @@ function parseCommandTemplate(template3, values) {
35295
36451
  return argv;
35296
36452
  }
35297
36453
  __name(parseCommandTemplate, "parseCommandTemplate");
35298
- __name7(parseCommandTemplate, "parseCommandTemplate");
36454
+ __name8(parseCommandTemplate, "parseCommandTemplate");
35299
36455
  function validateWorkflowExecArgv(argv) {
35300
36456
  if (!Array.isArray(argv)) throw refused("argv_invalid", 'argv must be an array of strings \u2014 exec(["git", "status"])');
35301
36457
  if (argv.length === 0) throw refused("argv_empty", "the command is empty");
@@ -35317,7 +36473,7 @@ function validateWorkflowExecArgv(argv) {
35317
36473
  ];
35318
36474
  }
35319
36475
  __name(validateWorkflowExecArgv, "validateWorkflowExecArgv");
35320
- __name7(validateWorkflowExecArgv, "validateWorkflowExecArgv");
36476
+ __name8(validateWorkflowExecArgv, "validateWorkflowExecArgv");
35321
36477
  function resolveWorkflowExecBinary(name, pathDirs) {
35322
36478
  if (typeof name !== "string" || name.length === 0) throw refused("argv_invalid", "argv[0] must name a binary");
35323
36479
  if (name.includes("/") || name.includes("\\") || name.startsWith(".")) {
@@ -35346,12 +36502,12 @@ function resolveWorkflowExecBinary(name, pathDirs) {
35346
36502
  ]);
35347
36503
  }
35348
36504
  __name(resolveWorkflowExecBinary, "resolveWorkflowExecBinary");
35349
- __name7(resolveWorkflowExecBinary, "resolveWorkflowExecBinary");
36505
+ __name8(resolveWorkflowExecBinary, "resolveWorkflowExecBinary");
35350
36506
  function within(root, p) {
35351
36507
  return p === root || p.startsWith(root.endsWith(path18.sep) ? root : root + path18.sep);
35352
36508
  }
35353
36509
  __name(within, "within");
35354
- __name7(within, "within");
36510
+ __name8(within, "within");
35355
36511
  function confineWorkflowExecCwd(root, cwd) {
35356
36512
  if (typeof root !== "string" || root.length === 0) throw refused("workspace_unavailable", "the step has no workspace");
35357
36513
  let rootReal;
@@ -35385,7 +36541,7 @@ function confineWorkflowExecCwd(root, cwd) {
35385
36541
  return abs;
35386
36542
  }
35387
36543
  __name(confineWorkflowExecCwd, "confineWorkflowExecCwd");
35388
- __name7(confineWorkflowExecCwd, "confineWorkflowExecCwd");
36544
+ __name8(confineWorkflowExecCwd, "confineWorkflowExecCwd");
35389
36545
  var RESERVED_ENV_KEY = /^(LUA_|LD_|DYLD_|GIT_|GH_|GITHUB_)|^(PATH|HOME|NODE_OPTIONS|BASH_ENV|ENV|TZ)$|_PROXY$/i;
35390
36546
  function checkWorkflowExecEnv(env) {
35391
36547
  if (env === void 0) return {};
@@ -35403,7 +36559,7 @@ function checkWorkflowExecEnv(env) {
35403
36559
  return out;
35404
36560
  }
35405
36561
  __name(checkWorkflowExecEnv, "checkWorkflowExecEnv");
35406
- __name7(checkWorkflowExecEnv, "checkWorkflowExecEnv");
36562
+ __name8(checkWorkflowExecEnv, "checkWorkflowExecEnv");
35407
36563
  var WORKFLOW_EXEC_GIT_DENIED_SUBCOMMANDS = Object.freeze([
35408
36564
  "push-mirror",
35409
36565
  "daemon",
@@ -35433,7 +36589,7 @@ function gitOptionMatches(arg, opt) {
35433
36589
  return opt.length === 2 && arg.length > 2 && arg.startsWith(opt);
35434
36590
  }
35435
36591
  __name(gitOptionMatches, "gitOptionMatches");
35436
- __name7(gitOptionMatches, "gitOptionMatches");
36592
+ __name8(gitOptionMatches, "gitOptionMatches");
35437
36593
  var GIT_PUSH_FORBIDDEN_FLAG = /^(--mirror|--delete|-d|-f|--force|--force-with-lease(=.*)?|--force-if-includes|--prune|--all|--tags)$/;
35438
36594
  function checkWorkflowExecGitArgv(argv, opts = {}) {
35439
36595
  if (argv[0] !== "git") return {};
@@ -35476,9 +36632,9 @@ function checkWorkflowExecGitArgv(argv, opts = {}) {
35476
36632
  };
35477
36633
  }
35478
36634
  __name(checkWorkflowExecGitArgv, "checkWorkflowExecGitArgv");
35479
- __name7(checkWorkflowExecGitArgv, "checkWorkflowExecGitArgv");
36635
+ __name8(checkWorkflowExecGitArgv, "checkWorkflowExecGitArgv");
35480
36636
  function formatWorkflowExecArgv(argv, max = WORKFLOW_EXEC_LOG_ARGV_MAX) {
35481
- const q = /* @__PURE__ */ __name7((a) => {
36637
+ const q = /* @__PURE__ */ __name8((a) => {
35482
36638
  const s = String(a);
35483
36639
  return s.length > 0 && /^[A-Za-z0-9_@%+=:,./-]+$/.test(s) ? s : `'${s.replace(/'/g, "'\\''")}'`;
35484
36640
  }, "q");
@@ -35486,7 +36642,7 @@ function formatWorkflowExecArgv(argv, max = WORKFLOW_EXEC_LOG_ARGV_MAX) {
35486
36642
  return line.length > max ? `${line.slice(0, max)}\u2026` : line;
35487
36643
  }
35488
36644
  __name(formatWorkflowExecArgv, "formatWorkflowExecArgv");
35489
- __name7(formatWorkflowExecArgv, "formatWorkflowExecArgv");
36645
+ __name8(formatWorkflowExecArgv, "formatWorkflowExecArgv");
35490
36646
  function spawnWorkflowExec(o) {
35491
36647
  const spawnFn = o.spawnImpl ?? nodeSpawn;
35492
36648
  const max = o.outputMaxBytes ?? WORKFLOW_EXEC_OUTPUT_MAX_BYTES;
@@ -35521,7 +36677,7 @@ function spawnWorkflowExec(o) {
35521
36677
  let settled = false;
35522
36678
  let killTimer;
35523
36679
  let wallTimer;
35524
- const collect2 = /* @__PURE__ */ __name7((stream) => {
36680
+ const collect2 = /* @__PURE__ */ __name8((stream) => {
35525
36681
  const chunks = [];
35526
36682
  let bytes = 0;
35527
36683
  stream?.on("data", (c) => {
@@ -35544,7 +36700,7 @@ function spawnWorkflowExec(o) {
35544
36700
  }, "collect");
35545
36701
  const stdout = collect2(child.stdout);
35546
36702
  const stderr = collect2(child.stderr);
35547
- const killTree = /* @__PURE__ */ __name7((sig) => {
36703
+ const killTree = /* @__PURE__ */ __name8((sig) => {
35548
36704
  const pid = child.pid;
35549
36705
  if (!pid) return;
35550
36706
  try {
@@ -35553,7 +36709,7 @@ function spawnWorkflowExec(o) {
35553
36709
  } catch {
35554
36710
  }
35555
36711
  }, "killTree");
35556
- const end = /* @__PURE__ */ __name7(() => {
36712
+ const end = /* @__PURE__ */ __name8(() => {
35557
36713
  if (settled || timedOut) return;
35558
36714
  timedOut = true;
35559
36715
  killTree("SIGTERM");
@@ -35564,7 +36720,7 @@ function spawnWorkflowExec(o) {
35564
36720
  }, grace);
35565
36721
  killTimer.unref?.();
35566
36722
  }, "end");
35567
- const cleanup = /* @__PURE__ */ __name7(() => {
36723
+ const cleanup = /* @__PURE__ */ __name8(() => {
35568
36724
  if (wallTimer) clearTimeout(wallTimer);
35569
36725
  if (killTimer) clearTimeout(killTimer);
35570
36726
  o.signal?.removeEventListener("abort", end);
@@ -35598,7 +36754,7 @@ function spawnWorkflowExec(o) {
35598
36754
  });
35599
36755
  }
35600
36756
  __name(spawnWorkflowExec, "spawnWorkflowExec");
35601
- __name7(spawnWorkflowExec, "spawnWorkflowExec");
36757
+ __name8(spawnWorkflowExec, "spawnWorkflowExec");
35602
36758
  async function runWorkflowExec(o) {
35603
36759
  const argv = validateWorkflowExecArgv(o.request.argv);
35604
36760
  const file = resolveWorkflowExecBinary(argv[0], o.pathDirs);
@@ -35644,7 +36800,7 @@ async function runWorkflowExec(o) {
35644
36800
  });
35645
36801
  }
35646
36802
  __name(runWorkflowExec, "runWorkflowExec");
35647
- __name7(runWorkflowExec, "runWorkflowExec");
36803
+ __name8(runWorkflowExec, "runWorkflowExec");
35648
36804
  function createWorkflowExecQueue() {
35649
36805
  let tail = Promise.resolve();
35650
36806
  return (task) => {
@@ -35654,7 +36810,7 @@ function createWorkflowExecQueue() {
35654
36810
  };
35655
36811
  }
35656
36812
  __name(createWorkflowExecQueue, "createWorkflowExecQueue");
35657
- __name7(createWorkflowExecQueue, "createWorkflowExecQueue");
36813
+ __name8(createWorkflowExecQueue, "createWorkflowExecQueue");
35658
36814
  function stderrTail(s) {
35659
36815
  const t = s.trim();
35660
36816
  if (!t) return "";
@@ -35662,9 +36818,9 @@ function stderrTail(s) {
35662
36818
  return `: ${tail.replace(/\s+/g, " ")}`;
35663
36819
  }
35664
36820
  __name(stderrTail, "stderrTail");
35665
- __name7(stderrTail, "stderrTail");
36821
+ __name8(stderrTail, "stderrTail");
35666
36822
  function buildWorkflowExecApi(run) {
35667
- const call = /* @__PURE__ */ __name7(async (req, strict) => {
36823
+ const call = /* @__PURE__ */ __name8(async (req, strict) => {
35668
36824
  const out = await run(req);
35669
36825
  if (out.timedOut) {
35670
36826
  throw new WorkflowExecError("EXEC_TIMEOUT", `[Lua] ${formatWorkflowExecArgv(out.argv)} did not finish within its wall (${out.durationMs} ms) and was killed (EXEC_TIMEOUT)`, out);
@@ -35674,7 +36830,7 @@ function buildWorkflowExecApi(run) {
35674
36830
  }
35675
36831
  return out;
35676
36832
  }, "call");
35677
- const request2 = /* @__PURE__ */ __name7((argv, opts) => {
36833
+ const request2 = /* @__PURE__ */ __name8((argv, opts) => {
35678
36834
  const o = opts && typeof opts === "object" ? opts : {};
35679
36835
  return {
35680
36836
  argv,
@@ -35683,9 +36839,9 @@ function buildWorkflowExecApi(run) {
35683
36839
  env: o.env
35684
36840
  };
35685
36841
  }, "request");
35686
- const exec = /* @__PURE__ */ __name7((argv, opts) => call(request2(argv, opts), false), "exec");
36842
+ const exec = /* @__PURE__ */ __name8((argv, opts) => call(request2(argv, opts), false), "exec");
35687
36843
  exec.strict = (argv, opts) => call(request2(argv, opts), true);
35688
- const $ = /* @__PURE__ */ __name7(async (strings, ...values) => call({
36844
+ const $ = /* @__PURE__ */ __name8(async (strings, ...values) => call({
35689
36845
  argv: parseCommandTemplate(strings, values)
35690
36846
  }, false), "$");
35691
36847
  $.strict = async (strings, ...values) => call({
@@ -35697,16 +36853,16 @@ function buildWorkflowExecApi(run) {
35697
36853
  };
35698
36854
  }
35699
36855
  __name(buildWorkflowExecApi, "buildWorkflowExecApi");
35700
- __name7(buildWorkflowExecApi, "buildWorkflowExecApi");
36856
+ __name8(buildWorkflowExecApi, "buildWorkflowExecApi");
35701
36857
  function unavailableWorkflowExecApi(why) {
35702
- const reject = /* @__PURE__ */ __name7(async () => {
36858
+ const reject = /* @__PURE__ */ __name8(async () => {
35703
36859
  throw new WorkflowExecError("EXEC_UNAVAILABLE", `[Lua] ctx.exec is not available here: ${why} (EXEC_UNAVAILABLE)`);
35704
36860
  }, "reject");
35705
36861
  const exec = Object.assign(() => reject(), {
35706
- strict: /* @__PURE__ */ __name7(() => reject(), "strict")
36862
+ strict: /* @__PURE__ */ __name8(() => reject(), "strict")
35707
36863
  });
35708
36864
  const $ = Object.assign(() => reject(), {
35709
- strict: /* @__PURE__ */ __name7(() => reject(), "strict")
36865
+ strict: /* @__PURE__ */ __name8(() => reject(), "strict")
35710
36866
  });
35711
36867
  return {
35712
36868
  exec,
@@ -35714,7 +36870,7 @@ function unavailableWorkflowExecApi(why) {
35714
36870
  };
35715
36871
  }
35716
36872
  __name(unavailableWorkflowExecApi, "unavailableWorkflowExecApi");
35717
- __name7(unavailableWorkflowExecApi, "unavailableWorkflowExecApi");
36873
+ __name8(unavailableWorkflowExecApi, "unavailableWorkflowExecApi");
35718
36874
 
35719
36875
  // src/utils/workflow-exec.ts
35720
36876
  var WORKFLOW_LOCAL_EXEC_ENV_KEYS = [
@@ -37507,7 +38663,14 @@ function createSandbox(options) {
37507
38663
  const { getAgentsInstance: getAgentsInstance2 } = await Promise.resolve().then(() => (init_lazy_instances(), lazy_instances_exports));
37508
38664
  const agents = await getAgentsInstance2();
37509
38665
  return agents.invokeForSandbox(targetAgentId, promptOrInput);
37510
- }, "invoke")
38666
+ }, "invoke"),
38667
+ // EM-WS2 — supervision members, offline twin (reads via your developer
38668
+ // credential; release ops and preview are refused offline).
38669
+ ...buildSupervisionAgentsApi(async (op, targetAgentId, args2) => {
38670
+ const { getAgentsInstance: getAgentsInstance2 } = await Promise.resolve().then(() => (init_lazy_instances(), lazy_instances_exports));
38671
+ const agents = await getAgentsInstance2();
38672
+ return agents.superviseForSandbox(op, targetAgentId, args2);
38673
+ })
37511
38674
  },
37512
38675
  // Unified.to raw provider passthrough (PRO-209). Proxied via the same
37513
38676
  // bearer-auth developer route the api-exports `Integrations` namespace
@@ -38236,6 +39399,10 @@ var WorkflowHandler = class extends BaseVersionedHandler {
38236
39399
  ...wf.backfillOnEnable ? {
38237
39400
  backfillOnEnable: wf.backfillOnEnable
38238
39401
  } : {},
39402
+ // EM-WS10: only when declared, so an undeclared push stays byte-identical (publish then clears any stale one).
39403
+ ...wf.health ? {
39404
+ health: wf.health
39405
+ } : {},
38239
39406
  ...wf.goal ? {
38240
39407
  goal: wf.goal
38241
39408
  } : {}
@@ -39706,8 +40873,8 @@ import vm5 from "vm";
39706
40873
  import { createHash as createHash7, randomUUID as randomUUID4 } from "crypto";
39707
40874
 
39708
40875
  // ../sandbox-runtime/dist/workflow-script-wrapper.mjs
39709
- var __defProp8 = Object.defineProperty;
39710
- var __name8 = /* @__PURE__ */ __name((target, value3) => __defProp8(target, "name", { value: value3, configurable: true }), "__name");
40876
+ var __defProp9 = Object.defineProperty;
40877
+ var __name9 = /* @__PURE__ */ __name((target, value3) => __defProp9(target, "name", { value: value3, configurable: true }), "__name");
39711
40878
  var WORKFLOW_SCRIPT_RUNTIME_KEY = "__luaWorkflowScriptRuntime";
39712
40879
  var WORKFLOW_SCRIPT_PROTOCOL_VERSION = 1;
39713
40880
  var WORKFLOW_SCRIPT_DEFAULT_CAPS = {
@@ -40042,18 +41209,18 @@ function computeWorkflowProtocolShipWindow(input) {
40042
41209
  };
40043
41210
  }
40044
41211
  __name(computeWorkflowProtocolShipWindow, "computeWorkflowProtocolShipWindow");
40045
- __name8(computeWorkflowProtocolShipWindow, "computeWorkflowProtocolShipWindow");
41212
+ __name9(computeWorkflowProtocolShipWindow, "computeWorkflowProtocolShipWindow");
40046
41213
  var WORKFLOW_SCRIPT_EFFORT_PROTOCOL_VERSION = 2;
40047
41214
  function scriptEffortForwardable(journalProtocolVersion) {
40048
41215
  return typeof journalProtocolVersion === "number" && journalProtocolVersion >= WORKFLOW_SCRIPT_EFFORT_PROTOCOL_VERSION;
40049
41216
  }
40050
41217
  __name(scriptEffortForwardable, "scriptEffortForwardable");
40051
- __name8(scriptEffortForwardable, "scriptEffortForwardable");
41218
+ __name9(scriptEffortForwardable, "scriptEffortForwardable");
40052
41219
  function workflowScriptReplaySource(journalProtocolVersion) {
40053
41220
  return WORKFLOW_SCRIPT_PROTOCOL_VERSIONS.includes(journalProtocolVersion) ? WORKFLOW_SCRIPT_REPLAY_SOURCES[journalProtocolVersion] : void 0;
40054
41221
  }
40055
41222
  __name(workflowScriptReplaySource, "workflowScriptReplaySource");
40056
- __name8(workflowScriptReplaySource, "workflowScriptReplaySource");
41223
+ __name9(workflowScriptReplaySource, "workflowScriptReplaySource");
40057
41224
  var HOST_BINDINGS = [
40058
41225
  "args",
40059
41226
  "agent",
@@ -40082,7 +41249,7 @@ function transformWorkflowScriptModule(script) {
40082
41249
  return script.replace(/^\s*export\s+const\s+meta\s*=/m, "const meta =");
40083
41250
  }
40084
41251
  __name(transformWorkflowScriptModule, "transformWorkflowScriptModule");
40085
- __name8(transformWorkflowScriptModule, "transformWorkflowScriptModule");
41252
+ __name9(transformWorkflowScriptModule, "transformWorkflowScriptModule");
40086
41253
  function buildWorkflowScriptWrapper(script, input) {
40087
41254
  const tick = input ?? {};
40088
41255
  const version = tick.journalProtocolVersion ?? WORKFLOW_SCRIPT_PROTOCOL_VERSION;
@@ -40132,7 +41299,7 @@ ${transformWorkflowScriptModule(script)}
40132
41299
  };
40133
41300
  }
40134
41301
  __name(buildWorkflowScriptWrapper, "buildWorkflowScriptWrapper");
40135
- __name8(buildWorkflowScriptWrapper, "buildWorkflowScriptWrapper");
41302
+ __name9(buildWorkflowScriptWrapper, "buildWorkflowScriptWrapper");
40136
41303
 
40137
41304
  // src/utils/workflow-script-replay.ts
40138
41305
  var ReplayRuntimeUnavailableError = class extends Error {
@@ -40568,7 +41735,7 @@ async function runWorkflowLocalFromProject(name, flags) {
40568
41735
  artefactsDir: flags.artefactsDir,
40569
41736
  workspaceDir: flags.workspace ? path23.resolve(flags.workspace) : void 0,
40570
41737
  env: parseEnvFlags(flags.env),
40571
- prompt: process.stdin.isTTY && !asJson ? promptForLocalDecision : void 0,
41738
+ prompt: process.stdin.isTTY && !asJson && !isCiModeEnabled() ? promptForLocalDecision : void 0,
40572
41739
  log: asJson ? void 0 : (line) => console.log(line)
40573
41740
  });
40574
41741
  } finally {
@@ -41561,6 +42728,7 @@ init_cli();
41561
42728
  init_command_utils();
41562
42729
  init_semver();
41563
42730
  init_auth_error();
42731
+ init_cli_error();
41564
42732
  init_constants();
41565
42733
 
41566
42734
  // src/api/agent-version.api.service.ts
@@ -42575,11 +43743,11 @@ function getDeployHint(type) {
42575
43743
  };
42576
43744
  }
42577
43745
  __name(getDeployHint, "getDeployHint");
42578
- function writePersonaServedHint(version) {
42579
- writeInfo(`\u{1F4A1} Persona v${version} is now served \u2014 the push published it and pointed the agent at it.`);
42580
- writeInfo(" Roll back with `lua deploy persona` (pick an earlier version) or `lua persona production deploy --persona-version <n>`.");
43746
+ function writePersonaStagedHint(version) {
43747
+ writeInfo(`\u{1F4A1} Persona v${version} staged \u2014 NOT activated. What the agent serves is unchanged.`);
43748
+ writeInfo(` Activate it with \`lua deploy persona --set-version ${version}\` (asks for confirmation first).`);
42581
43749
  }
42582
- __name(writePersonaServedHint, "writePersonaServedHint");
43750
+ __name(writePersonaStagedHint, "writePersonaStagedHint");
42583
43751
  async function promptVersionConfirmOrUpdate(currentVersion) {
42584
43752
  console.log(`
42585
43753
  Current version: ${currentVersion || "(none - first push)"}`);
@@ -42862,10 +44030,11 @@ async function pushCommand(type, cmdObj) {
42862
44030
  options.autoDeploy = false;
42863
44031
  }
42864
44032
  if (options.entityName && !type) {
42865
- console.log("\nUsage:");
42866
- console.log(" lua push skill --name mySkill --set-version 1.0.5 Push specific skill");
42867
- console.log(" lua push webhook --name myWebhook --set-version 2.0.0 Push specific webhook");
42868
- throw new Error("Type must be specified when using the --name option.");
44033
+ throw CliError.usage("Type must be specified when using the --name option.", [
44034
+ "Usage:",
44035
+ " lua push skill --name mySkill --set-version 1.0.5 Push specific skill",
44036
+ " lua push webhook --name myWebhook --set-version 2.0.0 Push specific webhook"
44037
+ ].join("\n"));
42869
44038
  }
42870
44039
  if (isStageAll) {
42871
44040
  return await pushAllCommand({
@@ -42878,10 +44047,11 @@ async function pushCommand(type, cmdObj) {
42878
44047
  }
42879
44048
  if (type === "all") {
42880
44049
  if (!options.force) {
42881
- console.log("\nUsage:");
42882
- console.log(" lua push all --force Push all components without prompts");
42883
- console.log(" lua push all --force --auto-deploy Push and deploy all to production");
42884
- throw new Error('The "all" type requires the --force flag');
44050
+ throw CliError.usage('The "all" type requires the --force flag', [
44051
+ "Usage:",
44052
+ " lua push all --force Push all components without prompts",
44053
+ " lua push all --force --auto-deploy Push and deploy all to production"
44054
+ ].join("\n"));
42885
44055
  }
42886
44056
  return await pushAllCommand({
42887
44057
  ...options,
@@ -43165,7 +44335,7 @@ Model: ${model}`);
43165
44335
  personaDeployWasAttempted = true;
43166
44336
  productionDeployedWithAutoDeploy = await deployPersonaVersionAfterPush(apiKey, agentId, result.persona.version, options.autoDeploy || false);
43167
44337
  } else {
43168
- writePersonaServedHint(result.persona.version);
44338
+ writePersonaStagedHint(result.persona.version);
43169
44339
  }
43170
44340
  }
43171
44341
  const personaAutoDeployFailed = Boolean(options.autoDeploy && personaDeployEligible && personaDeployWasAttempted && !productionDeployedWithAutoDeploy);
@@ -43479,7 +44649,7 @@ ${icon} Pushing ${items.length} ${handler.displayName}(s)...`);
43479
44649
  };
43480
44650
  }
43481
44651
  if (personaPushResult && !options.autoDeploy) {
43482
- writePersonaServedHint(personaPushResult.version);
44652
+ writePersonaStagedHint(personaPushResult.version);
43483
44653
  }
43484
44654
  if (toDeploy.length > 0) {
43485
44655
  writeProgress("\n\u{1F680} Deploying all pushed versions to production...");
@@ -43731,6 +44901,14 @@ function formatDeploySuccess(params) {
43731
44901
  return `\u2705 ${label2} "${name}" v${version} deployed successfully`;
43732
44902
  }
43733
44903
  __name(formatDeploySuccess, "formatDeploySuccess");
44904
+ function syncDeployedVersionToYaml(handler, name, deployedVersion, recordedVersion) {
44905
+ if (deployedVersion === recordedVersion) {
44906
+ return;
44907
+ }
44908
+ writeInfo(`\u{1F4DD} Updating YAML with deployed version: ${deployedVersion}`);
44909
+ handler.updateVersionInYaml(name, deployedVersion);
44910
+ }
44911
+ __name(syncDeployedVersionToYaml, "syncDeployedVersionToYaml");
43734
44912
  function deployAllExitCode(failedCount) {
43735
44913
  return failedCount > 0 ? CLI_EXIT.ERROR : void 0;
43736
44914
  }
@@ -43742,6 +44920,12 @@ init_skills_api_service();
43742
44920
  init_webhook_api_service();
43743
44921
  init_job_api_service();
43744
44922
  init_analytics();
44923
+ var SCOPED_PROMOTE_NOTICE = "\u2139\uFE0F For agents under versioning, `lua deploy` creates and promotes a new agent version scoped to this primitive; otherwise it goes live directly. For multi-primitive releases, `lua version promote <version>` remains the recommended flow.";
44924
+ var PERSONA_LABEL = "Persona";
44925
+ function pointerNotice(label2) {
44926
+ return `\u2139\uFE0F This updates the served ${label2} pointer now; it does not create an agent version. The next \`lua version promote\` resets it to whatever that version pins.`;
44927
+ }
44928
+ __name(pointerNotice, "pointerNotice");
43745
44929
  function normalizeVersion(v) {
43746
44930
  return {
43747
44931
  version: v.version,
@@ -43760,6 +44944,7 @@ var VERSIONED_DEPLOY_TYPES = [
43760
44944
  label: "Skill",
43761
44945
  emoji: "\u{1F6E0}\uFE0F",
43762
44946
  idField: "skillId",
44947
+ scoped: false,
43763
44948
  getVersions: /* @__PURE__ */ __name(async (apiKey, agentId, entityId) => {
43764
44949
  const api = new SkillApi(BASE_URLS.API, apiKey, agentId);
43765
44950
  const result = await api.getSkillVersions(entityId);
@@ -43772,6 +44957,7 @@ var VERSIONED_DEPLOY_TYPES = [
43772
44957
  label: "Webhook",
43773
44958
  emoji: "\u{1FA9D}",
43774
44959
  idField: "webhookId",
44960
+ scoped: true,
43775
44961
  getVersions: /* @__PURE__ */ __name(async (apiKey, agentId, entityId) => {
43776
44962
  const api = new WebhookApi(BASE_URLS.API, apiKey, agentId);
43777
44963
  const result = await api.getWebhookVersions(entityId);
@@ -43784,6 +44970,7 @@ var VERSIONED_DEPLOY_TYPES = [
43784
44970
  label: "Trigger",
43785
44971
  emoji: "\u26A1",
43786
44972
  idField: "triggerId",
44973
+ scoped: true,
43787
44974
  getVersions: /* @__PURE__ */ __name(async (apiKey, agentId, entityId) => {
43788
44975
  const api = new TriggerApi(BASE_URLS.API, apiKey, agentId);
43789
44976
  const result = await api.getTriggerVersions(entityId);
@@ -43796,6 +44983,7 @@ var VERSIONED_DEPLOY_TYPES = [
43796
44983
  label: "Job",
43797
44984
  emoji: "\u23F0",
43798
44985
  idField: "jobId",
44986
+ scoped: true,
43799
44987
  getVersions: /* @__PURE__ */ __name(async (apiKey, agentId, entityId) => {
43800
44988
  const api = new JobApi(BASE_URLS.API, apiKey, agentId);
43801
44989
  const result = await api.getJobVersions(entityId);
@@ -43808,6 +44996,7 @@ var VERSIONED_DEPLOY_TYPES = [
43808
44996
  label: "PreProcessor",
43809
44997
  emoji: "\u{1F4E5}",
43810
44998
  idField: "preprocessorId",
44999
+ scoped: true,
43811
45000
  getVersions: /* @__PURE__ */ __name(async (apiKey, agentId, entityId) => {
43812
45001
  const api = new PreProcessorApi(BASE_URLS.API, apiKey, agentId);
43813
45002
  const result = await api.getPreProcessorVersions(entityId);
@@ -43820,6 +45009,7 @@ var VERSIONED_DEPLOY_TYPES = [
43820
45009
  label: "PostProcessor",
43821
45010
  emoji: "\u{1F4E4}",
43822
45011
  idField: "postprocessorId",
45012
+ scoped: true,
43823
45013
  getVersions: /* @__PURE__ */ __name(async (apiKey, agentId, entityId) => {
43824
45014
  const api = new PostProcessorApi(BASE_URLS.API, apiKey, agentId);
43825
45015
  const result = await api.getPostProcessorVersions(entityId);
@@ -43898,13 +45088,14 @@ async function deployCommand(type, cmdObj) {
43898
45088
  selectedType = answer.type;
43899
45089
  }
43900
45090
  const apiKey = await requireAuthOrExit();
43901
- writeInfo("\u2139\uFE0F For agents under versioning, `lua deploy` creates and promotes a new agent version scoped to this primitive; otherwise it goes live directly. For multi-primitive releases, `lua version promote <version>` remains the recommended flow.");
43902
45091
  let personaDeployed = false;
43903
45092
  let versionedOutcome = null;
45093
+ let scopedPromoteNotice = false;
43904
45094
  if (selectedType === "persona") {
43905
45095
  personaDeployed = await deployPersonaVersion(apiKey, agentId, options);
43906
45096
  } else {
43907
45097
  const deployConfig = VERSIONED_DEPLOY_TYPES.find((dt) => dt.type === selectedType);
45098
+ scopedPromoteNotice = deployConfig.scoped;
43908
45099
  versionedOutcome = await deployVersionedPrimitive(deployConfig, config, apiKey, agentId, options);
43909
45100
  }
43910
45101
  trackEvent("cli_deploy_completed", {
@@ -43912,7 +45103,7 @@ async function deployCommand(type, cmdObj) {
43912
45103
  force_mode: options.force || false,
43913
45104
  entity_selected_by_name: !!options.name,
43914
45105
  version_selected_by_flag: !!options.version,
43915
- scoped_promote_notice: true
45106
+ scoped_promote_notice: scopedPromoteNotice
43916
45107
  });
43917
45108
  const deployed = selectedType === "persona" ? personaDeployed : versionedOutcome?.deployed ?? false;
43918
45109
  const hintPrintedAlready = selectedType !== "persona" && !!versionedOutcome?.hintPrinted;
@@ -43921,17 +45112,23 @@ async function deployCommand(type, cmdObj) {
43921
45112
  }
43922
45113
  if (selectedType === "webhook") {
43923
45114
  const webhookNameToken = versionedOutcome?.entityName || options.name?.trim() || "<webhook-name>";
45115
+ const triggerLine = webhookNameToken !== "<webhook-name>" ? {
45116
+ label: "Trigger:",
45117
+ command: `curl -X POST ${WEBHOOK_TRIGGER_BASE_URL}/${agentId}/${encodeURIComponent(webhookNameToken)}`
45118
+ } : {
45119
+ label: "Trigger:",
45120
+ command: "curl -X POST <URL from above>"
45121
+ };
43924
45122
  writeHintBlock({
43925
45123
  headline: "Webhook is live. Trigger it, then inspect logs:",
43926
45124
  lines: [
43927
- {
43928
- label: "Find URL:",
43929
- command: `lua webhooks view --webhook-name ${webhookNameToken}`
43930
- },
43931
- {
43932
- label: "Trigger:",
43933
- command: "curl -X POST <URL from above>"
43934
- },
45125
+ ...webhookNameToken === "<webhook-name>" ? [
45126
+ {
45127
+ label: "Find URL:",
45128
+ command: `lua webhooks view --webhook-name ${webhookNameToken}`
45129
+ }
45130
+ ] : [],
45131
+ triggerLine,
43935
45132
  {
43936
45133
  label: "Inspect:",
43937
45134
  command: buildLogsCommand({
@@ -43970,6 +45167,7 @@ async function deployCommand(type, cmdObj) {
43970
45167
  }
43971
45168
  __name(deployCommand, "deployCommand");
43972
45169
  async function deployVersionedPrimitive(deployConfig, config, apiKey, agentId, options) {
45170
+ writeInfo(deployConfig.scoped ? SCOPED_PROMOTE_NOTICE : pointerNotice(deployConfig.label));
43973
45171
  const entities = deployConfig.handler.getFromYaml(config);
43974
45172
  if (entities.length === 0) {
43975
45173
  writeInfo(`\u2139\uFE0F No ${deployConfig.label}s found in configuration. Nothing to deploy.`);
@@ -44060,10 +45258,7 @@ Available ${deployConfig.label}s:`);
44060
45258
  version: selectedVersion,
44061
45259
  agentVersion: result.agentVersion
44062
45260
  }));
44063
- if (selectedVersion !== selectedEntity.version) {
44064
- writeInfo(`\u{1F4DD} Updating YAML with deployed version: ${selectedVersion}`);
44065
- deployConfig.handler.updateVersionInYaml(selectedEntity.name, selectedVersion);
44066
- }
45261
+ syncDeployedVersionToYaml(deployConfig.handler, selectedEntity.name, selectedVersion, selectedEntity.version);
44067
45262
  if (deployConfig.type === "job") {
44068
45263
  writeHintBlock({
44069
45264
  headline: "Job is live. Trigger or wait for schedule, then inspect logs:",
@@ -44097,6 +45292,7 @@ Available ${deployConfig.label}s:`);
44097
45292
  __name(deployVersionedPrimitive, "deployVersionedPrimitive");
44098
45293
  async function deployPersonaVersion(apiKey, agentId, options) {
44099
45294
  const personaApi = new PersonaApi(BASE_URLS.API, apiKey, agentId);
45295
+ writeInfo(pointerNotice(PERSONA_LABEL));
44100
45296
  writeProgress("\u{1F504} Fetching persona versions...");
44101
45297
  const result = await personaApi.getVersions("all");
44102
45298
  const versions = result.data?.versions || [];
@@ -44125,7 +45321,9 @@ async function deployPersonaVersion(apiKey, agentId, options) {
44125
45321
  name: "version",
44126
45322
  message: "Select a persona version to deploy:",
44127
45323
  choices: sortedVersions.map((v) => ({
44128
- name: `v${v.version}${v.isCurrent ? " (CURRENT)" : ""} \u2014 ${new Date(v.createdDate).toLocaleDateString()}`,
45324
+ // PRO-2170: a push stages, so the list now contains versions that are
45325
+ // NOT served. Mark them, or the only clue is the absence of (CURRENT).
45326
+ name: `v${v.version}${v.isCurrent ? " (CURRENT)" : ""}${v.status === "staged" ? " (STAGED)" : v.status === "draft" ? " (DRAFT)" : ""} \u2014 ${new Date(v.createdDate).toLocaleDateString()}`,
44129
45327
  value: v.version
44130
45328
  }))
44131
45329
  }
@@ -44159,13 +45357,19 @@ async function deployAllCommand(_options) {
44159
45357
  validateSkillConfig(config);
44160
45358
  const apiKey = await requireAuthOrExit();
44161
45359
  const agentId = config.agent.agentId;
44162
- writeInfo("\u2139\uFE0F For agents under versioning, each deploy below creates and promotes an agent version scoped to that primitive. To switch everything atomically in one version instead, use `lua version create` + `lua version promote`.");
45360
+ const hasScopedEntity = VERSIONED_DEPLOY_TYPES.some((dt) => dt.scoped && dt.handler.getFromYaml(config).length > 0);
45361
+ if (hasScopedEntity) {
45362
+ writeInfo("\u2139\uFE0F For agents under versioning, each deploy below creates and promotes an agent version scoped to that primitive. To switch everything atomically in one version instead, use `lua version create` + `lua version promote`.");
45363
+ }
44163
45364
  let deployedCount = 0;
44164
45365
  let failedCount = 0;
44165
45366
  const failedItems = [];
44166
45367
  console.log("\n\u{1F680} Deploying latest versions of all primitives...\n");
44167
45368
  for (const deployConfig of VERSIONED_DEPLOY_TYPES) {
44168
45369
  const entities = deployConfig.handler.getFromYaml(config);
45370
+ if (!deployConfig.scoped && entities.length > 0) {
45371
+ writeInfo(pointerNotice(deployConfig.label));
45372
+ }
44169
45373
  for (const entity of entities) {
44170
45374
  const entityId = entity[deployConfig.idField];
44171
45375
  if (!entityId) {
@@ -44221,6 +45425,7 @@ async function deployAllCommand(_options) {
44221
45425
  const personaApi = new PersonaApi(BASE_URLS.API, apiKey, agentId);
44222
45426
  const latestPersona = await personaApi.getLatestVersion();
44223
45427
  if (latestPersona) {
45428
+ writeInfo(pointerNotice(PERSONA_LABEL));
44224
45429
  const deployResult = await personaApi.deployVersion(latestPersona.version);
44225
45430
  if (deployResult.success) {
44226
45431
  writeSuccess(` \u2705 Persona v${latestPersona.version} deployed`);
@@ -45086,6 +46291,7 @@ __name(parseMessageWithAttachments, "parseMessageWithAttachments");
45086
46291
 
45087
46292
  // src/commands/chat.ts
45088
46293
  init_command_utils();
46294
+ init_files();
45089
46295
  init_artifact_loader();
45090
46296
  init_types();
45091
46297
  init_analytics();
@@ -45386,12 +46592,13 @@ async function setupChatEnvironment(chatEnv, config) {
45386
46592
  await compileCommand({
45387
46593
  serverSync: "register-only"
45388
46594
  });
46595
+ const postCompileConfig = readYamlConfig() ?? config;
45389
46596
  const manifest = loadManifest();
45390
46597
  const skills = getPrimitivesByKind(manifest, PrimitiveKind.SKILL);
45391
46598
  let sandboxIds = {};
45392
46599
  if (skills.length > 0) {
45393
46600
  writeProgress("\u{1F504} Pushing skills to sandbox...");
45394
- sandboxIds = await pushSkillsToSandbox(chatEnv.apiKey, chatEnv.agentId, manifest, config, true);
46601
+ sandboxIds = await pushSkillsToSandbox(chatEnv.apiKey, chatEnv.agentId, manifest, postCompileConfig, true);
45395
46602
  if (Object.keys(sandboxIds).length > 0) {
45396
46603
  writeSuccess(`\u2705 Pushed ${Object.keys(sandboxIds).length} skills to sandbox`);
45397
46604
  } else {
@@ -45404,14 +46611,14 @@ async function setupChatEnvironment(chatEnv, config) {
45404
46611
  const postprocessors = getPrimitivesByKind(manifest, PrimitiveKind.POSTPROCESSOR);
45405
46612
  if (preprocessors.length > 0 || postprocessors.length > 0) {
45406
46613
  writeProgress("\u{1F504} Pushing processors to sandbox...");
45407
- const processorCounts = await pushProcessorsToSandbox(chatEnv.apiKey, chatEnv.agentId, manifest, config, true);
46614
+ const processorCounts = await pushProcessorsToSandbox(chatEnv.apiKey, chatEnv.agentId, manifest, postCompileConfig, true);
45408
46615
  if (processorCounts.preprocessors > 0 || processorCounts.postprocessors > 0) {
45409
46616
  writeSuccess(`\u2705 Pushed ${processorCounts.preprocessors} preprocessor(s) and ${processorCounts.postprocessors} postprocessor(s) to sandbox`);
45410
46617
  }
45411
46618
  }
45412
- chatEnv.yamlConfig = config;
45413
- chatEnv.preprocessorOverrides = await getAllSandboxPreProcessorIds(config);
45414
- chatEnv.postprocessorOverrides = await getAllSandboxPostProcessorIds(config);
46619
+ chatEnv.yamlConfig = postCompileConfig;
46620
+ chatEnv.preprocessorOverrides = await getAllSandboxPreProcessorIds(postCompileConfig);
46621
+ chatEnv.postprocessorOverrides = await getAllSandboxPostProcessorIds(postCompileConfig);
45415
46622
  chatEnv.persona = getAgentPersona() ?? void 0;
45416
46623
  }
45417
46624
  __name(setupChatEnvironment, "setupChatEnvironment");
@@ -46434,6 +47641,12 @@ init_compiler2();
46434
47641
  init_artifact_loader();
46435
47642
  init_analytics();
46436
47643
  init_cli_error();
47644
+ function versionStatusMarker(status) {
47645
+ if (status === "draft") return "[DRAFT]";
47646
+ if (status === "staged") return "[STAGED]";
47647
+ return "";
47648
+ }
47649
+ __name(versionStatusMarker, "versionStatusMarker");
46437
47650
  async function personaCommand(env, action, cmdObj) {
46438
47651
  return withErrorHandling(async () => {
46439
47652
  const options = {
@@ -46472,7 +47685,8 @@ async function personaCommand(env, action, cmdObj) {
46472
47685
  apiKey
46473
47686
  };
46474
47687
  if (selectedEnvironment === "sandbox") {
46475
- if (action === "view") {
47688
+ const normalizedAction = action ? validateOrSuggest("persona.action", action) : void 0;
47689
+ if (normalizedAction === "view") {
46476
47690
  const currentPersona = flattenPersonaTextAll(getAgentPersona());
46477
47691
  if (currentPersona.trim()) {
46478
47692
  console.log(currentPersona);
@@ -46481,6 +47695,16 @@ async function personaCommand(env, action, cmdObj) {
46481
47695
  }
46482
47696
  return;
46483
47697
  }
47698
+ if (normalizedAction === "versions") {
47699
+ writeProgress("\u{1F504} Loading persona versions...");
47700
+ const versions = await fetchVersionsCore(context);
47701
+ if (!versions) throw new Error("Failed to fetch persona versions");
47702
+ displayVersionsCore(versions);
47703
+ return;
47704
+ }
47705
+ if (normalizedAction) {
47706
+ throw CliError.usage(`Sandbox persona does not support action "${normalizedAction}"`, "Usage: lua persona sandbox view | lua persona sandbox versions");
47707
+ }
46484
47708
  await manageSandboxPersonaInteractive(context);
46485
47709
  } else {
46486
47710
  if (action) {
@@ -46550,7 +47774,8 @@ function displayVersionsCore(versions) {
46550
47774
  const dateStr = date.toLocaleDateString();
46551
47775
  const timeStr = date.toLocaleTimeString();
46552
47776
  const currentMark = v.isCurrent ? " \u2B50 CURRENT" : "";
46553
- const status = v.status === "draft" ? " [DRAFT]" : "";
47777
+ const marker = versionStatusMarker(v.status);
47778
+ const status = marker ? ` ${marker}` : "";
46554
47779
  console.log(` Version ${v.version}${status} - ${dateStr} ${timeStr}${currentMark}`);
46555
47780
  });
46556
47781
  console.log("\n" + "=".repeat(60));
@@ -46808,7 +48033,7 @@ async function listPersonaVersionsInteractive(context) {
46808
48033
  const date = new Date(version.createdDate);
46809
48034
  const dateStr = date.toLocaleDateString();
46810
48035
  const timeStr = date.toLocaleTimeString();
46811
- const status = version.status === "draft" ? "[DRAFT]" : "";
48036
+ const status = versionStatusMarker(version.status);
46812
48037
  const currentMark = version.isCurrent ? " \u2B50 CURRENT" : "";
46813
48038
  return {
46814
48039
  name: `Version ${version.version} ${status} - (${dateStr}) ${timeStr} ${currentMark}`,
@@ -46827,7 +48052,7 @@ async function viewVersionDetailsInteractive(version) {
46827
48052
  console.log(`Persona Version ${version.version}`);
46828
48053
  console.log("=".repeat(60));
46829
48054
  console.log(`Created: ${date.toLocaleString()}`);
46830
- const versionStatus = version.status === "draft" ? "\u{1F528} DRAFT" : "";
48055
+ const versionStatus = version.status === "draft" ? "\u{1F528} DRAFT" : version.status === "staged" ? "\u{1F4E4} STAGED (not served)" : "\u2B50 PUBLISHED";
46831
48056
  console.log(`Version Status: ${versionStatus}`);
46832
48057
  console.log(`Active Status: ${version.isCurrent ? "\u2B50 CURRENT" : "Available"}`);
46833
48058
  if (version.createdBy) {
@@ -46910,7 +48135,7 @@ async function deployPersonaVersionInteractive(context) {
46910
48135
  const dateStr = date.toLocaleDateString();
46911
48136
  const timeStr = date.toLocaleTimeString();
46912
48137
  const currentMark = v.isCurrent ? " \u2B50 CURRENTLY DEPLOYED" : "";
46913
- const status = v.status === "draft" ? "[DRAFT]" : "";
48138
+ const status = versionStatusMarker(v.status);
46914
48139
  return {
46915
48140
  name: `Version ${v.version} ${status} - (${dateStr}) ${timeStr} ${currentMark}`,
46916
48141
  value: v.version
@@ -52132,6 +53357,10 @@ function localVersionLine(version, hide) {
52132
53357
  return hide ? null : ` Version: ${version}`;
52133
53358
  }
52134
53359
  __name(localVersionLine, "localVersionLine");
53360
+ function priorityLine(priority) {
53361
+ return ` Priority: ${priority ?? 100}`;
53362
+ }
53363
+ __name(priorityLine, "priorityLine");
52135
53364
 
52136
53365
  // src/commands/skills.ts
52137
53366
  init_skills_api_service();
@@ -52142,7 +53371,8 @@ async function skillsCommand(actionOrEnv, actionArg, cmdObj) {
52142
53371
  return withErrorHandling(async () => {
52143
53372
  const options = {
52144
53373
  skillName: cmdObj?.skillName || null,
52145
- skillVersion: cmdObj?.skillVersion || null
53374
+ skillVersion: cmdObj?.skillVersion || null,
53375
+ json: cmdObj?.json || false
52146
53376
  };
52147
53377
  const { config, agentId, apiKey } = await initializeCommand();
52148
53378
  const hideVersions = await shouldHidePrimitiveVersions(apiKey, agentId);
@@ -52177,14 +53407,19 @@ async function skillsCommand(actionOrEnv, actionArg, cmdObj) {
52177
53407
  }
52178
53408
  return;
52179
53409
  }
53410
+ if (resolvedAction) {
53411
+ throw CliError.usage(`Sandbox skills do not support action "${resolvedAction}"`, 'Usage: lua skills sandbox view (only "view" is scriptable in sandbox)');
53412
+ }
52180
53413
  await manageSandboxSkillsInteractive(context3, config);
53414
+ } else if (resolvedAction) {
53415
+ await executeNonInteractive4(context3, config, resolvedAction, options);
52181
53416
  } else {
52182
53417
  await manageProductionSkillsInteractive(context3, config);
52183
53418
  }
52184
53419
  trackEvent("cli_skills_action", {
52185
53420
  environment: selectedEnvironment,
52186
53421
  action: resolvedAction || "interactive",
52187
- non_interactive: true
53422
+ non_interactive: !!resolvedAction
52188
53423
  });
52189
53424
  return;
52190
53425
  }
@@ -52295,6 +53530,15 @@ async function fetchVersionsCore2(context, skill) {
52295
53530
  };
52296
53531
  }
52297
53532
  __name(fetchVersionsCore2, "fetchVersionsCore");
53533
+ function mapSkillVersionsToJson(versions) {
53534
+ return versions.map((version) => ({
53535
+ id: version.id,
53536
+ version: version.version,
53537
+ isCurrent: version.isCurrent,
53538
+ createdDate: version.createdDate
53539
+ }));
53540
+ }
53541
+ __name(mapSkillVersionsToJson, "mapSkillVersionsToJson");
52298
53542
  function displayVersionsCore2(skill, versions, activeVersionId, hideVersions) {
52299
53543
  if (hideVersions) {
52300
53544
  primitiveVersionHistoryView(skill.name).forEach((line) => console.log(line));
@@ -52323,7 +53567,13 @@ async function deployVersionCore2(context, skill, version) {
52323
53567
  console.error(`\u274C Deploy Error: ${response.error?.message || "Unknown error"}`);
52324
53568
  return false;
52325
53569
  }
52326
- writeSuccess(`\u2705 Version ${version} of "${skill.name}" deployed successfully`);
53570
+ writeSuccess(formatDeploySuccess({
53571
+ label: "Skill",
53572
+ name: skill.name,
53573
+ version,
53574
+ agentVersion: response.data?.agentVersion
53575
+ }));
53576
+ syncDeployedVersionToYaml(skillHandler, skill.name, version, skill.version);
52327
53577
  writeHintBlock({
52328
53578
  headline: "Skill is live. Generate traffic to see it in action:",
52329
53579
  lines: [
@@ -52408,6 +53658,9 @@ async function promptVersionSelection2(versions, activeVersionId) {
52408
53658
  }
52409
53659
  __name(promptVersionSelection2, "promptVersionSelection");
52410
53660
  async function executeNonInteractive4(context, config, action, options) {
53661
+ if (options.json && action !== "versions") {
53662
+ throw CliError.usage("--json is only supported for the versions action", "Usage: lua skills versions --skill-name <name> --json");
53663
+ }
52411
53664
  const skills = config.skills || [];
52412
53665
  if (action === "view") {
52413
53666
  if (skills.length === 0) {
@@ -52443,6 +53696,10 @@ async function executeNonInteractive4(context, config, action, options) {
52443
53696
  case "versions": {
52444
53697
  const data = await fetchVersionsCore2(context, selectedSkill);
52445
53698
  if (!data) throw new Error("Failed to fetch skill versions");
53699
+ if (options.json) {
53700
+ console.log(JSON.stringify(mapSkillVersionsToJson(data.versions)));
53701
+ break;
53702
+ }
52446
53703
  if (!context.hideVersions && data.versions.length === 0) {
52447
53704
  console.log(`\u2139\uFE0F No versions found for ${selectedSkill.name}.`);
52448
53705
  console.log("\u{1F4A1} Push a version first using 'lua push skill'.");
@@ -53599,6 +54856,7 @@ async function displayWebhooksCore(context, webhooks) {
53599
54856
  const activeVersion = versions.find((v) => v.webhookId === activeVersionId);
53600
54857
  console.log(`\u{1FA9D} ${webhook.name}`);
53601
54858
  console.log(` Webhook ID: ${webhook.webhookId}`);
54859
+ console.log(` URL: ${WEBHOOK_TRIGGER_BASE_URL}/${context.agentId}/${encodeURIComponent(webhook.name)}`);
53602
54860
  if (activeVersion) {
53603
54861
  console.log(deployedVersionLine(activeVersion.version, context.hideVersions));
53604
54862
  console.log(` Deployed: ${new Date(activeVersion.createdAt).toLocaleString()}`);
@@ -53610,18 +54868,19 @@ async function displayWebhooksCore(context, webhooks) {
53610
54868
  }
53611
54869
  console.log();
53612
54870
  } else {
53613
- displayWebhookError(webhook, "Unable to fetch version info");
54871
+ displayWebhookError(webhook, "Unable to fetch version info", context.agentId);
53614
54872
  }
53615
54873
  } catch {
53616
- displayWebhookError(webhook, "Error loading versions");
54874
+ displayWebhookError(webhook, "Error loading versions", context.agentId);
53617
54875
  }
53618
54876
  }
53619
54877
  console.log("=".repeat(60));
53620
54878
  }
53621
54879
  __name(displayWebhooksCore, "displayWebhooksCore");
53622
- function displayWebhookError(webhook, status) {
54880
+ function displayWebhookError(webhook, status, agentId) {
53623
54881
  console.log(`\u{1FA9D} ${webhook.name}`);
53624
54882
  console.log(` Webhook ID: ${webhook.webhookId}`);
54883
+ console.log(` URL: ${WEBHOOK_TRIGGER_BASE_URL}/${agentId}/${encodeURIComponent(webhook.name)}`);
53625
54884
  console.log(` Status: ${status}`);
53626
54885
  console.log();
53627
54886
  }
@@ -53666,17 +54925,21 @@ async function deployVersionCore3(context, webhook, version) {
53666
54925
  console.error(`\u274C Deploy Error: ${deployResponse.error?.message || "Unknown error"}`);
53667
54926
  return false;
53668
54927
  }
53669
- writeSuccess(`\u2705 Version ${version} of "${webhook.name}" deployed successfully`);
54928
+ writeSuccess(formatDeploySuccess({
54929
+ label: "Webhook",
54930
+ name: webhook.name,
54931
+ version,
54932
+ agentVersion: deployResponse.data?.agentVersion
54933
+ }));
54934
+ syncDeployedVersionToYaml(webhookHandler, webhook.name, version, webhook.version);
54935
+ const webhookUrl = `${WEBHOOK_TRIGGER_BASE_URL}/${context.agentId}/${encodeURIComponent(webhook.name)}`;
54936
+ writeInfo(` URL: ${webhookUrl}`);
53670
54937
  writeHintBlock({
53671
54938
  headline: "Webhook is live. Trigger it, then inspect logs:",
53672
54939
  lines: [
53673
- {
53674
- label: "Find URL:",
53675
- command: `lua webhooks view --webhook-name ${webhook.name}`
53676
- },
53677
54940
  {
53678
54941
  label: "Trigger:",
53679
- command: "curl -X POST <URL from above>"
54942
+ command: `curl -X POST ${webhookUrl}`
53680
54943
  },
53681
54944
  {
53682
54945
  label: "Inspect:",
@@ -55328,6 +56591,10 @@ async function displayJobsCore(context, jobs, opts = {}) {
55328
56591
  if (jobData.nextRunAt) {
55329
56592
  console.log(` Next Run: ${new Date(jobData.nextRunAt).toLocaleString()}`);
55330
56593
  }
56594
+ if (jobData.health) {
56595
+ const h = jobData.health;
56596
+ console.log(` Health: ${h.state === "alerting" ? `ALERT ${(h.condition ?? "").replace("_", "-")}${h.since ? ` since ${new Date(h.since).toLocaleString()}` : ""}` : h.state}`);
56597
+ }
55331
56598
  console.log();
55332
56599
  } catch (error) {
55333
56600
  if (CliError.isCliError(error) && error.statusCode === 404) {
@@ -55396,7 +56663,13 @@ async function deployVersionCore4(context, job, version) {
55396
56663
  console.error(`\u274C Deploy Error: ${deployResponse.error?.message || "Unknown error"}`);
55397
56664
  return false;
55398
56665
  }
55399
- writeSuccess(`\u2705 Version ${version} of "${job.name}" deployed successfully`);
56666
+ writeSuccess(formatDeploySuccess({
56667
+ label: "Job",
56668
+ name: job.name,
56669
+ version,
56670
+ agentVersion: deployResponse.data?.agentVersion
56671
+ }));
56672
+ syncDeployedVersionToYaml(jobHandler, job.name, version, job.version);
55400
56673
  writeInfo("\u{1F4A1} The new version is now active and will run on schedule.");
55401
56674
  writeHintBlock({
55402
56675
  headline: "Job is live. Trigger it, then inspect:",
@@ -55508,7 +56781,7 @@ async function fetchAndDisplayHistoryCore(context, job) {
55508
56781
  const status = execution.status;
55509
56782
  const statusEmoji = status === "completed" ? "\u2705" : status === "failed" ? "\u274C" : status === "running" ? "\u{1F504}" : "\u23F3";
55510
56783
  console.log(`${index + 1}. ${statusEmoji} ${status.toUpperCase()}`);
55511
- console.log(` Execution ID: ${execution.executionId}`);
56784
+ console.log(` Execution ID: ${execution.id ?? execution.executionId ?? "N/A"}`);
55512
56785
  console.log(` Started: ${startedAt.toLocaleString()}`);
55513
56786
  if (execution.completedAt) {
55514
56787
  const completedAt = new Date(execution.completedAt);
@@ -56733,7 +58006,7 @@ async function activateCore(ctx, name, on) {
56733
58006
  emitJson(ctx, res);
56734
58007
  if (!ctx.json) {
56735
58008
  writeSuccess(`\u2705 Workflow "${wf.name}" ${on ? "activated" : "deactivated"}`);
56736
- writeInfo(on ? "\u{1F4A1} Schedules and triggers for this workflow are enabled." : "\u{1F4A1} Schedules and triggers for this workflow are paused.");
58009
+ writeInfo(on ? "\u{1F4A1} The workflow can start scheduled/triggered runs again \u2014 a schedule that is paused or auto-disabled stays that way (see `lua workflows schedules list` / `schedules resume <jobId>`)." : "\u{1F4A1} Scheduled and triggered starts are blocked while inactive \u2014 existing schedule pause/auto-disable state is unchanged.");
56737
58010
  }
56738
58011
  return WORKFLOW_EXIT.OK;
56739
58012
  }
@@ -58325,13 +59598,17 @@ function modelEventDetail(type, data) {
58325
59598
  __name(modelEventDetail, "modelEventDetail");
58326
59599
  async function logsCore(ctx, runId, o) {
58327
59600
  if (o.follow) return watchCore(ctx, runId, o);
59601
+ const since = o.since !== void 0 ? parseSinceFlag(o.since) : void 0;
59602
+ if (since !== void 0 && !Number.isFinite(since)) {
59603
+ throw CliError.usage(`logs: --since is not a duration or ISO timestamp ("${o.since}")`);
59604
+ }
58328
59605
  const res = await ctx.api.getRunEvents(runId, {
58329
59606
  limit: 500
58330
59607
  });
58331
59608
  if (!res.success || !res.data) return apiFailure(ctx, res, "logs");
58332
59609
  emitJson(ctx, res);
58333
59610
  if (ctx.json) return WORKFLOW_EXIT.OK;
58334
- const events = (res.data.events ?? []).filter((e) => (!o.step || e.stepId === o.step) && WORKFLOW_LOG_EVENT_PATTERN.test(e.type));
59611
+ const events = (res.data.events ?? []).filter((e) => (!o.step || e.stepId === o.step) && WORKFLOW_LOG_EVENT_PATTERN.test(e.type) && (since === void 0 || Date.parse(e.ts) >= since));
58335
59612
  if (events.length === 0) console.log("(no log events yet)");
58336
59613
  for (const e of events) {
58337
59614
  const data = scrubEventData(e.data);
@@ -59124,6 +60401,12 @@ var goalStatusLabel = /* @__PURE__ */ __name((g) => `${g.status}${g.pauseReason
59124
60401
  var goalJobStateLabel = /* @__PURE__ */ __name((g) => g.job ? ` \xB7 ${g.job.status}${g.job.status === "active" && g.job.nextRunAt ? `, next ${when2(g.job.nextRunAt)}` : ""}` : "", "goalJobStateLabel");
59125
60402
  var verdictLabel = /* @__PURE__ */ __name((v) => v ? `${v.done ? "done" : "continue"}${v.summary ? ` \xB7 ${v.summary.slice(0, 60)}` : ""}` : "\u2014", "verdictLabel");
59126
60403
  var scheduleStatus = /* @__PURE__ */ __name((r) => r.autoDisabled ? "auto-disabled" : r.status === "inactive" ? "inactive" : r.status === "completed" || r.status === "missed" ? r.status : r.paused ? "paused" : "active", "scheduleStatus");
60404
+ var scheduleHealthLabel = /* @__PURE__ */ __name((r) => {
60405
+ const h = r.health;
60406
+ if (!h) return "\u2014";
60407
+ if (h.state === "alerting") return `ALERT ${(h.condition ?? "").replace("_", "-")}${h.since ? ` since ${when2(h.since)}` : ""}`;
60408
+ return h.state;
60409
+ }, "scheduleHealthLabel");
59127
60410
  function goalRaiseHint(goalId, reason) {
59128
60411
  const flag = reason === "budget" ? "--max-credits <n>" : reason === "max_runs" ? "--max-runs <n>" : "--max-runs <n> | --max-credits <n>";
59129
60412
  return `a goal parked at its cap (max_runs / budget) re-arms when the cap is raised: lua workflows goals raise ${goalId} ${flag} \u2014 or edit it: lua workflows goals edit ${goalId} \u2026`;
@@ -59193,6 +60476,7 @@ function printSchedules(items, names) {
59193
60476
  "Last fired",
59194
60477
  "Status",
59195
60478
  "Strikes",
60479
+ "Health",
59196
60480
  "Goal"
59197
60481
  ], items.map((r) => [
59198
60482
  r.jobId,
@@ -59202,6 +60486,7 @@ function printSchedules(items, names) {
59202
60486
  when2(r.lastFiredAt),
59203
60487
  scheduleStatus(r),
59204
60488
  String(r.consecutiveFailures ?? 0),
60489
+ scheduleHealthLabel(r),
59205
60490
  r.goalId ?? "\u2014"
59206
60491
  ])));
59207
60492
  const owned = items.filter((r) => r.goalId).length;
@@ -60852,6 +62137,7 @@ async function displayPreProcessorsCore(context, preprocessors) {
60852
62137
  const activeVersion = versions.find((v) => v.versionId === activeVersionId);
60853
62138
  console.log(`\u{1F4E5} ${preprocessor.name}`);
60854
62139
  console.log(` PreProcessor ID: ${preprocessor.preprocessorId}`);
62140
+ console.log(priorityLine(response.data.priority));
60855
62141
  if (activeVersion) {
60856
62142
  console.log(deployedVersionLine(activeVersion.version, context.hideVersions));
60857
62143
  console.log(` Deployed: ${new Date(activeVersion.createdAt).toLocaleString()}`);
@@ -60918,7 +62204,13 @@ async function deployVersionCore5(context, preprocessor, version) {
60918
62204
  console.error(`\u274C Deploy Error: ${deployResponse.error?.message || "Unknown error"}`);
60919
62205
  return false;
60920
62206
  }
60921
- writeSuccess(`\u2705 Version ${version} of "${preprocessor.name}" deployed successfully`);
62207
+ writeSuccess(formatDeploySuccess({
62208
+ label: "PreProcessor",
62209
+ name: preprocessor.name,
62210
+ version,
62211
+ agentVersion: deployResponse.data?.agentVersion
62212
+ }));
62213
+ syncDeployedVersionToYaml(preprocessorHandler, preprocessor.name, version, preprocessor.version);
60922
62214
  writeHintBlock({
60923
62215
  headline: "Preprocessor is live. Send a test message to trigger it:",
60924
62216
  lines: [
@@ -61429,6 +62721,7 @@ async function displayPostProcessorsCore(context, postprocessors) {
61429
62721
  const activeVersion = versions.find((v) => v.versionId === activeVersionId);
61430
62722
  console.log(`\u{1F4E4} ${postprocessor.name}`);
61431
62723
  console.log(` PostProcessor ID: ${postprocessor.postprocessorId}`);
62724
+ console.log(priorityLine(response.data.priority));
61432
62725
  if (activeVersion) {
61433
62726
  console.log(deployedVersionLine(activeVersion.version, context.hideVersions));
61434
62727
  console.log(` Deployed: ${new Date(activeVersion.createdAt).toLocaleString()}`);
@@ -61495,7 +62788,13 @@ async function deployVersionCore6(context, postprocessor, version) {
61495
62788
  console.error(`\u274C Deploy Error: ${deployResponse.error?.message || "Unknown error"}`);
61496
62789
  return false;
61497
62790
  }
61498
- writeSuccess(`\u2705 Version ${version} of "${postprocessor.name}" deployed successfully`);
62791
+ writeSuccess(formatDeploySuccess({
62792
+ label: "PostProcessor",
62793
+ name: postprocessor.name,
62794
+ version,
62795
+ agentVersion: deployResponse.data?.agentVersion
62796
+ }));
62797
+ syncDeployedVersionToYaml(postprocessorHandler, postprocessor.name, version, postprocessor.version);
61499
62798
  writeHintBlock({
61500
62799
  headline: "Postprocessor is live. Send a test message to trigger it:",
61501
62800
  lines: [
@@ -62524,7 +63823,7 @@ async function templateCreateAction(templateApi, config, options) {
62524
63823
  validate: /* @__PURE__ */ __name((input) => input && input.trim().length > 0 ? true : "Display name cannot be empty.", "validate")
62525
63824
  });
62526
63825
  }
62527
- if (description === void 0) {
63826
+ if (description === void 0 && !isCiModeEnabled()) {
62528
63827
  questions.push({
62529
63828
  type: "input",
62530
63829
  name: "description",
@@ -62812,7 +64111,7 @@ ${"=".repeat(60)}`);
62812
64111
  console.log(`Visibility: ${template3.visibility === "private" ? "\u{1F512} Private" : "\u{1F310} Public"}`);
62813
64112
  console.log(`Listed: ${template3.listed ? "Yes" : "No"}`);
62814
64113
  console.log(`Installs: ${template3.installCount}`);
62815
- if (template3.latestVersion != null) console.log(`Latest version: v${template3.latestVersion}`);
64114
+ if (template3.latestVersion) console.log(`Latest version: v${template3.latestVersion}`);
62816
64115
  console.log(`Created: ${new Date(template3.createdAt).toLocaleDateString()}`);
62817
64116
  console.log(`
62818
64117
  ${"=".repeat(60)}
@@ -63428,9 +64727,13 @@ async function listSkillNonInteractive(marketplaceApi, config, apiKey, options)
63428
64727
  }
63429
64728
  __name(listSkillNonInteractive, "listSkillNonInteractive");
63430
64729
  async function publishVersionNonInteractive(marketplaceApi, config, apiKey, options) {
63431
- const { marketplaceId, versionId, changelog, envVarsJson } = options;
63432
- if (!marketplaceId || !versionId) {
63433
- throw CliError.usage("Missing required options", "Usage: lua marketplace skill publish --marketplace-id <id> --version-id <id> [--changelog <text>]");
64730
+ const { marketplaceId, changelog, envVarsJson } = options;
64731
+ let { versionId } = options;
64732
+ if (!marketplaceId || !versionId && !options.version) {
64733
+ throw CliError.usage("Missing required options", "Usage: lua marketplace skill publish --marketplace-id <id> (--version-id <id> | --version <semver>) [--changelog <text>]");
64734
+ }
64735
+ if (!versionId && options.version) {
64736
+ versionId = await resolveVersionIdFromSemver(marketplaceApi, config, apiKey, marketplaceId, options.version);
63434
64737
  }
63435
64738
  let envVars;
63436
64739
  if (envVarsJson) {
@@ -63451,6 +64754,40 @@ async function publishVersionNonInteractive(marketplaceApi, config, apiKey, opti
63451
64754
  writeInfo("\u{1F4A1} You will be notified once the review is complete.");
63452
64755
  }
63453
64756
  __name(publishVersionNonInteractive, "publishVersionNonInteractive");
64757
+ async function resolveVersionIdFromSemver(marketplaceApi, config, apiKey, marketplaceId, version) {
64758
+ const marketplaceSkill = await marketplaceApi.getSkillById(marketplaceId);
64759
+ const agentId = config.agent?.agentId;
64760
+ if (!agentId) {
64761
+ throw CliError.usage("Agent ID not found in configuration.");
64762
+ }
64763
+ const skillApi = new SkillApi(BASE_URLS.API, apiKey, agentId);
64764
+ const agentSkillsResponse = await skillApi.getSkills();
64765
+ if (!agentSkillsResponse.success || !agentSkillsResponse.data) {
64766
+ throw CliError.notFound(`Failed to fetch agent skills: ${agentSkillsResponse.message || "Unknown error"}`);
64767
+ }
64768
+ const agentSkills = agentSkillsResponse.data.skills || [];
64769
+ let sourceSkill = agentSkills.find((s) => s.id === marketplaceSkill.sourceSkillId);
64770
+ if (!sourceSkill) {
64771
+ const nameMatches = agentSkills.filter((s) => s.name === marketplaceSkill.name);
64772
+ if (nameMatches.length > 1) {
64773
+ throw CliError.usage(`Multiple agent skills are named "${marketplaceSkill.name}"; cannot determine which one to publish.`, "Pass --version-id explicitly to disambiguate instead of --version.");
64774
+ }
64775
+ sourceSkill = nameMatches[0];
64776
+ }
64777
+ if (!sourceSkill) {
64778
+ throw CliError.notFound(`Could not find the source skill on your agent.`, `The skill "${marketplaceSkill.name}" (ID: ${marketplaceSkill.sourceSkillId}) is missing from agent ${agentId}.`);
64779
+ }
64780
+ const versionsResponse = await skillApi.getSkillVersions(sourceSkill.id);
64781
+ if (!versionsResponse.success || !versionsResponse.data) {
64782
+ throw CliError.notFound(`Failed to fetch skill versions: ${versionsResponse.message || "Unknown error"}`);
64783
+ }
64784
+ const matchingVersion = (versionsResponse.data.versions || []).find((v) => v.version === version);
64785
+ if (!matchingVersion) {
64786
+ throw CliError.notFound(`Version "${version}" not found for skill "${sourceSkill.name}".`, `Run 'lua skills versions --skill-name ${sourceSkill.name} --json' to see available versions.`);
64787
+ }
64788
+ return matchingVersion.id;
64789
+ }
64790
+ __name(resolveVersionIdFromSemver, "resolveVersionIdFromSemver");
63454
64791
  async function updateMetadataNonInteractive(marketplaceApi, options) {
63455
64792
  const { marketplaceId, displayName } = options;
63456
64793
  if (!marketplaceId) {
@@ -66042,7 +67379,8 @@ async function executeNonInteractive12(context, action, cmdOptions) {
66042
67379
  // Trigger options
66043
67380
  triggers: cmdOptions?.triggers,
66044
67381
  customWebhook: cmdOptions?.customWebhook === true,
66045
- hookUrl: cmdOptions?.hookUrl
67382
+ hookUrl: cmdOptions?.hookUrl,
67383
+ forget: cmdOptions?.forget === true
66046
67384
  };
66047
67385
  const jsonOutput = cmdOptions?.json === true;
66048
67386
  switch (normalizedAction) {
@@ -66090,7 +67428,7 @@ async function executeNonInteractive12(context, action, cmdOptions) {
66090
67428
  throw CliError.usage("--connection-id is required for disconnect", "Run 'lua integrations list' to see connection IDs");
66091
67429
  }
66092
67430
  if (options.scope === "user") {
66093
- await disconnectUserConnection(context, options.connectionId);
67431
+ await disconnectUserConnection(context, options.connectionId, options.forget);
66094
67432
  } else {
66095
67433
  await disconnectIntegration(context, options.connectionId);
66096
67434
  }
@@ -66343,9 +67681,27 @@ function normalizeScopeFlag(raw) {
66343
67681
  return normalized;
66344
67682
  }
66345
67683
  __name(normalizeScopeFlag, "normalizeScopeFlag");
67684
+ function resolveCiScopeDefault(flagged, ciEnabled) {
67685
+ if (flagged) return flagged;
67686
+ return ciEnabled ? "agent" : void 0;
67687
+ }
67688
+ __name(resolveCiScopeDefault, "resolveCiScopeDefault");
67689
+ function assertAccountLabelForCi(userScope, accountLabel, ciEnabled) {
67690
+ if (userScope || !ciEnabled) return;
67691
+ if (accountLabel?.trim()) return;
67692
+ throw CliError.usage("--account-label is required when --ci is set (finalizeConnection asks for it only after OAuth succeeds, and --ci cannot answer prompts)", joinHint(void 0, "Prompting is not possible under --ci"));
67693
+ }
67694
+ __name(assertAccountLabelForCi, "assertAccountLabelForCi");
67695
+ function resolveDisconnectForget(explicitForget, ciEnabled) {
67696
+ if (explicitForget === true) return true;
67697
+ return ciEnabled ? false : "prompt";
67698
+ }
67699
+ __name(resolveDisconnectForget, "resolveDisconnectForget");
66346
67700
  async function resolveConnectScope(context, options) {
66347
67701
  const flagged = normalizeScopeFlag(options.scope);
66348
67702
  if (flagged) return flagged;
67703
+ const ciDefault = resolveCiScopeDefault(flagged, isCiModeEnabled());
67704
+ if (ciDefault) return ciDefault;
66349
67705
  const answer = await safePrompt([
66350
67706
  {
66351
67707
  type: "list",
@@ -66378,6 +67734,7 @@ async function connectIntegrationFlow(context, options = {}) {
66378
67734
  throw new Error("Agent-scoped options cannot be used with --scope user");
66379
67735
  }
66380
67736
  }
67737
+ assertAccountLabelForCi(userScope, options.accountLabel, isCiModeEnabled());
66381
67738
  writeProgress("\u{1F504} Fetching integrations...");
66382
67739
  let availableIntegrations;
66383
67740
  let agentConnectedTypes = /* @__PURE__ */ new Set();
@@ -67136,18 +68493,25 @@ async function listConnections(context) {
67136
68493
  }
67137
68494
  }
67138
68495
  __name(listConnections, "listConnections");
67139
- async function disconnectUserConnection(context, connectionId) {
67140
- const forget = await safePrompt([
67141
- {
67142
- type: "confirm",
67143
- name: "forget",
67144
- message: "Also forget what this connection already added to memory? (it is kept otherwise)",
67145
- default: false
67146
- }
67147
- ]);
67148
- if (!forget) return;
68496
+ async function disconnectUserConnection(context, connectionId, forgetFlag) {
68497
+ const decision = resolveDisconnectForget(forgetFlag, isCiModeEnabled());
68498
+ let shouldForget;
68499
+ if (decision === "prompt") {
68500
+ const forget = await safePrompt([
68501
+ {
68502
+ type: "confirm",
68503
+ name: "forget",
68504
+ message: "Also forget what this connection already added to memory? (it is kept otherwise)",
68505
+ default: false
68506
+ }
68507
+ ]);
68508
+ if (!forget) return;
68509
+ shouldForget = forget.forget;
68510
+ } else {
68511
+ shouldForget = decision;
68512
+ }
67149
68513
  writeProgress("\u{1F504} Disconnecting... (please wait, do not close this window)");
67150
- const result = await context.unifiedToApi.deleteUserConnection(connectionId, forget.forget);
68514
+ const result = await context.unifiedToApi.deleteUserConnection(connectionId, shouldForget);
67151
68515
  if (!result.success) {
67152
68516
  writeError(`\u274C Failed to disconnect: ${result.error?.message || "Unknown error"}`);
67153
68517
  return;
@@ -67156,14 +68520,14 @@ async function disconnectUserConnection(context, connectionId) {
67156
68520
  if (result.data?.deletedWebhooksCount) {
67157
68521
  console.log(` \u2713 Deleted ${result.data.deletedWebhooksCount} memory source(s)`);
67158
68522
  }
67159
- if (!forget.forget) {
68523
+ if (!shouldForget) {
67160
68524
  console.log(" \u2139\uFE0F What it already added to memory was kept.");
67161
68525
  }
67162
68526
  console.log();
67163
68527
  trackEvent("cli_integration_disconnected", {
67164
68528
  scope: "user",
67165
68529
  webhooks_deleted: result.data?.deletedWebhooksCount || 0,
67166
- forget_memories: forget.forget
68530
+ forget_memories: shouldForget
67167
68531
  });
67168
68532
  }
67169
68533
  __name(disconnectUserConnection, "disconnectUserConnection");
@@ -70442,6 +71806,7 @@ __name(defaultRestore, "defaultRestore");
70442
71806
  // src/commands/version.ts
70443
71807
  init_cli();
70444
71808
  init_command_utils();
71809
+ init_cli_error();
70445
71810
  init_analytics();
70446
71811
  init_files();
70447
71812
  init_semver();
@@ -70796,6 +72161,8 @@ async function versionDeleteCommand(versionArg, options = {}) {
70796
72161
  writeInfo("Aborted.");
70797
72162
  return;
70798
72163
  }
72164
+ } else if (!options.force && (!isTTY || isCi)) {
72165
+ throw CliError.usage(`Deleting v${version} needs a confirmation; pass --force to give it non-interactively.`, "Nothing was deleted.");
70799
72166
  }
70800
72167
  const api = new AgentVersionApi(BASE_URLS.API, apiKey, agentId);
70801
72168
  const response = await api.deleteVersion(version);
@@ -71407,7 +72774,7 @@ Arguments:
71407
72774
 
71408
72775
  Skill Actions:
71409
72776
  list --skill-name <name> --display-name <name> [--visibility public|private]
71410
- publish --marketplace-id <id> --version-id <id> [--changelog <text>] [--env-vars-json <json>]
72777
+ publish --marketplace-id <id> (--version-id <id> | --version <semver>) [--changelog <text>] [--env-vars-json <json>]
71411
72778
  edit --marketplace-id <id> --display-name <name>
71412
72779
  unlist --marketplace-id <id> --force
71413
72780
  unpublish --marketplace-id <id> --version-id <id> --force
@@ -71439,6 +72806,7 @@ Examples:
71439
72806
  $ lua marketplace skill org View this organization's owned skills
71440
72807
  $ lua marketplace skill list --skill-name mySkill --display-name "My Skill"
71441
72808
  $ lua marketplace skill publish --marketplace-id xyz --version-id v1
72809
+ $ lua marketplace skill publish --marketplace-id xyz --version 1.2.0 Alternative to --version-id
71442
72810
  $ lua marketplace skill unlist --marketplace-id xyz --force
71443
72811
  $ lua marketplace skill search --query "CRM"
71444
72812
  $ lua marketplace skill view --marketplace-id xyz --json
@@ -71623,7 +72991,7 @@ Examples:
71623
72991
  program2.command("persona [env] [action]").description("\u{1F916} Manage agent persona").option("--persona-version <version>", "Version number or 'latest' for deploy").option("--force", "Skip confirmation prompt").addHelpText("after", `
71624
72992
  Arguments:
71625
72993
  env Optional: 'sandbox', 'staging', or 'production' (prompts if not provided)
71626
- action Optional (production only): 'view', 'versions', 'deploy'
72994
+ action Optional: 'view', 'versions' (sandbox or production), 'deploy' (production only)
71627
72995
 
71628
72996
  Options:
71629
72997
  --persona-version <ver> Version number or 'latest' for deploy action
@@ -71632,6 +73000,7 @@ Options:
71632
73000
  Examples:
71633
73001
  $ lua persona Interactive selection
71634
73002
  $ lua persona sandbox Manage sandbox persona interactively
73003
+ $ lua persona sandbox versions List persona versions (sandbox)
71635
73004
  $ lua persona production Manage production persona interactively
71636
73005
  $ lua persona production view View current deployed persona
71637
73006
  $ lua persona production versions List all persona versions
@@ -71748,20 +73117,23 @@ Notes:
71748
73117
  acknowledgement is given AND the credential holds logs:manage \u2014 the scope alone is not
71749
73118
  enough, the flag is required too.
71750
73119
  `).action((options, command) => logsExportCommand(withGroupOptions(options ?? {}, command)));
71751
- program2.command("skills [actionOrEnv] [action]").description("\u2699\uFE0F Manage and view skills").option("--skill-name <name>", "Skill name").option("--skill-version <version>", "Version for deploy action (or 'latest')").addHelpText("after", `
73120
+ program2.command("skills [actionOrEnv] [action]").description("\u2699\uFE0F Manage and view skills").option("--skill-name <name>", "Skill name").option("--skill-version <version>", "Version for deploy action (or 'latest')").option("--json", "Print versions as JSON, including version ids (for versions action)").addHelpText("after", `
71752
73121
  Arguments:
71753
73122
  actionOrEnv Optional: environment ('sandbox', 'production') or action ('view', 'versions', 'deploy', 'delete')
71754
73123
 
71755
73124
  Options:
71756
73125
  --skill-name <name> Skill name (for versions/deploy/delete actions)
71757
73126
  --skill-version <ver> Version for deploy action, or 'latest'
73127
+ --json Print versions as JSON, including version ids (for versions action)
71758
73128
 
71759
73129
  Examples:
71760
73130
  $ lua skills Interactive selection
71761
73131
  $ lua skills sandbox View sandbox skills
71762
73132
  $ lua skills production Manage production skills
71763
73133
  $ lua skills view List all production skills
73134
+ $ lua skills production view Same non-interactive listing as 'lua skills view'
71764
73135
  $ lua skills versions --skill-name mySkill View skill versions
73136
+ $ lua skills versions --skill-name mySkill --json View skill version ids as JSON
71765
73137
  $ lua skills deploy --skill-name mySkill --skill-version 1.0.3 Deploy specific version
71766
73138
  $ lua skills deploy --skill-name mySkill --skill-version latest Deploy latest version
71767
73139
  $ lua skills delete --skill-name mySkill Delete a skill from server
@@ -71870,7 +73242,7 @@ Examples:
71870
73242
  $ lua jobs versions -i myJob View job versions
71871
73243
  $ lua jobs history -i myJob View execution history
71872
73244
  `).action(jobsCommand);
71873
- program2.command("workflows [action] [target] [extra]").description("\u{1F9ED} Manage workflows and their runs (list, start, watch, cancel, resume, retry-step, resolve-step, raise-budget, approve, signal, replay, export, schedules)").option("-i, --workflow-name <name>", "Workflow name (or id)").option("-r, --run-id <id>", "Run id").option("-v, --workflow-version <ver>", "deploy/start/export/goals create/schedules create: a semver, 'latest' (newest push) or a version id").option("--json", "Print the raw {success,data} envelope").option("--all", "list: include dynamic workflows").option("--input <json|@file>", "start/run/goals create/schedules create: run input").option("--idempotency-key <key>", "start: idempotency key").option("--correlation-key <key>", "start/runs: correlation key").option("--tag <tag>", "start/runs/schedules create: tag (repeatable, \u2264 10)", collect, []).option("--budget-credits <n>", "start/schedules create: run budget (credits)").option("--wait <s>", "start: server long-poll \u2264 55 s").option("--follow", "start/logs: attach watch").option("--status <status>", "runs/goals list: filter by status").option("--workflow <name>", "runs: filter by workflow").option("--limit <n>", "runs/goals list/approval-payload --path: page size").option("--cursor <c>", "runs/goals list/approval-payload --path: page cursor").option("--sort <field>", "runs: -createdAt|createdAt|-durationMs|durationMs").option("--steps", "status: per-step table").option("--strict", "status: exit 4/5 by terminal status, 6 for a gated run").option("--compose <on|off>", "policy models set: may the composer be shown the model menu").option("--max-class <fast|balanced|strong>", "policy models set: ceiling for class requests and the class map").option("--consent-actions <n>", "policy models set: estimated actions above which a composed run shows the card").option("--allow <codes>", "policy models set: comma-separated approved codes to narrow the set to").option("--class-fast <codes>", "policy models set: ordered overrides of the fast class (comma-separated)").option("--class-balanced <codes>", "policy models set: ordered overrides of the balanced class (comma-separated)").option("--class-strong <codes>", "policy models set: ordered overrides of the strong class (comma-separated)").option("--class-map <pairs>", "policy models set: comma-separated <taskClass>=<modelClass> pairs").option("--pins <class-only|allowed>", "policy models set: may a composed definition pin a concrete code").option("--fallback <same-class|same-provider>", "policy models set: where a failed leg may hop to").option("--enabled <on|off>", "policy autonomy set: may a start inside the envelope skip the consent card").option("--max-duration <seconds>", "policy autonomy set: the envelope\u2019s duration bound, in seconds").option("--max-actions <n>", "policy autonomy set: the envelope\u2019s estimated-actions bound").option("--max-runs-per-hour <n>", "policy autonomy set: autonomous starts per hour, per agent").option("--forms <list>", "policy autonomy set: comma-separated forms the envelope admits (graph,script,static)").option("--clear <keys>", "policy autonomy set: comma-separated members to clear back to the platform default").option("--agent <agentId>", "policy autonomy: not supported \u2014 no route writes a per-agent envelope (see the refusal)").option("--kind <kind>", "clear-gate: the gate kind to clear (e.g. model_policy)").option("--after <seq>", "watch: replay from seq").option("--timeout <s>", "watch / start --follow: give up after s seconds while the run is still live (exit 7)").option("--events", "watch: print raw frames").option("--wait-for-human", "watch / start --follow: keep following through a human boundary (approval, input, signal, park) instead of exiting 8").option("--reason <text>", "cancel: reason").option("--step <id>", "resume/retry-step/resolve-step/logs: step id").option("--outcome <skip|complete|fail>", "resolve-step: the decision on the parked step (--action is accepted too)").option("--action <skip|complete|fail>", "resolve-step: alias of --outcome").option("--output <json|@file>", "resolve-step: the output a completed step would have produced (required with --outcome complete)").option("--credits <n>", "raise-budget: the new priced cap of a budget-parked run, in the run's own budget unit \u2014 credits, or actions on a seat plan (above the current one)").option("--max-steps <n>", "raise-budget: the new step cap").option("--max-job-seconds <n>", "raise-budget: the new Job-tier seconds cap").option("--max-duration-seconds <n>", "raise-budget: the new wall-clock cap").option("--data <json|@file>", "resume: resumeData").option("--approval <id>", "approve/approval-payload: the wfa_\u2026 approval id (lua workflows status <runId> --steps --json \u2192 suspend.approvalId), not the step id").option("--path <array.path>", "approval-payload: page one array of a large payload (--cursor / --limit inside it)").option("--decision <approve|deny>", "approve: decision (default approve)").option("--note <text>", "approve/retry-step/resolve-step/raise-budget/goals close: note").option("--edit <json|@file>", "approve: edited payload (small inline edits)").option("--fingerprint <f>", "approve: payloadFingerprint (mandatory with --edit)").option("--payload <json|@file>", "signal: payload").option("--dedupe-key <key>", "signal: dedupe key").option("--local", "replay: replay locally against the compiled artifact").option("--since <dur>", "logs: window").option("--yes", "delete/delete-run/schedules delete: skip confirmation").option("--force", "delete: cancel in-flight runs first \xB7 run: seed from a changed graph \xB7 export: overwrite files").option("--step-output <id=json>", "run: complete a step with this output (repeatable)", collect, []).option("--approve <id[=@payload]>", "run: pre-answer an approval (repeatable)", collect, []).option("--deny <id[=@reason]>", "run: pre-deny an approval (repeatable)", collect, []).option("--signal <name=json>", "run: pre-supply a waitForSignal payload (repeatable)", collect, []).option("--from-run <runId>", "run: seed completed steps from a real run").option("--record <dir>", "run: record agent/tool outputs as fixtures").option("--fixtures <dir>", "run: replay recorded fixtures").option("--step-wall <s>", "run: per-step wall in seconds (default 600)").option("--job-wall <s>", "run: virtual wall for tier:'job' steps \u2014 splits at 14400 s segments, > 86400 is exit 2").option("--ledger-out <file>", "run: write the in-memory ledger as JSON").option("--agents <fake|live>", "run: fake agent steps (default) or call the dev API").option("--now <iso>", "run: virtual clock start").option("--park <id>", "run: simulate a platform-fault park of this step (repeatable)", collect, []).option("--fast-retries", "run: collapse retry backoff waits to 0").option("--real-time", "run: actually wait on sleeps/backoffs instead of fast-forwarding").option("--artefacts-dir <dir>", "run: back ctx.artefacts.* on disk").option("--workspace <dir>", "run: the checkout Job-tier code steps run in (ctx.workspace + ctx.exec / ctx.$)").option("--env <KEY=value>", "run: local env.template() overlay (repeatable; missing key \u21D2 exit 2)", collect, []).option("--max-ticks <n>", "run (script form): tick cap before SCRIPT_TICK_LIMIT (default 64)").option("--until <iso>", "archive-runs: window end").option("--out <dir>", "archive-runs: destination dir (archive-index.ndjson + <runId>.zip) \xB7 export: target dir").option("--concurrency <n>", "archive-runs: parallel exports (default 2, max 5)").option("--no-inputs", "archive-runs: exclude run inputs from the bundle").option("--no-artefacts", "archive-runs: exclude artefacts from the bundle").option("--retention-days <n>", "archive-runs: org run retention (default 90) \u2014 --since must fit retention \u2212 7 d").option("--connection <id>", "archive-runs: org storage connection for s3:// / gs:// sinks").option("--release", "workspace: release the run workspace (R42)").option("--attempt <n>", "job-logs: attempt (default latest)").option("--tail <n>", "job-logs: log lines (1..2000, default 200)").option("--objective <text>", "goals create: the objective (\u2264 2000 chars)").option("--judge-predicate <spec>", "goals create: deterministic judge \u2014 '<path> <op> [value]' (e.g. 'output.done truthy'), JSON or @file").option("--judge-agent <agentId|'$self'>", "goals create: judge agent \u2014 write '$self' quoted (or self); it needs --judge-role").option("--judge-role <json|@file>", "goals create: D25 role {name,instructions,tools} for a '$self' judge").option("--schema <json|@file>", "goals create: judge output JsonSchema (must declare a boolean `done`)").option("--cadence <cron|json|@file>", "goals create/schedules create: cadence entry (repeatable, \u2264 5); goals: none \u21D2 immediate", collect, []).option("--timezone <tz>", "goals create/edit/schedules create: IANA timezone for bare cron cadences").option("--notify <emailApp|email|app|off>", "schedules create: where each fire notifies").option("--backfill-on-enable <n|none>", "schedules create/patch/resume: replay \u2264 n missed fires on re-enable (patch: none clears it)").option("--backfill-now", "schedules resume (or patch --paused false): one-shot backfill on THIS re-enable").option("--paused <true|false>", "schedules patch: pause (true) or re-enable (false) the schedule").option("--max-runs <n>", "goals create/edit/raise: iteration cap (1..100)").option("--max-total-credits <n>", "goals create: lineage-wide credit gate").option("--max-credits <n|none>", "goals edit/raise: lineage-wide credit gate (edit: none clears it)").option("--every <interval>", "goals edit/schedules create: interval cadence \u2014 900, 15m, 2h (whole minutes, \u2265 60s)").option("--if-match <updatedAt>", "goals edit/raise: refuse the write if the goal changed since this updatedAt").addHelpText("after", `
73245
+ program2.command("workflows [action] [target] [extra]").description("\u{1F9ED} Manage workflows and their runs (list, start, watch, cancel, resume, retry-step, resolve-step, raise-budget, approve, signal, replay, export, schedules)").option("-i, --workflow-name <name>", "Workflow name (or id)").option("-r, --run-id <id>", "Run id").option("-v, --workflow-version <ver>", "deploy/start/export/goals create/schedules create: a semver, 'latest' (newest push) or a version id").option("--json", "Print the raw {success,data} envelope").option("--all", "list: include dynamic workflows").option("--input <json|@file>", "start/run/goals create/schedules create: run input").option("--idempotency-key <key>", "start: idempotency key").option("--correlation-key <key>", "start/runs: correlation key").option("--tag <tag>", "start/runs/schedules create: tag (repeatable, \u2264 10)", collect, []).option("--budget-credits <n>", "start/schedules create: run budget (credits)").option("--wait <s>", "start: server long-poll \u2264 55 s").option("--follow", "start/logs: attach watch").option("--status <status>", "runs/goals list: filter by status").option("--workflow <name>", "runs: filter by workflow").option("--limit <n>", "runs/goals list/approval-payload --path: page size").option("--cursor <c>", "runs/goals list/approval-payload --path: page cursor").option("--sort <field>", "runs: -createdAt|createdAt|-durationMs|durationMs").option("--steps", "status: per-step table").option("--strict", "status: exit 4/5 by terminal status, 6 for a gated run").option("--compose <on|off>", "policy models set: may the composer be shown the model menu").option("--max-class <fast|balanced|strong>", "policy models set: ceiling for class requests and the class map").option("--consent-actions <n>", "policy models set: estimated actions above which a composed run shows the card").option("--allow <codes>", "policy models set: comma-separated approved codes to narrow the set to").option("--class-fast <codes>", "policy models set: ordered overrides of the fast class (comma-separated)").option("--class-balanced <codes>", "policy models set: ordered overrides of the balanced class (comma-separated)").option("--class-strong <codes>", "policy models set: ordered overrides of the strong class (comma-separated)").option("--class-map <pairs>", "policy models set: comma-separated <taskClass>=<modelClass> pairs").option("--pins <class-only|allowed>", "policy models set: may a composed definition pin a concrete code").option("--fallback <same-class|same-provider>", "policy models set: where a failed leg may hop to").option("--enabled <on|off>", "policy autonomy set: may a start inside the envelope skip the consent card").option("--max-duration <seconds>", "policy autonomy set: the envelope\u2019s duration bound, in seconds").option("--max-actions <n>", "policy autonomy set: the envelope\u2019s estimated-actions bound").option("--max-runs-per-hour <n>", "policy autonomy set: autonomous starts per hour, per agent").option("--forms <list>", "policy autonomy set: comma-separated forms the envelope admits (graph,script,static)").option("--clear <keys>", "policy autonomy set: comma-separated members to clear back to the platform default").option("--agent <agentId>", "policy autonomy: not supported \u2014 no route writes a per-agent envelope (see the refusal)").option("--kind <kind>", "clear-gate: the gate kind to clear (e.g. model_policy)").option("--after <seq>", "watch: replay from seq").option("--timeout <s>", "watch / start --follow: give up after s seconds while the run is still live (exit 7)").option("--events", "watch: print raw frames").option("--wait-for-human", "watch / start --follow: keep following through a human boundary (approval, input, signal, park) instead of exiting 8").option("--reason <text>", "cancel: reason").option("--step <id>", "resume/retry-step/resolve-step/logs: step id").option("--outcome <skip|complete|fail>", "resolve-step: the decision on the parked step (--action is accepted too)").option("--action <skip|complete|fail>", "resolve-step: alias of --outcome").option("--output <json|@file>", "resolve-step: the output a completed step would have produced (required with --outcome complete)").option("--credits <n>", "raise-budget: the new priced cap of a budget-parked run, in the run's own budget unit \u2014 credits, or actions on a seat plan (above the current one)").option("--max-steps <n>", "raise-budget: the new step cap").option("--max-job-seconds <n>", "raise-budget: the new Job-tier seconds cap").option("--max-duration-seconds <n>", "raise-budget: the new wall-clock cap").option("--data <json|@file>", "resume: resumeData").option("--approval <id>", "approve/approval-payload: the wfa_\u2026 approval id (lua workflows status <runId> --steps --json \u2192 suspend.approvalId), not the step id").option("--path <array.path>", "approval-payload: page one array of a large payload (--cursor / --limit inside it)").option("--decision <approve|deny>", "approve: decision (default approve)").option("--note <text>", "approve/retry-step/resolve-step/raise-budget/goals close: note").option("--edit <json|@file>", "approve: edited payload (small inline edits)").option("--fingerprint <f>", "approve: payloadFingerprint (mandatory with --edit)").option("--payload <json|@file>", "signal: payload").option("--dedupe-key <key>", "signal: dedupe key").option("--local", "replay: replay locally against the compiled artifact").option("--since <dur>", "logs: only events at/after this time (Nd/Nh/Nm or ISO) \xB7 archive-runs: window").option("--yes", "delete/delete-run/schedules delete: skip confirmation").option("--force", "delete: cancel in-flight runs first \xB7 run: seed from a changed graph \xB7 export: overwrite files").option("--step-output <id=json>", "run: complete a step with this output (repeatable)", collect, []).option("--approve <id[=@payload]>", "run: pre-answer an approval (repeatable)", collect, []).option("--deny <id[=@reason]>", "run: pre-deny an approval (repeatable)", collect, []).option("--signal <name=json>", "run: pre-supply a waitForSignal payload (repeatable)", collect, []).option("--from-run <runId>", "run: seed completed steps from a real run").option("--record <dir>", "run: record agent/tool outputs as fixtures").option("--fixtures <dir>", "run: replay recorded fixtures").option("--step-wall <s>", "run: per-step wall in seconds (default 600)").option("--job-wall <s>", "run: virtual wall for tier:'job' steps \u2014 splits at 14400 s segments, > 86400 is exit 2").option("--ledger-out <file>", "run: write the in-memory ledger as JSON").option("--agents <fake|live>", "run: fake agent steps (default) or call the dev API").option("--now <iso>", "run: virtual clock start").option("--park <id>", "run: simulate a platform-fault park of this step (repeatable)", collect, []).option("--fast-retries", "run: collapse retry backoff waits to 0").option("--real-time", "run: actually wait on sleeps/backoffs instead of fast-forwarding").option("--artefacts-dir <dir>", "run: back ctx.artefacts.* on disk").option("--workspace <dir>", "run: the checkout Job-tier code steps run in (ctx.workspace + ctx.exec / ctx.$)").option("--env <KEY=value>", "run: local env.template() overlay (repeatable; missing key \u21D2 exit 2)", collect, []).option("--max-ticks <n>", "run (script form): tick cap before SCRIPT_TICK_LIMIT (default 64)").option("--until <iso>", "archive-runs: window end").option("--out <dir>", "archive-runs: destination dir (archive-index.ndjson + <runId>.zip) \xB7 export: target dir").option("--concurrency <n>", "archive-runs: parallel exports (default 2, max 5)").option("--no-inputs", "archive-runs: exclude run inputs from the bundle").option("--no-artefacts", "archive-runs: exclude artefacts from the bundle").option("--retention-days <n>", "archive-runs: org run retention (default 90) \u2014 --since must fit retention \u2212 7 d").option("--connection <id>", "archive-runs: org storage connection for s3:// / gs:// sinks").option("--release", "workspace: release the run workspace (R42)").option("--attempt <n>", "job-logs: attempt (default latest)").option("--tail <n>", "job-logs: log lines (1..2000, default 200)").option("--objective <text>", "goals create: the objective (\u2264 2000 chars)").option("--judge-predicate <spec>", "goals create: deterministic judge \u2014 '<path> <op> [value]' (e.g. 'output.done truthy'), JSON or @file").option("--judge-agent <agentId|'$self'>", "goals create: judge agent \u2014 write '$self' quoted (or self); it needs --judge-role").option("--judge-role <json|@file>", "goals create: D25 role {name,instructions,tools} for a '$self' judge").option("--schema <json|@file>", "goals create: judge output JsonSchema (must declare a boolean `done`)").option("--cadence <cron|json|@file>", "goals create/schedules create: cadence entry (repeatable, \u2264 5); goals: none \u21D2 immediate", collect, []).option("--timezone <tz>", "goals create/edit/schedules create: IANA timezone for bare cron cadences").option("--notify <emailApp|email|app|off>", "schedules create: where each fire notifies").option("--backfill-on-enable <n|none>", "schedules create/patch/resume: replay \u2264 n missed fires on re-enable (patch: none clears it)").option("--backfill-now", "schedules resume (or patch --paused false): one-shot backfill on THIS re-enable").option("--paused <true|false>", "schedules patch: pause (true) or re-enable (false) the schedule").option("--max-runs <n>", "goals create/edit/raise: iteration cap (1..100)").option("--max-total-credits <n>", "goals create: lineage-wide credit gate").option("--max-credits <n|none>", "goals edit/raise: lineage-wide credit gate (edit: none clears it)").option("--every <interval>", "goals edit/schedules create: interval cadence \u2014 900, 15m, 2h (whole minutes, \u2265 60s)").option("--if-match <updatedAt>", "goals edit/raise: refuse the write if the goal changed since this updatedAt").addHelpText("after", `
71874
73246
  Arguments:
71875
73247
  action list \xB7 view \xB7 versions \xB7 deploy \xB7 activate \xB7 deactivate \xB7 start \xB7 run \xB7 runs \xB7 status \xB7
71876
73248
  watch \xB7 cancel \xB7 resume \xB7 retry-step \xB7 resolve-step \xB7 raise-budget \xB7 approve \xB7 approval-payload \xB7
@@ -72005,7 +73377,7 @@ Examples:
72005
73377
  $ lua mcp deactivate --server-name api-server Deactivate a server
72006
73378
  $ lua mcp delete --server-name old-server Delete a server
72007
73379
  `).action(mcpCommand);
72008
- program2.command("integrations [action] [subaction]").description("\u{1F517} Connect third-party integrations via Unified.to").option("--integration <type>", "Integration type (e.g., linear, googlecalendar)").option("--auth-method <method>", "Authentication method: 'oauth' or 'token'").option("--scopes <scopes>", "Comma-separated OAuth scopes (or 'all' for all scopes)").option("--hide-sensitive <bool>", "Hide sensitive data from MCP tools (default: true)").option("--account-label <label>", "Account label used to distinguish multiple connected accounts").option("--scope <scope>", "Who owns the connection: 'agent' (default) or 'user'").option("--force", "Skip the confirmation prompt (for convert)").option("--connection-id <id>", "Exact connection ID to update, disconnect, convert or pause/resume").option("--connection <id>", "Connection ID for trigger").option("--webhook-id <id>", "Trigger ID to delete/pause/resume").option("--object <type>", "Object type for webhook (e.g., task_task, calendar_event)").option("--event <type>", "Event type for webhook: created, updated, or deleted").option("--hook-url <url>", "Custom webhook URL (default: agent trigger)").option("--interval <minutes>", "Polling interval in minutes for virtual webhooks, 1-2880 (default 1; e.g. 1, 5, 15, 60, 1440, 2880)").option("--triggers <events>", "Comma-separated triggers (e.g., task_task.created,task_task.updated)").option("--custom-webhook", "Use custom webhook URL instead of agent trigger").option("--json", "Output as JSON (for info and webhooks events commands)").option("--reason <text>", "Optional reason for pausing a trigger").addHelpText("after", `
73380
+ program2.command("integrations [action] [subaction]").description("\u{1F517} Connect third-party integrations via Unified.to").option("--integration <type>", "Integration type (e.g., linear, googlecalendar)").option("--auth-method <method>", "Authentication method: 'oauth' or 'token'").option("--scopes <scopes>", "Comma-separated OAuth scopes (or 'all' for all scopes)").option("--hide-sensitive <bool>", "Hide sensitive data from MCP tools (default: true)").option("--account-label <label>", "Account label used to distinguish multiple connected accounts").option("--scope <scope>", "Who owns the connection: 'agent' (default) or 'user'").option("--force", "Skip the confirmation prompt (for convert)").option("--forget", "Also forget what a personal connection (--scope user) added to memory on disconnect (default: false, memories kept)").option("--connection-id <id>", "Exact connection ID to update, disconnect, convert or pause/resume").option("--connection <id>", "Connection ID for trigger").option("--webhook-id <id>", "Trigger ID to delete/pause/resume").option("--object <type>", "Object type for webhook (e.g., task_task, calendar_event)").option("--event <type>", "Event type for webhook: created, updated, or deleted").option("--hook-url <url>", "Custom webhook URL (default: agent trigger)").option("--interval <minutes>", "Polling interval in minutes for virtual webhooks, 1-2880 (default 1; e.g. 1, 5, 15, 60, 1440, 2880)").option("--triggers <events>", "Comma-separated triggers (e.g., task_task.created,task_task.updated)").option("--custom-webhook", "Use custom webhook URL instead of agent trigger").option("--json", "Output as JSON (for info and webhooks events commands)").option("--reason <text>", "Optional reason for pausing a trigger").addHelpText("after", `
72009
73381
  Arguments:
72010
73382
  action Optional: 'connect', 'update', 'list', 'available', 'info', 'disconnect',
72011
73383
  'convert', 'webhooks' (alias: 'triggers'), or 'mcp'
@@ -72024,6 +73396,8 @@ Options:
72024
73396
  --triggers <events> Comma-separated triggers to enable (e.g., task_task.created,task_task.updated)
72025
73397
  --custom-webhook Use custom webhook URL instead of agent trigger
72026
73398
  --hook-url <url> Custom webhook URL (use with --custom-webhook)
73399
+ --forget Disconnect (--scope user): also forget what the connection added to memory
73400
+ (default: false, memories kept)
72027
73401
  --json Output as JSON (for info and webhooks events commands)
72028
73402
 
72029
73403
  Webhook/Trigger Options:
@@ -72036,6 +73410,8 @@ Webhook/Trigger Options:
72036
73410
 
72037
73411
  Note: Multiple accounts of one integration are supported; use --connection-id when updating one.
72038
73412
  Note: Triggers, account labels and --hide-sensitive are agent-scoped; they don't apply to --scope user.
73413
+ Note: --account-label is required under --ci for agent-scoped connects (the label prompt would
73414
+ otherwise fire after OAuth succeeds); --scope defaults to agent under --ci.
72039
73415
 
72040
73416
  Examples:
72041
73417
  $ lua integrations Interactive management
@@ -72055,6 +73431,8 @@ Examples:
72055
73431
  $ lua integrations info linear Show Linear integration details
72056
73432
  $ lua integrations info linear --json Output as JSON (for scripting)
72057
73433
  $ lua integrations disconnect --connection-id abc123 Disconnect an integration
73434
+ $ lua integrations connect --integration github --auth-method oauth --scopes all --account-label 'Support inbox' --ci
73435
+ $ lua integrations disconnect --connection-id abc123 --scope user --forget --ci
72058
73436
 
72059
73437
  Webhook/Trigger Examples ('triggers' is an alias for 'webhooks'):
72060
73438
  $ lua integrations webhooks list List all triggers
@@ -72226,8 +73604,10 @@ Examples:
72226
73604
  `).action(() => versionStatusCommand());
72227
73605
  versionGroup.command("delete <version>").description("Soft-delete a version").option("--force", "Skip confirmation prompt").addHelpText("after", `
72228
73606
  Examples:
72229
- $ lua version delete 3 Delete v3 (confirms first)
72230
- $ lua version delete v3 --force Skip confirmation
73607
+ $ lua version delete 3 Delete v3 (confirms first)
73608
+ $ lua version delete v3 --force Skip confirmation
73609
+ $ lua version delete v3 --ci Refused: needs --force (usage error, exit 2)
73610
+ $ lua version delete v3 --ci --force Delete non-interactively
72231
73611
  `).action((version, opts) => versionDeleteCommand(version, opts));
72232
73612
  const gitGroup = program2.command("git").description("Manage opt-in git auto-commits for this project");
72233
73613
  gitGroup.command("connect").description("Enable git auto-commits (runs sanity checks, writes git.enabled: true)").option("--auto-push", "Also enable post-commit auto-push (requires `lua git auth github` + a GitHub HTTPS origin remote)").action((opts) => gitConnectCommand({