@rudderhq/cli 0.4.3-canary.7 → 0.4.3-canary.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -9,110 +9,6 @@ var __export = (target, all) => {
9
9
  __defProp(target, name, { get: all[name], enumerable: true });
10
10
  };
11
11
 
12
- // src/config/hostnames.ts
13
- function normalizeHostnameInput(raw) {
14
- const input = raw.trim();
15
- if (!input) {
16
- throw new Error("Hostname is required");
17
- }
18
- try {
19
- const url = input.includes("://") ? new URL(input) : new URL(`http://${input}`);
20
- const hostname = url.hostname.trim().toLowerCase();
21
- if (!hostname) throw new Error("Hostname is required");
22
- return hostname;
23
- } catch {
24
- throw new Error(`Invalid hostname: ${raw}`);
25
- }
26
- }
27
- function parseHostnameCsv(raw) {
28
- if (!raw.trim()) return [];
29
- const unique2 = /* @__PURE__ */ new Set();
30
- for (const part of raw.split(",")) {
31
- const hostname = normalizeHostnameInput(part);
32
- unique2.add(hostname);
33
- }
34
- return Array.from(unique2);
35
- }
36
- var init_hostnames = __esm({
37
- "src/config/hostnames.ts"() {
38
- "use strict";
39
- }
40
- });
41
-
42
- // src/config/home.ts
43
- import os2 from "node:os";
44
- import path2 from "node:path";
45
- function resolveRudderHomeDir() {
46
- const envHome = process.env.RUDDER_HOME?.trim();
47
- if (envHome) return path2.resolve(expandHomePrefix(envHome));
48
- return path2.resolve(os2.homedir(), ".rudder");
49
- }
50
- function resolveRudderInstanceId(override) {
51
- const raw = override?.trim() || process.env.RUDDER_INSTANCE_ID?.trim() || DEFAULT_INSTANCE_ID;
52
- if (!INSTANCE_ID_RE.test(raw)) {
53
- throw new Error(
54
- `Invalid instance id '${raw}'. Allowed characters: letters, numbers, '_' and '-'.`
55
- );
56
- }
57
- return raw;
58
- }
59
- function resolveRudderInstanceRoot(instanceId) {
60
- const id = resolveRudderInstanceId(instanceId);
61
- return path2.resolve(resolveRudderHomeDir(), "instances", id);
62
- }
63
- function resolveDefaultConfigPath(instanceId) {
64
- return path2.resolve(resolveRudderInstanceRoot(instanceId), "config.json");
65
- }
66
- function resolveDefaultContextPath() {
67
- return path2.resolve(resolveRudderHomeDir(), "context.json");
68
- }
69
- function resolveDefaultCliAuthPath() {
70
- return path2.resolve(resolveRudderHomeDir(), "auth.json");
71
- }
72
- function resolveDefaultEmbeddedPostgresDir(instanceId) {
73
- return path2.resolve(resolveRudderInstanceRoot(instanceId), "db");
74
- }
75
- function resolveDefaultLogsDir(instanceId) {
76
- return path2.resolve(resolveRudderInstanceRoot(instanceId), "logs");
77
- }
78
- function resolveDefaultSecretsKeyFilePath(instanceId) {
79
- return path2.resolve(resolveRudderInstanceRoot(instanceId), "secrets", "master.key");
80
- }
81
- function resolveDefaultStorageDir(instanceId) {
82
- return path2.resolve(resolveRudderInstanceRoot(instanceId), "data", "storage");
83
- }
84
- function resolveDefaultBackupDir(instanceId) {
85
- return path2.resolve(resolveRudderInstanceRoot(instanceId), "data", "backups");
86
- }
87
- function expandHomePrefix(value) {
88
- if (value === "~") return os2.homedir();
89
- if (value.startsWith("~/")) return path2.resolve(os2.homedir(), value.slice(2));
90
- return value;
91
- }
92
- function describeLocalInstancePaths(instanceId) {
93
- const resolvedInstanceId = resolveRudderInstanceId(instanceId);
94
- const instanceRoot = resolveRudderInstanceRoot(resolvedInstanceId);
95
- return {
96
- homeDir: resolveRudderHomeDir(),
97
- instanceId: resolvedInstanceId,
98
- instanceRoot,
99
- configPath: resolveDefaultConfigPath(resolvedInstanceId),
100
- embeddedPostgresDataDir: resolveDefaultEmbeddedPostgresDir(resolvedInstanceId),
101
- backupDir: resolveDefaultBackupDir(resolvedInstanceId),
102
- logDir: resolveDefaultLogsDir(resolvedInstanceId),
103
- secretsKeyFilePath: resolveDefaultSecretsKeyFilePath(resolvedInstanceId),
104
- storageDir: resolveDefaultStorageDir(resolvedInstanceId)
105
- };
106
- }
107
- var DEFAULT_INSTANCE_ID, INSTANCE_ID_RE;
108
- var init_home = __esm({
109
- "src/config/home.ts"() {
110
- "use strict";
111
- DEFAULT_INSTANCE_ID = "default";
112
- INSTANCE_ID_RE = /^[a-zA-Z0-9_-]+$/;
113
- }
114
- });
115
-
116
12
  // ../packages/shared/dist/constants.js
