replicas-cli 0.2.726 → 0.2.728

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/README.md +1 -1
  2. package/dist/index.cjs +18 -205
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -45,7 +45,7 @@ Connect to a workspace via SSH.
45
45
  Open a workspace in VS Code via Remote SSH. Omit the argument to pick a workspace with the arrow keys and Enter, or pass a name or ID. Names with spaces work with or without quotes.
46
46
 
47
47
  ### Coding agents
48
- Use `replicas claude-auth` or `replicas codex-auth` to connect subscription credentials. Gemini CLI and Cursor use API keys configured in Coding Agents settings.
48
+ Use `replicas claude-auth` or `replicas codex-auth` to connect subscription credentials. Cursor uses API keys configured in Coding Agents settings.
49
49
 
50
50
  ## Configuration
51
51
 
package/dist/index.cjs CHANGED
@@ -7701,9 +7701,7 @@ var AGENT = {
7701
7701
  CLAUDE: "claude",
7702
7702
  CODEX: "codex",
7703
7703
  CURSOR: "cursor",
7704
- DEEPSEEK: "deepseek",
7705
7704
  FX: "fx",
7706
- GEMINI: "gemini",
7707
7705
  KIMI: "kimi",
7708
7706
  MUSE: "muse",
7709
7707
  OPENCODE: "opencode",
@@ -7715,7 +7713,6 @@ var VALID_RELAY_SUBAGENT_PROVIDERS = VALID_AGENT_PROVIDERS;
7715
7713
  var VALID_RELAY_BASE_PROVIDERS = [
7716
7714
  AGENT.CLAUDE,
7717
7715
  AGENT.CODEX,
7718
- AGENT.DEEPSEEK,
7719
7716
  AGENT.OPENCODE,
7720
7717
  AGENT.PI
7721
7718
  ];
@@ -7748,21 +7745,11 @@ var AGENT_PROVIDER_OPTIONS = [
7748
7745
  label: "Cursor",
7749
7746
  description: "Use Cursor for tasks"
7750
7747
  },
7751
- {
7752
- value: "deepseek",
7753
- label: "DeepSeek Harness",
7754
- description: "Use DeepSeek Harness for tasks"
7755
- },
7756
7748
  {
7757
7749
  value: "fx",
7758
7750
  label: "fx",
7759
7751
  description: "Use fx for tasks"
7760
7752
  },
7761
- {
7762
- value: "gemini",
7763
- label: "Gemini CLI",
7764
- description: "Use Gemini CLI for tasks"
7765
- },
7766
7753
  {
7767
7754
  value: "kimi",
7768
7755
  label: "Kimi Code",
@@ -7795,9 +7782,7 @@ var THINKING_LEVELS_BY_AGENT = {
7795
7782
  claude: [...STANDARD_THINKING_LEVELS, "ultracode"],
7796
7783
  codex: [...STANDARD_THINKING_LEVELS, "ultra"],
7797
7784
  cursor: STANDARD_THINKING_LEVELS,
7798
- deepseek: STANDARD_THINKING_LEVELS,
7799
7785
  fx: STANDARD_THINKING_LEVELS,
7800
- gemini: STANDARD_THINKING_LEVELS,
7801
7786
  kimi: STANDARD_THINKING_LEVELS,
7802
7787
  muse: VALID_THINKING_LEVELS.filter((level) => level !== "max" && level !== "ultracode"),
7803
7788
  opencode: STANDARD_THINKING_LEVELS,
@@ -7819,12 +7804,8 @@ function getProviderDisplayName(provider, variant = "short") {
7819
7804
  return "Codex";
7820
7805
  case "cursor":
7821
7806
  return "Cursor";
7822
- case "deepseek":
7823
- return variant === "long" ? "DeepSeek Harness" : "DeepSeek";
7824
7807
  case "fx":
7825
7808
  return "fx";
7826
- case "gemini":
7827
- return "Gemini";
7828
7809
  case "kimi":
7829
7810
  return variant === "long" ? "Kimi Code" : "Kimi";
7830
7811
  case "muse":
@@ -7880,7 +7861,6 @@ var CREDENTIAL_TYPE = {
7880
7861
  ASTER_API_KEY: "aster_api_key",
7881
7862
  OPENROUTER_API_KEY: "openrouter_api_key",
7882
7863
  AI_GATEWAY_API_KEY: "ai_gateway_api_key",
7883
- GEMINI_API_KEY: "gemini_api_key",
7884
7864
  MUSE_OAUTH: "muse_oauth",
7885
7865
  MUSE_API_KEY: "muse_api_key"
7886
7866
  };
@@ -7908,16 +7888,9 @@ var AGENT_CREDENTIAL_METHODS_IN_ORDER = {
7908
7888
  [AGENT.CURSOR]: [
7909
7889
  { method: CREDENTIAL_METHOD.API_KEY, credentialType: CREDENTIAL_TYPE.CURSOR_API_KEY }
7910
7890
  ],
7911
- [AGENT.DEEPSEEK]: [
7912
- { method: CREDENTIAL_METHOD.OPENROUTER, credentialType: CREDENTIAL_TYPE.OPENROUTER_API_KEY },
7913
- { method: CREDENTIAL_METHOD.OLLAMA, credentialType: CREDENTIAL_TYPE.OLLAMA }
7914
- ],
7915
7891
  [AGENT.FX]: [
7916
7892
  { method: CREDENTIAL_METHOD.AI_GATEWAY, credentialType: CREDENTIAL_TYPE.AI_GATEWAY_API_KEY }
7917
7893
  ],
7918
- [AGENT.GEMINI]: [
7919
- { method: CREDENTIAL_METHOD.API_KEY, credentialType: CREDENTIAL_TYPE.GEMINI_API_KEY }
7920
- ],
7921
7894
  [AGENT.KIMI]: [
7922
7895
  { method: CREDENTIAL_METHOD.AI_GATEWAY, credentialType: CREDENTIAL_TYPE.AI_GATEWAY_API_KEY },
7923
7896
  { method: CREDENTIAL_METHOD.OLLAMA, credentialType: CREDENTIAL_TYPE.OLLAMA }
@@ -22645,7 +22618,6 @@ var OX_ALPHA_MODEL = "stealth/ox-alpha";
22645
22618
  var DEEPSEEK_V4_PRO_MODEL = "deepseek/deepseek-v4-pro-0813";
22646
22619
  var DEEPSEEK_V4_FLASH_MODEL = "deepseek/deepseek-v4-flash-0731";
22647
22620
  var DEFAULT_FX_MODEL = "zai/glm-5.2";
22648
- var DEFAULT_GEMINI_MODEL = "gemini-3.8-flash";
22649
22621
  var DEFAULT_KIMI_MODEL = "moonshotai/kimi-k2.6";
22650
22622
  var MUSE_SPARK_1_3_MODEL = "muse-spark-1.3";
22651
22623
  var DEFAULT_MUSE_MODEL = "muse-spark-1.2";
@@ -22666,12 +22638,6 @@ var OPENROUTER_MODELS = [
22666
22638
  "xiaomi/mimo-v2.5-pro",
22667
22639
  "meta/muse-spark-1.3"
22668
22640
  ];
22669
- function prioritizeDeepseekModels(models) {
22670
- return [
22671
- ...models.filter((model) => model.startsWith("deepseek/")),
22672
- ...models.filter((model) => !model.startsWith("deepseek/"))
22673
- ];
22674
- }
22675
22641
  function normalizeClaudeModel(model) {
22676
22642
  if (model === "opus" || model === CLAUDE_OPUS_1M_MODEL || model === LEGACY_CLAUDE_OPUS_1M_MODEL) {
22677
22643
  return DEFAULT_CLAUDE_MODEL;
@@ -22751,9 +22717,7 @@ var AGENT_MODELS = {
22751
22717
  CLAUDE_HAIKU_4_5_MODEL,
22752
22718
  "kimi-k2.5"
22753
22719
  ],
22754
- deepseek: prioritizeDeepseekModels(DEFAULT_OPENROUTER_MODELS),
22755
22720
  fx: [DEFAULT_FX_MODEL],
22756
- gemini: [DEFAULT_GEMINI_MODEL, "gemini-3.1-pro-preview"],
22757
22721
  kimi: [DEFAULT_KIMI_MODEL],
22758
22722
  muse: [MUSE_SPARK_1_3_MODEL, DEFAULT_MUSE_MODEL],
22759
22723
  opencode: [...DEFAULT_OPENROUTER_MODELS, ...ASTER_MODELS],
@@ -22811,8 +22775,6 @@ var MODEL_LABELS = {
22811
22775
  "xiaomi/mimo-v2.5-pro": "MiMo V2.5 Pro via OpenRouter",
22812
22776
  "moonshotai/kimi-k2.6": "Kimi K2.6 via OpenRouter",
22813
22777
  "moonshotai/kimi-k3": "Kimi K3 via OpenRouter",
22814
- "gemini-3-flash-preview": "Gemini 3 Flash Preview",
22815
- "gemini-3.1-pro-preview": "Gemini 3.1 Pro Preview",
22816
22778
  [MUSE_SPARK_1_3_MODEL]: "Muse Spark 1.3",
22817
22779
  [DEFAULT_MUSE_MODEL]: "Muse Spark 1.2",
22818
22780
  "meta/muse-spark-1.3": "Muse Spark 1.3 via OpenRouter",
@@ -24051,6 +24013,8 @@ replicas media upload screenshot.png --name "Login page" --access public
24051
24013
 
24052
24014
  \`--share\` remains an alias for \`--access public\`. Public access prints the raw \`Forge embed\` Markdown instead of the authenticated chat-only embed for image, video, or audio media, backed by an opt-in bearer URL. Anyone with that unguessable URL can view the asset until it is rotated or revoked. HTML pages only support organization access. Use \`replicas media share <media-id>\` to rotate a public media URL and \`replicas media revoke <media-id>\` to revoke it.
24053
24015
 
24016
+ Permanently delete an upload with \`replicas media delete <media-id>\`. The backend only permits deletion when the media belongs to the current workspace; media from another workspace returns not found.
24017
+
24054
24018
  ## The URLs the CLI gives you \u2014 and where each one is allowed
24055
24019
 
24056
24020
  | URL | What it is | Where it's allowed |
@@ -24712,7 +24676,7 @@ In agent mode the CLI hides commands that don't make sense for in-workspace agen
24712
24676
  | \`replicas automation ...\` | Manage automations (cron + GitHub/GitLab event triggers) |
24713
24677
  | \`replicas preview ...\` | Register / list preview URLs (covered in \`PREVIEWS.md\`) |
24714
24678
  | \`replicas service ...\` | Run long-lived services detached so they survive workspace sleep/wake (see below) |
24715
- | \`replicas media ...\` | Upload media to the dashboard and follow \`MEDIA.md\` for destination embedding |
24679
+ | \`replicas media ...\` | Upload, list, share, revoke, or delete workspace media; follow \`MEDIA.md\` for destination embedding |
24716
24680
  | \`replicas slack thread ...\` | Attach or switch Slack thread routing (covered in \`SLACK.md\`) |
24717
24681
 
24718
24682
  \`replicas <command> --help\` is always the source of truth for flags.
@@ -25817,165 +25781,6 @@ function parseCursorEvents(events) {
25817
25781
  return messages;
25818
25782
  }
25819
25783
 
25820
- // ../shared/src/display-message/parsers/deepseek-parser.ts
25821
- function parseArguments(value) {
25822
- if (typeof value !== "string") return void 0;
25823
- const parsed = safeJsonParse(value, value);
25824
- return isRecord(parsed) ? parsed : stringifyDisplayValue(parsed);
25825
- }
25826
- function getDeepseekAssistantMessageText(event, blockType) {
25827
- if (!isRecord(event) || event.type !== "assistant/message" || !isRecord(event.data) || !isRecord(event.data.message) || !Array.isArray(event.data.message.content)) return "";
25828
- return event.data.message.content.flatMap((block) => isRecord(block) && block.type === blockType && typeof block.text === "string" ? [block.text] : []).join("");
25829
- }
25830
- function parseDeepseekEvents(events) {
25831
- const messages = [];
25832
- for (const source of events) {
25833
- if (source.type === "event_msg" && source.payload.type === "user_message") {
25834
- if (typeof source.payload.message === "string" && source.payload.message.trim()) {
25835
- const messageId = source.payload[USER_MESSAGE_ID_PAYLOAD_KEY];
25836
- messages.push({
25837
- id: typeof messageId === "string" ? messageId : `deepseek-user-${source.timestamp}`,
25838
- type: "user",
25839
- content: source.payload.message,
25840
- timestamp: source.timestamp
25841
- });
25842
- }
25843
- continue;
25844
- }
25845
- if (source.type === "deepseek-error") {
25846
- messages.push({
25847
- id: `deepseek-error-${source.timestamp}`,
25848
- type: "error",
25849
- message: typeof source.payload.message === "string" ? source.payload.message : "DeepSeek Harness failed",
25850
- timestamp: source.timestamp
25851
- });
25852
- continue;
25853
- }
25854
- if (source.type === "deepseek-input-request") {
25855
- const requestId = typeof source.payload.requestId === "string" ? source.payload.requestId : `deepseek-input-${source.timestamp}`;
25856
- if (source.payload.kind === "approval") {
25857
- upsertDisplayMessage(messages, createCallDisplayMessage({
25858
- id: requestId,
25859
- server: "deepseek",
25860
- tool: typeof source.payload.toolName === "string" ? source.payload.toolName : "approval",
25861
- input: typeof source.payload.reason === "string" ? source.payload.reason : void 0,
25862
- status: "in_progress",
25863
- timestamp: source.timestamp,
25864
- inputRequest: {
25865
- requestId,
25866
- status: "pending",
25867
- options: [
25868
- { id: "deny", label: "Deny", variant: "secondary" },
25869
- { id: "allow", label: "Allow once", variant: "primary" }
25870
- ]
25871
- }
25872
- }));
25873
- } else {
25874
- const questions = Array.isArray(source.payload.questions) ? source.payload.questions : [];
25875
- upsertDisplayMessage(messages, createCallDisplayMessage({
25876
- id: requestId,
25877
- server: "deepseek",
25878
- tool: "ask_user",
25879
- status: "in_progress",
25880
- timestamp: source.timestamp,
25881
- inputRequest: {
25882
- requestId,
25883
- status: "pending",
25884
- questions: questions.flatMap((question) => {
25885
- if (!isRecord(question) || typeof question.id !== "string" || typeof question.question !== "string") return [];
25886
- const options = Array.isArray(question.options) ? question.options : [];
25887
- return [{
25888
- id: question.id,
25889
- prompt: question.question,
25890
- multiSelect: question.multiSelect === true,
25891
- options: options.flatMap((option) => isRecord(option) && typeof option.label === "string" ? [{ id: `${question.id}:${option.label}`, label: option.label, ...typeof option.description === "string" ? { description: option.description } : {} }] : [])
25892
- }];
25893
- })
25894
- }
25895
- }));
25896
- }
25897
- continue;
25898
- }
25899
- if (source.type === "deepseek-input-resolved") {
25900
- const requestId = typeof source.payload.requestId === "string" ? source.payload.requestId : "";
25901
- const existing = messages.find((message) => message.type === "tool_call" && message.inputRequest?.requestId === requestId);
25902
- if (existing?.type === "tool_call" && existing.inputRequest) {
25903
- existing.inputRequest.status = source.payload.status === "aborted" ? "aborted" : "resolved";
25904
- existing.status = source.payload.status === "aborted" ? "failed" : "completed";
25905
- }
25906
- continue;
25907
- }
25908
- if (source.type === "deepseek-jobs" && Array.isArray(source.payload.jobs)) {
25909
- for (const job of source.payload.jobs) {
25910
- if (!isRecord(job) || typeof job.id !== "string") continue;
25911
- const existing = messages.find((message) => message.type === "background_task" && message.taskId === job.id);
25912
- const status = normalizeBackgroundTaskStatus(job.status);
25913
- const next = {
25914
- id: existing?.id ?? `deepseek-job-${job.id}`,
25915
- type: "background_task",
25916
- taskId: job.id,
25917
- status,
25918
- description: typeof job.label === "string" ? job.label : void 0,
25919
- taskType: typeof job.kind === "string" ? job.kind : void 0,
25920
- error: status === "failed" && typeof job.detail === "string" ? job.detail : void 0,
25921
- timestamp: existing?.timestamp ?? source.timestamp
25922
- };
25923
- if (existing?.type === "background_task") Object.assign(existing, next);
25924
- else messages.push(next);
25925
- }
25926
- continue;
25927
- }
25928
- if (source.type !== "deepseek-session-event" || !isRecord(source.payload.event)) continue;
25929
- const event = source.payload.event;
25930
- const data = isRecord(event.data) ? event.data : {};
25931
- const seq = typeof event.seq === "number" ? event.seq : source.timestamp;
25932
- if (event.type === "assistant/message") {
25933
- const content = getDeepseekAssistantMessageText(event, "text");
25934
- const reasoning = getDeepseekAssistantMessageText(event, "reasoning");
25935
- if (reasoning.trim()) messages.push({ id: `deepseek-reasoning-${seq}`, type: "reasoning", content: reasoning, status: "completed", timestamp: source.timestamp });
25936
- if (content.trim()) messages.push({ id: `deepseek-assistant-${seq}`, type: "agent", content, timestamp: source.timestamp });
25937
- continue;
25938
- }
25939
- if (event.type === "tool/call") {
25940
- const callId = typeof data.callId === "string" ? data.callId : String(seq);
25941
- upsertDisplayMessage(messages, createCallDisplayMessage({
25942
- id: `deepseek-tool-${callId}`,
25943
- server: "deepseek",
25944
- tool: typeof data.name === "string" ? data.name : "tool",
25945
- input: parseArguments(data.arguments),
25946
- status: "in_progress",
25947
- timestamp: source.timestamp
25948
- }));
25949
- continue;
25950
- }
25951
- if (event.type === "tool/result") {
25952
- const message = isRecord(data.message) ? data.message : {};
25953
- const messageSource = isRecord(message.source) ? message.source : {};
25954
- const result = Array.isArray(message.content) && isRecord(message.content[0]) ? message.content[0] : {};
25955
- const callId = typeof messageSource.callId === "string" ? messageSource.callId : typeof data.callId === "string" ? data.callId : String(seq);
25956
- const existing = messages.find((message2) => message2.id === `deepseek-tool-${callId}` && message2.type === "tool_call");
25957
- if (existing?.type === "tool_call") {
25958
- existing.output = stringifyDisplayValue(result.content ?? data.result);
25959
- existing.status = result.isError === true || data.isError === true ? "failed" : "completed";
25960
- }
25961
- continue;
25962
- }
25963
- if (event.type === "todo/write" && Array.isArray(data.items)) {
25964
- messages.push({
25965
- id: `deepseek-todo-${seq}`,
25966
- type: "todo_list",
25967
- items: data.items.flatMap((item) => {
25968
- if (!isRecord(item) || typeof item.content !== "string") return [];
25969
- const itemStatus = item.status === "in_progress" || item.status === "completed" ? item.status : "pending";
25970
- return [{ text: item.content, completed: itemStatus === "completed", itemStatus }];
25971
- }),
25972
- timestamp: source.timestamp
25973
- });
25974
- }
25975
- }
25976
- return messages;
25977
- }
25978
-
25979
25784
  // ../shared/src/display-message/parsers/acp-parser.ts
25980
25785
  var FX_CONTEXT_DIAGNOSTIC = /^\[context\] skill catalog omitted .*?(?:\r?\n|$)/;
25981
25786
  function getAcpTextChunk(update, kind) {
@@ -27170,18 +26975,12 @@ function parseAgentEvents(events, agentType) {
27170
26975
  if (agentType === "cursor") {
27171
26976
  return parseCursorEvents(events);
27172
26977
  }
27173
- if (agentType === "deepseek") {
27174
- return parseDeepseekEvents(events);
27175
- }
27176
26978
  if (agentType === "fx") {
27177
26979
  return parseFxEvents(events);
27178
26980
  }
27179
26981
  if (agentType === "kimi") {
27180
26982
  return parseAcpEvents(events, "kimi");
27181
26983
  }
27182
- if (agentType === "gemini") {
27183
- return parseAcpEvents(events, "gemini");
27184
- }
27185
26984
  if (agentType === "muse") {
27186
26985
  return parseMuseEvents(events);
27187
26986
  }
@@ -27455,7 +27254,7 @@ var headlessFilesystemAgentResultSchema = external_exports.object({
27455
27254
  });
27456
27255
 
27457
27256
  // ../shared/src/cli-version.ts
27458
- var CLI_VERSION = "0.2.726";
27257
+ var CLI_VERSION = "0.2.728";
27459
27258
 
27460
27259
  // ../shared/src/version.ts
27461
27260
  function compareVersions(v1, v2) {
@@ -31594,6 +31393,10 @@ async function mediaRevokeCommand(mediaId) {
31594
31393
  await agentFetch(`/v1/engine/media/${mediaId}/share`, { method: "DELETE" });
31595
31394
  console.log(`Revoked public share for ${mediaId}`);
31596
31395
  }
31396
+ async function mediaDeleteCommand(mediaId) {
31397
+ await agentFetch(`/v1/engine/media/${mediaId}`, { method: "DELETE" });
31398
+ console.log(`Deleted media ${mediaId}`);
31399
+ }
31597
31400
  async function mediaListCommand(options) {
31598
31401
  const qs = new URLSearchParams();
31599
31402
  if (options.kind) qs.set("kind", options.kind);
@@ -33203,6 +33006,16 @@ if (isAgentMode()) {
33203
33006
  } catch (error51) {
33204
33007
  if (error51 instanceof Error) console.error(import_chalk24.default.red(`
33205
33008
  \u2717 ${error51.message}
33009
+ `));
33010
+ process.exit(1);
33011
+ }
33012
+ });
33013
+ media.command("delete <mediaId>").description("Permanently delete media uploaded by this workspace").action(async (mediaId) => {
33014
+ try {
33015
+ await mediaDeleteCommand(mediaId);
33016
+ } catch (error51) {
33017
+ if (error51 instanceof Error) console.error(import_chalk24.default.red(`
33018
+ \u2717 ${error51.message}
33206
33019
  `));
33207
33020
  process.exit(1);
33208
33021
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-cli",
3
- "version": "0.2.726",
3
+ "version": "0.2.728",
4
4
  "description": "CLI for managing Replicas workspaces - SSH into cloud dev environments with automatic port forwarding",
5
5
  "main": "dist/index.cjs",
6
6
  "bin": {