sitevision-cli 1.0.0-beta.26 → 1.0.0-beta.27
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 +23 -0
- package/dist/shell/AddonPicker.js +1 -1
- package/dist/shell/Changelog.d.ts +6 -0
- package/dist/shell/Changelog.js +37 -0
- package/dist/shell/CommandPalette.d.ts +4 -0
- package/dist/shell/CommandPalette.js +2 -2
- package/dist/shell/Help.d.ts +6 -0
- package/dist/shell/Help.js +31 -0
- package/dist/shell/Popover.d.ts +12 -0
- package/dist/shell/Popover.js +15 -0
- package/dist/shell/Settings.js +1 -1
- package/dist/shell/Shell.js +101 -75
- package/dist/shell/actions.d.ts +2 -0
- package/dist/shell/actions.js +0 -0
- package/dist/utils/i18n.js +14 -0
- package/package.json +3 -2
- package/readme.md +1 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 1.0.0-beta.25
|
|
4
|
+
|
|
5
|
+
- Deploying to an addon that does not exist yet now offers to create it and
|
|
6
|
+
deploy again. If the addon list cannot be read, the error suggests logging in
|
|
7
|
+
again instead, since an expired session fails the same way.
|
|
8
|
+
- A Create addon action appears in the command palette when a deploy has found
|
|
9
|
+
the addon missing.
|
|
10
|
+
- Creating a RESTApp or MCPServer addon no longer sends a category, which only
|
|
11
|
+
WebApp and widget addons use.
|
|
12
|
+
|
|
13
|
+
## 1.0.0-beta.24
|
|
14
|
+
|
|
15
|
+
- Deploying to a non-production environment uploads the signed zip when it is at
|
|
16
|
+
least as new as the build. The log names the zip that was uploaded.
|
|
17
|
+
- `x` in the Log tab wraps long lines immediately, and wrapped lines no longer
|
|
18
|
+
push the newest line out of view.
|
|
19
|
+
- Keys: switching environment moved from `E` to `v`, and refreshing versions
|
|
20
|
+
from `R` to `r`. Tab in the Config form moves between fields without leaving
|
|
21
|
+
the form.
|
|
22
|
+
- The bottom bar now shows force deploy (`P`), stop, config, login and settings.
|
|
23
|
+
- Running commands are stopped when `svc` exits.
|
|
@@ -47,7 +47,7 @@ export function AddonPicker({ domain, appType, initialQuery, load, onSelect, onC
|
|
|
47
47
|
});
|
|
48
48
|
const visible = Math.max(3, height - 6);
|
|
49
49
|
const start = Math.max(0, Math.min(index - visible + 1, matches.length - visible));
|
|
50
|
-
return (_jsxs(Box, { flexDirection: "column",
|
|
50
|
+
return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsxs(Text, { children: [_jsx(Text, { bold: true, children: t('Addon Repository') }), _jsxs(Text, { dimColor: true, children: [" ", domain] })] }), _jsxs(Text, { children: [_jsx(Text, { color: ACCENT, children: "\u276F " }), query, _jsx(Text, { inverse: true, children: " " }), _jsxs(Text, { dimColor: true, children: [' ', addons ? t('{n} of {m}', { n: matches.length, m: addons.length }) : ''] })] }), !addons && !error && (_jsxs(Text, { color: ACCENT, children: [_jsx(Spinner, { type: "dots" }), " ", _jsx(Text, { dimColor: true, children: t('fetching addons') })] })), error && _jsx(Text, { color: "red", children: error }), matches.slice(start, start + visible).map((a, i) => {
|
|
51
51
|
const selected = start + i === index;
|
|
52
52
|
return (_jsxs(Box, { justifyContent: "space-between", children: [_jsx(Box, { flexShrink: 1, marginRight: 1, children: _jsxs(Text, { backgroundColor: selected ? ACCENT : undefined, color: selected ? 'black' : undefined, wrap: "truncate", children: [' ', a.name] }) }), _jsx(Box, { flexShrink: 0, children: _jsx(Text, { dimColor: true, children: a.appType ?? a.type }) })] }, a.id));
|
|
53
53
|
}), _jsx(Text, { dimColor: true, children: t('↑↓ move · Enter select · Esc cancel') })] }));
|
|
@@ -0,0 +1,6 @@
|
|
|
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, }: {
|
|
4
|
+
height: number;
|
|
5
|
+
onClose: () => void;
|
|
6
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { useMemo, useState } from 'react';
|
|
4
|
+
import { Box, Text, useInput } from 'ink';
|
|
5
|
+
import { t } from '../utils/i18n.js';
|
|
6
|
+
import { ACCENT } from './Frame.js';
|
|
7
|
+
/** CHANGELOG.md without its title, or undefined when it isn't shipped. */
|
|
8
|
+
export function readChangelog() {
|
|
9
|
+
try {
|
|
10
|
+
return readFileSync(new URL('../../CHANGELOG.md', import.meta.url), 'utf8')
|
|
11
|
+
.replace(/^# .*\n/, '')
|
|
12
|
+
.trim()
|
|
13
|
+
.split('\n');
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export function ChangelogPanel({ height, onClose, }) {
|
|
20
|
+
const lines = useMemo(() => readChangelog(), []);
|
|
21
|
+
const [top, setTop] = useState(0);
|
|
22
|
+
const visible = Math.max(1, height - 1);
|
|
23
|
+
const max = Math.max(0, (lines?.length ?? 0) - visible);
|
|
24
|
+
useInput((input, key) => {
|
|
25
|
+
if (key.escape || key.return || input === 'q')
|
|
26
|
+
onClose();
|
|
27
|
+
else if (key.upArrow)
|
|
28
|
+
setTop(n => Math.max(0, n - 1));
|
|
29
|
+
else if (key.downArrow)
|
|
30
|
+
setTop(n => Math.min(max, n + 1));
|
|
31
|
+
else if (key.pageUp)
|
|
32
|
+
setTop(n => Math.max(0, n - visible));
|
|
33
|
+
else if (key.pageDown)
|
|
34
|
+
setTop(n => Math.min(max, n + visible));
|
|
35
|
+
});
|
|
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.') }))] }));
|
|
37
|
+
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { ProjectInfo } from '../types/index.js';
|
|
2
2
|
import { type Action } from './actions.js';
|
|
3
|
+
export declare const GROUPS: {
|
|
4
|
+
id: Action['group'];
|
|
5
|
+
label: string;
|
|
6
|
+
}[];
|
|
3
7
|
export declare function CommandPalette({ project, onRun, onClose, height, }: {
|
|
4
8
|
project: ProjectInfo;
|
|
5
9
|
onRun: (action: Action) => void;
|
|
@@ -4,7 +4,7 @@ import { Box, Text, useInput } from 'ink';
|
|
|
4
4
|
import { ACCENT } from './Frame.js';
|
|
5
5
|
import { actions, fuzzyMatch } from './actions.js';
|
|
6
6
|
import { t } from '../utils/i18n.js';
|
|
7
|
-
const GROUPS = [
|
|
7
|
+
export const GROUPS = [
|
|
8
8
|
{ id: 'app', label: 'APP' },
|
|
9
9
|
{ id: 'setup', label: 'SETUP' },
|
|
10
10
|
{ id: 'auth', label: 'AUTH' },
|
|
@@ -59,5 +59,5 @@ export function CommandPalette({ project, onRun, onClose, height, }) {
|
|
|
59
59
|
const detail = action.detail?.(project);
|
|
60
60
|
rows.push(_jsxs(Box, { justifyContent: "space-between", children: [_jsx(Box, { flexShrink: 1, marginRight: 1, children: _jsxs(Text, { backgroundColor: i === index ? ACCENT : undefined, color: i === index ? 'black' : undefined, dimColor: !enabled && i !== index, wrap: "truncate", children: [' ', t(action.label), detail && _jsxs(Text, { dimColor: i !== index, children: [" \u00B7 ", detail] })] }) }), _jsx(Box, { flexShrink: 0, children: _jsx(Text, { bold: true, color: ACCENT, children: action.key ?? '—' }) })] }, action.id));
|
|
61
61
|
}
|
|
62
|
-
return (_jsxs(Box, { flexDirection: "column",
|
|
62
|
+
return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsxs(Text, { children: [_jsx(Text, { bold: true, children: t('Commands') }), _jsxs(Text, { dimColor: true, children: [" ", project.manifest.id] })] }), _jsxs(Text, { children: [_jsx(Text, { color: ACCENT, children: "\u276F " }), query, _jsx(Text, { inverse: true, children: " " }), _jsxs(Text, { dimColor: true, children: [" ", t('{n} actions', { n: ordered.length })] })] }), rows, _jsx(Text, { dimColor: true, children: t('type to filter · ↑↓ move · Enter run · Esc close') })] }));
|
|
63
63
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text, useInput } from 'ink';
|
|
3
|
+
import { t } from '../utils/i18n.js';
|
|
4
|
+
import { ACCENT } from './Frame.js';
|
|
5
|
+
import { actions } from './actions.js';
|
|
6
|
+
import { GROUPS } from './CommandPalette.js';
|
|
7
|
+
const MOVE = [
|
|
8
|
+
['Tab', 'switch pane'],
|
|
9
|
+
['1–4', 'tabs'],
|
|
10
|
+
['←→', 'tabs'],
|
|
11
|
+
['/', 'commands'],
|
|
12
|
+
['?', 'help'],
|
|
13
|
+
['Esc', 'back'],
|
|
14
|
+
];
|
|
15
|
+
function Row({ keys, label }) {
|
|
16
|
+
return (_jsxs(Text, { wrap: "truncate", children: [_jsx(Text, { bold: true, color: ACCENT, children: keys.padEnd(6) }), label] }));
|
|
17
|
+
}
|
|
18
|
+
export function HelpPanel({ here, height, onClose, }) {
|
|
19
|
+
useInput((input, key) => {
|
|
20
|
+
if (key.escape || key.return || input === '?' || input === 'q')
|
|
21
|
+
onClose();
|
|
22
|
+
});
|
|
23
|
+
// Only keys not already listed elsewhere, e.g. f and x on the Log tab.
|
|
24
|
+
const local = here.filter(hint => actions.every(action => action.key !== hint.key) &&
|
|
25
|
+
MOVE.every(([keys]) => keys !== hint.key));
|
|
26
|
+
return (_jsxs(Box, { flexDirection: "column", paddingX: 1, height: height, overflow: "hidden", children: [_jsxs(Text, { children: [_jsx(Text, { bold: true, children: t('Keys') }), _jsxs(Text, { dimColor: true, children: [" \u00B7 ", t('Esc close')] })] }), _jsxs(Box, { flexWrap: "wrap", columnGap: 4, children: [_jsx(Box, { flexDirection: "column", marginTop: 1, children: GROUPS.map(group => (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, dimColor: true, children: t(group.label) }), actions.flatMap(action => action.group === group.id && action.key
|
|
27
|
+
? [
|
|
28
|
+
_jsx(Row, { keys: action.key, label: t(action.label) }, action.id),
|
|
29
|
+
]
|
|
30
|
+
: [])] }, group.id))) }), _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [local.length > 0 && (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, dimColor: true, children: t('Here') }), local.map(hint => (_jsx(Row, { keys: hint.key, label: hint.label }, hint.key + hint.label)))] })), _jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, dimColor: true, children: t('Move around') }), MOVE.map(([keys, label]) => (_jsx(Row, { keys: keys, label: t(label) }, keys + label)))] })] })] })] }));
|
|
31
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* A bordered box floating centred over the frame. Render it as the last child
|
|
4
|
+
* of the root so it draws on top; Ink paints in tree order.
|
|
5
|
+
*/
|
|
6
|
+
export declare function Popover({ columns, rows, width, height, children, }: {
|
|
7
|
+
columns: number;
|
|
8
|
+
rows: number;
|
|
9
|
+
width: number;
|
|
10
|
+
height: number;
|
|
11
|
+
children: ReactNode;
|
|
12
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
import { ACCENT } from './Frame.js';
|
|
4
|
+
/**
|
|
5
|
+
* A bordered box floating centred over the frame. Render it as the last child
|
|
6
|
+
* of the root so it draws on top; Ink paints in tree order.
|
|
7
|
+
*/
|
|
8
|
+
export function Popover({ columns, rows, width, height, children, }) {
|
|
9
|
+
const w = Math.max(20, Math.min(width, columns - 4));
|
|
10
|
+
const h = Math.max(6, Math.min(height, rows - 2));
|
|
11
|
+
// Ink only overwrites cells it writes to, so blank the interior first or the
|
|
12
|
+
// content underneath shows through around shorter lines.
|
|
13
|
+
const blank = ' '.repeat(w - 2);
|
|
14
|
+
return (_jsxs(Box, { position: "absolute", top: Math.floor((rows - h) / 2), left: Math.floor((columns - w) / 2), width: w, height: h, flexDirection: "column", borderStyle: "round", borderColor: ACCENT, children: [_jsx(Box, { position: "absolute", flexDirection: "column", children: Array.from({ length: h - 2 }, (_, i) => (_jsx(Text, { children: blank }, i))) }), _jsx(Box, { flexDirection: "column", height: h - 2, overflow: "hidden", children: children })] }));
|
|
15
|
+
}
|
package/dist/shell/Settings.js
CHANGED
|
@@ -85,7 +85,7 @@ export function SettingsScreen({ onChanged, onClose, onOpenWorkspace, }) {
|
|
|
85
85
|
setEditing(true);
|
|
86
86
|
}
|
|
87
87
|
});
|
|
88
|
-
return (_jsxs(Box, { flexDirection: "column",
|
|
88
|
+
return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsxs(Text, { children: [_jsx(Text, { bold: true, children: t('Settings') }), _jsxs(Text, { dimColor: true, children: [" \u00B7 ", t('stored in {file}', { file: settingsFile() })] })] }), ROWS.map((row, i) => {
|
|
89
89
|
const focused = i === cursor && !onWorkspaceRow;
|
|
90
90
|
const typing = focused && editing;
|
|
91
91
|
const chosen = typing ? draft : values[row.key];
|
package/dist/shell/Shell.js
CHANGED
|
@@ -15,6 +15,9 @@ import { CommandPalette } from './CommandPalette.js';
|
|
|
15
15
|
import { ConfigForm } from './ConfigForm.js';
|
|
16
16
|
import { AddonPicker } from './AddonPicker.js';
|
|
17
17
|
import { SettingsScreen } from './Settings.js';
|
|
18
|
+
import { HelpPanel } from './Help.js';
|
|
19
|
+
import { Popover } from './Popover.js';
|
|
20
|
+
import { ChangelogPanel } from './Changelog.js';
|
|
18
21
|
import { baseEnvironment, environmentColor, environmentNames, environmentProject, isProductionEnvironment, resolveEnvironment, } from '../utils/environments.js';
|
|
19
22
|
import { t } from '../utils/i18n.js';
|
|
20
23
|
import { actionForKey, authState, resolveDeployConfig, } from './actions.js';
|
|
@@ -129,6 +132,9 @@ export function Shell({ apps: initialApps, workspaceRoot, version, minimal = fal
|
|
|
129
132
|
openSettings() {
|
|
130
133
|
setOverlay({ kind: 'settings' });
|
|
131
134
|
},
|
|
135
|
+
openChangelog() {
|
|
136
|
+
setOverlay({ kind: 'changelog' });
|
|
137
|
+
},
|
|
132
138
|
environment: env,
|
|
133
139
|
isProduction,
|
|
134
140
|
cycleEnvironment() {
|
|
@@ -183,6 +189,9 @@ export function Shell({ apps: initialApps, workspaceRoot, version, minimal = fal
|
|
|
183
189
|
confirm: message => new Promise(resolve => {
|
|
184
190
|
setOverlay({ kind: 'confirm', message, resolve });
|
|
185
191
|
}),
|
|
192
|
+
openHelp() {
|
|
193
|
+
setOverlay({ kind: 'help' });
|
|
194
|
+
},
|
|
186
195
|
}),
|
|
187
196
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
188
197
|
[project, reload, notify, quit, workspaceRoot, apps.length, env, envList]);
|
|
@@ -237,7 +246,8 @@ export function Shell({ apps: initialApps, workspaceRoot, version, minimal = fal
|
|
|
237
246
|
notify(task.error ?? t('{v} activated', { v: executable.appVersion }), task.error ? 'error' : 'ok');
|
|
238
247
|
await fetchVersions();
|
|
239
248
|
}, [versions, project, versionRow, context, notify, fetchVersions]);
|
|
240
|
-
|
|
249
|
+
// A popover owns the keyboard; the form stays mounted underneath it.
|
|
250
|
+
const formActive = (tab === 'config' || settings) && focus === 'content' && !overlay;
|
|
241
251
|
const [editing, setEditing] = useState(false);
|
|
242
252
|
const pickAddon = useCallback(async () => new Promise(resolve => {
|
|
243
253
|
setOverlay({ kind: 'picker', resolve });
|
|
@@ -270,6 +280,10 @@ export function Shell({ apps: initialApps, workspaceRoot, version, minimal = fal
|
|
|
270
280
|
setOverlay({ kind: 'palette' });
|
|
271
281
|
return;
|
|
272
282
|
}
|
|
283
|
+
if (input === '?') {
|
|
284
|
+
setOverlay({ kind: 'help' });
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
273
287
|
// The config form uses Tab/Shift+Tab to move between fields.
|
|
274
288
|
if (key.tab && !formActive) {
|
|
275
289
|
setFilter('');
|
|
@@ -418,88 +432,96 @@ export function Shell({ apps: initialApps, workspaceRoot, version, minimal = fal
|
|
|
418
432
|
['/', 'commands'],
|
|
419
433
|
['q', 'quit'],
|
|
420
434
|
]);
|
|
421
|
-
const
|
|
422
|
-
?
|
|
423
|
-
:
|
|
424
|
-
?
|
|
425
|
-
:
|
|
426
|
-
?
|
|
427
|
-
|
|
435
|
+
const hereHints = focus === 'nav' && !settings
|
|
436
|
+
? navHints
|
|
437
|
+
: settings
|
|
438
|
+
? settingsHints
|
|
439
|
+
: tab === 'versions'
|
|
440
|
+
? h([
|
|
441
|
+
['a', 'activate'],
|
|
442
|
+
['r', 'refresh'],
|
|
443
|
+
['p', 'deploy'],
|
|
444
|
+
['P', 'force'],
|
|
445
|
+
['/', 'commands'],
|
|
446
|
+
['q', 'quit'],
|
|
447
|
+
])
|
|
448
|
+
: tab === 'log'
|
|
428
449
|
? h([
|
|
429
|
-
['
|
|
430
|
-
['
|
|
450
|
+
['f', 'follow'],
|
|
451
|
+
['x', 'wrap'],
|
|
452
|
+
['K', 'stop'],
|
|
431
453
|
['p', 'deploy'],
|
|
432
454
|
['P', 'force'],
|
|
433
455
|
['/', 'commands'],
|
|
434
456
|
['q', 'quit'],
|
|
435
457
|
])
|
|
436
|
-
: tab === '
|
|
437
|
-
?
|
|
438
|
-
[
|
|
439
|
-
|
|
440
|
-
|
|
458
|
+
: tab === 'config'
|
|
459
|
+
? editing
|
|
460
|
+
? h([
|
|
461
|
+
['Enter', 'save'],
|
|
462
|
+
['Esc', 'cancel'],
|
|
463
|
+
])
|
|
464
|
+
: formActive
|
|
465
|
+
? h([
|
|
466
|
+
['↑↓', 'field'],
|
|
467
|
+
['Enter', 'edit'],
|
|
468
|
+
['^O', 'pick addon'],
|
|
469
|
+
['y', 'sync'],
|
|
470
|
+
['/', 'commands'],
|
|
471
|
+
['q', 'quit'],
|
|
472
|
+
])
|
|
473
|
+
: h([
|
|
474
|
+
['Tab', 'edit'],
|
|
475
|
+
['y', 'sync'],
|
|
476
|
+
['l', 'login'],
|
|
477
|
+
['/', 'commands'],
|
|
478
|
+
['q', 'quit'],
|
|
479
|
+
])
|
|
480
|
+
: h([
|
|
481
|
+
['d', 'dev'],
|
|
482
|
+
['w', 'watch'],
|
|
483
|
+
['b', 'build'],
|
|
484
|
+
['s', 'sign'],
|
|
441
485
|
['p', 'deploy'],
|
|
442
486
|
['P', 'force'],
|
|
487
|
+
['v', 'env'],
|
|
488
|
+
['K', 'stop'],
|
|
489
|
+
['a', 'versions'],
|
|
490
|
+
['e', 'config'],
|
|
491
|
+
['i', 'install'],
|
|
492
|
+
['l', 'login'],
|
|
493
|
+
[',', 'settings'],
|
|
443
494
|
['/', 'commands'],
|
|
444
495
|
['q', 'quit'],
|
|
445
|
-
])
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
])
|
|
452
|
-
: formActive
|
|
453
|
-
? h([
|
|
454
|
-
['↑↓', 'field'],
|
|
455
|
-
['Enter', 'edit'],
|
|
456
|
-
['^O', 'pick addon'],
|
|
457
|
-
['y', 'sync'],
|
|
458
|
-
['/', 'commands'],
|
|
459
|
-
['q', 'quit'],
|
|
460
|
-
])
|
|
461
|
-
: h([
|
|
462
|
-
['Tab', 'edit'],
|
|
463
|
-
['y', 'sync'],
|
|
464
|
-
['l', 'login'],
|
|
465
|
-
['/', 'commands'],
|
|
466
|
-
['q', 'quit'],
|
|
467
|
-
])
|
|
468
|
-
: h([
|
|
469
|
-
['d', 'dev'],
|
|
470
|
-
['w', 'watch'],
|
|
471
|
-
['b', 'build'],
|
|
472
|
-
['s', 'sign'],
|
|
473
|
-
['p', 'deploy'],
|
|
474
|
-
['P', 'force'],
|
|
475
|
-
['v', 'env'],
|
|
476
|
-
['K', 'stop'],
|
|
477
|
-
['a', 'versions'],
|
|
478
|
-
['e', 'config'],
|
|
479
|
-
['i', 'install'],
|
|
480
|
-
['l', 'login'],
|
|
481
|
-
[',', 'settings'],
|
|
482
|
-
['/', 'commands'],
|
|
483
|
-
['q', 'quit'],
|
|
484
|
-
]);
|
|
496
|
+
]);
|
|
497
|
+
const hints = overlay
|
|
498
|
+
? h([['Esc', 'cancel']])
|
|
499
|
+
: editing
|
|
500
|
+
? hereHints
|
|
501
|
+
: [...hereHints, ...h([['?', 'help']])];
|
|
485
502
|
const right = running.length > 0 ? (_jsxs(Text, { children: [_jsx(Text, { color: ACCENT, children: _jsx(Spinner, { type: "dots" }) }), ' ', running[0].label, " ", running[0].appName, running.length > 1 && (_jsxs(Text, { dimColor: true, children: [" \u00B7 ", t('{n} tasks', { n: running.length })] }))] })) : notice ? (_jsx(Text, { color: { info: undefined, ok: 'green', warn: 'yellow', error: 'red' }[notice.level], wrap: "truncate", children: notice.text })) : (_jsx(Text, { dimColor: true, children: t('idle') }));
|
|
486
503
|
const closeOverlay = () => setOverlay(null);
|
|
487
|
-
const
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
504
|
+
const popoverWidth = Math.min(96, columns - 8);
|
|
505
|
+
const popoverHeight = Math.min(30, frameRows - 4);
|
|
506
|
+
const popover = overlay &&
|
|
507
|
+
renderOverlay(overlay, {
|
|
508
|
+
project,
|
|
509
|
+
here: hereHints,
|
|
510
|
+
closeOverlay,
|
|
511
|
+
run,
|
|
512
|
+
notify,
|
|
513
|
+
loadAddons,
|
|
514
|
+
height: popoverHeight - 2,
|
|
515
|
+
rerender: tick,
|
|
516
|
+
openWorkspace: workspaceRoot
|
|
517
|
+
? () => {
|
|
518
|
+
setOverlay(null);
|
|
519
|
+
setSelected(apps.length);
|
|
520
|
+
setFocus('content');
|
|
521
|
+
}
|
|
522
|
+
: undefined,
|
|
523
|
+
});
|
|
524
|
+
const content = settings && workspaceTarget ? (_jsx(ConfigForm, { project: workspaceTarget, active: formActive, width: narrow ? columns : columns - sidebar, height: contentHeight, pickAddon: async () => null, onSaved: () => {
|
|
503
525
|
reload();
|
|
504
526
|
notify(t('workspace config saved'), 'ok');
|
|
505
527
|
}, onEditingChange: setEditing }, "workspace")) : (_jsxs(_Fragment, { children: [tab === 'overview' && (_jsx(Overview, { project: project, tasks: tasks, height: contentHeight })), tab === 'config' && (_jsx(ConfigForm, { project: {
|
|
@@ -517,10 +539,10 @@ export function Shell({ apps: initialApps, workspaceRoot, version, minimal = fal
|
|
|
517
539
|
color: environmentColor(env, rawProject.devProperties),
|
|
518
540
|
}, version: version }), _jsxs(Box, { flexGrow: 1, height: mainHeight, children: [!narrow && (_jsx(Navigator, { apps: matches.map(i => apps[i]), groupOf: groupOf, selected: matches.indexOf(selected), focused: focus === 'nav', tasks: tasks, height: mainHeight, single: single, settingsSelected: settings, width: sidebar, filter: filter })), _jsxs(Box, { flexDirection: "column", width: narrow ? columns : columns - sidebar, overflow: "hidden", borderStyle: "single", borderLeft: false, borderRight: false, borderBottom: false, borderColor: focus === 'content' ? ACCENT : undefined, borderDimColor: focus !== 'content', children: [narrow && !single && (_jsx(NavigatorStrip, { apps: matches.map(i => apps[i]), selected: matches.indexOf(selected), focused: focus === 'nav', width: columns, filter: filter })), settings ? (_jsxs(Box, { paddingX: 1, children: [_jsx(Text, { bold: true, color: ACCENT, children: t('Workspace settings') }), _jsx(Text, { dimColor: true, children: onboard && configIncomplete(workspaceTarget?.base)
|
|
519
541
|
? t(' · new workspace: fill in once, every app inherits · Esc skips')
|
|
520
|
-
: t(' · shared .dev_properties.json at the root') })] })) : (_jsx(TabBar, { tab: tab, narrow: narrow, focused: focus === 'content' })), _jsx(Box, { flexDirection: "column", height: contentHeight, overflow: "hidden", alignItems: "flex-start", children: content })] })] }), _jsx(BottomBar, { hints: hints, right: right })] }));
|
|
542
|
+
: t(' · shared .dev_properties.json at the root') })] })) : (_jsx(TabBar, { tab: tab, narrow: narrow, focused: focus === 'content' })), _jsx(Box, { flexDirection: "column", height: contentHeight, overflow: "hidden", alignItems: "flex-start", children: content })] })] }), _jsx(BottomBar, { hints: hints, right: right }), popover && (_jsx(Popover, { columns: columns, rows: frameRows, width: popoverWidth, height: popoverHeight, children: popover }))] }));
|
|
521
543
|
}
|
|
522
544
|
function renderOverlay(overlay, env) {
|
|
523
|
-
const { project, closeOverlay, run, notify, loadAddons, height, rerender, openWorkspace, } = env;
|
|
545
|
+
const { project, here, closeOverlay, run, notify, loadAddons, height, rerender, openWorkspace, } = env;
|
|
524
546
|
switch (overlay.kind) {
|
|
525
547
|
case 'palette':
|
|
526
548
|
return (_jsx(CommandPalette, { project: project, onRun: run, onClose: closeOverlay, height: height }));
|
|
@@ -557,6 +579,10 @@ function renderOverlay(overlay, env) {
|
|
|
557
579
|
closeOverlay();
|
|
558
580
|
overlay.resolve(null);
|
|
559
581
|
} }));
|
|
582
|
+
case 'help':
|
|
583
|
+
return _jsx(HelpPanel, { here: here, height: height, onClose: closeOverlay });
|
|
584
|
+
case 'changelog':
|
|
585
|
+
return _jsx(ChangelogPanel, { height: height, onClose: closeOverlay });
|
|
560
586
|
case 'settings':
|
|
561
587
|
return (_jsx(SettingsScreen, { onChanged: rerender, onClose: closeOverlay, onOpenWorkspace: openWorkspace }));
|
|
562
588
|
case 'picker':
|
|
@@ -576,7 +602,7 @@ function Confirm({ message, onAnswer, }) {
|
|
|
576
602
|
else if (input === 'n' || input === 'N')
|
|
577
603
|
onAnswer(false);
|
|
578
604
|
});
|
|
579
|
-
return (_jsxs(Box, { flexDirection: "column",
|
|
605
|
+
return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsx(Text, { children: message }), _jsx(Text, { dimColor: true, children: t('y confirm · n cancel') })] }));
|
|
580
606
|
}
|
|
581
607
|
function TextPrompt({ label, onSubmit, onCancel, }) {
|
|
582
608
|
const [value, setValue] = useState('');
|
|
@@ -590,5 +616,5 @@ function TextPrompt({ label, onSubmit, onCancel, }) {
|
|
|
590
616
|
else if (input && !key.ctrl && !key.meta)
|
|
591
617
|
setValue(v => v + input);
|
|
592
618
|
});
|
|
593
|
-
return (_jsxs(Box, { flexDirection: "column",
|
|
619
|
+
return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsx(Text, { bold: true, children: label }), _jsxs(Text, { children: [_jsx(Text, { color: ACCENT, children: "\u276F " }), value, _jsx(Text, { inverse: true, children: " " })] }), _jsx(Text, { dimColor: true, children: t('Press Enter to submit, Esc to cancel') })] }));
|
|
594
620
|
}
|
package/dist/shell/actions.d.ts
CHANGED
|
@@ -16,6 +16,8 @@ export interface ActionContext {
|
|
|
16
16
|
setTab: (tab: Tab) => void;
|
|
17
17
|
openWorkspaceSettings?: () => void;
|
|
18
18
|
openSettings: () => void;
|
|
19
|
+
openHelp: () => void;
|
|
20
|
+
openChangelog: () => void;
|
|
19
21
|
environment: string;
|
|
20
22
|
isProduction: boolean;
|
|
21
23
|
cycleEnvironment: () => void;
|
package/dist/shell/actions.js
CHANGED
|
Binary file
|
package/dist/utils/i18n.js
CHANGED
|
@@ -94,6 +94,20 @@ const sv = {
|
|
|
94
94
|
'to {env}': 'till {env}',
|
|
95
95
|
'Switch environment': 'Byt miljö',
|
|
96
96
|
'Add environment': 'Lägg till miljö',
|
|
97
|
+
Help: 'Hjälp',
|
|
98
|
+
'every key in one place': 'alla tangenter på ett ställe',
|
|
99
|
+
Keys: 'Tangenter',
|
|
100
|
+
'Esc close': 'Esc stäng',
|
|
101
|
+
Here: 'Här',
|
|
102
|
+
'Move around': 'Förflytta dig',
|
|
103
|
+
'switch pane': 'byt panel',
|
|
104
|
+
tabs: 'flikar',
|
|
105
|
+
help: 'hjälp',
|
|
106
|
+
"What's new": 'Nyheter',
|
|
107
|
+
'changelog for every release': 'ändringslogg för varje version',
|
|
108
|
+
Changelog: 'Ändringslogg',
|
|
109
|
+
'↑↓ scroll · Esc close': '↑↓ scrolla · Esc stäng',
|
|
110
|
+
'No changelog found.': 'Ingen ändringslogg hittades.',
|
|
97
111
|
'Create addon': 'Skapa tillägg',
|
|
98
112
|
'Create addon failed': 'Kunde inte skapa tillägget',
|
|
99
113
|
'addon {addon} created': 'tillägget {addon} skapat',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sitevision-cli",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.27",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"bin": {
|
|
6
6
|
"svc": "dist/cli.js"
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
"release:beta": "./scripts/publish-beta.sh"
|
|
18
18
|
},
|
|
19
19
|
"files": [
|
|
20
|
-
"dist"
|
|
20
|
+
"dist",
|
|
21
|
+
"CHANGELOG.md"
|
|
21
22
|
],
|
|
22
23
|
"dependencies": {
|
|
23
24
|
"@napi-rs/keyring": "^1.3.0",
|
package/readme.md
CHANGED
|
@@ -59,6 +59,7 @@ and `p` to deploy and activate.
|
|
|
59
59
|
| `K` | Stop running tasks |
|
|
60
60
|
| `1`–`4` | Overview · Config · Versions · Log |
|
|
61
61
|
| `/` | Command palette |
|
|
62
|
+
| `?` | Help: every key in one place |
|
|
62
63
|
| `,` | Settings (language, intro animation) |
|
|
63
64
|
| `Tab` / `Esc` | Switch pane / back |
|
|
64
65
|
| `q` | Quit |
|