sitevision-cli 1.0.0-beta.28 → 1.0.0-beta.29

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.0-beta.29
4
+
5
+ - After an update, the shell opens What's new with the changes since the
6
+ version you last ran.
7
+
3
8
  ## 1.0.0-beta.28
4
9
 
5
10
  ## 1.0.0-beta.27
package/dist/cli.js CHANGED
@@ -145,7 +145,7 @@ async function playIntro(art) {
145
145
  // Run the full-screen shell on the alternate screen buffer so the scrollback
146
146
  // is untouched, and restore it on exit. The animated wordmark plays first,
147
147
  // inside the same buffer, when the terminal is wide enough for it.
148
- async function runShell(apps, workspaceRoot) {
148
+ async function runShell(apps, workspaceRoot, updatedFrom) {
149
149
  process.stdout.write('\x1b[?1049h\x1b[H');
150
150
  // Also leave the alternate screen when a signal exits past the finally.
151
151
  process.once('exit', () => process.stdout.write('\x1b[?1049l'));
@@ -157,7 +157,7 @@ async function runShell(apps, workspaceRoot) {
157
157
  await playIntro(art);
158
158
  process.stdout.write('\x1b[2J\x1b[H');
159
159
  }
160
- const app = render(_jsx(Shell, { apps: apps, workspaceRoot: workspaceRoot, version: pkg.version, minimal: cli.flags.minimal }));
160
+ const app = render(_jsx(Shell, { apps: apps, workspaceRoot: workspaceRoot, version: pkg.version, minimal: cli.flags.minimal, updatedFrom: updatedFrom }));
161
161
  await app.waitUntilExit();
162
162
  }
163
163
  finally {
@@ -181,7 +181,8 @@ async function main() {
181
181
  const lastSeen = getLastSeenVersion();
182
182
  const isUpdate = !firstRun && lastSeen !== undefined && lastSeen !== pkg.version;
183
183
  if (!firstRun) {
184
- if (isUpdate) {
184
+ // The shell shows the changelog itself; only direct commands get a banner.
185
+ if (isUpdate && commandName) {
185
186
  printBranding();
186
187
  console.log(`\x1b[32m\n ✨ Updated to v${pkg.version}\x1b[0m \x1b[2m(from v${lastSeen})\x1b[0m\n`);
187
188
  }
@@ -211,7 +212,7 @@ async function main() {
211
212
  if (apps.length === 0) {
212
213
  fail('No Sitevision apps found here.', 'Run svc inside an app directory (manifest.json) or at the root of a repo that contains apps.');
213
214
  }
214
- await runShell(apps, process.cwd());
215
+ await runShell(apps, process.cwd(), isUpdate ? lastSeen : undefined);
215
216
  shutdown();
216
217
  return;
217
218
  }
@@ -225,7 +226,7 @@ async function main() {
225
226
  app.waitUntilExit().then(() => resolve(), () => resolve());
226
227
  });
227
228
  }
228
- await runShell([project]);
229
+ await runShell([project], undefined, isUpdate ? lastSeen : undefined);
229
230
  shutdown();
230
231
  return;
231
232
  }
@@ -1,6 +1,10 @@
1
- /** CHANGELOG.md without its title, or undefined when it isn't shipped. */
2
- export declare function readChangelog(): string[] | undefined;
3
- export declare function ChangelogPanel({ height, onClose, }: {
1
+ /**
2
+ * CHANGELOG.md without its title, or undefined when it isn't shipped. With
3
+ * `since`, only the releases above that version's heading.
4
+ */
5
+ export declare function readChangelog(since?: string): string[] | undefined;
6
+ export declare function ChangelogPanel({ since, height, onClose, }: {
7
+ since?: string;
4
8
  height: number;
5
9
  onClose: () => void;
6
10
  }): import("react").JSX.Element;
@@ -4,20 +4,25 @@ import { useMemo, useState } from 'react';
4
4
  import { Box, Text, useInput } from 'ink';
5
5
  import { t } from '../utils/i18n.js';
6
6
  import { ACCENT } from './Frame.js';
7
- /** CHANGELOG.md without its title, or undefined when it isn't shipped. */
8
- export function readChangelog() {
7
+ /**
8
+ * CHANGELOG.md without its title, or undefined when it isn't shipped. With
9
+ * `since`, only the releases above that version's heading.
10
+ */
11
+ export function readChangelog(since) {
9
12
  try {
10
- return readFileSync(new URL('../../CHANGELOG.md', import.meta.url), 'utf8')
13
+ const lines = readFileSync(new URL('../../CHANGELOG.md', import.meta.url), 'utf8')
11
14
  .replace(/^# .*\n/, '')
12
15
  .trim()
13
16
  .split('\n');
17
+ const end = since ? lines.indexOf(`## ${since}`) : -1;
18
+ return end > 0 ? lines.slice(0, end) : lines;
14
19
  }
15
20
  catch {
16
21
  return undefined;
17
22
  }
18
23
  }
19
- export function ChangelogPanel({ height, onClose, }) {
20
- const lines = useMemo(() => readChangelog(), []);
24
+ export function ChangelogPanel({ since, height, onClose, }) {
25
+ const lines = useMemo(() => readChangelog(since), [since]);
21
26
  const [top, setTop] = useState(0);
22
27
  const visible = Math.max(1, height - 1);
23
28
  const max = Math.max(0, (lines?.length ?? 0) - visible);
@@ -33,5 +38,7 @@ export function ChangelogPanel({ height, onClose, }) {
33
38
  else if (key.pageDown)
34
39
  setTop(n => Math.min(max, n + visible));
35
40
  });
36
- return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsxs(Text, { children: [_jsx(Text, { bold: true, children: t('Changelog') }), _jsxs(Text, { dimColor: true, children: [" \u00B7 ", t('↑↓ scroll · Esc close')] })] }), lines ? (lines.slice(top, top + visible).map((line, i) => line.startsWith('## ') ? (_jsx(Text, { bold: true, color: ACCENT, children: line.slice(3) }, top + i)) : (_jsx(Text, { wrap: "truncate", children: line || ' ' }, top + i)))) : (_jsx(Text, { dimColor: true, children: t('No changelog found.') }))] }));
41
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsxs(Text, { children: [_jsx(Text, { bold: true, children: since
42
+ ? t("What's new since {version}", { version: since })
43
+ : t('Changelog') }), _jsxs(Text, { dimColor: true, children: [" \u00B7 ", t('↑↓ scroll · Esc close')] })] }), lines ? (lines.slice(top, top + visible).map((line, i) => line.startsWith('## ') ? (_jsx(Text, { bold: true, color: ACCENT, children: line.slice(3) }, top + i)) : (_jsx(Text, { wrap: "truncate", children: line || ' ' }, top + i)))) : (_jsx(Text, { dimColor: true, children: t('No changelog found.') }))] }));
37
44
  }
