@dosu/cli 0.53.0-beta.1 → 0.53.0-beta.2

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/bin/dosu.js +104 -70
  2. package/package.json +1 -1
package/bin/dosu.js CHANGED
@@ -5006,7 +5006,7 @@ function isNpxInvocation(channel = INSTALL_CHANNEL, env = process.env) {
5006
5006
  function getVersionString() {
5007
5007
  return `v${VERSION}`;
5008
5008
  }
5009
- var VERSION = "0.53.0-beta.1", INSTALL_CHANNEL = "npm";
5009
+ var VERSION = "0.53.0-beta.2", INSTALL_CHANNEL = "npm";
5010
5010
 
5011
5011
  // src/debug/logger.ts
5012
5012
  import {
@@ -5144,7 +5144,7 @@ var init_logger = __esm(() => {
5144
5144
  });
5145
5145
 
5146
5146
  // src/client/contract.ts
5147
- var CLI_CONTRACT_HASH = "bb1ad28625bd";
5147
+ var CLI_CONTRACT_HASH = "1d4be4b6214f";
5148
5148
 
5149
5149
  // src/client/trpc.ts
5150
5150
  var exports_trpc = {};
@@ -5327,6 +5327,37 @@ function breadcrumb(segments, width = contentWidth()) {
5327
5327
  function visibleWidth(text) {
5328
5328
  return text.replace(ANSI_PATTERN2, "").length;
5329
5329
  }
5330
+ function tabStrip(labels, active2, width, { spread = true } = {}) {
5331
+ const GAP_MIN = 3;
5332
+ const totalLen = labels.reduce((sum, [, label]) => sum + label.length, 0);
5333
+ const slots = Math.max(1, labels.length - 1);
5334
+ const spare = spread ? Math.max(GAP_MIN * slots, width - totalLen) : GAP_MIN * slots;
5335
+ const baseGap = Math.floor(spare / slots);
5336
+ const bonus = spare % slots;
5337
+ let row = "";
5338
+ let col = 0;
5339
+ let activeStart = 0;
5340
+ let activeLen = 0;
5341
+ labels.forEach(([id, label], i2) => {
5342
+ if (i2 > 0) {
5343
+ const gap = baseGap + (i2 <= bonus ? 1 : 0);
5344
+ row += " ".repeat(gap);
5345
+ col += gap;
5346
+ }
5347
+ if (id === active2) {
5348
+ activeStart = col;
5349
+ activeLen = label.length;
5350
+ row += brand(import_picocolors9.default.bold(label));
5351
+ } else {
5352
+ row += import_picocolors9.default.dim(label);
5353
+ }
5354
+ col += label.length;
5355
+ });
5356
+ const ruleEnd = spread ? width : col;
5357
+ const tail = Math.max(0, ruleEnd - activeStart - activeLen);
5358
+ const rule = import_picocolors9.default.dim("─".repeat(activeStart)) + brand("━".repeat(activeLen)) + import_picocolors9.default.dim("─".repeat(tail));
5359
+ return [row, rule];
5360
+ }
5330
5361
  function centerBlock(lines, width) {
5331
5362
  const blockWidth = Math.max(...lines.map(visibleWidth));
5332
5363
  const pad = " ".repeat(Math.max(0, Math.floor((width - blockWidth) / 2)));
@@ -5385,6 +5416,7 @@ function installCenteredLayout(stream = process.stdout) {
5385
5416
  }
5386
5417
  var import_picocolors9, ESC2, CONTENT_WIDTH = 64, TOKEN_PATTERN, COLUMN_RESET_FINALS, active = false, ANSI_PATTERN2;
5387
5418
  var init_layout = __esm(() => {
5419
+ init_styles();
5388
5420
  import_picocolors9 = __toESM(require_picocolors(), 1);
5389
5421
  ESC2 = String.fromCharCode(27);
5390
5422
  TOKEN_PATTERN = new RegExp(`(\r
@@ -71919,7 +71951,7 @@ var init_settings = __esm(() => {
71919
71951
  });
71920
71952
 
71921
71953
  // src/telemetry/debug-id.ts
71922
- var BUNDLE_DEBUG_ID_PLACEHOLDER = "fd3fcdcd-886d-763b-6475-6e2164756e21";
71954
+ var BUNDLE_DEBUG_ID_PLACEHOLDER = "e949e449-7f03-cfbf-6475-6e2164756e21";
71923
71955
 
71924
71956
  // src/telemetry/telemetry.ts
71925
71957
  import { randomUUID as randomUUID4 } from "node:crypto";
@@ -73966,40 +73998,12 @@ function progressLine(done, ready, width, notes = 0) {
73966
73998
  return `${bar} ${done}/${total} mined · ${pct}%${suffix}`;
73967
73999
  }
73968
74000
  function tabBar(tab, queuedCount, openCount, minedCount, width) {
73969
- const labels = [
74001
+ return tabStrip([
73970
74002
  ["activity", "Activity"],
73971
74003
  ["mined", `Mined (${minedCount})`],
73972
74004
  ["queued", `Queued (${queuedCount})`],
73973
74005
  ["open", `Open (${openCount})`]
73974
- ];
73975
- const GAP_MIN = 3;
73976
- const totalLen = labels.reduce((sum, [, label]) => sum + label.length, 0);
73977
- const slots = labels.length - 1;
73978
- const spare = Math.max(GAP_MIN * slots, width - totalLen);
73979
- const baseGap = Math.floor(spare / slots);
73980
- const bonus = spare % slots;
73981
- let row = "";
73982
- let col = 0;
73983
- let activeStart = 0;
73984
- let activeLen = 0;
73985
- labels.forEach(([id2, label], i5) => {
73986
- if (i5 > 0) {
73987
- const gap = baseGap + (i5 <= bonus ? 1 : 0);
73988
- row += " ".repeat(gap);
73989
- col += gap;
73990
- }
73991
- if (id2 === tab) {
73992
- activeStart = col;
73993
- activeLen = label.length;
73994
- row += brand(import_picocolors30.default.bold(label));
73995
- } else {
73996
- row += import_picocolors30.default.dim(label);
73997
- }
73998
- col += label.length;
73999
- });
74000
- const tail = Math.max(0, width - activeStart - activeLen);
74001
- const rule2 = import_picocolors30.default.dim("─".repeat(activeStart)) + brand("━".repeat(activeLen)) + import_picocolors30.default.dim("─".repeat(tail));
74002
- return [row, rule2];
74006
+ ], tab, width);
74003
74007
  }
74004
74008
  function activityWidth(columns) {
74005
74009
  return Math.max(20, columns - 2 * layoutMargin(columns) - 1);
@@ -75883,12 +75887,21 @@ var init_flow2 = __esm(() => {
75883
75887
  function reduceAnalyticsViewKey(key) {
75884
75888
  if (key === "q" || key === ESC8 || key === CTRL_C5)
75885
75889
  return "back";
75890
+ if (key === "\t" || key === KEY_RIGHT4)
75891
+ return "tab";
75892
+ if (key === KEY_LEFT4)
75893
+ return "tab-back";
75886
75894
  if (key === KEY_UP5 || key === "k")
75887
75895
  return "up";
75888
75896
  if (key === KEY_DOWN5 || key === "j")
75889
75897
  return "down";
75890
75898
  return "none";
75891
75899
  }
75900
+ function cycleAnalyticsTab(tab, delta = 1) {
75901
+ const index = ANALYTICS_VIEW_TABS.indexOf(tab);
75902
+ const next = (index + delta + ANALYTICS_VIEW_TABS.length) % ANALYTICS_VIEW_TABS.length;
75903
+ return ANALYTICS_VIEW_TABS[next];
75904
+ }
75892
75905
  function clip2(text, max) {
75893
75906
  return text.length <= max ? text : `${text.slice(0, max - 1)}…`;
75894
75907
  }
@@ -75925,32 +75938,30 @@ function loadPageStatsFromConfig() {
75925
75938
  return Promise.resolve(null);
75926
75939
  }
75927
75940
  }
75928
- function analyticsRows(state, pageStats = null) {
75941
+ function overviewRows(state) {
75929
75942
  const minedTotal = state.total_mined ?? 0;
75930
75943
  const notes = state.total_notes ?? 0;
75931
75944
  const tokens = state.total_learning_tokens ?? 0;
75932
- const label = (text) => text.padEnd(26);
75933
- const rows = [];
75934
- if (minedTotal > 0 || notes > 0) {
75935
- rows.push(`${label("Sessions mined")}${minedTotal}`, `${label("Suggested pages")}${notes}`);
75936
- if (tokens > 0) {
75937
- rows.push(`${label("Investigation distilled")}${formatTokenCount(tokens)} tokens`);
75938
- }
75939
- const byProject = new Map;
75940
- for (const record2 of state.mined_sessions ?? []) {
75941
- const key = record2.project ?? "(unknown)";
75942
- byProject.set(key, (byProject.get(key) ?? 0) + 1);
75943
- }
75944
- if (byProject.size > 0) {
75945
- rows.push("", "Mined by project (recent history)");
75946
- const top = [...byProject.entries()].sort((a9, b2) => b2[1] - a9[1]).slice(0, 8);
75947
- for (const [project, count] of top) {
75948
- rows.push(`${label(clip2(project, 24))}${count}`);
75949
- }
75950
- }
75945
+ if (minedTotal === 0 && notes === 0)
75946
+ return [];
75947
+ const rows = [`${label("Sessions mined")}${minedTotal}`, `${label("Suggested pages")}${notes}`];
75948
+ if (tokens > 0) {
75949
+ rows.push(`${label("Investigation distilled")}${formatTokenCount(tokens)} tokens`);
75950
+ }
75951
+ return rows;
75952
+ }
75953
+ function projectRows(state) {
75954
+ const byProject = new Map;
75955
+ for (const record2 of state.mined_sessions ?? []) {
75956
+ const key = record2.project ?? "(unknown)";
75957
+ byProject.set(key, (byProject.get(key) ?? 0) + 1);
75951
75958
  }
75959
+ return [...byProject.entries()].sort((a9, b2) => b2[1] - a9[1]).map(([project, count]) => `${label(clip2(project, 24))}${count}`);
75960
+ }
75961
+ function pageRows(pageStats) {
75962
+ const rows = [];
75952
75963
  if (pageStats && pageStats.topCited.length > 0) {
75953
- rows.push(...rows.length > 0 ? [""] : [], `Top cited pages (${TOP_CITED_DAYS}d)`);
75964
+ rows.push(`Top cited pages (${TOP_CITED_DAYS}d)`);
75954
75965
  for (const row of pageStats.topCited) {
75955
75966
  rows.push(`${label(clip2(row.title, 24))}${row.citation_count}`);
75956
75967
  }
@@ -75971,22 +75982,35 @@ function windowReport(lines, scroll, height = ANALYTICS_VIEW_LINES) {
75971
75982
  below: Math.max(0, lines.length - clamped - height)
75972
75983
  };
75973
75984
  }
75974
- function renderAnalyticsFrame(state, scroll, pageStats = null) {
75975
- const rows = analyticsRows(state, pageStats);
75985
+ function analyticsTabRows(tab, state, pageStats) {
75986
+ if (tab === "overview")
75987
+ return overviewRows(state);
75988
+ if (tab === "projects")
75989
+ return projectRows(state);
75990
+ return pageRows(pageStats);
75991
+ }
75992
+ function renderAnalyticsFrame(state, tab, scroll, pageStats = null, pagesPending = false, width = contentWidth()) {
75993
+ const rows = analyticsTabRows(tab, state, pageStats);
75976
75994
  const { visible, above, below } = windowReport(rows, scroll);
75977
- const listRows = visible.length > 0 ? visible.map((row) => import_picocolors32.default.dim(row)) : [import_picocolors32.default.dim("No analytics yet. They appear after the first mining run.")];
75995
+ const empty = tab === "overview" ? "No analytics yet. They appear after the first mining run." : tab === "projects" ? "No per-project history yet. It fills in as sessions are mined." : pagesPending ? "Loading page analytics..." : "No page analytics yet.";
75996
+ const listRows = visible.length > 0 ? visible.map((row) => import_picocolors32.default.dim(row)) : [import_picocolors32.default.dim(empty)];
75978
75997
  const scrollParts = [];
75979
75998
  if (above > 0)
75980
75999
  scrollParts.push(`↑ ${above} earlier`);
75981
76000
  if (below > 0)
75982
76001
  scrollParts.push(`↓ ${below} more`);
75983
76002
  const lines = [
75984
- breadcrumb(["Home", "Analytics"]),
76003
+ breadcrumb(["Home", "Analytics"], width),
75985
76004
  "",
76005
+ ...tabStrip([
76006
+ ["overview", "Overview"],
76007
+ ["projects", "Projects"],
76008
+ ["pages", "Pages"]
76009
+ ], tab, width, { spread: false }),
75986
76010
  ...listRows,
75987
76011
  ...scrollParts.length > 0 ? [import_picocolors32.default.dim(scrollParts.join(" · "))] : [],
75988
76012
  "",
75989
- import_picocolors32.default.dim("↑↓ scroll · esc back")
76013
+ import_picocolors32.default.dim("tab switch · ↑↓ scroll · esc back")
75990
76014
  ];
75991
76015
  return lines.join(`
75992
76016
  `);
@@ -75999,14 +76023,17 @@ function runAnalyticsView(io2 = {}) {
75999
76023
  const getStatus = io2.getStatus ?? (() => getSyncStatus({ readLog: () => "" }));
76000
76024
  const loadPageStats = io2.loadPageStats ?? loadPageStatsFromConfig;
76001
76025
  const pollMs = io2.pollMs ?? ANALYTICS_VIEW_POLL_MS;
76026
+ let tab = "overview";
76002
76027
  let scroll = 0;
76003
76028
  let status = getStatus();
76004
76029
  let pageStats = null;
76030
+ let pagesPending = true;
76005
76031
  let closed = false;
76006
76032
  let lastFrame = null;
76007
76033
  const draw = () => {
76008
76034
  status = getStatus();
76009
- const frame = renderAnalyticsFrame(status.state, scroll, pageStats);
76035
+ const width = Math.min(contentWidth(output2.columns ?? 80), (output2.columns ?? 80) - 1);
76036
+ const frame = renderAnalyticsFrame(status.state, tab, scroll, pageStats, pagesPending, width);
76010
76037
  if (frame === lastFrame)
76011
76038
  return;
76012
76039
  lastFrame = frame;
@@ -76027,9 +76054,10 @@ ${CLEAR_BELOW2}`);
76027
76054
  output2.write(HIDE_CURSOR4);
76028
76055
  draw();
76029
76056
  loadPageStats().then((stats) => {
76030
- if (closed || !stats)
76057
+ if (closed)
76031
76058
  return;
76032
76059
  pageStats = stats;
76060
+ pagesPending = false;
76033
76061
  draw();
76034
76062
  });
76035
76063
  return new Promise((resolve6) => {
@@ -76056,13 +76084,17 @@ ${CLEAR_BELOW2}`);
76056
76084
  finish();
76057
76085
  return;
76058
76086
  }
76059
- if (action === "up") {
76087
+ if (action === "tab" || action === "tab-back") {
76088
+ tab = cycleAnalyticsTab(tab, action === "tab" ? 1 : -1);
76089
+ scroll = 0;
76090
+ draw();
76091
+ } else if (action === "up") {
76060
76092
  if (scroll > 0) {
76061
76093
  scroll -= 1;
76062
76094
  draw();
76063
76095
  }
76064
76096
  } else if (action === "down") {
76065
- const maxScroll = Math.max(0, analyticsRows(status.state, pageStats).length - ANALYTICS_VIEW_LINES);
76097
+ const maxScroll = Math.max(0, analyticsTabRows(tab, status.state, pageStats).length - ANALYTICS_VIEW_LINES);
76066
76098
  if (scroll < maxScroll) {
76067
76099
  scroll += 1;
76068
76100
  draw();
@@ -76073,7 +76105,7 @@ ${CLEAR_BELOW2}`);
76073
76105
  input2.on("data", onData);
76074
76106
  });
76075
76107
  }
76076
- var import_picocolors32, ESC8, HIDE_CURSOR4, SHOW_CURSOR4, CTRL_C5, KEY_UP5, KEY_DOWN5, CURSOR_HOME2, CLEAR_BELOW2, CLEAR_EOL2, ANALYTICS_VIEW_POLL_MS = 1000, ANALYTICS_VIEW_LINES = 12, TOP_PAGES_LIMIT = 5, TOP_CITED_DAYS = 30;
76108
+ var import_picocolors32, ESC8, HIDE_CURSOR4, SHOW_CURSOR4, CTRL_C5, KEY_UP5, KEY_DOWN5, KEY_RIGHT4, KEY_LEFT4, CURSOR_HOME2, CLEAR_BELOW2, CLEAR_EOL2, ANALYTICS_VIEW_POLL_MS = 1000, ANALYTICS_VIEW_LINES = 12, ANALYTICS_VIEW_TABS, TOP_PAGES_LIMIT = 5, TOP_CITED_DAYS = 30, label = (text) => text.padEnd(26);
76077
76109
  var init_analytics_view = __esm(() => {
76078
76110
  init_trpc();
76079
76111
  init_config();
@@ -76088,9 +76120,12 @@ var init_analytics_view = __esm(() => {
76088
76120
  CTRL_C5 = String.fromCharCode(3);
76089
76121
  KEY_UP5 = `${ESC8}[A`;
76090
76122
  KEY_DOWN5 = `${ESC8}[B`;
76123
+ KEY_RIGHT4 = `${ESC8}[C`;
76124
+ KEY_LEFT4 = `${ESC8}[D`;
76091
76125
  CURSOR_HOME2 = `${ESC8}[H`;
76092
76126
  CLEAR_BELOW2 = `${ESC8}[0J`;
76093
76127
  CLEAR_EOL2 = `${ESC8}[K`;
76128
+ ANALYTICS_VIEW_TABS = ["overview", "projects", "pages"];
76094
76129
  });
76095
76130
 
76096
76131
  // src/tui/banner.ts
@@ -76144,8 +76179,8 @@ function checklistRows(ctx) {
76144
76179
  `${import_picocolors33.default.yellow(`↑ ${ctx.update.version} available`)} ${import_picocolors33.default.dim(`${DOT3} ${ctx.update.hint}`)}`
76145
76180
  ]);
76146
76181
  }
76147
- const labelWidth = Math.max(...rows.map(([label]) => label.length));
76148
- return rows.map(([label, value]) => `${import_picocolors33.default.dim(label.padEnd(labelWidth))} ${value}`);
76182
+ const labelWidth = Math.max(...rows.map(([label2]) => label2.length));
76183
+ return rows.map(([label2, value]) => `${import_picocolors33.default.dim(label2.padEnd(labelWidth))} ${value}`);
76149
76184
  }
76150
76185
  function renderBanner(ctx) {
76151
76186
  const logo = LOGO_ROWS.map(paintLogoRow);
@@ -76274,7 +76309,7 @@ function wrapBody(text, width) {
76274
76309
  function clip3(text, max) {
76275
76310
  return text.length <= max ? text : `${text.slice(0, max - 1)}…`;
76276
76311
  }
76277
- function pageRows(pages, width) {
76312
+ function pageRows2(pages, width) {
76278
76313
  const titleWidth = Math.max(16, width - 32);
76279
76314
  return pages.map((page) => {
76280
76315
  const title = clip3(page.title, titleWidth).padEnd(titleWidth + 1);
@@ -76298,7 +76333,7 @@ function renderPagesFrame(model, width, selected) {
76298
76333
  } else if (model.pages.length === 0) {
76299
76334
  body.push(import_picocolors34.default.dim("No pages in this Library yet."));
76300
76335
  } else {
76301
- const rows = pageRows(model.pages, width - 2);
76336
+ const rows = pageRows2(model.pages, width - 2);
76302
76337
  const { start, above } = windowSelection(rows.length, selected);
76303
76338
  const visible = rows.slice(start, start + PAGES_VIEW_LINES);
76304
76339
  body.push(...visible.map((row, i5) => start + i5 === selected ? `${brand("▸")} ${import_picocolors34.default.bold(row)}` : ` ${import_picocolors34.default.dim(row)}`));
@@ -80953,7 +80988,6 @@ var LIBRARY_VISIBILITIES = ["public", "internal", "private"];
80953
80988
  var CONFIG_SETTINGS = {
80954
80989
  commit_to_trigger_pr: true,
80955
80990
  default_accept_review: true,
80956
- default_save_publish: true,
80957
80991
  review_timeout_days: true
80958
80992
  };
80959
80993
  var CONFIG_SETTING_NAMES = Object.keys(CONFIG_SETTINGS);
@@ -82690,4 +82724,4 @@ execute().catch((err) => {
82690
82724
  process.exit(1);
82691
82725
  });
82692
82726
 
82693
- //# debugId=fd3fcdcd-886d-763b-6475-6e2164756e21
82727
+ //# debugId=e949e449-7f03-cfbf-6475-6e2164756e21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dosu/cli",
3
- "version": "0.53.0-beta.1",
3
+ "version": "0.53.0-beta.2",
4
4
  "type": "module",
5
5
  "description": "Dosu CLI - Manage MCP servers for AI tools",
6
6
  "license": "MIT",