117
13
  var ORGANIZATION_STATUSES, ORGANIZATION_INTELLIGENCE_PROFILE_PURPOSES, ORGANIZATION_INTELLIGENCE_PROFILE_STATUSES, DEPLOYMENT_MODES, DEPLOYMENT_EXPOSURES, AUTH_BASE_URL_MODES, AGENT_STATUSES, AGENT_RUNTIME_TYPES, AGENT_ROLES, AGENT_ICON_NAMES, AGENT_DICEBEAR_NOTIONISTS_ICON_PREFIX, AGENT_AVATAR_BACKGROUND_PRESET_IDS, ISSUE_STATUSES, ISSUE_PRIORITIES, AGENT_INTEGRATION_PROVIDERS, AGENT_INTEGRATION_STATUSES, AGENT_INTEGRATION_TRANSPORTS, AGENT_INTEGRATION_PROVIDER_REGIONS, AGENT_INTEGRATION_CHAT_TYPES, AGENT_INTEGRATION_DROP_REASONS, AGENT_INTEGRATION_OUTBOUND_STATUSES, CUSTOM_INTEGRATION_KINDS, CUSTOM_INTEGRATION_SCOPES, CUSTOM_INTEGRATION_STATUSES, CUSTOM_INTEGRATION_TOOL_STATUSES, CUSTOM_INTEGRATION_BINDING_STATUSES, CUSTOM_INTEGRATION_TOOL_CALL_STATUSES, CALENDAR_SOURCE_TYPES, CALENDAR_OWNER_TYPES, CALENDAR_VISIBILITIES, CALENDAR_SOURCE_STATUSES, CALENDAR_EVENT_KINDS, CALENDAR_EVENT_STATUSES, CALENDAR_SOURCE_MODES, CHAT_CONVERSATION_STATUSES, CHAT_ISSUE_CREATION_MODES, CHAT_MESSAGE_ROLES, CHAT_MESSAGE_KINDS, CHAT_MESSAGE_STATUSES, CHAT_CONTEXT_ENTITY_TYPES, GOAL_LEVELS, GOAL_STATUSES, PROJECT_STATUSES, ORGANIZATION_RESOURCE_KINDS, ORGANIZATION_RESOURCE_SOURCE_TYPES, PROJECT_RESOURCE_ATTACHMENT_ROLES, AUTOMATION_STATUSES, AUTOMATION_CONCURRENCY_POLICIES, AUTOMATION_CATCH_UP_POLICIES, AUTOMATION_OUTPUT_MODES, AUTOMATION_TRIGGER_SIGNING_MODES, PROJECT_COLORS, PROJECT_ICONS, APPROVAL_TYPES, SECRET_PROVIDERS, STORAGE_PROVIDERS, BILLING_TYPES, FINANCE_EVENT_KINDS, FINANCE_DIRECTIONS, FINANCE_UNITS, BUDGET_SCOPE_TYPES, BUDGET_METRICS, BUDGET_WINDOW_KINDS, BUDGET_INCIDENT_RESOLUTION_ACTIONS, INVITE_JOIN_TYPES, JOIN_REQUEST_TYPES, JOIN_REQUEST_STATUSES, PERMISSION_KEYS, PLUGIN_STATUSES, PLUGIN_CATEGORIES, PLUGIN_CAPABILITIES, PLUGIN_UI_SLOT_TYPES, PLUGIN_RESERVED_COMPANY_ROUTE_SEGMENTS, PLUGIN_LAUNCHER_PLACEMENT_ZONES, PLUGIN_LAUNCHER_ACTIONS, PLUGIN_LAUNCHER_BOUNDS, PLUGIN_LAUNCHER_RENDER_ENVIRONMENTS, PLUGIN_UI_SLOT_ENTITY_TYPES, PLUGIN_STATE_SCOPE_KINDS;