@@ -4,6 +4,7 @@ interface Props {
4
4
  workspaceRoot?: string;
5
5
  version: string;
6
6
  minimal?: boolean;
7
+ updatedFrom?: string;
7
8
  }
8
- export declare function Shell({ apps: initialApps, workspaceRoot, version, minimal, }: Props): import("react").JSX.Element;
9
+ export declare function Shell({ apps: initialApps, workspaceRoot, version, minimal, updatedFrom, }: Props): import("react").JSX.Element;
9
10
  export {};
@@ -35,7 +35,7 @@ function useSize() {
35
35
  }, [stdout]);
36
36
  return size;
37
37
  }
38
- export function Shell({ apps: initialApps, workspaceRoot, version, minimal = false, }) {
38
+ export function Shell({ apps: initialApps, workspaceRoot, version, minimal = false, updatedFrom, }) {
39
39
  const { exit } = useApp();
40
40
  const { columns, rows } = useSize();
41
41
  const tasks = useTasks();
@@ -45,7 +45,7 @@ export function Shell({ apps: initialApps, workspaceRoot, version, minimal = fal
45
45
  const [selected, setSelected] = useState(onboard ? initialApps.length : 0);
46
46
  const [tab, setTab] = useState('overview');
47
47
  const [focus, setFocus] = useState(workspaceRoot && !onboard ? 'nav' : 'content');
48
- const [overlay, setOverlay] = useState(null);
48
+ const [overlay, setOverlay] = useState(updatedFrom ? { kind: 'changelog', since: updatedFrom } : null);
49
49
  const [filter, setFilter] = useState('');
50
50
  const [versions, setVersions] = useState({});
51
51
  const [versionRow, setVersionRow] = useState(0);
@@ -582,7 +582,7 @@ function renderOverlay(overlay, env) {
582
582
  case 'help':
583
583
  return _jsx(HelpPanel, { here: here, height: height, onClose: closeOverlay });
584
584
  case 'changelog':
585
- return _jsx(ChangelogPanel, { height: height, onClose: closeOverlay });
585
+ return (_jsx(ChangelogPanel, { since: overlay.since, height: height, onClose: closeOverlay }));
586
586
  case 'settings':
587
587
  return (_jsx(SettingsScreen, { onChanged: rerender, onClose: closeOverlay, onOpenWorkspace: openWorkspace }));
588
588
  case 'picker':
@@ -106,6 +106,7 @@ const sv = {
106
106
  "What's new": 'Nyheter',
107
107
  'changelog for every release': 'ändringslogg för varje version',
108
108
  Changelog: 'Ändringslogg',
109
+ "What's new since {version}": 'Nyheter sedan {version}',
109
110
  '↑↓ scroll · Esc close': '↑↓ scrolla · Esc stäng',
110
111
  'No changelog found.': 'Ingen ändringslogg hittades.',
111
112
  'Create addon': 'Skapa tillägg',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sitevision-cli",
3
- "version": "1.0.0-beta.28",
3
+ "version": "1.0.0-beta.29",
4
4
  "license": "MIT",
5
5
  "bin": {
6
6
  "svc": "dist/cli.js"