@mutagent/cli 0.2.186 → 0.2.187

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/bin/cli.js +223 -177
  2. package/package.json +2 -2
package/dist/bin/cli.js CHANGED
@@ -37810,11 +37810,117 @@ import chalk64 from "chalk";
37810
37810
 
37811
37811
  // src/lib/integration-sources-input.ts
37812
37812
  init_errors();
37813
- var CREATABLE_KINDS = ["langfuse", "openobserve"];
37813
+
37814
+ // src/lib/integration-sources-guidance.ts
37815
+ init_errors();
37816
+ var SOURCES = "mutagent integrations sources";
37817
+ var READ_ONLY_CODE = "INTEGRATION_SOURCE_READ_ONLY";
37818
+ function testFailureWords(id, check, status) {
37819
+ const http = status === undefined ? "" : ` (HTTP ${String(status)})`;
37820
+ switch (check) {
37821
+ case "credentials_refused":
37822
+ return {
37823
+ message: `The source refused the stored credentials${http}: check credentials_refused failed.`,
37824
+ fix: `Get new keys from the source platform, then run: ${SOURCES} rotate ${id} … --secret-stdin`
37825
+ };
37826
+ case "unreachable":
37827
+ return {
37828
+ message: "The server could not reach the source host: check unreachable failed.",
37829
+ fix: `Check the host is up and public (${SOURCES} list shows it); if it moved, remove the source and add it again.`
37830
+ };
37831
+ case "http_error":
37832
+ return {
37833
+ message: `The source answered with an error${http}: check http_error failed.`,
37834
+ fix: "Check the source platform is healthy and the host is its API base URL, then test again."
37835
+ };
37836
+ case "invalid_response":
37837
+ return {
37838
+ message: "The host did not answer like the source platform: check invalid_response failed.",
37839
+ fix: "Check --host is the platform API base URL (not a dashboard page), then remove and add the source again."
37840
+ };
37841
+ case "host_refused":
37842
+ return {
37843
+ message: "The source host resolves to an address the server may not call: check host_refused failed.",
37844
+ fix: "Use the public URL of the trace platform: remove the source and add it with a public --host."
37845
+ };
37846
+ default:
37847
+ return {
37848
+ message: `The connection test failed${http}${check === undefined ? "" : `: check ${check} failed`}.`,
37849
+ fix: `Run: ${SOURCES} test ${id} again; if it keeps failing, report it: mutagent feedback send --category bug -m "source test ${check ?? "failed"}"`
37850
+ };
37851
+ }
37852
+ }
37853
+
37854
+ class SourceTestFailedError extends MutagentError {
37855
+ sourceId;
37856
+ check;
37857
+ httpStatus;
37858
+ testedAt;
37859
+ constructor(sourceId, check, httpStatus, testedAt) {
37860
+ const words = testFailureWords(sourceId, check, httpStatus);
37861
+ super("INTEGRATION_SOURCE_TEST_FAILED", words.message, words.fix);
37862
+ this.sourceId = sourceId;
37863
+ this.check = check;
37864
+ this.httpStatus = httpStatus;
37865
+ this.testedAt = testedAt;
37866
+ }
37867
+ toJSON() {
37868
+ return {
37869
+ ...super.toJSON(),
37870
+ sourceId: this.sourceId,
37871
+ check: this.check ?? null,
37872
+ ...this.httpStatus === undefined ? {} : { status: this.httpStatus },
37873
+ testedAt: this.testedAt
37874
+ };
37875
+ }
37876
+ }
37877
+ function defaultFix(code, ctx) {
37878
+ const id = ctx.id ?? "<id>";
37879
+ const pullId = ctx.pullId ?? "<pullId>";
37880
+ switch (code) {
37881
+ case "INTEGRATION_SOURCE_NOT_FOUND":
37882
+ return `Run: ${SOURCES} list`;
37883
+ case "INTEGRATION_PULL_NOT_FOUND":
37884
+ return `Run: ${SOURCES} pulls ${id}`;
37885
+ case "INTEGRATION_PULL_NOT_READY":
37886
+ return `Wait for the pull to succeed: ${SOURCES} pull-get ${id} ${pullId}`;
37887
+ case "INTEGRATION_PULL_RUNNING":
37888
+ return `Wait for it to finish (${SOURCES} pulls ${id}), then start another.`;
37889
+ case "INTEGRATION_SOURCE_NAME_TAKEN":
37890
+ return `Pick another name with --name (${SOURCES} list shows the names in use).`;
37891
+ case "INTEGRATION_SOURCE_CREDENTIALS_INVALID":
37892
+ return `Pass the credentials the source's kind takes: ${SOURCES} rotate --help`;
37893
+ case "INTEGRATION_SOURCE_CREDENTIALS_UNREADABLE":
37894
+ return `Rotate the credentials, then test again: ${SOURCES} rotate ${id} … --secret-stdin`;
37895
+ case "INTEGRATION_SOURCE_NOT_TESTABLE":
37896
+ case READ_ONLY_CODE:
37897
+ return "OTLP traces arrive by push; there is nothing to test, rotate, pull or delete.";
37898
+ case "INTEGRATION_SOURCE_HOST_INVALID":
37899
+ case "INTEGRATION_SOURCE_HOST_REFUSED":
37900
+ return "Pass --host the public base URL of the platform, e.g. https://cloud.langfuse.com.";
37901
+ case "INTEGRATION_PULL_WINDOW_INVALID":
37902
+ return "Pass --since and --until as ISO-8601 times, --since first.";
37903
+ case "INTEGRATION_SOURCE_ENCRYPTION_UNAVAILABLE":
37904
+ case "INTEGRATION_PULL_STORE_UNAVAILABLE":
37905
+ return "The server is not configured for this: the platform operator must fix it; nothing on this machine can. " + 'Tell the user, or report it: mutagent feedback send --category bug -m "<what failed>"';
37906
+ default:
37907
+ return `Run: ${SOURCES} --help`;
37908
+ }
37909
+ }
37910
+ var OPERATOR_CODES = new Set(["INTEGRATION_SOURCE_ENCRYPTION_UNAVAILABLE", "INTEGRATION_PULL_STORE_UNAVAILABLE"]);
37911
+ function fixFor(code, serverFix, ctx) {
37912
+ if (OPERATOR_CODES.has(code))
37913
+ return defaultFix(code, ctx);
37914
+ return serverFix ?? defaultFix(code, ctx);
37915
+ }
37916
+
37917
+ // src/lib/integration-sources-input.ts
37918
+ var CREATABLE_KINDS = ["langfuse", "openobserve", "dash0"];
37814
37919
  var OPENOBSERVE_SIGNALS = ["events", "spans"];
37920
+ var DASH0_DATASET = /^[a-zA-Z0-9_-]{3,26}$/;
37815
37921
  var MAX_PULL_LIMIT = 5000;
37816
37922
  var MAX_TAGS = 20;
