@great-arrow/cli 0.1.38 → 0.1.39

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/index.js +57 -17
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -9399,7 +9399,7 @@ function isNodeError(value) {
9399
9399
 
9400
9400
  // src/lib/version.ts
9401
9401
  var CLI_PACKAGE_NAME = "@great-arrow/cli";
9402
- var CLI_VERSION = "0.1.38";
9402
+ var CLI_VERSION = "0.1.39";
9403
9403
  var GAD_INSTALL_VERSION = "2026.08.08";
9404
9404
  var GAD_INSTALL_MIN_VERSION = "2026.06.22";
9405
9405
  var GAD_INSTALL_HEADER = "X-GAD-Install-Version";
@@ -16327,7 +16327,11 @@ async function reportSeen(opts) {
16327
16327
  }
16328
16328
 
16329
16329
  // src/lib/glance-footer.ts
16330
- var FETCH_TIMEOUT_MS = 1500;
16330
+ var BASE_FETCH_TIMEOUT_MS = 1500;
16331
+ var TIP_FETCH_TIMEOUT_MS = 6e3;
16332
+ function fetchBudgetMs(askForTip) {
16333
+ return askForTip ? TIP_FETCH_TIMEOUT_MS : BASE_FETCH_TIMEOUT_MS;
16334
+ }
16331
16335
  var THROTTLE_INTERVAL_MS = 4 * 60 * 60 * 1e3;
16332
16336
  var TIP_THROTTLE_INTERVAL_MS = 20 * 60 * 60 * 1e3;
16333
16337
  var URGENT_THRESHOLD = 15;
@@ -16341,8 +16345,20 @@ async function maybeShowGlanceFooter(argv) {
16341
16345
  const entry = state[workspaceKey] ?? {};
16342
16346
  const now = Date.now();
16343
16347
  const askForTip = shouldRequestTip({ state: entry, now });
16344
- const payload = await fetchGlance(auth.apiUrl, auth.token, askForTip);
16345
- if (!payload) return;
16348
+ const fetched = await fetchGlance(auth.apiUrl, auth.token, askForTip);
16349
+ const payload = fetched.payload;
16350
+ if (!payload) {
16351
+ if (fetched.tipMaybeSpent) {
16352
+ state[workspaceKey] = nextGlanceState(entry, {
16353
+ now,
16354
+ tipMaybeSpent: true,
16355
+ showNeedsYou: false,
16356
+ topItemId: null
16357
+ });
16358
+ await saveGlanceState(state);
16359
+ }
16360
+ return;
16361
+ }
16346
16362
  const showNeedsYou = payload.urgency !== null && shouldShowGlance({
16347
16363
  urgency: payload.urgency,
16348
16364
  topItemId: topSignature(payload),
@@ -16350,14 +16366,22 @@ async function maybeShowGlanceFooter(argv) {
16350
16366
  now
16351
16367
  });
16352
16368
  const tip = payload.tip;
16353
- if (!showNeedsYou && !tip) return;
16369
+ const nextEntry = nextGlanceState(entry, {
16370
+ now,
16371
+ tipMaybeSpent: fetched.tipMaybeSpent,
16372
+ showNeedsYou,
16373
+ topItemId: topSignature(payload)
16374
+ });
16375
+ if (!showNeedsYou && !tip) {
16376
+ if (nextEntry !== entry) {
16377
+ state[workspaceKey] = nextEntry;
16378
+ await saveGlanceState(state);
16379
+ }
16380
+ return;
16381
+ }
16354
16382
  const printed = showNeedsYou ? renderFooter(payload, auth.apiUrl) : [];
16355
16383
  if (tip) renderTip(tip, auth.apiUrl);
16356
- state[workspaceKey] = {
16357
- ...entry,
16358
- ...showNeedsYou ? { lastShownAt: now, lastTopItemId: topSignature(payload) } : {},
16359
- ...tip ? { lastTipAt: now } : {}
16360
- };
16384
+ state[workspaceKey] = nextEntry;
16361
16385
  await saveGlanceState(state);
16362
16386
  await reportSeen({
16363
16387
  apiUrl: auth.apiUrl,
@@ -16389,7 +16413,8 @@ function firstCommand(argv) {
16389
16413
  }
16390
16414
  async function fetchGlance(apiUrl, token, includeTip) {
16391
16415
  const controller = new AbortController();
16392
- const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
16416
+ const timer = setTimeout(() => controller.abort(), fetchBudgetMs(includeTip));
16417
+ let tipMaybeSpent = includeTip;
16393
16418
  try {
16394
16419
  const response = await fetch(`${apiUrl}/api/mcp`, {
16395
16420
  method: "POST",
@@ -16410,14 +16435,20 @@ async function fetchGlance(apiUrl, token, includeTip) {
16410
16435
  }),
16411
16436
  signal: controller.signal
16412
16437
  });
16413
- if (!response.ok) return null;
16438
+ if (!response.ok) {
16439
+ tipMaybeSpent = false;
16440
+ return { payload: null, tipMaybeSpent };
16441
+ }
16414
16442
  const data = await response.json();
16415
- if (data.error) return null;
16416
- return normalizeGlance(
16417
- parseMcpPayload(data.result?.content ?? data.result)
16418
- );
16443
+ if (data.error) return { payload: null, tipMaybeSpent };
16444
+ return {
16445
+ payload: normalizeGlance(
16446
+ parseMcpPayload(data.result?.content ?? data.result)
16447
+ ),
16448
+ tipMaybeSpent
16449
+ };
16419
16450
  } catch {
16420
- return null;
16451
+ return { payload: null, tipMaybeSpent };
16421
16452
  } finally {
16422
16453
  clearTimeout(timer);
16423
16454
  }
@@ -16566,6 +16597,15 @@ function topSignature(payload) {
16566
16597
  if (payload.topGoal) return `goal:${payload.topGoal.title}`;
16567
16598
  return "empty";
16568
16599
  }
16600
+ function nextGlanceState(entry, input) {
16601
+ const { now, tipMaybeSpent, showNeedsYou, topItemId } = input;
16602
+ if (!tipMaybeSpent && !showNeedsYou) return entry;
16603
+ return {
16604
+ ...entry,
16605
+ ...showNeedsYou && topItemId !== null ? { lastShownAt: now, lastTopItemId: topItemId } : {},
16606
+ ...tipMaybeSpent ? { lastTipAt: now } : {}
16607
+ };
16608
+ }
16569
16609
  function shouldShowGlance(input) {
16570
16610
  const { urgency, topItemId, state, now } = input;
16571
16611
  if (urgency > URGENT_THRESHOLD) return false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@great-arrow/cli",
3
- "version": "0.1.38",
3
+ "version": "0.1.39",
4
4
  "description": "GreatArrow.ai CLI tool",
5
5
  "type": "module",
6
6
  "bin": {