replicas-mcp 0.2.12 → 0.2.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +647 -133
- package/package.json +1 -1
- package/src/index.ts +1 -1
package/dist/index.js
CHANGED
|
@@ -3,13 +3,16 @@
|
|
|
3
3
|
// src/index.ts
|
|
4
4
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
5
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
6
|
-
import { z as
|
|
6
|
+
import { z as z3 } from "zod";
|
|
7
7
|
|
|
8
8
|
// ../shared/src/agent.ts
|
|
9
9
|
var AGENT = {
|
|
10
10
|
CLAUDE: "claude",
|
|
11
11
|
CODEX: "codex",
|
|
12
12
|
CURSOR: "cursor",
|
|
13
|
+
DEEPSEEK: "deepseek",
|
|
14
|
+
FX: "fx",
|
|
15
|
+
KIMI: "kimi",
|
|
13
16
|
OPENCODE: "opencode",
|
|
14
17
|
PI: "pi",
|
|
15
18
|
RELAY: "relay"
|
|
@@ -28,6 +31,9 @@ var THINKING_LEVELS_BY_AGENT = {
|
|
|
28
31
|
claude: [...STANDARD_THINKING_LEVELS, "ultracode"],
|
|
29
32
|
codex: [...STANDARD_THINKING_LEVELS, "ultra"],
|
|
30
33
|
cursor: STANDARD_THINKING_LEVELS,
|
|
34
|
+
deepseek: STANDARD_THINKING_LEVELS,
|
|
35
|
+
fx: STANDARD_THINKING_LEVELS,
|
|
36
|
+
kimi: STANDARD_THINKING_LEVELS,
|
|
31
37
|
opencode: STANDARD_THINKING_LEVELS,
|
|
32
38
|
pi: STANDARD_THINKING_LEVELS,
|
|
33
39
|
relay: [...STANDARD_THINKING_LEVELS, "ultracode"]
|
|
@@ -41,6 +47,12 @@ function getProviderDisplayName(provider, variant = "short") {
|
|
|
41
47
|
return "Codex";
|
|
42
48
|
case "cursor":
|
|
43
49
|
return "Cursor";
|
|
50
|
+
case "deepseek":
|
|
51
|
+
return variant === "long" ? "DeepSeek Harness" : "DeepSeek";
|
|
52
|
+
case "fx":
|
|
53
|
+
return "fx";
|
|
54
|
+
case "kimi":
|
|
55
|
+
return variant === "long" ? "Kimi Code" : "Kimi";
|
|
44
56
|
case "opencode":
|
|
45
57
|
return "Opencode";
|
|
46
58
|
case "pi":
|
|
@@ -55,6 +67,9 @@ function getCodingAgentDisplayNames() {
|
|
|
55
67
|
return VALID_CODING_AGENT_PROVIDERS.map((provider) => getProviderDisplayName(provider)).join(", ");
|
|
56
68
|
}
|
|
57
69
|
|
|
70
|
+
// ../shared/src/analytics/types.ts
|
|
71
|
+
import { z } from "zod";
|
|
72
|
+
|
|
58
73
|
// ../shared/src/credentials/types.ts
|
|
59
74
|
var CREDENTIAL_SCOPE = {
|
|
60
75
|
USER: "user",
|
|
@@ -76,7 +91,8 @@ var CREDENTIAL_METHOD = {
|
|
|
76
91
|
BEDROCK: "bedrock",
|
|
77
92
|
OPENCODE_GO: "opencode-go",
|
|
78
93
|
ASTER: "aster",
|
|
79
|
-
OPENROUTER: "openrouter"
|
|
94
|
+
OPENROUTER: "openrouter",
|
|
95
|
+
AI_GATEWAY: "ai-gateway"
|
|
80
96
|
};
|
|
81
97
|
var CREDENTIAL_TYPE = {
|
|
82
98
|
CLAUDE_OAUTH: "claude",
|
|
@@ -89,7 +105,8 @@ var CREDENTIAL_TYPE = {
|
|
|
89
105
|
CURSOR_API_KEY: "cursor_api_key",
|
|
90
106
|
OPENCODE_GO_API_KEY: "opencode_go_api_key",
|
|
91
107
|
ASTER_API_KEY: "aster_api_key",
|
|
92
|
-
OPENROUTER_API_KEY: "openrouter_api_key"
|
|
108
|
+
OPENROUTER_API_KEY: "openrouter_api_key",
|
|
109
|
+
AI_GATEWAY_API_KEY: "ai_gateway_api_key"
|
|
93
110
|
};
|
|
94
111
|
var AGENT_CREDENTIAL_METHODS_IN_ORDER = {
|
|
95
112
|
[AGENT.CLAUDE]: [
|
|
@@ -106,6 +123,15 @@ var AGENT_CREDENTIAL_METHODS_IN_ORDER = {
|
|
|
106
123
|
[AGENT.CURSOR]: [
|
|
107
124
|
{ method: CREDENTIAL_METHOD.API_KEY, credentialType: CREDENTIAL_TYPE.CURSOR_API_KEY }
|
|
108
125
|
],
|
|
126
|
+
[AGENT.DEEPSEEK]: [
|
|
127
|
+
{ method: CREDENTIAL_METHOD.OPENROUTER, credentialType: CREDENTIAL_TYPE.OPENROUTER_API_KEY }
|
|
128
|
+
],
|
|
129
|
+
[AGENT.FX]: [
|
|
130
|
+
{ method: CREDENTIAL_METHOD.AI_GATEWAY, credentialType: CREDENTIAL_TYPE.AI_GATEWAY_API_KEY }
|
|
131
|
+
],
|
|
132
|
+
[AGENT.KIMI]: [
|
|
133
|
+
{ method: CREDENTIAL_METHOD.AI_GATEWAY, credentialType: CREDENTIAL_TYPE.AI_GATEWAY_API_KEY }
|
|
134
|
+
],
|
|
109
135
|
[AGENT.OPENCODE]: [
|
|
110
136
|
{ method: CREDENTIAL_METHOD.OPENCODE_GO, credentialType: CREDENTIAL_TYPE.OPENCODE_GO_API_KEY },
|
|
111
137
|
{ method: CREDENTIAL_METHOD.ASTER, credentialType: CREDENTIAL_TYPE.ASTER_API_KEY },
|
|
@@ -117,6 +143,13 @@ var AGENT_CREDENTIAL_METHODS_IN_ORDER = {
|
|
|
117
143
|
]
|
|
118
144
|
};
|
|
119
145
|
|
|
146
|
+
// ../shared/src/analytics/types.ts
|
|
147
|
+
var agentCredentialSnapshotSchema = z.object({
|
|
148
|
+
method: z.enum(CREDENTIAL_METHOD),
|
|
149
|
+
scope: z.enum(CREDENTIAL_SCOPE),
|
|
150
|
+
revision: z.string().optional()
|
|
151
|
+
});
|
|
152
|
+
|
|
120
153
|
// ../shared/src/event.ts
|
|
121
154
|
var CLAUDE_PARTIAL_MESSAGE_EVENT_TYPE = "claude-partial-message";
|
|
122
155
|
function coerceClaudePartialMessagePayload(payload) {
|
|
@@ -138,6 +171,37 @@ var USER_MESSAGE_ID_PAYLOAD_KEY = "replicasMessageId";
|
|
|
138
171
|
var CODEX_ASP_ITEM_ID_PAYLOAD_KEY = "codexAspItemId";
|
|
139
172
|
var CODEX_QUOTA_STATUS_EVENT_TYPE = "codex-quota-status";
|
|
140
173
|
|
|
174
|
+
// ../shared/src/urls.ts
|
|
175
|
+
var HOME_PATH = "/home";
|
|
176
|
+
var DASHBOARD_PATH = "/dashboard";
|
|
177
|
+
var WEB_APP_PATHS = {
|
|
178
|
+
home: HOME_PATH,
|
|
179
|
+
onboarding: `${HOME_PATH}/onboarding`,
|
|
180
|
+
workspaces: `${HOME_PATH}/workspace`,
|
|
181
|
+
automations: `${HOME_PATH}/automations`,
|
|
182
|
+
environment: `${HOME_PATH}/environment`,
|
|
183
|
+
analytics: `${HOME_PATH}/analytics`,
|
|
184
|
+
dashboard: DASHBOARD_PATH,
|
|
185
|
+
agents: `${DASHBOARD_PATH}/agents`,
|
|
186
|
+
integrations: `${DASHBOARD_PATH}/integrations`,
|
|
187
|
+
integrationsGithub: `${DASHBOARD_PATH}/integrations/github`,
|
|
188
|
+
integrationsGitlab: `${DASHBOARD_PATH}/integrations/gitlab`,
|
|
189
|
+
settings: `${DASHBOARD_PATH}/settings`,
|
|
190
|
+
billing: `${DASHBOARD_PATH}/billing`,
|
|
191
|
+
members: `${DASHBOARD_PATH}/members`,
|
|
192
|
+
"audit-logs": `${DASHBOARD_PATH}/audit-logs`,
|
|
193
|
+
accountAgents: `${DASHBOARD_PATH}/account/agents`,
|
|
194
|
+
accountProfile: `${DASHBOARD_PATH}/account/profile`,
|
|
195
|
+
accountIntegrations: `${DASHBOARD_PATH}/account/integrations`,
|
|
196
|
+
accountApiKeys: `${DASHBOARD_PATH}/account/api-keys`,
|
|
197
|
+
accountPreferences: `${DASHBOARD_PATH}/account/preferences`,
|
|
198
|
+
fullscreenWorkspaces: "/workspaces"
|
|
199
|
+
};
|
|
200
|
+
var LEGACY_WEB_APP_PATHS = {
|
|
201
|
+
app: "/app",
|
|
202
|
+
dashboardWorkspaces: `${DASHBOARD_PATH}/workspaces`
|
|
203
|
+
};
|
|
204
|
+
|
|
141
205
|
// ../shared/src/default-skills/replicas-agent/abilities/computer.ts
|
|
142
206
|
var SECTION = `### Computer use (Linux desktop control)
|
|
143
207
|
Drive the workspace's Linux desktop - open a browser, click, type, scroll, screenshot, record - via the \`replicas computer\` CLI. Every Replicas workspace boots with a live H.264 and Opus stream published as an authenticated preview, so a \`Desktop\` tab is always available in the dashboard. Use \`replicas computer info\` to get the viewer URL when you want to share it (e.g. point a user on Slack at the live stream).
|
|
@@ -615,35 +679,8 @@ var GITLAB_ABILITY = {
|
|
|
615
679
|
referenceFile: { name: "GITLAB.md", content: REFERENCE4 }
|
|
616
680
|
};
|
|
617
681
|
|
|
618
|
-
// ../shared/src/default-skills/replicas-agent/abilities/learnings.ts
|
|
619
|
-
var SECTION5 = `### Learnings
|
|
620
|
-
Propose additions, updates, or deletions to curated organization knowledge.
|
|
621
|
-
|
|
622
|
-
**Reference:** \`references/LEARNINGS.md\``;
|
|
623
|
-
var REFERENCE5 = `# Learnings
|
|
624
|
-
|
|
625
|
-
Learnings are curated, human-approved knowledge entries your organization maintains: conventions, gotchas, environment facts, and process rules.
|
|
626
|
-
|
|
627
|
-
All writes are proposals: a human reviews them in the dashboard, and nothing takes effect until approved.
|
|
628
|
-
|
|
629
|
-
Use \`replicas learnings --help\` and subcommand help such as \`replicas learnings add --help\`, \`replicas learnings update --help\`, or \`replicas learnings delete --help\` for current command syntax.
|
|
630
|
-
|
|
631
|
-
A human approves every proposal before it takes effect, so don't agonize over borderline calls \u2014 but keep proposals genuinely useful rather than reflexive.
|
|
632
|
-
|
|
633
|
-
- Propose \`add\` for anything repeatable and org-useful: user corrections and preferences, hard-won environment or process knowledge, conventions and decisions worth following, and gotchas that would waste time again. If you learned it the hard way this task, capture it.
|
|
634
|
-
- Never store task-specific details that won't recur, facts trivially derivable by reading the repo, or secrets/credentials.
|
|
635
|
-
- Propose \`update\` or \`delete\` when a learning is contradicted by the current code or docs, especially if the outdated guidance would affect future repeated work.
|
|
636
|
-
- Write narrow triggers describing when the entry should surface (e.g. "UI/UX work on the admin panel"), not vague topics.`;
|
|
637
|
-
var LEARNINGS_ABILITY = {
|
|
638
|
-
label: "Learnings",
|
|
639
|
-
description: "Propose changes to curated org knowledge for human review.",
|
|
640
|
-
bullet: "- Proposing changes to organization Learnings (curated, human-approved knowledge)",
|
|
641
|
-
section: SECTION5,
|
|
642
|
-
referenceFile: { name: "LEARNINGS.md", content: REFERENCE5 }
|
|
643
|
-
};
|
|
644
|
-
|
|
645
682
|
// ../shared/src/default-skills/replicas-agent/abilities/linear.ts
|
|
646
|
-
var
|
|
683
|
+
var SECTION5 = `### Linear
|
|
647
684
|
Fetch issues, update state, add comments, and search through the workspace-scoped TypeScript SDK.
|
|
648
685
|
|
|
649
686
|
**Reference:** \`references/LINEAR.md\`
|
|
@@ -652,7 +689,7 @@ Use this when:
|
|
|
652
689
|
- You encounter a Linear issue link and need to understand the task
|
|
653
690
|
- You need to update an issue's state or add a comment
|
|
654
691
|
- You need to search Linear issues`;
|
|
655
|
-
var
|
|
692
|
+
var REFERENCE5 = `# Linear Integration
|
|
656
693
|
|
|
657
694
|
Use \`@replicas/sdk\`; never request or handle a Linear OAuth token. Replicas refreshes the organization credential behind the gateway.
|
|
658
695
|
|
|
@@ -702,12 +739,12 @@ var LINEAR_ABILITY = {
|
|
|
702
739
|
label: "Linear",
|
|
703
740
|
description: "Fetch issues, comment, and update state through @replicas/sdk.",
|
|
704
741
|
bullet: "- Interacting with Linear (fetching issues, updating state, commenting, etc.)",
|
|
705
|
-
section:
|
|
706
|
-
referenceFile: { name: "LINEAR.md", content:
|
|
742
|
+
section: SECTION5,
|
|
743
|
+
referenceFile: { name: "LINEAR.md", content: REFERENCE5 }
|
|
707
744
|
};
|
|
708
745
|
|
|
709
746
|
// ../shared/src/default-skills/replicas-agent/abilities/media.ts
|
|
710
|
-
var
|
|
747
|
+
var SECTION6 = `### Media
|
|
711
748
|
Share screenshots, screen recordings, generated diagrams, audio clips, and self-contained HTML pages through Replicas and external messages.
|
|
712
749
|
|
|
713
750
|
**Reference:** \`references/MEDIA.md\`
|
|
@@ -717,7 +754,7 @@ Use this when:
|
|
|
717
754
|
- You produce a self-contained HTML report that should be linked from a pull request
|
|
718
755
|
- You record video output (browser automation, screen capture) \u2014 including the recommended aspect ratio and FPS
|
|
719
756
|
- You need to embed media in a Slack/Linear/GitHub message AND keep a referenceable copy in the Replicas dashboard`;
|
|
720
|
-
var
|
|
757
|
+
var REFERENCE6 = `# Media (Screenshots, Recordings, Audio, HTML)
|
|
721
758
|
|
|
722
759
|
This guide covers how to share screenshots, screen recordings, generated diagrams, audio clips, and self-contained HTML pages through Replicas and external surfaces (Slack, Linear, GitHub).
|
|
723
760
|
|
|
@@ -1023,12 +1060,12 @@ var MEDIA_ABILITY = {
|
|
|
1023
1060
|
label: "Media",
|
|
1024
1061
|
description: "Share screenshots, recordings, generated images, audio clips, and HTML pages.",
|
|
1025
1062
|
bullet: "- Producing or showing the user any media \u2014 screenshots, screen recordings, generated images or diagrams, audio clips, or HTML recap pages \u2014 including in your Replicas chat reply, PR descriptions/comments, and other external platforms",
|
|
1026
|
-
section:
|
|
1027
|
-
referenceFile: { name: "MEDIA.md", content:
|
|
1063
|
+
section: SECTION6,
|
|
1064
|
+
referenceFile: { name: "MEDIA.md", content: REFERENCE6 }
|
|
1028
1065
|
};
|
|
1029
1066
|
|
|
1030
1067
|
// ../shared/src/default-skills/replicas-agent/abilities/previews.ts
|
|
1031
|
-
var
|
|
1068
|
+
var SECTION7 = `### Previews
|
|
1032
1069
|
Expose locally running services (web apps, APIs, databases) as public preview URLs so humans can interact with them directly.
|
|
1033
1070
|
|
|
1034
1071
|
**Reference:** \`references/PREVIEWS.md\`
|
|
@@ -1037,7 +1074,7 @@ Use this when:
|
|
|
1037
1074
|
- You need to start a service that a human should view or interact with
|
|
1038
1075
|
- The task involves UI work that benefits from human review
|
|
1039
1076
|
- You are verifying frontend/backend integrations visually`;
|
|
1040
|
-
var
|
|
1077
|
+
var REFERENCE7 = `# Preview URLs
|
|
1041
1078
|
|
|
1042
1079
|
When you run services on ports \u2014 such as a web app, API server, or database \u2014 humans may want to interact with them directly. You can expose your locally running services as public preview URLs.
|
|
1043
1080
|
|
|
@@ -1113,12 +1150,12 @@ var PREVIEWS_ABILITY = {
|
|
|
1113
1150
|
label: "Previews",
|
|
1114
1151
|
description: "Expose locally running services on public preview URLs for humans.",
|
|
1115
1152
|
bullet: "- Creating preview URLs for locally running services",
|
|
1116
|
-
section:
|
|
1117
|
-
referenceFile: { name: "PREVIEWS.md", content:
|
|
1153
|
+
section: SECTION7,
|
|
1154
|
+
referenceFile: { name: "PREVIEWS.md", content: REFERENCE7 }
|
|
1118
1155
|
};
|
|
1119
1156
|
|
|
1120
1157
|
// ../shared/src/default-skills/replicas-agent/abilities/plugins.ts
|
|
1121
|
-
var
|
|
1158
|
+
var SECTION8 = `### Plugins
|
|
1122
1159
|
Discover and execute installed marketplace tools through the workspace-scoped TypeScript SDK.
|
|
1123
1160
|
|
|
1124
1161
|
**Reference:** \`references/PLUGINS.md\`
|
|
@@ -1128,10 +1165,15 @@ Use this when:
|
|
|
1128
1165
|
- The user asks to manage Calendly events, invitees, or scheduling links
|
|
1129
1166
|
- The user asks to read or change Google Ads, Docs, Drive, Search Console, or Sheets data
|
|
1130
1167
|
- The user asks for ClickHouse analytics or PostHog product data
|
|
1168
|
+
- The user asks to create or control an E2B sandbox
|
|
1169
|
+
- The user asks to invoke a connected Modal function
|
|
1170
|
+
- The user asks to query or update a connected turbopuffer namespace
|
|
1171
|
+
- The user asks for PlanetScale organizations, databases, branches, or Insights data
|
|
1172
|
+
- The user asks to analyze text with Pangram
|
|
1131
1173
|
- The user asks for Stripe customers, payments, invoices, subscriptions, or balances`;
|
|
1132
|
-
var
|
|
1174
|
+
var REFERENCE8 = `# Plugins
|
|
1133
1175
|
|
|
1134
|
-
Plugins are TypeScript libraries, not MCP servers. Import \`@replicas/sdk\`; Replicas authenticates the workspace and selects only the owner\u2019s personal connection or the organization fallback.
|
|
1176
|
+
Plugins are TypeScript libraries, not MCP servers. Import \`@replicas/sdk\`; Replicas authenticates the workspace and selects only the owner\u2019s personal connection or the organization fallback. Provider credentials, sessions, and project keys are never exposed.
|
|
1135
1177
|
|
|
1136
1178
|
Plugin tools may read or write provider data according to the connected account's permissions. Only execute write or destructive tools when they match the user's request.
|
|
1137
1179
|
|
|
@@ -1181,17 +1223,80 @@ const results = await Promise.all(customerIds.map((customer) =>
|
|
|
1181
1223
|
\`\`\`
|
|
1182
1224
|
|
|
1183
1225
|
Never attempt to import Composio, create a session, manage a connection, or call a provider with raw credentials. Those operations are intentionally unavailable inside the workspace.
|
|
1226
|
+
|
|
1227
|
+
## PlanetScale
|
|
1228
|
+
|
|
1229
|
+
PlanetScale is a native OAuth integration. Pass a relative path from the PlanetScale v1 API; Replicas refreshes access tokens server-side:
|
|
1230
|
+
|
|
1231
|
+
\`\`\`ts
|
|
1232
|
+
const organizations = await replicas.planetscale.request('/organizations');
|
|
1233
|
+
const databases = await replicas.planetscale.request('/organizations/acme/databases');
|
|
1234
|
+
\`\`\`
|
|
1235
|
+
|
|
1236
|
+
OAuth scopes control permitted operations. Confirm mutations before using POST, PUT, PATCH, or DELETE.
|
|
1237
|
+
|
|
1238
|
+
## Modal
|
|
1239
|
+
|
|
1240
|
+
Modal is a native integration and uses its official JavaScript SDK behind the Replicas gateway. Invoke a deployed function by name:
|
|
1241
|
+
|
|
1242
|
+
\`\`\`ts
|
|
1243
|
+
const result = await replicas.modal.call({
|
|
1244
|
+
app: 'my-app',
|
|
1245
|
+
function: 'my-function',
|
|
1246
|
+
args: ['input'],
|
|
1247
|
+
environment: 'main',
|
|
1248
|
+
});
|
|
1249
|
+
\`\`\`
|
|
1250
|
+
|
|
1251
|
+
Function calls execute with the connected Modal token and may mutate external state. Confirm the requested action before invoking a function with side effects.
|
|
1252
|
+
|
|
1253
|
+
## turbopuffer
|
|
1254
|
+
|
|
1255
|
+
turbopuffer is a native integration backed by its official TypeScript SDK. Use the provider-shaped helpers:
|
|
1256
|
+
|
|
1257
|
+
\`\`\`ts
|
|
1258
|
+
const namespaces = await replicas.turbopuffer.namespaces({ prefix: 'products' });
|
|
1259
|
+
const results = await replicas.turbopuffer.query('products', {
|
|
1260
|
+
rank_by: ['text', 'BM25', 'wireless headphones'],
|
|
1261
|
+
top_k: 10,
|
|
1262
|
+
});
|
|
1263
|
+
\`\`\`
|
|
1264
|
+
|
|
1265
|
+
\`write\` mutates namespace data. Confirm the requested change before calling it.
|
|
1266
|
+
|
|
1267
|
+
## Pangram
|
|
1268
|
+
|
|
1269
|
+
Pangram is a native integration. Text sent to either method is processed by Pangram and consumes the connected account's credits:
|
|
1270
|
+
|
|
1271
|
+
\`\`\`ts
|
|
1272
|
+
const detection = await replicas.pangram.detect({ text });
|
|
1273
|
+
const plagiarism = await replicas.pangram.plagiarism(text);
|
|
1274
|
+
\`\`\`
|
|
1275
|
+
|
|
1276
|
+
Do not send private or sensitive text without the user's authorization.
|
|
1277
|
+
|
|
1278
|
+
## E2B
|
|
1279
|
+
|
|
1280
|
+
E2B is a native integration backed by its official JavaScript SDK. Create a sandbox, run commands, and remove it when finished:
|
|
1281
|
+
|
|
1282
|
+
\`\`\`ts
|
|
1283
|
+
const { sandboxId } = await replicas.e2b.create({ timeoutMs: 300_000 });
|
|
1284
|
+
const result = await replicas.e2b.run(sandboxId, 'python analysis.py', { cwd: '/home/user' });
|
|
1285
|
+
await replicas.e2b.kill(sandboxId);
|
|
1286
|
+
\`\`\`
|
|
1287
|
+
|
|
1288
|
+
Sandbox operations consume the connected account's E2B credits. Kill sandboxes after use unless the user asked to keep one running.
|
|
1184
1289
|
`;
|
|
1185
1290
|
var PLUGINS_ABILITY = {
|
|
1186
1291
|
label: "Plugins",
|
|
1187
1292
|
description: "Use installed marketplace tools through @replicas/sdk.",
|
|
1188
1293
|
bullet: "- Interacting with installed marketplace plugins through TypeScript",
|
|
1189
|
-
section:
|
|
1190
|
-
referenceFile: { name: "PLUGINS.md", content:
|
|
1294
|
+
section: SECTION8,
|
|
1295
|
+
referenceFile: { name: "PLUGINS.md", content: REFERENCE8 }
|
|
1191
1296
|
};
|
|
1192
1297
|
|
|
1193
1298
|
// ../shared/src/default-skills/replicas-agent/abilities/replicas.ts
|
|
1194
|
-
var
|
|
1299
|
+
var SECTION9 = `### Replicas (in-workspace CLI)
|
|
1195
1300
|
Take action *with* Replicas itself \u2014 manage automations, environments (variables, files), repos, and \`replicas.json\` config \u2014 using the pre-installed, pre-authenticated \`replicas\` CLI.
|
|
1196
1301
|
|
|
1197
1302
|
**Reference:** \`references/REPLICAS.md\`
|
|
@@ -1202,7 +1307,7 @@ Use this when:
|
|
|
1202
1307
|
- The user asks "what envs / repos / automations do I have?"
|
|
1203
1308
|
- The user asks you to scaffold a \`replicas.json\` / \`replicas.yaml\` in a repo
|
|
1204
1309
|
- You need to run a long-lived service (dev server, daemon) \u2014 always use \`replicas service start\` so it survives workspace sleep/wake`;
|
|
1205
|
-
var
|
|
1310
|
+
var REFERENCE9 = `# Replicas (in-workspace CLI)
|
|
1206
1311
|
|
|
1207
1312
|
This guide covers how to take action *with* Replicas itself from inside a Replicas workspace \u2014 managing automations, environments (and their variables/files), repos, previews, and the user's \`replicas.json\` config \u2014 using the pre-installed \`replicas\` CLI.
|
|
1208
1313
|
|
|
@@ -1429,13 +1534,13 @@ var REPLICAS_ABILITY = {
|
|
|
1429
1534
|
description: "Teach the agent about Replicas itself \u2014 automations, environments, the in-workspace CLI.",
|
|
1430
1535
|
// No bullet — help_instructions covers the `replicas` CLI surface in detail.
|
|
1431
1536
|
bullet: "",
|
|
1432
|
-
section:
|
|
1433
|
-
referenceFile: { name: "REPLICAS.md", content:
|
|
1537
|
+
section: SECTION9,
|
|
1538
|
+
referenceFile: { name: "REPLICAS.md", content: REFERENCE9 },
|
|
1434
1539
|
locked: true
|
|
1435
1540
|
};
|
|
1436
1541
|
|
|
1437
1542
|
// ../shared/src/default-skills/replicas-agent/abilities/sentry.ts
|
|
1438
|
-
var
|
|
1543
|
+
var SECTION10 = `### Sentry
|
|
1439
1544
|
Read issues and project data through the workspace-scoped TypeScript SDK.
|
|
1440
1545
|
|
|
1441
1546
|
**Reference:** \`references/SENTRY.md\`
|
|
@@ -1443,7 +1548,7 @@ Read issues and project data through the workspace-scoped TypeScript SDK.
|
|
|
1443
1548
|
Use this when:
|
|
1444
1549
|
- You need to inspect Sentry projects or issues
|
|
1445
1550
|
- A user asks for error-monitoring context outside a webhook-triggered task`;
|
|
1446
|
-
var
|
|
1551
|
+
var REFERENCE10 = `# Sentry Integration
|
|
1447
1552
|
|
|
1448
1553
|
Use \`@replicas/sdk\`; never request or read a Sentry token. Sentry access is organization-scoped and read-only.
|
|
1449
1554
|
|
|
@@ -1462,12 +1567,12 @@ var SENTRY_ABILITY = {
|
|
|
1462
1567
|
label: "Sentry",
|
|
1463
1568
|
description: "Read Sentry projects and issues through @replicas/sdk.",
|
|
1464
1569
|
bullet: "- Interacting with Sentry (reading projects, issues, and error context)",
|
|
1465
|
-
section:
|
|
1466
|
-
referenceFile: { name: "SENTRY.md", content:
|
|
1570
|
+
section: SECTION10,
|
|
1571
|
+
referenceFile: { name: "SENTRY.md", content: REFERENCE10 }
|
|
1467
1572
|
};
|
|
1468
1573
|
|
|
1469
1574
|
// ../shared/src/default-skills/replicas-agent/abilities/slack.ts
|
|
1470
|
-
var
|
|
1575
|
+
var SECTION11 = `### Slack
|
|
1471
1576
|
Send messages, read threads, search conversations, and upload files through the workspace-scoped TypeScript SDK.
|
|
1472
1577
|
|
|
1473
1578
|
**Reference:** \`references/SLACK.md\`
|
|
@@ -1476,7 +1581,7 @@ Use this when:
|
|
|
1476
1581
|
- You need to send a message to a Slack channel or thread
|
|
1477
1582
|
- You need to read or search Slack conversations
|
|
1478
1583
|
- You encounter a Slack message link and need its full thread`;
|
|
1479
|
-
var
|
|
1584
|
+
var REFERENCE11 = `# Slack Integration
|
|
1480
1585
|
|
|
1481
1586
|
Use \`@replicas/sdk\`; never read or send a Slack token directly. The SDK calls Replicas, which selects only this workspace's organization connection.
|
|
1482
1587
|
|
|
@@ -1511,7 +1616,7 @@ const message = await replicas.slack.call<{ channel: string; ts: string }>('chat
|
|
|
1511
1616
|
await replicas.slack.attachThread({ channel: message.channel, threadTs: message.ts });
|
|
1512
1617
|
\`\`\`
|
|
1513
1618
|
|
|
1514
|
-
A link in the message text stays plain text, so
|
|
1619
|
+
A link in the message text stays plain text, so the message that first shares a pull request or merge request link passes \`blocks\` alongside \`text\` to render a button for it. Keep \`text\` set to the same message \u2014 Slack uses it for notifications and fallback.
|
|
1515
1620
|
|
|
1516
1621
|
\`\`\`ts
|
|
1517
1622
|
await replicas.slack.call('chat.postMessage', {
|
|
@@ -1523,14 +1628,14 @@ await replicas.slack.call('chat.postMessage', {
|
|
|
1523
1628
|
{
|
|
1524
1629
|
type: 'actions',
|
|
1525
1630
|
elements: [
|
|
1526
|
-
{ type: 'button', text: { type: 'plain_text', text: 'View PR' }, url: prUrl, action_id: 'view_pr' },
|
|
1631
|
+
{ type: 'button', style: 'primary', text: { type: 'plain_text', text: 'View PR' }, url: prUrl, action_id: 'view_pr' },
|
|
1527
1632
|
],
|
|
1528
1633
|
},
|
|
1529
1634
|
],
|
|
1530
1635
|
});
|
|
1531
1636
|
\`\`\`
|
|
1532
1637
|
|
|
1533
|
-
Use "View MR" for GitLab. With several links, give each button a unique \`action_id\` and name its repository in the label ("View PR \xB7 web").
|
|
1638
|
+
Only the announcing message gets the button \u2014 follow-ups about a pull request already linked in the thread keep the link in the text and drop the \`blocks\`. Use "View MR" for GitLab. With several links, give each button a unique \`action_id\` and name its repository in the label ("View PR \xB7 web").
|
|
1534
1639
|
|
|
1535
1640
|
Attach every new top-level conversation so future replies route to this workspace. For a reply in another thread, attach its root \`thread_ts\`, not the reply timestamp. Do not attach the originating thread again.
|
|
1536
1641
|
|
|
@@ -1549,8 +1654,8 @@ var SLACK_ABILITY = {
|
|
|
1549
1654
|
label: "Slack",
|
|
1550
1655
|
description: "Send messages, read threads, and search through @replicas/sdk.",
|
|
1551
1656
|
bullet: "- Interacting with Slack (sending messages, reading threads, etc.)",
|
|
1552
|
-
section:
|
|
1553
|
-
referenceFile: { name: "SLACK.md", content:
|
|
1657
|
+
section: SECTION11,
|
|
1658
|
+
referenceFile: { name: "SLACK.md", content: REFERENCE11 }
|
|
1554
1659
|
};
|
|
1555
1660
|
|
|
1556
1661
|
// ../shared/src/default-skills/replicas-agent/registry.ts
|
|
@@ -1560,7 +1665,6 @@ var REPLICAS_AGENT_ABILITY_REGISTRY = {
|
|
|
1560
1665
|
docker: DOCKER_ABILITY,
|
|
1561
1666
|
github: GITHUB_ABILITY,
|
|
1562
1667
|
gitlab: GITLAB_ABILITY,
|
|
1563
|
-
learnings: LEARNINGS_ABILITY,
|
|
1564
1668
|
linear: LINEAR_ABILITY,
|
|
1565
1669
|
media: MEDIA_ABILITY,
|
|
1566
1670
|
plugins: PLUGINS_ABILITY,
|
|
@@ -1654,12 +1758,24 @@ var GPT_5_6_TERRA_MODEL = "gpt-5.6-terra";
|
|
|
1654
1758
|
var GPT_5_6_LUNA_MODEL = "gpt-5.6-luna";
|
|
1655
1759
|
var DEFAULT_CODEX_MODEL = GPT_5_6_SOL_MODEL;
|
|
1656
1760
|
var DEFAULT_OPENCODE_MODEL = "z-ai/glm-5.2";
|
|
1761
|
+
var DEEPSEEK_V4_PRO_MODEL = "deepseek/deepseek-v4-pro-0813";
|
|
1762
|
+
var DEEPSEEK_V4_FLASH_MODEL = "deepseek/deepseek-v4-flash-0731";
|
|
1763
|
+
var DEFAULT_FX_MODEL = "zai/glm-5.2";
|
|
1764
|
+
var DEFAULT_KIMI_MODEL = "moonshotai/kimi-k2.6";
|
|
1657
1765
|
var OPENROUTER_MODELS = [
|
|
1658
1766
|
DEFAULT_OPENCODE_MODEL,
|
|
1767
|
+
DEEPSEEK_V4_PRO_MODEL,
|
|
1768
|
+
DEEPSEEK_V4_FLASH_MODEL,
|
|
1659
1769
|
"minimax/minimax-m3",
|
|
1660
1770
|
"xiaomi/mimo-v2.5-pro",
|
|
1661
1771
|
"moonshotai/kimi-k2.6"
|
|
1662
1772
|
];
|
|
1773
|
+
function prioritizeDeepseekModels(models) {
|
|
1774
|
+
return [
|
|
1775
|
+
...models.filter((model) => model.startsWith("deepseek/")),
|
|
1776
|
+
...models.filter((model) => !model.startsWith("deepseek/"))
|
|
1777
|
+
];
|
|
1778
|
+
}
|
|
1663
1779
|
var CLAUDE_MODEL_CONTEXT_WINDOWS = {
|
|
1664
1780
|
[CLAUDE_FABLE_5_MODEL]: 1e6,
|
|
1665
1781
|
[CLAUDE_OPUS_5_MODEL]: 1e6,
|
|
@@ -1709,11 +1825,15 @@ var AGENT_MODELS = {
|
|
|
1709
1825
|
"gpt-5-mini",
|
|
1710
1826
|
"gemini-3.1-pro",
|
|
1711
1827
|
"gemini-3-flash",
|
|
1828
|
+
"grok-4.6",
|
|
1712
1829
|
"grok-4.5",
|
|
1713
1830
|
"grok-4.3",
|
|
1714
1831
|
CLAUDE_HAIKU_4_5_MODEL,
|
|
1715
1832
|
"kimi-k2.5"
|
|
1716
1833
|
],
|
|
1834
|
+
deepseek: prioritizeDeepseekModels(OPENROUTER_MODELS),
|
|
1835
|
+
fx: [DEFAULT_FX_MODEL],
|
|
1836
|
+
kimi: [DEFAULT_KIMI_MODEL],
|
|
1717
1837
|
opencode: [...OPENROUTER_MODELS, ...ASTER_MODELS],
|
|
1718
1838
|
pi: [...OPENROUTER_MODELS, ...ASTER_MODELS],
|
|
1719
1839
|
relay: [CLAUDE_FABLE_5_MODEL, CLAUDE_OPUS_5_MODEL, CLAUDE_OPUS_4_8_MODEL, CLAUDE_SONNET_5_MODEL]
|
|
@@ -1733,6 +1853,8 @@ var MODEL_LABELS = {
|
|
|
1733
1853
|
[GPT_5_6_LUNA_MODEL]: "GPT-5.6 Luna",
|
|
1734
1854
|
"gpt-5.5": "GPT-5.5",
|
|
1735
1855
|
[DEFAULT_OPENCODE_MODEL]: "GLM 5.2 via OpenRouter",
|
|
1856
|
+
[DEEPSEEK_V4_PRO_MODEL]: "DeepSeek V4 Pro via OpenRouter",
|
|
1857
|
+
[DEEPSEEK_V4_FLASH_MODEL]: "DeepSeek V4 Flash via OpenRouter",
|
|
1736
1858
|
"minimax/minimax-m3": "MiniMax M3 via OpenRouter",
|
|
1737
1859
|
"xiaomi/mimo-v2.5-pro": "MiMo V2.5 Pro via OpenRouter",
|
|
1738
1860
|
"moonshotai/kimi-k2.6": "Kimi K2.6 via OpenRouter",
|
|
@@ -1753,6 +1875,7 @@ var MODEL_LABELS = {
|
|
|
1753
1875
|
[CLAUDE_HAIKU_4_5_MODEL]: "Haiku 4.5",
|
|
1754
1876
|
"gemini-3.1-pro": "Gemini 3.1 Pro",
|
|
1755
1877
|
"gemini-3-flash": "Gemini 3 Flash",
|
|
1878
|
+
"grok-4.6": "Grok 4.6",
|
|
1756
1879
|
"grok-4.5": "Grok 4.5",
|
|
1757
1880
|
"grok-4.3": "Grok 4.3",
|
|
1758
1881
|
"kimi-k2.5": "Kimi K2.5"
|
|
@@ -1762,51 +1885,51 @@ var MAX_CANVAS_FILE_BYTES = 25 * 1024 * 1024;
|
|
|
1762
1885
|
var MAX_CANVAS_PREVIEW_BYTES = 5 * 1024 * 1024;
|
|
1763
1886
|
|
|
1764
1887
|
// ../shared/src/engine/v1.ts
|
|
1765
|
-
import { z } from "zod";
|
|
1766
|
-
var createChatRequestSchema =
|
|
1767
|
-
id:
|
|
1768
|
-
createdAt:
|
|
1769
|
-
provider:
|
|
1770
|
-
title:
|
|
1771
|
-
parentChatId:
|
|
1772
|
-
clientRequestId:
|
|
1888
|
+
import { z as z2 } from "zod";
|
|
1889
|
+
var createChatRequestSchema = z2.object({
|
|
1890
|
+
id: z2.string().uuid().optional(),
|
|
1891
|
+
createdAt: z2.string().datetime().optional(),
|
|
1892
|
+
provider: z2.enum(VALID_AGENT_PROVIDERS),
|
|
1893
|
+
title: z2.string().min(1).optional(),
|
|
1894
|
+
parentChatId: z2.string().uuid().optional(),
|
|
1895
|
+
clientRequestId: z2.string().min(1).max(128).optional()
|
|
1773
1896
|
});
|
|
1774
|
-
var sendChatMessageRequestSchema =
|
|
1775
|
-
messageId:
|
|
1776
|
-
submittedAt:
|
|
1777
|
-
message:
|
|
1778
|
-
model:
|
|
1779
|
-
customInstructions:
|
|
1780
|
-
planMode:
|
|
1781
|
-
images:
|
|
1782
|
-
type:
|
|
1783
|
-
source:
|
|
1784
|
-
|
|
1785
|
-
|
|
1897
|
+
var sendChatMessageRequestSchema = z2.object({
|
|
1898
|
+
messageId: z2.string().optional(),
|
|
1899
|
+
submittedAt: z2.string().optional(),
|
|
1900
|
+
message: z2.string(),
|
|
1901
|
+
model: z2.string().optional(),
|
|
1902
|
+
customInstructions: z2.string().optional(),
|
|
1903
|
+
planMode: z2.boolean().optional(),
|
|
1904
|
+
images: z2.array(z2.object({
|
|
1905
|
+
type: z2.literal("image"),
|
|
1906
|
+
source: z2.discriminatedUnion("type", [
|
|
1907
|
+
z2.object({ type: z2.literal("base64"), media_type: z2.enum(IMAGE_MEDIA_TYPES), data: z2.string() }),
|
|
1908
|
+
z2.object({ type: z2.literal("url"), url: z2.string() })
|
|
1786
1909
|
])
|
|
1787
1910
|
})).optional(),
|
|
1788
|
-
thinkingLevel:
|
|
1789
|
-
goalMode:
|
|
1790
|
-
fastMode:
|
|
1791
|
-
enableInteractiveTools:
|
|
1792
|
-
type:
|
|
1793
|
-
merge:
|
|
1794
|
-
idempotencyKey:
|
|
1795
|
-
senderUserId:
|
|
1796
|
-
senderEmail:
|
|
1797
|
-
senderDisplayName:
|
|
1798
|
-
senderAvatarUrl:
|
|
1799
|
-
errorNotificationTarget:
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
type:
|
|
1804
|
-
provider:
|
|
1805
|
-
resource:
|
|
1806
|
-
repositoryId:
|
|
1807
|
-
resourceNumber:
|
|
1911
|
+
thinkingLevel: z2.enum(VALID_THINKING_LEVELS).optional(),
|
|
1912
|
+
goalMode: z2.boolean().optional(),
|
|
1913
|
+
fastMode: z2.boolean().optional(),
|
|
1914
|
+
enableInteractiveTools: z2.boolean().optional(),
|
|
1915
|
+
type: z2.string().optional(),
|
|
1916
|
+
merge: z2.boolean().optional(),
|
|
1917
|
+
idempotencyKey: z2.string().optional(),
|
|
1918
|
+
senderUserId: z2.string().optional(),
|
|
1919
|
+
senderEmail: z2.string().optional(),
|
|
1920
|
+
senderDisplayName: z2.string().optional(),
|
|
1921
|
+
senderAvatarUrl: z2.string().optional(),
|
|
1922
|
+
errorNotificationTarget: z2.discriminatedUnion("type", [
|
|
1923
|
+
z2.object({ type: z2.literal("slack") }),
|
|
1924
|
+
z2.object({ type: z2.literal("linear"), sessionId: z2.string() }),
|
|
1925
|
+
z2.object({
|
|
1926
|
+
type: z2.literal("code_host"),
|
|
1927
|
+
provider: z2.enum(["github", "gitlab"]),
|
|
1928
|
+
resource: z2.enum(["issue", "pull_request"]),
|
|
1929
|
+
repositoryId: z2.string(),
|
|
1930
|
+
resourceNumber: z2.number()
|
|
1808
1931
|
}),
|
|
1809
|
-
|
|
1932
|
+
z2.object({ type: z2.literal("automation"), executionId: z2.string() })
|
|
1810
1933
|
]).optional()
|
|
1811
1934
|
}).passthrough();
|
|
1812
1935
|
|
|
@@ -2156,6 +2279,15 @@ function areUserMessagesWithinMatchWindow(a, b) {
|
|
|
2156
2279
|
return a.content === b.content && Math.abs(parseTimestampMs(a.timestamp) - parseTimestampMs(b.timestamp)) <= USER_MESSAGE_MATCH_GRACE_PERIOD_MS;
|
|
2157
2280
|
}
|
|
2158
2281
|
|
|
2282
|
+
// ../shared/src/agent-event-utils.ts
|
|
2283
|
+
function getUserMessage(event) {
|
|
2284
|
+
return event.type === "event_msg" && event.payload.type === "user_message" && typeof event.payload.message === "string" ? event.payload.message : null;
|
|
2285
|
+
}
|
|
2286
|
+
function getUserMessageId(event) {
|
|
2287
|
+
const messageId = event.payload[USER_MESSAGE_ID_PAYLOAD_KEY];
|
|
2288
|
+
return typeof messageId === "string" ? messageId : null;
|
|
2289
|
+
}
|
|
2290
|
+
|
|
2159
2291
|
// ../shared/src/display-message/parsers/codex-parser.ts
|
|
2160
2292
|
function getStatusFromExitCode(exitCode) {
|
|
2161
2293
|
return exitCode === 0 ? "completed" : "failed";
|
|
@@ -2581,6 +2713,305 @@ function parseCursorEvents(events) {
|
|
|
2581
2713
|
return messages;
|
|
2582
2714
|
}
|
|
2583
2715
|
|
|
2716
|
+
// ../shared/src/display-message/parsers/deepseek-parser.ts
|
|
2717
|
+
function parseArguments(value) {
|
|
2718
|
+
if (typeof value !== "string") return void 0;
|
|
2719
|
+
const parsed = safeJsonParse(value, value);
|
|
2720
|
+
return isRecord(parsed) ? parsed : stringifyDisplayValue(parsed);
|
|
2721
|
+
}
|
|
2722
|
+
function getDeepseekAssistantMessageText(event, blockType) {
|
|
2723
|
+
if (!isRecord(event) || event.type !== "assistant/message" || !isRecord(event.data) || !isRecord(event.data.message) || !Array.isArray(event.data.message.content)) return "";
|
|
2724
|
+
return event.data.message.content.flatMap((block) => isRecord(block) && block.type === blockType && typeof block.text === "string" ? [block.text] : []).join("");
|
|
2725
|
+
}
|
|
2726
|
+
function parseDeepseekEvents(events) {
|
|
2727
|
+
const messages = [];
|
|
2728
|
+
for (const source of events) {
|
|
2729
|
+
if (source.type === "event_msg" && source.payload.type === "user_message") {
|
|
2730
|
+
if (typeof source.payload.message === "string" && source.payload.message.trim()) {
|
|
2731
|
+
const messageId = source.payload[USER_MESSAGE_ID_PAYLOAD_KEY];
|
|
2732
|
+
messages.push({
|
|
2733
|
+
id: typeof messageId === "string" ? messageId : `deepseek-user-${source.timestamp}`,
|
|
2734
|
+
type: "user",
|
|
2735
|
+
content: source.payload.message,
|
|
2736
|
+
timestamp: source.timestamp
|
|
2737
|
+
});
|
|
2738
|
+
}
|
|
2739
|
+
continue;
|
|
2740
|
+
}
|
|
2741
|
+
if (source.type === "deepseek-error") {
|
|
2742
|
+
messages.push({
|
|
2743
|
+
id: `deepseek-error-${source.timestamp}`,
|
|
2744
|
+
type: "error",
|
|
2745
|
+
message: typeof source.payload.message === "string" ? source.payload.message : "DeepSeek Harness failed",
|
|
2746
|
+
timestamp: source.timestamp
|
|
2747
|
+
});
|
|
2748
|
+
continue;
|
|
2749
|
+
}
|
|
2750
|
+
if (source.type === "deepseek-input-request") {
|
|
2751
|
+
const requestId = typeof source.payload.requestId === "string" ? source.payload.requestId : `deepseek-input-${source.timestamp}`;
|
|
2752
|
+
if (source.payload.kind === "approval") {
|
|
2753
|
+
upsertDisplayMessage(messages, createCallDisplayMessage({
|
|
2754
|
+
id: requestId,
|
|
2755
|
+
server: "deepseek",
|
|
2756
|
+
tool: typeof source.payload.toolName === "string" ? source.payload.toolName : "approval",
|
|
2757
|
+
input: typeof source.payload.reason === "string" ? source.payload.reason : void 0,
|
|
2758
|
+
status: "in_progress",
|
|
2759
|
+
timestamp: source.timestamp,
|
|
2760
|
+
inputRequest: {
|
|
2761
|
+
requestId,
|
|
2762
|
+
status: "pending",
|
|
2763
|
+
options: [
|
|
2764
|
+
{ id: "deny", label: "Deny", variant: "secondary" },
|
|
2765
|
+
{ id: "allow", label: "Allow once", variant: "primary" }
|
|
2766
|
+
]
|
|
2767
|
+
}
|
|
2768
|
+
}));
|
|
2769
|
+
} else {
|
|
2770
|
+
const questions = Array.isArray(source.payload.questions) ? source.payload.questions : [];
|
|
2771
|
+
upsertDisplayMessage(messages, createCallDisplayMessage({
|
|
2772
|
+
id: requestId,
|
|
2773
|
+
server: "deepseek",
|
|
2774
|
+
tool: "ask_user",
|
|
2775
|
+
status: "in_progress",
|
|
2776
|
+
timestamp: source.timestamp,
|
|
2777
|
+
inputRequest: {
|
|
2778
|
+
requestId,
|
|
2779
|
+
status: "pending",
|
|
2780
|
+
questions: questions.flatMap((question) => {
|
|
2781
|
+
if (!isRecord(question) || typeof question.id !== "string" || typeof question.question !== "string") return [];
|
|
2782
|
+
const options = Array.isArray(question.options) ? question.options : [];
|
|
2783
|
+
return [{
|
|
2784
|
+
id: question.id,
|
|
2785
|
+
prompt: question.question,
|
|
2786
|
+
multiSelect: question.multiSelect === true,
|
|
2787
|
+
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 } : {} }] : [])
|
|
2788
|
+
}];
|
|
2789
|
+
})
|
|
2790
|
+
}
|
|
2791
|
+
}));
|
|
2792
|
+
}
|
|
2793
|
+
continue;
|
|
2794
|
+
}
|
|
2795
|
+
if (source.type === "deepseek-input-resolved") {
|
|
2796
|
+
const requestId = typeof source.payload.requestId === "string" ? source.payload.requestId : "";
|
|
2797
|
+
const existing = messages.find((message) => message.type === "tool_call" && message.inputRequest?.requestId === requestId);
|
|
2798
|
+
if (existing?.type === "tool_call" && existing.inputRequest) {
|
|
2799
|
+
existing.inputRequest.status = source.payload.status === "aborted" ? "aborted" : "resolved";
|
|
2800
|
+
existing.status = source.payload.status === "aborted" ? "failed" : "completed";
|
|
2801
|
+
}
|
|
2802
|
+
continue;
|
|
2803
|
+
}
|
|
2804
|
+
if (source.type === "deepseek-jobs" && Array.isArray(source.payload.jobs)) {
|
|
2805
|
+
for (const job of source.payload.jobs) {
|
|
2806
|
+
if (!isRecord(job) || typeof job.id !== "string") continue;
|
|
2807
|
+
const existing = messages.find((message) => message.type === "background_task" && message.taskId === job.id);
|
|
2808
|
+
const status = normalizeBackgroundTaskStatus(job.status);
|
|
2809
|
+
const next = {
|
|
2810
|
+
id: existing?.id ?? `deepseek-job-${job.id}`,
|
|
2811
|
+
type: "background_task",
|
|
2812
|
+
taskId: job.id,
|
|
2813
|
+
status,
|
|
2814
|
+
description: typeof job.label === "string" ? job.label : void 0,
|
|
2815
|
+
taskType: typeof job.kind === "string" ? job.kind : void 0,
|
|
2816
|
+
error: status === "failed" && typeof job.detail === "string" ? job.detail : void 0,
|
|
2817
|
+
timestamp: existing?.timestamp ?? source.timestamp
|
|
2818
|
+
};
|
|
2819
|
+
if (existing?.type === "background_task") Object.assign(existing, next);
|
|
2820
|
+
else messages.push(next);
|
|
2821
|
+
}
|
|
2822
|
+
continue;
|
|
2823
|
+
}
|
|
2824
|
+
if (source.type !== "deepseek-session-event" || !isRecord(source.payload.event)) continue;
|
|
2825
|
+
const event = source.payload.event;
|
|
2826
|
+
const data = isRecord(event.data) ? event.data : {};
|
|
2827
|
+
const seq = typeof event.seq === "number" ? event.seq : source.timestamp;
|
|
2828
|
+
if (event.type === "assistant/message") {
|
|
2829
|
+
const content = getDeepseekAssistantMessageText(event, "text");
|
|
2830
|
+
const reasoning = getDeepseekAssistantMessageText(event, "reasoning");
|
|
2831
|
+
if (reasoning.trim()) messages.push({ id: `deepseek-reasoning-${seq}`, type: "reasoning", content: reasoning, status: "completed", timestamp: source.timestamp });
|
|
2832
|
+
if (content.trim()) messages.push({ id: `deepseek-assistant-${seq}`, type: "agent", content, timestamp: source.timestamp });
|
|
2833
|
+
continue;
|
|
2834
|
+
}
|
|
2835
|
+
if (event.type === "tool/call") {
|
|
2836
|
+
const callId = typeof data.callId === "string" ? data.callId : String(seq);
|
|
2837
|
+
upsertDisplayMessage(messages, createCallDisplayMessage({
|
|
2838
|
+
id: `deepseek-tool-${callId}`,
|
|
2839
|
+
server: "deepseek",
|
|
2840
|
+
tool: typeof data.name === "string" ? data.name : "tool",
|
|
2841
|
+
input: parseArguments(data.arguments),
|
|
2842
|
+
status: "in_progress",
|
|
2843
|
+
timestamp: source.timestamp
|
|
2844
|
+
}));
|
|
2845
|
+
continue;
|
|
2846
|
+
}
|
|
2847
|
+
if (event.type === "tool/result") {
|
|
2848
|
+
const message = isRecord(data.message) ? data.message : {};
|
|
2849
|
+
const messageSource = isRecord(message.source) ? message.source : {};
|
|
2850
|
+
const result2 = Array.isArray(message.content) && isRecord(message.content[0]) ? message.content[0] : {};
|
|
2851
|
+
const callId = typeof messageSource.callId === "string" ? messageSource.callId : typeof data.callId === "string" ? data.callId : String(seq);
|
|
2852
|
+
const existing = messages.find((message2) => message2.id === `deepseek-tool-${callId}` && message2.type === "tool_call");
|
|
2853
|
+
if (existing?.type === "tool_call") {
|
|
2854
|
+
existing.output = stringifyDisplayValue(result2.content ?? data.result);
|
|
2855
|
+
existing.status = result2.isError === true || data.isError === true ? "failed" : "completed";
|
|
2856
|
+
}
|
|
2857
|
+
continue;
|
|
2858
|
+
}
|
|
2859
|
+
if (event.type === "todo/write" && Array.isArray(data.items)) {
|
|
2860
|
+
messages.push({
|
|
2861
|
+
id: `deepseek-todo-${seq}`,
|
|
2862
|
+
type: "todo_list",
|
|
2863
|
+
items: data.items.flatMap((item) => {
|
|
2864
|
+
if (!isRecord(item) || typeof item.content !== "string") return [];
|
|
2865
|
+
const itemStatus = item.status === "in_progress" || item.status === "completed" ? item.status : "pending";
|
|
2866
|
+
return [{ text: item.content, completed: itemStatus === "completed", itemStatus }];
|
|
2867
|
+
}),
|
|
2868
|
+
timestamp: source.timestamp
|
|
2869
|
+
});
|
|
2870
|
+
}
|
|
2871
|
+
}
|
|
2872
|
+
return messages;
|
|
2873
|
+
}
|
|
2874
|
+
|
|
2875
|
+
// ../shared/src/display-message/parsers/acp-parser.ts
|
|
2876
|
+
var FX_CONTEXT_DIAGNOSTIC = /^\[context\] skill catalog omitted .*?(?:\r?\n|$)/;
|
|
2877
|
+
function getAcpTextChunk(update, kind) {
|
|
2878
|
+
if (!isRecord(update) || update.sessionUpdate !== kind || !isRecord(update.content) || update.content.type !== "text") return null;
|
|
2879
|
+
return typeof update.content.text === "string" && update.content.text.length > 0 ? update.content.text : null;
|
|
2880
|
+
}
|
|
2881
|
+
function isProviderEvent(event, provider, suffix) {
|
|
2882
|
+
return event.type === `acp-${suffix}` && (event.payload.provider === void 0 || event.payload.provider === provider) || event.type === `${provider}-${suffix}`;
|
|
2883
|
+
}
|
|
2884
|
+
function parseAcpEvents(events, provider) {
|
|
2885
|
+
const messages = [];
|
|
2886
|
+
const activeChunks = {};
|
|
2887
|
+
const resolvedInputs = /* @__PURE__ */ new Map();
|
|
2888
|
+
let chunkSequence = 0;
|
|
2889
|
+
for (const event of events) {
|
|
2890
|
+
const userContent = getUserMessage(event);
|
|
2891
|
+
if (userContent !== null) {
|
|
2892
|
+
activeChunks.agent_message_chunk = void 0;
|
|
2893
|
+
activeChunks.agent_thought_chunk = void 0;
|
|
2894
|
+
if (userContent.trim()) {
|
|
2895
|
+
messages.push({
|
|
2896
|
+
id: getUserMessageId(event) ?? `${provider}-user-${event.timestamp}`,
|
|
2897
|
+
type: "user",
|
|
2898
|
+
content: userContent,
|
|
2899
|
+
timestamp: event.timestamp
|
|
2900
|
+
});
|
|
2901
|
+
}
|
|
2902
|
+
continue;
|
|
2903
|
+
}
|
|
2904
|
+
if (isProviderEvent(event, provider, "error")) {
|
|
2905
|
+
messages.push({
|
|
2906
|
+
id: `${provider}-error-${event.timestamp}`,
|
|
2907
|
+
type: "error",
|
|
2908
|
+
message: typeof event.payload.message === "string" ? event.payload.message : `${provider} failed`,
|
|
2909
|
+
timestamp: event.timestamp
|
|
2910
|
+
});
|
|
2911
|
+
continue;
|
|
2912
|
+
}
|
|
2913
|
+
if (isProviderEvent(event, provider, "turn-complete")) {
|
|
2914
|
+
for (const message of messages) {
|
|
2915
|
+
if (message.type === "reasoning" && message.status === "in_progress") message.status = "completed";
|
|
2916
|
+
}
|
|
2917
|
+
activeChunks.agent_message_chunk = void 0;
|
|
2918
|
+
activeChunks.agent_thought_chunk = void 0;
|
|
2919
|
+
continue;
|
|
2920
|
+
}
|
|
2921
|
+
if (event.type === "replicas-tool-input-request" && typeof event.payload.toolUseId === "string" && typeof event.payload.requestId === "string") {
|
|
2922
|
+
const message = messages.find((candidate) => candidate.type === "tool_call" && candidate.id === `${provider}-tool-${event.payload.toolUseId}`);
|
|
2923
|
+
if (message && (Array.isArray(event.payload.options) || Array.isArray(event.payload.questions))) {
|
|
2924
|
+
const resolved = resolvedInputs.get(event.payload.toolUseId);
|
|
2925
|
+
message.inputRequest = {
|
|
2926
|
+
requestId: event.payload.requestId,
|
|
2927
|
+
status: resolved?.selectionId === "aborted" ? "aborted" : resolved ? "resolved" : "pending",
|
|
2928
|
+
...Array.isArray(event.payload.options) ? { options: event.payload.options } : {},
|
|
2929
|
+
...Array.isArray(event.payload.questions) ? { questions: event.payload.questions } : {},
|
|
2930
|
+
...resolved ? { selectionId: resolved.selectionId } : {},
|
|
2931
|
+
...resolved?.selectionSummary ? { selectionSummary: resolved.selectionSummary } : {}
|
|
2932
|
+
};
|
|
2933
|
+
}
|
|
2934
|
+
continue;
|
|
2935
|
+
}
|
|
2936
|
+
if (event.type === "replicas-tool-input-resolved" && typeof event.payload.toolUseId === "string" && typeof event.payload.selectionId === "string") {
|
|
2937
|
+
const resolved = {
|
|
2938
|
+
selectionId: event.payload.selectionId,
|
|
2939
|
+
...typeof event.payload.selectionSummary === "string" ? { selectionSummary: event.payload.selectionSummary } : {}
|
|
2940
|
+
};
|
|
2941
|
+
resolvedInputs.set(event.payload.toolUseId, resolved);
|
|
2942
|
+
const message = messages.find((candidate) => candidate.type === "tool_call" && candidate.id === `${provider}-tool-${event.payload.toolUseId}`);
|
|
2943
|
+
if (message?.inputRequest) {
|
|
2944
|
+
message.inputRequest = {
|
|
2945
|
+
...message.inputRequest,
|
|
2946
|
+
status: resolved.selectionId === "aborted" ? "aborted" : "resolved",
|
|
2947
|
+
...resolved
|
|
2948
|
+
};
|
|
2949
|
+
}
|
|
2950
|
+
continue;
|
|
2951
|
+
}
|
|
2952
|
+
if (!isProviderEvent(event, provider, "session-update") || !isRecord(event.payload.update)) continue;
|
|
2953
|
+
const update = event.payload.update;
|
|
2954
|
+
const kind = update.sessionUpdate;
|
|
2955
|
+
if (kind === "agent_message_chunk" || kind === "agent_thought_chunk") {
|
|
2956
|
+
const content = getAcpTextChunk(update, kind);
|
|
2957
|
+
if (content === null) continue;
|
|
2958
|
+
const explicitId = typeof update.messageId === "string" && update.messageId.length > 0 ? `${provider}-${kind}-${update.messageId}` : null;
|
|
2959
|
+
const id = explicitId ?? activeChunks[kind] ?? `${provider}-${kind}-${chunkSequence++}`;
|
|
2960
|
+
activeChunks[kind] = id;
|
|
2961
|
+
const otherKind = kind === "agent_message_chunk" ? "agent_thought_chunk" : "agent_message_chunk";
|
|
2962
|
+
if (!explicitId) activeChunks[otherKind] = void 0;
|
|
2963
|
+
const existing = messages.find((message) => message.id === id);
|
|
2964
|
+
const text = `${existing && "content" in existing && typeof existing.content === "string" ? existing.content : ""}${content}`.replace(provider === "fx" ? FX_CONTEXT_DIAGNOSTIC : /$^/, "");
|
|
2965
|
+
if (!text) continue;
|
|
2966
|
+
upsertDisplayMessage(messages, kind === "agent_thought_chunk" ? { id, type: "reasoning", content: text, status: "in_progress", timestamp: existing?.timestamp ?? event.timestamp } : { id, type: "agent", content: text, timestamp: existing?.timestamp ?? event.timestamp });
|
|
2967
|
+
continue;
|
|
2968
|
+
}
|
|
2969
|
+
activeChunks.agent_message_chunk = void 0;
|
|
2970
|
+
activeChunks.agent_thought_chunk = void 0;
|
|
2971
|
+
if ((kind === "tool_call" || kind === "tool_call_update") && typeof update.toolCallId === "string") {
|
|
2972
|
+
const id = `${provider}-tool-${update.toolCallId}`;
|
|
2973
|
+
const existing = messages.find((message) => message.id === id && message.type === "tool_call");
|
|
2974
|
+
const status = update.status === "completed" || update.status === "failed" ? update.status === "failed" ? "failed" : "completed" : "in_progress";
|
|
2975
|
+
const contentOutput = Array.isArray(update.content) && update.content.length > 0 ? stringifyDisplayValue(update.content) : void 0;
|
|
2976
|
+
upsertDisplayMessage(messages, createCallDisplayMessage({
|
|
2977
|
+
id,
|
|
2978
|
+
server: provider,
|
|
2979
|
+
tool: typeof update.name === "string" && update.name ? update.name : typeof update.title === "string" && update.title ? update.title : existing?.tool ?? (typeof update.kind === "string" ? update.kind : "tool"),
|
|
2980
|
+
input: update.rawInput === void 0 ? existing?.input : isRecord(update.rawInput) ? update.rawInput : stringifyDisplayValue(update.rawInput),
|
|
2981
|
+
output: update.rawOutput === void 0 ? contentOutput ?? existing?.output : stringifyDisplayValue(update.rawOutput),
|
|
2982
|
+
status,
|
|
2983
|
+
timestamp: existing?.timestamp ?? event.timestamp
|
|
2984
|
+
}));
|
|
2985
|
+
continue;
|
|
2986
|
+
}
|
|
2987
|
+
const plan = kind === "plan" ? update : isRecord(update.plan) ? update.plan : void 0;
|
|
2988
|
+
if ((kind === "plan" || kind === "plan_update") && plan && Array.isArray(plan.entries)) {
|
|
2989
|
+
const items = plan.entries.flatMap((entry) => {
|
|
2990
|
+
if (!isRecord(entry) || typeof entry.content !== "string") return [];
|
|
2991
|
+
const itemStatus = entry.status === "completed" || entry.status === "in_progress" ? entry.status : "pending";
|
|
2992
|
+
return [{
|
|
2993
|
+
text: entry.content,
|
|
2994
|
+
completed: entry.status === "completed",
|
|
2995
|
+
itemStatus
|
|
2996
|
+
}];
|
|
2997
|
+
});
|
|
2998
|
+
upsertDisplayMessage(messages, {
|
|
2999
|
+
id: `${provider}-plan-${typeof plan.planId === "string" ? plan.planId : "current"}`,
|
|
3000
|
+
type: "todo_list",
|
|
3001
|
+
items,
|
|
3002
|
+
status: items.every((item) => item.completed) ? "completed" : "in_progress",
|
|
3003
|
+
timestamp: event.timestamp
|
|
3004
|
+
});
|
|
3005
|
+
}
|
|
3006
|
+
}
|
|
3007
|
+
return messages;
|
|
3008
|
+
}
|
|
3009
|
+
|
|
3010
|
+
// ../shared/src/display-message/parsers/fx-parser.ts
|
|
3011
|
+
function parseFxEvents(events) {
|
|
3012
|
+
return parseAcpEvents(events, "fx");
|
|
3013
|
+
}
|
|
3014
|
+
|
|
2584
3015
|
// ../shared/src/display-message/parsers/opencode-parser.ts
|
|
2585
3016
|
function timestampFromMs(value, fallback) {
|
|
2586
3017
|
return typeof value === "number" && Number.isFinite(value) ? new Date(value).toISOString() : fallback;
|
|
@@ -3327,6 +3758,15 @@ function parseAgentEvents(events, agentType) {
|
|
|
3327
3758
|
if (agentType === "cursor") {
|
|
3328
3759
|
return parseCursorEvents(events);
|
|
3329
3760
|
}
|
|
3761
|
+
if (agentType === "deepseek") {
|
|
3762
|
+
return parseDeepseekEvents(events);
|
|
3763
|
+
}
|
|
3764
|
+
if (agentType === "fx") {
|
|
3765
|
+
return parseFxEvents(events);
|
|
3766
|
+
}
|
|
3767
|
+
if (agentType === "kimi") {
|
|
3768
|
+
return parseAcpEvents(events, "kimi");
|
|
3769
|
+
}
|
|
3330
3770
|
if (agentType === "opencode") {
|
|
3331
3771
|
return parseOpencodeEvents(events);
|
|
3332
3772
|
}
|
|
@@ -3336,6 +3776,80 @@ function parseAgentEvents(events, agentType) {
|
|
|
3336
3776
|
return parseClaudeEvents(events);
|
|
3337
3777
|
}
|
|
3338
3778
|
|
|
3779
|
+
// ../shared/src/pricing.ts
|
|
3780
|
+
var AUTOMATED_SOURCES = ["api", "automation"];
|
|
3781
|
+
var AUTOMATED_SOURCES_SQL = AUTOMATED_SOURCES.map((s) => `'${s}'`).join(", ");
|
|
3782
|
+
var PLANS = {
|
|
3783
|
+
trial: {
|
|
3784
|
+
id: "trial",
|
|
3785
|
+
name: "Free Trial",
|
|
3786
|
+
monthlyPrice: 0,
|
|
3787
|
+
seatPriceCents: 0,
|
|
3788
|
+
features: [
|
|
3789
|
+
"14 days free, no credit card required",
|
|
3790
|
+
"Unlimited manual workspace minutes",
|
|
3791
|
+
"15,000 automated workspace minutes",
|
|
3792
|
+
"Unlimited repositories and environments",
|
|
3793
|
+
"Unlimited automations",
|
|
3794
|
+
"Warm pools and warm hooks",
|
|
3795
|
+
"API access"
|
|
3796
|
+
]
|
|
3797
|
+
},
|
|
3798
|
+
developer: {
|
|
3799
|
+
id: "developer",
|
|
3800
|
+
name: "Developer",
|
|
3801
|
+
monthlyPrice: 120,
|
|
3802
|
+
seatPriceCents: 12e3,
|
|
3803
|
+
features: [
|
|
3804
|
+
"Unlimited manual workspace minutes",
|
|
3805
|
+
"5,000 automated workspace minutes per month",
|
|
3806
|
+
"Up to 10 repositories",
|
|
3807
|
+
"Up to 15 environments",
|
|
3808
|
+
"Up to 5 automations",
|
|
3809
|
+
"Warm pools and warm hooks",
|
|
3810
|
+
"API access"
|
|
3811
|
+
]
|
|
3812
|
+
},
|
|
3813
|
+
team: {
|
|
3814
|
+
id: "team",
|
|
3815
|
+
name: "Team",
|
|
3816
|
+
monthlyPrice: 300,
|
|
3817
|
+
seatPriceCents: 3e4,
|
|
3818
|
+
features: [
|
|
3819
|
+
"Unlimited manual workspace minutes",
|
|
3820
|
+
"15,000 automated workspace minutes per month",
|
|
3821
|
+
"Unlimited repositories",
|
|
3822
|
+
"Unlimited automations",
|
|
3823
|
+
"Warm pools and warm hooks",
|
|
3824
|
+
"Higher API rate limits",
|
|
3825
|
+
"Access to a static egress IP",
|
|
3826
|
+
"Auto-upgraded sandbox resources (4 vCPU, 32 GB disk, 16 GB memory)",
|
|
3827
|
+
"Shared Slack support channel"
|
|
3828
|
+
]
|
|
3829
|
+
},
|
|
3830
|
+
enterprise: {
|
|
3831
|
+
id: "enterprise",
|
|
3832
|
+
name: "Enterprise",
|
|
3833
|
+
monthlyPrice: 0,
|
|
3834
|
+
seatPriceCents: 0,
|
|
3835
|
+
features: [
|
|
3836
|
+
"Unlimited manual workspace minutes",
|
|
3837
|
+
"Unlimited automated workspace minutes",
|
|
3838
|
+
"Unlimited automations",
|
|
3839
|
+
"Custom warm hooks and pools",
|
|
3840
|
+
"Custom API rates",
|
|
3841
|
+
"Custom rate limits",
|
|
3842
|
+
"Shared Slack support channel",
|
|
3843
|
+
"SOC 2",
|
|
3844
|
+
"Data Processing Agreement (DPA)",
|
|
3845
|
+
"SCIM user provisioning",
|
|
3846
|
+
"Custom security and privacy settings"
|
|
3847
|
+
]
|
|
3848
|
+
}
|
|
3849
|
+
};
|
|
3850
|
+
var TEAM_PLAN = PLANS.team;
|
|
3851
|
+
var ENTERPRISE_PLAN = PLANS.enterprise;
|
|
3852
|
+
|
|
3339
3853
|
// ../shared/src/routes/workspaces.ts
|
|
3340
3854
|
var WORKSPACE_STATUSES = ["active", "sleeping", "archived", "preparing", "error"];
|
|
3341
3855
|
var VALID_LIFECYCLE_POLICIES = ["default", "archive_when_done", "sleep_when_done", "delete_after_inactivity"];
|
|
@@ -3396,24 +3910,24 @@ function result(data, isError = false) {
|
|
|
3396
3910
|
}
|
|
3397
3911
|
var server = new McpServer({
|
|
3398
3912
|
name: "replicas-mcp",
|
|
3399
|
-
version: "0.2.
|
|
3913
|
+
version: "0.2.14"
|
|
3400
3914
|
});
|
|
3401
3915
|
var registerTool = server.registerTool.bind(server);
|
|
3402
|
-
var codingAgentSchema =
|
|
3916
|
+
var codingAgentSchema = z3.string().refine(isValidCodingAgentProvider, {
|
|
3403
3917
|
message: `Coding agent must be ${getCodingAgentDisplayNames()}`
|
|
3404
3918
|
});
|
|
3405
|
-
var lifecyclePolicySchema =
|
|
3919
|
+
var lifecyclePolicySchema = z3.enum(VALID_LIFECYCLE_POLICIES);
|
|
3406
3920
|
registerTool(
|
|
3407
3921
|
"create_replica",
|
|
3408
3922
|
{
|
|
3409
3923
|
description: "Create a new replica workspace and send initial message",
|
|
3410
3924
|
inputSchema: {
|
|
3411
|
-
name:
|
|
3412
|
-
message:
|
|
3413
|
-
repository_ids:
|
|
3414
|
-
repository_set_id:
|
|
3925
|
+
name: z3.string().regex(/^\S+$/, "Name cannot contain spaces"),
|
|
3926
|
+
message: z3.string(),
|
|
3927
|
+
repository_ids: z3.array(z3.string()).min(1).optional().describe("Repository IDs to include. Mutually exclusive with repository_set_id."),
|
|
3928
|
+
repository_set_id: z3.string().optional().describe("Repository set ID to use. Mutually exclusive with repository_ids."),
|
|
3415
3929
|
coding_agent: codingAgentSchema.optional().describe("Coding agent to use (default: claude)"),
|
|
3416
|
-
model:
|
|
3930
|
+
model: z3.string().optional().describe("Model to use for the coding agent"),
|
|
3417
3931
|
lifecycle_policy: lifecyclePolicySchema.optional().describe("Lifecycle policy for the workspace")
|
|
3418
3932
|
}
|
|
3419
3933
|
},
|
|
@@ -3439,11 +3953,11 @@ registerTool(
|
|
|
3439
3953
|
{
|
|
3440
3954
|
description: "List all replicas with pagination and optional filters",
|
|
3441
3955
|
inputSchema: {
|
|
3442
|
-
page:
|
|
3443
|
-
limit:
|
|
3444
|
-
user_id:
|
|
3445
|
-
source:
|
|
3446
|
-
status:
|
|
3956
|
+
page: z3.number().optional(),
|
|
3957
|
+
limit: z3.number().optional(),
|
|
3958
|
+
user_id: z3.string().optional().describe("Filter by creator user ID"),
|
|
3959
|
+
source: z3.enum(["api", "dashboard", "slack", "linear", "github", "gitlab", "automation"]).optional().describe("Filter by creation source"),
|
|
3960
|
+
status: z3.enum(["active", "sleeping", "preparing"]).optional().describe("Filter by workspace status")
|
|
3447
3961
|
}
|
|
3448
3962
|
},
|
|
3449
3963
|
async (args) => {
|
|
@@ -3466,8 +3980,8 @@ registerTool(
|
|
|
3466
3980
|
{
|
|
3467
3981
|
description: "Get replica details by ID, including current status, chats, and repository statuses",
|
|
3468
3982
|
inputSchema: {
|
|
3469
|
-
id:
|
|
3470
|
-
include:
|
|
3983
|
+
id: z3.string(),
|
|
3984
|
+
include: z3.array(z3.enum(["environment", "diffs"])).optional().describe("Extra data to include in response")
|
|
3471
3985
|
}
|
|
3472
3986
|
},
|
|
3473
3987
|
async (args) => {
|
|
@@ -3486,12 +4000,12 @@ registerTool(
|
|
|
3486
4000
|
{
|
|
3487
4001
|
description: "Send a message to an existing replica. Automatically handles waking sleeping replicas.",
|
|
3488
4002
|
inputSchema: {
|
|
3489
|
-
id:
|
|
3490
|
-
message:
|
|
4003
|
+
id: z3.string(),
|
|
4004
|
+
message: z3.string(),
|
|
3491
4005
|
coding_agent: codingAgentSchema.optional().describe("Coding agent to use"),
|
|
3492
|
-
chat_id:
|
|
3493
|
-
model:
|
|
3494
|
-
plan_mode:
|
|
4006
|
+
chat_id: z3.string().optional().describe("Chat ID to send the message to (uses default chat if omitted)"),
|
|
4007
|
+
model: z3.string().optional().describe("Model to use"),
|
|
4008
|
+
plan_mode: z3.boolean().optional().describe("Whether to use plan mode")
|
|
3495
4009
|
}
|
|
3496
4010
|
},
|
|
3497
4011
|
async (args) => {
|
|
@@ -3512,7 +4026,7 @@ registerTool(
|
|
|
3512
4026
|
{
|
|
3513
4027
|
description: "Delete a replica. This terminates the workspace and cannot be undone.",
|
|
3514
4028
|
inputSchema: {
|
|
3515
|
-
id:
|
|
4029
|
+
id: z3.string()
|
|
3516
4030
|
}
|
|
3517
4031
|
},
|
|
3518
4032
|
async (args) => {
|
|
@@ -3554,7 +4068,7 @@ registerTool(
|
|
|
3554
4068
|
{
|
|
3555
4069
|
description: "List chats in a replica workspace",
|
|
3556
4070
|
inputSchema: {
|
|
3557
|
-
id:
|
|
4071
|
+
id: z3.string().describe("Replica ID")
|
|
3558
4072
|
}
|
|
3559
4073
|
},
|
|
3560
4074
|
async (args) => {
|
|
@@ -3570,9 +4084,9 @@ registerTool(
|
|
|
3570
4084
|
{
|
|
3571
4085
|
description: "Create a new chat in a replica workspace",
|
|
3572
4086
|
inputSchema: {
|
|
3573
|
-
id:
|
|
4087
|
+
id: z3.string().describe("Replica ID"),
|
|
3574
4088
|
provider: codingAgentSchema.describe("Coding agent provider for the chat"),
|
|
3575
|
-
title:
|
|
4089
|
+
title: z3.string().optional().describe("Optional title for the chat")
|
|
3576
4090
|
}
|
|
3577
4091
|
},
|
|
3578
4092
|
async (args) => {
|
|
@@ -3590,8 +4104,8 @@ registerTool(
|
|
|
3590
4104
|
{
|
|
3591
4105
|
description: "Delete a chat from a replica workspace",
|
|
3592
4106
|
inputSchema: {
|
|
3593
|
-
id:
|
|
3594
|
-
chat_id:
|
|
4107
|
+
id: z3.string().describe("Replica ID"),
|
|
4108
|
+
chat_id: z3.string().describe("Chat ID to delete")
|
|
3595
4109
|
}
|
|
3596
4110
|
},
|
|
3597
4111
|
async (args) => {
|
|
@@ -3607,8 +4121,8 @@ registerTool(
|
|
|
3607
4121
|
{
|
|
3608
4122
|
description: "Read conversation history of a replica. Returns parsed DisplayMessage objects (user messages, agent responses, commands, file changes, tool calls, etc). If the workspace is sleeping, it will be woken and you should retry in 30-90 seconds.",
|
|
3609
4123
|
inputSchema: {
|
|
3610
|
-
id:
|
|
3611
|
-
chat_id:
|
|
4124
|
+
id: z3.string(),
|
|
4125
|
+
chat_id: z3.string().optional().describe("Read history for a specific chat (uses default chat if omitted)")
|
|
3612
4126
|
}
|
|
3613
4127
|
},
|
|
3614
4128
|
async (args) => {
|
|
@@ -3642,7 +4156,7 @@ registerTool(
|
|
|
3642
4156
|
{
|
|
3643
4157
|
description: "Get warm and start hook logs for a replica workspace",
|
|
3644
4158
|
inputSchema: {
|
|
3645
|
-
id:
|
|
4159
|
+
id: z3.string().describe("Replica ID")
|
|
3646
4160
|
}
|
|
3647
4161
|
},
|
|
3648
4162
|
async (args) => {
|
package/package.json
CHANGED