@duvoai/cli 1.77.2 → 1.78.0

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/duvo.js +125 -12
  2. package/package.json +1 -1
package/dist/bin/duvo.js CHANGED
@@ -34338,9 +34338,6 @@ var adminOrgAddDomainRequestSchema = z71.object({
34338
34338
  var adminOrgAddDomainResponseSchema = z71.object({
34339
34339
  domain: adminOrgDomainSchema
34340
34340
  });
34341
- var adminOrgAssignTeamRequestSchema = z71.object({
34342
- teamId: z71.guid()
34343
- });
34344
34341
  var adminOrgAddMemberRequestSchema = z71.object({
34345
34342
  userId: z71.guid(),
34346
34343
  role: z71.enum(ORG_ROLES2.ALL)
@@ -38521,6 +38518,7 @@ var FEATURE_FLAG_CATALOGUE = {
38521
38518
  AGENT_BUILDER_ASK_DUVO: {
38522
38519
  key: "agent_builder_ask_duvo",
38523
38520
  defaultValue: false,
38521
+ implies: ["agent_chat"],
38524
38522
  description: "Routes the Agent Builder prompt input through Ask Duvo instead of building the AOP inline: the welcome hero and the config-editor composer hand their prompt to a fresh Ask Duvo chat that continues the conversation, and the builder input hides itself once handed off. When off, both inputs keep generating and editing the AOP in place. Requires AGENT_CHAT \u2014 the handoff needs the chat surface to land in, so with AGENT_CHAT off this flag does nothing. Separate from AGENT_CHAT so the builder handoff can roll out independently of the rest of Ask Duvo. Off by default for staged rollout."
38525
38523
  },
38526
38524
  BROWSING_RECORDING_SCREENSHOTS: {
@@ -38536,11 +38534,13 @@ var FEATURE_FLAG_CATALOGUE = {
38536
38534
  AGENT_CHAT_UI_RESOURCES: {
38537
38535
  key: "agent_chat_ui_resources",
38538
38536
  defaultValue: false,
38537
+ implies: ["agent_chat"],
38539
38538
  description: "Renders interactive UI-resource preview cards (MCP Apps) in the Ask Duvo transcript \u2014 v1: the Pulse dashboard preview on artifact-applied notices, shown in a sandboxed opaque-origin iframe. Frontend render gate only: snapshot capture and persistence (the transport layer) run regardless, so flipping this on needs no backfill. Off-by-default for staged rollout to internal teams first."
38540
38539
  },
38541
38540
  AGENT_CHAT_V2: {
38542
38541
  key: "agent_chat_v2",
38543
38542
  defaultValue: false,
38543
+ implies: ["agent_chat"],
38544
38544
  description: "Ask Duvo v2 runtime: duvo CLI tool surface via a managed cross-team user-scoped API key, replacing the public-API MCP server \u2014 see specs/ask-duvo-cli-tools/PLAN.md"
38545
38545
  },
38546
38546
  CASE_SCHEMA: {
@@ -38571,6 +38571,7 @@ var FEATURE_FLAG_CATALOGUE = {
38571
38571
  AUTOMATION_VERSIONING: {
38572
38572
  key: "automation_versioning",
38573
38573
  defaultValue: false,
38574
+ implies: ["automations"],
38574
38575
  description: "Makes the Automations migration convert straight to revision semantics instead of the lite workspace. When off (the default), POST /automations/migrate writes automation containers only and stamps team.automations_migrated_at; when on, it also snapshots each automation's current live builds, queue routing, trigger configs and recurring schedules as revision 1 and stamps team.automation_revisions_migrated_at. Only applies to a team that is still standalone \u2014 it is not the lite-to-versioned cutover, which resolves its groups from existing automation membership rather than by closure discovery. Resolved by team/org (user-level overrides are ignored by the migration gate), and only consulted for a team that also has AUTOMATIONS on."
38575
38576
  },
38576
38577
  AGENT_QUEUE_DETAIL_REDESIGN: {
@@ -38746,6 +38747,7 @@ var FEATURE_FLAG_CATALOGUE = {
38746
38747
  META_AGENT_ARTIFACTS: {
38747
38748
  key: "meta_agent_artifacts",
38748
38749
  defaultValue: false,
38750
+ implies: ["agent_chat"],
38749
38751
  description: "Enables Ask Duvo Artifacts \u2014 Ask Duvo binds to the artifact on the current page and can create/edit it (Pulse first). When disabled, chat sends carry no structured page context, the duvoChat Pulse tools refuse, and the artifact endpoints return 404. The `meta_agent_artifacts` key is the legacy name kept deliberately: renaming a flag key orphans its per-team overrides."
38750
38752
  },
38751
38753
  MINUTE_SCHEDULING: {
@@ -38796,6 +38798,7 @@ var FEATURE_FLAG_CATALOGUE = {
38796
38798
  PULSE_EDIT_IN_ASK_DUVO: {
38797
38799
  key: "pulse_edit_in_ask_duvo",
38798
38800
  defaultValue: false,
38801
+ implies: ["agent_chat", "meta_agent_artifacts"],
38799
38802
  description: "Routes Pulse through Ask Duvo instead of the native Pulse chat panel. Covers both halves of a dashboard's life. Editing: clicking 'Edit in chat' opens the Ask Duvo rail bound to the dashboard (so the agent can edit it and prior Pulse chat messages surface in-rail); with the flag off the button toggles the native in-page Pulse chat panel as before. Creating: submitting a prompt on the New Pulse page opens an Ask Duvo conversation whose first message is that prompt and whose hidden companion turn makes the agent build the dashboard immediately, so the build narrates in the conversation instead of in silence; with the flag off New Pulse creates the dashboard directly and lands on its canvas. Text-only submissions take the Ask Duvo path \u2014 a submission carrying file attachments always creates directly, since the in-chat create tool cannot carry them. Requires META_AGENT_ARTIFACTS (which registers the in-chat create/edit tools; without it the agent falls back to the public createPulseDashboard tool and produces a dashboard with no binding and no in-chat progress) and AGENT_CHAT (the surface the conversation lands in). Off-by-default for staged rollout."
38800
38803
  },
38801
38804
  PULSE_OPENUI: {
@@ -38811,6 +38814,11 @@ var FEATURE_FLAG_CATALOGUE = {
38811
38814
  FREIGHT_MODULE: {
38812
38815
  key: "freight_module",
38813
38816
  defaultValue: false,
38817
+ // The hard gate on the surface is `team.automations_migrated_at`, and
38818
+ // AUTOMATIONS is the flag that exposes the migration producing that
38819
+ // stamp: a team without it has no workspace for a Module to install
38820
+ // into, so turning this on alone leaves the surface unreachable.
38821
+ implies: ["automations"],
38814
38822
  description: "Per-team opt-in for the Freight Audit Module. Gates the Automation Modules surface: the 'Modules' entry at the top of the Process Automation sidebar section, the /teams/:teamId/modules page (which lists the Freight Audit module), and the module surfaces on the Automation detail page \u2014 an automation whose name matches a catalog module (currently 'Freight Audit') gets a 'Setup' tab with the static module overview, a 'Modules / {name}' breadcrumb, a 'Demo' badge, and a setup CTA in place of the revision switcher. When off, the nav entry is hidden, the page returns 404, and the detail page renders as a plain automation (a ?tab=setup deep link falls back to General). The surface additionally requires the team to be on the Automations workspace (`automations_migrated_at` stamped) \u2014 `lite` or `versioned`, since a Module installs into an automation and the installer writes the owning automation in whichever shape the team's model holds; for a standalone team the nav entry is hidden and the page redirects to Agents even with the flag on. Also gates the Ask Duvo card on Pulse dashboards: the generator may render a `[data-duvo-ask]` card whose submitted question opens Ask Duvo in the side panel on a fresh chat. When OFF, the frame strips any such card out of the dashboard before writing it in and the parent bridge is inert, so a dashboard built with a card renders without one rather than showing a control that does nothing. The card additionally requires AGENT_CHAT, since a question has nowhere to go without Ask Duvo. Also switches the Ask Duvo transcript to its business-clean reading experience: every consecutive tool call in a turn \u2014 including a subagent delegation and the subagent's own calls \u2014 folds into a single collapsed 'Duvo took N steps' row that expands on click into the individual tool cards, in place of the per-tool rows (and the nested delegation card) shown otherwise. Frontend-only and purely presentational: the running tool still surfaces as the activity-line verb, and turning the flag off restores the per-tool transcript with no data change. Off by default for staged rollout."
38815
38823
  },
38816
38824
  AUTOMATIONS_TO_MODULES: {
@@ -38821,6 +38829,7 @@ var FEATURE_FLAG_CATALOGUE = {
38821
38829
  MODULE_SOLUTIONS_GALLERY: {
38822
38830
  key: "module_solutions_gallery",
38823
38831
  defaultValue: false,
38832
+ implies: ["freight_module"],
38824
38833
  description: "Per-team opt-in for the Module Solutions gallery \u2014 the Explore section's 'Module Solutions' entry and the /teams/:teamId/solutions page, which lays the module catalog out as the supply-chain value chain. Exists for demoing our modules vision: the catalog is mostly placeholder modules mapping out the chain rather than wired surfaces, so it is shown to the teams a demo is being given to and nobody else. When off (default), the Explore section is hidden in the sidebar, the entry drops out of the command palette, and the page returns 404; a module's own /teams/:teamId/modules/:slug workspace is unaffected and keeps answering to FREIGHT_MODULE. Requires FREIGHT_MODULE and the team being on the Automations workspace (`automations_migrated_at` stamped) for the same reason the modules surface does \u2014 a Module installs into an automation, so a team with no workspace has nowhere to put one."
38825
38834
  },
38826
38835
  AUTOMATION_RUN_TOASTS: {
@@ -38867,6 +38876,104 @@ var FEATURE_FLAG_DESCRIPTIONS = Object.fromEntries(
38867
38876
  entry.description
38868
38877
  ])
38869
38878
  );
38879
+ var FEATURE_FLAG_IMPLICATIONS = (() => {
38880
+ const implications = {};
38881
+ for (const entry of Object.values(FEATURE_FLAG_CATALOGUE)) {
38882
+ implications[entry.key] = "implies" in entry ? [...entry.implies] : [];
38883
+ }
38884
+ return implications;
38885
+ })();
38886
+ var FEATURE_FLAG_IMPLIED_BY = (() => {
38887
+ const impliedBy = {};
38888
+ for (const flagKey of Object.keys(
38889
+ FEATURE_FLAG_IMPLICATIONS
38890
+ )) {
38891
+ impliedBy[flagKey] = [];
38892
+ }
38893
+ for (const [flagKey, implied] of Object.entries(
38894
+ FEATURE_FLAG_IMPLICATIONS
38895
+ )) {
38896
+ for (const impliedKey of implied) {
38897
+ impliedBy[impliedKey].push(flagKey);
38898
+ }
38899
+ }
38900
+ return impliedBy;
38901
+ })();
38902
+ function collectFlagClosure(startKey, edges) {
38903
+ const seen = /* @__PURE__ */ new Set([startKey]);
38904
+ const ordered = [];
38905
+ const visit = /* @__PURE__ */ __name3((flagKey) => {
38906
+ for (const next of edges[flagKey] ?? []) {
38907
+ if (seen.has(next)) {
38908
+ continue;
38909
+ }
38910
+ seen.add(next);
38911
+ visit(next);
38912
+ ordered.push(next);
38913
+ }
38914
+ }, "visit");
38915
+ visit(startKey);
38916
+ return ordered;
38917
+ }
38918
+ __name(collectFlagClosure, "collectFlagClosure");
38919
+ __name3(collectFlagClosure, "collectFlagClosure");
38920
+ function getImpliedFeatureFlags(flagKey) {
38921
+ return collectFlagClosure(flagKey, FEATURE_FLAG_IMPLICATIONS);
38922
+ }
38923
+ __name(getImpliedFeatureFlags, "getImpliedFeatureFlags");
38924
+ __name3(getImpliedFeatureFlags, "getImpliedFeatureFlags");
38925
+ function getImplyingFeatureFlags(flagKey) {
38926
+ return collectFlagClosure(flagKey, FEATURE_FLAG_IMPLIED_BY);
38927
+ }
38928
+ __name(getImplyingFeatureFlags, "getImplyingFeatureFlags");
38929
+ __name3(getImplyingFeatureFlags, "getImplyingFeatureFlags");
38930
+ function findFeatureFlagImplicationCycle() {
38931
+ const visiting = /* @__PURE__ */ new Set();
38932
+ const settled = /* @__PURE__ */ new Set();
38933
+ const path = [];
38934
+ const walk = /* @__PURE__ */ __name3((flagKey) => {
38935
+ if (visiting.has(flagKey)) {
38936
+ return [...path.slice(path.indexOf(flagKey)), flagKey];
38937
+ }
38938
+ if (settled.has(flagKey)) {
38939
+ return null;
38940
+ }
38941
+ visiting.add(flagKey);
38942
+ path.push(flagKey);
38943
+ for (const implied of FEATURE_FLAG_IMPLICATIONS[flagKey] ?? []) {
38944
+ const cycle = walk(implied);
38945
+ if (cycle) {
38946
+ return cycle;
38947
+ }
38948
+ }
38949
+ path.pop();
38950
+ visiting.delete(flagKey);
38951
+ settled.add(flagKey);
38952
+ return null;
38953
+ }, "walk");
38954
+ for (const flagKey of Object.keys(
38955
+ FEATURE_FLAG_IMPLICATIONS
38956
+ )) {
38957
+ const cycle = walk(flagKey);
38958
+ if (cycle) {
38959
+ return cycle;
38960
+ }
38961
+ }
38962
+ return null;
38963
+ }
38964
+ __name(findFeatureFlagImplicationCycle, "findFeatureFlagImplicationCycle");
38965
+ __name3(findFeatureFlagImplicationCycle, "findFeatureFlagImplicationCycle");
38966
+ function resolveFeatureFlagWithImplications(flagKey, resolveOwnValue) {
38967
+ const impliedBy = getImplyingFeatureFlags(flagKey).filter(
38968
+ (implyingKey) => resolveOwnValue(implyingKey) === true
38969
+ );
38970
+ if (impliedBy.length > 0) {
38971
+ return { value: true, impliedBy };
38972
+ }
38973
+ return { value: resolveOwnValue(flagKey), impliedBy };
38974
+ }
38975
+ __name(resolveFeatureFlagWithImplications, "resolveFeatureFlagWithImplications");
38976
+ __name3(resolveFeatureFlagWithImplications, "resolveFeatureFlagWithImplications");
38870
38977
  function coerceFlagValue(value) {
38871
38978
  if (value === void 0) {
38872
38979
  return void 0;
@@ -63514,10 +63621,10 @@ var TABLE_COLUMNS40 = [
63514
63621
  { header: "STATUS", cell: /* @__PURE__ */ __name((row) => row.status, "cell") },
63515
63622
  { header: "UPDATED", cell: /* @__PURE__ */ __name((row) => row.updated_at, "cell") }
63516
63623
  ];
63517
- var SCOPE_FLAGS = ["--team", "--shared", "--automation"];
63624
+ var SCOPE_FLAGS = ["--published", "--shared", "--automation"];
63518
63625
  function resolveScope(options) {
63519
63626
  const selected = [
63520
- options.team && "--team",
63627
+ options.published && "--published",
63521
63628
  options.shared && "--shared",
63522
63629
  options.automation && "--automation"
63523
63630
  ].filter((flag) => typeof flag === "string");
@@ -63526,7 +63633,7 @@ function resolveScope(options) {
63526
63633
  `${SCOPE_FLAGS.join(", ")} are different scopes \u2014 pass at most one. You passed ${selected.join(" and ")}.`
63527
63634
  );
63528
63635
  }
63529
- if (options.team) {
63636
+ if (options.published) {
63530
63637
  return "team";
63531
63638
  }
63532
63639
  if (options.shared) {
@@ -63539,9 +63646,11 @@ function resolveScope(options) {
63539
63646
  }
63540
63647
  __name(resolveScope, "resolveScope");
63541
63648
  function registerPulseList(pulse) {
63542
- pulse.command("list", { isDefault: true }).description("List your Pulse dashboards").option(
63543
- "--team",
63544
- "list dashboards a teammate published to your whole team instead of your own"
63649
+ pulse.command("list", { isDefault: true }).description(
63650
+ "List your Pulse dashboards in the selected team (--team <id>, DUVO_TEAM_ID, or the profile default)"
63651
+ ).option(
63652
+ "--published",
63653
+ "list dashboards a teammate published to the whole team instead of your own"
63545
63654
  ).option("--shared", "deprecated: always returns no dashboards").option(
63546
63655
  "--automation",
63547
63656
  "list the dashboards owned by your team's automations, each prefixed with its automation's name"
@@ -63552,7 +63661,11 @@ function registerPulseList(pulse) {
63552
63661
  max: MAX_LIMIT15
63553
63662
  });
63554
63663
  const offset = parseOffset(options.offset);
63555
- const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
63664
+ const config = await requireAuthenticatedConfig(this);
63665
+ const { apiKey, apiBaseUrl } = config;
63666
+ const teamId = await resolveRequiredTeamId(config, {
63667
+ override: getTeamFlag(this)
63668
+ });
63556
63669
  const searchParams = new URLSearchParams();
63557
63670
  const scope = resolveScope(options);
63558
63671
  searchParams.append("scope", scope);
@@ -63560,7 +63673,7 @@ function registerPulseList(pulse) {
63560
63673
  searchParams.append("offset", String(offset));
63561
63674
  const raw = await httpRequest({
63562
63675
  method: "GET",
63563
- path: "/v2/artifacts",
63676
+ path: buildTeamPath(teamId, "/artifacts"),
63564
63677
  apiKey,
63565
63678
  apiBaseUrl,
63566
63679
  searchParams
@@ -70628,7 +70741,7 @@ __name(isStandaloneBinary, "isStandaloneBinary");
70628
70741
  import { createRequire } from "node:module";
70629
70742
  function getPackageMeta() {
70630
70743
  if (true) {
70631
- return { name: "@duvoai/cli", version: "1.77.2" };
70744
+ return { name: "@duvoai/cli", version: "1.78.0" };
70632
70745
  }
70633
70746
  const require2 = createRequire(import.meta.url);
70634
70747
  const raw = require2("../../package.json");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@duvoai/cli",
3
- "version": "1.77.2",
3
+ "version": "1.78.0",
4
4
  "description": "Command-line interface for the Duvo public API",
5
5
  "bin": {
6
6
  "duvo": "./dist/bin/duvo.js"