lua-cli 3.39.4 → 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
  }
@@ -2505,6 +2516,180 @@ function scheduledTimeKey(scheduledTime) {
2505
2516
  function scheduledWorkflowRunIdForTime(jobId, scheduledTime) {
2506
2517
  return scheduledWorkflowRunId(jobId, scheduledTime);
2507
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
+ }
2508
2693
  function workflowGoalJudgeKind(judge) {
2509
2694
  return judge && typeof judge === "object" && judge.predicate !== void 0 ? "predicate" : "agent";
2510
2695
  }
@@ -2831,6 +3016,14 @@ function isWebRouteBody(value3) {
2831
3016
  if (b.kind === "text" || b.kind === "base64") return typeof b.value === "string";
2832
3017
  return false;
2833
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
+ }
2834
3027
  function isWebRouteInput(value3) {
2835
3028
  if (!value3 || typeof value3 !== "object") return false;
2836
3029
  const v = value3;
@@ -2839,9 +3032,9 @@ function isWebRouteInput(value3) {
2839
3032
  if (!r || typeof r !== "object") return false;
2840
3033
  if (!WEB_ROUTE_METHODS.includes(String(r.method))) return false;
2841
3034
  if (typeof r.path !== "string" || !r.path.startsWith("/")) return false;
2842
- if (!r.params || typeof r.params !== "object") return false;
2843
- if (!r.query || typeof r.query !== "object") return false;
2844
- if (!r.headers || typeof r.headers !== "object") return false;
3035
+ if (!isStringRecord(r.params)) return false;
3036
+ if (!isQueryRecord(r.query)) return false;
3037
+ if (!isStringRecord(r.headers)) return false;
2845
3038
  if (r.body !== void 0) {
2846
3039
  if (r.method === "GET") return false;
2847
3040
  if (!isWebRouteBody(r.body)) return false;
@@ -2852,7 +3045,299 @@ function isWebRouteInput(value3) {
2852
3045
  if (!app || typeof app.id !== "string" || typeof app.name !== "string" || typeof app.origin !== "string") return false;
2853
3046
  return true;
2854
3047
  }
2855
- 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, 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;
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;
2856
3341
  var init_dist = __esm({
2857
3342
  "../shared-types/dist/index.mjs"() {
2858
3343
  "use strict";
@@ -2897,6 +3382,35 @@ var init_dist = __esm({
2897
3382
  __name2(personaToLiteral, "personaToLiteral");
2898
3383
  __name(aiGenerateInputFromSimplified, "aiGenerateInputFromSimplified");
2899
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");
2900
3414
  REVIEWABLE_ACTION_EXECUTE_TOOL_ALLOWLIST = [
2901
3415
  "sendChannelMessage",
2902
3416
  "sendWhatsappTemplate",
@@ -3601,7 +4115,8 @@ This text is who you are for this person. As you learn them, their name, their w
3601
4115
  "model-resolver",
3602
4116
  "workflow-step",
3603
4117
  "workflow-script",
3604
- "workflow"
4118
+ "workflow",
4119
+ "supervision"
3605
4120
  ];
3606
4121
  AGENT_LOG_ENVIRONMENTS = [
3607
4122
  "production",
@@ -4745,6 +5260,41 @@ This text is who you are for this person. As you learn them, their name, their w
4745
5260
  ];
4746
5261
  WORKFLOW_SIGNAL_PAYLOAD_MAX_BYTES = 64 * 1024;
4747
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");
4748
5298
  WORKFLOW_GOAL_JUDGE_SELF = "$self";
4749
5299
  __name(workflowGoalJudgeKind, "workflowGoalJudgeKind");
4750
5300
  __name2(workflowGoalJudgeKind, "workflowGoalJudgeKind");
@@ -5383,8 +5933,119 @@ listed here; never invent a target.`;
5383
5933
  WEB_ROUTE_MAX_RESPONSE_BYTES = 4 * 1024 * 1024;
5384
5934
  __name(isWebRouteBody, "isWebRouteBody");
5385
5935
  __name2(isWebRouteBody, "isWebRouteBody");
5936
+ __name(isStringRecord, "isStringRecord");
5937
+ __name2(isStringRecord, "isStringRecord");
5938
+ __name(isQueryRecord, "isQueryRecord");
5939
+ __name2(isQueryRecord, "isQueryRecord");
5386
5940
  __name(isWebRouteInput, "isWebRouteInput");
5387
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");
5388
6049
  }
5389
6050
  });
5390
6051
 
@@ -5999,7 +6660,31 @@ function effectiveJobTools(jobTools, readOnly) {
5999
6660
  }
6000
6661
  return out;
6001
6662
  }
6002
- 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;
6003
6688
  var init_workflow_job_tools = __esm({
6004
6689
  "../shared-types/dist/workflow-job-tools.mjs"() {
6005
6690
  "use strict";
@@ -6034,6 +6719,19 @@ var init_workflow_job_tools = __esm({
6034
6719
  ];
6035
6720
  __name(effectiveJobTools, "effectiveJobTools");
6036
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");
6037
6735
  }
6038
6736
  });
6039
6737
 
@@ -6984,6 +7682,26 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
6984
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);
6985
7683
  }
6986
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
+ }
6987
7705
  if (node.type === "agent" && ws && ws !== "inherit" && ws.mount === "ro" && Array.isArray(tools) && effectiveJobTools(tools, true).length === 0) {
6988
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);
6989
7707
  }
@@ -10452,6 +11170,15 @@ function createWorkflow(cfg) {
10452
11170
  const n2 = cfg.backfillOnEnable.maxOccurrences;
10453
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)");
10454
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
+ }
10455
11182
  const keys = /* @__PURE__ */ new Set();
10456
11183
  envRefKeys(cfg.schedule, keys);
10457
11184
  envRefKeys(cfg.workspace, keys);
@@ -10476,6 +11203,7 @@ var init2, state2, lit2, eq2, ne2, gt2, gte2, lt2, lte2, inSet2, notIn2, exists2
10476
11203
  var init_workflow = __esm({
10477
11204
  "src/types/workflow.ts"() {
10478
11205
  "use strict";
11206
+ init_workflow_job_tools();
10479
11207
  init_dist();
10480
11208
  init_dist2();
10481
11209
  __name(createStep, "createStep");
@@ -10974,6 +11702,15 @@ var init_workflow = __esm({
10974
11702
  throw new LuaWorkflowBuildError("max-turns-invalid", `"${id2}": ${m} must be an integer ${min}..${max}`);
10975
11703
  }
10976
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
+ }
10977
11714
  assertTimeout({
10978
11715
  id: id2,
10979
11716
  timeoutSeconds: opts.timeoutSeconds,
@@ -11006,7 +11743,9 @@ var init_workflow = __esm({
11006
11743
  harness: opts.harness,
11007
11744
  maxTurns: opts.maxTurns,
11008
11745
  maxMessages: opts.maxMessages,
11009
- maxInputTokens: opts.maxInputTokens
11746
+ maxInputTokens: opts.maxInputTokens,
11747
+ plugins: opts.plugins,
11748
+ target: opts.target
11010
11749
  });
11011
11750
  return this.push({
11012
11751
  kind: "declare",
@@ -11799,18 +12538,18 @@ var init_http_client = __esm({
11799
12538
  * Use this only when a successful response contains a one-time secret that
11800
12539
  * cannot be recovered after an ambiguous network or server failure.
11801
12540
  */
11802
- async httpPostOnce(url, data, headers) {
12541
+ async httpPostOnce(url, data, headers, overrides) {
11803
12542
  return this.retryableRequest(this.baseUrl + url, {
11804
12543
  method: "POST",
11805
12544
  body: data ? JSON.stringify(data) : void 0,
11806
12545
  headers
11807
- }, 0);
12546
+ }, 0, overrides);
11808
12547
  }
11809
- async httpPostCoreDrainRetry(url, data, headers) {
11810
- 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);
11811
12550
  if (!isCoreDrainApiError(first.error)) return first;
11812
12551
  await new Promise((resolve7) => setTimeout(resolve7, coreDrainApiRetryDelayMs(first.error)));
11813
- return this.httpPostOnce(url, data, headers);
12552
+ return this.httpPostOnce(url, data, headers, overrides);
11814
12553
  }
11815
12554
  /**
11816
12555
  * Performs an HTTP PUT request
@@ -13388,7 +14127,7 @@ var init_base_handler = __esm({
13388
14127
  if (syncVersions && Array.isArray(versions) && versions.length > 0) {
13389
14128
  const activeVersion = this.getActiveVersion(serverItem);
13390
14129
  const currentVersion = item.version;
13391
- if (activeVersion && activeVersion !== currentVersion) {
14130
+ if (activeVersion && compareVersions(activeVersion, currentVersion) > 0) {
13392
14131
  const msg = `\u{1F4DD} Updated "${item.name}" ${this.displayName} version: ${currentVersion} \u2192 ${activeVersion}`;
13393
14132
  msgs.push(msg);
13394
14133
  console.log(msg);
@@ -15933,6 +16672,7 @@ var init_job_plugin = __esm({
15933
16672
  "src/compiler/plugins/job.plugin.ts"() {
15934
16673
  "use strict";
15935
16674
  init_base();
16675
+ init_dist();
15936
16676
  init_ast_helpers();
15937
16677
  init_class_hierarchy();
15938
16678
  JobPlugin = class extends BasePlugin {
@@ -15978,6 +16718,8 @@ var init_job_plugin = __esm({
15978
16718
  maxAttempts: extractNestedProperty(retryObj, "maxAttempts"),
15979
16719
  backoffSeconds: extractNestedProperty(retryObj, "backoffSeconds")
15980
16720
  } : void 0;
16721
+ const healthHit = findClassMember(classDecl, "health", "property");
16722
+ const healthConfig = healthHit && Node5.isPropertyDeclaration(healthHit.node) ? evaluateNodeAsObject(healthHit.node.getInitializer()) : void 0;
15981
16723
  return {
15982
16724
  kind: this.kind,
15983
16725
  name,
@@ -15998,7 +16740,9 @@ var init_job_plugin = __esm({
15998
16740
  hasTimeout: timeoutHit !== void 0,
15999
16741
  hasRetry: retryHit !== void 0,
16000
16742
  timeoutValue,
16001
- retryConfig
16743
+ retryConfig,
16744
+ hasHealth: healthHit !== void 0,
16745
+ healthConfig
16002
16746
  }
16003
16747
  };
16004
16748
  }
@@ -16013,6 +16757,7 @@ var init_job_plugin = __esm({
16013
16757
  schedule: __lua_instance__.schedule,
16014
16758
  timeout: __lua_instance__.timeout,
16015
16759
  retry: __lua_instance__.retry,
16760
+ health: __lua_instance__.health,
16016
16761
  execute: typeof __lua_instance__.execute === 'function' ? __lua_instance__.execute.bind(__lua_instance__) : undefined,
16017
16762
  }`;
16018
16763
  }
@@ -16034,6 +16779,7 @@ var init_job_plugin = __esm({
16034
16779
  maxAttempts: extractNestedProperty(retryObj, "maxAttempts"),
16035
16780
  backoffSeconds: extractNestedProperty(retryObj, "backoffSeconds")
16036
16781
  } : void 0;
16782
+ const healthConfig = extractObjectProperty(config, "health");
16037
16783
  return {
16038
16784
  kind: this.kind,
16039
16785
  ...common,
@@ -16048,7 +16794,9 @@ var init_job_plugin = __esm({
16048
16794
  hasTimeout: config.getProperty("timeout") !== void 0,
16049
16795
  hasRetry: config.getProperty("retry") !== void 0,
16050
16796
  timeoutValue,
16051
- retryConfig
16797
+ retryConfig,
16798
+ hasHealth: config.getProperty("health") !== void 0,
16799
+ healthConfig
16052
16800
  }
16053
16801
  };
16054
16802
  }
@@ -16075,6 +16823,29 @@ var init_job_plugin = __esm({
16075
16823
  line: metadata.line
16076
16824
  }));
16077
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
+ }
16078
16849
  return {
16079
16850
  valid: errors.length === 0,
16080
16851
  errors,
@@ -16102,7 +16873,10 @@ var init_job_plugin = __esm({
16102
16873
  timezone: jobMeta.scheduleTimezone
16103
16874
  } : void 0,
16104
16875
  timeout: jobMeta.timeoutValue,
16105
- retry: jobMeta.retryConfig
16876
+ retry: jobMeta.retryConfig,
16877
+ ...jobMeta.healthConfig ? {
16878
+ health: jobMeta.healthConfig
16879
+ } : {}
16106
16880
  };
16107
16881
  }
16108
16882
  };
@@ -18132,7 +18906,7 @@ function shapeReasoningSetting(value3) {
18132
18906
  return Object.keys(result).length > 0 ? result : void 0;
18133
18907
  }
18134
18908
  function shapeModelSettings(raw) {
18135
- const KNOWN_KEYS = [
18909
+ const KNOWN_KEYS2 = [
18136
18910
  "temperature",
18137
18911
  "topP",
18138
18912
  "topK",
@@ -18144,7 +18918,7 @@ function shapeModelSettings(raw) {
18144
18918
  "reasoning"
18145
18919
  ];
18146
18920
  const result = {};
18147
- for (const key of KNOWN_KEYS) {
18921
+ for (const key of KNOWN_KEYS2) {
18148
18922
  const value3 = raw[key];
18149
18923
  if (value3 === void 0) continue;
18150
18924
  if (key === "stopSequences") {
@@ -22270,6 +23044,8 @@ function metaOf(node, sources) {
22270
23044
  pick("outputSchema", n2.outputSchema);
22271
23045
  const jobTools = n2.toolScope?.jobTools;
22272
23046
  pick("jobTools", jobTools);
23047
+ pick("plugins", n2.plugins);
23048
+ pick("target", n2.target);
22273
23049
  }
22274
23050
  if (n2.type === "approval") {
22275
23051
  pick("editedPayloadSchema", n2.editedPayloadSchema);
@@ -23152,6 +23928,7 @@ ${firstBundleFrame(vmResult.error.stack)}` : ""}`,
23152
23928
  schedule: config.schedule,
23153
23929
  scheduleInput: config.scheduleInput,
23154
23930
  backfillOnEnable: config.backfillOnEnable,
23931
+ health: config.health,
23155
23932
  outputVisibility: config.outputVisibility,
23156
23933
  goal: config.goal
23157
23934
  };
@@ -27162,6 +27939,48 @@ var init_integrations_api_service = __esm({
27162
27939
  });
27163
27940
 
27164
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
+ }
27165
27984
  var AgentsApiService;
27166
27985
  var init_agents_api_service = __esm({
27167
27986
  "src/api/agents.api.service.ts"() {
@@ -27181,7 +28000,9 @@ var init_agents_api_service = __esm({
27181
28000
  });
27182
28001
  if (body.identifier) query.set("identifier", body.identifier);
27183
28002
  const chatBody = this.toChatGenerateBody(body);
27184
- 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);
27185
28006
  }
27186
28007
  /**
27187
28008
  * Sandbox overload: mirrors the `AI.generate` pattern where the simplified
@@ -27199,7 +28020,128 @@ var init_agents_api_service = __esm({
27199
28020
  if (!result.data) {
27200
28021
  throw new Error("Agent invocation failed: empty response");
27201
28022
  }
27202
- 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
+ }
27203
28145
  }
27204
28146
  toChatGenerateBody(body) {
27205
28147
  const messages = body.messages ? body.messages : [
@@ -27225,10 +28167,15 @@ var init_agents_api_service = __esm({
27225
28167
  } : {},
27226
28168
  ...body.clientContext !== void 0 ? {
27227
28169
  clientContext: body.clientContext
28170
+ } : {},
28171
+ ...body.model !== void 0 ? {
28172
+ model: body.model
27228
28173
  } : {}
27229
28174
  };
27230
28175
  }
27231
28176
  };
28177
+ __name(toInvocationOutput, "toInvocationOutput");
28178
+ __name(runSummary, "runSummary");
27232
28179
  }
27233
28180
  });
27234
28181
 
@@ -29279,6 +30226,9 @@ var init_mcp_server_handler = __esm({
29279
30226
  name: server.name,
29280
30227
  transport: server.config?.transport || "streamable-http"
29281
30228
  };
30229
+ if (server.description) {
30230
+ result.description = server.description;
30231
+ }
29282
30232
  if (server.config?.url !== void 0) {
29283
30233
  result.url = server.config.url;
29284
30234
  }
@@ -33353,7 +34303,7 @@ async function syncCommand(options) {
33353
34303
  try {
33354
34304
  writeProgress("\u{1F504} Compiling to get latest local state...");
33355
34305
  await compileCommand({
33356
- serverSync: true
34306
+ serverSync: !options?.check
33357
34307
  });
33358
34308
  writeProgress("\u{1F504} Checking for drift between server and local code...");
33359
34309
  const { agentId, apiKey } = await initializeCommand({
@@ -34461,7 +35411,7 @@ var JobHandler = class extends BaseVersionedHandler {
34461
35411
  };
34462
35412
  }
34463
35413
  /**
34464
- * 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.
34465
35415
  */
34466
35416
  buildPushData(primitive, compressedCode, codeS3Hash) {
34467
35417
  const job = primitive;
@@ -34476,7 +35426,11 @@ var JobHandler = class extends BaseVersionedHandler {
34476
35426
  schedule: job.schedule,
34477
35427
  timeout: job.timeout,
34478
35428
  retry: job.retry,
34479
- 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
+ } : {}
34480
35434
  };
34481
35435
  }
34482
35436
  };
@@ -35131,6 +36085,105 @@ init_workflow_api_service();
35131
36085
  init_artifact_loader();
35132
36086
  init_bundle_upload();
35133
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
+
35134
36187
  // src/utils/sandbox.ts
35135
36188
  init_dist4();
35136
36189
  import vm4 from "vm";
@@ -35251,8 +36304,8 @@ import path19 from "path";
35251
36304
  import { spawn as nodeSpawn } from "child_process";
35252
36305
  import { accessSync, constants as fsConstants, realpathSync, statSync as statSync5 } from "fs";
35253
36306
  import path18 from "path";
35254
- var __defProp7 = Object.defineProperty;
35255
- 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");
35256
36309
  var WORKFLOW_EXEC_BINARIES = Object.freeze([
35257
36310
  "git",
35258
36311
  "gh",
@@ -35276,7 +36329,7 @@ var WorkflowExecError = class extends Error {
35276
36329
  __name(this, "WorkflowExecError");
35277
36330
  }
35278
36331
  static {
35279
- __name7(this, "WorkflowExecError");
36332
+ __name8(this, "WorkflowExecError");
35280
36333
  }
35281
36334
  code;
35282
36335
  reason;
@@ -35310,7 +36363,7 @@ function isWorkflowExecError(err) {
35310
36363
  return !!e && typeof e === "object" && e.name === "ExecError" && typeof e.code === "string";
35311
36364
  }
35312
36365
  __name(isWorkflowExecError, "isWorkflowExecError");
35313
- __name7(isWorkflowExecError, "isWorkflowExecError");
36366
+ __name8(isWorkflowExecError, "isWorkflowExecError");
35314
36367
  function workflowExecRefusal(reason, detail, argv) {
35315
36368
  return new WorkflowExecError("EXEC_REFUSED", `[Lua] exec refused: ${detail} (EXEC_REFUSED/${reason})`, {
35316
36369
  reason,
@@ -35320,7 +36373,7 @@ function workflowExecRefusal(reason, detail, argv) {
35320
36373
  });
35321
36374
  }
35322
36375
  __name(workflowExecRefusal, "workflowExecRefusal");
35323
- __name7(workflowExecRefusal, "workflowExecRefusal");
36376
+ __name8(workflowExecRefusal, "workflowExecRefusal");
35324
36377
  var refused = workflowExecRefusal;
35325
36378
  var ALLOWLIST_TEXT = WORKFLOW_EXEC_BINARIES.join(", ");
35326
36379
  function parseCommandTemplate(template3, values) {
@@ -35331,13 +36384,13 @@ function parseCommandTemplate(template3, values) {
35331
36384
  const argv = [];
35332
36385
  let current = null;
35333
36386
  let quote = null;
35334
- const flush = /* @__PURE__ */ __name7(() => {
36387
+ const flush = /* @__PURE__ */ __name8(() => {
35335
36388
  if (current !== null) {
35336
36389
  argv.push(current);
35337
36390
  current = null;
35338
36391
  }
35339
36392
  }, "flush");
35340
- const scalar = /* @__PURE__ */ __name7((v, at) => {
36393
+ const scalar = /* @__PURE__ */ __name8((v, at) => {
35341
36394
  if (typeof v === "string") return v;
35342
36395
  if (typeof v === "number" && Number.isFinite(v)) return String(v);
35343
36396
  if (typeof v === "boolean") return String(v);
@@ -35398,7 +36451,7 @@ function parseCommandTemplate(template3, values) {
35398
36451
  return argv;
35399
36452
  }
35400
36453
  __name(parseCommandTemplate, "parseCommandTemplate");
35401
- __name7(parseCommandTemplate, "parseCommandTemplate");
36454
+ __name8(parseCommandTemplate, "parseCommandTemplate");
35402
36455
  function validateWorkflowExecArgv(argv) {
35403
36456
  if (!Array.isArray(argv)) throw refused("argv_invalid", 'argv must be an array of strings \u2014 exec(["git", "status"])');
35404
36457
  if (argv.length === 0) throw refused("argv_empty", "the command is empty");
@@ -35420,7 +36473,7 @@ function validateWorkflowExecArgv(argv) {
35420
36473
  ];
35421
36474
  }
35422
36475
  __name(validateWorkflowExecArgv, "validateWorkflowExecArgv");
35423
- __name7(validateWorkflowExecArgv, "validateWorkflowExecArgv");
36476
+ __name8(validateWorkflowExecArgv, "validateWorkflowExecArgv");
35424
36477
  function resolveWorkflowExecBinary(name, pathDirs) {
35425
36478
  if (typeof name !== "string" || name.length === 0) throw refused("argv_invalid", "argv[0] must name a binary");
35426
36479
  if (name.includes("/") || name.includes("\\") || name.startsWith(".")) {
@@ -35449,12 +36502,12 @@ function resolveWorkflowExecBinary(name, pathDirs) {
35449
36502
  ]);
35450
36503
  }
35451
36504
  __name(resolveWorkflowExecBinary, "resolveWorkflowExecBinary");
35452
- __name7(resolveWorkflowExecBinary, "resolveWorkflowExecBinary");
36505
+ __name8(resolveWorkflowExecBinary, "resolveWorkflowExecBinary");
35453
36506
  function within(root, p) {
35454
36507
  return p === root || p.startsWith(root.endsWith(path18.sep) ? root : root + path18.sep);
35455
36508
  }
35456
36509
  __name(within, "within");
35457
- __name7(within, "within");
36510
+ __name8(within, "within");
35458
36511
  function confineWorkflowExecCwd(root, cwd) {
35459
36512
  if (typeof root !== "string" || root.length === 0) throw refused("workspace_unavailable", "the step has no workspace");
35460
36513
  let rootReal;
@@ -35488,7 +36541,7 @@ function confineWorkflowExecCwd(root, cwd) {
35488
36541
  return abs;
35489
36542
  }
35490
36543
  __name(confineWorkflowExecCwd, "confineWorkflowExecCwd");
35491
- __name7(confineWorkflowExecCwd, "confineWorkflowExecCwd");
36544
+ __name8(confineWorkflowExecCwd, "confineWorkflowExecCwd");
35492
36545
  var RESERVED_ENV_KEY = /^(LUA_|LD_|DYLD_|GIT_|GH_|GITHUB_)|^(PATH|HOME|NODE_OPTIONS|BASH_ENV|ENV|TZ)$|_PROXY$/i;
35493
36546
  function checkWorkflowExecEnv(env) {
35494
36547
  if (env === void 0) return {};
@@ -35506,7 +36559,7 @@ function checkWorkflowExecEnv(env) {
35506
36559
  return out;
35507
36560
  }
35508
36561
  __name(checkWorkflowExecEnv, "checkWorkflowExecEnv");
35509
- __name7(checkWorkflowExecEnv, "checkWorkflowExecEnv");
36562
+ __name8(checkWorkflowExecEnv, "checkWorkflowExecEnv");
35510
36563
  var WORKFLOW_EXEC_GIT_DENIED_SUBCOMMANDS = Object.freeze([
35511
36564
  "push-mirror",
35512
36565
  "daemon",
@@ -35536,7 +36589,7 @@ function gitOptionMatches(arg, opt) {
35536
36589
  return opt.length === 2 && arg.length > 2 && arg.startsWith(opt);
35537
36590
  }
35538
36591
  __name(gitOptionMatches, "gitOptionMatches");
35539
- __name7(gitOptionMatches, "gitOptionMatches");
36592
+ __name8(gitOptionMatches, "gitOptionMatches");
35540
36593
  var GIT_PUSH_FORBIDDEN_FLAG = /^(--mirror|--delete|-d|-f|--force|--force-with-lease(=.*)?|--force-if-includes|--prune|--all|--tags)$/;
35541
36594
  function checkWorkflowExecGitArgv(argv, opts = {}) {
35542
36595
  if (argv[0] !== "git") return {};
@@ -35579,9 +36632,9 @@ function checkWorkflowExecGitArgv(argv, opts = {}) {
35579
36632
  };
35580
36633
  }
35581
36634
  __name(checkWorkflowExecGitArgv, "checkWorkflowExecGitArgv");
35582
- __name7(checkWorkflowExecGitArgv, "checkWorkflowExecGitArgv");
36635
+ __name8(checkWorkflowExecGitArgv, "checkWorkflowExecGitArgv");
35583
36636
  function formatWorkflowExecArgv(argv, max = WORKFLOW_EXEC_LOG_ARGV_MAX) {
35584
- const q = /* @__PURE__ */ __name7((a) => {
36637
+ const q = /* @__PURE__ */ __name8((a) => {
35585
36638
  const s = String(a);
35586
36639
  return s.length > 0 && /^[A-Za-z0-9_@%+=:,./-]+$/.test(s) ? s : `'${s.replace(/'/g, "'\\''")}'`;
35587
36640
  }, "q");
@@ -35589,7 +36642,7 @@ function formatWorkflowExecArgv(argv, max = WORKFLOW_EXEC_LOG_ARGV_MAX) {
35589
36642
  return line.length > max ? `${line.slice(0, max)}\u2026` : line;
35590
36643
  }
35591
36644
  __name(formatWorkflowExecArgv, "formatWorkflowExecArgv");
35592
- __name7(formatWorkflowExecArgv, "formatWorkflowExecArgv");
36645
+ __name8(formatWorkflowExecArgv, "formatWorkflowExecArgv");
35593
36646
  function spawnWorkflowExec(o) {
35594
36647
  const spawnFn = o.spawnImpl ?? nodeSpawn;
35595
36648
  const max = o.outputMaxBytes ?? WORKFLOW_EXEC_OUTPUT_MAX_BYTES;
@@ -35624,7 +36677,7 @@ function spawnWorkflowExec(o) {
35624
36677
  let settled = false;
35625
36678
  let killTimer;
35626
36679
  let wallTimer;
35627
- const collect2 = /* @__PURE__ */ __name7((stream) => {
36680
+ const collect2 = /* @__PURE__ */ __name8((stream) => {
35628
36681
  const chunks = [];
35629
36682
  let bytes = 0;
35630
36683
  stream?.on("data", (c) => {
@@ -35647,7 +36700,7 @@ function spawnWorkflowExec(o) {
35647
36700
  }, "collect");
35648
36701
  const stdout = collect2(child.stdout);
35649
36702
  const stderr = collect2(child.stderr);
35650
- const killTree = /* @__PURE__ */ __name7((sig) => {
36703
+ const killTree = /* @__PURE__ */ __name8((sig) => {
35651
36704
  const pid = child.pid;
35652
36705
  if (!pid) return;
35653
36706
  try {
@@ -35656,7 +36709,7 @@ function spawnWorkflowExec(o) {
35656
36709
  } catch {
35657
36710
  }
35658
36711
  }, "killTree");
35659
- const end = /* @__PURE__ */ __name7(() => {
36712
+ const end = /* @__PURE__ */ __name8(() => {
35660
36713
  if (settled || timedOut) return;
35661
36714
  timedOut = true;
35662
36715
  killTree("SIGTERM");
@@ -35667,7 +36720,7 @@ function spawnWorkflowExec(o) {
35667
36720
  }, grace);
35668
36721
  killTimer.unref?.();
35669
36722
  }, "end");
35670
- const cleanup = /* @__PURE__ */ __name7(() => {
36723
+ const cleanup = /* @__PURE__ */ __name8(() => {
35671
36724
  if (wallTimer) clearTimeout(wallTimer);
35672
36725
  if (killTimer) clearTimeout(killTimer);
35673
36726
  o.signal?.removeEventListener("abort", end);
@@ -35701,7 +36754,7 @@ function spawnWorkflowExec(o) {
35701
36754
  });
35702
36755
  }
35703
36756
  __name(spawnWorkflowExec, "spawnWorkflowExec");
35704
- __name7(spawnWorkflowExec, "spawnWorkflowExec");
36757
+ __name8(spawnWorkflowExec, "spawnWorkflowExec");
35705
36758
  async function runWorkflowExec(o) {
35706
36759
  const argv = validateWorkflowExecArgv(o.request.argv);
35707
36760
  const file = resolveWorkflowExecBinary(argv[0], o.pathDirs);
@@ -35747,7 +36800,7 @@ async function runWorkflowExec(o) {
35747
36800
  });
35748
36801
  }
35749
36802
  __name(runWorkflowExec, "runWorkflowExec");
35750
- __name7(runWorkflowExec, "runWorkflowExec");
36803
+ __name8(runWorkflowExec, "runWorkflowExec");
35751
36804
  function createWorkflowExecQueue() {
35752
36805
  let tail = Promise.resolve();
35753
36806
  return (task) => {
@@ -35757,7 +36810,7 @@ function createWorkflowExecQueue() {
35757
36810
  };
35758
36811
  }
35759
36812
  __name(createWorkflowExecQueue, "createWorkflowExecQueue");
35760
- __name7(createWorkflowExecQueue, "createWorkflowExecQueue");
36813
+ __name8(createWorkflowExecQueue, "createWorkflowExecQueue");
35761
36814
  function stderrTail(s) {
35762
36815
  const t = s.trim();
35763
36816
  if (!t) return "";
@@ -35765,9 +36818,9 @@ function stderrTail(s) {
35765
36818
  return `: ${tail.replace(/\s+/g, " ")}`;
35766
36819
  }
35767
36820
  __name(stderrTail, "stderrTail");
35768
- __name7(stderrTail, "stderrTail");
36821
+ __name8(stderrTail, "stderrTail");
35769
36822
  function buildWorkflowExecApi(run) {
35770
- const call = /* @__PURE__ */ __name7(async (req, strict) => {
36823
+ const call = /* @__PURE__ */ __name8(async (req, strict) => {
35771
36824
  const out = await run(req);
35772
36825
  if (out.timedOut) {
35773
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);
@@ -35777,7 +36830,7 @@ function buildWorkflowExecApi(run) {
35777
36830
  }
35778
36831
  return out;
35779
36832
  }, "call");
35780
- const request2 = /* @__PURE__ */ __name7((argv, opts) => {
36833
+ const request2 = /* @__PURE__ */ __name8((argv, opts) => {
35781
36834
  const o = opts && typeof opts === "object" ? opts : {};
35782
36835
  return {
35783
36836
  argv,
@@ -35786,9 +36839,9 @@ function buildWorkflowExecApi(run) {
35786
36839
  env: o.env
35787
36840
  };
35788
36841
  }, "request");
35789
- 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");
35790
36843
  exec.strict = (argv, opts) => call(request2(argv, opts), true);
35791
- const $ = /* @__PURE__ */ __name7(async (strings, ...values) => call({
36844
+ const $ = /* @__PURE__ */ __name8(async (strings, ...values) => call({
35792
36845
  argv: parseCommandTemplate(strings, values)
35793
36846
  }, false), "$");
35794
36847
  $.strict = async (strings, ...values) => call({
@@ -35800,16 +36853,16 @@ function buildWorkflowExecApi(run) {
35800
36853
  };
35801
36854
  }
35802
36855
  __name(buildWorkflowExecApi, "buildWorkflowExecApi");
35803
- __name7(buildWorkflowExecApi, "buildWorkflowExecApi");
36856
+ __name8(buildWorkflowExecApi, "buildWorkflowExecApi");
35804
36857
  function unavailableWorkflowExecApi(why) {
35805
- const reject = /* @__PURE__ */ __name7(async () => {
36858
+ const reject = /* @__PURE__ */ __name8(async () => {
35806
36859
  throw new WorkflowExecError("EXEC_UNAVAILABLE", `[Lua] ctx.exec is not available here: ${why} (EXEC_UNAVAILABLE)`);
35807
36860
  }, "reject");
35808
36861
  const exec = Object.assign(() => reject(), {
35809
- strict: /* @__PURE__ */ __name7(() => reject(), "strict")
36862
+ strict: /* @__PURE__ */ __name8(() => reject(), "strict")
35810
36863
  });
35811
36864
  const $ = Object.assign(() => reject(), {
35812
- strict: /* @__PURE__ */ __name7(() => reject(), "strict")
36865
+ strict: /* @__PURE__ */ __name8(() => reject(), "strict")
35813
36866
  });
35814
36867
  return {
35815
36868
  exec,
@@ -35817,7 +36870,7 @@ function unavailableWorkflowExecApi(why) {
35817
36870
  };
35818
36871
  }
35819
36872
  __name(unavailableWorkflowExecApi, "unavailableWorkflowExecApi");
35820
- __name7(unavailableWorkflowExecApi, "unavailableWorkflowExecApi");
36873
+ __name8(unavailableWorkflowExecApi, "unavailableWorkflowExecApi");
35821
36874
 
35822
36875
  // src/utils/workflow-exec.ts
35823
36876
  var WORKFLOW_LOCAL_EXEC_ENV_KEYS = [
@@ -37610,7 +38663,14 @@ function createSandbox(options) {
37610
38663
  const { getAgentsInstance: getAgentsInstance2 } = await Promise.resolve().then(() => (init_lazy_instances(), lazy_instances_exports));
37611
38664
  const agents = await getAgentsInstance2();
37612
38665
  return agents.invokeForSandbox(targetAgentId, promptOrInput);
37613
- }, "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
+ })
37614
38674
  },
37615
38675
  // Unified.to raw provider passthrough (PRO-209). Proxied via the same
37616
38676
  // bearer-auth developer route the api-exports `Integrations` namespace
@@ -38339,6 +39399,10 @@ var WorkflowHandler = class extends BaseVersionedHandler {
38339
39399
  ...wf.backfillOnEnable ? {
38340
39400
  backfillOnEnable: wf.backfillOnEnable
38341
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
+ } : {},
38342
39406
  ...wf.goal ? {
38343
39407
  goal: wf.goal
38344
39408
  } : {}
@@ -39809,8 +40873,8 @@ import vm5 from "vm";
39809
40873
  import { createHash as createHash7, randomUUID as randomUUID4 } from "crypto";
39810
40874
 
39811
40875
  // ../sandbox-runtime/dist/workflow-script-wrapper.mjs
39812
- var __defProp8 = Object.defineProperty;
39813
- 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");
39814
40878
  var WORKFLOW_SCRIPT_RUNTIME_KEY = "__luaWorkflowScriptRuntime";
39815
40879
  var WORKFLOW_SCRIPT_PROTOCOL_VERSION = 1;
39816
40880
  var WORKFLOW_SCRIPT_DEFAULT_CAPS = {
@@ -40145,18 +41209,18 @@ function computeWorkflowProtocolShipWindow(input) {
40145
41209
  };
40146
41210
  }
40147
41211
  __name(computeWorkflowProtocolShipWindow, "computeWorkflowProtocolShipWindow");
40148
- __name8(computeWorkflowProtocolShipWindow, "computeWorkflowProtocolShipWindow");
41212
+ __name9(computeWorkflowProtocolShipWindow, "computeWorkflowProtocolShipWindow");
40149
41213
  var WORKFLOW_SCRIPT_EFFORT_PROTOCOL_VERSION = 2;
40150
41214
  function scriptEffortForwardable(journalProtocolVersion) {
40151
41215
  return typeof journalProtocolVersion === "number" && journalProtocolVersion >= WORKFLOW_SCRIPT_EFFORT_PROTOCOL_VERSION;
40152
41216
  }
40153
41217
  __name(scriptEffortForwardable, "scriptEffortForwardable");
40154
- __name8(scriptEffortForwardable, "scriptEffortForwardable");
41218
+ __name9(scriptEffortForwardable, "scriptEffortForwardable");
40155
41219
  function workflowScriptReplaySource(journalProtocolVersion) {
40156
41220
  return WORKFLOW_SCRIPT_PROTOCOL_VERSIONS.includes(journalProtocolVersion) ? WORKFLOW_SCRIPT_REPLAY_SOURCES[journalProtocolVersion] : void 0;
40157
41221
  }
40158
41222
  __name(workflowScriptReplaySource, "workflowScriptReplaySource");
40159
- __name8(workflowScriptReplaySource, "workflowScriptReplaySource");
41223
+ __name9(workflowScriptReplaySource, "workflowScriptReplaySource");
40160
41224
  var HOST_BINDINGS = [
40161
41225
  "args",
40162
41226
  "agent",
@@ -40185,7 +41249,7 @@ function transformWorkflowScriptModule(script) {
40185
41249
  return script.replace(/^\s*export\s+const\s+meta\s*=/m, "const meta =");
40186
41250
  }
40187
41251
  __name(transformWorkflowScriptModule, "transformWorkflowScriptModule");
40188
- __name8(transformWorkflowScriptModule, "transformWorkflowScriptModule");
41252
+ __name9(transformWorkflowScriptModule, "transformWorkflowScriptModule");
40189
41253
  function buildWorkflowScriptWrapper(script, input) {
40190
41254
  const tick = input ?? {};
40191
41255
  const version = tick.journalProtocolVersion ?? WORKFLOW_SCRIPT_PROTOCOL_VERSION;
@@ -40235,7 +41299,7 @@ ${transformWorkflowScriptModule(script)}
40235
41299
  };
40236
41300
  }
40237
41301
  __name(buildWorkflowScriptWrapper, "buildWorkflowScriptWrapper");
40238
- __name8(buildWorkflowScriptWrapper, "buildWorkflowScriptWrapper");
41302
+ __name9(buildWorkflowScriptWrapper, "buildWorkflowScriptWrapper");
40239
41303
 
40240
41304
  // src/utils/workflow-script-replay.ts
40241
41305
  var ReplayRuntimeUnavailableError = class extends Error {
@@ -40671,7 +41735,7 @@ async function runWorkflowLocalFromProject(name, flags) {
40671
41735
  artefactsDir: flags.artefactsDir,
40672
41736
  workspaceDir: flags.workspace ? path23.resolve(flags.workspace) : void 0,
40673
41737
  env: parseEnvFlags(flags.env),
40674
- prompt: process.stdin.isTTY && !asJson ? promptForLocalDecision : void 0,
41738
+ prompt: process.stdin.isTTY && !asJson && !isCiModeEnabled() ? promptForLocalDecision : void 0,
40675
41739
  log: asJson ? void 0 : (line) => console.log(line)
40676
41740
  });
40677
41741
  } finally {
@@ -41664,6 +42728,7 @@ init_cli();
41664
42728
  init_command_utils();
41665
42729
  init_semver();
41666
42730
  init_auth_error();
42731
+ init_cli_error();
41667
42732
  init_constants();
41668
42733
 
41669
42734
  // src/api/agent-version.api.service.ts
@@ -42965,10 +44030,11 @@ async function pushCommand(type, cmdObj) {
42965
44030
  options.autoDeploy = false;
42966
44031
  }
42967
44032
  if (options.entityName && !type) {
42968
- console.log("\nUsage:");
42969
- console.log(" lua push skill --name mySkill --set-version 1.0.5 Push specific skill");
42970
- console.log(" lua push webhook --name myWebhook --set-version 2.0.0 Push specific webhook");
42971
- 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"));
42972
44038
  }
42973
44039
  if (isStageAll) {
42974
44040
  return await pushAllCommand({
@@ -42981,10 +44047,11 @@ async function pushCommand(type, cmdObj) {
42981
44047
  }
42982
44048
  if (type === "all") {
42983
44049
  if (!options.force) {
42984
- console.log("\nUsage:");
42985
- console.log(" lua push all --force Push all components without prompts");
42986
- console.log(" lua push all --force --auto-deploy Push and deploy all to production");
42987
- 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"));
42988
44055
  }
42989
44056
  return await pushAllCommand({
42990
44057
  ...options,
@@ -43834,6 +44901,14 @@ function formatDeploySuccess(params) {
43834
44901
  return `\u2705 ${label2} "${name}" v${version} deployed successfully`;
43835
44902
  }
43836
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");
43837
44912
  function deployAllExitCode(failedCount) {
43838
44913
  return failedCount > 0 ? CLI_EXIT.ERROR : void 0;
43839
44914
  }
@@ -43845,6 +44920,12 @@ init_skills_api_service();
43845
44920
  init_webhook_api_service();
43846
44921
  init_job_api_service();
43847
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");
43848
44929
  function normalizeVersion(v) {
43849
44930
  return {
43850
44931
  version: v.version,
@@ -43863,6 +44944,7 @@ var VERSIONED_DEPLOY_TYPES = [
43863
44944
  label: "Skill",
43864
44945
  emoji: "\u{1F6E0}\uFE0F",
43865
44946
  idField: "skillId",
44947
+ scoped: false,
43866
44948
  getVersions: /* @__PURE__ */ __name(async (apiKey, agentId, entityId) => {
43867
44949
  const api = new SkillApi(BASE_URLS.API, apiKey, agentId);
43868
44950
  const result = await api.getSkillVersions(entityId);
@@ -43875,6 +44957,7 @@ var VERSIONED_DEPLOY_TYPES = [
43875
44957
  label: "Webhook",
43876
44958
  emoji: "\u{1FA9D}",
43877
44959
  idField: "webhookId",
44960
+ scoped: true,
43878
44961
  getVersions: /* @__PURE__ */ __name(async (apiKey, agentId, entityId) => {
43879
44962
  const api = new WebhookApi(BASE_URLS.API, apiKey, agentId);
43880
44963
  const result = await api.getWebhookVersions(entityId);
@@ -43887,6 +44970,7 @@ var VERSIONED_DEPLOY_TYPES = [
43887
44970
  label: "Trigger",
43888
44971
  emoji: "\u26A1",
43889
44972
  idField: "triggerId",
44973
+ scoped: true,
43890
44974
  getVersions: /* @__PURE__ */ __name(async (apiKey, agentId, entityId) => {
43891
44975
  const api = new TriggerApi(BASE_URLS.API, apiKey, agentId);
43892
44976
  const result = await api.getTriggerVersions(entityId);
@@ -43899,6 +44983,7 @@ var VERSIONED_DEPLOY_TYPES = [
43899
44983
  label: "Job",
43900
44984
  emoji: "\u23F0",
43901
44985
  idField: "jobId",
44986
+ scoped: true,
43902
44987
  getVersions: /* @__PURE__ */ __name(async (apiKey, agentId, entityId) => {
43903
44988
  const api = new JobApi(BASE_URLS.API, apiKey, agentId);
43904
44989
  const result = await api.getJobVersions(entityId);
@@ -43911,6 +44996,7 @@ var VERSIONED_DEPLOY_TYPES = [
43911
44996
  label: "PreProcessor",
43912
44997
  emoji: "\u{1F4E5}",
43913
44998
  idField: "preprocessorId",
44999
+ scoped: true,
43914
45000
  getVersions: /* @__PURE__ */ __name(async (apiKey, agentId, entityId) => {
43915
45001
  const api = new PreProcessorApi(BASE_URLS.API, apiKey, agentId);
43916
45002
  const result = await api.getPreProcessorVersions(entityId);
@@ -43923,6 +45009,7 @@ var VERSIONED_DEPLOY_TYPES = [
43923
45009
  label: "PostProcessor",
43924
45010
  emoji: "\u{1F4E4}",
43925
45011
  idField: "postprocessorId",
45012
+ scoped: true,
43926
45013
  getVersions: /* @__PURE__ */ __name(async (apiKey, agentId, entityId) => {
43927
45014
  const api = new PostProcessorApi(BASE_URLS.API, apiKey, agentId);
43928
45015
  const result = await api.getPostProcessorVersions(entityId);
@@ -44001,13 +45088,14 @@ async function deployCommand(type, cmdObj) {
44001
45088
  selectedType = answer.type;
44002
45089
  }
44003
45090
  const apiKey = await requireAuthOrExit();
44004
- 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.");
44005
45091
  let personaDeployed = false;
44006
45092
  let versionedOutcome = null;
45093
+ let scopedPromoteNotice = false;
44007
45094
  if (selectedType === "persona") {
44008
45095
  personaDeployed = await deployPersonaVersion(apiKey, agentId, options);
44009
45096
  } else {
44010
45097
  const deployConfig = VERSIONED_DEPLOY_TYPES.find((dt) => dt.type === selectedType);
45098
+ scopedPromoteNotice = deployConfig.scoped;
44011
45099
  versionedOutcome = await deployVersionedPrimitive(deployConfig, config, apiKey, agentId, options);
44012
45100
  }
44013
45101
  trackEvent("cli_deploy_completed", {
@@ -44015,7 +45103,7 @@ async function deployCommand(type, cmdObj) {
44015
45103
  force_mode: options.force || false,
44016
45104
  entity_selected_by_name: !!options.name,
44017
45105
  version_selected_by_flag: !!options.version,
44018
- scoped_promote_notice: true
45106
+ scoped_promote_notice: scopedPromoteNotice
44019
45107
  });
44020
45108
  const deployed = selectedType === "persona" ? personaDeployed : versionedOutcome?.deployed ?? false;
44021
45109
  const hintPrintedAlready = selectedType !== "persona" && !!versionedOutcome?.hintPrinted;
@@ -44024,17 +45112,23 @@ async function deployCommand(type, cmdObj) {
44024
45112
  }
44025
45113
  if (selectedType === "webhook") {
44026
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
+ };
44027
45122
  writeHintBlock({
44028
45123
  headline: "Webhook is live. Trigger it, then inspect logs:",
44029
45124
  lines: [
44030
- {
44031
- label: "Find URL:",
44032
- command: `lua webhooks view --webhook-name ${webhookNameToken}`
44033
- },
44034
- {
44035
- label: "Trigger:",
44036
- command: "curl -X POST <URL from above>"
44037
- },
45125
+ ...webhookNameToken === "<webhook-name>" ? [
45126
+ {
45127
+ label: "Find URL:",
45128
+ command: `lua webhooks view --webhook-name ${webhookNameToken}`
45129
+ }
45130
+ ] : [],
45131
+ triggerLine,
44038
45132
  {
44039
45133
  label: "Inspect:",
44040
45134
  command: buildLogsCommand({
@@ -44073,6 +45167,7 @@ async function deployCommand(type, cmdObj) {
44073
45167
  }
44074
45168
  __name(deployCommand, "deployCommand");
44075
45169
  async function deployVersionedPrimitive(deployConfig, config, apiKey, agentId, options) {
45170
+ writeInfo(deployConfig.scoped ? SCOPED_PROMOTE_NOTICE : pointerNotice(deployConfig.label));
44076
45171
  const entities = deployConfig.handler.getFromYaml(config);
44077
45172
  if (entities.length === 0) {
44078
45173
  writeInfo(`\u2139\uFE0F No ${deployConfig.label}s found in configuration. Nothing to deploy.`);
@@ -44163,10 +45258,7 @@ Available ${deployConfig.label}s:`);
44163
45258
  version: selectedVersion,
44164
45259
  agentVersion: result.agentVersion
44165
45260
  }));
44166
- if (selectedVersion !== selectedEntity.version) {
44167
- writeInfo(`\u{1F4DD} Updating YAML with deployed version: ${selectedVersion}`);
44168
- deployConfig.handler.updateVersionInYaml(selectedEntity.name, selectedVersion);
44169
- }
45261
+ syncDeployedVersionToYaml(deployConfig.handler, selectedEntity.name, selectedVersion, selectedEntity.version);
44170
45262
  if (deployConfig.type === "job") {
44171
45263
  writeHintBlock({
44172
45264
  headline: "Job is live. Trigger or wait for schedule, then inspect logs:",
@@ -44200,6 +45292,7 @@ Available ${deployConfig.label}s:`);
44200
45292
  __name(deployVersionedPrimitive, "deployVersionedPrimitive");
44201
45293
  async function deployPersonaVersion(apiKey, agentId, options) {
44202
45294
  const personaApi = new PersonaApi(BASE_URLS.API, apiKey, agentId);
45295
+ writeInfo(pointerNotice(PERSONA_LABEL));
44203
45296
  writeProgress("\u{1F504} Fetching persona versions...");
44204
45297
  const result = await personaApi.getVersions("all");
44205
45298
  const versions = result.data?.versions || [];
@@ -44264,13 +45357,19 @@ async function deployAllCommand(_options) {
44264
45357
  validateSkillConfig(config);
44265
45358
  const apiKey = await requireAuthOrExit();
44266
45359
  const agentId = config.agent.agentId;
44267
- 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
+ }
44268
45364
  let deployedCount = 0;
44269
45365
  let failedCount = 0;
44270
45366
  const failedItems = [];
44271
45367
  console.log("\n\u{1F680} Deploying latest versions of all primitives...\n");
44272
45368
  for (const deployConfig of VERSIONED_DEPLOY_TYPES) {
44273
45369
  const entities = deployConfig.handler.getFromYaml(config);
45370
+ if (!deployConfig.scoped && entities.length > 0) {
45371
+ writeInfo(pointerNotice(deployConfig.label));
45372
+ }
44274
45373
  for (const entity of entities) {
44275
45374
  const entityId = entity[deployConfig.idField];
44276
45375
  if (!entityId) {
@@ -44326,6 +45425,7 @@ async function deployAllCommand(_options) {
44326
45425
  const personaApi = new PersonaApi(BASE_URLS.API, apiKey, agentId);
44327
45426
  const latestPersona = await personaApi.getLatestVersion();
44328
45427
  if (latestPersona) {
45428
+ writeInfo(pointerNotice(PERSONA_LABEL));
44329
45429
  const deployResult = await personaApi.deployVersion(latestPersona.version);
44330
45430
  if (deployResult.success) {
44331
45431
  writeSuccess(` \u2705 Persona v${latestPersona.version} deployed`);
@@ -45191,6 +46291,7 @@ __name(parseMessageWithAttachments, "parseMessageWithAttachments");
45191
46291
 
45192
46292
  // src/commands/chat.ts
45193
46293
  init_command_utils();
46294
+ init_files();
45194
46295
  init_artifact_loader();
45195
46296
  init_types();
45196
46297
  init_analytics();
@@ -45491,12 +46592,13 @@ async function setupChatEnvironment(chatEnv, config) {
45491
46592
  await compileCommand({
45492
46593
  serverSync: "register-only"
45493
46594
  });
46595
+ const postCompileConfig = readYamlConfig() ?? config;
45494
46596
  const manifest = loadManifest();
45495
46597
  const skills = getPrimitivesByKind(manifest, PrimitiveKind.SKILL);
45496
46598
  let sandboxIds = {};
45497
46599
  if (skills.length > 0) {
45498
46600
  writeProgress("\u{1F504} Pushing skills to sandbox...");
45499
- sandboxIds = await pushSkillsToSandbox(chatEnv.apiKey, chatEnv.agentId, manifest, config, true);
46601
+ sandboxIds = await pushSkillsToSandbox(chatEnv.apiKey, chatEnv.agentId, manifest, postCompileConfig, true);
45500
46602
  if (Object.keys(sandboxIds).length > 0) {
45501
46603
  writeSuccess(`\u2705 Pushed ${Object.keys(sandboxIds).length} skills to sandbox`);
45502
46604
  } else {
@@ -45509,14 +46611,14 @@ async function setupChatEnvironment(chatEnv, config) {
45509
46611
  const postprocessors = getPrimitivesByKind(manifest, PrimitiveKind.POSTPROCESSOR);
45510
46612
  if (preprocessors.length > 0 || postprocessors.length > 0) {
45511
46613
  writeProgress("\u{1F504} Pushing processors to sandbox...");
45512
- const processorCounts = await pushProcessorsToSandbox(chatEnv.apiKey, chatEnv.agentId, manifest, config, true);
46614
+ const processorCounts = await pushProcessorsToSandbox(chatEnv.apiKey, chatEnv.agentId, manifest, postCompileConfig, true);
45513
46615
  if (processorCounts.preprocessors > 0 || processorCounts.postprocessors > 0) {
45514
46616
  writeSuccess(`\u2705 Pushed ${processorCounts.preprocessors} preprocessor(s) and ${processorCounts.postprocessors} postprocessor(s) to sandbox`);
45515
46617
  }
45516
46618
  }
45517
- chatEnv.yamlConfig = config;
45518
- chatEnv.preprocessorOverrides = await getAllSandboxPreProcessorIds(config);
45519
- chatEnv.postprocessorOverrides = await getAllSandboxPostProcessorIds(config);
46619
+ chatEnv.yamlConfig = postCompileConfig;
46620
+ chatEnv.preprocessorOverrides = await getAllSandboxPreProcessorIds(postCompileConfig);
46621
+ chatEnv.postprocessorOverrides = await getAllSandboxPostProcessorIds(postCompileConfig);
45520
46622
  chatEnv.persona = getAgentPersona() ?? void 0;
45521
46623
  }
45522
46624
  __name(setupChatEnvironment, "setupChatEnvironment");
@@ -46583,7 +47685,8 @@ async function personaCommand(env, action, cmdObj) {
46583
47685
  apiKey
46584
47686
  };
46585
47687
  if (selectedEnvironment === "sandbox") {
46586
- if (action === "view") {
47688
+ const normalizedAction = action ? validateOrSuggest("persona.action", action) : void 0;
47689
+ if (normalizedAction === "view") {
46587
47690
  const currentPersona = flattenPersonaTextAll(getAgentPersona());
46588
47691
  if (currentPersona.trim()) {
46589
47692
  console.log(currentPersona);
@@ -46592,6 +47695,16 @@ async function personaCommand(env, action, cmdObj) {
46592
47695
  }
46593
47696
  return;
46594
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
+ }
46595
47708
  await manageSandboxPersonaInteractive(context);
46596
47709
  } else {
46597
47710
  if (action) {
@@ -52244,6 +53357,10 @@ function localVersionLine(version, hide) {
52244
53357
  return hide ? null : ` Version: ${version}`;
52245
53358
  }
52246
53359
  __name(localVersionLine, "localVersionLine");
53360
+ function priorityLine(priority) {
53361
+ return ` Priority: ${priority ?? 100}`;
53362
+ }
53363
+ __name(priorityLine, "priorityLine");
52247
53364
 
52248
53365
  // src/commands/skills.ts
52249
53366
  init_skills_api_service();
@@ -52254,7 +53371,8 @@ async function skillsCommand(actionOrEnv, actionArg, cmdObj) {
52254
53371
  return withErrorHandling(async () => {
52255
53372
  const options = {
52256
53373
  skillName: cmdObj?.skillName || null,
52257
- skillVersion: cmdObj?.skillVersion || null
53374
+ skillVersion: cmdObj?.skillVersion || null,
53375
+ json: cmdObj?.json || false
52258
53376
  };
52259
53377
  const { config, agentId, apiKey } = await initializeCommand();
52260
53378
  const hideVersions = await shouldHidePrimitiveVersions(apiKey, agentId);
@@ -52289,14 +53407,19 @@ async function skillsCommand(actionOrEnv, actionArg, cmdObj) {
52289
53407
  }
52290
53408
  return;
52291
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
+ }
52292
53413
  await manageSandboxSkillsInteractive(context3, config);
53414
+ } else if (resolvedAction) {
53415
+ await executeNonInteractive4(context3, config, resolvedAction, options);
52293
53416
  } else {
52294
53417
  await manageProductionSkillsInteractive(context3, config);
52295
53418
  }
52296
53419
  trackEvent("cli_skills_action", {
52297
53420
  environment: selectedEnvironment,
52298
53421
  action: resolvedAction || "interactive",
52299
- non_interactive: true
53422
+ non_interactive: !!resolvedAction
52300
53423
  });
52301
53424
  return;
52302
53425
  }
@@ -52407,6 +53530,15 @@ async function fetchVersionsCore2(context, skill) {
52407
53530
  };
52408
53531
  }
52409
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");
52410
53542
  function displayVersionsCore2(skill, versions, activeVersionId, hideVersions) {
52411
53543
  if (hideVersions) {
52412
53544
  primitiveVersionHistoryView(skill.name).forEach((line) => console.log(line));
@@ -52435,7 +53567,13 @@ async function deployVersionCore2(context, skill, version) {
52435
53567
  console.error(`\u274C Deploy Error: ${response.error?.message || "Unknown error"}`);
52436
53568
  return false;
52437
53569
  }
52438
- 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);
52439
53577
  writeHintBlock({
52440
53578
  headline: "Skill is live. Generate traffic to see it in action:",
52441
53579
  lines: [
@@ -52520,6 +53658,9 @@ async function promptVersionSelection2(versions, activeVersionId) {
52520
53658
  }
52521
53659
  __name(promptVersionSelection2, "promptVersionSelection");
52522
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
+ }
52523
53664
  const skills = config.skills || [];
52524
53665
  if (action === "view") {
52525
53666
  if (skills.length === 0) {
@@ -52555,6 +53696,10 @@ async function executeNonInteractive4(context, config, action, options) {
52555
53696
  case "versions": {
52556
53697
  const data = await fetchVersionsCore2(context, selectedSkill);
52557
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
+ }
52558
53703
  if (!context.hideVersions && data.versions.length === 0) {
52559
53704
  console.log(`\u2139\uFE0F No versions found for ${selectedSkill.name}.`);
52560
53705
  console.log("\u{1F4A1} Push a version first using 'lua push skill'.");
@@ -53711,6 +54856,7 @@ async function displayWebhooksCore(context, webhooks) {
53711
54856
  const activeVersion = versions.find((v) => v.webhookId === activeVersionId);
53712
54857
  console.log(`\u{1FA9D} ${webhook.name}`);
53713
54858
  console.log(` Webhook ID: ${webhook.webhookId}`);
54859
+ console.log(` URL: ${WEBHOOK_TRIGGER_BASE_URL}/${context.agentId}/${encodeURIComponent(webhook.name)}`);
53714
54860
  if (activeVersion) {
53715
54861
  console.log(deployedVersionLine(activeVersion.version, context.hideVersions));
53716
54862
  console.log(` Deployed: ${new Date(activeVersion.createdAt).toLocaleString()}`);
@@ -53722,18 +54868,19 @@ async function displayWebhooksCore(context, webhooks) {
53722
54868
  }
53723
54869
  console.log();
53724
54870
  } else {
53725
- displayWebhookError(webhook, "Unable to fetch version info");
54871
+ displayWebhookError(webhook, "Unable to fetch version info", context.agentId);
53726
54872
  }
53727
54873
  } catch {
53728
- displayWebhookError(webhook, "Error loading versions");
54874
+ displayWebhookError(webhook, "Error loading versions", context.agentId);
53729
54875
  }
53730
54876
  }
53731
54877
  console.log("=".repeat(60));
53732
54878
  }
53733
54879
  __name(displayWebhooksCore, "displayWebhooksCore");
53734
- function displayWebhookError(webhook, status) {
54880
+ function displayWebhookError(webhook, status, agentId) {
53735
54881
  console.log(`\u{1FA9D} ${webhook.name}`);
53736
54882
  console.log(` Webhook ID: ${webhook.webhookId}`);
54883
+ console.log(` URL: ${WEBHOOK_TRIGGER_BASE_URL}/${agentId}/${encodeURIComponent(webhook.name)}`);
53737
54884
  console.log(` Status: ${status}`);
53738
54885
  console.log();
53739
54886
  }
@@ -53778,17 +54925,21 @@ async function deployVersionCore3(context, webhook, version) {
53778
54925
  console.error(`\u274C Deploy Error: ${deployResponse.error?.message || "Unknown error"}`);
53779
54926
  return false;
53780
54927
  }
53781
- 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}`);
53782
54937
  writeHintBlock({
53783
54938
  headline: "Webhook is live. Trigger it, then inspect logs:",
53784
54939
  lines: [
53785
- {
53786
- label: "Find URL:",
53787
- command: `lua webhooks view --webhook-name ${webhook.name}`
53788
- },
53789
54940
  {
53790
54941
  label: "Trigger:",
53791
- command: "curl -X POST <URL from above>"
54942
+ command: `curl -X POST ${webhookUrl}`
53792
54943
  },
53793
54944
  {
53794
54945
  label: "Inspect:",
@@ -55440,6 +56591,10 @@ async function displayJobsCore(context, jobs, opts = {}) {
55440
56591
  if (jobData.nextRunAt) {
55441
56592
  console.log(` Next Run: ${new Date(jobData.nextRunAt).toLocaleString()}`);
55442
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
+ }
55443
56598
  console.log();
55444
56599
  } catch (error) {
55445
56600
  if (CliError.isCliError(error) && error.statusCode === 404) {
@@ -55508,7 +56663,13 @@ async function deployVersionCore4(context, job, version) {
55508
56663
  console.error(`\u274C Deploy Error: ${deployResponse.error?.message || "Unknown error"}`);
55509
56664
  return false;
55510
56665
  }
55511
- 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);
55512
56673
  writeInfo("\u{1F4A1} The new version is now active and will run on schedule.");
55513
56674
  writeHintBlock({
55514
56675
  headline: "Job is live. Trigger it, then inspect:",
@@ -55620,7 +56781,7 @@ async function fetchAndDisplayHistoryCore(context, job) {
55620
56781
  const status = execution.status;
55621
56782
  const statusEmoji = status === "completed" ? "\u2705" : status === "failed" ? "\u274C" : status === "running" ? "\u{1F504}" : "\u23F3";
55622
56783
  console.log(`${index + 1}. ${statusEmoji} ${status.toUpperCase()}`);
55623
- console.log(` Execution ID: ${execution.executionId}`);
56784
+ console.log(` Execution ID: ${execution.id ?? execution.executionId ?? "N/A"}`);
55624
56785
  console.log(` Started: ${startedAt.toLocaleString()}`);
55625
56786
  if (execution.completedAt) {
55626
56787
  const completedAt = new Date(execution.completedAt);
@@ -56845,7 +58006,7 @@ async function activateCore(ctx, name, on) {
56845
58006
  emitJson(ctx, res);
56846
58007
  if (!ctx.json) {
56847
58008
  writeSuccess(`\u2705 Workflow "${wf.name}" ${on ? "activated" : "deactivated"}`);
56848
- 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.");
56849
58010
  }
56850
58011
  return WORKFLOW_EXIT.OK;
56851
58012
  }
@@ -58437,13 +59598,17 @@ function modelEventDetail(type, data) {
58437
59598
  __name(modelEventDetail, "modelEventDetail");
58438
59599
  async function logsCore(ctx, runId, o) {
58439
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
+ }
58440
59605
  const res = await ctx.api.getRunEvents(runId, {
58441
59606
  limit: 500
58442
59607
  });
58443
59608
  if (!res.success || !res.data) return apiFailure(ctx, res, "logs");
58444
59609
  emitJson(ctx, res);
58445
59610
  if (ctx.json) return WORKFLOW_EXIT.OK;
58446
- 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));
58447
59612
  if (events.length === 0) console.log("(no log events yet)");
58448
59613
  for (const e of events) {
58449
59614
  const data = scrubEventData(e.data);
@@ -59236,6 +60401,12 @@ var goalStatusLabel = /* @__PURE__ */ __name((g) => `${g.status}${g.pauseReason
59236
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");
59237
60402
  var verdictLabel = /* @__PURE__ */ __name((v) => v ? `${v.done ? "done" : "continue"}${v.summary ? ` \xB7 ${v.summary.slice(0, 60)}` : ""}` : "\u2014", "verdictLabel");
59238
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");
59239
60410
  function goalRaiseHint(goalId, reason) {
59240
60411
  const flag = reason === "budget" ? "--max-credits <n>" : reason === "max_runs" ? "--max-runs <n>" : "--max-runs <n> | --max-credits <n>";
59241
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`;
@@ -59305,6 +60476,7 @@ function printSchedules(items, names) {
59305
60476
  "Last fired",
59306
60477
  "Status",
59307
60478
  "Strikes",
60479
+ "Health",
59308
60480
  "Goal"
59309
60481
  ], items.map((r) => [
59310
60482
  r.jobId,
@@ -59314,6 +60486,7 @@ function printSchedules(items, names) {
59314
60486
  when2(r.lastFiredAt),
59315
60487
  scheduleStatus(r),
59316
60488
  String(r.consecutiveFailures ?? 0),
60489
+ scheduleHealthLabel(r),
59317
60490
  r.goalId ?? "\u2014"
59318
60491
  ])));
59319
60492
  const owned = items.filter((r) => r.goalId).length;
@@ -60964,6 +62137,7 @@ async function displayPreProcessorsCore(context, preprocessors) {
60964
62137
  const activeVersion = versions.find((v) => v.versionId === activeVersionId);
60965
62138
  console.log(`\u{1F4E5} ${preprocessor.name}`);
60966
62139
  console.log(` PreProcessor ID: ${preprocessor.preprocessorId}`);
62140
+ console.log(priorityLine(response.data.priority));
60967
62141
  if (activeVersion) {
60968
62142
  console.log(deployedVersionLine(activeVersion.version, context.hideVersions));
60969
62143
  console.log(` Deployed: ${new Date(activeVersion.createdAt).toLocaleString()}`);
@@ -61030,7 +62204,13 @@ async function deployVersionCore5(context, preprocessor, version) {
61030
62204
  console.error(`\u274C Deploy Error: ${deployResponse.error?.message || "Unknown error"}`);
61031
62205
  return false;
61032
62206
  }
61033
- 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);
61034
62214
  writeHintBlock({
61035
62215
  headline: "Preprocessor is live. Send a test message to trigger it:",
61036
62216
  lines: [
@@ -61541,6 +62721,7 @@ async function displayPostProcessorsCore(context, postprocessors) {
61541
62721
  const activeVersion = versions.find((v) => v.versionId === activeVersionId);
61542
62722
  console.log(`\u{1F4E4} ${postprocessor.name}`);
61543
62723
  console.log(` PostProcessor ID: ${postprocessor.postprocessorId}`);
62724
+ console.log(priorityLine(response.data.priority));
61544
62725
  if (activeVersion) {
61545
62726
  console.log(deployedVersionLine(activeVersion.version, context.hideVersions));
61546
62727
  console.log(` Deployed: ${new Date(activeVersion.createdAt).toLocaleString()}`);
@@ -61607,7 +62788,13 @@ async function deployVersionCore6(context, postprocessor, version) {
61607
62788
  console.error(`\u274C Deploy Error: ${deployResponse.error?.message || "Unknown error"}`);
61608
62789
  return false;
61609
62790
  }
61610
- 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);
61611
62798
  writeHintBlock({
61612
62799
  headline: "Postprocessor is live. Send a test message to trigger it:",
61613
62800
  lines: [
@@ -62636,7 +63823,7 @@ async function templateCreateAction(templateApi, config, options) {
62636
63823
  validate: /* @__PURE__ */ __name((input) => input && input.trim().length > 0 ? true : "Display name cannot be empty.", "validate")
62637
63824
  });
62638
63825
  }
62639
- if (description === void 0) {
63826
+ if (description === void 0 && !isCiModeEnabled()) {
62640
63827
  questions.push({
62641
63828
  type: "input",
62642
63829
  name: "description",
@@ -62924,7 +64111,7 @@ ${"=".repeat(60)}`);
62924
64111
  console.log(`Visibility: ${template3.visibility === "private" ? "\u{1F512} Private" : "\u{1F310} Public"}`);
62925
64112
  console.log(`Listed: ${template3.listed ? "Yes" : "No"}`);
62926
64113
  console.log(`Installs: ${template3.installCount}`);
62927
- if (template3.latestVersion != null) console.log(`Latest version: v${template3.latestVersion}`);
64114
+ if (template3.latestVersion) console.log(`Latest version: v${template3.latestVersion}`);
62928
64115
  console.log(`Created: ${new Date(template3.createdAt).toLocaleDateString()}`);
62929
64116
  console.log(`
62930
64117
  ${"=".repeat(60)}
@@ -63540,9 +64727,13 @@ async function listSkillNonInteractive(marketplaceApi, config, apiKey, options)
63540
64727
  }
63541
64728
  __name(listSkillNonInteractive, "listSkillNonInteractive");
63542
64729
  async function publishVersionNonInteractive(marketplaceApi, config, apiKey, options) {
63543
- const { marketplaceId, versionId, changelog, envVarsJson } = options;
63544
- if (!marketplaceId || !versionId) {
63545
- 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);
63546
64737
  }
63547
64738
  let envVars;
63548
64739
  if (envVarsJson) {
@@ -63563,6 +64754,40 @@ async function publishVersionNonInteractive(marketplaceApi, config, apiKey, opti
63563
64754
  writeInfo("\u{1F4A1} You will be notified once the review is complete.");
63564
64755
  }
63565
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");
63566
64791
  async function updateMetadataNonInteractive(marketplaceApi, options) {
63567
64792
  const { marketplaceId, displayName } = options;
63568
64793
  if (!marketplaceId) {
@@ -66154,7 +67379,8 @@ async function executeNonInteractive12(context, action, cmdOptions) {
66154
67379
  // Trigger options
66155
67380
  triggers: cmdOptions?.triggers,
66156
67381
  customWebhook: cmdOptions?.customWebhook === true,
66157
- hookUrl: cmdOptions?.hookUrl
67382
+ hookUrl: cmdOptions?.hookUrl,
67383
+ forget: cmdOptions?.forget === true
66158
67384
  };
66159
67385
  const jsonOutput = cmdOptions?.json === true;
66160
67386
  switch (normalizedAction) {
@@ -66202,7 +67428,7 @@ async function executeNonInteractive12(context, action, cmdOptions) {
66202
67428
  throw CliError.usage("--connection-id is required for disconnect", "Run 'lua integrations list' to see connection IDs");
66203
67429
  }
66204
67430
  if (options.scope === "user") {
66205
- await disconnectUserConnection(context, options.connectionId);
67431
+ await disconnectUserConnection(context, options.connectionId, options.forget);
66206
67432
  } else {
66207
67433
  await disconnectIntegration(context, options.connectionId);
66208
67434
  }
@@ -66455,9 +67681,27 @@ function normalizeScopeFlag(raw) {
66455
67681
  return normalized;
66456
67682
  }
66457
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");
66458
67700
  async function resolveConnectScope(context, options) {
66459
67701
  const flagged = normalizeScopeFlag(options.scope);
66460
67702
  if (flagged) return flagged;
67703
+ const ciDefault = resolveCiScopeDefault(flagged, isCiModeEnabled());
67704
+ if (ciDefault) return ciDefault;
66461
67705
  const answer = await safePrompt([
66462
67706
  {
66463
67707
  type: "list",
@@ -66490,6 +67734,7 @@ async function connectIntegrationFlow(context, options = {}) {
66490
67734
  throw new Error("Agent-scoped options cannot be used with --scope user");
66491
67735
  }
66492
67736
  }
67737
+ assertAccountLabelForCi(userScope, options.accountLabel, isCiModeEnabled());
66493
67738
  writeProgress("\u{1F504} Fetching integrations...");
66494
67739
  let availableIntegrations;
66495
67740
  let agentConnectedTypes = /* @__PURE__ */ new Set();
@@ -67248,18 +68493,25 @@ async function listConnections(context) {
67248
68493
  }
67249
68494
  }
67250
68495
  __name(listConnections, "listConnections");
67251
- async function disconnectUserConnection(context, connectionId) {
67252
- const forget = await safePrompt([
67253
- {
67254
- type: "confirm",
67255
- name: "forget",
67256
- message: "Also forget what this connection already added to memory? (it is kept otherwise)",
67257
- default: false
67258
- }
67259
- ]);
67260
- 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
+ }
67261
68513
  writeProgress("\u{1F504} Disconnecting... (please wait, do not close this window)");
67262
- const result = await context.unifiedToApi.deleteUserConnection(connectionId, forget.forget);
68514
+ const result = await context.unifiedToApi.deleteUserConnection(connectionId, shouldForget);
67263
68515
  if (!result.success) {
67264
68516
  writeError(`\u274C Failed to disconnect: ${result.error?.message || "Unknown error"}`);
67265
68517
  return;
@@ -67268,14 +68520,14 @@ async function disconnectUserConnection(context, connectionId) {
67268
68520
  if (result.data?.deletedWebhooksCount) {
67269
68521
  console.log(` \u2713 Deleted ${result.data.deletedWebhooksCount} memory source(s)`);
67270
68522
  }
67271
- if (!forget.forget) {
68523
+ if (!shouldForget) {
67272
68524
  console.log(" \u2139\uFE0F What it already added to memory was kept.");
67273
68525
  }
67274
68526
  console.log();
67275
68527
  trackEvent("cli_integration_disconnected", {
67276
68528
  scope: "user",
67277
68529
  webhooks_deleted: result.data?.deletedWebhooksCount || 0,
67278
- forget_memories: forget.forget
68530
+ forget_memories: shouldForget
67279
68531
  });
67280
68532
  }
67281
68533
  __name(disconnectUserConnection, "disconnectUserConnection");
@@ -70554,6 +71806,7 @@ __name(defaultRestore, "defaultRestore");
70554
71806
  // src/commands/version.ts
70555
71807
  init_cli();
70556
71808
  init_command_utils();
71809
+ init_cli_error();
70557
71810
  init_analytics();
70558
71811
  init_files();
70559
71812
  init_semver();
@@ -70908,6 +72161,8 @@ async function versionDeleteCommand(versionArg, options = {}) {
70908
72161
  writeInfo("Aborted.");
70909
72162
  return;
70910
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.");
70911
72166
  }
70912
72167
  const api = new AgentVersionApi(BASE_URLS.API, apiKey, agentId);
70913
72168
  const response = await api.deleteVersion(version);
@@ -71519,7 +72774,7 @@ Arguments:
71519
72774
 
71520
72775
  Skill Actions:
71521
72776
  list --skill-name <name> --display-name <name> [--visibility public|private]
71522
- 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>]
71523
72778
  edit --marketplace-id <id> --display-name <name>
71524
72779
  unlist --marketplace-id <id> --force
71525
72780
  unpublish --marketplace-id <id> --version-id <id> --force
@@ -71551,6 +72806,7 @@ Examples:
71551
72806
  $ lua marketplace skill org View this organization's owned skills
71552
72807
  $ lua marketplace skill list --skill-name mySkill --display-name "My Skill"
71553
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
71554
72810
  $ lua marketplace skill unlist --marketplace-id xyz --force
71555
72811
  $ lua marketplace skill search --query "CRM"
71556
72812
  $ lua marketplace skill view --marketplace-id xyz --json
@@ -71735,7 +72991,7 @@ Examples:
71735
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", `
71736
72992
  Arguments:
71737
72993
  env Optional: 'sandbox', 'staging', or 'production' (prompts if not provided)
71738
- action Optional (production only): 'view', 'versions', 'deploy'
72994
+ action Optional: 'view', 'versions' (sandbox or production), 'deploy' (production only)
71739
72995
 
71740
72996
  Options:
71741
72997
  --persona-version <ver> Version number or 'latest' for deploy action
@@ -71744,6 +73000,7 @@ Options:
71744
73000
  Examples:
71745
73001
  $ lua persona Interactive selection
71746
73002
  $ lua persona sandbox Manage sandbox persona interactively
73003
+ $ lua persona sandbox versions List persona versions (sandbox)
71747
73004
  $ lua persona production Manage production persona interactively
71748
73005
  $ lua persona production view View current deployed persona
71749
73006
  $ lua persona production versions List all persona versions
@@ -71860,20 +73117,23 @@ Notes:
71860
73117
  acknowledgement is given AND the credential holds logs:manage \u2014 the scope alone is not
71861
73118
  enough, the flag is required too.
71862
73119
  `).action((options, command) => logsExportCommand(withGroupOptions(options ?? {}, command)));
71863
- 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", `
71864
73121
  Arguments:
71865
73122
  actionOrEnv Optional: environment ('sandbox', 'production') or action ('view', 'versions', 'deploy', 'delete')
71866
73123
 
71867
73124
  Options:
71868
73125
  --skill-name <name> Skill name (for versions/deploy/delete actions)
71869
73126
  --skill-version <ver> Version for deploy action, or 'latest'
73127
+ --json Print versions as JSON, including version ids (for versions action)
71870
73128
 
71871
73129
  Examples:
71872
73130
  $ lua skills Interactive selection
71873
73131
  $ lua skills sandbox View sandbox skills
71874
73132
  $ lua skills production Manage production skills
71875
73133
  $ lua skills view List all production skills
73134
+ $ lua skills production view Same non-interactive listing as 'lua skills view'
71876
73135
  $ lua skills versions --skill-name mySkill View skill versions
73136
+ $ lua skills versions --skill-name mySkill --json View skill version ids as JSON
71877
73137
  $ lua skills deploy --skill-name mySkill --skill-version 1.0.3 Deploy specific version
71878
73138
  $ lua skills deploy --skill-name mySkill --skill-version latest Deploy latest version
71879
73139
  $ lua skills delete --skill-name mySkill Delete a skill from server
@@ -71982,7 +73242,7 @@ Examples:
71982
73242
  $ lua jobs versions -i myJob View job versions
71983
73243
  $ lua jobs history -i myJob View execution history
71984
73244
  `).action(jobsCommand);
71985
- 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", `
71986
73246
  Arguments:
71987
73247
  action list \xB7 view \xB7 versions \xB7 deploy \xB7 activate \xB7 deactivate \xB7 start \xB7 run \xB7 runs \xB7 status \xB7
71988
73248
  watch \xB7 cancel \xB7 resume \xB7 retry-step \xB7 resolve-step \xB7 raise-budget \xB7 approve \xB7 approval-payload \xB7
@@ -72117,7 +73377,7 @@ Examples:
72117
73377
  $ lua mcp deactivate --server-name api-server Deactivate a server
72118
73378
  $ lua mcp delete --server-name old-server Delete a server
72119
73379
  `).action(mcpCommand);
72120
- 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", `
72121
73381
  Arguments:
72122
73382
  action Optional: 'connect', 'update', 'list', 'available', 'info', 'disconnect',
72123
73383
  'convert', 'webhooks' (alias: 'triggers'), or 'mcp'
@@ -72136,6 +73396,8 @@ Options:
72136
73396
  --triggers <events> Comma-separated triggers to enable (e.g., task_task.created,task_task.updated)
72137
73397
  --custom-webhook Use custom webhook URL instead of agent trigger
72138
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)
72139
73401
  --json Output as JSON (for info and webhooks events commands)
72140
73402
 
72141
73403
  Webhook/Trigger Options:
@@ -72148,6 +73410,8 @@ Webhook/Trigger Options:
72148
73410
 
72149
73411
  Note: Multiple accounts of one integration are supported; use --connection-id when updating one.
72150
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.
72151
73415
 
72152
73416
  Examples:
72153
73417
  $ lua integrations Interactive management
@@ -72167,6 +73431,8 @@ Examples:
72167
73431
  $ lua integrations info linear Show Linear integration details
72168
73432
  $ lua integrations info linear --json Output as JSON (for scripting)
72169
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
72170
73436
 
72171
73437
  Webhook/Trigger Examples ('triggers' is an alias for 'webhooks'):
72172
73438
  $ lua integrations webhooks list List all triggers
@@ -72338,8 +73604,10 @@ Examples:
72338
73604
  `).action(() => versionStatusCommand());
72339
73605
  versionGroup.command("delete <version>").description("Soft-delete a version").option("--force", "Skip confirmation prompt").addHelpText("after", `
72340
73606
  Examples:
72341
- $ lua version delete 3 Delete v3 (confirms first)
72342
- $ 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
72343
73611
  `).action((version, opts) => versionDeleteCommand(version, opts));
72344
73612
  const gitGroup = program2.command("git").description("Manage opt-in git auto-commits for this project");
72345
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({