veryfront 0.0.83 → 0.0.86
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/README.md +21 -60
- package/esm/deno.js +1 -1
- package/esm/src/cli/app/components/list-select.js +2 -2
- package/esm/src/cli/app/index.d.ts +1 -1
- package/esm/src/cli/app/index.d.ts.map +1 -1
- package/esm/src/cli/app/index.js +26 -33
- package/esm/src/cli/app/state.d.ts +3 -0
- package/esm/src/cli/app/state.d.ts.map +1 -1
- package/esm/src/cli/app/state.js +4 -0
- package/esm/src/cli/app/views/dashboard.d.ts.map +1 -1
- package/esm/src/cli/app/views/dashboard.js +46 -58
- package/esm/src/cli/app/views/startup.d.ts +39 -0
- package/esm/src/cli/app/views/startup.d.ts.map +1 -0
- package/esm/src/cli/app/views/startup.js +103 -0
- package/esm/src/cli/commands/dev.js +2 -2
- package/esm/src/cli/commands/new.js +1 -1
- package/esm/src/cli/ui/colors.d.ts +8 -0
- package/esm/src/cli/ui/colors.d.ts.map +1 -1
- package/esm/src/cli/ui/colors.js +34 -0
- package/esm/src/cli/ui/dot-matrix.d.ts +8 -0
- package/esm/src/cli/ui/dot-matrix.d.ts.map +1 -1
- package/esm/src/cli/ui/dot-matrix.js +67 -2
- package/esm/src/cli/ui/tui.js +1 -1
- package/esm/src/modules/react-loader/ssr-module-loader/loader.d.ts.map +1 -1
- package/esm/src/modules/react-loader/ssr-module-loader/loader.js +28 -6
- package/esm/src/transforms/esm/http-cache.d.ts.map +1 -1
- package/esm/src/transforms/esm/http-cache.js +25 -17
- package/package.json +1 -1
- package/src/deno.js +1 -1
- package/src/src/cli/app/components/list-select.ts +2 -2
- package/src/src/cli/app/index.ts +34 -35
- package/src/src/cli/app/state.ts +7 -0
- package/src/src/cli/app/views/dashboard.ts +47 -61
- package/src/src/cli/app/views/startup.ts +132 -0
- package/src/src/cli/commands/dev.ts +2 -2
- package/src/src/cli/commands/new.ts +1 -1
- package/src/src/cli/ui/colors.ts +37 -0
- package/src/src/cli/ui/dot-matrix.ts +77 -1
- package/src/src/cli/ui/tui.ts +1 -1
- package/src/src/modules/react-loader/ssr-module-loader/loader.ts +43 -30
- package/src/src/transforms/esm/http-cache.ts +26 -17
package/README.md
CHANGED
|
@@ -1,73 +1,34 @@
|
|
|
1
|
-
# Veryfront
|
|
1
|
+
# Veryfront Code
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
[](https://github.com/veryfront/veryfront-renderer/actions/workflows/ci.yml)
|
|
5
|
-
[](https://opensource.org/licenses/MIT)
|
|
6
|
-
|
|
7
|
-
The all-in-one React framework for building AI-powered applications and agents.
|
|
8
|
-
|
|
9
|
-
## Features
|
|
10
|
-
|
|
11
|
-
- **Zero config** — Auto-discovery from file structure
|
|
12
|
-
- **Multi-runtime** — Deno, Node.js, Bun, Cloudflare Workers
|
|
13
|
-
- **Full-stack React** — SSR, SSG, ISR, streaming
|
|
14
|
-
- **MCP built-in** — Model Context Protocol server
|
|
15
|
-
- **Production-ready** — Rate limiting, caching, observability
|
|
16
|
-
|
|
17
|
-
## Quick Start
|
|
3
|
+
The simplest way to build AI-powered apps.
|
|
18
4
|
|
|
19
5
|
```bash
|
|
20
6
|
npx veryfront
|
|
21
7
|
```
|
|
22
8
|
|
|
23
|
-
## Commands
|
|
24
|
-
|
|
25
|
-
| Command | What it does | When to use |
|
|
26
|
-
| ---------------------------- | ---------------------------------- | ---------------------------------------------- |
|
|
27
|
-
| `npx veryfront` | Starts TUI dashboard on port 8080 | Explore projects and develop interactively |
|
|
28
|
-
| `npx veryfront init` | Create a new project | Start a new Veryfront app from scratch |
|
|
29
|
-
| `npx veryfront dev` | Starts dev server on port 3000 | Develop a specific project with HMR |
|
|
30
|
-
| `npx veryfront build` | Production build | Prepare app for deployment |
|
|
31
|
-
| `npx veryfront deploy` | Deploy to Veryfront Cloud | Ship app to production |
|
|
32
|
-
| `npx veryfront --port 3001` | TUI on custom port | Port 8080 is busy |
|
|
33
|
-
| `npx veryfront --headless` | Server without TUI | Running in CI or want logs only |
|
|
34
|
-
| `npx veryfront doctor` | Check system health | Something isn't working, need diagnostics |
|
|
35
|
-
| `npx veryfront --help` | Show all commands | See what's available |
|
|
36
|
-
|
|
37
|
-
## Project Structure
|
|
38
|
-
|
|
39
9
|
```
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
│
|
|
43
|
-
│
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
10
|
+
╭──────────────────────────────────────────────────────────╮
|
|
11
|
+
│ │
|
|
12
|
+
│ ○ ○ ○ ○ ○ ○ ○ │
|
|
13
|
+
│ ○ ● ● ● ○ ○ ○ Veryfront Code is now running │
|
|
14
|
+
│ ○ ● ● ● ○ ○ ○ │
|
|
15
|
+
│ ○ ● ● ○ ● ● ○ Url http://veryfront.me:8080 │
|
|
16
|
+
│ ○ ○ ○ ● ● ● ○ Mcp http://veryfront.me:9999/mcp │
|
|
17
|
+
│ ○ ○ ○ ● ● ● ○ │
|
|
18
|
+
│ ○ ○ ○ ○ ○ ○ ○ │
|
|
19
|
+
│ │
|
|
20
|
+
╰──────────────────────────────────────────────────────────╯
|
|
49
21
|
```
|
|
50
22
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
## Documentation
|
|
54
|
-
|
|
55
|
-
- [Getting Started](https://veryfront.com/docs/framework)
|
|
56
|
-
- [Agents](https://veryfront.com/docs/framework/agents)
|
|
57
|
-
- [Tools](https://veryfront.com/docs/framework/tools)
|
|
58
|
-
- [Workflows](https://veryfront.com/docs/framework/workflows)
|
|
59
|
-
- [MCP Server](https://veryfront.com/docs/framework/mcp)
|
|
60
|
-
|
|
61
|
-
## Community
|
|
62
|
-
|
|
63
|
-
- [Discord](https://discord.gg/veryfront)
|
|
64
|
-
- [X](https://x.com/veryfrontdev)
|
|
65
|
-
- [GitHub Discussions](https://github.com/veryfront/veryfront/discussions)
|
|
23
|
+
One command. Zero config. Just build.
|
|
66
24
|
|
|
67
|
-
|
|
25
|
+
[Docs](https://veryfront.com/docs/framework) · [Discord](https://discord.gg/veryfront) · [X](https://x.com/veryfrontdev) · MIT
|
|
68
26
|
|
|
69
|
-
|
|
27
|
+
## Releasing
|
|
70
28
|
|
|
71
|
-
|
|
29
|
+
Create a new release with `gh release create vX.X.X`. The publish workflow runs automatically and takes ~4-5 minutes:
|
|
72
30
|
|
|
73
|
-
|
|
31
|
+
1. Builds native binaries for 5 platforms (macOS arm64/x64, Linux x64/arm64, Windows x64)
|
|
32
|
+
2. Publishes to npm with provenance
|
|
33
|
+
3. Creates GitHub releases in both repos
|
|
34
|
+
4. Updates Homebrew formula
|
package/esm/deno.js
CHANGED
|
@@ -123,9 +123,9 @@ export function renderList(state, options = {}) {
|
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
125
|
if (start > 0)
|
|
126
|
-
lines.unshift(` ${dim("
|
|
126
|
+
lines.unshift(` ${dim("↑")} ${dim("more above")}`);
|
|
127
127
|
if (end < state.items.length)
|
|
128
|
-
lines.push(` ${dim("
|
|
128
|
+
lines.push(` ${dim("↓")} ${dim("more below")}`);
|
|
129
129
|
return lines.join("\n");
|
|
130
130
|
}
|
|
131
131
|
/**
|
|
@@ -35,7 +35,7 @@ export interface App {
|
|
|
35
35
|
*/
|
|
36
36
|
export declare function createApp(config: AppConfig): App;
|
|
37
37
|
/**
|
|
38
|
-
* Show startup animation
|
|
38
|
+
* Show startup animation with boxed view and shimmer effect
|
|
39
39
|
*/
|
|
40
40
|
export declare function showStartup(steps: string[]): Promise<void>;
|
|
41
41
|
export type { AppState } from "./state.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/src/cli/app/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/src/cli/app/index.ts"],"names":[],"mappings":"AAkCA,OAAO,EAEL,KAAK,QAAQ,EAcb,KAAK,YAAY,EAQlB,MAAM,YAAY,CAAC;AASpB,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,QAAQ,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,GAAG;IAClB,oBAAoB;IACpB,KAAK,IAAI,IAAI,CAAC;IACd,wCAAwC;IACxC,IAAI,IAAI,IAAI,CAAC;IACb,mBAAmB;IACnB,MAAM,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;IACpC,wBAAwB;IACxB,QAAQ,IAAI,QAAQ,CAAC;IACrB,8BAA8B;IAC9B,MAAM,IAAI,IAAI,CAAC;IACf,uBAAuB;IACvB,cAAc,IAAI,IAAI,CAAC;IACvB,mBAAmB;IACnB,QAAQ,IAAI,IAAI,CAAC;IACjB,mBAAmB;IACnB,WAAW,IAAI,IAAI,CAAC;IACpB,uCAAuC;IACvC,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvE,qDAAqD;IACrD,gBAAgB,IAAI,MAAM,IAAI,CAAC;CAChC;AAuMD;;GAEG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,SAAS,GAAG,GAAG,CA4mChD;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA2BhE;AAED,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,6BAA6B,CAAC"}
|
package/esm/src/cli/app/index.js
CHANGED
|
@@ -11,12 +11,14 @@ import { join } from "../../platform/compat/path/index.js";
|
|
|
11
11
|
import { getRuntimeEnv } from "../../config/runtime-env.js";
|
|
12
12
|
import { getStdinReader, setRawMode } from "../../platform/compat/stdin.js";
|
|
13
13
|
import { cursor, screen, SPINNER_FRAMES } from "../ui/ansi.js";
|
|
14
|
-
import { brand, dim
|
|
14
|
+
import { brand, dim } from "../ui/colors.js";
|
|
15
|
+
import { getTerminalWidth } from "../ui/layout.js";
|
|
15
16
|
import { moveDown, moveUp, selectByNumber } from "./components/list-select.js";
|
|
16
17
|
import { renderDashboard, renderEmptyState } from "./views/dashboard.js";
|
|
18
|
+
import { createStartupState, incrementFrame, renderStartup, setStepActive, } from "./views/startup.js";
|
|
17
19
|
import { openInBrowser, openInIDE, openInStudio, openMCPSettings } from "./actions.js";
|
|
18
20
|
import { initCommand } from "../commands/init/init-command.js";
|
|
19
|
-
import { addLog, createInitialState, endInput, getActiveSelection, goBack, navigateTo, scrollLogs, setActiveList, setExamples, setProjects, setTemplates, startInput, toggleLogsExpanded, updateActiveList, updateInputValue, updateMCP, updateRemote, updateServer, } from "./state.js";
|
|
21
|
+
import { addLog, createInitialState, endInput, getActiveSelection, goBack, navigateTo, scrollLogs, setActiveList, setExamples, setProjects, setTemplates, startInput, toggleHelp, toggleLogsExpanded, updateActiveList, updateInputValue, updateMCP, updateRemote, updateServer, } from "./state.js";
|
|
20
22
|
import { handleInputKey, renderInput, renderLogs } from "./components/inline-input.js";
|
|
21
23
|
import { login, logout, validateToken } from "../auth/login.js";
|
|
22
24
|
import { readToken } from "../auth/token-store.js";
|
|
@@ -430,10 +432,12 @@ export function createApp(config) {
|
|
|
430
432
|
content = renderDashboard(state);
|
|
431
433
|
}
|
|
432
434
|
const parts = [content];
|
|
435
|
+
// Divider width matches the box in dashboard
|
|
436
|
+
const dividerWidth = Math.min(getTerminalWidth() - 4, 80);
|
|
433
437
|
if (state.logs.length > 0) {
|
|
434
438
|
const logsHeader = state.logsExpanded ? "▼ Logs" : "▶ Logs";
|
|
435
439
|
parts.push("");
|
|
436
|
-
parts.push(
|
|
440
|
+
parts.push(dim("─".repeat(dividerWidth)));
|
|
437
441
|
parts.push(` ${dim(logsHeader)} ${dim(`(${state.logs.length})`)} ${dim("l")} ${dim("toggle")} ${state.logsExpanded ? `${dim("↑↓")} ${dim("scroll")}` : ""}`);
|
|
438
442
|
parts.push(renderLogs(state.logs, {
|
|
439
443
|
maxLines: state.logsExpanded ? 15 : 3,
|
|
@@ -443,13 +447,13 @@ export function createApp(config) {
|
|
|
443
447
|
}
|
|
444
448
|
if (state.input.active) {
|
|
445
449
|
parts.push("");
|
|
446
|
-
parts.push(
|
|
450
|
+
parts.push(dim("─".repeat(dividerWidth)));
|
|
447
451
|
parts.push(renderInput(state.input));
|
|
448
452
|
}
|
|
449
453
|
if (!isInteractiveMode)
|
|
450
454
|
return;
|
|
451
455
|
write(cursor.moveTo(1, 1) + screen.clearDown);
|
|
452
|
-
write(parts.join("\n"));
|
|
456
|
+
write("\n" + parts.join("\n"));
|
|
453
457
|
}
|
|
454
458
|
function update(updater) {
|
|
455
459
|
state = updater(state);
|
|
@@ -792,7 +796,7 @@ export function createApp(config) {
|
|
|
792
796
|
return;
|
|
793
797
|
}
|
|
794
798
|
if (key === "?") {
|
|
795
|
-
update(
|
|
799
|
+
update(toggleHelp());
|
|
796
800
|
return;
|
|
797
801
|
}
|
|
798
802
|
if (key === "m" && state.mcp.enabled) {
|
|
@@ -1212,40 +1216,29 @@ export function createApp(config) {
|
|
|
1212
1216
|
};
|
|
1213
1217
|
}
|
|
1214
1218
|
/**
|
|
1215
|
-
* Show startup animation
|
|
1219
|
+
* Show startup animation with boxed view and shimmer effect
|
|
1216
1220
|
*/
|
|
1217
1221
|
export async function showStartup(steps) {
|
|
1218
1222
|
const write = (text) => writeStdout(text);
|
|
1219
1223
|
write(screen.altOn + cursor.hide);
|
|
1224
|
+
let startupState = createStartupState(steps);
|
|
1225
|
+
// Show each step with spinning avatar animation
|
|
1220
1226
|
for (let i = 0; i < steps.length; i++) {
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
const
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
...completed,
|
|
1230
|
-
current,
|
|
1231
|
-
...pending,
|
|
1232
|
-
"",
|
|
1233
|
-
].join("\n");
|
|
1234
|
-
write(cursor.moveTo(1, 1) + screen.clearDown + content);
|
|
1235
|
-
await new Promise((r) => dntShim.setTimeout(r, 200));
|
|
1227
|
+
startupState = setStepActive(startupState, i);
|
|
1228
|
+
// Animate spinning avatar (16 frames at 60ms = ~1s per step for full rotation)
|
|
1229
|
+
const framesPerStep = 16;
|
|
1230
|
+
for (let f = 0; f < framesPerStep; f++) {
|
|
1231
|
+
write(cursor.moveTo(1, 1) + screen.clearDown + "\n" + renderStartup(startupState));
|
|
1232
|
+
startupState = incrementFrame(startupState);
|
|
1233
|
+
await new Promise((r) => dntShim.setTimeout(r, 60));
|
|
1234
|
+
}
|
|
1236
1235
|
}
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
"",
|
|
1242
|
-
...allComplete,
|
|
1243
|
-
"",
|
|
1244
|
-
].join("\n");
|
|
1245
|
-
write(cursor.moveTo(1, 1) + screen.clearDown + finalContent);
|
|
1246
|
-
await new Promise((r) => dntShim.setTimeout(r, 300));
|
|
1236
|
+
// Mark all steps done - logo fills up and holds before transitioning
|
|
1237
|
+
startupState = setStepActive(startupState, steps.length);
|
|
1238
|
+
write(cursor.moveTo(1, 1) + screen.clearDown + "\n" + renderStartup(startupState));
|
|
1239
|
+
await new Promise((r) => dntShim.setTimeout(r, 400));
|
|
1247
1240
|
// Don't exit alternate screen - let app.start() continue in it
|
|
1248
|
-
//
|
|
1241
|
+
// Dashboard takes over directly from here
|
|
1249
1242
|
}
|
|
1250
1243
|
export * from "./state.js";
|
|
1251
1244
|
export * from "./actions.js";
|
|
@@ -84,6 +84,8 @@ export interface AppState {
|
|
|
84
84
|
authProviderIndex: number;
|
|
85
85
|
/** New project option index (0=template, 1=example, 2=scratch) */
|
|
86
86
|
newProjectIndex: number;
|
|
87
|
+
/** Show expanded help */
|
|
88
|
+
showHelp: boolean;
|
|
87
89
|
}
|
|
88
90
|
export declare function createInitialState(): AppState;
|
|
89
91
|
export type StateUpdater = (state: AppState) => AppState;
|
|
@@ -117,6 +119,7 @@ export declare function endInput(): StateUpdater;
|
|
|
117
119
|
export declare function addLog(level: LogEntry["level"], message: string, meta?: LogMeta): StateUpdater;
|
|
118
120
|
export declare function clearLogs(): StateUpdater;
|
|
119
121
|
export declare function toggleLogsExpanded(): StateUpdater;
|
|
122
|
+
export declare function toggleHelp(): StateUpdater;
|
|
120
123
|
export declare function scrollLogs(direction: "up" | "down"): StateUpdater;
|
|
121
124
|
export declare function getActiveSelection(state: AppState): ListItem<ProjectInfo> | undefined;
|
|
122
125
|
//# sourceMappingURL=state.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../../src/src/cli/app/state.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../../src/src/cli/app/state.ts"],"names":[],"mappings":"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"}
|
package/esm/src/cli/app/state.js
CHANGED
|
@@ -49,6 +49,7 @@ export function createInitialState() {
|
|
|
49
49
|
logScroll: 0,
|
|
50
50
|
authProviderIndex: 0,
|
|
51
51
|
newProjectIndex: 0,
|
|
52
|
+
showHelp: false,
|
|
52
53
|
};
|
|
53
54
|
}
|
|
54
55
|
export function setProjects(projects) {
|
|
@@ -192,6 +193,9 @@ export function toggleLogsExpanded() {
|
|
|
192
193
|
logScroll: 0,
|
|
193
194
|
});
|
|
194
195
|
}
|
|
196
|
+
export function toggleHelp() {
|
|
197
|
+
return (state) => ({ ...state, showHelp: !state.showHelp });
|
|
198
|
+
}
|
|
195
199
|
export function scrollLogs(direction) {
|
|
196
200
|
return (state) => {
|
|
197
201
|
if (!state.logsExpanded)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../../../../src/src/cli/app/views/dashboard.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CA4EvD;
|
|
1
|
+
{"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../../../../src/src/cli/app/views/dashboard.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CA4EvD;AAmFD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAY5D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Main view showing server status, projects, and quick actions.
|
|
5
5
|
*/
|
|
6
6
|
import { box } from "../../ui/box.js";
|
|
7
|
-
import { brand, dim, error, muted
|
|
7
|
+
import { brand, dim, error, muted } from "../../ui/colors.js";
|
|
8
8
|
import { getTerminalWidth } from "../../ui/layout.js";
|
|
9
9
|
import { getAgentFaceWithText } from "../../ui/dot-matrix.js";
|
|
10
10
|
import { renderList } from "../components/list-select.js";
|
|
@@ -21,7 +21,7 @@ export function renderDashboard(state) {
|
|
|
21
21
|
const hasRemoteProjects = state.remote.user && state.remote.projects.length > 0;
|
|
22
22
|
if (hasProjects) {
|
|
23
23
|
const isActive = state.activeList === "projects";
|
|
24
|
-
lines.push(renderSection("Local
|
|
24
|
+
lines.push(renderSection("Local", state.projects.items.length, isActive));
|
|
25
25
|
lines.push(renderList(state.projects, {
|
|
26
26
|
maxWidth: maxListWidth,
|
|
27
27
|
visibleCount: 5,
|
|
@@ -36,9 +36,9 @@ export function renderDashboard(state) {
|
|
|
36
36
|
const start = state.remote.scrollOffset;
|
|
37
37
|
const end = Math.min(start + visibleCount, state.remote.projects.length);
|
|
38
38
|
const visibleProjects = state.remote.projects.slice(start, end);
|
|
39
|
-
lines.push(renderSection("Remote
|
|
39
|
+
lines.push(renderSection("Remote", state.remote.projects.length, isRemoteActive));
|
|
40
40
|
if (start > 0) {
|
|
41
|
-
lines.push(` ${dim("
|
|
41
|
+
lines.push(` ${dim("↑")} ${dim("more above")}`);
|
|
42
42
|
}
|
|
43
43
|
visibleProjects.forEach((p, i) => {
|
|
44
44
|
const actualIndex = start + i;
|
|
@@ -54,7 +54,7 @@ export function renderDashboard(state) {
|
|
|
54
54
|
lines.push(`${cursor} ${num} ${label}`);
|
|
55
55
|
});
|
|
56
56
|
if (end < state.remote.projects.length) {
|
|
57
|
-
lines.push(` ${dim("
|
|
57
|
+
lines.push(` ${dim("↓")} ${dim("more below")}`);
|
|
58
58
|
}
|
|
59
59
|
lines.push("");
|
|
60
60
|
}
|
|
@@ -72,24 +72,24 @@ export function renderDashboard(state) {
|
|
|
72
72
|
return lines.join("\n");
|
|
73
73
|
}
|
|
74
74
|
/**
|
|
75
|
-
* Render the banner with agent face and server info
|
|
75
|
+
* Render the banner with agent face and server info inside a box
|
|
76
76
|
*/
|
|
77
77
|
function renderBanner(state) {
|
|
78
|
-
const
|
|
79
|
-
const mcpDot = state.mcp.enabled ? success("●") : dim("○");
|
|
78
|
+
const termWidth = Math.min(getTerminalWidth() - 4, 80);
|
|
80
79
|
const textLines = [];
|
|
81
|
-
textLines.push(
|
|
82
|
-
textLines.push(
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
80
|
+
textLines.push("");
|
|
81
|
+
textLines.push(`${brand("Veryfront Code")} ${dim("is now running")}`);
|
|
82
|
+
textLines.push("");
|
|
83
|
+
// Server URL and MCP URL - always reserve both lines to prevent jumps
|
|
84
|
+
textLines.push(`${dim("Url")} ${brand(state.server.url)}`);
|
|
85
|
+
if (state.mcp.enabled && state.mcp.transport === "http") {
|
|
86
|
+
const port = state.mcp.httpPort ?? 9999;
|
|
87
|
+
textLines.push(`${dim("Mcp")} ${brand(`http://veryfront.me:${port}/mcp`)}`);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
textLines.push("");
|
|
92
91
|
}
|
|
92
|
+
// Errors/warnings on separate line if any
|
|
93
93
|
const { errors, warnings } = state.server;
|
|
94
94
|
if (errors > 0 || warnings > 0) {
|
|
95
95
|
const parts = [];
|
|
@@ -99,50 +99,49 @@ function renderBanner(state) {
|
|
|
99
99
|
parts.push(muted(`${warnings} warnings`));
|
|
100
100
|
textLines.push(parts.join(" "));
|
|
101
101
|
}
|
|
102
|
-
|
|
102
|
+
// Pad to 7 text lines (matching avatar height) for consistent title position
|
|
103
|
+
while (textLines.length < 7) {
|
|
104
|
+
textLines.push("");
|
|
105
|
+
}
|
|
106
|
+
const content = getAgentFaceWithText(textLines, {
|
|
103
107
|
litColor: "\x1b[38;2;252;143;93m", // Veryfront brand orange
|
|
104
108
|
});
|
|
109
|
+
return box(content, {
|
|
110
|
+
style: "rounded",
|
|
111
|
+
width: termWidth,
|
|
112
|
+
paddingX: 2,
|
|
113
|
+
paddingY: 1,
|
|
114
|
+
borderColor: "\x1b[2m", // Dim to match footer
|
|
115
|
+
});
|
|
105
116
|
}
|
|
106
117
|
/**
|
|
107
118
|
* Render a section header
|
|
108
119
|
*/
|
|
109
|
-
function renderSection(title,
|
|
120
|
+
function renderSection(title, _count, isActive = true) {
|
|
110
121
|
const indicator = isActive ? brand("›") : " ";
|
|
111
122
|
const titleText = isActive ? title : dim(title);
|
|
112
|
-
return ` ${indicator} ${titleText}
|
|
123
|
+
return ` ${indicator} ${titleText}`;
|
|
113
124
|
}
|
|
114
125
|
/**
|
|
115
126
|
* Render the help bar at the bottom
|
|
116
127
|
*/
|
|
117
128
|
function renderHelpBar(state) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
// Count sections for tab switching
|
|
123
|
-
const sectionCount = [hasProjects, hasExamples, hasRemoteProjects].filter(Boolean).length;
|
|
124
|
-
if (sectionCount > 1) {
|
|
125
|
-
parts.push(dim("tab switch"));
|
|
126
|
-
}
|
|
127
|
-
parts.push(dim("↑↓ nav"));
|
|
128
|
-
if (hasProjects || hasExamples || hasRemoteProjects) {
|
|
129
|
-
parts.push(dim("o open"), dim("s studio"), dim("i ide"));
|
|
129
|
+
// Minimal by default, ? reveals all
|
|
130
|
+
if (!state.showHelp) {
|
|
131
|
+
const userInfo = state.remote.user ? ` ${dim("-")} ${brand(state.remote.user.email)}` : "";
|
|
132
|
+
return ` ${dim("↑↓ select enter open ? more q quit")}${userInfo}`;
|
|
130
133
|
}
|
|
134
|
+
// Expanded help
|
|
135
|
+
const lines = [];
|
|
136
|
+
lines.push(` ${dim("o")} open ${dim("s")} studio ${dim("i")} ide`);
|
|
131
137
|
if (!state.remote.user) {
|
|
132
|
-
|
|
138
|
+
lines.push(` ${dim("n")} new ${dim("a")} login`);
|
|
133
139
|
}
|
|
134
140
|
else {
|
|
135
|
-
|
|
136
|
-
if (state.activeList === "projects") {
|
|
137
|
-
parts.push(dim("p pull"), dim("u push"));
|
|
138
|
-
}
|
|
139
|
-
else if (state.activeList === "remoteProjects") {
|
|
140
|
-
parts.push(dim("p pull"));
|
|
141
|
-
}
|
|
142
|
-
parts.push(dim("n new"), dim("x logout"));
|
|
141
|
+
lines.push(` ${dim("n")} new ${dim("p")} pull ${dim("u")} push ${dim("x")} logout`);
|
|
143
142
|
}
|
|
144
|
-
|
|
145
|
-
return
|
|
143
|
+
lines.push(` ${dim("? hide q quit")}`);
|
|
144
|
+
return lines.join("\n");
|
|
146
145
|
}
|
|
147
146
|
/**
|
|
148
147
|
* Render a boxed dashboard (alternative style)
|
|
@@ -152,7 +151,7 @@ export function renderDashboardBoxed(state) {
|
|
|
152
151
|
const content = renderDashboard(state);
|
|
153
152
|
return box(content, {
|
|
154
153
|
style: "rounded",
|
|
155
|
-
title: "Veryfront",
|
|
154
|
+
title: "Veryfront Code",
|
|
156
155
|
titleColor: "\x1b[38;2;252;143;93m",
|
|
157
156
|
width: termWidth,
|
|
158
157
|
paddingX: 1,
|
|
@@ -163,16 +162,5 @@ export function renderDashboardBoxed(state) {
|
|
|
163
162
|
* Render empty state when no projects found
|
|
164
163
|
*/
|
|
165
164
|
export function renderEmptyState() {
|
|
166
|
-
return
|
|
167
|
-
"",
|
|
168
|
-
` ${dim("No projects found.")}`,
|
|
169
|
-
"",
|
|
170
|
-
` ${dim("Get started:")}`,
|
|
171
|
-
` ${brand("[n]")} Create a new project`,
|
|
172
|
-
` ${brand("[t]")} Browse templates`,
|
|
173
|
-
"",
|
|
174
|
-
` ${dim("Or run with a project directory:")}`,
|
|
175
|
-
` ${muted("deno task start --project ./my-project")}`,
|
|
176
|
-
"",
|
|
177
|
-
].join("\n");
|
|
165
|
+
return `\n ${dim("No projects.")} ${brand("n")} ${dim("to create")}\n`;
|
|
178
166
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Startup View
|
|
3
|
+
*
|
|
4
|
+
* Shows loading progress with consistent box sizing.
|
|
5
|
+
* Displays avatar, title, and step checklist.
|
|
6
|
+
*/
|
|
7
|
+
export interface StartupStep {
|
|
8
|
+
label: string;
|
|
9
|
+
status: "pending" | "active" | "done";
|
|
10
|
+
}
|
|
11
|
+
export interface StartupState {
|
|
12
|
+
steps: StartupStep[];
|
|
13
|
+
serverUrl?: string;
|
|
14
|
+
mcpUrl?: string;
|
|
15
|
+
ready: boolean;
|
|
16
|
+
/** Animation frame counter for shimmer effect */
|
|
17
|
+
frame: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Render the startup view inside a consistent-sized box
|
|
21
|
+
*/
|
|
22
|
+
export declare function renderStartup(state: StartupState): string;
|
|
23
|
+
/**
|
|
24
|
+
* Create initial startup state with steps
|
|
25
|
+
*/
|
|
26
|
+
export declare function createStartupState(stepLabels: string[]): StartupState;
|
|
27
|
+
/**
|
|
28
|
+
* Increment animation frame for shimmer effect
|
|
29
|
+
*/
|
|
30
|
+
export declare function incrementFrame(state: StartupState): StartupState;
|
|
31
|
+
/**
|
|
32
|
+
* Set a step to active
|
|
33
|
+
*/
|
|
34
|
+
export declare function setStepActive(state: StartupState, index: number): StartupState;
|
|
35
|
+
/**
|
|
36
|
+
* Mark all steps done and set ready
|
|
37
|
+
*/
|
|
38
|
+
export declare function setStartupReady(state: StartupState, serverUrl: string, mcpUrl?: string): StartupState;
|
|
39
|
+
//# sourceMappingURL=startup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"startup.d.ts","sourceRoot":"","sources":["../../../../../src/src/cli/app/views/startup.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAC;CACvC;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAqDzD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,YAAY,CAMrE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,YAAY,GAAG,YAAY,CAEhE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,CAO9E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,GACd,YAAY,CAOd"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Startup View
|
|
3
|
+
*
|
|
4
|
+
* Shows loading progress with consistent box sizing.
|
|
5
|
+
* Displays avatar, title, and step checklist.
|
|
6
|
+
*/
|
|
7
|
+
import { box } from "../../ui/box.js";
|
|
8
|
+
import { brand, dim, shimmer } from "../../ui/colors.js";
|
|
9
|
+
// Dim orange for completed steps - matches the trailing dots in spinning animation
|
|
10
|
+
const dimOrange = (text) => `\x1b[38;2;180;100;65m${text}\x1b[0m`;
|
|
11
|
+
import { getTerminalWidth } from "../../ui/layout.js";
|
|
12
|
+
import { getAgentFaceWithText, getSpinningAgentFace } from "../../ui/dot-matrix.js";
|
|
13
|
+
/**
|
|
14
|
+
* Render the startup view inside a consistent-sized box
|
|
15
|
+
*/
|
|
16
|
+
export function renderStartup(state) {
|
|
17
|
+
const termWidth = Math.min(getTerminalWidth() - 4, 80);
|
|
18
|
+
const textLines = [];
|
|
19
|
+
if (state.ready) {
|
|
20
|
+
// Running state - always reserve space for both URL lines to prevent jumps
|
|
21
|
+
textLines.push("");
|
|
22
|
+
textLines.push(`${brand("Veryfront Code")} ${dim("is now running")}`);
|
|
23
|
+
textLines.push("");
|
|
24
|
+
textLines.push(state.serverUrl ? `${dim("Url")} ${brand(state.serverUrl)}` : "");
|
|
25
|
+
textLines.push(state.mcpUrl ? `${dim("Mcp")} ${brand(state.mcpUrl)}` : "");
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
// Loading state - match ready state layout
|
|
29
|
+
textLines.push("");
|
|
30
|
+
textLines.push(`${brand("Veryfront Code")} ${dim("starting...")}`);
|
|
31
|
+
textLines.push("");
|
|
32
|
+
for (const step of state.steps) {
|
|
33
|
+
if (step.status === "done") {
|
|
34
|
+
// Completed: dim orange (fades into background, coherent with avatar)
|
|
35
|
+
textLines.push(`${dimOrange("●")} ${dimOrange(step.label)}`);
|
|
36
|
+
}
|
|
37
|
+
else if (step.status === "active") {
|
|
38
|
+
// Active: bright orange dot with shimmer text
|
|
39
|
+
textLines.push(`${brand("●")} ${shimmer(step.label, state.frame)}`);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
// Pending: gray empty circle
|
|
43
|
+
textLines.push(`${dim("○")} ${dim(step.label)}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Pad to 7 text lines (matching avatar height) for consistent title position
|
|
48
|
+
while (textLines.length < 7) {
|
|
49
|
+
textLines.push("");
|
|
50
|
+
}
|
|
51
|
+
// Use spinning avatar during loading, static when ready or all steps done
|
|
52
|
+
const allStepsDone = state.steps.every((s) => s.status === "done");
|
|
53
|
+
const content = state.ready || allStepsDone
|
|
54
|
+
? getAgentFaceWithText(textLines, {
|
|
55
|
+
litColor: "\x1b[38;2;252;143;93m", // Veryfront brand orange
|
|
56
|
+
})
|
|
57
|
+
: getSpinningAgentFace(textLines, state.frame, {
|
|
58
|
+
litColor: "\x1b[38;2;252;143;93m", // Veryfront brand orange
|
|
59
|
+
});
|
|
60
|
+
return box(content, {
|
|
61
|
+
style: "rounded",
|
|
62
|
+
width: termWidth,
|
|
63
|
+
paddingX: 2,
|
|
64
|
+
paddingY: 1,
|
|
65
|
+
borderColor: "\x1b[2m", // Dim to match footer
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Create initial startup state with steps
|
|
70
|
+
*/
|
|
71
|
+
export function createStartupState(stepLabels) {
|
|
72
|
+
return {
|
|
73
|
+
steps: stepLabels.map((label) => ({ label, status: "pending" })),
|
|
74
|
+
ready: false,
|
|
75
|
+
frame: 0,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Increment animation frame for shimmer effect
|
|
80
|
+
*/
|
|
81
|
+
export function incrementFrame(state) {
|
|
82
|
+
return { ...state, frame: state.frame + 1 };
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Set a step to active
|
|
86
|
+
*/
|
|
87
|
+
export function setStepActive(state, index) {
|
|
88
|
+
const steps = state.steps.map((step, i) => ({
|
|
89
|
+
...step,
|
|
90
|
+
status: i < index ? "done" : i === index ? "active" : "pending",
|
|
91
|
+
}));
|
|
92
|
+
return { ...state, steps };
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Mark all steps done and set ready
|
|
96
|
+
*/
|
|
97
|
+
export function setStartupReady(state, serverUrl, mcpUrl) {
|
|
98
|
+
const steps = state.steps.map((step) => ({
|
|
99
|
+
...step,
|
|
100
|
+
status: "done",
|
|
101
|
+
}));
|
|
102
|
+
return { ...state, steps, serverUrl, mcpUrl, ready: true };
|
|
103
|
+
}
|