@rudderhq/cli 0.7.16 → 0.7.18

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
@@ -21223,8 +21223,7 @@ var init_plugin_v1 = __esm({
21223
21223
  inspectRudderPluginArchiveSchema = z36.object({
21224
21224
  sourceLabel: z36.string().trim().min(1).max(240),
21225
21225
  filename: z36.string().trim().min(1).max(240).refine((value) => /\.zip$/i.test(value), "Only ZIP Plugin archives are supported"),
21226
- // 100 MiB binary package ceiling plus base64 expansion.
21227
- content: z36.string().min(1).max(14e7),
21226
+ content: z36.string().min(1).max(14e6),
21228
21227
  encoding: z36.literal("base64")
21229
21228
  }).strict();
21230
21229
  configureRudderPluginMarketplaceSchema = z36.object({
@@ -28031,7 +28030,7 @@ var IssueTransportBudget = class {
28031
28030
  });
28032
28031
  return { filePath, scope, surface: this.surface, attempt: "fallback" };
28033
28032
  }
28034
- throw issueTransportUnavailable(state, now);
28033
+ throw issueTransportUnavailable(state, now, scope);
28035
28034
  });
28036
28035
  } catch (error) {
28037
28036
  if (error instanceof ApiRequestError) throw error;
@@ -28067,7 +28066,8 @@ var IssueTransportBudget = class {
28067
28066
  expiresAt: now + this.backoffMs
28068
28067
  };
28069
28068
  await writeState(reservation.filePath, state);
28070
- attachTransportDiagnostic(error, state, now);
28069
+ attachTransportDiagnostic(error, state, now, reservation.scope);
28070
+ appendFallbackGuidance(error, state, reservation.scope);
28071
28071
  if (budgetExhausted) {
28072
28072
  error.code = "issue_transport_unavailable";
28073
28073
  error.message = "Issue transport unavailable";
@@ -28109,7 +28109,7 @@ var IssueTransportBudget = class {
28109
28109
  };
28110
28110
  function issueTransportScope(method, requestPath) {
28111
28111
  const normalizedMethod = String(method ?? "GET").toUpperCase();
28112
- const pathname = requestPath.split("?", 1)[0] ?? "";
28112
+ const [pathname, queryString] = requestPath.split("?", 2);
28113
28113
  const match = /^\/api\/issues\/([^/]+)(?:\/(heartbeat-context|comments)(?:\/([^/]+))?)?$/.exec(pathname);
28114
28114
  if (!match) return null;
28115
28115
  const issueId = decodeURIComponent(match[1] ?? "");
@@ -28121,7 +28121,13 @@ function issueTransportScope(method, requestPath) {
28121
28121
  if (normalizedMethod === "GET" && resource === "comments" && !commentId) operation = "issue.comments.list";
28122
28122
  if (normalizedMethod === "GET" && resource === "comments" && commentId) operation = "issue.comments.get";
28123
28123
  if (normalizedMethod === "POST" && resource === "comments" && !commentId) operation = "issue.comment";
28124
- return operation ? { operation, issueId } : null;
28124
+ if (!operation) return null;
28125
+ const query = new URLSearchParams(queryString ?? "");
28126
+ return {
28127
+ operation,
28128
+ issueId,
28129
+ fallbackCommand: buildCliFallbackCommand(operation, issueId, commentId, query)
28130
+ };
28125
28131
  }
28126
28132
  function buildFingerprint(scope, error) {
28127
28133
  const normalizedMessage = error.message.trim().replace(/\s+/g, " ").toLowerCase().slice(0, 256);
@@ -28134,24 +28140,34 @@ function buildFingerprint(scope, error) {
28134
28140
  normalizedMessage
28135
28141
  };
28136
28142
  }
28137
- function issueTransportUnavailable(state, now) {
28138
- const details = { issueTransport: transportDiagnostic(state, now) };
28143
+ function issueTransportUnavailable(state, now, requestScope = state) {
28144
+ const details = { issueTransport: transportDiagnostic(state, now, requestScope) };
28139
28145
  return new ApiRequestError(
28140
28146
  503,
28141
- state.phase === "fallback_in_flight" ? "Issue transport probe already in flight" : "Issue transport unavailable",
28147
+ issueTransportErrorMessage(state, requestScope),
28142
28148
  details,
28143
28149
  { error: "Issue transport unavailable", code: "issue_transport_unavailable", details },
28144
28150
  "issue_transport_unavailable"
28145
28151
  );
28146
28152
  }
28147
- function attachTransportDiagnostic(error, state, now) {
28153
+ function attachTransportDiagnostic(error, state, now, requestScope = state) {
28148
28154
  const upstreamDetails = error.details;
28149
28155
  error.details = {
28150
28156
  ...isRecord2(upstreamDetails) ? upstreamDetails : upstreamDetails === void 0 ? {} : { upstreamDetails },
28151
- issueTransport: transportDiagnostic(state, now)
28157
+ issueTransport: transportDiagnostic(state, now, requestScope)
28152
28158
  };
28153
28159
  }
28154
- function transportDiagnostic(state, now) {
28160
+ function appendFallbackGuidance(error, state, requestScope) {
28161
+ const fallback = issueTransportFallbackAction(state, requestScope);
28162
+ if (!fallback) return;
28163
+ error.message = `${error.message}; use the equivalent ${fallbackSurfaceLabel(fallback.surface)} fallback once: ${fallbackTarget(fallback)}`;
28164
+ }
28165
+ function issueTransportErrorMessage(state, requestScope = state) {
28166
+ const base = state.phase === "fallback_in_flight" ? "Issue transport probe already in flight" : "Issue transport unavailable";
28167
+ const fallback = issueTransportFallbackAction(state, requestScope);
28168
+ return fallback ? `${base}; use the equivalent ${fallbackSurfaceLabel(fallback.surface)} fallback once: ${fallbackTarget(fallback)}` : base;
28169
+ }
28170
+ function transportDiagnostic(state, now, requestScope = state) {
28155
28171
  return {
28156
28172
  state: state.phase,
28157
28173
  fingerprint: state.failure?.fingerprint ?? null,
@@ -28164,10 +28180,65 @@ function transportDiagnostic(state, now) {
28164
28180
  fallbackSurface: state.fallbackSurface ?? null,
28165
28181
  fallbackMatchedFingerprint: state.fallbackMatchedFingerprint ?? null,
28166
28182
  fallbackBudgetRemaining: state.phase === "fallback_available" ? 1 : 0,
28183
+ fallbackAction: issueTransportFallbackAction(state, requestScope),
28167
28184
  retryAfterMs: Math.max(0, state.expiresAt - now),
28168
28185
  checkpoint: "Issue transport unavailable"
28169
28186
  };
28170
28187
  }
28188
+ function issueTransportFallbackAction(state, requestScope = state) {
28189
+ if (state.phase !== "fallback_available") return null;
28190
+ if (state.initialSurface === "mcp") {
28191
+ return {
28192
+ surface: "cli",
28193
+ command: requestScope.fallbackCommand ?? state.fallbackCommand ?? buildCliFallbackCommand(state.operation, state.issueId, void 0, new URLSearchParams())
28194
+ };
28195
+ }
28196
+ return {
28197
+ surface: "mcp",
28198
+ tool: mcpToolNameForOperation(state.operation)
28199
+ };
28200
+ }
28201
+ function fallbackSurfaceLabel(surface) {
28202
+ return surface === "cli" ? "Rudder CLI" : "Rudder MCP";
28203
+ }
28204
+ function fallbackTarget(fallback) {
28205
+ return fallback.command ?? fallback.tool ?? "the alternate Rudder transport";
28206
+ }
28207
+ function mcpToolNameForOperation(operation) {
28208
+ return `rudder_${operation.replace(/\./g, "_")}`;
28209
+ }
28210
+ function buildCliFallbackCommand(operation, issueId, commentId, query) {
28211
+ const issue = shellQuote(issueId);
28212
+ switch (operation) {
28213
+ case "issue.get":
28214
+ return `rudder issue get ${issue} --json`;
28215
+ case "issue.context": {
28216
+ const command = [`rudder issue context ${issue}`];
28217
+ appendCliOption(command, "--wake-comment-id", query.get("wakeCommentId"));
28218
+ return `${command.join(" ")} --json`;
28219
+ }
28220
+ case "issue.comments.list": {
28221
+ const command = [`rudder issue comments list ${issue}`];
28222
+ appendCliOption(command, "--after", query.get("after"));
28223
+ appendCliOption(command, "--order", query.get("order"));
28224
+ return `${command.join(" ")} --json`;
28225
+ }
28226
+ case "issue.comments.get":
28227
+ return `rudder issue comments get ${issue} ${shellQuote(commentId ?? "<comment-id>")} --json`;
28228
+ case "issue.comment":
28229
+ return `rudder issue comment ${issue} --body-file ./issue-comment.md --json`;
28230
+ default:
28231
+ return `rudder issue ${shellQuote(operation)} ${issue} --json`;
28232
+ }
28233
+ }
28234
+ function appendCliOption(command, option, value) {
28235
+ if (value === null || value.trim().length === 0) return;
28236
+ command.push(option, shellQuote(value));
28237
+ }
28238
+ function shellQuote(value) {
28239
+ if (/^[A-Za-z0-9_./:-]+$/.test(value)) return value;
28240
+ return `'${value.replace(/'/g, "'\\''")}'`;
28241
+ }
28171
28242
  async function readState(filePath) {
28172
28243
  try {
28173
28244
  const parsed = JSON.parse(await fs.readFile(filePath, "utf8"));
@@ -30720,7 +30791,7 @@ function jsonSchemaViolation(value, schema) {
30720
30791
  }
30721
30792
  const types = Array.isArray(schema.type) ? schema.type : schema.type === void 0 ? [] : [schema.type];
30722
30793
  if (types.length > 0) {
30723
- const validType = types.some((type) => type === "string" ? typeof value === "string" : type === "number" ? typeof value === "number" && Number.isFinite(value) : type === "boolean" ? typeof value === "boolean" : type === "array" ? Array.isArray(value) : type === "object" ? isRecord3(value) : type === "null" ? value === null : false);
30794
+ const validType = types.some((type) => type === "string" ? typeof value === "string" : type === "number" ? typeof value === "number" && Number.isFinite(value) : type === "boolean" ? typeof value === "boolean" : type === "array" ? Array.isArray(value) : type === "object" ? isRecord3(value) : false);
30724
30795
  if (!validType) return `must be ${types.join(" or ")}`;
30725
30796
  }
30726
30797
  if (typeof value === "string") {
@@ -30758,9 +30829,6 @@ function jsonSchemaViolation(value, schema) {
30758
30829
  }
30759
30830
  }
30760
30831
  if (isRecord3(value) && schema.type === "object") {
30761
- if (typeof schema.minProperties === "number" && Object.keys(value).length < schema.minProperties) {
30762
- return `must contain at least ${schema.minProperties} properties`;
30763
- }
30764
30832
  const properties = isRecord3(schema.properties) ? schema.properties : {};
30765
30833
  const required = Array.isArray(schema.required) ? schema.required.map(String) : [];
30766
30834
  for (const key of required) {
@@ -31414,17 +31482,21 @@ Reason: {{context.passiveFollowup.reason}}
31414
31482
  Before changing the issue, continue to progress the current issue, then inspect the current issue state and any side effects from the previous run. Finally, do exactly one close-out action: add a progress comment, mark the issue done, block it with a reason, or hand it off explicitly with explanation.
31415
31483
  ${ISSUE_ASSIGNEE_EXECUTION_RAIL}`;
31416
31484
  var RUDDER_AGENT_OPERATING_CONTRACT = [
31417
- "You are a helpful assistant running inside Rudder. 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.",
31485
+ "You are a helpful assistant running inside Rudder. Your home directory is `$AGENT_HOME`. Everything personal to you -- life, memory, knowledge -- lives there. Every agent has its own folders and you may update them when necessary.",
31418
31486
  "",
31419
- "Read Rudder mcp tools to firstly.",
31420
- "Use these paths consistently:",
31487
+ "## Basic Rules",
31488
+ "- If you want to perform any Rudder-related operation such as issue, chat, agent run, automation, or projects, you can use rudder-mcp.",
31489
+ "- When working in an issue, the only scenario for user feedback and communication is via issue comments. Whenever there is progress, changes, or responses, always post an issue comment. Users do not see the entire trajectory of your agent run by default.",
31490
+ "- Another scenario is when you need to request something from the user. In such cases, use a request approval to seek the user's assistance.",
31491
+ "- 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.",
31492
+ "- When the user explicitly mentions previously handled issue, tasks or conversations, retrieve the relevant tasks first before proceeding with the next action.",
31421
31493
  "",
31494
+ "## Basic Paths",
31422
31495
  "- Your personal instructions live under `$AGENT_HOME/instructions`.",
31423
31496
  "- Personal memory lives under `$AGENT_HOME/memory`.",
31424
31497
  "- Tacit memory instruction lives at `$AGENT_HOME/instructions/MEMORY.md` and is automatically loaded when present.",
31425
31498
  "- Personal skills live under `$AGENT_HOME/skills`.",
31426
- "- Shared organization workspace root lives under `$RUDDER_ORG_WORKSPACE_ROOT`.",
31427
- "- Shared organization skills live under `$RUDDER_ORG_SKILLS_DIR`.",
31499
+ "- Shared organization workspace root lives under `$RUDDER_ORG_WORKSPACE_ROOT` and shared org's skills live under `$RUDDER_ORG_SKILLS_DIR`.",
31428
31500
  "- Project Library root lives under `$RUDDER_PROJECT_LIBRARY_ROOT` when the run has project context.",
31429
31501
  "- Project Library locator lives in `$RUDDER_PROJECT_LIBRARY_PATH` when the run has project context, for example `projects/<project-key>`.",
31430
31502
  '- Library-backed project resources use `sourceType: "library"`; their `locator` points into `library:projects/<project-key>/`.',
@@ -31440,11 +31512,8 @@ var RUDDER_AGENT_OPERATING_CONTRACT = [
31440
31512
  "When you create or copy a skill under `$AGENT_HOME/skills/<slug>/`, check the agent's Skills snapshot before claiming it will load in future runs. If it is installed but not enabled, say exactly that future runs will not load it until enabled, and offer to enable it with `rudder agent skills enable <agent-id> <selection-ref>` when you have permission.",
31441
31513
  "If there is an AGENTS.md file in the project you're working on, please read it first and follow the project's development guidelines.",
31442
31514
  "",
31443
- "When you write issue comments or chat replies, match the language of the user's or board's most recent substantive message unless they explicitly ask for a different language.",
31444
- "When you mention a web page, issue URL, external dashboard, or other user-openable target in an issue comment or chat reply, write it as a clickable Markdown link with a descriptive label, for example `[NameSilo transfer page](https://www.namesilo.com/account_domain_manage_transfer.php)`. Do not put action URLs in backticks or code blocks unless you are showing literal code or a command.",
31445
31515
  "",
31446
31516
  "## Rudder Renderable Links",
31447
- "",
31448
31517
  "When you mention Rudder entities in any user-visible Markdown output, prefer Rudder's renderable Markdown link syntax over plain IDs, bare URLs, or backticked references so the UI can render chips and navigate correctly.",
31449
31518
  "",
31450
31519
  "- Issues: use `[](issue://<issue-id>)`; include `?c=<comment-id>` when linking to a specific comment.",
@@ -31454,6 +31523,7 @@ var RUDDER_AGENT_OPERATING_CONTRACT = [
31454
31523
  "- Chat threads: use `[](chat://<conversation-id>)` when citing a Rudder chat conversation.",
31455
31524
  "- Skills: use `[](skill://<skill-ref>)` when citing a Rudder skill reference. The skill ref may be an org skill, agent skill, bundled Rudder skill, or local-machine skill ref; the UI resolves the display label when metadata is available.",
31456
31525
  '- Library files: use the `markdownLink` returned by `rudder library file ref "$RUDDER_PROJECT_LIBRARY_PATH/<relative-file>" --json` with project context, or `rudder library file ref "artifacts/YYYY-MM-DD/<conversation-title>/<relative-file>" --json` without project context; do not hand-write `library-entry://...` links, and treat `library-file://...` as legacy path syntax only.',
31526
+ "- Web page, issue URL, external dashboard, or other user-openable target: write it as a clickable Markdown link with a descriptive label, eg: [NameSilo transfer page](https://www.namesilo.com/account_domain_manage_transfer.php). Do not put action URLs in backticks or code blocks unless you are showing literal code or a command.",
31457
31527
  "",
31458
31528
  "Write these as normal Markdown links, not inside code spans or code blocks, unless you are literally documenting the syntax.",
31459
31529
  "",
@@ -31471,13 +31541,9 @@ var RUDDER_AGENT_OPERATING_CONTRACT = [
31471
31541
  "",
31472
31542
  "You MUST use the `para-memory-files` skill for all memory operations: storing facts, writing daily notes, creating entities, running weekly synthesis, recalling past context, and managing shared work notes. The skill defines your three-layer memory system (knowledge graph, daily notes, tacit knowledge), the PARA folder structure, atomic fact schemas, memory decay rules, and recall conventions.",
31473
31543
  "",
31474
- "Keep stable preferences and operating lessons in `$AGENT_HOME/instructions/MEMORY.md`. Use `$AGENT_HOME/memory/YYYY-MM-DD.md` for daily notes and `$AGENT_HOME/life/` for structured long-term memory. Rudder injects bounded today/yesterday daily-memory excerpts in the startup context bundle; open the files directly when you need full detail.",
31475
- "",
31476
- "Invoke it whenever you need to remember, retrieve, or organize anything.",
31544
+ "Keep stable preferences and operating lessons in `$AGENT_HOME/instructions/MEMORY.md`. Use `$AGENT_HOME/memory/YYYY-MM-DD.md` for daily notes and `$AGENT_HOME/life/` for structured long-term memory. ",
31477
31545
  "",
31478
- "## Other",
31479
- "- 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.",
31480
- "- When the user explicitly mentions previously handled issue, tasks or conversations, you need to retrieve the relevant tasks first before proceeding with the next action."
31546
+ "Invoke it whenever you need to remember, retrieve, or organize anything."
31481
31547
  ].join("\n");
31482
31548
  var RUDDER_AGENT_HEARTBEAT_INSTRUCTION = [
31483
31549
  "This section is injected by Rudder only for heartbeat scene runs. It is the platform-owned heartbeat/self-check pipeline.",
@@ -38275,6 +38341,11 @@ function findDesktopExecutablePids(executablePath, target) {
38275
38341
  return matchesExecutable && pid !== process.pid ? [pid] : [];
38276
38342
  });
38277
38343
  }
38344
+ function desktopApplicationEnvironment() {
38345
+ const env = { ...process.env };
38346
+ delete env.ELECTRON_RUN_AS_NODE;
38347
+ return env;
38348
+ }
38278
38349
  async function waitForUpdateQuitResponse(responsePath, timeoutMs = 8e3) {
38279
38350
  const startedAt = Date.now();
38280
38351
  while (Date.now() - startedAt < timeoutMs) {
@@ -38292,6 +38363,7 @@ async function requestDesktopQuit(executablePath, target, options = {}) {
38292
38363
  `${DESKTOP_UPDATE_QUIT_ARG}=${responsePath}`,
38293
38364
  ...options.forceUpdate ? [DESKTOP_UPDATE_FORCE_ARG] : []
38294
38365
  ], {
38366
+ env: desktopApplicationEnvironment(),
38295
38367
  stdio: "ignore",
38296
38368
  timeout: 5e3
38297
38369
  });
@@ -38917,12 +38989,12 @@ async function startCommand(opts) {
38917
38989
  let applySignal = null;
38918
38990
  let applySignalController = null;
38919
38991
  if (desktopProgressJson && opts.desktopWaitForApply === true) {
38992
+ applySignalController = createDesktopApplySignalController();
38920
38993
  writeDesktopProgress({
38921
38994
  phase: "ready_to_install",
38922
38995
  message: "Desktop update is downloaded and verified.",
38923
38996
  percent: 100
38924
38997
  });
38925
- applySignalController = createDesktopApplySignalController();
38926
38998
  applySignal = await applySignalController.waitForInitialSignal();
38927
38999
  writeDesktopProgress({
38928
39000
  phase: "preparing_restart",