118
14
  var init_constants = __esm({
@@ -1130,7 +1026,7 @@ var init_secret = __esm({
1130
1026
 
1131
1027
  // ../packages/shared/dist/validators/model-fallbacks.js
1132
1028
  import { z as z7 } from "zod";
1133
- function isRecord2(value) {
1029
+ function isRecord(value) {
1134
1030
  return typeof value === "object" && value !== null && !Array.isArray(value);
1135
1031
  }
1136
1032
  function validateModelFallbacksConfig(value, ctx, pathPrefix) {
@@ -1156,7 +1052,7 @@ function validateModelFallbacksConfig(value, ctx, pathPrefix) {
1156
1052
  }
1157
1053
  return;
1158
1054
  }
1159
- if (!isRecord2(fallback)) {
1055
+ if (!isRecord(fallback)) {
1160
1056
  ctx.addIssue({
1161
1057
  code: z7.ZodIssueCode.custom,
1162
1058
  message: "modelFallbacks entries must be strings or runtime/model objects",
@@ -1184,13 +1080,13 @@ function validateModelFallbacksConfig(value, ctx, pathPrefix) {
1184
1080
  path: [...pathPrefix, "modelFallbacks", index, "model"]
1185
1081
  });
1186
1082
  }
1187
- if (fallback.config !== void 0 && !isRecord2(fallback.config)) {
1083
+ if (fallback.config !== void 0 && !isRecord(fallback.config)) {
1188
1084
  ctx.addIssue({
1189
1085
  code: z7.ZodIssueCode.custom,
1190
1086
  message: "modelFallbacks entry config must be an object",
1191
1087
  path: [...pathPrefix, "modelFallbacks", index, "config"]
1192
1088
  });
1193
- } else if (isRecord2(fallback.config) && fallback.config.env !== void 0) {
1089
+ } else if (isRecord(fallback.config) && fallback.config.env !== void 0) {
1194
1090
  const parsed = envConfigSchema.safeParse(fallback.config.env);
1195
1091
  if (!parsed.success) {
1196
1092
  ctx.addIssue({
@@ -3380,6 +3276,110 @@ var init_dist = __esm({
3380
3276
  }
3381
3277
  });
3382
3278
 
3279
+ // src/config/hostnames.ts
3280
+ function normalizeHostnameInput(raw) {
3281
+ const input = raw.trim();
3282
+ if (!input) {
3283
+ throw new Error("Hostname is required");
3284
+ }
3285
+ try {
3286
+ const url = input.includes("://") ? new URL(input) : new URL(`http://${input}`);
3287
+ const hostname = url.hostname.trim().toLowerCase();
3288
+ if (!hostname) throw new Error("Hostname is required");
3289
+ return hostname;
3290
+ } catch {
3291
+ throw new Error(`Invalid hostname: ${raw}`);
3292
+ }
3293
+ }
3294
+ function parseHostnameCsv(raw) {
3295
+ if (!raw.trim()) return [];
3296
+ const unique2 = /* @__PURE__ */ new Set();
3297
+ for (const part of raw.split(",")) {
3298
+ const hostname = normalizeHostnameInput(part);
3299
+ unique2.add(hostname);
3300
+ }
3301
+ return Array.from(unique2);
3302
+ }
3303
+ var init_hostnames = __esm({
3304
+ "src/config/hostnames.ts"() {
3305
+ "use strict";
3306
+ }
3307
+ });
3308
+
3309
+ // src/config/home.ts
3310
+ import os2 from "node:os";
3311
+ import path2 from "node:path";
3312
+ function resolveRudderHomeDir() {
3313
+ const envHome = process.env.RUDDER_HOME?.trim();
3314
+ if (envHome) return path2.resolve(expandHomePrefix(envHome));
3315
+ return path2.resolve(os2.homedir(), ".rudder");
3316
+ }
3317
+ function resolveRudderInstanceId(override) {
3318
+ const raw = override?.trim() || process.env.RUDDER_INSTANCE_ID?.trim() || DEFAULT_INSTANCE_ID;
3319
+ if (!INSTANCE_ID_RE.test(raw)) {
3320
+ throw new Error(
3321
+ `Invalid instance id '${raw}'. Allowed characters: letters, numbers, '_' and '-'.`
3322
+ );
3323
+ }
3324
+ return raw;
3325
+ }
3326
+ function resolveRudderInstanceRoot(instanceId) {
3327
+ const id = resolveRudderInstanceId(instanceId);
3328
+ return path2.resolve(resolveRudderHomeDir(), "instances", id);
3329
+ }
3330
+ function resolveDefaultConfigPath(instanceId) {
3331
+ return path2.resolve(resolveRudderInstanceRoot(instanceId), "config.json");
3332
+ }
3333
+ function resolveDefaultContextPath() {
3334
+ return path2.resolve(resolveRudderHomeDir(), "context.json");
3335
+ }
3336
+ function resolveDefaultCliAuthPath() {
3337
+ return path2.resolve(resolveRudderHomeDir(), "auth.json");
3338
+ }
3339
+ function resolveDefaultEmbeddedPostgresDir(instanceId) {
3340
+ return path2.resolve(resolveRudderInstanceRoot(instanceId), "db");
3341
+ }
3342
+ function resolveDefaultLogsDir(instanceId) {
3343
+ return path2.resolve(resolveRudderInstanceRoot(instanceId), "logs");
3344
+ }
3345
+ function resolveDefaultSecretsKeyFilePath(instanceId) {
3346
+ return path2.resolve(resolveRudderInstanceRoot(instanceId), "secrets", "master.key");
3347
+ }
3348
+ function resolveDefaultStorageDir(instanceId) {
3349
+ return path2.resolve(resolveRudderInstanceRoot(instanceId), "data", "storage");
3350
+ }
3351
+ function resolveDefaultBackupDir(instanceId) {
3352
+ return path2.resolve(resolveRudderInstanceRoot(instanceId), "data", "backups");
3353
+ }
3354
+ function expandHomePrefix(value) {
3355
+ if (value === "~") return os2.homedir();
3356
+ if (value.startsWith("~/")) return path2.resolve(os2.homedir(), value.slice(2));
3357
+ return value;
3358
+ }
3359
+ function describeLocalInstancePaths(instanceId) {
3360
+ const resolvedInstanceId = resolveRudderInstanceId(instanceId);
3361
+ const instanceRoot = resolveRudderInstanceRoot(resolvedInstanceId);
3362
+ return {
3363
+ homeDir: resolveRudderHomeDir(),
3364
+ instanceId: resolvedInstanceId,
3365
+ instanceRoot,
3366
+ configPath: resolveDefaultConfigPath(resolvedInstanceId),
3367
+ embeddedPostgresDataDir: resolveDefaultEmbeddedPostgresDir(resolvedInstanceId),
3368
+ backupDir: resolveDefaultBackupDir(resolvedInstanceId),
3369
+ logDir: resolveDefaultLogsDir(resolvedInstanceId),
3370
+ secretsKeyFilePath: resolveDefaultSecretsKeyFilePath(resolvedInstanceId),
3371
+ storageDir: resolveDefaultStorageDir(resolvedInstanceId)
3372
+ };
3373
+ }
3374
+ var DEFAULT_INSTANCE_ID, INSTANCE_ID_RE;
3375
+ var init_home = __esm({
3376
+ "src/config/home.ts"() {
3377
+ "use strict";
3378
+ DEFAULT_INSTANCE_ID = "default";
3379
+ INSTANCE_ID_RE = /^[a-zA-Z0-9_-]+$/;
3380
+ }
3381
+ });
3382
+
3383
3383
  // src/config/schema.ts
3384
3384
  var init_schema = __esm({
3385
3385
  "src/config/schema.ts"() {
@@ -6819,6 +6819,7 @@ var init_onboard = __esm({
6819
6819
  import { Command, CommanderError } from "commander";
6820
6820
 
6821
6821
  // src/agent-v1-mcp-server.ts
6822
+ init_dist();
6822
6823
  import { spawn, spawnSync } from "node:child_process";
6823
6824
  import { existsSync } from "node:fs";
6824
6825
  import fs from "node:fs/promises";
@@ -8042,52 +8043,214 @@ function formatAgentCliCapabilitiesHumanReadable(capabilities = getAgentCliCapab
8042
8043
  return lines.join("\n").trimEnd();
8043
8044
  }
8044
8045
 
8045
- // src/agent-v1-mcp-server.ts
8046
- var RUDDER_MCP_SERVER_NAME = "rudder-control-plane";
8047
- var RESERVED_MODEL_ARGUMENTS = /* @__PURE__ */ new Set([
8048
- "orgId",
8049
- "org_id",
8050
- "companyId",
8051
- "company_id",
8052
- "agentId",
8053
- "agent_id",
8054
- "runId",
8055
- "run_id",
8056
- "apiBase",
8057
- "api_base",
8058
- "apiKey",
8059
- "api_key",
8060
- "authorization"
8061
- ]);
8062
- var NORMALIZED_RESERVED_MODEL_ARGUMENTS = /* @__PURE__ */ new Set([
8063
- "orgid",
8064
- "companyid",
8065
- "agentid",
8066
- "runid",
8067
- "apibase",
8068
- "apikey",
8069
- "authorization"
8070
- ]);
8071
- function buildMcpServerEnv(env = process.env) {
8072
- return {
8073
- ...process.env,
8074
- ...env,
8075
- RUDDER_API_URL: env.RUDDER_API_URL,
8076
- RUDDER_API_KEY: env.RUDDER_API_KEY,
8077
- RUDDER_ORG_ID: env.RUDDER_ORG_ID,
8078
- RUDDER_AGENT_ID: env.RUDDER_AGENT_ID,
8079
- RUDDER_RUN_ID: env.RUDDER_RUN_ID,
8080
- RUDDER_PROJECT_LIBRARY_PATH: env.RUDDER_PROJECT_LIBRARY_PATH,
8081
- RUDDER_MCP_RUDDER_BIN: env.RUDDER_MCP_RUDDER_BIN
8082
- };
8083
- }
8084
- function buildAgentV1ToolCallPlan(toolName, rawArgs, env = buildMcpServerEnv()) {
8085
- const input = isRecord(rawArgs) ? rawArgs : {};
8086
- const capabilityId = toolNameToCapabilityId(toolName);
8087
- if (!capabilityId) {
8088
- throw new Error(`Unknown Rudder MCP tool: ${toolName}`);
8089
- }
8090
- const capability = getAgentCliCapabilityById(capabilityId);
8046
+ // src/client/http.ts
8047
+ import { URL as URL2 } from "node:url";
8048
+ var ApiRequestError = class extends Error {
8049
+ status;
8050
+ code;
8051
+ details;
8052
+ body;
8053
+ constructor(status, message, details, body, code) {
8054
+ super(message);
8055
+ this.status = status;
8056
+ this.code = code ?? null;
8057
+ this.details = details;
8058
+ this.body = body;
8059
+ }
8060
+ };
8061
+ var RudderApiClient = class {
8062
+ apiBase;
8063
+ apiKey;
8064
+ agentId;
8065
+ runId;
8066
+ recoverAuth;
8067
+ constructor(opts) {
8068
+ this.apiBase = opts.apiBase.replace(/\/+$/, "");
8069
+ this.apiKey = opts.apiKey?.trim() || void 0;
8070
+ this.agentId = opts.agentId?.trim() || void 0;
8071
+ this.runId = opts.runId?.trim() || void 0;
8072
+ this.recoverAuth = opts.recoverAuth;
8073
+ }
8074
+ get(path24, opts) {
8075
+ return this.request(path24, { method: "GET" }, opts);
8076
+ }
8077
+ post(path24, body, opts) {
8078
+ return this.request(path24, {
8079
+ method: "POST",
8080
+ body: body === void 0 ? void 0 : JSON.stringify(body)
8081
+ }, opts);
8082
+ }
8083
+ postForm(path24, form, opts) {
8084
+ return this.request(path24, {
8085
+ method: "POST",
8086
+ body: form
8087
+ }, opts);
8088
+ }
8089
+ patch(path24, body, opts) {
8090
+ return this.request(path24, {
8091
+ method: "PATCH",
8092
+ body: body === void 0 ? void 0 : JSON.stringify(body)
8093
+ }, opts);
8094
+ }
8095
+ put(path24, body, opts) {
8096
+ return this.request(path24, {
8097
+ method: "PUT",
8098
+ body: body === void 0 ? void 0 : JSON.stringify(body)
8099
+ }, opts);
8100
+ }
8101
+ delete(path24, opts) {
8102
+ return this.request(path24, { method: "DELETE" }, opts);
8103
+ }
8104
+ setApiKey(apiKey) {
8105
+ this.apiKey = apiKey?.trim() || void 0;
8106
+ }
8107
+ async request(path24, init, opts, hasRetriedAuth = false) {
8108
+ const url = buildUrl(this.apiBase, path24);
8109
+ const headers = {
8110
+ accept: "application/json",
8111
+ ...toStringRecord(init.headers)
8112
+ };
8113
+ if (typeof init.body === "string") {
8114
+ headers["content-type"] = headers["content-type"] ?? "application/json";
8115
+ }
8116
+ if (this.apiKey) {
8117
+ headers.authorization = `Bearer ${this.apiKey}`;
8118
+ }
8119
+ if (shouldAttachAgentContext(init.method)) {
8120
+ if (this.agentId) {
8121
+ headers["x-rudder-agent-id"] = this.agentId;
8122
+ }
8123
+ if (this.runId) {
8124
+ headers["x-rudder-run-id"] = this.runId;
8125
+ }
8126
+ }
8127
+ const response = await fetch(url, {
8128
+ ...init,
8129
+ headers
8130
+ });
8131
+ if (opts?.ignoreNotFound && response.status === 404) {
8132
+ return null;
8133
+ }
8134
+ if (!response.ok) {
8135
+ const apiError = await toApiError(response);
8136
+ if (!hasRetriedAuth && this.recoverAuth) {
8137
+ const recoveredToken = await this.recoverAuth({
8138
+ path: path24,
8139
+ method: String(init.method ?? "GET").toUpperCase(),
8140
+ error: apiError
8141
+ });
8142
+ if (recoveredToken) {
8143
+ this.setApiKey(recoveredToken);
8144
+ return this.request(path24, init, opts, true);
8145
+ }
8146
+ }
8147
+ throw apiError;
8148
+ }
8149
+ if (response.status === 204) {
8150
+ return null;
8151
+ }
8152
+ const text6 = await response.text();
8153
+ if (!text6.trim()) {
8154
+ return null;
8155
+ }
8156
+ return safeParseJson(text6);
8157
+ }
8158
+ };
8159
+ function shouldAttachAgentContext(method) {
8160
+ const normalized = String(method ?? "GET").toUpperCase();
8161
+ return normalized !== "GET" && normalized !== "HEAD";
8162
+ }
8163
+ function buildUrl(apiBase, path24) {
8164
+ const normalizedPath = path24.startsWith("/") ? path24 : `/${path24}`;
8165
+ const [pathname, query] = normalizedPath.split("?");
8166
+ const url = new URL2(apiBase);
8167
+ url.pathname = `${url.pathname.replace(/\/+$/, "")}${pathname}`;
8168
+ if (query) url.search = query;
8169
+ return url.toString();
8170
+ }
8171
+ function safeParseJson(text6) {
8172
+ try {
8173
+ return JSON.parse(text6);
8174
+ } catch {
8175
+ return text6;
8176
+ }
8177
+ }
8178
+ async function toApiError(response) {
8179
+ const text6 = await response.text();
8180
+ const parsed = safeParseJson(text6);
8181
+ if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
8182
+ const body = parsed;
8183
+ const message = typeof body.error === "string" && body.error.trim() || typeof body.message === "string" && body.message.trim() || `Request failed with status ${response.status}`;
8184
+ const code = typeof body.code === "string" && body.code.trim().length > 0 ? body.code.trim() : null;
8185
+ return new ApiRequestError(response.status, message, body.details, parsed, code);
8186
+ }
8187
+ return new ApiRequestError(
8188
+ response.status,
8189
+ `Request failed with status ${response.status}`,
8190
+ void 0,
8191
+ parsed,
8192
+ null
8193
+ );
8194
+ }
8195
+ function toStringRecord(headers) {
8196
+ if (!headers) return {};
8197
+ if (Array.isArray(headers)) {
8198
+ return Object.fromEntries(headers.map(([key, value]) => [key, String(value)]));
8199
+ }
8200
+ if (headers instanceof Headers) {
8201
+ return Object.fromEntries(headers.entries());
8202
+ }
8203
+ return Object.fromEntries(
8204
+ Object.entries(headers).map(([key, value]) => [key, String(value)])
8205
+ );
8206
+ }
8207
+
8208
+ // src/agent-v1-mcp-server.ts
8209
+ var RUDDER_MCP_SERVER_NAME = "rudder-control-plane";
8210
+ var RESERVED_MODEL_ARGUMENTS = /* @__PURE__ */ new Set([
8211
+ "orgId",
8212
+ "org_id",
8213
+ "companyId",
8214
+ "company_id",
8215
+ "agentId",
8216
+ "agent_id",
8217
+ "runId",
8218
+ "run_id",
8219
+ "apiBase",
8220
+ "api_base",
8221
+ "apiKey",
8222
+ "api_key",
8223
+ "authorization"
8224
+ ]);
8225
+ var NORMALIZED_RESERVED_MODEL_ARGUMENTS = /* @__PURE__ */ new Set([
8226
+ "orgid",
8227
+ "companyid",
8228
+ "agentid",
8229
+ "runid",
8230
+ "apibase",
8231
+ "apikey",
8232
+ "authorization"
8233
+ ]);
8234
+ function buildMcpServerEnv(env = process.env) {
8235
+ return {
8236
+ ...process.env,
8237
+ ...env,
8238
+ RUDDER_API_URL: env.RUDDER_API_URL,
8239
+ RUDDER_API_KEY: env.RUDDER_API_KEY,
8240
+ RUDDER_ORG_ID: env.RUDDER_ORG_ID,
8241
+ RUDDER_AGENT_ID: env.RUDDER_AGENT_ID,
8242
+ RUDDER_RUN_ID: env.RUDDER_RUN_ID,
8243
+ RUDDER_PROJECT_LIBRARY_PATH: env.RUDDER_PROJECT_LIBRARY_PATH,
8244
+ RUDDER_MCP_RUDDER_BIN: env.RUDDER_MCP_RUDDER_BIN
8245
+ };
8246
+ }
8247
+ function buildAgentV1ToolCallPlan(toolName, rawArgs, env = buildMcpServerEnv()) {
8248
+ const input = isRecord2(rawArgs) ? rawArgs : {};
8249
+ const capabilityId = toolNameToCapabilityId(toolName);
8250
+ if (!capabilityId) {
8251
+ throw new Error(`Unknown Rudder MCP tool: ${toolName}`);
8252
+ }
8253
+ const capability = getAgentCliCapabilityById(capabilityId);
8091
8254
  rejectModelProvidedRuntimeIdentity(input);
8092
8255
  assertRuntimeMcpContext(capability, env);
8093
8256
  const tempFiles = [];
@@ -8204,7 +8367,7 @@ async function callToolSafely(params, env) {
8204
8367
  const details = errorDetails(err);
8205
8368
  const payload = {
8206
8369
  status: "error",
8207
- code: isRecord(details) && typeof details.code === "string" ? details.code : "rudder_mcp_tool_error",
8370
+ code: isRecord2(details) && typeof details.code === "string" ? details.code : "rudder_mcp_tool_error",
8208
8371
  message: errorMessage(err),
8209
8372
  details: details ?? null
8210
8373
  };
@@ -8219,10 +8382,12 @@ async function callToolSafely(params, env) {
8219
8382
  }
8220
8383
  }
8221
8384
  async function callTool(params, env) {
8222
- const record = isRecord(params) ? params : {};
8385
+ const record = isRecord2(params) ? params : {};
8223
8386
  const toolName = typeof record.name === "string" ? record.name : "";
8224
8387
  const args = record.arguments;
8225
8388
  const plan = buildAgentV1ToolCallPlan(toolName, args, env);
8389
+ const directResult = await callToolDirectlyIfSupported(toolName, args, env);
8390
+ if (directResult) return directResult;
8226
8391
  const tempDir = plan.tempFiles.length > 0 ? await fs.mkdtemp(path.join(os.tmpdir(), "rudder-mcp-")) : null;
8227
8392
  const materializedArgs = [...plan.args];
8228
8393
  try {
@@ -8261,6 +8426,85 @@ async function callTool(params, env) {
8261
8426
  if (tempDir) await fs.rm(tempDir, { recursive: true, force: true });
8262
8427
  }
8263
8428
  }
8429
+ async function callToolDirectlyIfSupported(toolName, rawArgs, env) {
8430
+ const capabilityId = toolNameToCapabilityId(toolName);
8431
+ if (!capabilityId) return null;
8432
+ const input = isRecord2(rawArgs) ? rawArgs : {};
8433
+ const api = mcpApiClient(env);
8434
+ switch (capabilityId) {
8435
+ case "agent.me":
8436
+ return mcpSuccess(await api.get("/api/agents/me"));
8437
+ case "agent.inbox":
8438
+ return mcpSuccess(await api.get("/api/agents/me/inbox-lite"));
8439
+ case "issue.get":
8440
+ return mcpSuccess(await api.get(`/api/issues/${encodeURIComponent(requiredAnyString(input, ["issue", "issueId"]))}`));
8441
+ case "issue.context": {
8442
+ const params = new URLSearchParams();
8443
+ const wakeCommentId = optionalString(input.wakeCommentId);
8444
+ if (wakeCommentId) params.set("wakeCommentId", wakeCommentId);
8445
+ const query = params.toString();
8446
+ return mcpSuccess(await api.get(
8447
+ `/api/issues/${encodeURIComponent(requiredAnyString(input, ["issue", "issueId"]))}/heartbeat-context${query ? `?${query}` : ""}`
8448
+ ));
8449
+ }
8450
+ case "issue.checkout": {
8451
+ const expectedStatuses = parseCsvInput(input.expectedStatuses, "todo,backlog,blocked");
8452
+ const payload = checkoutIssueSchema.parse({
8453
+ agentId: optionalString(env.RUDDER_AGENT_ID),
8454
+ expectedStatuses
8455
+ });
8456
+ return mcpSuccess(await api.post(
8457
+ `/api/issues/${encodeURIComponent(requiredAnyString(input, ["issue", "issueId"]))}/checkout`,
8458
+ payload
8459
+ ));
8460
+ }
8461
+ case "issue.comment": {
8462
+ const payload = addIssueCommentSchema.parse({
8463
+ body: requiredAnyString(input, ["body", "comment"]),
8464
+ reopen: input.reopen === true ? true : void 0
8465
+ });
8466
+ return mcpSuccess(await api.post(
8467
+ `/api/issues/${encodeURIComponent(requiredAnyString(input, ["issue", "issueId"]))}/comments`,
8468
+ payload
8469
+ ));
8470
+ }
8471
+ case "issue.done": {
8472
+ const comment = requiredAnyString(input, ["comment", "body"]);
8473
+ return mcpSuccess(await api.patch(
8474
+ `/api/issues/${encodeURIComponent(requiredAnyString(input, ["issue", "issueId"]))}`,
8475
+ { status: "done", comment }
8476
+ ));
8477
+ }
8478
+ default:
8479
+ return null;
8480
+ }
8481
+ }
8482
+ function mcpApiClient(env) {
8483
+ const apiBase = optionalString(env.RUDDER_API_URL);
8484
+ if (!apiBase) {
8485
+ const err = new Error("Rudder MCP runtime context is incomplete. Missing RUDDER_API_URL.");
8486
+ err.code = "rudder_mcp_missing_runtime_context";
8487
+ throw err;
8488
+ }
8489
+ return new RudderApiClient({
8490
+ apiBase,
8491
+ apiKey: optionalString(env.RUDDER_API_KEY) ?? void 0,
8492
+ agentId: optionalString(env.RUDDER_AGENT_ID) ?? void 0,
8493
+ runId: optionalString(env.RUDDER_RUN_ID) ?? void 0
8494
+ });
8495
+ }
8496
+ function mcpSuccess(data) {
8497
+ const text6 = JSON.stringify(data ?? {});
8498
+ return {
8499
+ content: [{ type: "text", text: text6 }],
8500
+ ...structuredContentFromJsonText(text6),
8501
+ isError: false
8502
+ };
8503
+ }
8504
+ function parseCsvInput(value, fallback) {
8505
+ const source = Array.isArray(value) ? value.map((entry) => optionalString(entry)).filter(Boolean).join(",") : optionalString(value) || fallback;
8506
+ return source.split(",").map((entry) => entry.trim()).filter(Boolean);
8507
+ }
8264
8508
  function cliArgsForCapability(capabilityId, input, tempFiles, env) {
8265
8509
  getAgentCliCapabilityById(capabilityId);
8266
8510
  switch (capabilityId) {
@@ -8688,7 +8932,7 @@ function toMcpToolListEntry(tool) {
8688
8932
  };
8689
8933
  }
8690
8934
  function requestedProtocolVersion(params) {
8691
- if (!isRecord(params)) return null;
8935
+ if (!isRecord2(params)) return null;
8692
8936
  return typeof params.protocolVersion === "string" && params.protocolVersion.trim().length > 0 ? params.protocolVersion.trim() : null;
8693
8937
  }
8694
8938
  function toolNameToCapabilityId(toolName) {
@@ -8733,7 +8977,7 @@ function pushJson(args, flag, value) {
8733
8977
  args.push(flag, value.trim());
8734
8978
  return;
8735
8979
  }
8736
- if (isRecord(value) || Array.isArray(value)) {
8980
+ if (isRecord2(value) || Array.isArray(value)) {
8737
8981
  args.push(flag, JSON.stringify(value));
8738
8982
  }
8739
8983
  }
@@ -8786,7 +9030,7 @@ function assertRuntimeMcpContext(capability, env) {
8786
9030
  function structuredContentFromJsonText(text6) {
8787
9031
  try {
8788
9032
  const parsed = JSON.parse(text6);
8789
- if (isRecord(parsed)) return { structuredContent: parsed };
9033
+ if (isRecord2(parsed)) return { structuredContent: parsed };
8790
9034
  return { structuredContent: { result: parsed } };
8791
9035
  } catch {
8792
9036
  return {};
@@ -8850,7 +9094,7 @@ function errorDetails(err) {
8850
9094
  const code = err.code;
8851
9095
  return code ? { code } : void 0;
8852
9096
  }
8853
- function isRecord(value) {
9097
+ function isRecord2(value) {
8854
9098
  return typeof value === "object" && value !== null && !Array.isArray(value);
8855
9099
  }
8856
9100
 
@@ -9233,168 +9477,6 @@ function resolveProfile(context, profileName) {
9233
9477
  return { name, profile };
9234
9478
  }
9235
9479
 
9236
- // src/client/http.ts
9237
- import { URL as URL2 } from "node:url";
9238
- var ApiRequestError = class extends Error {
9239
- status;
9240
- code;
9241
- details;
9242
- body;
9243
- constructor(status, message, details, body, code) {
9244
- super(message);
9245
- this.status = status;
9246
- this.code = code ?? null;
9247
- this.details = details;
9248
- this.body = body;
9249
- }
9250
- };
9251
- var RudderApiClient = class {
9252
- apiBase;
9253
- apiKey;
9254
- agentId;
9255
- runId;
9256
- recoverAuth;
9257
- constructor(opts) {
9258
- this.apiBase = opts.apiBase.replace(/\/+$/, "");
9259
- this.apiKey = opts.apiKey?.trim() || void 0;
9260
- this.agentId = opts.agentId?.trim() || void 0;
9261
- this.runId = opts.runId?.trim() || void 0;
9262
- this.recoverAuth = opts.recoverAuth;
9263
- }
9264
- get(path24, opts) {
9265
- return this.request(path24, { method: "GET" }, opts);
9266
- }
9267
- post(path24, body, opts) {
9268
- return this.request(path24, {
9269
- method: "POST",
9270
- body: body === void 0 ? void 0 : JSON.stringify(body)
9271
- }, opts);
9272
- }
9273
- postForm(path24, form, opts) {
9274
- return this.request(path24, {
9275
- method: "POST",
9276
- body: form
9277
- }, opts);
9278
- }
9279
- patch(path24, body, opts) {
9280
- return this.request(path24, {
9281
- method: "PATCH",
9282
- body: body === void 0 ? void 0 : JSON.stringify(body)
9283
- }, opts);
9284
- }
9285
- put(path24, body, opts) {
9286
- return this.request(path24, {
9287
- method: "PUT",
9288
- body: body === void 0 ? void 0 : JSON.stringify(body)
9289
- }, opts);
9290
- }
9291
- delete(path24, opts) {
9292
- return this.request(path24, { method: "DELETE" }, opts);
9293
- }
9294
- setApiKey(apiKey) {
9295
- this.apiKey = apiKey?.trim() || void 0;
9296
- }
9297
- async request(path24, init, opts, hasRetriedAuth = false) {
9298
- const url = buildUrl(this.apiBase, path24);
9299
- const headers = {
9300
- accept: "application/json",
9301
- ...toStringRecord(init.headers)
9302
- };
9303
- if (typeof init.body === "string") {
9304
- headers["content-type"] = headers["content-type"] ?? "application/json";
9305
- }
9306
- if (this.apiKey) {
9307
- headers.authorization = `Bearer ${this.apiKey}`;
9308
- }
9309
- if (shouldAttachAgentContext(init.method)) {
9310
- if (this.agentId) {
9311
- headers["x-rudder-agent-id"] = this.agentId;
9312
- }
9313
- if (this.runId) {
9314
- headers["x-rudder-run-id"] = this.runId;
9315
- }
9316
- }
9317
- const response = await fetch(url, {
9318
- ...init,
9319
- headers
9320
- });
9321
- if (opts?.ignoreNotFound && response.status === 404) {
9322
- return null;
9323
- }
9324
- if (!response.ok) {
9325
- const apiError = await toApiError(response);
9326
- if (!hasRetriedAuth && this.recoverAuth) {
9327
- const recoveredToken = await this.recoverAuth({
9328
- path: path24,
9329
- method: String(init.method ?? "GET").toUpperCase(),
9330
- error: apiError
9331
- });
9332
- if (recoveredToken) {
9333
- this.setApiKey(recoveredToken);
9334
- return this.request(path24, init, opts, true);
9335
- }
9336
- }
9337
- throw apiError;
9338
- }
9339
- if (response.status === 204) {
9340
- return null;
9341
- }
9342
- const text6 = await response.text();
9343
- if (!text6.trim()) {
9344
- return null;
9345
- }
9346
- return safeParseJson(text6);
9347
- }
9348
- };
9349
- function shouldAttachAgentContext(method) {
9350
- const normalized = String(method ?? "GET").toUpperCase();
9351
- return normalized !== "GET" && normalized !== "HEAD";
9352
- }
9353
- function buildUrl(apiBase, path24) {
9354
- const normalizedPath = path24.startsWith("/") ? path24 : `/${path24}`;
9355
- const [pathname, query] = normalizedPath.split("?");
9356
- const url = new URL2(apiBase);
9357
- url.pathname = `${url.pathname.replace(/\/+$/, "")}${pathname}`;
9358
- if (query) url.search = query;
9359
- return url.toString();
9360
- }
9361
- function safeParseJson(text6) {
9362
- try {
9363
- return JSON.parse(text6);
9364
- } catch {
9365
- return text6;
9366
- }
9367
- }
9368
- async function toApiError(response) {
9369
- const text6 = await response.text();
9370
- const parsed = safeParseJson(text6);
9371
- if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
9372
- const body = parsed;
9373
- const message = typeof body.error === "string" && body.error.trim() || typeof body.message === "string" && body.message.trim() || `Request failed with status ${response.status}`;
9374
- const code = typeof body.code === "string" && body.code.trim().length > 0 ? body.code.trim() : null;
9375
- return new ApiRequestError(response.status, message, body.details, parsed, code);
9376
- }
9377
- return new ApiRequestError(
9378
- response.status,
9379
- `Request failed with status ${response.status}`,
9380
- void 0,
9381
- parsed,
9382
- null
9383
- );
9384
- }
9385
- function toStringRecord(headers) {
9386
- if (!headers) return {};
9387
- if (Array.isArray(headers)) {
9388
- return Object.fromEntries(headers.map(([key, value]) => [key, String(value)]));
9389
- }
9390
- if (headers instanceof Headers) {
9391
- return Object.fromEntries(headers.entries());
9392
- }
9393
- return Object.fromEntries(
9394
- Object.entries(headers).map(([key, value]) => [key, String(value)])
9395
- );
9396
- }
9397
-
9398
9480
  // src/commands/client/common.ts
9399
9481
  init_store();
9400
9482
  var currentCommandFullIds = false;
@@ -9746,11 +9828,12 @@ function asString(value, fallback) {
9746
9828
  var RUDDER_AGENT_OPERATING_CONTRACT = [
9747
9829
  "# Rudder Agent Operating Contract",
9748
9830
  "",
9749
- "Your home directory is `$AGENT_HOME`. Everything personal to you -- life, memory, knowledge -- lives there. Other agents may have their own folders and you may update them when necessary.",
9831
+ "You are a helpful assistant. Your home directory is `$AGENT_HOME`. Everything personal to you -- life, memory, knowledge -- lives there. Other agents may have their own folders and you may update them when necessary.",
9750
9832
  "",
9833
+ "Read Rudder mcp tools to firstly.",
9751
9834
  "Use these paths consistently:",
9752
9835
  "",
9753
- "- Personal instructions live under `$AGENT_HOME/instructions`.",
9836
+ "- Your personal instructions live under `$AGENT_HOME/instructions`.",
9754
9837
  "- Personal memory lives under `$AGENT_HOME/memory`.",
9755
9838
  "- Tacit memory instruction lives at `$AGENT_HOME/instructions/MEMORY.md` and is automatically loaded when present.",
9756
9839
  "- Personal skills live under `$AGENT_HOME/skills`.",
@@ -9799,11 +9882,6 @@ var RUDDER_AGENT_OPERATING_CONTRACT = [
9799
9882
  "",
9800
9883
  "Invoke it whenever you need to remember, retrieve, or organize anything.",
9801
9884
  "",
9802
- "## Safety Considerations",
9803
- "",
9804
- "- Never exfiltrate secrets or private data.",
9805
- "- Do not perform any destructive commands unless explicitly requested by the board.",
9806
- "",
9807
9885
  "## Other",
9808
9886
  "- You can use `rudder` skill to see Agent best practise in Rudder. eg: update Agent profile, crud automation, manage library, project, org, curd agent run, chat, issue.",
9809
9887
  "- Before taking action, deeply analyze and research the existing information to ensure you have comprehensive context information before proceeding with the next action. You have your own goal, memory, skills, automation, library, project, org, use these resources to make better decisions.",