37817
- var SOURCES = "mutagent integrations sources";
37923
+ var SOURCES2 = "mutagent integrations sources";
37818
37924
  function invalid5(message, fix) {
37819
37925
  const error = new ValidationError(message);
37820
37926
  error.suggestion = fix;
@@ -37827,7 +37933,7 @@ function checkLength(flag, value, max) {
37827
37933
  throw invalid5(`${flag} is longer than ${String(max)} characters.`, `Shorten ${flag}.`);
37828
37934
  return value;
37829
37935
  }
37830
- var ADD_HELP = `Run: ${SOURCES} add --help`;
37936
+ var ADD_HELP = `Run: ${SOURCES2} add --help`;
37831
37937
  function indirectSecret(flags, inputs) {
37832
37938
  if (flags.secretEnv !== undefined && flags.secretStdin === true) {
37833
37939
  throw invalid5("--secret-env and --secret-stdin were both given.", "Pass the secret one way only.");
@@ -37857,31 +37963,41 @@ function oneSecret(flagName, flagValue, flags, inputs) {
37857
37963
  function credentialsFor(kind, flags, inputs, verb) {
37858
37964
  if (kind === "langfuse") {
37859
37965
  if (flags.email !== undefined || flags.password !== undefined || flags.token !== undefined) {
37860
- throw invalid5("A langfuse source takes --public-key and a secret key, not --email, --password or --token.", `Run: ${SOURCES} ${verb} --public-key <pk-lf-…> --secret-stdin`);
37966
+ throw invalid5("A langfuse source takes --public-key and a secret key, not --email, --password or --token.", `Run: ${SOURCES2} ${verb} --public-key <pk-lf-…> --secret-stdin`);
37861
37967
  }
37862
37968
  const secretKey = oneSecret("--secret-key", flags.secretKey, flags, inputs);
37863
37969
  if (flags.publicKey === undefined || secretKey === undefined) {
37864
- throw invalid5("A langfuse source needs --public-key and a secret key (--secret-key, --secret-env or --secret-stdin).", `Run: ${SOURCES} ${verb} --public-key <pk-lf-…> --secret-stdin`);
37970
+ throw invalid5("A langfuse source needs --public-key and a secret key (--secret-key, --secret-env or --secret-stdin).", `Run: ${SOURCES2} ${verb} --public-key <pk-lf-…> --secret-stdin`);
37865
37971
  }
37866
37972
  return { publicKey: checkLength("--public-key", flags.publicKey, 512), secretKey: checkLength("the secret key", secretKey, 512) };
37867
37973
  }
37974
+ if (kind === "dash0") {
37975
+ if (flags.publicKey !== undefined || flags.secretKey !== undefined || flags.email !== undefined || flags.password !== undefined) {
37976
+ throw invalid5("A dash0 source takes an auth token (--token), not --public-key, --secret-key, --email or --password.", `Run: ${SOURCES2} ${verb} --secret-env DASH0_AUTH_TOKEN (or --token, or --secret-stdin)`);
37977
+ }
37978
+ const authToken = oneSecret("--token", flags.token, flags, inputs);
37979
+ if (authToken === undefined) {
37980
+ throw invalid5("A dash0 source needs an auth token (--token, --secret-env or --secret-stdin).", `Run: ${SOURCES2} ${verb} --secret-env DASH0_AUTH_TOKEN (or --token, or --secret-stdin)`);
37981
+ }
37982
+ return { authToken: checkLength("the auth token", authToken, 512) };
37983
+ }
37868
37984
  if (flags.publicKey !== undefined || flags.secretKey !== undefined) {
37869
- throw invalid5("An openobserve source takes --email with a password, or a --token; not --public-key or --secret-key.", `Run: ${SOURCES} ${verb} --token <token> (or --email <email> --secret-stdin)`);
37985
+ throw invalid5("An openobserve source takes --email with a password, or a --token; not --public-key or --secret-key.", `Run: ${SOURCES2} ${verb} --token <token> (or --email <email> --secret-stdin)`);
37870
37986
  }
37871
37987
  if (flags.email !== undefined) {
37872
37988
  if (flags.token !== undefined)
37873
37989
  throw invalid5("--email and --token were both given.", "Pass --email with a password, or --token alone.");
37874
37990
  const password = oneSecret("--password", flags.password, flags, inputs);
37875
37991
  if (password === undefined) {
37876
- throw invalid5("--email needs a password (--password, --secret-env or --secret-stdin).", `Run: ${SOURCES} ${verb} --email <email> --secret-stdin`);
37992
+ throw invalid5("--email needs a password (--password, --secret-env or --secret-stdin).", `Run: ${SOURCES2} ${verb} --email <email> --secret-stdin`);
37877
37993
  }
37878
37994
  return { email: checkLength("--email", flags.email, 512), password: checkLength("the password", password, 512) };
37879
37995
  }
37880
37996
  if (flags.password !== undefined)
37881
- throw invalid5("--password needs --email.", `Run: ${SOURCES} ${verb} --email <email> --secret-stdin`);
37997
+ throw invalid5("--password needs --email.", `Run: ${SOURCES2} ${verb} --email <email> --secret-stdin`);
37882
37998
  const token = oneSecret("--token", flags.token, flags, inputs);
37883
37999
  if (token === undefined) {
37884
- throw invalid5("An openobserve source needs a --token, or --email with a password.", `Run: ${SOURCES} ${verb} --token <token> (or --email <email> --secret-stdin)`);
38000
+ throw invalid5("An openobserve source needs a --token, or --email with a password.", `Run: ${SOURCES2} ${verb} --token <token> (or --email <email> --secret-stdin)`);
37885
38001
  }
37886
38002
  return { token: checkLength("the token", token, 512) };
37887
38003
  }
@@ -37889,7 +38005,7 @@ function creatableKind(kind) {
37889
38005
  if (CREATABLE_KINDS.includes(kind))
37890
38006
  return kind;
37891
38007
  if (kind === "otlp") {
37892
- throw invalid5("OTLP traces arrive by push through OTLP ingest; there is no OTLP source to add.", `Send traces to the OTLP endpoint; ${SOURCES} list shows them once they arrive.`);
38008
+ throw invalid5("OTLP traces arrive by push through OTLP ingest; there is no OTLP source to add.", `Send traces to the OTLP endpoint; ${SOURCES2} list shows them once they arrive.`);
37893
38009
  }
37894
38010
  throw invalid5(`Unknown source kind "${kind}". Kinds: ${CREATABLE_KINDS.join(", ")}.`, ADD_HELP);
37895
38011
  }
@@ -37914,12 +38030,12 @@ function refuseKeyOptionsInSandbox(flags, verb) {
37914
38030
  const given = KEY_OPTIONS2.filter(([field]) => flags[field] !== undefined && flags[field] !== false).map(([, flag]) => flag);
37915
38031
  if (given.length === 0)
37916
38032
  return;
37917
- const fix = verb === "add" ? `Run the same ${SOURCES} add without ${given.join(", ")}: the answer is a one-time page where the user stores the key.` : "The user changes a stored key in Configuration → Integrations; it is never passed through a cloud session.";
38033
+ const fix = verb === "add" ? `Run the same ${SOURCES2} add without ${given.join(", ")}: the answer is a one-time page where the user stores the key.` : "The user changes a stored key in Configuration → Integrations; it is never passed through a cloud session.";
37918
38034
  throw new MutagentError("SANDBOX_SCOPE", `Keys aren't passed through a cloud session, and ${given.join(", ")} ${given.length === 1 ? "carries" : "carry"} one. The user stores keys on a one-time page or in Configuration.`, fix);
37919
38035
  }
37920
38036
  var AT_SIGNS = /@|%40|@/i;
37921
38037
  function sandboxHost(raw) {
37922
- const refuse = () => new MutagentError("SANDBOX_SCOPE", "--host isn't a plain base URL (http or https, no user:password, query or fragment), and a cloud session never passes anything that could carry a key. The user stores keys on a one-time page or in Configuration.", `Run the same ${SOURCES} add with --host as the base URL only, e.g. https://cloud.langfuse.com: the answer is a one-time page where the user stores the key.`);
38038
+ const refuse = () => new MutagentError("SANDBOX_SCOPE", "--host isn't a plain base URL (http or https, no user:password, query or fragment), and a cloud session never passes anything that could carry a key. The user stores keys on a one-time page or in Configuration.", `Run the same ${SOURCES2} add with --host as the base URL only, e.g. https://cloud.langfuse.com: the answer is a one-time page where the user stores the key.`);
37923
38039
  if (AT_SIGNS.test(raw))
37924
38040
  throw refuse();
37925
38041
  let url;
@@ -37937,9 +38053,14 @@ function sandboxHost(raw) {
37937
38053
  function buildSourceBody(kindArg, flags, credentialsOf) {
37938
38054
  const kind = creatableKind(kindArg);
37939
38055
  if (flags.name === undefined)
37940
- throw invalid5("--name is required.", `Run: ${SOURCES} add ${kind} --name <name> …`);
38056
+ throw invalid5("--name is required.", `Run: ${SOURCES2} add ${kind} --name <name> …`);
37941
38057
  const name = checkLength("--name", flags.name, 100);
37942
38058
  const host = flags.host === undefined ? undefined : checkLength("--host", flags.host, 2048);
38059
+ if (kind !== "dash0" && flags.dataset !== undefined) {
38060
+ throw invalid5(`--dataset is a dash0 setting; a ${kind} source has none.`, ADD_HELP);
38061
+ }
38062
+ if (kind === "dash0")
38063
+ return dash0Body(name, host, flags, () => credentialsOf(kind));
37943
38064
  if (kind === "langfuse") {
37944
38065
  if (flags.openobserveOrg !== undefined || flags.stream !== undefined || flags.signal !== undefined) {
37945
38066
  throw invalid5("--openobserve-org, --stream and --signal are openobserve settings; a langfuse source has none.", ADD_HELP);
@@ -37948,7 +38069,7 @@ function buildSourceBody(kindArg, flags, credentialsOf) {
37948
38069
  return { kind, name, ...host === undefined ? {} : { host }, ...credentials === undefined ? {} : { credentials } };
37949
38070
  }
37950
38071
  if (host === undefined)
37951
- throw invalid5("An openobserve source needs --host (e.g. https://api.openobserve.ai).", `Run: ${SOURCES} add openobserve --host <url> …`);
38072
+ throw invalid5("An openobserve source needs --host (e.g. https://api.openobserve.ai).", `Run: ${SOURCES2} add openobserve --host <url> …`);
37952
38073
  const org = flags.openobserveOrg === undefined ? undefined : checkLength("--openobserve-org", flags.openobserveOrg, 128);
37953
38074
  const stream = flags.stream === undefined ? undefined : checkLength("--stream", flags.stream, 256);
37954
38075
  if (flags.signal !== undefined && !OPENOBSERVE_SIGNALS.includes(flags.signal)) {
@@ -37965,6 +38086,25 @@ function buildSourceBody(kindArg, flags, credentialsOf) {
37965
38086
  ...credentials === undefined ? {} : { credentials }
37966
38087
  };
37967
38088
  }
38089
+ function dash0Body(name, host, flags, credentialsOf) {
38090
+ if (flags.openobserveOrg !== undefined || flags.stream !== undefined || flags.signal !== undefined) {
38091
+ throw invalid5("--openobserve-org, --stream and --signal are openobserve settings; a dash0 source has --dataset.", ADD_HELP);
38092
+ }
38093
+ if (host === undefined) {
38094
+ throw invalid5("A dash0 source needs --host, the regional API URL (e.g. https://api.eu-west-1.aws.dash0.com).", `Run: ${SOURCES2} add dash0 --host <api url> …`);
38095
+ }
38096
+ if (flags.dataset !== undefined && !DASH0_DATASET.test(flags.dataset)) {
38097
+ throw invalid5('--dataset must be 3-26 letters, digits, "-" or "_".', "Pass the dataset name from Dash0 Settings → Datasets, or omit --dataset for the default.");
38098
+ }
38099
+ const credentials = credentialsOf();
38100
+ return {
38101
+ kind: "dash0",
38102
+ name,
38103
+ host,
38104
+ ...flags.dataset === undefined ? {} : { dataset: flags.dataset },
38105
+ ...credentials === undefined ? {} : { credentials }
38106
+ };
38107
+ }
37968
38108
  function instant(flag, value) {
37969
38109
  const ms = /^\d{4}-\d{2}-\d{2}/.test(value) ? Date.parse(value) : Number.NaN;
37970
38110
  if (Number.isNaN(ms))
@@ -38001,7 +38141,7 @@ function buildPullBody(flags) {
38001
38141
  function requireRemoveConsent(id, opts) {
38002
38142
  if (opts.force === true || opts.yes === true)
38003
38143
  return;
38004
- throw new MutagentError("CONFIRMATION_REQUIRED", `Removing trace source ${id} needs --force: its stored credentials, pulls and pulled traces are deleted.`, `Confirm with the user, then re-run: ${SOURCES} remove ${id} --force`);
38144
+ throw new MutagentError("CONFIRMATION_REQUIRED", `Removing trace source ${id} needs --force: its stored credentials, pulls and pulled traces are deleted.`, `Confirm with the user, then re-run: ${SOURCES2} remove ${id} --force`);
38005
38145
  }
38006
38146
  function isVirtualRow(raw) {
38007
38147
  if (raw === undefined)
@@ -38010,108 +38150,9 @@ function isVirtualRow(raw) {
38010
38150
  return raw.virtual;
38011
38151
  return raw.kind === "otlp";
38012
38152
  }
38013
- var READ_ONLY_CODE = "INTEGRATION_SOURCE_READ_ONLY";
38014
38153
  function readOnlyRefusal(id) {
38015
38154
  return new MutagentError(READ_ONLY_CODE, `${id} is OTLP ingest, a read-only source: OTLP traces arrive by push.`, "This row is derived from OTLP ingest: it lists while traces arrive and has nothing to rotate, test, pull or delete. " + "Its traces are already on the platform.");
38016
38155
  }
38017
- function testFailureWords(id, check, status) {
38018
- const http = status === undefined ? "" : ` (HTTP ${String(status)})`;
38019
- switch (check) {
38020
- case "credentials_refused":
38021
- return {
38022
- message: `The source refused the stored credentials${http}: check credentials_refused failed.`,
38023
- fix: `Get new keys from the source platform, then run: ${SOURCES} rotate ${id} … --secret-stdin`
38024
- };
38025
- case "unreachable":
38026
- return {
38027
- message: "The server could not reach the source host: check unreachable failed.",
38028
- fix: `Check the host is up and public (${SOURCES} list shows it); if it moved, remove the source and add it again.`
38029
- };
38030
- case "http_error":
38031
- return {
38032
- message: `The source answered with an error${http}: check http_error failed.`,
38033
- fix: "Check the source platform is healthy and the host is its API base URL, then test again."
38034
- };
38035
- case "invalid_response":
38036
- return {
38037
- message: "The host did not answer like the source platform: check invalid_response failed.",
38038
- fix: "Check --host is the platform API base URL (not a dashboard page), then remove and add the source again."
38039
- };
38040
- case "host_refused":
38041
- return {
38042
- message: "The source host resolves to an address the server may not call: check host_refused failed.",
38043
- fix: "Use the public URL of the trace platform: remove the source and add it with a public --host."
38044
- };
38045
- default:
38046
- return {
38047
- message: `The connection test failed${http}${check === undefined ? "" : `: check ${check} failed`}.`,
38048
- fix: `Run: ${SOURCES} test ${id} again; if it keeps failing, report it: mutagent feedback send --category bug -m "source test ${check ?? "failed"}"`
38049
- };
38050
- }
38051
- }
38052
-
38053
- class SourceTestFailedError extends MutagentError {
38054
- sourceId;
38055
- check;
38056
- httpStatus;
38057
- testedAt;
38058
- constructor(sourceId, check, httpStatus, testedAt) {
38059
- const words = testFailureWords(sourceId, check, httpStatus);
38060
- super("INTEGRATION_SOURCE_TEST_FAILED", words.message, words.fix);
38061
- this.sourceId = sourceId;
38062
- this.check = check;
38063
- this.httpStatus = httpStatus;
38064
- this.testedAt = testedAt;
38065
- }
38066
- toJSON() {
38067
- return {
38068
- ...super.toJSON(),
38069
- sourceId: this.sourceId,
38070
- check: this.check ?? null,
38071
- ...this.httpStatus === undefined ? {} : { status: this.httpStatus },
38072
- testedAt: this.testedAt
38073
- };
38074
- }
38075
- }
38076
- function defaultFix(code, ctx) {
38077
- const id = ctx.id ?? "<id>";
38078
- const pullId = ctx.pullId ?? "<pullId>";
38079
- switch (code) {
38080
- case "INTEGRATION_SOURCE_NOT_FOUND":
38081
- return `Run: ${SOURCES} list`;
38082
- case "INTEGRATION_PULL_NOT_FOUND":
38083
- return `Run: ${SOURCES} pulls ${id}`;
38084
- case "INTEGRATION_PULL_NOT_READY":
38085
- return `Wait for the pull to succeed: ${SOURCES} pull-get ${id} ${pullId}`;
38086
- case "INTEGRATION_PULL_RUNNING":
38087
- return `Wait for it to finish (${SOURCES} pulls ${id}), then start another.`;
38088
- case "INTEGRATION_SOURCE_NAME_TAKEN":
38089
- return `Pick another name with --name (${SOURCES} list shows the names in use).`;
38090
- case "INTEGRATION_SOURCE_CREDENTIALS_INVALID":
38091
- return `Pass the credentials the source's kind takes: ${SOURCES} rotate --help`;
38092
- case "INTEGRATION_SOURCE_CREDENTIALS_UNREADABLE":
38093
- return `Rotate the credentials, then test again: ${SOURCES} rotate ${id} … --secret-stdin`;
38094
- case "INTEGRATION_SOURCE_NOT_TESTABLE":
38095
- case READ_ONLY_CODE:
38096
- return "OTLP traces arrive by push; there is nothing to test, rotate, pull or delete.";
38097
- case "INTEGRATION_SOURCE_HOST_INVALID":
38098
- case "INTEGRATION_SOURCE_HOST_REFUSED":
38099
- return "Pass --host the public base URL of the platform, e.g. https://cloud.langfuse.com.";
38100
- case "INTEGRATION_PULL_WINDOW_INVALID":
38101
- return "Pass --since and --until as ISO-8601 times, --since first.";
38102
- case "INTEGRATION_SOURCE_ENCRYPTION_UNAVAILABLE":
38103
- case "INTEGRATION_PULL_STORE_UNAVAILABLE":
38104
- return "The server is not configured for this: the platform operator must fix it; nothing on this machine can. " + 'Tell the user, or report it: mutagent feedback send --category bug -m "<what failed>"';
38105
- default:
38106
- return `Run: ${SOURCES} --help`;
38107
- }
38108
- }
38109
- var OPERATOR_CODES = new Set(["INTEGRATION_SOURCE_ENCRYPTION_UNAVAILABLE", "INTEGRATION_PULL_STORE_UNAVAILABLE"]);
38110
- function fixFor(code, serverFix, ctx) {
38111
- if (OPERATOR_CODES.has(code))
38112
- return defaultFix(code, ctx);
38113
- return serverFix ?? defaultFix(code, ctx);
38114
- }
38115
38156
 
38116
38157
  // src/lib/integrations-api.ts
38117
38158
  init_config();
@@ -38321,7 +38362,7 @@ init_output();
38321
38362
  // src/commands/integrations/shared.ts
38322
38363
  init_errors();
38323
38364
  import { readFileSync as readFileSync24 } from "fs";
38324
- var SOURCES2 = "mutagent integrations sources";
38365
+ var SOURCES3 = "mutagent integrations sources";
38325
38366
  function isJsonMode2(command) {
38326
38367
  return Boolean(command.optsWithGlobals().json);
38327
38368
  }
@@ -38363,7 +38404,7 @@ async function findWritableSource(conn, id) {
38363
38404
  return found;
38364
38405
  }
38365
38406
  function sourceNotFound(id) {
38366
- return new MutagentError("INTEGRATION_SOURCE_NOT_FOUND", `No trace source ${id} in this workspace.`, `Run: ${SOURCES2} list`);
38407
+ return new MutagentError("INTEGRATION_SOURCE_NOT_FOUND", `No trace source ${id} in this workspace.`, `Run: ${SOURCES3} list`);
38367
38408
  }
38368
38409
  function readStdin2() {
38369
38410
  if (process.stdin.isTTY) {
@@ -38418,15 +38459,15 @@ function pullView(p) {
38418
38459
  function pullNext(id, p) {
38419
38460
  const status = p.status;
38420
38461
  if (status === "running") {
38421
- return { note: "Still running.", next: [`${SOURCES2} pull-get ${id} ${p.id} --json`] };
38462
+ return { note: "Still running.", next: [`${SOURCES3} pull-get ${id} ${p.id} --json`] };
38422
38463
  }
38423
38464
  if (status === "failed") {
38424
38465
  return {
38425
38466
  note: `Failed: ${p.errorCode ?? "no reason recorded"}. Test the source, then pull again.`,
38426
- next: [`${SOURCES2} test ${id} --json`, `${SOURCES2} pull ${id} --json`]
38467
+ next: [`${SOURCES3} test ${id} --json`, `${SOURCES3} pull ${id} --json`]
38427
38468
  };
38428
38469
  }
38429
- const read = [`${SOURCES2} pull-manifest ${id} ${p.id} --json`, `${SOURCES2} pull-traces ${id} ${p.id} --out traces.jsonl`];
38470
+ const read = [`${SOURCES3} pull-manifest ${id} ${p.id} --json`, `${SOURCES3} pull-traces ${id} ${p.id} --out traces.jsonl`];
38430
38471
  if (p.complete === false) {
38431
38472
  const why = p.truncated ? `truncated (${p.truncationCause ?? "cause not recorded"})` : "short of the source total";
38432
38473
  return { note: `Succeeded but incomplete: ${why}. Do not treat these traces as the whole window.`, next: read };
@@ -38436,9 +38477,9 @@ function pullNext(id, p) {
38436
38477
  function registerPull(sources) {
38437
38478
  sources.command("pull").description("Start a pull of a source's traces into UniTF on the server").argument("<id>", "The source id").option("--since <time>", "Window start, ISO-8601 (omit for open)").option("--until <time>", "Window end, ISO-8601 (omit for open)").option("--limit <n>", "At most this many traces, 1-5000 (server default 500)").option("--agent-name <name>", "Only traces of this agent").option("--session-id <id>", "Only traces of this session").option("--tag <tag>", "Only traces with this tag (repeatable, at most 20)", (v, acc = []) => [...acc, v]).addHelpText("after", `
38438
38479
  Examples:
38439
- ${chalk64.dim("$")} ${SOURCES2} pull src_123
38440
- ${chalk64.dim("$")} ${SOURCES2} pull src_123 --since 2026-09-01T00:00:00Z --until 2026-09-02T00:00:00Z --limit 1000
38441
- ${chalk64.dim("$")} ${SOURCES2} pull src_123 --agent-name support-bot --tag prod --tag eu --json
38480
+ ${chalk64.dim("$")} ${SOURCES3} pull src_123
38481
+ ${chalk64.dim("$")} ${SOURCES3} pull src_123 --since 2026-09-01T00:00:00Z --until 2026-09-02T00:00:00Z --limit 1000
38482
+ ${chalk64.dim("$")} ${SOURCES3} pull src_123 --agent-name support-bot --tag prod --tag eu --json
38442
38483
 
38443
38484
  Starts the pull and returns at once (status running). Poll it with pull-get; once it has
38444
38485
  succeeded, read pull-manifest and pull-traces. One running pull per source. A throttled or
@@ -38454,7 +38495,7 @@ AI Agent Directive:
38454
38495
  await findWritableSource(conn, id);
38455
38496
  const started = await conn.call((i) => i.startIntegrationSourcePull({ id, body }), { id });
38456
38497
  const links = pullLinks(id, started.id);
38457
- const next = [`${SOURCES2} pull-get ${id} ${started.id} --json`];
38498
+ const next = [`${SOURCES3} pull-get ${id} ${started.id} --json`];
38458
38499
  if (isJson) {
38459
38500
  const directive = sourceDirective({
38460
38501
  template: "integration_pull_started",
@@ -38475,8 +38516,8 @@ AI Agent Directive:
38475
38516
  function registerPulls(sources) {
38476
38517
  sources.command("pulls").description("A source's pulls, newest first (at most 50; kept 90 days)").argument("<id>", "The source id").addHelpText("after", `
38477
38518
  Examples:
38478
- ${chalk64.dim("$")} ${SOURCES2} pulls src_123
38479
- ${chalk64.dim("$")} ${SOURCES2} pulls src_123 --json
38519
+ ${chalk64.dim("$")} ${SOURCES3} pulls src_123
38520
+ ${chalk64.dim("$")} ${SOURCES3} pulls src_123 --json
38480
38521
 
38481
38522
  AI Agent Directive:
38482
38523
  Reading is free. --json returns { pulls, count }.
@@ -38490,7 +38531,7 @@ AI Agent Directive:
38490
38531
  return;
38491
38532
  }
38492
38533
  if (list.items.length === 0) {
38493
- console.log(chalk64.gray(`No pulls. Start one: ${SOURCES2} pull ${id}`));
38534
+ console.log(chalk64.gray(`No pulls. Start one: ${SOURCES3} pull ${id}`));
38494
38535
  return;
38495
38536
  }
38496
38537
  new OutputFormatter("table").output(list.items.map((p) => ({
@@ -38506,8 +38547,8 @@ AI Agent Directive:
38506
38547
  function registerPullGet(sources) {
38507
38548
  sources.command("pull-get").description("One pull: its status, counts and coverage").argument("<id>", "The source id").argument("<pullId>", "The pull id (from pull or pulls)").addHelpText("after", `
38508
38549
  Examples:
38509
- ${chalk64.dim("$")} ${SOURCES2} pull-get src_123 pull_456
38510
- ${chalk64.dim("$")} ${SOURCES2} pull-get src_123 pull_456 --json
38550
+ ${chalk64.dim("$")} ${SOURCES3} pull-get src_123 pull_456
38551
+ ${chalk64.dim("$")} ${SOURCES3} pull-get src_123 pull_456 --json
38511
38552
 
38512
38553
  AI Agent Directive:
38513
38554
  Reading is free: poll it while status is running. --json returns { pull, note, next, _links }.
@@ -38535,8 +38576,8 @@ AI Agent Directive:
38535
38576
  function registerPullManifest(sources) {
38536
38577
  sources.command("pull-manifest").description("A pull's unitf@0.1 manifest: what the JSONL holds and how completely").argument("<id>", "The source id").argument("<pullId>", "The pull id").addHelpText("after", `
38537
38578
  Examples:
38538
- ${chalk64.dim("$")} ${SOURCES2} pull-manifest src_123 pull_456
38539
- ${chalk64.dim("$")} ${SOURCES2} pull-manifest src_123 pull_456 --json
38579
+ ${chalk64.dim("$")} ${SOURCES3} pull-manifest src_123 pull_456
38580
+ ${chalk64.dim("$")} ${SOURCES3} pull-manifest src_123 pull_456 --json
38540
38581
 
38541
38582
  Available once the pull has succeeded (INTEGRATION_PULL_NOT_READY before).
38542
38583
 
@@ -38609,8 +38650,8 @@ var stdoutSink = {
38609
38650
  function registerPullTraces(sources) {
38610
38651
  sources.command("pull-traces").description("Stream a pull's UniTF JSONL to stdout, or to a file with --out").argument("<id>", "The source id").argument("<pullId>", "The pull id").option("-o, --out <file>", "Write the JSONL to this file instead of stdout").addHelpText("after", `
38611
38652
  Examples:
38612
- ${chalk64.dim("$")} ${SOURCES2} pull-traces src_123 pull_456 > traces.jsonl
38613
- ${chalk64.dim("$")} ${SOURCES2} pull-traces src_123 pull_456 --out traces.jsonl --json
38653
+ ${chalk64.dim("$")} ${SOURCES3} pull-traces src_123 pull_456 > traces.jsonl
38654
+ ${chalk64.dim("$")} ${SOURCES3} pull-traces src_123 pull_456 --out traces.jsonl --json
38614
38655
 
38615
38656
  One UniTF 0.1 trace per line, streamed as it arrives. Available once the pull has succeeded.
38616
38657
  --json: without --out, stdout is the JSONL unchanged (each line is already JSON; nothing
@@ -38672,7 +38713,7 @@ function shellQuote3(value) {
38672
38713
  return `'${value.replace(/'/g, `'\\''`)}'`;
38673
38714
  }
38674
38715
  function rerunCommand(body) {
38675
- const parts = [`${SOURCES2} add ${shellQuote3(String(body.kind))}`, `--name ${shellQuote3(String(body.name))}`];
38716
+ const parts = [`${SOURCES3} add ${shellQuote3(String(body.kind))}`, `--name ${shellQuote3(String(body.name))}`];
38676
38717
  if (typeof body.host === "string")
38677
38718
  parts.push(`--host ${shellQuote3(body.host)}`);
38678
38719
  if (typeof body.org === "string")
@@ -38681,6 +38722,8 @@ function rerunCommand(body) {
38681
38722
  parts.push(`--stream ${shellQuote3(body.stream)}`);
38682
38723
  if (typeof body.signal === "string")
38683
38724
  parts.push(`--signal ${shellQuote3(body.signal)}`);
38725
+ if (typeof body.dataset === "string")
38726
+ parts.push(`--dataset ${shellQuote3(body.dataset)}`);
38684
38727
  return parts.join(" ");
38685
38728
  }
38686
38729
  function printSecretRequired(isJson, detail, rerun) {
@@ -38712,7 +38755,7 @@ function secretInputs(flags) {
38712
38755
  return inputs;
38713
38756
  }
38714
38757
  function addCredentialOptions(cmd) {
38715
- return cmd.option("--public-key <key>", "langfuse: the public key (pk-lf-…)").option("--secret-key <key>", "langfuse: the secret key (sk-lf-…); prefer --secret-stdin or --secret-env").option("--email <email>", "openobserve: the user email, with a password").option("--password <password>", "openobserve: the password for --email; prefer --secret-stdin or --secret-env").option("--token <token>", 'openobserve: an issued token ("Basic …", "Bearer …" or base64), instead of --email').option("--secret-env <VAR>", "Read the kind's secret (secret key, password or token) from this environment variable").option("--secret-stdin", "Read the kind's secret from stdin (a trailing newline is dropped)");
38758
+ return cmd.option("--public-key <key>", "langfuse: the public key (pk-lf-…)").option("--secret-key <key>", "langfuse: the secret key (sk-lf-…); prefer --secret-stdin or --secret-env").option("--email <email>", "openobserve: the user email, with a password").option("--password <password>", "openobserve: the password for --email; prefer --secret-stdin or --secret-env").option("--token <token>", 'openobserve: an issued token ("Basic …", "Bearer …" or base64), instead of --email; dash0: the auth token (auth_…)').option("--secret-env <VAR>", "Read the kind's secret (secret key, password or token) from this environment variable").option("--secret-stdin", "Read the kind's secret from stdin (a trailing newline is dropped)");
38716
38759
  }
38717
38760
  function row4(s) {
38718
38761
  const lastTest = s.readOnly ? s.ingest ? `latest trace ${s.ingest.latestTraceAt}` : "—" : s.lastTest ? `${s.lastTest.outcome}${s.lastTest.code ? ` (${s.lastTest.code})` : ""}` : "never";
@@ -38727,8 +38770,8 @@ function row4(s) {
38727
38770
  function registerList8(sources) {
38728
38771
  sources.command("list").alias("ls").description("Trace sources in the workspace, newest first").addHelpText("after", `
38729
38772
  Examples:
38730
- ${chalk66.dim("$")} ${SOURCES2} list
38731
- ${chalk66.dim("$")} ${SOURCES2} list --json
38773
+ ${chalk66.dim("$")} ${SOURCES3} list
38774
+ ${chalk66.dim("$")} ${SOURCES3} list --json
38732
38775
 
38733
38776
  Credentials are never returned; each source names its current ones by credentialRef.
38734
38777
  A row marked read-only is OTLP ingest: it lists while OTLP traces arrive (latest trace
@@ -38746,7 +38789,7 @@ AI Agent Directive:
38746
38789
  return;
38747
38790
  }
38748
38791
  if (all.length === 0) {
38749
- console.log(chalk66.gray(`No trace sources. Connect one: ${SOURCES2} add langfuse --name <name> --public-key <pk> --secret-stdin`));
38792
+ console.log(chalk66.gray(`No trace sources. Connect one: ${SOURCES3} add langfuse --name <name> --public-key <pk> --secret-stdin`));
38750
38793
  return;
38751
38794
  }
38752
38795
  new OutputFormatter("table").output(all.map(row4));
@@ -38754,18 +38797,20 @@ AI Agent Directive:
38754
38797
  });
38755
38798
  }
38756
38799
  function registerAdd(sources) {
38757
- addCredentialOptions(sources.command("add").description("Connect a Langfuse or OpenObserve trace source (credentials are write-only)").argument("<kind>", "langfuse | openobserve").option("--name <name>", "A name, unique in the workspace (1-100 characters)").option("--host <url>", "Base URL: langfuse default https://cloud.langfuse.com; required for openobserve").option("--openobserve-org <org>", `openobserve: organization id, the model's org (default "default"); not the global --org`).option("--stream <stream>", 'openobserve: stream name (default "default")').option("--signal <signal>", "openobserve: events | spans (omit to detect it from the rows)")).addHelpText("after", `
38800
+ addCredentialOptions(sources.command("add").description("Connect a Langfuse, OpenObserve or Dash0 trace source (credentials are write-only)").argument("<kind>", "langfuse | openobserve | dash0").option("--name <name>", "A name, unique in the workspace (1-100 characters)").option("--host <url>", "Base URL: langfuse default https://cloud.langfuse.com; required for openobserve; dash0: the regional API URL").option("--openobserve-org <org>", `openobserve: organization id, the model's org (default "default"); not the global --org`).option("--stream <stream>", 'openobserve: stream name (default "default")').option("--signal <signal>", "openobserve: events | spans (omit to detect it from the rows)").option("--dataset <dataset>", "dash0: the dataset to read (omit for the organization's default)")).addHelpText("after", `
38758
38801
  Examples:
38759
- ${chalk66.dim("$")} pass show langfuse/sk | ${SOURCES2} add langfuse --name prod --public-key pk-lf-… --secret-stdin
38760
- ${chalk66.dim("$")} ${SOURCES2} add langfuse --name self-hosted --host https://langfuse.example.com --public-key pk-lf-… --secret-env LANGFUSE_SECRET_KEY
38761
- ${chalk66.dim("$")} ${SOURCES2} add openobserve --name oo --host https://api.openobserve.ai --openobserve-org acme --email ops@acme.com --secret-stdin
38762
- ${chalk66.dim("$")} ${SOURCES2} add openobserve --name oo --host http://oo.internal.example:5080 --secret-env OO_TOKEN --json
38763
-
38764
- The secret (langfuse secret key; openobserve password with --email, or token without) comes
38802
+ ${chalk66.dim("$")} pass show langfuse/sk | ${SOURCES3} add langfuse --name prod --public-key pk-lf-… --secret-stdin
38803
+ ${chalk66.dim("$")} ${SOURCES3} add langfuse --name self-hosted --host https://langfuse.example.com --public-key pk-lf-… --secret-env LANGFUSE_SECRET_KEY
38804
+ ${chalk66.dim("$")} ${SOURCES3} add openobserve --name oo --host https://api.openobserve.ai --openobserve-org acme --email ops@acme.com --secret-stdin
38805
+ ${chalk66.dim("$")} ${SOURCES3} add openobserve --name oo --host http://oo.internal.example:5080 --secret-env OO_TOKEN --json
38806
+ ${chalk66.dim("$")} ${SOURCES3} add dash0 --name dash0 --host https://api.eu-west-1.aws.dash0.com --dataset production --secret-env DASH0_AUTH_TOKEN
38807
+
38808
+ The secret (langfuse secret key; openobserve password with --email, or token without; dash0
38809
+ auth token, from Settings → Auth Tokens, with --host from Settings → Endpoints → API) comes
38765
38810
  from its flag, from --secret-env <VAR>, or from stdin with --secret-stdin: exactly one. A flag
38766
38811
  leaves it in your shell history. Credentials are write-only: no output ever shows them.
38767
38812
  The host must be a public http(s) base URL. OTLP traces arrive by push; there is no otlp kind to add.
38768
- Next: ${SOURCES2} test <id>.
38813
+ Next: ${SOURCES3} test <id>.
38769
38814
 
38770
38815
  In a cloud sandbox:
38771
38816
  Keys never go through the session: every key option (--public-key, --secret-key,
@@ -38801,7 +38846,7 @@ ${WRITE_DIRECTIVE}
38801
38846
  return;
38802
38847
  }
38803
38848
  const links = sourceLinks(view.id);
38804
- const next = [`${SOURCES2} test ${view.id} --json`, `${SOURCES2} pull ${view.id} --json`];
38849
+ const next = [`${SOURCES3} test ${view.id} --json`, `${SOURCES3} pull ${view.id} --json`];
38805
38850
  if (isJson) {
38806
38851
  const directive = sourceDirective({ template: "integration_source_added", title: `Trace Source Added — ${view.name}`, fields: sourceFields(view), links, next });
38807
38852
  new OutputFormatter("json").output({ success: true, source: view, _links: links, _directive: directive });
@@ -38809,7 +38854,7 @@ ${WRITE_DIRECTIVE}
38809
38854
  return;
38810
38855
  }
38811
38856
  console.log(chalk66.green(`✓ Added ${view.kind} source ${view.name} (id: ${view.id})`));
38812
- console.log(` Next: ${SOURCES2} test ${view.id}`);
38857
+ console.log(` Next: ${SOURCES3} test ${view.id}`);
38813
38858
  });
38814
38859
  });
38815
38860
  }
@@ -38824,8 +38869,8 @@ async function createSource(body, sandbox) {
38824
38869
  function registerRemove(sources) {
38825
38870
  sources.command("remove").description("Delete a trace source, its credentials, its pulls and their output").argument("<id>", "The source id (from list)").option("-f, --force", "Required: confirms the delete (every mode; there is no prompt)").option("-y, --yes", "Same as --force").addHelpText("after", `
38826
38871
  Examples:
38827
- ${chalk66.dim("$")} ${SOURCES2} remove src_123 --force
38828
- ${chalk66.dim("$")} ${SOURCES2} remove src_123 --force --json
38872
+ ${chalk66.dim("$")} ${SOURCES3} remove src_123 --force
38873
+ ${chalk66.dim("$")} ${SOURCES3} remove src_123 --force --json
38829
38874
 
38830
38875
  Destructive: without -f/--force (or --yes) it refuses and sends nothing, in a terminal
38831
38876
  or not, with --json or not. There is no confirmation prompt. Removing a source that is
@@ -38847,7 +38892,7 @@ AI Agent Directive:
38847
38892
  title: `Trace Source Removed — ${id}`,
38848
38893
  fields: { sourceId: id },
38849
38894
  links,
38850
- next: [`${SOURCES2} list --json`]
38895
+ next: [`${SOURCES3} list --json`]
38851
38896
  });
38852
38897
  new OutputFormatter("json").output({ success: true, removedId: id, _links: links, _directive: directive });
38853
38898
  echoDirectiveToStderr(directive);
@@ -38860,8 +38905,8 @@ AI Agent Directive:
38860
38905
  function registerTest2(sources) {
38861
38906
  sources.command("test").description("Test a source's connection with its stored credentials").argument("<id>", "The source id").addHelpText("after", `
38862
38907
  Examples:
38863
- ${chalk66.dim("$")} ${SOURCES2} test src_123
38864
- ${chalk66.dim("$")} ${SOURCES2} test src_123 --json
38908
+ ${chalk66.dim("$")} ${SOURCES3} test src_123
38909
+ ${chalk66.dim("$")} ${SOURCES3} test src_123 --json
38865
38910
 
38866
38911
  One authenticated request from the server to the source; the outcome is recorded as the
38867
38912
  source's last test. A failed test exits 1 and names the check that failed:
@@ -38900,14 +38945,15 @@ In a cloud sandbox:
38900
38945
  function registerRotate(sources) {
38901
38946
  addCredentialOptions(sources.command("rotate").description("Replace a source's credentials (the key version goes up, the last test is cleared)").argument("<id>", "The source id")).addHelpText("after", `
38902
38947
  Examples:
38903
- ${chalk66.dim("$")} pass show langfuse/sk | ${SOURCES2} rotate src_123 --public-key pk-lf-… --secret-stdin
38904
- ${chalk66.dim("$")} ${SOURCES2} rotate src_456 --secret-env OO_TOKEN --json
38905
- ${chalk66.dim("$")} ${SOURCES2} rotate src_456 --email ops@acme.com --secret-stdin
38948
+ ${chalk66.dim("$")} pass show langfuse/sk | ${SOURCES3} rotate src_123 --public-key pk-lf-… --secret-stdin
38949
+ ${chalk66.dim("$")} ${SOURCES3} rotate src_456 --secret-env OO_TOKEN --json
38950
+ ${chalk66.dim("$")} ${SOURCES3} rotate src_456 --email ops@acme.com --secret-stdin
38906
38951
 
38907
38952
  Takes the credentials the source's kind takes (it reads the source's kind first): langfuse
38908
- --public-key and a secret key; openobserve --email and a password, or a token. The secret
38953
+ --public-key and a secret key; openobserve --email and a password, or a token; dash0 an auth
38954
+ token. The secret
38909
38955
  comes from its flag, --secret-env <VAR> or --secret-stdin. Credentials are write-only.
38910
- Next: ${SOURCES2} test <id>.
38956
+ Next: ${SOURCES3} test <id>.
38911
38957
 
38912
38958
  ${WRITE_DIRECTIVE}
38913
38959
  `).action(async (id, flags, command) => {
@@ -38923,7 +38969,7 @@ ${WRITE_DIRECTIVE}
38923
38969
  const rotated = await conn.call((i) => i.rotateIntegrationSourceCredentials({ id, body: { credentials } }), { id });
38924
38970
  const view = sourceView(rotated, undefined);
38925
38971
  const links = sourceLinks(id);
38926
- const next = [`${SOURCES2} test ${id} --json`];
38972
+ const next = [`${SOURCES3} test ${id} --json`];
38927
38973
  if (isJson) {
38928
38974
  const directive = sourceDirective({ template: "integration_source_rotated", title: `Credentials Rotated — ${view.name}`, fields: sourceFields(view), links, next });
38929
38975
  new OutputFormatter("json").output({ success: true, source: view, _links: links, _directive: directive });
@@ -38931,7 +38977,7 @@ ${WRITE_DIRECTIVE}
38931
38977
  return;
38932
38978
  }
38933
38979
  console.log(chalk66.green(`✓ Rotated the credentials of ${view.name} (key version ${String(view.keyVersion)})`));
38934
- console.log(` Next: ${SOURCES2} test ${id}`);
38980
+ console.log(` Next: ${SOURCES3} test ${id}`);
38935
38981
  });
38936
38982
  });
38937
38983
  }
@@ -38946,21 +38992,21 @@ function registerSourceVerbs(sources) {
38946
38992
  // src/commands/integrations/index.ts
38947
38993
  init_errors();
38948
38994
  function createSourcesCommand() {
38949
- const sources = new Command27("sources").description("Trace sources (Langfuse, OpenObserve): connect, test, rotate, and pull traces into UniTF");
38995
+ const sources = new Command27("sources").description("Trace sources (Langfuse, OpenObserve, Dash0): connect, test, rotate, and pull traces into UniTF");
38950
38996
  registerSourceVerbs(sources);
38951
38997
  registerPullVerbs(sources);
38952
38998
  sources.addHelpText("after", `
38953
38999
  Examples:
38954
- ${chalk67.dim("$")} ${SOURCES2} list
38955
- ${chalk67.dim("$")} pass show langfuse/sk | ${SOURCES2} add langfuse --name prod --public-key pk-lf-… --secret-stdin
38956
- ${chalk67.dim("$")} ${SOURCES2} test <id>
38957
- ${chalk67.dim("$")} ${SOURCES2} rotate <id> --public-key pk-lf-… --secret-env LANGFUSE_SECRET_KEY
38958
- ${chalk67.dim("$")} ${SOURCES2} remove <id> --force
38959
- ${chalk67.dim("$")} ${SOURCES2} pull <id> [--since <iso>] [--until <iso>] [--limit <n>] [--agent-name <n>] [--session-id <s>] [--tag <t>]…
38960
- ${chalk67.dim("$")} ${SOURCES2} pulls <id>
38961
- ${chalk67.dim("$")} ${SOURCES2} pull-get <id> <pullId>
38962
- ${chalk67.dim("$")} ${SOURCES2} pull-manifest <id> <pullId>
38963
- ${chalk67.dim("$")} ${SOURCES2} pull-traces <id> <pullId> [--out <file>]
39000
+ ${chalk67.dim("$")} ${SOURCES3} list
39001
+ ${chalk67.dim("$")} pass show langfuse/sk | ${SOURCES3} add langfuse --name prod --public-key pk-lf-… --secret-stdin
39002
+ ${chalk67.dim("$")} ${SOURCES3} test <id>
39003
+ ${chalk67.dim("$")} ${SOURCES3} rotate <id> --public-key pk-lf-… --secret-env LANGFUSE_SECRET_KEY
39004
+ ${chalk67.dim("$")} ${SOURCES3} remove <id> --force
39005
+ ${chalk67.dim("$")} ${SOURCES3} pull <id> [--since <iso>] [--until <iso>] [--limit <n>] [--agent-name <n>] [--session-id <s>] [--tag <t>]…
39006
+ ${chalk67.dim("$")} ${SOURCES3} pulls <id>
39007
+ ${chalk67.dim("$")} ${SOURCES3} pull-get <id> <pullId>
39008
+ ${chalk67.dim("$")} ${SOURCES3} pull-manifest <id> <pullId>
39009
+ ${chalk67.dim("$")} ${SOURCES3} pull-traces <id> <pullId> [--out <file>]
38964
39010
 
38965
39011
  Credentials are write-only: they are stored encrypted and no command ever prints them.
38966
39012
  A secret comes from its flag, from --secret-env <VAR>, or from stdin with --secret-stdin.
@@ -38970,12 +39016,12 @@ or 'mutagent workspaces use'.
38970
39016
  ${EXIT_CODES_LINE}
38971
39017
 
38972
39018
  AI Agent Directive:
38973
- 1. Read first: '${SOURCES2} list --json'. Reads need no confirmation.
39019
+ 1. Read first: '${SOURCES3} list --json'. Reads need no confirmation.
38974
39020
  2. add, rotate, remove and pull are writes: confirm with the user, then run them
38975
39021
  (remove with --force).
38976
39022
  3. Never ask the user to paste a secret into the chat. Have them run the command in
38977
39023
  their own terminal with --secret-stdin (piped) or --secret-env <VAR>.
38978
- 4. Before trusting pulled traces, check '${SOURCES2} pull-manifest <id> <pullId> --json'
39024
+ 4. Before trusting pulled traces, check '${SOURCES3} pull-manifest <id> <pullId> --json'
38979
39025
  coverage.complete.
38980
39026
  5. On an error, run the command in suggestedAction once; never retry blind. When the
38981
39027
  fix names the platform operator, tell the user: it cannot be fixed from here.
@@ -38987,17 +39033,17 @@ function createIntegrationsCommand() {
38987
39033
  integrations.addCommand(createSourcesCommand());
38988
39034
  integrations.addHelpText("after", `
38989
39035
  Groups:
38990
- sources Trace sources (Langfuse, OpenObserve) and pulls of their traces into UniTF
39036
+ sources Trace sources (Langfuse, OpenObserve, Dash0) and pulls of their traces into UniTF
38991
39037
 
38992
39038
  Deploy targets are not available yet: the platform has not built them, so there is no
38993
39039
  command for them. Messaging (GitHub, Slack, events, runs) lives in 'mutagent gateway'.
38994
39040
 
38995
39041
  Examples:
38996
- ${chalk67.dim("$")} ${SOURCES2} list
38997
- ${chalk67.dim("$")} ${SOURCES2} --help
39042
+ ${chalk67.dim("$")} ${SOURCES3} list
39043
+ ${chalk67.dim("$")} ${SOURCES3} --help
38998
39044
 
38999
39045
  AI Agent Directive:
39000
- Start with '${SOURCES2} list --json'. Do not look for a targets command; there is none yet.
39046
+ Start with '${SOURCES3} list --json'. Do not look for a targets command; there is none yet.
39001
39047
  `);
39002
39048
  return integrations;
39003
39049
  }
@@ -44627,4 +44673,4 @@ if (process.env.CLI_VERSION) {
44627
44673
  }
44628
44674
  runCli(process.argv.slice(2), cliVersion);
44629
44675
 
44630
- //# debugId=BBE3EBCBEECE0C5A64756E2164756E21
44676
+ //# debugId=B287580A222D152F64756E2164756E21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mutagent/cli",
3
- "version": "0.2.186",
3
+ "version": "0.2.187",
4
4
  "description": "Bun-native CLI for the MutagenT AI platform - auth, provider config, and lifecycle-tool installer for AI-native workflows",
5
5
  "type": "module",
6
6
  "bin": {
@@ -94,5 +94,5 @@
94
94
  "bugs": {
95
95
  "url": "https://docs.mutagent.io/support"
96
96
  },
97
- "gitHead": "218a081952a0e9fa2990715980a549cc0d49969b"
97
+ "gitHead": "c93c4ae6a70e14b434b2539724baa9fc64830ab6"
98
98
  }