@synap-core/cli 1.13.1-next.20261103.8afcf02 → 1.13.1-next.20261104.d3e629d

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.
@@ -1,5 +1,5 @@
1
1
  {
2
- "builtAt": "2026-11-03T12:45:51.323Z",
3
- "sha": "8afcf02",
2
+ "builtAt": "2026-11-04T11:24:28.490Z",
3
+ "sha": "d3e629d",
4
4
  "dirty": false
5
5
  }
@@ -34,6 +34,7 @@ import prompts from "prompts";
34
34
  import { fetchPublicBrowseRows, fetchMyRows, fetchAvailableSlugs, fetchRetiredWorkspaceSlugs, fetchPackageDefinition, fetchPackageRecord, hydrateMineCategories, } from "../lib/cp-packages.js";
35
35
  import { fetchInstalledSlugs, fetchInstalledTemplates, fetchInstalledInventory, installedRowsToTemplates, fetchWorkspaceAttachments, fetchWorkspaceAttachmentsStrict, verifyStampLanded, INSTALLED_KINDS } from "../lib/installed.js";
36
36
  import { isSuite } from "../lib/suite.js";
37
+ import { refreshPodCatalogFor, catalogRefreshLine } from "../lib/catalog-refresh.js";
37
38
  import { TEMPLATE_STEP_LABELS, classifyTemplateStep, proposalsDoor, stepFromApplyState, templateStepGlyph, templateStepPhrase, } from "../lib/template-steps.js";
38
39
  import { capabilityAdd } from "./capability.js";
39
40
  import { bundledTemplatesVersion } from "../lib/bundle-version.js";
@@ -1517,7 +1518,22 @@ async function previewDataChanges(entry, cat, cfg) {
1517
1518
  return { payload, error: `the pod's preview failed: ${status}` };
1518
1519
  }
1519
1520
  }
