everything-dev 0.3.2 → 1.3.2
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 +64 -0
- package/cli.js +10 -0
- package/dist/_virtual/_rolldown/runtime.cjs +29 -0
- package/dist/api-contract.cjs +172 -0
- package/dist/api-contract.cjs.map +1 -0
- package/dist/api-contract.mjs +171 -0
- package/dist/api-contract.mjs.map +1 -0
- package/dist/api.cjs +124 -0
- package/dist/api.cjs.map +1 -0
- package/dist/api.d.cts +36 -0
- package/dist/api.d.cts.map +1 -0
- package/dist/api.d.mts +36 -0
- package/dist/api.d.mts.map +1 -0
- package/dist/api.mjs +119 -0
- package/dist/api.mjs.map +1 -0
- package/dist/app.cjs +156 -0
- package/dist/app.cjs.map +1 -0
- package/dist/app.mjs +153 -0
- package/dist/app.mjs.map +1 -0
- package/dist/cli/catalog.cjs +30 -0
- package/dist/cli/catalog.cjs.map +1 -0
- package/dist/cli/catalog.mjs +29 -0
- package/dist/cli/catalog.mjs.map +1 -0
- package/dist/cli/help.cjs +16 -0
- package/dist/cli/help.cjs.map +1 -0
- package/dist/cli/help.mjs +16 -0
- package/dist/cli/help.mjs.map +1 -0
- package/dist/cli/init.cjs +317 -0
- package/dist/cli/init.cjs.map +1 -0
- package/dist/cli/init.d.cts +36 -0
- package/dist/cli/init.d.cts.map +1 -0
- package/dist/cli/init.d.mts +36 -0
- package/dist/cli/init.d.mts.map +1 -0
- package/dist/cli/init.mjs +309 -0
- package/dist/cli/init.mjs.map +1 -0
- package/dist/cli/parse.cjs +96 -0
- package/dist/cli/parse.cjs.map +1 -0
- package/dist/cli/parse.mjs +95 -0
- package/dist/cli/parse.mjs.map +1 -0
- package/dist/cli/prompts.cjs +42 -0
- package/dist/cli/prompts.cjs.map +1 -0
- package/dist/cli/prompts.mjs +41 -0
- package/dist/cli/prompts.mjs.map +1 -0
- package/dist/cli.cjs +167 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +166 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/components/dev-view.cjs +307 -0
- package/dist/components/dev-view.cjs.map +1 -0
- package/dist/components/dev-view.mjs +306 -0
- package/dist/components/dev-view.mjs.map +1 -0
- package/dist/components/streaming-view.cjs +146 -0
- package/dist/components/streaming-view.cjs.map +1 -0
- package/dist/components/streaming-view.mjs +144 -0
- package/dist/components/streaming-view.mjs.map +1 -0
- package/dist/config.cjs +280 -0
- package/dist/config.cjs.map +1 -0
- package/dist/config.d.cts +35 -0
- package/dist/config.d.cts.map +1 -0
- package/dist/config.d.mts +35 -0
- package/dist/config.d.mts.map +1 -0
- package/dist/config.mjs +266 -0
- package/dist/config.mjs.map +1 -0
- package/dist/contract.cjs +209 -0
- package/dist/contract.cjs.map +1 -0
- package/dist/contract.d.cts +490 -0
- package/dist/contract.d.cts.map +1 -0
- package/dist/contract.d.mts +490 -0
- package/dist/contract.d.mts.map +1 -0
- package/dist/contract.meta.cjs +104 -0
- package/dist/contract.meta.cjs.map +1 -0
- package/dist/contract.meta.d.cts +141 -0
- package/dist/contract.meta.d.cts.map +1 -0
- package/dist/contract.meta.d.mts +141 -0
- package/dist/contract.meta.d.mts.map +1 -0
- package/dist/contract.meta.mjs +102 -0
- package/dist/contract.meta.mjs.map +1 -0
- package/dist/contract.mjs +186 -0
- package/dist/contract.mjs.map +1 -0
- package/dist/dev-logs.cjs +53 -0
- package/dist/dev-logs.cjs.map +1 -0
- package/dist/dev-logs.mjs +51 -0
- package/dist/dev-logs.mjs.map +1 -0
- package/dist/dev-session.cjs +195 -0
- package/dist/dev-session.cjs.map +1 -0
- package/dist/dev-session.mjs +194 -0
- package/dist/dev-session.mjs.map +1 -0
- package/dist/fastkv.cjs +89 -0
- package/dist/fastkv.cjs.map +1 -0
- package/dist/fastkv.d.cts +11 -0
- package/dist/fastkv.d.cts.map +1 -0
- package/dist/fastkv.d.mts +11 -0
- package/dist/fastkv.d.mts.map +1 -0
- package/dist/fastkv.mjs +82 -0
- package/dist/fastkv.mjs.map +1 -0
- package/dist/federation.server.cjs +27 -0
- package/dist/federation.server.cjs.map +1 -0
- package/dist/federation.server.mjs +27 -0
- package/dist/federation.server.mjs.map +1 -0
- package/dist/host.cjs +367 -0
- package/dist/host.cjs.map +1 -0
- package/dist/host.d.cts +22 -0
- package/dist/host.d.cts.map +1 -0
- package/dist/host.d.mts +22 -0
- package/dist/host.d.mts.map +1 -0
- package/dist/host.mjs +364 -0
- package/dist/host.mjs.map +1 -0
- package/dist/index.cjs +122 -0
- package/dist/index.d.cts +7 -0
- package/dist/index.d.mts +7 -0
- package/dist/index.mjs +9 -0
- package/dist/integrity.cjs +39 -0
- package/dist/integrity.cjs.map +1 -0
- package/dist/integrity.d.cts +7 -0
- package/dist/integrity.d.cts.map +1 -0
- package/dist/integrity.d.mts +7 -0
- package/dist/integrity.d.mts.map +1 -0
- package/dist/integrity.mjs +35 -0
- package/dist/integrity.mjs.map +1 -0
- package/dist/mf.cjs +77 -0
- package/dist/mf.cjs.map +1 -0
- package/dist/mf.d.cts +19 -0
- package/dist/mf.d.cts.map +1 -0
- package/dist/mf.d.mts +19 -0
- package/dist/mf.d.mts.map +1 -0
- package/dist/mf.mjs +71 -0
- package/dist/mf.mjs.map +1 -0
- package/dist/near-cli.cjs +196 -0
- package/dist/near-cli.cjs.map +1 -0
- package/dist/near-cli.mjs +193 -0
- package/dist/near-cli.mjs.map +1 -0
- package/dist/network.cjs +9 -0
- package/dist/network.cjs.map +1 -0
- package/dist/network.mjs +8 -0
- package/dist/network.mjs.map +1 -0
- package/dist/orchestrator.cjs +441 -0
- package/dist/orchestrator.cjs.map +1 -0
- package/dist/orchestrator.d.cts +40 -0
- package/dist/orchestrator.d.cts.map +1 -0
- package/dist/orchestrator.d.mts +40 -0
- package/dist/orchestrator.d.mts.map +1 -0
- package/dist/orchestrator.mjs +436 -0
- package/dist/orchestrator.mjs.map +1 -0
- package/dist/plugin.cjs +825 -0
- package/dist/plugin.cjs.map +1 -0
- package/dist/plugin.d.cts +347 -0
- package/dist/plugin.d.cts.map +1 -0
- package/dist/plugin.d.mts +348 -0
- package/dist/plugin.d.mts.map +1 -0
- package/dist/plugin.mjs +822 -0
- package/dist/plugin.mjs.map +1 -0
- package/dist/process-registry.cjs +120 -0
- package/dist/process-registry.cjs.map +1 -0
- package/dist/process-registry.d.cts +25 -0
- package/dist/process-registry.d.cts.map +1 -0
- package/dist/process-registry.d.mts +25 -0
- package/dist/process-registry.d.mts.map +1 -0
- package/dist/process-registry.mjs +119 -0
- package/dist/process-registry.mjs.map +1 -0
- package/dist/sdk.cjs +61 -0
- package/dist/sdk.d.cts +5 -0
- package/dist/sdk.d.mts +5 -0
- package/dist/sdk.mjs +6 -0
- package/dist/shared.cjs +143 -0
- package/dist/shared.cjs.map +1 -0
- package/dist/shared.d.cts +33 -0
- package/dist/shared.d.cts.map +1 -0
- package/dist/shared.d.mts +33 -0
- package/dist/shared.d.mts.map +1 -0
- package/dist/shared.mjs +140 -0
- package/dist/shared.mjs.map +1 -0
- package/dist/types.cjs +160 -0
- package/dist/types.cjs.map +1 -0
- package/dist/types.d.cts +269 -0
- package/dist/types.d.cts.map +1 -0
- package/dist/types.d.mts +269 -0
- package/dist/types.d.mts.map +1 -0
- package/dist/types.mjs +144 -0
- package/dist/types.mjs.map +1 -0
- package/dist/ui/head.cjs +67 -0
- package/dist/ui/head.cjs.map +1 -0
- package/dist/ui/head.d.cts +19 -0
- package/dist/ui/head.d.cts.map +1 -0
- package/dist/ui/head.d.mts +19 -0
- package/dist/ui/head.d.mts.map +1 -0
- package/dist/ui/head.mjs +61 -0
- package/dist/ui/head.mjs.map +1 -0
- package/dist/ui/index.cjs +32 -0
- package/dist/ui/index.d.cts +7 -0
- package/dist/ui/index.d.mts +7 -0
- package/dist/ui/index.mjs +6 -0
- package/dist/ui/metadata.cjs +106 -0
- package/dist/ui/metadata.cjs.map +1 -0
- package/dist/ui/metadata.d.cts +35 -0
- package/dist/ui/metadata.d.cts.map +1 -0
- package/dist/ui/metadata.d.mts +35 -0
- package/dist/ui/metadata.d.mts.map +1 -0
- package/dist/ui/metadata.mjs +100 -0
- package/dist/ui/metadata.mjs.map +1 -0
- package/dist/ui/router.cjs +56 -0
- package/dist/ui/router.cjs.map +1 -0
- package/dist/ui/router.d.cts +11 -0
- package/dist/ui/router.d.cts.map +1 -0
- package/dist/ui/router.d.mts +11 -0
- package/dist/ui/router.d.mts.map +1 -0
- package/dist/ui/router.mjs +51 -0
- package/dist/ui/router.mjs.map +1 -0
- package/dist/ui/runtime.cjs +65 -0
- package/dist/ui/runtime.cjs.map +1 -0
- package/dist/ui/runtime.d.cts +29 -0
- package/dist/ui/runtime.d.cts.map +1 -0
- package/dist/ui/runtime.d.mts +29 -0
- package/dist/ui/runtime.d.mts.map +1 -0
- package/dist/ui/runtime.mjs +53 -0
- package/dist/ui/runtime.mjs.map +1 -0
- package/dist/ui/types.cjs +0 -0
- package/dist/ui/types.d.cts +52 -0
- package/dist/ui/types.d.cts.map +1 -0
- package/dist/ui/types.d.mts +52 -0
- package/dist/ui/types.d.mts.map +1 -0
- package/dist/ui/types.mjs +1 -0
- package/dist/utils/banner.cjs +24 -0
- package/dist/utils/banner.cjs.map +1 -0
- package/dist/utils/banner.mjs +23 -0
- package/dist/utils/banner.mjs.map +1 -0
- package/dist/utils/linkify.cjs +15 -0
- package/dist/utils/linkify.cjs.map +1 -0
- package/dist/utils/linkify.mjs +14 -0
- package/dist/utils/linkify.mjs.map +1 -0
- package/dist/utils/run.cjs +40 -0
- package/dist/utils/run.cjs.map +1 -0
- package/dist/utils/run.mjs +39 -0
- package/dist/utils/run.mjs.map +1 -0
- package/dist/utils/theme.cjs +44 -0
- package/dist/utils/theme.cjs.map +1 -0
- package/dist/utils/theme.mjs +37 -0
- package/dist/utils/theme.mjs.map +1 -0
- package/package.json +269 -80
- package/src/api-contract.ts +309 -0
- package/src/api.ts +181 -0
- package/src/app.ts +346 -0
- package/src/cli/catalog.ts +49 -0
- package/src/cli/help.ts +13 -0
- package/src/cli/init.ts +415 -0
- package/src/cli/parse.ts +130 -0
- package/src/cli/prompts.ts +64 -0
- package/src/cli.ts +203 -1507
- package/src/components/dev-view.tsx +104 -41
- package/src/components/streaming-view.ts +89 -22
- package/src/config.ts +462 -532
- package/src/contract.meta.ts +96 -0
- package/src/contract.ts +164 -561
- package/src/dev-logs.ts +85 -0
- package/src/dev-session.ts +318 -0
- package/src/fastkv.ts +153 -0
- package/src/federation.server.ts +43 -0
- package/src/host.ts +526 -0
- package/src/index.ts +6 -3
- package/src/integrity.ts +54 -0
- package/src/mf.ts +105 -0
- package/src/near-cli.ts +284 -0
- package/src/network.ts +3 -0
- package/src/orchestrator.ts +648 -0
- package/src/plugin.ts +1116 -2303
- package/src/process-registry.ts +154 -0
- package/src/scripts/sync-api-contract.ts +24 -0
- package/src/sdk.ts +14 -0
- package/src/shared.ts +206 -0
- package/src/types.ts +152 -206
- package/src/ui/head.ts +34 -27
- package/src/ui/index.ts +3 -3
- package/src/ui/metadata.ts +95 -0
- package/src/ui/router.ts +22 -6
- package/src/ui/runtime.ts +55 -6
- package/src/ui/types.ts +24 -11
- package/src/utils/banner.ts +10 -6
- package/src/utils/run.ts +26 -27
- package/src/utils/theme.ts +3 -66
- package/src/components/monitor-view.tsx +0 -475
- package/src/components/status-view.tsx +0 -173
- package/src/lib/env.ts +0 -109
- package/src/lib/near-cli.ts +0 -289
- package/src/lib/nova.ts +0 -266
- package/src/lib/orchestrator.ts +0 -276
- package/src/lib/process-registry.ts +0 -166
- package/src/lib/process.ts +0 -549
- package/src/lib/resource-monitor/assertions.ts +0 -234
- package/src/lib/resource-monitor/command.ts +0 -283
- package/src/lib/resource-monitor/diff.ts +0 -157
- package/src/lib/resource-monitor/errors.ts +0 -127
- package/src/lib/resource-monitor/index.ts +0 -305
- package/src/lib/resource-monitor/platform/darwin.ts +0 -306
- package/src/lib/resource-monitor/platform/index.ts +0 -35
- package/src/lib/resource-monitor/platform/linux.ts +0 -332
- package/src/lib/resource-monitor/platform/windows.ts +0 -298
- package/src/lib/resource-monitor/snapshot.ts +0 -217
- package/src/lib/resource-monitor/types.ts +0 -74
- package/src/lib/session-recorder/errors.ts +0 -102
- package/src/lib/session-recorder/flows/login.ts +0 -210
- package/src/lib/session-recorder/index.ts +0 -361
- package/src/lib/session-recorder/playwright.ts +0 -257
- package/src/lib/session-recorder/report.ts +0 -353
- package/src/lib/session-recorder/server.ts +0 -267
- package/src/lib/session-recorder/types.ts +0 -115
- package/src/lib/sync.ts +0 -1
- package/src/ui/files.ts +0 -134
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { Box, render, Text, useApp, useInput } from "ink";
|
|
2
2
|
import { useEffect, useState } from "react";
|
|
3
|
+
import type { SourceMode } from "../types";
|
|
3
4
|
import { linkify } from "../utils/linkify";
|
|
4
5
|
import { colors, divider, frames, gradients, icons } from "../utils/theme";
|
|
5
6
|
|
|
7
|
+
const PLUGIN_PREFIX = "plugin:";
|
|
8
|
+
|
|
6
9
|
export type ProcessStatus = "pending" | "starting" | "ready" | "error";
|
|
7
10
|
|
|
8
11
|
export interface ProcessState {
|
|
@@ -10,11 +13,11 @@ export interface ProcessState {
|
|
|
10
13
|
status: ProcessStatus;
|
|
11
14
|
port: number;
|
|
12
15
|
message?: string;
|
|
13
|
-
source?:
|
|
14
|
-
proxyTarget?: string;
|
|
16
|
+
source?: SourceMode;
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
export interface LogEntry {
|
|
20
|
+
id: string;
|
|
18
21
|
source: string;
|
|
19
22
|
line: string;
|
|
20
23
|
timestamp: number;
|
|
@@ -26,8 +29,8 @@ interface DevViewProps {
|
|
|
26
29
|
logs: LogEntry[];
|
|
27
30
|
description: string;
|
|
28
31
|
proxyTarget?: string;
|
|
29
|
-
onExit?: () => void;
|
|
30
|
-
onExportLogs?: () => void;
|
|
32
|
+
onExit?: () => Promise<void> | void;
|
|
33
|
+
onExportLogs?: () => Promise<void> | void;
|
|
31
34
|
}
|
|
32
35
|
|
|
33
36
|
function StatusIcon({ status }: { status: ProcessStatus }) {
|
|
@@ -44,10 +47,49 @@ function StatusIcon({ status }: { status: ProcessStatus }) {
|
|
|
44
47
|
}
|
|
45
48
|
|
|
46
49
|
function getServiceColor(name: string): string {
|
|
50
|
+
if (name.startsWith(PLUGIN_PREFIX)) return "#ffaa00";
|
|
47
51
|
return name === "host" ? "#00ffff" : name === "ui" ? "#ff00ff" : "#0080ff";
|
|
48
52
|
}
|
|
49
53
|
|
|
50
|
-
function
|
|
54
|
+
function getDisplayName(name: string): string {
|
|
55
|
+
return name.startsWith(PLUGIN_PREFIX)
|
|
56
|
+
? name.slice(PLUGIN_PREFIX.length).toUpperCase()
|
|
57
|
+
: name.toUpperCase();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function isPlugin(name: string): boolean {
|
|
61
|
+
return name.startsWith(PLUGIN_PREFIX);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function getSectionedProcesses(processes: ProcessState[]): Array<{
|
|
65
|
+
key: string;
|
|
66
|
+
title: string;
|
|
67
|
+
processes: ProcessState[];
|
|
68
|
+
}> {
|
|
69
|
+
const plugins = processes.filter((p) => isPlugin(p.name));
|
|
70
|
+
const services = processes.filter((p) => !isPlugin(p.name));
|
|
71
|
+
const sections: Array<{ key: string; title: string; processes: ProcessState[] }> = [];
|
|
72
|
+
if (plugins.length > 0) sections.push({ key: "plugins", title: "PLUGINS", processes: plugins });
|
|
73
|
+
if (services.length > 0)
|
|
74
|
+
sections.push({ key: "services", title: "SERVICES", processes: services });
|
|
75
|
+
return sections;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function getColumnWidths(processes: ProcessState[]): { name: number; source: number } {
|
|
79
|
+
const name = Math.max(6, ...processes.map((p) => getDisplayName(p.name).length));
|
|
80
|
+
const source = Math.max(10, ...processes.map((p) => (p.source ? `(${p.source})`.length : 0)));
|
|
81
|
+
return { name, source };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function ProcessRow({
|
|
85
|
+
proc,
|
|
86
|
+
nameWidth,
|
|
87
|
+
sourceWidth,
|
|
88
|
+
}: {
|
|
89
|
+
proc: ProcessState;
|
|
90
|
+
nameWidth: number;
|
|
91
|
+
sourceWidth: number;
|
|
92
|
+
}) {
|
|
51
93
|
const color = getServiceColor(proc.name);
|
|
52
94
|
const portStr = proc.port > 0 ? `:${proc.port}` : "";
|
|
53
95
|
const sourceLabel = proc.source ? ` (${proc.source})` : "";
|
|
@@ -67,27 +109,32 @@ function ProcessRow({ proc }: { proc: ProcessState }) {
|
|
|
67
109
|
<StatusIcon status={proc.status} />
|
|
68
110
|
<Text> </Text>
|
|
69
111
|
<Text color={color} bold>
|
|
70
|
-
{proc.name
|
|
71
|
-
</Text>
|
|
72
|
-
<Text color="gray">{sourceLabel.padEnd(10)}</Text>
|
|
73
|
-
<Text color={proc.status === "ready" ? "#00ff41" : "gray"}>
|
|
74
|
-
{statusText}
|
|
112
|
+
{getDisplayName(proc.name).padEnd(nameWidth)}
|
|
75
113
|
</Text>
|
|
114
|
+
<Text color="gray">{sourceLabel.padEnd(sourceWidth)}</Text>
|
|
115
|
+
<Text color={proc.status === "ready" ? "#00ff41" : "gray"}>{statusText}</Text>
|
|
76
116
|
{proc.port > 0 && <Text color="#00ffff"> {portStr}</Text>}
|
|
77
117
|
</Box>
|
|
78
118
|
);
|
|
79
119
|
}
|
|
80
120
|
|
|
121
|
+
function SectionHeader({ title }: { title: string }) {
|
|
122
|
+
return (
|
|
123
|
+
<Box marginBottom={0} marginTop={1}>
|
|
124
|
+
<Text color="#00ffff" bold>
|
|
125
|
+
{title}
|
|
126
|
+
</Text>
|
|
127
|
+
</Box>
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
81
131
|
function LogLine({ entry }: { entry: LogEntry }) {
|
|
82
132
|
const color = getServiceColor(entry.source);
|
|
83
133
|
|
|
84
134
|
return (
|
|
85
135
|
<Box>
|
|
86
136
|
<Text color={color}>[{entry.source}]</Text>
|
|
87
|
-
<Text color={entry.isError ? "#ff3366" : undefined}>
|
|
88
|
-
{" "}
|
|
89
|
-
{linkify(entry.line)}
|
|
90
|
-
</Text>
|
|
137
|
+
<Text color={entry.isError ? "#ff3366" : undefined}> {linkify(entry.line)}</Text>
|
|
91
138
|
</Box>
|
|
92
139
|
);
|
|
93
140
|
}
|
|
@@ -115,15 +162,22 @@ function DevView({
|
|
|
115
162
|
onExportLogs,
|
|
116
163
|
}: DevViewProps) {
|
|
117
164
|
const { exit } = useApp();
|
|
165
|
+
const [isShuttingDown, setIsShuttingDown] = useState(false);
|
|
118
166
|
|
|
119
167
|
useInput((input, key) => {
|
|
168
|
+
if (isShuttingDown) return;
|
|
169
|
+
|
|
120
170
|
if (input === "q" || (key.ctrl && input === "c")) {
|
|
121
|
-
|
|
122
|
-
|
|
171
|
+
setIsShuttingDown(true);
|
|
172
|
+
Promise.resolve(onExit?.()).then(() => {
|
|
173
|
+
exit();
|
|
174
|
+
});
|
|
123
175
|
}
|
|
124
176
|
if (input === "l") {
|
|
125
|
-
|
|
126
|
-
|
|
177
|
+
setIsShuttingDown(true);
|
|
178
|
+
Promise.resolve(onExportLogs?.()).then(() => {
|
|
179
|
+
exit();
|
|
180
|
+
});
|
|
127
181
|
}
|
|
128
182
|
});
|
|
129
183
|
|
|
@@ -132,8 +186,9 @@ function DevView({
|
|
|
132
186
|
const allReady = readyCount === total;
|
|
133
187
|
const hostProcess = processes.find((p) => p.name === "host");
|
|
134
188
|
const hostPort = hostProcess?.port || 3000;
|
|
135
|
-
|
|
136
189
|
const recentLogs = logs.slice(-12);
|
|
190
|
+
const sectionedProcesses = getSectionedProcesses(processes);
|
|
191
|
+
const columnWidths = getColumnWidths(processes);
|
|
137
192
|
|
|
138
193
|
return (
|
|
139
194
|
<Box flexDirection="column">
|
|
@@ -180,8 +235,18 @@ function DevView({
|
|
|
180
235
|
<Text>{colors.dim(divider(52))}</Text>
|
|
181
236
|
</Box>
|
|
182
237
|
|
|
183
|
-
{
|
|
184
|
-
<
|
|
238
|
+
{sectionedProcesses.map((section) => (
|
|
239
|
+
<Box key={section.key} flexDirection="column">
|
|
240
|
+
<SectionHeader title={section.title} />
|
|
241
|
+
{section.processes.map((proc) => (
|
|
242
|
+
<ProcessRow
|
|
243
|
+
key={proc.name}
|
|
244
|
+
proc={proc}
|
|
245
|
+
nameWidth={columnWidths.name}
|
|
246
|
+
sourceWidth={columnWidths.source}
|
|
247
|
+
/>
|
|
248
|
+
))}
|
|
249
|
+
</Box>
|
|
185
250
|
))}
|
|
186
251
|
|
|
187
252
|
<Box marginTop={1} marginBottom={0}>
|
|
@@ -207,8 +272,8 @@ function DevView({
|
|
|
207
272
|
<Text>{colors.dim(divider(52))}</Text>
|
|
208
273
|
</Box>
|
|
209
274
|
<Box flexDirection="column" marginTop={0}>
|
|
210
|
-
{recentLogs.map((entry
|
|
211
|
-
<LogLine key={
|
|
275
|
+
{recentLogs.map((entry) => (
|
|
276
|
+
<LogLine key={entry.id} entry={entry} />
|
|
212
277
|
))}
|
|
213
278
|
</Box>
|
|
214
279
|
</>
|
|
@@ -218,11 +283,7 @@ function DevView({
|
|
|
218
283
|
}
|
|
219
284
|
|
|
220
285
|
export interface DevViewHandle {
|
|
221
|
-
updateProcess: (
|
|
222
|
-
name: string,
|
|
223
|
-
status: ProcessStatus,
|
|
224
|
-
message?: string,
|
|
225
|
-
) => void;
|
|
286
|
+
updateProcess: (name: string, status: ProcessStatus, message?: string) => void;
|
|
226
287
|
addLog: (source: string, line: string, isError?: boolean) => void;
|
|
227
288
|
unmount: () => void;
|
|
228
289
|
}
|
|
@@ -231,27 +292,30 @@ export function renderDevView(
|
|
|
231
292
|
initialProcesses: ProcessState[],
|
|
232
293
|
description: string,
|
|
233
294
|
env: Record<string, string>,
|
|
234
|
-
onExit?: () => void,
|
|
235
|
-
onExportLogs?: () => void,
|
|
295
|
+
onExit?: () => Promise<void> | void,
|
|
296
|
+
onExportLogs?: () => Promise<void> | void,
|
|
236
297
|
): DevViewHandle {
|
|
237
298
|
let processes = [...initialProcesses];
|
|
238
299
|
let logs: LogEntry[] = [];
|
|
239
300
|
let rerender: (() => void) | null = null;
|
|
240
301
|
const proxyTarget = env.API_PROXY;
|
|
302
|
+
let logSeq = 0;
|
|
303
|
+
let lastLogKey: string | null = null;
|
|
241
304
|
|
|
242
|
-
const updateProcess = (
|
|
243
|
-
name:
|
|
244
|
-
status: ProcessStatus,
|
|
245
|
-
message?: string,
|
|
246
|
-
) => {
|
|
247
|
-
processes = processes.map((p) =>
|
|
248
|
-
p.name === name ? { ...p, status, message } : p,
|
|
249
|
-
);
|
|
305
|
+
const updateProcess = (name: string, status: ProcessStatus, message?: string) => {
|
|
306
|
+
processes = processes.map((p) => (p.name === name ? { ...p, status, message } : p));
|
|
250
307
|
rerender?.();
|
|
251
308
|
};
|
|
252
309
|
|
|
253
310
|
const addLog = (source: string, line: string, isError = false) => {
|
|
254
|
-
|
|
311
|
+
const nextKey = `${source}:${isError ? "1" : "0"}:${line}`;
|
|
312
|
+
if (nextKey === lastLogKey) return;
|
|
313
|
+
lastLogKey = nextKey;
|
|
314
|
+
|
|
315
|
+
logs = [
|
|
316
|
+
...logs,
|
|
317
|
+
{ id: `${Date.now()}-${++logSeq}`, source, line, timestamp: Date.now(), isError },
|
|
318
|
+
];
|
|
255
319
|
if (logs.length > 100) logs = logs.slice(-100);
|
|
256
320
|
rerender?.();
|
|
257
321
|
};
|
|
@@ -260,7 +324,7 @@ export function renderDevView(
|
|
|
260
324
|
const [, forceUpdate] = useState(0);
|
|
261
325
|
|
|
262
326
|
useEffect(() => {
|
|
263
|
-
rerender = () => forceUpdate((n) => n + 1);
|
|
327
|
+
rerender = () => forceUpdate((n: number) => n + 1);
|
|
264
328
|
return () => {
|
|
265
329
|
rerender = null;
|
|
266
330
|
};
|
|
@@ -279,6 +343,5 @@ export function renderDevView(
|
|
|
279
343
|
}
|
|
280
344
|
|
|
281
345
|
const { unmount } = render(<DevViewWrapper />);
|
|
282
|
-
|
|
283
346
|
return { updateProcess, addLog, unmount };
|
|
284
347
|
}
|
|
@@ -4,11 +4,12 @@ import { colors, icons } from "../utils/theme";
|
|
|
4
4
|
import type { ProcessState, ProcessStatus } from "./dev-view";
|
|
5
5
|
|
|
6
6
|
const orange = chalk.hex("#ffaa00");
|
|
7
|
+
const PLUGIN_PREFIX = "plugin:";
|
|
7
8
|
|
|
8
9
|
export interface StreamingViewHandle {
|
|
9
10
|
updateProcess: (name: string, status: ProcessStatus, message?: string) => void;
|
|
10
11
|
addLog: (source: string, line: string, isError?: boolean) => void;
|
|
11
|
-
unmount: () => void;
|
|
12
|
+
unmount: () => Promise<void> | void;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
const getTimestamp = (): string => {
|
|
@@ -16,21 +17,50 @@ const getTimestamp = (): string => {
|
|
|
16
17
|
return `${now.getHours().toString().padStart(2, "0")}:${now.getMinutes().toString().padStart(2, "0")}:${now.getSeconds().toString().padStart(2, "0")}`;
|
|
17
18
|
};
|
|
18
19
|
|
|
19
|
-
const write = (text: string) => process.stdout.write(text
|
|
20
|
+
const write = (text: string) => process.stdout.write(`${text}\n`);
|
|
20
21
|
|
|
21
|
-
const getServiceColor = (name: string): (s: string) => string => {
|
|
22
|
+
const getServiceColor = (name: string): ((s: string) => string) => {
|
|
23
|
+
if (name.startsWith(PLUGIN_PREFIX)) return orange;
|
|
22
24
|
if (name === "host") return colors.cyan;
|
|
23
25
|
if (name === "ui" || name === "ui-ssr") return colors.magenta;
|
|
24
26
|
if (name === "api") return colors.blue;
|
|
25
27
|
return colors.white;
|
|
26
28
|
};
|
|
27
29
|
|
|
30
|
+
const getDisplayName = (name: string): string => {
|
|
31
|
+
return name.startsWith(PLUGIN_PREFIX)
|
|
32
|
+
? name.slice(PLUGIN_PREFIX.length).toUpperCase()
|
|
33
|
+
: name.toUpperCase();
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const isPlugin = (name: string): boolean => name.startsWith(PLUGIN_PREFIX);
|
|
37
|
+
|
|
38
|
+
const getSectionedProcesses = (processes: ProcessState[]) => {
|
|
39
|
+
const plugins = processes.filter((p) => isPlugin(p.name));
|
|
40
|
+
const services = processes.filter((p) => !isPlugin(p.name));
|
|
41
|
+
const sections: Array<{ key: string; title: string; processes: ProcessState[] }> = [];
|
|
42
|
+
if (plugins.length > 0) sections.push({ key: "plugins", title: "PLUGINS", processes: plugins });
|
|
43
|
+
if (services.length > 0)
|
|
44
|
+
sections.push({ key: "services", title: "SERVICES", processes: services });
|
|
45
|
+
return sections;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const getColumnWidths = (processes: ProcessState[]) => {
|
|
49
|
+
const name = Math.max(6, ...processes.map((p) => getDisplayName(p.name).length));
|
|
50
|
+
const source = Math.max(10, ...processes.map((p) => (p.source ? ` (${p.source})`.length : 0)));
|
|
51
|
+
return { name, source };
|
|
52
|
+
};
|
|
53
|
+
|
|
28
54
|
const getStatusIcon = (status: ProcessStatus): string => {
|
|
29
55
|
switch (status) {
|
|
30
|
-
case "pending":
|
|
31
|
-
|
|
32
|
-
case "
|
|
33
|
-
|
|
56
|
+
case "pending":
|
|
57
|
+
return icons.pending;
|
|
58
|
+
case "starting":
|
|
59
|
+
return icons.scan;
|
|
60
|
+
case "ready":
|
|
61
|
+
return icons.ok;
|
|
62
|
+
case "error":
|
|
63
|
+
return icons.err;
|
|
34
64
|
}
|
|
35
65
|
};
|
|
36
66
|
|
|
@@ -38,8 +68,7 @@ export function renderStreamingView(
|
|
|
38
68
|
initialProcesses: ProcessState[],
|
|
39
69
|
description: string,
|
|
40
70
|
env: Record<string, string>,
|
|
41
|
-
onExit?: () => void,
|
|
42
|
-
_onExportLogs?: () => void,
|
|
71
|
+
onExit?: () => Promise<void> | void,
|
|
43
72
|
): StreamingViewHandle {
|
|
44
73
|
const processes = new Map<string, ProcessState>();
|
|
45
74
|
for (const p of initialProcesses) {
|
|
@@ -47,9 +76,12 @@ export function renderStreamingView(
|
|
|
47
76
|
}
|
|
48
77
|
|
|
49
78
|
let allReadyPrinted = false;
|
|
50
|
-
const hostProcess = initialProcesses.find(p => p.name === "host");
|
|
79
|
+
const hostProcess = initialProcesses.find((p) => p.name === "host");
|
|
51
80
|
const hostPort = hostProcess?.port || 3000;
|
|
52
81
|
const proxyTarget = env.API_PROXY;
|
|
82
|
+
const sectionedProcesses = getSectionedProcesses(initialProcesses);
|
|
83
|
+
const columnWidths = getColumnWidths(initialProcesses);
|
|
84
|
+
const lastLogBySource = new Map<string, string>();
|
|
53
85
|
|
|
54
86
|
console.log();
|
|
55
87
|
console.log(colors.cyan(`${"─".repeat(52)}`));
|
|
@@ -62,16 +94,21 @@ export function renderStreamingView(
|
|
|
62
94
|
console.log();
|
|
63
95
|
}
|
|
64
96
|
|
|
65
|
-
for (const
|
|
66
|
-
|
|
67
|
-
const
|
|
68
|
-
|
|
97
|
+
for (const section of sectionedProcesses) {
|
|
98
|
+
console.log(colors.cyan(` ${section.title}`));
|
|
99
|
+
for (const proc of section.processes) {
|
|
100
|
+
const color = getServiceColor(proc.name);
|
|
101
|
+
const sourceLabel = proc.source ? ` (${proc.source})` : "";
|
|
102
|
+
console.log(
|
|
103
|
+
`${colors.dim(`[${getTimestamp()}]`)} ${color(`[${getDisplayName(proc.name).padEnd(columnWidths.name)}]`)} ${icons.pending} waiting${sourceLabel.padEnd(columnWidths.source)}`,
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
console.log();
|
|
69
107
|
}
|
|
70
108
|
|
|
71
109
|
const checkAllReady = () => {
|
|
72
110
|
if (allReadyPrinted) return;
|
|
73
|
-
|
|
74
|
-
const allReady = Array.from(processes.values()).every(p => p.status === "ready");
|
|
111
|
+
const allReady = Array.from(processes.values()).every((p) => p.status === "ready");
|
|
75
112
|
if (allReady) {
|
|
76
113
|
allReadyPrinted = true;
|
|
77
114
|
console.log();
|
|
@@ -92,28 +129,58 @@ export function renderStreamingView(
|
|
|
92
129
|
|
|
93
130
|
const color = getServiceColor(name);
|
|
94
131
|
const icon = getStatusIcon(status);
|
|
95
|
-
const
|
|
132
|
+
const displayName = getDisplayName(name).padEnd(columnWidths.name);
|
|
133
|
+
const sourceLabel = proc?.source ? ` (${proc.source})` : "";
|
|
134
|
+
const statusText =
|
|
135
|
+
status === "ready"
|
|
136
|
+
? "ready"
|
|
137
|
+
: status === "starting"
|
|
138
|
+
? "starting"
|
|
139
|
+
: status === "error"
|
|
140
|
+
? "failed"
|
|
141
|
+
: "waiting";
|
|
96
142
|
const portStr = proc.port > 0 && status === "ready" ? ` :${proc.port}` : "";
|
|
97
143
|
|
|
98
|
-
write(
|
|
144
|
+
write(
|
|
145
|
+
`${colors.dim(`[${getTimestamp()}]`)} ${color(`[${displayName}]`)} ${status === "ready" ? colors.green(icon) : status === "error" ? colors.error(icon) : icon} ${statusText}${sourceLabel.padEnd(columnWidths.source)}${portStr}`,
|
|
146
|
+
);
|
|
99
147
|
|
|
100
148
|
checkAllReady();
|
|
101
149
|
};
|
|
102
150
|
|
|
103
151
|
const addLog = (source: string, line: string, isError = false) => {
|
|
152
|
+
const lastLine = lastLogBySource.get(source);
|
|
153
|
+
const nextLine = `${isError ? "ERR" : "OUT"}:${line}`;
|
|
154
|
+
if (lastLine === nextLine) return;
|
|
155
|
+
lastLogBySource.set(source, nextLine);
|
|
156
|
+
|
|
104
157
|
const color = getServiceColor(source);
|
|
105
158
|
const logColor = isError ? colors.error : colors.dim;
|
|
106
|
-
write(
|
|
159
|
+
write(
|
|
160
|
+
`${colors.dim(`[${getTimestamp()}]`)} ${color(`[${source.toUpperCase()}]`)} ${colors.dim("│")} ${logColor(linkify(line))}`,
|
|
161
|
+
);
|
|
107
162
|
};
|
|
108
163
|
|
|
109
|
-
const unmount = () =>
|
|
110
|
-
|
|
164
|
+
const unmount = () => onExit?.();
|
|
165
|
+
|
|
166
|
+
let signalCount = 0;
|
|
167
|
+
const forceExit = () => {
|
|
168
|
+
console.log("\n[CLI] Force exit");
|
|
169
|
+
process.exit(0);
|
|
111
170
|
};
|
|
112
171
|
|
|
113
172
|
process.on("SIGINT", () => {
|
|
173
|
+
signalCount++;
|
|
174
|
+
if (signalCount > 1) {
|
|
175
|
+
forceExit();
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
114
178
|
console.log();
|
|
115
179
|
console.log(colors.dim(`[${getTimestamp()}] Shutting down...`));
|
|
116
|
-
|
|
180
|
+
const timeout = setTimeout(forceExit, 5000);
|
|
181
|
+
Promise.resolve(unmount()).then(() => {
|
|
182
|
+
clearTimeout(timeout);
|
|
183
|
+
});
|
|
117
184
|
});
|
|
118
185
|
|
|
119
186
|
return { updateProcess, addLog, unmount };
|