@super-one/cli 0.75.0-alpha.1 → 0.75.0-alpha.2

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.
Files changed (3) hide show
  1. package/MANIFEST.json +2 -2
  2. package/lib/cli.mjs +982 -152
  3. package/package.json +10 -10
package/lib/cli.mjs CHANGED
@@ -137,8 +137,8 @@ import { fileURLToPath } from "node:url";
137
137
  function resolveCliReleaseVersion() {
138
138
  const fromEnv = process.env.SUPERONE_CLI_VERSION?.trim();
139
139
  if (fromEnv) return fromEnv;
140
- if ("0.75.0-alpha.1".trim()) {
141
- return "0.75.0-alpha.1".trim();
140
+ if ("0.75.0-alpha.2".trim()) {
141
+ return "0.75.0-alpha.2".trim();
142
142
  }
143
143
  const fromDist = readDistManifestVersion();
144
144
  if (fromDist) return fromDist;
@@ -466,7 +466,7 @@ var init_superone_tool_descriptions = __esm({
466
466
  SESSION_TAGS_FILTER_DESCRIPTION = "Tags from session_tag_list. Filter sessions that have these labels.";
467
467
  SESSION_TAG_MATCH_DESCRIPTION = "any = at least one listed tag (default). all = every listed tag. Ignored when tags is omitted.";
468
468
  SESSION_CLEANUP_DESCRIPTION = "Hide, unhide, or delete SuperOne sessions by id (from session_list; ids may be from any project). hide/unhide need no confirmation. delete always opens a user confirmation dialog. Never deletes the current session; skips pinned unless includePinned. Prefer session_list to choose ids first.";
469
- CONFIG_READ_DESCRIPTION = "Read live SuperOne settings and their field schema. Always call this before config_apply. Omit domain to list settings and resource domains; pass domain to read exact keys, current values, and constraints. For resource domains, pass recordId to read one record before updating or deleting it. Use read_manual for documentation.";
469
+ CONFIG_READ_DESCRIPTION = "Read live SuperOne settings and their field schema. Always call this before config_apply. Omit domain to list settings and resource domains; pass domain to read exact keys, current values, and constraints. For resource domains, pass recordId to read one record before updating or deleting it. See read_manual product/settings for defaults, project preferences, Jev keys and icons.";
470
470
  CONFIG_APPLY_DESCRIPTION = "Propose a settings change or resource create/update/delete using keys returned by config_read. Pass exactly one of changes or resource. Every call opens an editable confirmation dialog and applies nothing without user approval. For updates, send only changed fields. Stop on cancelled or error; on rejected, use the returned feedback before retrying.";
471
471
  LIST_MEDIA_PROVIDERS_DESCRIPTION = "List configured media providers that have usable credentials. Filter by image or video. Use a returned provider id with media_generate_image or media_generate_video; use kind to select the matching media manual topic. Honor returned sizing and sizeNote constraints.";
472
472
  GENERATE_IMAGE_DESCRIPTION = "Generate or edit an image; pass source files in reference_image_paths for edits. Discover configured providers with media_list_providers when not already known. Read the matching media provider-task topic for unfamiliar options. Inspect previewPaths; savedPaths holds originals for export or edits. Check warnings for ignored options. Results display automatically; do not embed them again.";
@@ -509,8 +509,8 @@ var init_superone_tool_descriptions = __esm({
509
509
  ENVIRONMENT_GET_INFO_IDS_DESCRIPTION = "Environments to read; omit for all.";
510
510
  ENVIRONMENT_GET_INFO_INCLUDE_DESCRIPTION = 'Detail groups to add. Default ["hardware"]; [] returns IDs, labels and state only.';
511
511
  ARCHIVE_ENVIRONMENT_DESCRIPTION = "Target environment ID from environment_get_info. Omit or use localhost for the calling session host.";
512
- LAYOUT_SNAPSHOT_DESCRIPTION = "Read a SuperOne session layout: tabs/groups, panels, sidebar and chat mode. layout reports the available split area, minimum tile sizes, maxSessions, environment-qualified tiles with geometry, focus, normal/maximized state and divider ids/ratios. Hidden saved layouts contain identities/proportions only. Area uses viewport CSS pixels; tile/divider coordinates are area-relative. Divider ids survive resizing/focus, expire on topology changes. Omit target for caller, use foreground or an explicit environment/session. Read ids and sizes before layout_act.";
513
- LAYOUT_ACT_DESCRIPTION = "Arrange SuperOne. focus_session focuses an existing tile or replaces the focused tile without collapsing splits. split_session sessionIds sets the final list: automatic sizing by default, or layout for explicit nested splits/order/ratios; sessionId+direction adds one. close_split removes tiles; closeAll retains focus and clears restore state. maximize_split isolates a tile; restore_splits restores it. resize_splits changes divider ratios atomically; use split_session layout to change structure. Returns layout geometry/capacity. Hidden targets skip window changes; tab changes queue. Never stops/deletes sessions. Open via browser_tabs / terminal_tabs. visible reports on-screen results.";
512
+ LAYOUT_SNAPSHOT_DESCRIPTION = "Read a SuperOne session layout: tabs/groups, panels, sidebar, chat and window mode. window.native reports outer bounds, minimum size, display work area, fullscreen/maximized state in DIP. layout reports split area/capacity, environment-qualified tiles, focus and divider ids/ratios. Hidden saved layouts contain identities/proportions only. Area uses viewport CSS pixels; tile/divider coordinates are area-relative. Divider ids survive resizing/focus, expire on topology changes. Omit target for caller, or use foreground or an explicit session. Reuse layout_act state/layout results; read a snapshot for missing ids or after external changes.";
513
+ LAYOUT_ACT_DESCRIPTION = "Arrange SuperOne. focus_session preserves splits. split_session sessionIds sets the final list, automatically sized or with nested layout/order/ratios; sessionId+direction adds one. close_split removes tiles; closeAll retains focus. maximize_split isolates a tile; restore_splits restores it; resize_splits adjusts ratios. window_mode selects mini/full; resize_window sets size; enter_fullscreen/exit_fullscreen set OS fullscreen. Returns relevant state and layout geometry when affected: reuse ids/sizes instead of rereading layout_snapshot. Hidden targets skip window changes; tab changes queue. Never stops/deletes sessions. Open via browser_tabs/terminal_tabs. visible reports on-screen results.";
514
514
  LAYOUT_TARGET_DESCRIPTION = "caller (default), foreground, or {environmentId, sessionId} from session_list/search/collab. localhost means the invoking session host. focus_session requires an explicit object; other actions can prepare a background layout without switching.";
515
515
  LAYOUT_ACT_PATH_DESCRIPTION = "open_file: the file, absolute or relative to your working folder.";
516
516
  LAYOUT_ACT_LINE_DESCRIPTION = "open_file: 1-based line to reveal.";
@@ -518,9 +518,9 @@ var init_superone_tool_descriptions = __esm({
518
518
  LAYOUT_ACT_GROUP_DESCRIPTION = "Group index from layout_snapshot groups. resize_group; move_tab target, default the tab's own group (a tab alone there goes beside the group before it).";
519
519
  LAYOUT_ACT_DIRECTION_DESCRIPTION = "move_tab: right / down / left / up of the group as a new group, or into it. split_session: any side. Default right.";
520
520
  LAYOUT_ACT_INDEX_DESCRIPTION = "move_tab: 0-based position among the destination group's tabs; with into and your own group it reorders.";
521
- LAYOUT_ACT_WIDTH_DESCRIPTION = "resize_sidebar / resize_panel / resize_group: target width in px. Sidebar and panel clamp to layout_snapshot sizes; the result has the applied size.";
522
- LAYOUT_ACT_HEIGHT_DESCRIPTION = "resize_group: target height in px.";
523
- LAYOUT_ACT_MODE_DESCRIPTION = "chat_mode: docked (a column beside the panel), floating (a movable window over the panel, which then fills the window) or icon (that window collapsed).";
521
+ LAYOUT_ACT_WIDTH_DESCRIPTION = "resize_sidebar/resize_panel/resize_group: CSS px, clamped to layout sizes. resize_window: outer width in DIP, clamped to layout minimum and display work area; exits maximized state, requires exit_fullscreen first. Result reports actual size. resize_window/resize_group need width, height, or both.";
522
+ LAYOUT_ACT_HEIGHT_DESCRIPTION = "resize_group: CSS px. resize_window: outer height in DIP, clamped to layout minimum and display work area; requires exit_fullscreen first.";
523
+ LAYOUT_ACT_MODE_DESCRIPTION = "chat_mode: docked (column), floating (over the panel), icon (collapsed). window_mode: mini (convert this native window in place) or full (restore the complete app, not OS fullscreen). Requires a visible target; close splits with close_split first. Waits for the window animation; repeated mode is a no-op.";
524
524
  LAYOUT_ACT_POSITION_DESCRIPTION = "chat_mode: where the floating chat or its icon snaps. Alone it moves the chat without changing mode; while docked it is kept for the next float.";
525
525
  LAYOUT_ACT_SESSION_DESCRIPTION = "split_session / close_split: a session id from session_list, session_search or session_collab_*.";
526
526
  }
@@ -786,11 +786,37 @@ var init_host_action_collaboration_descriptors = __esm({
786
786
  }
787
787
  });
788
788
 
789
+ // ../../packages/shared/src/config-tool-schema.ts
790
+ var CONFIG_SETTINGS_DOMAINS;
791
+ var init_config_tool_schema = __esm({
792
+ "../../packages/shared/src/config-tool-schema.ts"() {
793
+ "use strict";
794
+ CONFIG_SETTINGS_DOMAINS = [
795
+ "general",
796
+ "appearance",
797
+ "browser",
798
+ "computer-use",
799
+ "agent-claude",
800
+ "agent-codex",
801
+ "agent-acp",
802
+ "agent-cursor",
803
+ "agent-dsh",
804
+ "ai-provider",
805
+ "custom-platform",
806
+ "default-provider",
807
+ "project-claude",
808
+ "jev",
809
+ "app-icon"
810
+ ];
811
+ }
812
+ });
813
+
789
814
  // ../../packages/shared/src/environment/host-action-setup-descriptors.ts
790
815
  var HOST_ACTION_SETUP_DESCRIPTORS;
791
816
  var init_host_action_setup_descriptors = __esm({
792
817
  "../../packages/shared/src/environment/host-action-setup-descriptors.ts"() {
793
818
  "use strict";
819
+ init_config_tool_schema();
794
820
  init_superone_tool_descriptions();
795
821
  HOST_ACTION_SETUP_DESCRIPTORS = [
796
822
  {
@@ -843,16 +869,7 @@ var init_host_action_setup_descriptors = __esm({
843
869
  "properties": {
844
870
  "domain": {
845
871
  "type": "string",
846
- "enum": [
847
- "general",
848
- "appearance",
849
- "browser",
850
- "computer-use",
851
- "agent-claude",
852
- "agent-codex",
853
- "ai-provider",
854
- "custom-platform"
855
- ],
872
+ "enum": CONFIG_SETTINGS_DOMAINS,
856
873
  "description": "Which settings domain to read. Omit to list all domains with their descriptions."
857
874
  },
858
875
  "recordId": {
@@ -871,7 +888,7 @@ var init_host_action_setup_descriptors = __esm({
871
888
  "properties": {
872
889
  "changes": {
873
890
  "type": "array",
874
- "description": "Scalar settings changes to propose. Each item targets one field key from config_read. Mutually exclusive with `resource`.",
891
+ "description": "Settings changes to propose. Each item targets one field key from config_read. Mutually exclusive with `resource`.",
875
892
  "items": {
876
893
  "type": "object",
877
894
  "properties": {
@@ -884,7 +901,9 @@ var init_host_action_setup_descriptors = __esm({
884
901
  "string",
885
902
  "number",
886
903
  "boolean",
887
- "null"
904
+ "null",
905
+ "array",
906
+ "object"
888
907
  ],
889
908
  "description": 'The new value. Use null (or "") to reset a clearable field to its default.'
890
909
  }
@@ -4578,7 +4597,7 @@ var init_host_action_terminal_descriptors = __esm({
4578
4597
  });
4579
4598
 
4580
4599
  // ../../packages/shared/src/layout-control.ts
4581
- var LAYOUT_ACT_ACTIONS, LAYOUT_DIRECTIONS, LAYOUT_CHAT_MODES, LAYOUT_CHAT_POSITIONS;
4600
+ var LAYOUT_ACT_ACTIONS, LAYOUT_DIRECTIONS, LAYOUT_CHAT_MODES, LAYOUT_WINDOW_MODES, LAYOUT_CHAT_POSITIONS;
4582
4601
  var init_layout_control = __esm({
4583
4602
  "../../packages/shared/src/layout-control.ts"() {
4584
4603
  "use strict";
@@ -4602,6 +4621,10 @@ var init_layout_control = __esm({
4602
4621
  "resize_sidebar",
4603
4622
  "resize_panel",
4604
4623
  "chat_mode",
4624
+ "window_mode",
4625
+ "resize_window",
4626
+ "enter_fullscreen",
4627
+ "exit_fullscreen",
4605
4628
  "show_terminal",
4606
4629
  "hide_terminal",
4607
4630
  "split_session",
@@ -4609,6 +4632,7 @@ var init_layout_control = __esm({
4609
4632
  ];
4610
4633
  LAYOUT_DIRECTIONS = ["right", "down", "left", "up", "into"];
4611
4634
  LAYOUT_CHAT_MODES = ["docked", "floating", "icon"];
4635
+ LAYOUT_WINDOW_MODES = ["mini", "full"];
4612
4636
  LAYOUT_CHAT_POSITIONS = ["top-left", "top", "top-right", "right", "bottom-right", "bottom", "bottom-left", "left"];
4613
4637
  }
4614
4638
  });
@@ -4694,7 +4718,7 @@ var init_host_action_layout_descriptors = __esm({
4694
4718
  },
4695
4719
  width: { type: "integer", minimum: 1, description: LAYOUT_ACT_WIDTH_DESCRIPTION },
4696
4720
  height: { type: "integer", minimum: 1, description: LAYOUT_ACT_HEIGHT_DESCRIPTION },
4697
- mode: { type: "string", enum: [...LAYOUT_CHAT_MODES], description: LAYOUT_ACT_MODE_DESCRIPTION },
4721
+ mode: { type: "string", enum: [...LAYOUT_CHAT_MODES, ...LAYOUT_WINDOW_MODES], description: LAYOUT_ACT_MODE_DESCRIPTION },
4698
4722
  position: { type: "string", enum: [...LAYOUT_CHAT_POSITIONS], description: LAYOUT_ACT_POSITION_DESCRIPTION }
4699
4723
  },
4700
4724
  required: ["action"],
@@ -11631,6 +11655,22 @@ var init_launch_options = __esm({
11631
11655
  }
11632
11656
  });
11633
11657
 
11658
+ // ../../packages/shared/src/window-layout.ts
11659
+ var WINDOW_LAYOUT_IPC_CHANNELS;
11660
+ var init_window_layout = __esm({
11661
+ "../../packages/shared/src/window-layout.ts"() {
11662
+ "use strict";
11663
+ WINDOW_LAYOUT_IPC_CHANNELS = {
11664
+ GET_FULLSCREEN: "app:get-fullscreen",
11665
+ FULLSCREEN_CHANGED: "app:fullscreen-changed",
11666
+ SET_MIN_WINDOW_SIZE: "app:set-min-window-size",
11667
+ GET_WINDOW_LAYOUT_STATE: "app:get-window-layout-state",
11668
+ RESIZE_WINDOW: "app:resize-window",
11669
+ SET_WINDOW_FULLSCREEN: "app:set-window-fullscreen"
11670
+ };
11671
+ }
11672
+ });
11673
+
11634
11674
  // ../../packages/shared/src/agent-types.ts
11635
11675
  function hasOneM(id) {
11636
11676
  return id.endsWith(ONE_M_SUFFIX);
@@ -11658,10 +11698,11 @@ function resolveMappedClaudeModelId(model, env) {
11658
11698
  if (env[BUCKET_ENV_KEYS.opus.id]) return "opus";
11659
11699
  return stripOneM(model);
11660
11700
  }
11661
- var SESSION_AGENT_LAUNCHES_FIELD, SESSION_AGENT_TASK_MAX, DEFAULT_CONTEXT_WINDOW, CODEX_GPT_5_6_CONTEXT_WINDOW, CODEX_PERMISSION_PRESETS, DEFAULT_CODEX_PERMISSION_PRESET, DEFAULT_CODEX_PERMISSION_PROFILE, CLAUDE_ACCOUNT_PROVIDER_PREFIX, CLAUDE_CLI_ACCOUNT_PROVIDER_ID, MODEL_BUCKETS, BUCKET_ENV_KEYS, ONE_M_SUFFIX, MODEL_MAPPING_ENV_IDS;
11701
+ var SESSION_AGENT_LAUNCHES_FIELD, SESSION_AGENT_TASK_MAX, DEFAULT_CONTEXT_WINDOW, CODEX_GPT_5_6_CONTEXT_WINDOW, CODEX_PERMISSION_PRESETS, DEFAULT_CODEX_PERMISSION_PRESET, DEFAULT_CODEX_PERMISSION_PROFILE, CLAUDE_ACCOUNT_PROVIDER_PREFIX, CLAUDE_CLI_ACCOUNT_PROVIDER_ID, MODEL_BUCKETS, BUCKET_ENV_KEYS, ONE_M_SUFFIX, MODEL_MAPPING_ENV_IDS, AgentIpcChannels;
11662
11702
  var init_agent_types = __esm({
11663
11703
  "../../packages/shared/src/agent-types.ts"() {
11664
11704
  "use strict";
11705
+ init_window_layout();
11665
11706
  SESSION_AGENT_LAUNCHES_FIELD = "sessionAgentLaunchesJson";
11666
11707
  SESSION_AGENT_TASK_MAX = 1e5;
11667
11708
  DEFAULT_CONTEXT_WINDOW = 2e5;
@@ -11718,6 +11759,772 @@ var init_agent_types = __esm({
11718
11759
  };
11719
11760
  ONE_M_SUFFIX = "[1m]";
11720
11761
  MODEL_MAPPING_ENV_IDS = MODEL_BUCKETS.map((bucket) => BUCKET_ENV_KEYS[bucket].id);
11762
+ AgentIpcChannels = {
11763
+ // App-level channels
11764
+ CONNECT_CLAUDE: "app:connect-claude",
11765
+ CONNECT_CODEX: "app:connect-codex",
11766
+ CONNECT_OPENCODE: "app:connect-opencode",
11767
+ CONNECT_CURSOR: "app:connect-cursor",
11768
+ CONNECT_DEEPSEEK: "app:connect-deepseek",
11769
+ DEEPSEEK_TRAJECTORY: "app:deepseek-trajectory",
11770
+ DEEPSEEK_TRAJECTORY_PAGE: "app:deepseek-trajectory-page",
11771
+ DEEPSEEK_TRAJECTORY_PAYLOAD: "app:deepseek-trajectory-payload",
11772
+ DEEPSEEK_TRAJECTORY_WATCH: "app:deepseek-trajectory-watch",
11773
+ DEEPSEEK_TRAJECTORY_CHANGED: "app:deepseek-trajectory-changed",
11774
+ SAVE_TEXT_AS: "app:save-text-as",
11775
+ DEEPSEEK_PRESETS: "app:deepseek-presets",
11776
+ SET_CURSOR_API_KEY: "app:set-cursor-api-key",
11777
+ GET_CURSOR_AUTH_STATUS: "app:get-cursor-auth-status",
11778
+ CURSOR_LIST_AGENTS: "app:cursor-list-agents",
11779
+ CURSOR_LIST_RUNS: "app:cursor-list-runs",
11780
+ CURSOR_ARCHIVE_AGENT: "app:cursor-archive-agent",
11781
+ CURSOR_UNARCHIVE_AGENT: "app:cursor-unarchive-agent",
11782
+ CURSOR_DELETE_AGENT: "app:cursor-delete-agent",
11783
+ CURSOR_LIST_ARTIFACTS: "app:cursor-list-artifacts",
11784
+ CURSOR_DOWNLOAD_ARTIFACT: "app:cursor-download-artifact",
11785
+ CURSOR_LIST_REPOSITORIES: "app:cursor-list-repositories",
11786
+ CURSOR_UPDATE_BASE_CONFIG: "app:cursor-update-base-config",
11787
+ GET_CURSOR_BASE_CONFIG: "app:get-cursor-base-config",
11788
+ CURSOR_GET_AGENT: "app:cursor-get-agent",
11789
+ CURSOR_LIST_MESSAGES: "app:cursor-list-messages",
11790
+ CURSOR_GET_RUN: "app:cursor-get-run",
11791
+ CURSOR_CANCEL_RUN: "app:cursor-cancel-run",
11792
+ CURSOR_SDK_LOGIN: "app:cursor-sdk-login",
11793
+ CURSOR_SDK_LOGOUT: "app:cursor-sdk-logout",
11794
+ CURSOR_SDK_AUTH_STATUS: "app:cursor-sdk-auth-status",
11795
+ CURSOR_GET_USAGE: "app:cursor-get-usage",
11796
+ CURSOR_LIST_SLASH_ITEMS: "app:cursor-list-slash-items",
11797
+ GET_STARTUP_DATA: "app:get-startup-data",
11798
+ GET_APP_METRICS: "app:get-app-metrics",
11799
+ SELECT_FOLDER: "app:select-folder",
11800
+ GET_RECENT_FOLDERS: "app:get-recent-folders",
11801
+ ADD_RECENT_FOLDER: "app:add-recent-folder",
11802
+ REMOVE_RECENT_FOLDER: "app:remove-recent-folder",
11803
+ GET_PROJECT_ID: "app:get-project-id",
11804
+ OPEN_FOLDER: "app:open-folder",
11805
+ OPEN_TMP_FOLDER: "app:open-tmp-folder",
11806
+ CACHE_IMAGE: "app:cache-image",
11807
+ RESOLVE_FAVICON: "app:resolve-favicon",
11808
+ RESOLVE_SITE_IDENTITY: "app:resolve-site-identity",
11809
+ RESOLVE_LINK_PREVIEW: "app:resolve-link-preview",
11810
+ CACHE_FAVICON: "app:cache-favicon",
11811
+ CLOSE_PROJECT: "app:close-project",
11812
+ SETUP_CHECK_CLAUDE: "app:setup-check-claude",
11813
+ SETUP_INSTALL_CLAUDE: "app:setup-install-claude",
11814
+ SETUP_EVENT: "app:setup-event",
11815
+ CODEX_LIST_MODELS: "codex:list-models",
11816
+ CODEX_GET_AUTH_STATUS: "codex:get-auth-status",
11817
+ CODEX_SET_AUTH: "codex:set-auth",
11818
+ CODEX_GET_ACCOUNT_STATUS: "codex:get-account-status",
11819
+ CODEX_ACCOUNT_LOGIN_START: "codex:account-login-start",
11820
+ CODEX_ACCOUNT_LOGIN_CANCEL: "codex:account-login-cancel",
11821
+ CODEX_ACCOUNT_LOGOUT: "codex:account-logout",
11822
+ CODEX_GET_RATE_LIMITS: "codex:get-rate-limits",
11823
+ CODEX_GET_ACCOUNT_USAGE: "codex:get-account-usage",
11824
+ CODEX_GET_SERVER_DIAGNOSTICS: "codex:get-server-diagnostics",
11825
+ CODEX_GET_CONFIG_REQUIREMENTS: "codex:get-config-requirements",
11826
+ CODEX_CONSUME_RATE_LIMIT_RESET: "codex:consume-rate-limit-reset",
11827
+ CODEX_LIST_REALTIME_VOICES: "codex:list-realtime-voices",
11828
+ CODEX_LIST_REALTIME_VOICE_PREVIEWS: "codex:list-realtime-voice-previews",
11829
+ CODEX_MCP_OAUTH_LOGIN: "codex:mcp-oauth-login",
11830
+ CODEX_EXTERNAL_AGENT_DETECT: "codex:external-agent-detect",
11831
+ CODEX_EXTERNAL_AGENT_IMPORT: "codex:external-agent-import",
11832
+ // Claude channels
11833
+ CLAUDE_GET_RATE_LIMITS: "claude:get-rate-limits",
11834
+ CLAUDE_LIST_ACCOUNTS: "claude:list-accounts",
11835
+ CLAUDE_SIGN_IN_ACCOUNT: "claude:sign-in-account",
11836
+ CLAUDE_SIGN_OUT_ACCOUNT: "claude:sign-out-account",
11837
+ CLAUDE_SET_DEFAULT_ACCOUNT: "claude:set-default-account",
11838
+ CLAUDE_CANCEL_SIGN_IN: "claude:cancel-sign-in",
11839
+ // Third-party provider usage channels
11840
+ PROVIDER_GET_RATE_LIMITS: "provider:get-rate-limits",
11841
+ ACP_GET_RATE_LIMITS: "acp:get-rate-limits",
11842
+ // Agent channels
11843
+ PREWARM: "agent:prewarm",
11844
+ START_REALTIME_VOICE: "agent:start-realtime-voice",
11845
+ READY_REALTIME_VOICE: "agent:ready-realtime-voice",
11846
+ STOP_REALTIME_VOICE: "agent:stop-realtime-voice",
11847
+ LOAD_REALTIME_TIMELINE: "agent:load-realtime-timeline",
11848
+ GET_REALTIME_TIMELINE: "agent:get-realtime-timeline",
11849
+ SUGGESTED_TASK_LAUNCH_OPTIONS: "agent:suggested-task-launch-options",
11850
+ LAUNCH_SUGGESTED_TASK: "agent:launch-suggested-task",
11851
+ EVENT: "agent:event",
11852
+ SANDBOX_PROBE: "sandbox:probe",
11853
+ LIST_DIRECTORY: "agent:list-directory",
11854
+ LIST_DIRECTORY_FOR_ADD_DIR: "agent:list-directory-for-add-dir",
11855
+ VALIDATE_ADD_DIR: "agent:validate-add-dir",
11856
+ FIND_LINE_NUMBER: "agent:find-line-number",
11857
+ SEARCH_FILES: "agent:search-files",
11858
+ SEARCH_MENTIONS: "agent:search-mentions",
11859
+ PLUGINS_RELOAD: "plugins:reload",
11860
+ // Plugins
11861
+ PLUGINS_LIST: "plugins:list",
11862
+ PLUGINS_READ: "plugins:read",
11863
+ PLUGINS_READ_FILE: "plugins:read-file",
11864
+ PLUGINS_DELETE: "plugins:delete",
11865
+ PLUGINS_SET_ENABLED: "plugins:set-enabled",
11866
+ PLUGINS_REVIEW_MODS: "plugins:review-mods",
11867
+ PLUGINS_READ_CONFIG: "plugins:read-config",
11868
+ PLUGINS_SAVE_CONFIG: "plugins:save-config",
11869
+ PLUGINS_LIST_MARKETPLACE: "plugins:list-marketplace",
11870
+ PLUGINS_INSTALL: "plugins:install",
11871
+ PLUGINS_UPDATE: "plugins:update",
11872
+ PLUGINS_UPDATE_MARKETPLACE: "plugins:update-marketplace",
11873
+ PLUGINS_ADD_MARKETPLACE: "plugins:add-marketplace",
11874
+ PLUGINS_REMOVE_MARKETPLACE: "plugins:remove-marketplace",
11875
+ PLUGINS_READ_MARKETPLACE: "plugins:read-marketplace",
11876
+ PLUGINS_READ_MARKETPLACE_FILE: "plugins:read-marketplace-file",
11877
+ PLUGINS_GITHUB_STARS: "plugins:github-stars",
11878
+ /** List/search public (or authenticated) GitHub repos under an owner. */
11879
+ PLUGINS_GITHUB_SEARCH_REPOS: "plugins:github-search-repos",
11880
+ /** Free-text GitHub repository search (add-project name query). */
11881
+ PLUGINS_GITHUB_QUERY_REPOS: "plugins:github-query-repos",
11882
+ /** Authenticated viewer's repos via `gh` (add-project default GitHub list). */
11883
+ PLUGINS_GITHUB_LIST_MY_REPOS: "plugins:github-list-my-repos",
11884
+ // Skills
11885
+ SKILLS_LIST: "skills:list",
11886
+ /** Project slash skills + commands (remote node or local discovery). */
11887
+ SLASH_RESOURCES_LIST: "skills:slash-resources",
11888
+ SKILLS_READ: "skills:read",
11889
+ SKILLS_READ_FILE: "skills:read-file",
11890
+ SKILLS_INSTALL: "skills:install",
11891
+ SKILLS_DELETE: "skills:delete",
11892
+ SKILLS_TOGGLE: "skills:toggle",
11893
+ // Codex skills
11894
+ CODEX_SKILLS_LIST: "codex:skills-list",
11895
+ CODEX_SKILLS_READ: "codex:skills-read",
11896
+ CODEX_SKILLS_READ_FILE: "codex:skills-read-file",
11897
+ CODEX_SKILLS_DELETE: "codex:skills-delete",
11898
+ CODEX_SKILLS_TOGGLE: "codex:skills-toggle",
11899
+ // Codex hooks (read-only)
11900
+ CODEX_HOOKS_LIST: "codex:hooks-list",
11901
+ CODEX_MCP_STATUS: "codex:mcp-status",
11902
+ // Codex skills change notification (push to renderer)
11903
+ CODEX_SKILLS_CHANGED: "codex:skills-changed",
11904
+ // Codex goal
11905
+ // Codex marketplace
11906
+ CODEX_MARKETPLACE_ADD: "codex:marketplace-add",
11907
+ CODEX_MARKETPLACE_REMOVE: "codex:marketplace-remove",
11908
+ CODEX_MARKETPLACE_UPGRADE: "codex:marketplace-upgrade",
11909
+ // Codex plugins
11910
+ CODEX_PLUGINS_LIST: "codex:plugins-list",
11911
+ CODEX_PLUGINS_READ: "codex:plugins-read",
11912
+ CODEX_PLUGINS_READ_FILE: "codex:plugins-read-file",
11913
+ CODEX_PLUGINS_DELETE: "codex:plugins-delete",
11914
+ CODEX_PLUGINS_LIST_MARKETPLACE: "codex:plugins-list-marketplace",
11915
+ CODEX_PLUGINS_INSTALL: "codex:plugins-install",
11916
+ CODEX_PLUGINS_DIRECTORY: "codex:plugins-directory",
11917
+ CODEX_PLUGINS_CATEGORY: "codex:plugins-category",
11918
+ CODEX_PLUGINS_DETAIL: "codex:plugins-detail",
11919
+ CODEX_PLUGINS_SEARCH: "codex:plugins-search",
11920
+ CODEX_PLUGINS_PERSONAL: "codex:plugins-personal",
11921
+ CODEX_PLUGINS_INSTALL_TARGET: "codex:plugins-install-target",
11922
+ // Codex MCP config
11923
+ CODEX_MCP_LIST_CONFIG: "codex:mcp-list-config",
11924
+ CODEX_MCP_SAVE_CONFIG: "codex:mcp-save-config",
11925
+ CODEX_MCP_DELETE_CONFIG: "codex:mcp-delete-config",
11926
+ CODEX_MCP_TOGGLE_CONFIG: "codex:mcp-toggle-config",
11927
+ // dsh MCP config
11928
+ DSH_MCP_LIST_CONFIG: "dsh:mcp-list-config",
11929
+ DSH_MCP_SAVE_CONFIG: "dsh:mcp-save-config",
11930
+ DSH_MCP_DELETE_CONFIG: "dsh:mcp-delete-config",
11931
+ DSH_MCP_TOGGLE_CONFIG: "dsh:mcp-toggle-config",
11932
+ DSH_PLUGIN_LIST: "dsh:plugin-list",
11933
+ DSH_PLUGIN_INSTALL: "dsh:plugin-install",
11934
+ DSH_PLUGIN_SET_DISABLED: "dsh:plugin-set-disabled",
11935
+ DSH_PLUGIN_UNINSTALL: "dsh:plugin-uninstall",
11936
+ // MCP config
11937
+ MCP_LIST_CONFIG: "mcp:list-config",
11938
+ MCP_SAVE_CONFIG: "mcp:save-config",
11939
+ MCP_DELETE_CONFIG: "mcp:delete-config",
11940
+ MCP_TOGGLE_CONFIG: "mcp:toggle-config",
11941
+ MCP_LIST_TOOL_PERMISSIONS: "mcp:list-tool-permissions",
11942
+ MCP_SET_TOOL_PERMISSION: "mcp:set-tool-permission",
11943
+ MCP_CHECK_SERVERS: "mcp:check-servers",
11944
+ MCP_META_CACHE: "mcp:meta-cache",
11945
+ MCP_PROBE_ICONS: "mcp:probe-icons",
11946
+ MCP_OAUTH_AUTHORIZE: "mcp:oauth-authorize",
11947
+ // MCP library
11948
+ MCP_LIST_LIBRARY: "mcp:list-library",
11949
+ MCP_DELETE_LIBRARY_ENTRY: "mcp:delete-library-entry",
11950
+ // MCP bundles (.mcpb)
11951
+ MCPB_PREVIEW: "mcpb:preview",
11952
+ MCPB_INSTALL: "mcpb:install",
11953
+ MCPB_UNINSTALL: "mcpb:uninstall",
11954
+ MCPB_LIST: "mcpb:list",
11955
+ MCPB_REVEAL: "mcpb:reveal",
11956
+ // Hooks config (settings.json#hooks)
11957
+ HOOKS_LIST: "hooks:list",
11958
+ HOOKS_SAVE: "hooks:save",
11959
+ HOOKS_DELETE: "hooks:delete",
11960
+ CLAUDE_PROJECT_PREFERENCES_GET: "claude:project-preferences-get",
11961
+ CLAUDE_PROJECT_PREFERENCES_SAVE: "claude:project-preferences-save",
11962
+ // Agents
11963
+ AGENTS_LIST: "agents:list",
11964
+ AGENTS_READ_FILE: "agents:read-file",
11965
+ // Git
11966
+ GIT_INFO: "app:git-info",
11967
+ GIT_IS_REPO: "app:git-is-repo",
11968
+ GIT_INIT: "app:git-init",
11969
+ GIT_LIST_BRANCHES: "app:git-list-branches",
11970
+ GIT_SWITCH_BRANCH: "app:git-switch-branch",
11971
+ GIT_CREATE_BRANCH: "app:git-create-branch",
11972
+ GIT_WORKTREE_EXISTS: "app:git-worktree-exists",
11973
+ GIT_WORKTREE_INFO: "app:git-worktree-info",
11974
+ GIT_ACTIVATE_WORKTREE: "app:git-activate-worktree",
11975
+ GIT_SWITCH_WORKTREE: "app:git-switch-worktree",
11976
+ GIT_CHECKED_OUT_BRANCHES: "app:git-checked-out-branches",
11977
+ GIT_HANDOFF_TO_LOCAL: "app:git-handoff-to-local",
11978
+ GIT_HANDOFF_PREVIEW: "app:git-handoff-preview",
11979
+ GIT_ASSIGN_BRANCH: "app:git-assign-branch",
11980
+ GIT_STATUS_FILES: "app:git-status-files",
11981
+ GIT_LOG: "app:git-log",
11982
+ GIT_MENTION_REFS: "app:git-mention-refs",
11983
+ GIT_MENTION_CAPABILITIES: "app:git-mention-capabilities",
11984
+ GIT_FILE_TREE: "app:git-file-tree",
11985
+ GIT_LIST_DIR: "app:git-list-dir",
11986
+ FILE_MOVE: "app:file-move",
11987
+ FILE_COPY_IN: "app:file-copy-in",
11988
+ FILE_MOVE_IN: "app:file-move-in",
11989
+ FILE_DELETE: "app:file-delete",
11990
+ FILE_RENAME: "app:file-rename",
11991
+ FILE_CREATE: "app:file-create",
11992
+ FILE_SHOW_IN_FOLDER: "app:file-show-in-folder",
11993
+ SHOW_CONTEXT_MENU: "app:show-context-menu",
11994
+ START_DRAG: "app:start-drag",
11995
+ PATH_STAT: "app:path-stat",
11996
+ MEDIA_SERVER_PORT: "app:media-server-port",
11997
+ CONTENT_ZOOM: "app:content-zoom",
11998
+ BROWSER_ANNOTATE_SHORTCUT: "app:browser-annotate-shortcut",
11999
+ BROWSER_BOOKMARK_SHORTCUT: "app:browser-bookmark-shortcut",
12000
+ BROWSER_NEW_TAB_SHORTCUT: "app:browser-new-tab-shortcut",
12001
+ BROWSER_OPEN_TAB: "app:browser-open-tab",
12002
+ CLOSE_TAB_SHORTCUT: "app:close-tab-shortcut",
12003
+ CLOSE_WINDOW: "app:close-window",
12004
+ ...WINDOW_LAYOUT_IPC_CHANNELS,
12005
+ OPEN_SESSION_WINDOW: "app:open-session-window",
12006
+ /** Turn the *sender's own* window into a mini session window (and back). */
12007
+ CONVERT_WINDOW_TO_MINI: "app:convert-window-to-mini",
12008
+ RESTORE_WINDOW_FROM_MINI: "app:restore-window-from-mini",
12009
+ /** Push + pull of "is this window currently converted, and onto which session". */
12010
+ WINDOW_MINI_MODE_CHANGED: "app:window-mini-mode-changed",
12011
+ GET_WINDOW_MINI_MODE: "app:get-window-mini-mode",
12012
+ DRAG_PREVIEW_START: "app:drag-preview-start",
12013
+ DRAG_PREVIEW_END: "app:drag-preview-end",
12014
+ DRAG_PREVIEW_UPDATE: "app:drag-preview-update",
12015
+ DRAG_PREVIEW_ZONE: "app:drag-preview-zone",
12016
+ SET_WINDOW_ALWAYS_ON_TOP: "app:set-window-always-on-top",
12017
+ SET_WINDOW_CHROME_COLORS: "app:set-window-chrome-colors",
12018
+ GET_THEME: "app:get-theme",
12019
+ SET_THEME: "app:set-theme",
12020
+ THEME_CHANGED: "app:theme-changed",
12021
+ COMPOSER_DRAFTS_GET: "app:composer-drafts-get",
12022
+ COMPOSER_DRAFT_PUBLISH: "app:composer-draft-publish",
12023
+ COMPOSER_DRAFT_CHANGED: "app:composer-draft-changed",
12024
+ RECENT_FOLDERS_CHANGED: "app:recent-folders-changed",
12025
+ OPEN_EXTERNAL_LINK: "app:open-external-link",
12026
+ MOBILE_APP_DOWNLOADS: "app:mobile-app-downloads",
12027
+ CLIPBOARD_READ: "app:clipboard-read",
12028
+ CLIPBOARD_WRITE: "app:clipboard-write",
12029
+ GIT_DIFF_FILE: "app:git-diff-file",
12030
+ SESSION_PROJECT: "app:session-project",
12031
+ READ_PROJECT_FILE: "app:read-project-file",
12032
+ STAT_PREVIEW_FILE: "app:stat-preview-file",
12033
+ COMPOSE_USDZ_PREVIEW: "app:compose-usdz-preview",
12034
+ LIST_DEVICE_MODELS: "app:list-device-models",
12035
+ LOAD_DEVICE_MODEL: "app:load-device-model",
12036
+ SAVE_FILE: "app:save-file",
12037
+ READ_FILE_AS_DATA_URI: "app:read-file-as-data-uri",
12038
+ STAGE_ATTACHMENT_ORIGINAL: "app:stage-attachment-original",
12039
+ ATTACHMENT_ORIGINAL_STATUS: "app:attachment-original-status",
12040
+ RETRY_ATTACHMENT_ORIGINAL: "app:retry-attachment-original",
12041
+ SAVE_FILE_AS: "app:save-file-as",
12042
+ CLIPBOARD_WRITE_IMAGE: "app:clipboard-write-image",
12043
+ BROWSER_FETCH_IMAGE: "app:browser-fetch-image",
12044
+ BROWSER_SAVE_IMAGE: "app:browser-save-image",
12045
+ BROWSER_COPY_IMAGE_AT: "app:browser-copy-image-at",
12046
+ REVEAL_FILE: "app:reveal-file",
12047
+ // Concurrent session management
12048
+ PARK_SESSION: "agent:park-session",
12049
+ ACTIVATE_SESSION: "agent:activate-session",
12050
+ SET_SESSION_FOREGROUND: "agent:set-session-foreground",
12051
+ /** Main → renderer: the user clicked a notification; open this session. */
12052
+ NOTIFICATION_ACTIVATE: "app:notification-activate",
12053
+ // Live session snapshots for renderer resync
12054
+ GET_LIVE_SNAPSHOTS: "agent:get-live-snapshots",
12055
+ // Session history
12056
+ SESSIONS_CHANGED: "sessions:changed",
12057
+ SCHEDULED_SEND_CHANGED: "sessions:scheduled-send-changed",
12058
+ // Additional directories
12059
+ // Settings
12060
+ SET_FAST_MODE: "app:set-fast-mode",
12061
+ APP_SETTINGS_GET: "app:settings-get",
12062
+ APP_SETTINGS_SAVE: "app:settings-save",
12063
+ APP_SETTINGS_CHANGED: "app:settings-changed",
12064
+ /**
12065
+ * Node surface served to controller desktops. It runs while one is paired
12066
+ * or a "Pair New Desktop" QR is open (see `remoteNodeAccessEnabled`).
12067
+ */
12068
+ NODE_HOST_STATUS: "nodeHost:status",
12069
+ NODE_HOST_CONTROLLERS: "nodeHost:controllers",
12070
+ NODE_HOST_REMOVE_CONTROLLER: "nodeHost:removeController",
12071
+ NODE_HOST_SET_CONTROLLER_ENABLED: "nodeHost:setControllerEnabled",
12072
+ /** Take a session another desktop started here back from it. */
12073
+ NODE_HOST_RELEASE_SESSION: "nodeHost:releaseSession",
12074
+ /** Push: the controller list or the host status changed. */
12075
+ NODE_HOST_CHANGED: "nodeHost:changed",
12076
+ /** Controller QR shown here; a phone paired with the controller scans it. */
12077
+ NODE_HOST_PAIRING_START: "nodeHost:pairingStart",
12078
+ NODE_HOST_PAIRING_CONFIRM: "nodeHost:pairingConfirm",
12079
+ NODE_HOST_PAIRING_CANCEL: "nodeHost:pairingCancel",
12080
+ /** Push: {@link ControllerPairingEvent}. */
12081
+ NODE_HOST_PAIRING_EVENT: "nodeHost:pairingEvent",
12082
+ /** Development builds: a node pairing code without a phone (`desktop-node-lab`). */
12083
+ NODE_HOST_DEV_MINT_CODE: "nodeHost:devMintCode",
12084
+ /** Resolved OS Downloads folder, shown as the placeholder for an unset download directory. */
12085
+ APP_DEFAULT_DOWNLOAD_DIR: "app:default-download-dir",
12086
+ /** Jev (TypeSafe) API key for the experimental browser fast loop: configured? / replace. */
12087
+ JEV_API_KEY_STATUS: "app:jev-api-key-status",
12088
+ JEV_API_KEY_SET: "app:jev-api-key-set",
12089
+ /** What the session sync zone holds and what a sweep would free; the sweep itself. */
12090
+ SYNC_ZONE_USAGE_GET: "app:sync-zone-usage",
12091
+ SYNC_ZONE_RECLAIM: "app:sync-zone-reclaim",
12092
+ SYNC_ZONE_RETRY_HANDOFFS: "app:sync-zone-retry-handoffs",
12093
+ /** Stable per-installation id used as the analytics distinct id. */
12094
+ APP_INSTALL_ID_GET: "app:install-id-get",
12095
+ /**
12096
+ * Read Computer Use TCC status / open permission float.
12097
+ * false — status only
12098
+ * true | 'guided' — two-step onboarding float
12099
+ * 'accessibility' | 'screenRecording' — single-pane float
12100
+ */
12101
+ COMPUTER_USE_OPEN_PERMISSIONS: "computer-use:open-permissions",
12102
+ /** Restart helper once and re-read TCC / runtime permission status. */
12103
+ COMPUTER_USE_RECHECK_PERMISSIONS: "computer-use:recheck-permissions",
12104
+ /** Dismiss the Computer Use permission drag float. */
12105
+ COMPUTER_USE_CLOSE_PERMISSION_FLOAT: "computer-use:close-permission-float",
12106
+ /** Resize the permission float to match measured content size. */
12107
+ COMPUTER_USE_RESIZE_PERMISSION_FLOAT: "computer-use:resize-permission-float",
12108
+ /** Push live permission status into the drag float. */
12109
+ COMPUTER_USE_PERMISSION_STATUS: "computer-use:permission-status",
12110
+ /** Guided float: continue from Accessibility to Screen Recording. */
12111
+ COMPUTER_USE_CONTINUE_PERMISSION_STEP: "computer-use:continue-permission-step",
12112
+ /** List currently running apps (for Computer Use always-allow picker). */
12113
+ COMPUTER_USE_LIST_RUNNING_APPS: "computer-use:list-running-apps",
12114
+ /** List connected displays that can host Computer Use target windows. */
12115
+ COMPUTER_USE_LIST_DISPLAYS: "computer-use:list-displays",
12116
+ /** Connected display topology changed (add/remove/metrics). */
12117
+ COMPUTER_USE_DISPLAYS_CHANGED: "computer-use:displays-changed",
12118
+ /** Installed desktop apps catalog (mention popup / search). */
12119
+ COMPUTER_USE_LIST_INSTALLED_APPS: "computer-use:list-installed-apps",
12120
+ /** Session-scoped temporary grants from @ desktop-app mentions. */
12121
+ COMPUTER_USE_GRANT_SESSION_APPS: "computer-use:grant-session-apps",
12122
+ /** Best-effort app icon data URI for a bundle id (UI only; cached in main). */
12123
+ COMPUTER_USE_RESOLVE_APP_ICON: "computer-use:resolve-app-icon",
12124
+ /** Main -> renderer: Computer Use target metadata for the session-owned PiP. */
12125
+ COMPUTER_USE_VIEWFINDER_CLAIM: "computer-use:viewfinder-claim",
12126
+ /** Main -> renderer: compressed frame for the current Computer Use target. */
12127
+ COMPUTER_USE_VIEWFINDER_FRAME: "computer-use:viewfinder-frame",
12128
+ /** Renderer -> main: focus the active window behind a Computer Use PiP. */
12129
+ COMPUTER_USE_VIEWFINDER_FOCUS: "computer-use:viewfinder-focus",
12130
+ /** Renderer -> main: stop capture after the Computer Use PiP loses visibility. */
12131
+ COMPUTER_USE_VIEWFINDER_HIDE: "computer-use:viewfinder-hide",
12132
+ /** Renderer -> main: resume a Computer Use PiP explicitly hidden by the user. */
12133
+ COMPUTER_USE_VIEWFINDER_RESTORE: "computer-use:viewfinder-restore",
12134
+ /** Renderer -> main: match Computer Use capture pixels to the visible PiP size. */
12135
+ COMPUTER_USE_VIEWFINDER_RESIZE: "computer-use:viewfinder-resize",
12136
+ BROWSER_HISTORY_RECORD: "app:browser-history-record",
12137
+ BROWSER_HISTORY_SUGGEST: "app:browser-history-suggest",
12138
+ BROWSER_HISTORY_DELETE: "app:browser-history-delete",
12139
+ BROWSER_CERT_ERROR: "app:browser-cert-error",
12140
+ BROWSER_CERT_PROCEED: "app:browser-cert-proceed",
12141
+ /** Main -> renderer: a browser tab started or stopped producing sound. */
12142
+ BROWSER_AUDIO_STATE: "app:browser-audio-state",
12143
+ APP_SYSTEM_LOCALE: "app:system-locale",
12144
+ APP_LOCALE_CHANGED: "app:locale-changed",
12145
+ APP_ICON_PICK_FILE: "app:icon-pick-file",
12146
+ APP_ICON_SET: "app:icon-set",
12147
+ APP_ICON_RESET: "app:icon-reset",
12148
+ // Usage statistics
12149
+ USAGE_QUERY: "app:usage:query",
12150
+ USAGE_COUNTS_QUERY: "app:usage:counts",
12151
+ USAGE_HARNESS_SESSION_RANKS: "app:usage:harness-session-ranks",
12152
+ USAGE_BACKFILL_STATUS: "app:usage:backfill-status",
12153
+ USAGE_BACKFILL_DONE: "app:usage:backfill-done",
12154
+ // Logging
12155
+ GET_LOG_PATH: "app:get-log-path",
12156
+ TRACE: "app:trace",
12157
+ // Updater
12158
+ UPDATER_EVENT: "updater:event",
12159
+ UPDATER_INSTALL: "updater:install",
12160
+ NOTIFICATION_PRIME: "notifications:prime",
12161
+ UPDATER_CHECK: "updater:check",
12162
+ UPDATER_DOWNLOAD: "updater:download",
12163
+ UPDATER_SIMULATE: "updater:simulate",
12164
+ /** Pull the last updater event so a late/reloaded renderer can catch up. */
12165
+ UPDATER_GET_STATE: "updater:getState",
12166
+ /** macOS bundle-id bridge (see UpdateEvent 'identity-migration'). */
12167
+ UPDATER_MIGRATION_DOWNLOAD: "updater:migrationDownload",
12168
+ UPDATER_MIGRATION_OPEN_INSTALLER: "updater:migrationOpenInstaller",
12169
+ UPDATER_MIGRATION_REVEAL: "updater:migrationReveal",
12170
+ // File watcher
12171
+ FILE_WATCH_START: "app:file-watch-start",
12172
+ FILE_WATCH_STOP: "app:file-watch-stop",
12173
+ FILE_CHANGE_EVENT: "app:file-change-event",
12174
+ GIT_HEAD_CHANGE: "app:git-head-change",
12175
+ // Unified AI provider platform (registry + credentials + bindings)
12176
+ PLATFORMS_LIST: "platforms:list",
12177
+ PLATFORMS_CREATE_CUSTOM: "platforms:create-custom",
12178
+ PLATFORMS_UPDATE_CUSTOM: "platforms:update-custom",
12179
+ PLATFORMS_DELETE_CUSTOM: "platforms:delete-custom",
12180
+ CREDENTIALS_LIST: "credentials:list",
12181
+ CREDENTIALS_CREATE: "credentials:create",
12182
+ CREDENTIALS_UPDATE: "credentials:update",
12183
+ CREDENTIALS_DELETE: "credentials:delete",
12184
+ BINDINGS_GET: "bindings:get",
12185
+ BINDINGS_SET: "bindings:set",
12186
+ BINDINGS_CLEAR: "bindings:clear",
12187
+ PROVIDERS_TEST_ENDPOINT: "providers:test-endpoint",
12188
+ PROVIDERS_DISCOVER_MODELS: "providers:discover-models",
12189
+ ACP_LIST_AGENTS: "acp:list-agents",
12190
+ /** Refresh ACP agent model catalogs once per app open (uses cache thereafter). */
12191
+ ACP_REFRESH_MODELS: "acp:refresh-models",
12192
+ /** Report unsaved editor buffer content for ACP fs/read_text_file. */
12193
+ ACP_SET_UNSAVED_BUFFER: "acp:set-unsaved-buffer",
12194
+ /** Observe the sandbox Grok will apply (SuperOne never sets it). Read-only. */
12195
+ ACP_GET_SANDBOX: "acp:get-sandbox",
12196
+ // Media generation providers (read-only status derived from image-serving credentials)
12197
+ MEDIA_GEN_PROVIDERS: "mediaGen:providers",
12198
+ // Model catalog (models.dev, local-cached)
12199
+ MODEL_CATALOG_GET: "modelCatalog:get",
12200
+ MODEL_CATALOG_REFRESH: "modelCatalog:refresh",
12201
+ // Session Providers (new session_providers table)
12202
+ SESSION_PROVIDERS_LIST: "sessionProviders:list",
12203
+ SESSION_PROVIDERS_LIST_BY_HARNESS: "sessionProviders:list-by-harness",
12204
+ SESSION_PROVIDERS_GET: "sessionProviders:get",
12205
+ SESSION_PROVIDERS_GET_BASE: "sessionProviders:get-base",
12206
+ SESSION_PROVIDERS_CREATE: "sessionProviders:create",
12207
+ SESSION_PROVIDERS_UPDATE: "sessionProviders:update",
12208
+ SESSION_PROVIDERS_DELETE: "sessionProviders:delete",
12209
+ /** `@codex` / `@grok` composer list — usable agents only. */
12210
+ SESSION_PROVIDERS_MENTION_TARGETS: "sessionProviders:mention-targets",
12211
+ // Bash output watcher
12212
+ BASH_OUTPUT_WATCH: "app:bash-output-watch",
12213
+ BASH_OUTPUT_UNWATCH: "app:bash-output-unwatch",
12214
+ BASH_OUTPUT_EVENT: "app:bash-output-event",
12215
+ BASH_OUTPUT_READ_MORE: "app:bash-output-read-more",
12216
+ BASH_OUTPUT_READ_FILE: "app:bash-output-read-file",
12217
+ // Workflow subagent transcripts
12218
+ LIST_WORKFLOW_AGENTS: "app:list-workflow-agents",
12219
+ READ_WORKFLOW_OUTPUT: "app:read-workflow-output",
12220
+ READ_WORKFLOW_SCRIPT: "app:read-workflow-script",
12221
+ /** Scan project + user `.grok/workflows/*.rhai` with parsed args. */
12222
+ DISCOVER_GROK_WORKFLOWS: "app:discover-grok-workflows",
12223
+ READ_SUBAGENT_TRANSCRIPT: "app:read-subagent-transcript",
12224
+ // Remote control
12225
+ REMOTE_CLIENT_REGISTERED: "remote:client-registered",
12226
+ REMOTE_LIST_PAIRED: "remote:list-paired",
12227
+ REMOTE_REMOVE_PAIRED: "remote:remove-paired",
12228
+ REMOTE_SET_PAIRED_ENABLED: "remote:set-paired-enabled",
12229
+ REMOTE_DEVICE_STATUS_CHANGED: "remote:device-status-changed",
12230
+ REMOTE_UPLOAD_PROGRESS: "remote:upload-progress",
12231
+ REMOTE_START_PAIRING: "remote:start-pairing",
12232
+ REMOTE_CONFIRM_PAIRING: "remote:confirm-pairing",
12233
+ REMOTE_CANCEL_PAIRING: "remote:cancel-pairing",
12234
+ REMOTE_PAIRING_CODE_RECEIVED: "remote:pairing-code-received",
12235
+ REMOTE_PAIRING_EXPIRED: "remote:pairing-expired",
12236
+ REMOTE_PAIRING_ALREADY_PAIRED: "remote:pairing-already-paired",
12237
+ REMOTE_GET_RELAY_STATUS: "remote:get-relay-status",
12238
+ REMOTE_GET_LAN_STATUS: "remote:get-lan-status",
12239
+ REMOTE_GET_HOSTNAME: "remote:get-hostname",
12240
+ REMOTE_GET_CONFIG: "remote:get-config",
12241
+ REMOTE_SAVE_CONFIG: "remote:save-config",
12242
+ REMOTE_RELAY_STATUS: "remote:relay-status",
12243
+ REMOTE_LAN_STATUS: "remote:lan-status",
12244
+ WIDGET_IFRAME_READY: "widget:iframe-ready",
12245
+ WIDGET_SAVE_TEMPLATE: "widget:save-template",
12246
+ // Mini-App
12247
+ MINIAPP_LIST: "miniapp:list",
12248
+ MINIAPP_OPEN: "miniapp:open",
12249
+ MINIAPP_CLOSE: "miniapp:close",
12250
+ MINIAPP_AUTHORIZE: "miniapp:authorize",
12251
+ MINIAPP_UNAUTHORIZE: "miniapp:unauthorize",
12252
+ BROWSER_AUTOMATION_CALL: "browser:automation-call",
12253
+ BROWSER_AUTOMATION_RESULT: "browser:automation-result",
12254
+ MINIAPP_TOOL_INTERCEPT_OPEN: "miniapp:tool-intercept-open",
12255
+ MINIAPP_TOOL_INTERCEPT_SUBMIT: "miniapp:tool-intercept-submit",
12256
+ MINIAPP_TOOL_INTERCEPT_CANCEL: "miniapp:tool-intercept-cancel",
12257
+ MINIAPP_TOOL_INTERCEPT_CLEAR: "miniapp:tool-intercept-clear",
12258
+ MINIAPP_SHOW_ITEM_IN_FOLDER: "miniapp:show-item-in-folder",
12259
+ MINIAPP_START_DRAG: "miniapp:start-drag",
12260
+ MINIAPP_GET_PRELOAD_PATH: "miniapp:get-preload-path",
12261
+ MINIAPP_HOST_POST_MESSAGE: "miniapp:host-post-message",
12262
+ MINIAPP_HOST_MESSAGE: "miniapp:host-message",
12263
+ /** main → renderer: stdout/stderr and failures of a development MiniApp Host. */
12264
+ MINIAPP_HOST_LOG: "miniapp:host-log",
12265
+ MINIAPP_DEV_SERVER: "miniapp:dev-server",
12266
+ MINIAPP_HOST_LIST: "miniapp:host-list",
12267
+ MINIAPP_HOST_STOP: "miniapp:host-stop",
12268
+ MINIAPP_HOST_STATE: "miniapp:host-state",
12269
+ /** main → renderer: a MiniApp Host asks the renderer to perform a host action. */
12270
+ MINIAPP_HOST_ACTION: "miniapp:host-action",
12271
+ /** renderer → main: result of one MINIAPP_HOST_ACTION. */
12272
+ MINIAPP_HOST_ACTION_RESULT: "miniapp:host-action-result",
12273
+ /** renderer → main: the agent consumed a mini-app's context card. */
12274
+ MINIAPP_CONTEXT_CONSUMED: "miniapp:context-consumed",
12275
+ MINIAPP_DETECT_DEV: "miniapp:detect-dev",
12276
+ MINIAPP_PREVIEW: "miniapp:preview",
12277
+ MINIAPP_CONFIRM_INSTALL: "miniapp:confirm-install",
12278
+ MINIAPP_CANCEL_INSTALL: "miniapp:cancel-install",
12279
+ MINIAPP_UNINSTALL: "miniapp:uninstall",
12280
+ MINIAPP_PACK: "miniapp:pack",
12281
+ MINIAPP_GET_INSTALL_META: "miniapp:get-install-meta",
12282
+ MINIAPP_GET_PREAPPROVED: "miniapp:get-preapproved",
12283
+ MINIAPP_SET_PREAPPROVED: "miniapp:set-preapproved",
12284
+ MINIAPP_DEV_APP_READY: "miniapp:dev-app-ready",
12285
+ MINIAPP_DEV_REGISTRY_LIST: "miniapp:dev-registry:list",
12286
+ MINIAPP_DEV_REGISTRY_ADD: "miniapp:dev-registry:add",
12287
+ MINIAPP_DEV_REGISTRY_REMOVE: "miniapp:dev-registry:remove",
12288
+ MINIAPP_DEV_REGISTRY_INSTALL: "miniapp:dev-registry:install",
12289
+ MINIAPP_DEV_REGISTRY_UNINSTALL: "miniapp:dev-registry:uninstall",
12290
+ MINIAPP_DEV_REGISTRY_SET_ENABLED: "miniapp:dev-registry:set-enabled",
12291
+ MINIAPP_DEV_REGISTRY_REVEAL_SOURCE: "miniapp:dev-registry:reveal-source",
12292
+ // Automations
12293
+ AUTOMATIONS_LIST: "automations:list",
12294
+ AUTOMATIONS_CREATE: "automations:create",
12295
+ AUTOMATIONS_UPDATE: "automations:update",
12296
+ AUTOMATIONS_DELETE: "automations:delete",
12297
+ AUTOMATIONS_RUN_NOW: "automations:run-now",
12298
+ /** Run lifecycle (running/completed/error) for a single automation. */
12299
+ AUTOMATIONS_EVENT: "automations:event",
12300
+ /** List mutation (create/update/delete) — renderer should re-list. Optional projectPath scopes refresh. */
12301
+ AUTOMATIONS_CHANGED: "automations:changed",
12302
+ // Terminal
12303
+ TERMINAL_CREATE: "terminal:create",
12304
+ TERMINAL_LIST: "terminal:list",
12305
+ TERMINAL_SNAPSHOT: "terminal:snapshot",
12306
+ TERMINAL_WRITE: "terminal:write",
12307
+ TERMINAL_RESIZE: "terminal:resize",
12308
+ TERMINAL_KILL: "terminal:kill",
12309
+ TERMINAL_CLAIM: "terminal:claim",
12310
+ TERMINAL_RELEASE: "terminal:release",
12311
+ TERMINAL_EVENT: "terminal:event",
12312
+ /** Stored "always allow in this project" command rules (settings > Terminal). */
12313
+ TERMINAL_COMMAND_RULES_LIST: "terminal:command-rules:list",
12314
+ TERMINAL_COMMAND_RULE_REMOVE: "terminal:command-rules:remove",
12315
+ // Multi-environment / remote node (Main environment host)
12316
+ ENVIRONMENT_SESSION_SOURCE: "environment:sessionSource",
12317
+ ENVIRONMENT_SESSION_LINK_METADATA: "environment:sessionLinkMetadata",
12318
+ ENVIRONMENT_SESSION_LINK_TARGET: "environment:sessionLinkTarget",
12319
+ ENVIRONMENT_LIST: "environment:list",
12320
+ ENVIRONMENT_GET_LOCAL_ID: "environment:getLocalId",
12321
+ ENVIRONMENT_WORKSPACE_LIST_DIR: "environment:workspaceListDir",
12322
+ ENVIRONMENT_WORKSPACE_READ_FILE: "environment:workspaceReadFile",
12323
+ /** Remote tool-output / agent-transcript byte-offset tail watch. */
12324
+ ENVIRONMENT_WORKSPACE_TAIL_WATCH_START: "environment:workspaceTailWatchStart",
12325
+ ENVIRONMENT_WORKSPACE_TAIL_WATCH_POLL: "environment:workspaceTailWatchPoll",
12326
+ ENVIRONMENT_WORKSPACE_TAIL_WATCH_STOP: "environment:workspaceTailWatchStop",
12327
+ ENVIRONMENT_PAIR_REMOTE: "environment:pairRemote",
12328
+ ENVIRONMENT_CONNECT_FAILOVER: "environment:connectWithFailover",
12329
+ /** Dev-only: probe local remote-node lab (`bun run dev:cli:lab`). */
12330
+ ENVIRONMENT_LOCAL_LAB_STATUS: "environment:localLabStatus",
12331
+ /** Dev-only: mint pairing token + pair/connect to local lab. */
12332
+ ENVIRONMENT_PAIR_LOCAL_LAB: "environment:pairLocalLab",
12333
+ // Environment management UI (Settings → Environments)
12334
+ ENVIRONMENT_LIST_ITEMS: "environment:listItems",
12335
+ ENVIRONMENT_ADD_OVER_SSH: "environment:addOverSsh",
12336
+ /** Install this desktop's CLI on an already-paired node and restart it. */
12337
+ ENVIRONMENT_UPGRADE_NODE: "environment:upgradeNode",
12338
+ /** Read local ~/.ssh/config Host aliases for the add-device picker. */
12339
+ ENVIRONMENT_LIST_SSH_CONFIG_HOSTS: "environment:listSshConfigHosts",
12340
+ /** Projects for a host (`local` or remote connectionId) — sidebar project list. */
12341
+ ENVIRONMENT_LIST_PROJECTS: "environment:listProjects",
12342
+ /** Open/register a project path on a host (local disk or remote project.open). */
12343
+ ENVIRONMENT_OPEN_PROJECT: "environment:openProject",
12344
+ /** Unregister a project from a host list (local recents or remote project.remove). */
12345
+ ENVIRONMENT_REMOVE_PROJECT: "environment:removeProject",
12346
+ /** Edit Project: rename and/or set the project's workspace folders. */
12347
+ ENVIRONMENT_UPDATE_PROJECT: "environment:updateProject",
12348
+ /** List sessions for a remote project (local uses sessions:* DB IPC). */
12349
+ ENVIRONMENT_LIST_SESSIONS: "environment:listSessions",
12350
+ /** Cross-project pinned sessions for one environment (sidebar Pinned section). */
12351
+ ENVIRONMENT_LIST_PINNED_SESSIONS: "environment:listPinnedSessions",
12352
+ /** Unsent composer drafts, stored in the environment that owns the project. */
12353
+ ENVIRONMENT_LIST_DRAFTS: "environment:listDrafts",
12354
+ ENVIRONMENT_UPSERT_DRAFT: "environment:upsertDraft",
12355
+ ENVIRONMENT_DELETE_DRAFT: "environment:deleteDraft",
12356
+ ENVIRONMENT_DISCONNECT_DRAFT: "environment:disconnectDraft",
12357
+ ENVIRONMENT_PREPARE_DRAFT_OPEN: "environment:prepareDraftOpen",
12358
+ ENVIRONMENT_DRAFT_OPEN_READY: "environment:draftOpenReady",
12359
+ /** Create a session on a remote project (local uses agent:create-session). */
12360
+ ENVIRONMENT_CREATE_SESSION: "environment:createSession",
12361
+ ENVIRONMENT_GET_SESSION: "environment:getSession",
12362
+ ENVIRONMENT_SEND_SESSION_MESSAGE: "environment:sendSessionMessage",
12363
+ /** Open a remote session in the chat at a node snapshot (`session.load`) and follow it. */
12364
+ ENVIRONMENT_OPEN_REMOTE_SESSION: "environment:openRemoteSession",
12365
+ ENVIRONMENT_SUBSCRIBE_DETAIL: "environment:subscribeDetail",
12366
+ ENVIRONMENT_UNSUBSCRIBE_DETAIL: "environment:unsubscribeDetail",
12367
+ ENVIRONMENT_INTERRUPT_SESSION: "environment:interruptSession",
12368
+ /** Change a session's durable settings (modes, model, effort, provider), local or remote. */
12369
+ ENVIRONMENT_PATCH_SESSION_SETTINGS: "environment:patchSessionSettings",
12370
+ ENVIRONMENT_CALL_SESSION: "environment:callSession",
12371
+ ENVIRONMENT_DISCONNECT_SESSION_CONTROLLER: "environment:disconnectSessionController",
12372
+ ENVIRONMENT_CALL_COMPOSER: "environment:callComposer",
12373
+ ENVIRONMENT_CALL_SESSION_LIST: "environment:callSessionList",
12374
+ /** Take control of a remote session back after its host released it (Reconnect). */
12375
+ ENVIRONMENT_RECLAIM_SESSION_CONTROL: "environment:reclaimSessionControl",
12376
+ /** One op on a session's mod surface (`@superone/shared/mod-ui`), local or remote. */
12377
+ ENVIRONMENT_MOD_UI: "environment:modUi",
12378
+ ENVIRONMENT_RENAME_SESSION: "environment:renameSession",
12379
+ ENVIRONMENT_REMOVE_SESSION: "environment:removeSession",
12380
+ ENVIRONMENT_SET_SESSION_UI_FLAGS: "environment:setSessionUiFlags",
12381
+ ENVIRONMENT_FORK_SESSION: "environment:forkSession",
12382
+ ENVIRONMENT_RESPOND_SESSION_PERMISSION: "environment:respondSessionPermission",
12383
+ ENVIRONMENT_RESPOND_SESSION_QUESTION: "environment:respondSessionQuestion",
12384
+ ENVIRONMENT_RESPOND_SESSION_PLAN: "environment:respondSessionPlan",
12385
+ ENVIRONMENT_RESUME_REMOTE_SESSION_EVENTS: "environment:resumeRemoteSessionEvents",
12386
+ /** List directories at an absolute path for the add-project browser. */
12387
+ ENVIRONMENT_BROWSE_PATH: "environment:browsePath",
12388
+ /** Clone a git repository onto a host and register it as a project. */
12389
+ ENVIRONMENT_CLONE_REPOSITORY: "environment:cloneRepository",
12390
+ /** Main → requesting renderer clone download percent (local host only). */
12391
+ ENVIRONMENT_CLONE_PROGRESS: "environment:cloneProgress",
12392
+ ENVIRONMENT_CONNECT: "environment:connect",
12393
+ ENVIRONMENT_DISCONNECT: "environment:disconnect",
12394
+ ENVIRONMENT_FORGET: "environment:forget",
12395
+ /** Explicit transient retry (does not unblock auth). */
12396
+ ENVIRONMENT_RETRY_NOW: "environment:retryNow",
12397
+ /** Re-pair existing connectionId with a new pairing token (identity-safe). */
12398
+ ENVIRONMENT_REPAIR_PAIRING: "environment:repairPairing",
12399
+ /** Re-pair over the stored SSH endpoint; the desktop mints the token itself. */
12400
+ ENVIRONMENT_REPAIR_PAIRING_SSH: "environment:repairPairingOverSsh",
12401
+ /** Node QR shown here; a phone paired with the node scans it. */
12402
+ ENVIRONMENT_NODE_PAIRING_START: "environment:nodePairingStart",
12403
+ ENVIRONMENT_NODE_PAIRING_CANCEL: "environment:nodePairingCancel",
12404
+ /** Main → renderer push: {@link NodePairingEvent}. */
12405
+ ENVIRONMENT_NODE_PAIRING_EVENT: "environment:nodePairingEvent",
12406
+ /** Development builds: pair a node code without a phone (`desktop-node-lab`). */
12407
+ ENVIRONMENT_DEV_PAIR_NODE_CODE: "environment:devPairNodeCode",
12408
+ /** Main → renderer supervisor state push. */
12409
+ ENVIRONMENT_STATUS_EVENT: "environment:statusEvent",
12410
+ /** A remote session the chat must read again (`EnvironmentHost.onRemoteSessionResync`). */
12411
+ ENVIRONMENT_SESSION_RESYNC_EVENT: "environment:sessionResyncEvent",
12412
+ /** A paired machine's project list changed (`EnvironmentHost.onProjectListChanged`). */
12413
+ ENVIRONMENT_PROJECTS_CHANGED_EVENT: "environment:projectsChangedEvent",
12414
+ /** Main → renderer SSH probe/install progress push. */
12415
+ ENVIRONMENT_INSTALL_PROGRESS: "environment:installProgress",
12416
+ /** Node-local AI provider credentials (masked). */
12417
+ ENVIRONMENT_PROVIDER_LIST_CREDENTIALS: "environment:providerListCredentials",
12418
+ ENVIRONMENT_PROVIDER_CREATE_CREDENTIAL: "environment:providerCreateCredential",
12419
+ ENVIRONMENT_PROVIDER_UPDATE_CREDENTIAL: "environment:providerUpdateCredential",
12420
+ ENVIRONMENT_PROVIDER_DELETE_CREDENTIAL: "environment:providerDeleteCredential",
12421
+ ENVIRONMENT_PROVIDER_LIST_BINDINGS: "environment:providerListBindings",
12422
+ ENVIRONMENT_PROVIDER_SET_BINDING: "environment:providerSetBinding",
12423
+ ENVIRONMENT_PROVIDER_CLEAR_BINDING: "environment:providerClearBinding",
12424
+ ENVIRONMENT_PROVIDER_LIST_CUSTOM_PLATFORMS: "environment:providerListCustomPlatforms",
12425
+ ENVIRONMENT_PROVIDER_UPSERT_CUSTOM_PLATFORM: "environment:providerUpsertCustomPlatform",
12426
+ ENVIRONMENT_PROVIDER_DELETE_CUSTOM_PLATFORM: "environment:providerDeleteCustomPlatform",
12427
+ /** Push desktop credentials → node (Main builds plaintext bundle; renderer never sees secrets). */
12428
+ ENVIRONMENT_PROVIDER_PUSH_LOCAL: "environment:providerPushLocal",
12429
+ /** Pull node credentials → desktop (admin). */
12430
+ ENVIRONMENT_PROVIDER_PULL_REMOTE: "environment:providerPullRemote",
12431
+ ENVIRONMENT_PROVIDER_LIST_MODELS: "environment:providerListModels",
12432
+ /** Remote node harness catalog (node:admin). */
12433
+ // The four things only the iOS Simulator has: whether this machine has a usable
12434
+ // Xcode, which runtimes it installed, Apple's DeviceKit artwork, and making a new
12435
+ // simulator. Android has no counterpart to any of them, so they are NOT part of
12436
+ // the neutral set below and never will be.
12437
+ ENVIRONMENT_IOS_SIMULATOR_STATUS: "environment:iosSimulatorStatus",
12438
+ ENVIRONMENT_IOS_SIMULATOR_RUNTIMES: "environment:iosSimulatorRuntimes",
12439
+ ENVIRONMENT_IOS_SIMULATOR_CHROME: "environment:iosSimulatorChrome",
12440
+ ENVIRONMENT_IOS_SIMULATOR_CREATE: "environment:iosSimulatorCreate",
12441
+ // Devices of any platform — simulators, emulators and phones through one set of
12442
+ // channels. Everything the panel does to a device it already has is here; the
12443
+ // platform is carried in the device id, and `device/ipc.ts` routes on it.
12444
+ // What this machine could still be given. Neutral on purpose: the menu that offers
12445
+ // "add a device" offers every platform's path in one list, and only one of them —
12446
+ // creating an iOS simulator — is something SuperOne finishes itself.
12447
+ ENVIRONMENT_DEVICE_SETUP_OPTIONS: "environment:deviceSetupOptions",
12448
+ ENVIRONMENT_DEVICE_SETUP_OPEN: "environment:deviceSetupOpen",
12449
+ ENVIRONMENT_DEVICE_LIST: "environment:deviceList",
12450
+ ENVIRONMENT_DEVICE_BIND: "environment:deviceBind",
12451
+ ENVIRONMENT_DEVICE_BOOT: "environment:deviceBoot",
12452
+ ENVIRONMENT_DEVICE_DETACH: "environment:deviceDetach",
12453
+ ENVIRONMENT_DEVICE_SHUTDOWN: "environment:deviceShutdown",
12454
+ ENVIRONMENT_DEVICE_RELEASE: "environment:deviceRelease",
12455
+ ENVIRONMENT_DEVICE_INPUT: "environment:deviceInput",
12456
+ ENVIRONMENT_DEVICE_SCREENSHOT: "environment:deviceScreenshot",
12457
+ ENVIRONMENT_DEVICE_RECORD_START: "environment:deviceRecordStart",
12458
+ ENVIRONMENT_DEVICE_RECORD_STOP: "environment:deviceRecordStop",
12459
+ ENVIRONMENT_DEVICE_STREAM_OPEN: "environment:deviceStreamOpen",
12460
+ ENVIRONMENT_DEVICE_STREAM_CLOSE: "environment:deviceStreamClose",
12461
+ ENVIRONMENT_DEVICE_STREAM_PORT: "environment:deviceStreamPort",
12462
+ ENVIRONMENT_DEVICE_STATE: "environment:deviceState",
12463
+ ENVIRONMENT_DEVICE_ENVIRONMENT: "environment:deviceEnvironment",
12464
+ ENVIRONMENT_DEVICE_CONFIGURE: "environment:deviceConfigure",
12465
+ ENVIRONMENT_DEVICE_ENVIRONMENT_CHANGED: "environment:deviceEnvironmentChanged",
12466
+ /** Main -> renderer: the concrete device currently operated by an agent tool. */
12467
+ ENVIRONMENT_DEVICE_VIEWFINDER_CLAIM: "environment:deviceViewfinderClaim",
12468
+ ENVIRONMENT_DEVICE_ROTATE_GESTURE: "environment:deviceRotateGesture",
12469
+ // Local desktop harness installation catalog (Settings → Harnesses)
12470
+ HARNESS_LIST: "harness:list",
12471
+ HARNESS_ENABLE: "harness:enable",
12472
+ HARNESS_DISABLE: "harness:disable",
12473
+ HARNESS_PROBE: "harness:probe",
12474
+ HARNESS_ENSURE: "harness:ensure",
12475
+ /** Main → renderer progress while downloading/extracting a managed runtime. */
12476
+ HARNESS_INSTALL_PROGRESS: "harness:installProgress",
12477
+ /** Onboarding: scan PATH for first-party harness CLIs. */
12478
+ HARNESS_SCAN_CLI: "harness:scanCli",
12479
+ /**
12480
+ * Startup fallback: ensure every enabled managed harness matches the app pin.
12481
+ * Progress via HARNESS_INSTALL_PROGRESS. Happy path pre-fetches during update.
12482
+ */
12483
+ HARNESS_ALIGN_ENABLED: "harness:alignEnabled",
12484
+ /** True when any enabled managed harness is not pin-aligned (skip gate UI if false). */
12485
+ HARNESS_NEEDS_ALIGN: "harness:needsAlign",
12486
+ /** Retry harness pre-fetch after a failed atomic update package. */
12487
+ UPDATER_RETRY_HARNESS: "updater:retryHarness",
12488
+ /** Remote Skills / MCP via node `skills.*` / `mcp.*` (EnvironmentHost). */
12489
+ ENVIRONMENT_LIST_REMOTE_SKILLS: "environment:listRemoteSkills",
12490
+ ENVIRONMENT_GET_REMOTE_SKILL: "environment:getRemoteSkill",
12491
+ ENVIRONMENT_READ_REMOTE_SKILL_FILE: "environment:readRemoteSkillFile",
12492
+ ENVIRONMENT_DELETE_REMOTE_SKILL: "environment:deleteRemoteSkill",
12493
+ ENVIRONMENT_INSTALL_REMOTE_SKILL: "environment:installRemoteSkill",
12494
+ ENVIRONMENT_LIST_REMOTE_MCP_CONFIGS: "environment:listRemoteMcpConfigs",
12495
+ ENVIRONMENT_SAVE_REMOTE_MCP_CONFIG: "environment:saveRemoteMcpConfig",
12496
+ ENVIRONMENT_TOGGLE_REMOTE_MCP_CONFIG: "environment:toggleRemoteMcpConfig",
12497
+ ENVIRONMENT_DELETE_REMOTE_MCP_CONFIG: "environment:deleteRemoteMcpConfig",
12498
+ /** Node harness.resources aggregate (models + skills/commands/agents/prompts). */
12499
+ ENVIRONMENT_MCP_APPS_PROVIDER: "environment:mcpApps.provider",
12500
+ MCP_APP_HOST_REQUEST: "environment:mcpApps.hostRequest",
12501
+ MCP_APP_REGISTER_DOCUMENT: "environment:mcpApps.registerDocument",
12502
+ MCP_APP_RELEASE_DOCUMENT: "environment:mcpApps.releaseDocument",
12503
+ MCP_APP_CANCEL_REQUEST: "environment:mcpApps.cancelRequest",
12504
+ /** File entrypoints: which Apps open a file, open it in one, close it. */
12505
+ MCP_APP_FILE_HANDLERS: "environment:mcpApps.fileHandlers",
12506
+ MCP_APP_OPEN_FILE: "environment:mcpApps.openFile",
12507
+ MCP_APP_CLOSE_FILE: "environment:mcpApps.closeFile",
12508
+ /** Composer @-mentions from servers that declare `mentions/search`. */
12509
+ MCP_APP_MENTION_SEARCH: "environment:mcpApps.mentionSearch",
12510
+ MCP_APP_MENTION_READ: "environment:mcpApps.mentionRead",
12511
+ MCP_FORM_PICK_RESOURCES: "environment:mcpForm.pickResources",
12512
+ MCP_FORM_PREVIEW_RESOURCE: "environment:mcpForm.previewResource",
12513
+ /** Sign a View's MCP server in through its harness (browser + optional loopback relay). */
12514
+ ENVIRONMENT_MCP_APPS_AUTHENTICATE: "environment:mcpApps.authenticate",
12515
+ ENVIRONMENT_HARNESS_RESOURCES: "environment:harnessResources",
12516
+ /** Node session_providers CRUD. */
12517
+ /** Node-side collaboration agent profiles — authoritative agentIds for @-mentions on a remote session. */
12518
+ ENVIRONMENT_COLLAB_LIST_PROFILES: "environment:collabListProfiles",
12519
+ /** Agent profiles a remote collaboration child can run on an environmentId (RemoteAgentProfiles). */
12520
+ ENVIRONMENT_REMOTE_AGENT_PROFILES: "environment:remoteAgentProfiles",
12521
+ ENVIRONMENT_SESSION_PROVIDERS_LIST: "environment:sessionProvidersList",
12522
+ ENVIRONMENT_SESSION_PROVIDERS_GET: "environment:sessionProvidersGet",
12523
+ ENVIRONMENT_SESSION_PROVIDERS_GET_BASE: "environment:sessionProvidersGetBase",
12524
+ ENVIRONMENT_SESSION_PROVIDERS_CREATE: "environment:sessionProvidersCreate",
12525
+ ENVIRONMENT_SESSION_PROVIDERS_UPDATE: "environment:sessionProvidersUpdate",
12526
+ ENVIRONMENT_SESSION_PROVIDERS_DELETE: "environment:sessionProvidersDelete"
12527
+ };
11721
12528
  }
11722
12529
  });
11723
12530
 
@@ -18419,7 +19226,7 @@ var init_suggested_task_launch = __esm({
18419
19226
  function record5(value) {
18420
19227
  return value && typeof value === "object" && !Array.isArray(value) ? value : {};
18421
19228
  }
18422
- function isSuggestTool(toolName) {
19229
+ function isSuggestTaskTool(toolName) {
18423
19230
  if (typeof toolName !== "string") return false;
18424
19231
  const mcp = parseMcpToolName(toolName);
18425
19232
  return mcp?.serverName === "superone" && mcp.mcpToolName === SUGGEST_TASK_TOOL_NAME;
@@ -18447,7 +19254,7 @@ function contentOf(message) {
18447
19254
  function locateToolUse(messages, toolUseId) {
18448
19255
  for (let messageIndex = messages.length - 1; messageIndex >= 0; messageIndex--) {
18449
19256
  const use = contentOf(messages[messageIndex]).find((row2) => row2.type === "tool_use" && row2.toolUseId === toolUseId);
18450
- if (use) return isSuggestTool(use.toolName) ? { messageIndex, rowId: String(use.toolUseId), row: use } : null;
19257
+ if (use) return isSuggestTaskTool(use.toolName) ? { messageIndex, rowId: String(use.toolUseId), row: use } : null;
18451
19258
  }
18452
19259
  return null;
18453
19260
  }
@@ -21730,6 +22537,8 @@ var init_harness_capabilities = __esm({
21730
22537
  terminalCommandApproval: "harness",
21731
22538
  modUi: true,
21732
22539
  supportsShortWidgetResult: true,
22540
+ supportsCuratedPluginDirectory: false,
22541
+ supportsMcpToolPermissionRules: true,
21733
22542
  // `ultrathink` adds a deeper-reasoning reminder to the turn (effort is
21734
22543
  // untouched); `ultracode` opts it into the Workflow tool, on messages stamped
21735
22544
  // human — see `claudeMessageOrigin`.
@@ -21760,6 +22569,8 @@ var init_harness_capabilities = __esm({
21760
22569
  terminalCommandApproval: "harness",
21761
22570
  modUi: false,
21762
22571
  supportsShortWidgetResult: true,
22572
+ supportsCuratedPluginDirectory: true,
22573
+ supportsMcpToolPermissionRules: false,
21763
22574
  promptKeywords: [],
21764
22575
  displayName: "Codex"
21765
22576
  },
@@ -21798,6 +22609,8 @@ var init_harness_capabilities = __esm({
21798
22609
  terminalCommandApproval: "harness",
21799
22610
  modUi: false,
21800
22611
  supportsShortWidgetResult: false,
22612
+ supportsCuratedPluginDirectory: false,
22613
+ supportsMcpToolPermissionRules: false,
21801
22614
  promptKeywords: [],
21802
22615
  displayName: "Others"
21803
22616
  },
@@ -21820,6 +22633,8 @@ var init_harness_capabilities = __esm({
21820
22633
  terminalCommandApproval: "harness",
21821
22634
  modUi: false,
21822
22635
  supportsShortWidgetResult: false,
22636
+ supportsCuratedPluginDirectory: false,
22637
+ supportsMcpToolPermissionRules: false,
21823
22638
  promptKeywords: [],
21824
22639
  displayName: "OpenCode"
21825
22640
  },
@@ -21844,6 +22659,8 @@ var init_harness_capabilities = __esm({
21844
22659
  terminalCommandApproval: "executor",
21845
22660
  modUi: false,
21846
22661
  supportsShortWidgetResult: false,
22662
+ supportsCuratedPluginDirectory: false,
22663
+ supportsMcpToolPermissionRules: false,
21847
22664
  promptKeywords: [],
21848
22665
  displayName: "Cursor"
21849
22666
  },
@@ -21881,6 +22698,8 @@ var init_harness_capabilities = __esm({
21881
22698
  terminalCommandApproval: "harness",
21882
22699
  modUi: false,
21883
22700
  supportsShortWidgetResult: false,
22701
+ supportsCuratedPluginDirectory: false,
22702
+ supportsMcpToolPermissionRules: false,
21884
22703
  promptKeywords: [],
21885
22704
  displayName: "DeepSeek"
21886
22705
  }
@@ -32200,36 +33019,12 @@ var init_fuzzy = __esm({
32200
33019
  }
32201
33020
  });
32202
33021
 
32203
- // ../../packages/runtime/src/fs/plugins-manage.ts
32204
- import { execFile as execFile3, execFileSync as execFileSync2 } from "node:child_process";
32205
- import {
32206
- cpSync,
32207
- existsSync as existsSync17,
32208
- mkdirSync as mkdirSync9,
32209
- readdirSync as readdirSync6,
32210
- readFileSync as readFileSync11,
32211
- statSync as statSync5,
32212
- writeFileSync as writeFileSync8
32213
- } from "node:fs";
32214
- import { dirname as dirname10, join as join18, resolve as resolve9 } from "node:path";
33022
+ // ../../packages/runtime/src/fs/claude-settings-files.ts
33023
+ import { existsSync as existsSync17, mkdirSync as mkdirSync9, readFileSync as readFileSync11, writeFileSync as writeFileSync8 } from "node:fs";
33024
+ import { dirname as dirname10, join as join18 } from "node:path";
32215
33025
  import { homedir as osHomedir7 } from "node:os";
32216
- function homeOf6(opts) {
32217
- return opts?.homeDir ?? osHomedir7();
32218
- }
32219
- function pluginsDir(opts) {
32220
- return join18(homeOf6(opts), ".claude", "plugins");
32221
- }
32222
- function installedFile(opts) {
32223
- return join18(pluginsDir(opts), "installed_plugins.json");
32224
- }
32225
- function marketplacesFile(opts) {
32226
- return join18(pluginsDir(opts), "known_marketplaces.json");
32227
- }
32228
- function installCountsFile(opts) {
32229
- return join18(pluginsDir(opts), "install-counts-cache.json");
32230
- }
32231
33026
  function getUserSettingsPath(opts) {
32232
- return join18(homeOf6(opts), ".claude", "settings.json");
33027
+ return join18(opts?.homeDir ?? osHomedir7(), ".claude", "settings.json");
32233
33028
  }
32234
33029
  function getProjectSettingsPath2(cwd) {
32235
33030
  return join18(cwd, ".claude", "settings.json");
@@ -32237,6 +33032,9 @@ function getProjectSettingsPath2(cwd) {
32237
33032
  function getLocalSettingsPath(cwd) {
32238
33033
  return join18(cwd, ".claude", "settings.local.json");
32239
33034
  }
33035
+ function settingsLayers(cwd, opts) {
33036
+ return cwd ? [getUserSettingsPath(opts), getProjectSettingsPath2(cwd), getLocalSettingsPath(cwd)] : [getUserSettingsPath(opts)];
33037
+ }
32240
33038
  function readJsonObject(filePath) {
32241
33039
  if (!existsSync17(filePath)) return {};
32242
33040
  try {
@@ -32246,6 +33044,44 @@ function readJsonObject(filePath) {
32246
33044
  return {};
32247
33045
  }
32248
33046
  }
33047
+ function writeSettingsJson(filePath, data) {
33048
+ mkdirSync9(dirname10(filePath), { recursive: true });
33049
+ writeFileSync8(filePath, JSON.stringify(data, null, 2) + "\n");
33050
+ }
33051
+ var init_claude_settings_files = __esm({
33052
+ "../../packages/runtime/src/fs/claude-settings-files.ts"() {
33053
+ "use strict";
33054
+ }
33055
+ });
33056
+
33057
+ // ../../packages/runtime/src/fs/plugins-manage.ts
33058
+ import { execFile as execFile3, execFileSync as execFileSync2 } from "node:child_process";
33059
+ import {
33060
+ cpSync,
33061
+ existsSync as existsSync18,
33062
+ mkdirSync as mkdirSync10,
33063
+ readdirSync as readdirSync6,
33064
+ readFileSync as readFileSync12,
33065
+ statSync as statSync5,
33066
+ writeFileSync as writeFileSync9
33067
+ } from "node:fs";
33068
+ import { join as join19, resolve as resolve9 } from "node:path";
33069
+ import { homedir as osHomedir8 } from "node:os";
33070
+ function homeOf6(opts) {
33071
+ return opts?.homeDir ?? osHomedir8();
33072
+ }
33073
+ function pluginsDir(opts) {
33074
+ return join19(homeOf6(opts), ".claude", "plugins");
33075
+ }
33076
+ function installedFile(opts) {
33077
+ return join19(pluginsDir(opts), "installed_plugins.json");
33078
+ }
33079
+ function marketplacesFile(opts) {
33080
+ return join19(pluginsDir(opts), "known_marketplaces.json");
33081
+ }
33082
+ function installCountsFile(opts) {
33083
+ return join19(pluginsDir(opts), "install-counts-cache.json");
33084
+ }
32249
33085
  function readExtraKnownMarketplaces(filePath) {
32250
33086
  const data = readJsonObject(filePath);
32251
33087
  const ek = data.extraKnownMarketplaces;
@@ -32267,12 +33103,8 @@ function getMarketplaceScopeMap(cwd, opts) {
32267
33103
  }
32268
33104
  return map2;
32269
33105
  }
32270
- function writeSettingsJson(filePath, data) {
32271
- mkdirSync9(dirname10(filePath), { recursive: true });
32272
- writeFileSync8(filePath, JSON.stringify(data, null, 2) + "\n");
32273
- }
32274
33106
  function removeMarketplaceFromSettings(filePath, name) {
32275
- if (!existsSync17(filePath)) return false;
33107
+ if (!existsSync18(filePath)) return false;
32276
33108
  const data = readJsonObject(filePath);
32277
33109
  const ek = data.extraKnownMarketplaces;
32278
33110
  if (!ek || typeof ek !== "object" || Array.isArray(ek)) return false;
@@ -32286,18 +33118,18 @@ function removeMarketplaceFromSettings(filePath, name) {
32286
33118
  return true;
32287
33119
  }
32288
33120
  function readMarketplaceManifestPlugins(mpDir) {
32289
- const manifest = readJson2(join18(mpDir, ".claude-plugin", "marketplace.json"));
33121
+ const manifest = readJson2(join19(mpDir, ".claude-plugin", "marketplace.json"));
32290
33122
  return Array.isArray(manifest?.plugins) ? manifest.plugins.filter((p3) => p3 && typeof p3.name === "string") : [];
32291
33123
  }
32292
33124
  function resolvePluginSourceDir(mpDir, name, source) {
32293
33125
  if (typeof source === "string" && source.trim()) {
32294
33126
  const rel = source.replace(/^\.\/?/, "");
32295
- const resolved = rel ? join18(mpDir, rel) : mpDir;
32296
- if (existsSync17(resolved)) return resolved;
33127
+ const resolved = rel ? join19(mpDir, rel) : mpDir;
33128
+ if (existsSync18(resolved)) return resolved;
32297
33129
  }
32298
33130
  for (const subDir of ["plugins", "external_plugins"]) {
32299
- const candidate = join18(mpDir, subDir, name);
32300
- if (existsSync17(candidate)) return candidate;
33131
+ const candidate = join19(mpDir, subDir, name);
33132
+ if (existsSync18(candidate)) return candidate;
32301
33133
  }
32302
33134
  return mpDir;
32303
33135
  }
@@ -32319,8 +33151,8 @@ function resolveMarketplaceScope(mpName, mpInfo, scopeMap) {
32319
33151
  }
32320
33152
  function readJson2(filePath) {
32321
33153
  try {
32322
- if (!existsSync17(filePath)) return null;
32323
- return JSON.parse(readFileSync11(filePath, "utf-8"));
33154
+ if (!existsSync18(filePath)) return null;
33155
+ return JSON.parse(readFileSync12(filePath, "utf-8"));
32324
33156
  } catch {
32325
33157
  return null;
32326
33158
  }
@@ -32328,16 +33160,16 @@ function readJson2(filePath) {
32328
33160
  function scanDir2(dirPath) {
32329
33161
  try {
32330
33162
  return readdirSync6(dirPath, { withFileTypes: true }).filter((e) => !e.name.startsWith(".")).sort((a, b3) => {
32331
- const aDir = a.isDirectory() || a.isSymbolicLink() && statSync5(join18(dirPath, a.name)).isDirectory();
32332
- const bDir = b3.isDirectory() || b3.isSymbolicLink() && statSync5(join18(dirPath, b3.name)).isDirectory();
33163
+ const aDir = a.isDirectory() || a.isSymbolicLink() && statSync5(join19(dirPath, a.name)).isDirectory();
33164
+ const bDir = b3.isDirectory() || b3.isSymbolicLink() && statSync5(join19(dirPath, b3.name)).isDirectory();
32333
33165
  if (aDir !== bDir) return aDir ? -1 : 1;
32334
33166
  return a.name.localeCompare(b3.name);
32335
33167
  }).map((e) => {
32336
- const isDir = e.isDirectory() || e.isSymbolicLink() && statSync5(join18(dirPath, e.name)).isDirectory();
33168
+ const isDir = e.isDirectory() || e.isSymbolicLink() && statSync5(join19(dirPath, e.name)).isDirectory();
32337
33169
  return {
32338
33170
  name: e.name,
32339
33171
  isDirectory: isDir,
32340
- ...isDir ? { children: scanDir2(join18(dirPath, e.name)) } : {}
33172
+ ...isDir ? { children: scanDir2(join19(dirPath, e.name)) } : {}
32341
33173
  };
32342
33174
  });
32343
33175
  } catch {
@@ -32345,25 +33177,25 @@ function scanDir2(dirPath) {
32345
33177
  }
32346
33178
  }
32347
33179
  function readPluginManifest(installPath) {
32348
- return readJson2(join18(installPath, ".claude-plugin", "plugin.json"));
33180
+ return readJson2(join19(installPath, ".claude-plugin", "plugin.json"));
32349
33181
  }
32350
33182
  function detectPluginContents(installPath) {
32351
33183
  const modules = readHooksJson(installPath)?.modules;
32352
33184
  return {
32353
- hasCommands: existsSync17(join18(installPath, "commands")),
32354
- hasAgents: existsSync17(join18(installPath, "agents")),
32355
- hasSkills: existsSync17(join18(installPath, "skills")),
32356
- hasHooks: existsSync17(join18(installPath, "hooks")),
33185
+ hasCommands: existsSync18(join19(installPath, "commands")),
33186
+ hasAgents: existsSync18(join19(installPath, "agents")),
33187
+ hasSkills: existsSync18(join19(installPath, "skills")),
33188
+ hasHooks: existsSync18(join19(installPath, "hooks")),
32357
33189
  hasMod: Array.isArray(modules) && modules.length > 0,
32358
- hasMcpServers: existsSync17(join18(installPath, ".mcp.json"))
33190
+ hasMcpServers: existsSync18(join19(installPath, ".mcp.json"))
32359
33191
  };
32360
33192
  }
32361
33193
  function readHooksJson(installPath) {
32362
- const candidates = [join18(installPath, "hooks", "hooks.json"), join18(installPath, "hooks.json")];
33194
+ const candidates = [join19(installPath, "hooks", "hooks.json"), join19(installPath, "hooks.json")];
32363
33195
  for (const p3 of candidates) {
32364
- if (!existsSync17(p3)) continue;
33196
+ if (!existsSync18(p3)) continue;
32365
33197
  try {
32366
- const raw = JSON.parse(readFileSync11(p3, "utf-8"));
33198
+ const raw = JSON.parse(readFileSync12(p3, "utf-8"));
32367
33199
  if (raw && typeof raw === "object" && !Array.isArray(raw)) return raw;
32368
33200
  } catch {
32369
33201
  }
@@ -32376,10 +33208,10 @@ function readHookEvents(installPath) {
32376
33208
  return events;
32377
33209
  }
32378
33210
  function readMcpServersMap(installPath) {
32379
- const mcpPath = join18(installPath, ".mcp.json");
32380
- if (!existsSync17(mcpPath)) return {};
33211
+ const mcpPath = join19(installPath, ".mcp.json");
33212
+ if (!existsSync18(mcpPath)) return {};
32381
33213
  try {
32382
- const raw = JSON.parse(readFileSync11(mcpPath, "utf-8"));
33214
+ const raw = JSON.parse(readFileSync12(mcpPath, "utf-8"));
32383
33215
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) return {};
32384
33216
  const root = raw;
32385
33217
  const wrapped = root.mcpServers;
@@ -32400,7 +33232,7 @@ function getMarketplaceLocations(opts) {
32400
33232
  const marketplaces = readJson2(marketplacesFile(opts));
32401
33233
  if (!marketplaces) return locations2;
32402
33234
  for (const [name, info] of Object.entries(marketplaces)) {
32403
- if (!info.installLocation || !existsSync17(join18(info.installLocation, ".git"))) continue;
33235
+ if (!info.installLocation || !existsSync18(join19(info.installLocation, ".git"))) continue;
32404
33236
  locations2.set(name, info.installLocation);
32405
33237
  }
32406
33238
  return locations2;
@@ -32419,13 +33251,13 @@ function getPluginLatestCommitSha(marketplaceDir, pluginName) {
32419
33251
  }
32420
33252
  }
32421
33253
  function getPluginNewVersion(mpDir, pluginName) {
32422
- const mpManifest = readJson2(join18(mpDir, ".claude-plugin", "marketplace.json"));
33254
+ const mpManifest = readJson2(join19(mpDir, ".claude-plugin", "marketplace.json"));
32423
33255
  const mpEntry = mpManifest?.plugins?.find((p3) => p3.name === pluginName);
32424
33256
  if (mpEntry?.version) return mpEntry.version;
32425
33257
  const sourceDir = findPluginSourceDir(mpDir, pluginName);
32426
33258
  if (sourceDir) {
32427
33259
  const pluginManifest = readJson2(
32428
- join18(sourceDir, ".claude-plugin", "plugin.json")
33260
+ join19(sourceDir, ".claude-plugin", "plugin.json")
32429
33261
  );
32430
33262
  if (pluginManifest?.version) return pluginManifest.version;
32431
33263
  }
@@ -32439,32 +33271,29 @@ function findPluginSourceDir(mpDir, pluginName) {
32439
33271
  const entry3 = readMarketplaceManifestPlugins(mpDir).find((p3) => p3.name === pluginName);
32440
33272
  if (entry3 && typeof entry3.source === "string" && entry3.source.trim()) {
32441
33273
  const rel = entry3.source.replace(/^\.\/?/, "");
32442
- const resolved = rel ? join18(mpDir, rel) : mpDir;
32443
- if (existsSync17(resolved)) return resolved;
33274
+ const resolved = rel ? join19(mpDir, rel) : mpDir;
33275
+ if (existsSync18(resolved)) return resolved;
32444
33276
  }
32445
33277
  for (const subDir of ["plugins", "external_plugins"]) {
32446
- const candidate = join18(mpDir, subDir, pluginName);
32447
- if (existsSync17(candidate)) return candidate;
33278
+ const candidate = join19(mpDir, subDir, pluginName);
33279
+ if (existsSync18(candidate)) return candidate;
32448
33280
  }
32449
33281
  return null;
32450
33282
  }
32451
- function enabledPluginsSources(cwd, opts) {
32452
- return cwd ? [getUserSettingsPath(opts), getProjectSettingsPath2(cwd), getLocalSettingsPath(cwd)] : [getUserSettingsPath(opts)];
32453
- }
32454
33283
  function enabledPluginsEntry(filePath, key) {
32455
33284
  const map2 = readJsonObject(filePath).enabledPlugins;
32456
33285
  return map2 && typeof map2 === "object" && !Array.isArray(map2) ? map2[key] : void 0;
32457
33286
  }
32458
33287
  function isPluginEnabled(cwd, key, defaultEnabled, opts) {
32459
33288
  let value;
32460
- for (const file2 of enabledPluginsSources(cwd, opts)) {
33289
+ for (const file2 of settingsLayers(cwd, opts)) {
32461
33290
  const entry3 = enabledPluginsEntry(file2, key);
32462
33291
  if (entry3 !== void 0) value = entry3;
32463
33292
  }
32464
33293
  return value === void 0 ? defaultEnabled !== false : value === true || Array.isArray(value);
32465
33294
  }
32466
33295
  function setPluginEnabled(cwd, key, scope, enabled, opts) {
32467
- const sources = enabledPluginsSources(cwd, opts);
33296
+ const sources = settingsLayers(cwd, opts);
32468
33297
  const deciding = [...sources].reverse().find((file2) => enabledPluginsEntry(file2, key) !== void 0);
32469
33298
  const target2 = deciding ?? (scope === "user" || !cwd ? getUserSettingsPath(opts) : getProjectSettingsPath2(cwd));
32470
33299
  const data = readJsonObject(target2);
@@ -32559,9 +33388,9 @@ function readPluginFile(cwd, pluginKey, relativePath, opts) {
32559
33388
  if (!isUser && !isProject) continue;
32560
33389
  const resolved = resolve9(entry3.installPath, relativePath);
32561
33390
  if (!isPathAtOrWithinAllowed(resolved, [entry3.installPath])) return null;
32562
- if (!existsSync17(resolved) || statSync5(resolved).isDirectory()) return null;
33391
+ if (!existsSync18(resolved) || statSync5(resolved).isDirectory()) return null;
32563
33392
  try {
32564
- return readFileSync11(resolved, "utf-8");
33393
+ return readFileSync12(resolved, "utf-8");
32565
33394
  } catch {
32566
33395
  return null;
32567
33396
  }
@@ -32578,7 +33407,7 @@ function deletePlugin(key, scope, cwd, opts) {
32578
33407
  if (data.plugins[key].length === 0) {
32579
33408
  delete data.plugins[key];
32580
33409
  }
32581
- writeFileSync8(installedFile(opts), JSON.stringify(data, null, 2), "utf-8");
33410
+ writeFileSync9(installedFile(opts), JSON.stringify(data, null, 2), "utf-8");
32582
33411
  }
32583
33412
  function listMarketplacePlugins(cwd, opts) {
32584
33413
  const marketplaces = readJson2(marketplacesFile(opts));
@@ -32610,7 +33439,7 @@ function listMarketplacePlugins(cwd, opts) {
32610
33439
  const plugins = [];
32611
33440
  for (const [mpName, mpInfo] of Object.entries(marketplaces)) {
32612
33441
  const mpDir = mpInfo.installLocation;
32613
- if (!mpDir || !existsSync17(mpDir)) continue;
33442
+ if (!mpDir || !existsSync18(mpDir)) continue;
32614
33443
  const marketplaceSource = marketplaceSourceLabel(mpInfo);
32615
33444
  const pushPlugin = (name, sourceDir, manifestEntry) => {
32616
33445
  const ownManifest = readPluginManifest(sourceDir);
@@ -32641,12 +33470,12 @@ function listMarketplacePlugins(cwd, opts) {
32641
33470
  continue;
32642
33471
  }
32643
33472
  for (const subDir of ["plugins", "external_plugins"]) {
32644
- const pluginsDirPath = join18(mpDir, subDir);
32645
- if (!existsSync17(pluginsDirPath)) continue;
33473
+ const pluginsDirPath = join19(mpDir, subDir);
33474
+ if (!existsSync18(pluginsDirPath)) continue;
32646
33475
  try {
32647
33476
  for (const entry3 of readdirSync6(pluginsDirPath, { withFileTypes: true })) {
32648
33477
  if (!entry3.isDirectory() && !entry3.isSymbolicLink()) continue;
32649
- const pluginDir = join18(pluginsDirPath, entry3.name);
33478
+ const pluginDir = join19(pluginsDirPath, entry3.name);
32650
33479
  if (!readPluginManifest(pluginDir)) continue;
32651
33480
  pushPlugin(entry3.name, pluginDir);
32652
33481
  }
@@ -32700,9 +33529,9 @@ function updatePlugin(key, scope, cwd, opts) {
32700
33529
  if (!sourceDir) return;
32701
33530
  const newVersion = getPluginNewVersion(mpDir, name);
32702
33531
  if (!newVersion) return;
32703
- const cacheDir = join18(pluginsDir(opts), "cache", marketplace, name, newVersion);
32704
- if (!existsSync17(cacheDir)) {
32705
- mkdirSync9(cacheDir, { recursive: true });
33532
+ const cacheDir = join19(pluginsDir(opts), "cache", marketplace, name, newVersion);
33533
+ if (!existsSync18(cacheDir)) {
33534
+ mkdirSync10(cacheDir, { recursive: true });
32706
33535
  cpSync(sourceDir, cacheDir, { recursive: true });
32707
33536
  }
32708
33537
  const latestSha = getPluginLatestCommitSha(mpDir, name);
@@ -32714,7 +33543,7 @@ function updatePlugin(key, scope, cwd, opts) {
32714
33543
  entry3.lastUpdated = (/* @__PURE__ */ new Date()).toISOString();
32715
33544
  if (latestSha) entry3.gitCommitSha = latestSha;
32716
33545
  }
32717
- writeFileSync8(installedFile(opts), JSON.stringify(data, null, 2), "utf-8");
33546
+ writeFileSync9(installedFile(opts), JSON.stringify(data, null, 2), "utf-8");
32718
33547
  }
32719
33548
  function addMarketplace(source, scope, cwd) {
32720
33549
  return new Promise((resolvePromise, reject) => {
@@ -32757,7 +33586,7 @@ function removeMarketplace(name, scope, cwd, opts) {
32757
33586
  function readMarketplacePluginContent(marketplace, name, opts) {
32758
33587
  const marketplaces = readJson2(marketplacesFile(opts));
32759
33588
  const mpInfo = marketplaces?.[marketplace];
32760
- if (!mpInfo?.installLocation || !existsSync17(mpInfo.installLocation)) return null;
33589
+ if (!mpInfo?.installLocation || !existsSync18(mpInfo.installLocation)) return null;
32761
33590
  const sourceDir = findPluginSourceDir(mpInfo.installLocation, name);
32762
33591
  if (!sourceDir) return null;
32763
33592
  const manifest = readPluginManifest(sourceDir);
@@ -32814,14 +33643,14 @@ function readMarketplacePluginContent(marketplace, name, opts) {
32814
33643
  function readMarketplacePluginFile(marketplace, name, relativePath, opts) {
32815
33644
  const marketplaces = readJson2(marketplacesFile(opts));
32816
33645
  const mpInfo = marketplaces?.[marketplace];
32817
- if (!mpInfo?.installLocation || !existsSync17(mpInfo.installLocation)) return null;
33646
+ if (!mpInfo?.installLocation || !existsSync18(mpInfo.installLocation)) return null;
32818
33647
  const sourceDir = findPluginSourceDir(mpInfo.installLocation, name);
32819
33648
  if (!sourceDir) return null;
32820
33649
  const resolved = resolve9(sourceDir, relativePath);
32821
33650
  if (!isPathAtOrWithinAllowed(resolved, [sourceDir])) return null;
32822
- if (!existsSync17(resolved) || statSync5(resolved).isDirectory()) return null;
33651
+ if (!existsSync18(resolved) || statSync5(resolved).isDirectory()) return null;
32823
33652
  try {
32824
- return readFileSync11(resolved, "utf-8");
33653
+ return readFileSync12(resolved, "utf-8");
32825
33654
  } catch {
32826
33655
  return null;
32827
33656
  }
@@ -32830,6 +33659,7 @@ var init_plugins_manage = __esm({
32830
33659
  "../../packages/runtime/src/fs/plugins-manage.ts"() {
32831
33660
  "use strict";
32832
33661
  init_path_security();
33662
+ init_claude_settings_files();
32833
33663
  }
32834
33664
  });
32835
33665
 
@@ -32840,38 +33670,20 @@ var init_plugin_review = __esm({
32840
33670
  }
32841
33671
  });
32842
33672
 
33673
+ // ../../packages/runtime/src/fs/mcp-tool-permissions-claude.ts
33674
+ var init_mcp_tool_permissions_claude = __esm({
33675
+ "../../packages/runtime/src/fs/mcp-tool-permissions-claude.ts"() {
33676
+ "use strict";
33677
+ init_tool_ui();
33678
+ init_claude_settings_files();
33679
+ }
33680
+ });
33681
+
32843
33682
  // ../../packages/runtime/src/fs/hooks-config.ts
32844
- import { existsSync as existsSync18, mkdirSync as mkdirSync10, readFileSync as readFileSync12, writeFileSync as writeFileSync9 } from "node:fs";
32845
- import { dirname as dirname11, join as join19 } from "node:path";
32846
- import { homedir as osHomedir8 } from "node:os";
32847
- function homeOf7(opts) {
32848
- return opts?.homeDir ?? osHomedir8();
32849
- }
32850
- function getUserSettingsPath2(opts) {
32851
- return join19(homeOf7(opts), ".claude", "settings.json");
32852
- }
32853
- function getProjectSettingsPath3(cwd) {
32854
- return join19(cwd, ".claude", "settings.json");
32855
- }
32856
- function getLocalSettingsPath2(cwd) {
32857
- return join19(cwd, ".claude", "settings.local.json");
32858
- }
32859
33683
  function pathFor(scope, cwd, opts) {
32860
- if (scope === "user") return getUserSettingsPath2(opts);
32861
- if (scope === "project") return getProjectSettingsPath3(cwd);
32862
- return getLocalSettingsPath2(cwd);
32863
- }
32864
- function readJsonFile2(filePath) {
32865
- if (!existsSync18(filePath)) return {};
32866
- try {
32867
- return JSON.parse(readFileSync12(filePath, "utf-8"));
32868
- } catch {
32869
- return {};
32870
- }
32871
- }
32872
- function writeJsonFile2(filePath, data) {
32873
- mkdirSync10(dirname11(filePath), { recursive: true });
32874
- writeFileSync9(filePath, JSON.stringify(data, null, 2));
33684
+ if (scope === "user") return getUserSettingsPath(opts);
33685
+ if (scope === "project") return getProjectSettingsPath2(cwd);
33686
+ return getLocalSettingsPath(cwd);
32875
33687
  }
32876
33688
  function getHooksMap(data) {
32877
33689
  const h = data.hooks;
@@ -32895,7 +33707,7 @@ function listHooks(cwd, opts) {
32895
33707
  const result3 = [];
32896
33708
  const scopes = ["user", "project", "local"];
32897
33709
  for (const scope of scopes) {
32898
- const data = readJsonFile2(pathFor(scope, cwd, opts));
33710
+ const data = readJsonObject(pathFor(scope, cwd, opts));
32899
33711
  const hooks = getHooksMap(data);
32900
33712
  for (const event of Object.keys(hooks)) {
32901
33713
  const groups = hooks[event] ?? [];
@@ -32920,7 +33732,7 @@ function saveHook(cwd, payload, replaceId, opts) {
32920
33732
  deleteHook(cwd, replaceId, opts);
32921
33733
  }
32922
33734
  const filePath = pathFor(payload.scope, cwd, opts);
32923
- const data = readJsonFile2(filePath);
33735
+ const data = readJsonObject(filePath);
32924
33736
  if (!data.hooks || typeof data.hooks !== "object" || Array.isArray(data.hooks)) {
32925
33737
  data.hooks = {};
32926
33738
  }
@@ -32937,14 +33749,14 @@ function saveHook(cwd, payload, replaceId, opts) {
32937
33749
  }
32938
33750
  if (!Array.isArray(group.hooks)) group.hooks = [];
32939
33751
  group.hooks.push(payload.entry);
32940
- writeJsonFile2(filePath, data);
33752
+ writeSettingsJson(filePath, data);
32941
33753
  }
32942
33754
  function deleteHook(cwd, id, opts) {
32943
33755
  const parsed = parseId(id);
32944
33756
  if (!parsed) return;
32945
33757
  const { scope, event, gIdx, eIdx } = parsed;
32946
33758
  const filePath = pathFor(scope, cwd, opts);
32947
- const data = readJsonFile2(filePath);
33759
+ const data = readJsonObject(filePath);
32948
33760
  const hooks = getHooksMap(data);
32949
33761
  const groups = hooks[event];
32950
33762
  if (!Array.isArray(groups) || !groups[gIdx]) return;
@@ -32958,11 +33770,12 @@ function deleteHook(cwd, id, opts) {
32958
33770
  } else {
32959
33771
  data.hooks = hooks;
32960
33772
  }
32961
- writeJsonFile2(filePath, data);
33773
+ writeSettingsJson(filePath, data);
32962
33774
  }
32963
33775
  var init_hooks_config = __esm({
32964
33776
  "../../packages/runtime/src/fs/hooks-config.ts"() {
32965
33777
  "use strict";
33778
+ init_claude_settings_files();
32966
33779
  }
32967
33780
  });
32968
33781
 
@@ -32979,6 +33792,7 @@ var init_fs = __esm({
32979
33792
  init_fuzzy();
32980
33793
  init_plugins_manage();
32981
33794
  init_plugin_review();
33795
+ init_mcp_tool_permissions_claude();
32982
33796
  init_hooks_config();
32983
33797
  init_agents_discover();
32984
33798
  }
@@ -33437,7 +34251,7 @@ function codexKeychainAccount(home) {
33437
34251
  }
33438
34252
  return `cli|${createHash7("sha256").update(canonical).digest("hex").slice(0, 16)}`;
33439
34253
  }
33440
- function readLogin(home) {
34254
+ function readCodexLogin(home = codexHome()) {
33441
34255
  const file2 = join25(home, "auth.json");
33442
34256
  if (existsSync23(file2)) {
33443
34257
  const login = loginFrom(readFileSync17(file2, "utf8"));
@@ -33478,7 +34292,7 @@ function parseCodexUsage(body, nowSeconds = Math.floor(Date.now() / 1e3)) {
33478
34292
  }
33479
34293
  async function readCodexRateLimits(opts = {}) {
33480
34294
  const home = opts.home ?? codexHome();
33481
- const login = readLogin(home);
34295
+ const login = readCodexLogin(home);
33482
34296
  if (!login) return { value: null };
33483
34297
  const fingerprint = createHash7("sha256").update(login.accessToken).digest("hex");
33484
34298
  return throttle2.read(home, fingerprint, opts.force === true, async () => {
@@ -33557,7 +34371,7 @@ function keychainToken() {
33557
34371
  return null;
33558
34372
  }
33559
34373
  }
33560
- function readLogin2(open2, statePath) {
34374
+ function readLogin(open2, statePath) {
33561
34375
  if (process.platform !== "darwin") return null;
33562
34376
  const fromApp = existsSync24(statePath) ? stateValue(open2, statePath, "cursorAuth/accessToken") : null;
33563
34377
  const accessToken = fromApp ?? keychainToken();
@@ -33592,7 +34406,7 @@ function parseCursorUsage(body, membership) {
33592
34406
  }
33593
34407
  async function readCursorRateLimits(open2, opts = {}) {
33594
34408
  const statePath = opts.statePath ?? cursorStateDbPath();
33595
- const login = readLogin2(open2, statePath);
34409
+ const login = readLogin(open2, statePath);
33596
34410
  if (!login) return { value: null };
33597
34411
  const expiresAt = jwtExpiresAtMs(login.accessToken);
33598
34412
  if (expiresAt !== null && expiresAt <= Date.now()) return { value: null, error: "Cursor login expired. Open Cursor or run `cursor-agent login`." };
@@ -36149,6 +36963,20 @@ var init_codex_usage_cache = __esm({
36149
36963
  }
36150
36964
  });
36151
36965
 
36966
+ // ../../packages/codex/src/plugin-target.ts
36967
+ function buildCodexPluginRequestParams(plugin) {
36968
+ if (plugin.marketplacePath) {
36969
+ return { marketplacePath: plugin.marketplacePath, pluginName: plugin.name };
36970
+ }
36971
+ if (!plugin.remotePluginId) throw new Error(`Missing remote ID for Codex plugin: ${plugin.name}`);
36972
+ return { remoteMarketplaceName: plugin.marketplace, pluginName: plugin.remotePluginId };
36973
+ }
36974
+ var init_plugin_target = __esm({
36975
+ "../../packages/codex/src/plugin-target.ts"() {
36976
+ "use strict";
36977
+ }
36978
+ });
36979
+
36152
36980
  // ../../packages/codex/src/codex-admin.ts
36153
36981
  import { randomUUID as randomUUID9 } from "node:crypto";
36154
36982
  function normalizeApiKey(value) {
@@ -36476,7 +37304,7 @@ async function listPluginInventory(client3, projectPath) {
36476
37304
  if (!marketplace) continue;
36477
37305
  const marketplaceName = readString5(marketplace.name);
36478
37306
  const marketplacePath = readString5(marketplace.path);
36479
- if (!marketplaceName || !marketplacePath) continue;
37307
+ if (!marketplaceName) continue;
36480
37308
  const plugins = Array.isArray(marketplace.plugins) ? marketplace.plugins : [];
36481
37309
  for (const rawPlugin of plugins) {
36482
37310
  const plugin = asRecord10(rawPlugin);
@@ -36491,6 +37319,7 @@ async function listPluginInventory(client3, projectPath) {
36491
37319
  name,
36492
37320
  marketplace: marketplaceName,
36493
37321
  marketplacePath,
37322
+ remotePluginId: readString5(plugin.remotePluginId) ?? void 0,
36494
37323
  sourcePath,
36495
37324
  installed: readBoolean2(plugin.installed) ?? false,
36496
37325
  enabled: readBoolean2(plugin.enabled) ?? false
@@ -36499,8 +37328,8 @@ async function listPluginInventory(client3, projectPath) {
36499
37328
  }
36500
37329
  return records2;
36501
37330
  }
36502
- async function installPlugin2(client3, marketplacePath, pluginName) {
36503
- await client3.request("plugin/install", { marketplacePath, pluginName });
37331
+ async function installPlugin2(client3, plugin) {
37332
+ await client3.request("plugin/install", buildCodexPluginRequestParams(plugin));
36504
37333
  }
36505
37334
  async function uninstallPlugin(client3, pluginId) {
36506
37335
  await client3.request("plugin/uninstall", { pluginId });
@@ -36558,6 +37387,7 @@ var init_codex_admin = __esm({
36558
37387
  init_app_server_client();
36559
37388
  init_subscription_usage3();
36560
37389
  init_codex_usage_cache();
37390
+ init_plugin_target();
36561
37391
  rateLimitThrottle = new UsageThrottle(USAGE_POLL_MS);
36562
37392
  accountUsageThrottle = new UsageThrottle(USAGE_POLL_MS);
36563
37393
  }
@@ -45851,7 +46681,7 @@ var init_managed_official = __esm({
45851
46681
  "../../packages/runtime/src/harness/managed-official.ts"() {
45852
46682
  "use strict";
45853
46683
  init_managed_layout();
45854
- OFFICIAL_CLAUDE_SDK_VERSION = "0.3.300";
46684
+ OFFICIAL_CLAUDE_SDK_VERSION = "0.3.302";
45855
46685
  OFFICIAL_CODEX_NPM_VERSION = "0.163.0";
45856
46686
  OFFICIAL_CODEX_PACKAGE = "@openai/codex";
45857
46687
  }
@@ -88903,7 +89733,7 @@ var init_codex_admin_service = __esm({
88903
89733
  const records2 = await listPluginInventory(client3, path);
88904
89734
  const record12 = records2.find((r) => r.key === key);
88905
89735
  if (!record12) throw new Error(`Unknown Codex plugin: ${key}`);
88906
- await installPlugin2(client3, record12.marketplacePath, record12.name);
89736
+ await installPlugin2(client3, record12);
88907
89737
  });
88908
89738
  }
88909
89739
  async uninstallPlugin(projectId, key, apiProviderId) {