1521
+ /**
1522
+ * Before a command reads the pod's update verdict: ask the pod to refresh its
1523
+ * catalog (`lib/catalog-refresh.ts`) and, unless printing JSON, say so when
1524
+ * it could not. Never blocks the command.
1525
+ */
1526
+ async function refreshCatalogFirst(opts) {
1527
+ const refresh = await refreshPodCatalogFor(opts);
1528
+ const line = catalogRefreshLine(refresh);
1529
+ if (line && !opts.json)
1530
+ log.warn(line);
1531
+ return refresh;
1532
+ }
1520
1533
  export async function marketUpdate(slugsArg, opts) {
1534
+ // Refresh the pod's catalog first, so a template published a minute ago
1535
+ // shows in the verdict below (the pod otherwise refreshes every 10 min).
1536
+ const catalogRefresh = await refreshCatalogFirst(opts);
1521
1537
  const applyTimeoutMs = parseApplyTimeoutMs(opts.timeout);
1522
1538
  const cat = await buildMarketCatalog();
1523
1539
  // THE POD'S ANSWER, never the CLI's: which installed package has an update
@@ -1536,7 +1552,7 @@ export async function marketUpdate(slugsArg, opts) {
1536
1552
  process.exitCode = 1;
1537
1553
  const unavailable = e instanceof StandingsUnavailableError ? e.reason : null;
1538
1554
  if (opts.json) {
1539
- console.log(JSON.stringify({ checks: [], loggedIn: cat.loggedIn, error: unavailable ?? "pod-unreachable" }, null, 2));
1555
+ console.log(JSON.stringify({ checks: [], loggedIn: cat.loggedIn, catalogRefresh, error: unavailable ?? "pod-unreachable" }, null, 2));
1540
1556
  return;
1541
1557
  }
1542
1558
  if (e instanceof StandingsUnavailableError) {
@@ -1553,7 +1569,7 @@ export async function marketUpdate(slugsArg, opts) {
1553
1569
  const degraded = false;
1554
1570
  if (standings.length === 0) {
1555
1571
  if (opts.json) {
1556
- console.log(JSON.stringify({ checks: [], loggedIn: cat.loggedIn, degraded }, null, 2));
1572
+ console.log(JSON.stringify({ checks: [], loggedIn: cat.loggedIn, catalogRefresh, degraded }, null, 2));
1557
1573
  return;
1558
1574
  }
1559
1575
  log.warn("No installed packages found on this pod.");
@@ -1576,7 +1592,7 @@ export async function marketUpdate(slugsArg, opts) {
1576
1592
  }
1577
1593
  if (validSlugs.length === 0) {
1578
1594
  if (opts.json) {
1579
- console.log(JSON.stringify({ checks: [], loggedIn: cat.loggedIn, unknownSlugs, applied: [] }, null, 2));
1595
+ console.log(JSON.stringify({ checks: [], loggedIn: cat.loggedIn, catalogRefresh, unknownSlugs, applied: [] }, null, 2));
1580
1596
  return;
1581
1597
  }
1582
1598
  log.hint("List what's installed: synap market installed");
@@ -1703,6 +1719,7 @@ export async function marketUpdate(slugsArg, opts) {
1703
1719
  console.log(JSON.stringify({
1704
1720
  checks,
1705
1721
  loggedIn: cat.loggedIn,
1722
+ catalogRefresh,
1706
1723
  unknownSlugs,
1707
1724
  applied: [],
1708
1725
  status: noVersionInfo.length > 0 ? "partial" : "clean",
@@ -1720,7 +1737,12 @@ export async function marketUpdate(slugsArg, opts) {
1720
1737
  log.info("No updates to apply.");
1721
1738
  }
1722
1739
  else {
1723
- log.success("Nothing to update.");
1740
+ // A clean verdict is only "verified" against a catalog the pod just
1741
+ // refreshed; otherwise it is the pod's last copy, said as such.
1742
+ if (catalogRefresh.state === "refreshed")
1743
+ log.success("Nothing to update.");
1744
+ else
1745
+ log.info("Nothing to update in the pod's last copy of the catalog (not refreshed, see above).");
1724
1746
  // `market update` only checks TEMPLATE-ATTACHED workspaces — a hand-built
1725
1747
  // one (no packageSlug) can't be "behind" a template, so it's silently
1726
1748
  // absent here. Point at the fuller home so "nothing to update" never reads
@@ -1737,6 +1759,7 @@ export async function marketUpdate(slugsArg, opts) {
1737
1759
  console.log(JSON.stringify({
1738
1760
  checks,
1739
1761
  loggedIn: cat.loggedIn,
1762
+ catalogRefresh,
1740
1763
  unknownSlugs,
1741
1764
  applied: [],
1742
1765
  nextSteps: steps,
@@ -1796,6 +1819,7 @@ export async function marketUpdate(slugsArg, opts) {
1796
1819
  console.log(JSON.stringify({
1797
1820
  checks,
1798
1821
  loggedIn: cat.loggedIn,
1822
+ catalogRefresh,
1799
1823
  unknownSlugs,
1800
1824
  applied: results,
1801
1825
  summary,
@@ -2337,6 +2361,9 @@ export async function marketInstalled(opts) {
2337
2361
  // view install was invisible here, to `market update`, and to every drift
2338
2362
  // marker. On a pod too old to serve it, `fetchInstalledInventory` degrades to
2339
2363
  // exactly the old workspace-only behaviour and says so (`degraded`).
2364
+ // Refresh the pod's catalog first, so a template published a minute ago
2365
+ // shows in the verdict below (the pod otherwise refreshes every 10 min).
2366
+ const catalogRefresh = await refreshCatalogFirst(opts);
2340
2367
  const [inv, cat] = await Promise.all([fetchInstalledInventory(), buildMarketCatalog()]);
2341
2368
  const installedTemplates = installedRowsToTemplates(inv.rows);
2342
2369
  const unlinked = collectUnlinked(inv.rows);
@@ -2345,7 +2372,7 @@ export async function marketInstalled(opts) {
2345
2372
  : undefined;
2346
2373
  if (installedTemplates.length === 0 && unlinked.length === 0) {
2347
2374
  if (opts.json) {
2348
- console.log(JSON.stringify({ rows: [], unlinked: [], loggedIn: cat.loggedIn, degraded: inv.degraded, degradedNote }, null, 2));
2375
+ console.log(JSON.stringify({ rows: [], unlinked: [], loggedIn: cat.loggedIn, catalogRefresh, degraded: inv.degraded, degradedNote }, null, 2));
2349
2376
  return;
2350
2377
  }
2351
2378
  log.warn("No installed packages found on this pod.");
@@ -2390,6 +2417,7 @@ export async function marketInstalled(opts) {
2390
2417
  layers: graph.layers.map((bucket) => bucket.map((n) => n.slug)),
2391
2418
  cycles: graph.cycles,
2392
2419
  loggedIn: cat.loggedIn,
2420
+ catalogRefresh,
2393
2421
  degraded: inv.degraded,
2394
2422
  nextSteps: steps,
2395
2423
  }, null, 2));
@@ -2427,6 +2455,7 @@ export async function marketInstalled(opts) {
2427
2455
  };
2428
2456
  }),
2429
2457
  loggedIn: cat.loggedIn,
2458
+ catalogRefresh,
2430
2459
  degraded: inv.degraded,
2431
2460
  nextSteps: steps,
2432
2461
  }, null, 2));
@@ -2502,6 +2531,7 @@ export async function marketInstalled(opts) {
2502
2531
  ...(u.note ? { note: u.note } : {}),
2503
2532
  })),
2504
2533
  loggedIn: cat.loggedIn,
2534
+ catalogRefresh,
2505
2535
  degraded: inv.degraded,
2506
2536
  ...(degradedNote ? { degradedNote } : {}),
2507
2537
  nextSteps: steps,
@@ -2638,10 +2668,13 @@ export function attachmentStatusLabel(s) {
2638
2668
  * `computeUpdates` for the stamped-drift verdict. Never writes.
2639
2669
  */
2640
2670
  export async function marketWorkspaces(opts) {
2671
+ // Refresh the pod's catalog first, so a template published a minute ago
2672
+ // shows in the verdict below (the pod otherwise refreshes every 10 min).
2673
+ const catalogRefresh = await refreshCatalogFirst(opts);
2641
2674
  const [attachments, cat] = await Promise.all([fetchWorkspaceAttachments(), buildMarketCatalog()]);
2642
2675
  if (attachments.length === 0) {
2643
2676
  if (opts.json) {
2644
- console.log(JSON.stringify({ workspaces: [], loggedIn: cat.loggedIn }, null, 2));
2677
+ console.log(JSON.stringify({ workspaces: [], loggedIn: cat.loggedIn, catalogRefresh }, null, 2));
2645
2678
  return;
2646
2679
  }
2647
2680
  log.warn("No workspaces found on this pod.");
@@ -2683,6 +2716,7 @@ export async function marketWorkspaces(opts) {
2683
2716
  : {}),
2684
2717
  })),
2685
2718
  loggedIn: cat.loggedIn,
2719
+ catalogRefresh,
2686
2720
  }, null, 2));
2687
2721
  return;
2688
2722
  }
@@ -3054,6 +3088,9 @@ export async function marketTemplates(opts) {
3054
3088
  renderHubError(e);
3055
3089
  process.exit(1);
3056
3090
  }
3091
+ // Refresh the pod's catalog first, so a template published a minute ago
3092
+ // shows in the verdict below (the pod otherwise refreshes every 10 min).
3093
+ const catalogRefresh = await refreshCatalogFirst(opts);
3057
3094
  const cat = await buildMarketCatalog();
3058
3095
  // STRICT: this is the consolidated home — "pod unreachable" must never render
3059
3096
  // as "No workspaces found · stand one up", the exact false-empty lie the
@@ -3065,7 +3102,7 @@ export async function marketTemplates(opts) {
3065
3102
  catch (e) {
3066
3103
  process.exitCode = 1;
3067
3104
  if (opts.json) {
3068
- console.log(JSON.stringify({ needsAttention: [], upToDate: [], unlinked: [], loggedIn: cat.loggedIn, error: "pod-unreachable" }, null, 2));
3105
+ console.log(JSON.stringify({ needsAttention: [], upToDate: [], unlinked: [], loggedIn: cat.loggedIn, catalogRefresh, error: "pod-unreachable" }, null, 2));
3069
3106
  return;
3070
3107
  }
3071
3108
  log.error("Couldn't reach your pod to read its workspaces — not saying it's empty.");
@@ -3075,7 +3112,7 @@ export async function marketTemplates(opts) {
3075
3112
  }
3076
3113
  if (attachments.length === 0) {
3077
3114
  if (opts.json) {
3078
- console.log(JSON.stringify({ needsAttention: [], upToDate: [], unlinked: [], loggedIn: cat.loggedIn }, null, 2));
3115
+ console.log(JSON.stringify({ needsAttention: [], upToDate: [], unlinked: [], loggedIn: cat.loggedIn, catalogRefresh }, null, 2));
3079
3116
  return;
3080
3117
  }
3081
3118
  log.warn("No workspaces found on this pod.");
@@ -3104,6 +3141,7 @@ export async function marketTemplates(opts) {
3104
3141
  upToDate: ok.map(templateRowToJson),
3105
3142
  unlinked: unlinked.map(templateRowToJson),
3106
3143
  loggedIn: cat.loggedIn,
3144
+ catalogRefresh,
3107
3145
  }, null, 2));
3108
3146
  return;
3109
3147
  }
@@ -3124,7 +3162,10 @@ export async function marketTemplates(opts) {
3124
3162
  log.blank();
3125
3163
  }
3126
3164
  else {
3127
- log.success(" Everything attached is up to date.");
3165
+ if (catalogRefresh.state === "refreshed")
3166
+ log.success(" Everything attached is up to date.");
3167
+ else
3168
+ log.info(" Everything attached is up to date in the pod's last copy of the catalog (not refreshed, see above).");
3128
3169
  log.blank();
3129
3170
  }
3130
3171
  if (!opts.needsAttention) {