@pulse-editor/cli 0.1.1-beta.3 → 0.1.1-beta.31
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/dist/app.js +2 -1
- package/dist/cli.js +1 -0
- package/dist/components/commands/build.js +18 -33
- package/dist/components/commands/create.js +38 -12
- package/dist/components/commands/dev.js +36 -4
- package/dist/components/commands/help.js +2 -1
- package/dist/components/commands/preview.js +51 -7
- package/dist/components/commands/publish.js +23 -37
- package/dist/components/commands/{preview copy.d.ts → upgrade.d.ts} +1 -1
- package/dist/components/commands/upgrade.js +53 -0
- package/dist/lib/backend/publish-app.d.ts +1 -0
- package/dist/lib/backend/publish-app.js +27 -0
- package/dist/lib/cli-flags.d.ts +14 -0
- package/dist/lib/cli-flags.js +14 -0
- package/dist/lib/execa-utils/clean.js +1 -1
- package/dist/lib/execa-utils/deps.js +10 -1
- package/dist/lib/manual.js +52 -0
- package/dist/lib/server/express.js +33 -18
- package/dist/lib/server/preview/backend/load-remote.cjs +33 -23
- package/dist/lib/server/preview/frontend/index.html +11 -11
- package/dist/lib/webpack/compile.d.ts +2 -0
- package/dist/lib/webpack/compile.js +28 -0
- package/dist/lib/webpack/dist/pregistered-actions.d.ts +2 -0
- package/dist/lib/webpack/dist/pulse.config.d.ts +7 -0
- package/dist/lib/webpack/dist/src/lib/agents/code-modifier-agent.d.ts +2 -0
- package/dist/lib/webpack/dist/src/lib/agents/vibe-coding-agent.d.ts +3 -0
- package/dist/lib/webpack/dist/src/lib/mcp/utils.d.ts +3 -0
- package/dist/lib/webpack/dist/src/lib/streaming/message-stream-controller.d.ts +10 -0
- package/dist/lib/webpack/dist/src/lib/types.d.ts +58 -0
- package/dist/lib/webpack/dist/src/server-function/generate-code/v1/generate.d.ts +5 -0
- package/dist/lib/webpack/dist/src/server-function/generate-code/v2/generate.d.ts +1 -0
- package/dist/lib/webpack/tsconfig.server.json +19 -0
- package/dist/lib/webpack/webpack.config.d.ts +2 -0
- package/dist/lib/webpack/webpack.config.js +527 -0
- package/package.json +29 -15
- package/readme.md +35 -1
- package/dist/components/commands/preview copy.js +0 -14
- package/dist/components/commands/start copy.d.ts +0 -5
- package/dist/components/commands/start copy.js +0 -14
- package/dist/lib/deps.d.ts +0 -1
- package/dist/lib/deps.js +0 -5
- package/dist/lib/node_module_bin.d.ts +0 -1
- package/dist/lib/node_module_bin.js +0 -7
- package/dist/lib/server/preview/backend/index.d.ts +0 -1
- package/dist/lib/server/preview/backend/index.js +0 -23
package/dist/lib/cli-flags.js
CHANGED
|
@@ -29,4 +29,18 @@ export const flags = defineFlags({
|
|
|
29
29
|
type: 'string',
|
|
30
30
|
shortFlag: 't',
|
|
31
31
|
},
|
|
32
|
+
beta: {
|
|
33
|
+
type: 'boolean',
|
|
34
|
+
},
|
|
35
|
+
build: {
|
|
36
|
+
type: 'boolean',
|
|
37
|
+
default: true,
|
|
38
|
+
},
|
|
39
|
+
path: {
|
|
40
|
+
type: 'string',
|
|
41
|
+
shortFlag: 'p',
|
|
42
|
+
},
|
|
43
|
+
displayName: {
|
|
44
|
+
type: 'string',
|
|
45
|
+
},
|
|
32
46
|
});
|
|
@@ -1,5 +1,14 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
1
2
|
// Get deps bin at node_modules/@pulse-editor/cli/node_modules
|
|
2
3
|
export function getDepsBinPath(name) {
|
|
3
4
|
const workingDir = process.cwd();
|
|
4
|
-
|
|
5
|
+
// Check if the package is installed in the node_modules, if yes, just return "npx <name>"
|
|
6
|
+
if (fs.existsSync(`${workingDir}/node_modules/${name}`)) {
|
|
7
|
+
return `npx ${name}`;
|
|
8
|
+
}
|
|
9
|
+
// Check if the package exists in node_modules/@pulse-editor/cli/node_modules
|
|
10
|
+
else if (fs.existsSync(`${workingDir}/node_modules/@pulse-editor/cli/node_modules/${name}`)) {
|
|
11
|
+
return `${workingDir}/node_modules/@pulse-editor/cli/node_modules/.bin/${process.platform === 'win32' ? `${name}.cmd` : name}`;
|
|
12
|
+
}
|
|
13
|
+
throw new Error(`Dependency ${name} not found.`);
|
|
5
14
|
}
|
package/dist/lib/manual.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const help = `\
|
|
2
2
|
help [command] Show help for a command.
|
|
3
|
+
|
|
3
4
|
`;
|
|
4
5
|
const chat = `\
|
|
5
6
|
chat [message] (WIP) Chat with the Pulse Editor AI assistant.
|
|
@@ -22,9 +23,14 @@ const login = `\
|
|
|
22
23
|
`;
|
|
23
24
|
const logout = `\
|
|
24
25
|
logout Logout from the Pulse Editor Platform.
|
|
26
|
+
|
|
25
27
|
`;
|
|
26
28
|
const publish = `\
|
|
27
29
|
publish Publish Pulse Editor Extension in current directory to the Pulse Editor Platform.
|
|
30
|
+
Flags:
|
|
31
|
+
--noBuild
|
|
32
|
+
Skip the build step before publishing.
|
|
33
|
+
|
|
28
34
|
`;
|
|
29
35
|
const create = `\
|
|
30
36
|
create Create a new Pulse App using the starter template.
|
|
@@ -38,6 +44,46 @@ const create = `\
|
|
|
38
44
|
--visibility, -v [visibility]
|
|
39
45
|
The visibility of the new project. Options are private,
|
|
40
46
|
public, and unlisted.
|
|
47
|
+
--path, -p [path]
|
|
48
|
+
The path where to create the new project. Defaults to
|
|
49
|
+
the name of the project in the current working directory.
|
|
50
|
+
|
|
51
|
+
`;
|
|
52
|
+
const preview = `\
|
|
53
|
+
preview Build the Pulse App in development mode and
|
|
54
|
+
start a preview server accessible via browser
|
|
55
|
+
with live reloading.
|
|
56
|
+
|
|
57
|
+
`;
|
|
58
|
+
const dev = `\
|
|
59
|
+
dev Build the Pulse App in development mode and
|
|
60
|
+
start a local development server for Pulse Editor
|
|
61
|
+
to load the app from, with live reloading.
|
|
62
|
+
|
|
63
|
+
`;
|
|
64
|
+
const build = `\
|
|
65
|
+
build Build the Pulse App for production deployment.
|
|
66
|
+
Flags:
|
|
67
|
+
--target, -t [target]
|
|
68
|
+
The build target. Options are 'client', 'server', or
|
|
69
|
+
unspecified (both client and server).
|
|
70
|
+
|
|
71
|
+
`;
|
|
72
|
+
const start = `\
|
|
73
|
+
start Build the Pulse App in production mode and
|
|
74
|
+
start a local server for Pulse Editor to load the app from.
|
|
75
|
+
|
|
76
|
+
`;
|
|
77
|
+
const clean = `\
|
|
78
|
+
clean Clean the dist/ directory.
|
|
79
|
+
|
|
80
|
+
`;
|
|
81
|
+
const upgrade = `\
|
|
82
|
+
upgrade Upgrade Pulse Editor CLI and related packages to the latest version.
|
|
83
|
+
Flags:
|
|
84
|
+
--beta
|
|
85
|
+
Upgrade to the latest beta version.
|
|
86
|
+
|
|
41
87
|
`;
|
|
42
88
|
export const commandsManual = {
|
|
43
89
|
help,
|
|
@@ -46,4 +92,10 @@ export const commandsManual = {
|
|
|
46
92
|
logout,
|
|
47
93
|
publish,
|
|
48
94
|
create,
|
|
95
|
+
preview,
|
|
96
|
+
dev,
|
|
97
|
+
build,
|
|
98
|
+
start,
|
|
99
|
+
clean,
|
|
100
|
+
upgrade,
|
|
49
101
|
};
|
|
@@ -16,7 +16,7 @@ dotenv.config({
|
|
|
16
16
|
quiet: true,
|
|
17
17
|
});
|
|
18
18
|
const isPreview = process.env?.['PREVIEW'];
|
|
19
|
-
const isDev = process.env?.['NODE_ENV'];
|
|
19
|
+
const isDev = process.env?.['NODE_ENV'] === 'development';
|
|
20
20
|
const workspaceId = process.env?.['WORKSPACE_ID'];
|
|
21
21
|
const pulseConfig = await readConfigFile();
|
|
22
22
|
if (isDev || isPreview) {
|
|
@@ -65,19 +65,34 @@ app.all(/^\/server-function\/(.*)/, async (req, res) => {
|
|
|
65
65
|
});
|
|
66
66
|
const dir = path.resolve('node_modules/@pulse-editor/cli/dist/lib/server/preview/backend/load-remote.cjs');
|
|
67
67
|
const fileUrl = pathToFileURL(dir).href;
|
|
68
|
-
const {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if (response.body) {
|
|
74
|
-
// Convert WHATWG stream to Node.js stream
|
|
75
|
-
const nodeStream = Readable.fromWeb(response.body);
|
|
76
|
-
// Pipe it directly to Express
|
|
77
|
-
await streamPipeline(nodeStream, res);
|
|
68
|
+
const { loadFunc, loadPrice } = await import(fileUrl);
|
|
69
|
+
const price = await loadPrice(func, pulseConfig.id, 'http://localhost:3030', pulseConfig.version);
|
|
70
|
+
if (price) {
|
|
71
|
+
// Make func name and price bold in console
|
|
72
|
+
console.log(`🏃 Running function \x1b[1m${func}\x1b[0m, credits consumed: \x1b[1m${price}\x1b[0m`);
|
|
78
73
|
}
|
|
79
74
|
else {
|
|
80
|
-
|
|
75
|
+
console.log(`🏃 Running function \x1b[1m${func}\x1b[0m.`);
|
|
76
|
+
}
|
|
77
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
78
|
+
const loadedFunc = await loadFunc(func, pulseConfig.id, 'http://localhost:3030', pulseConfig.version);
|
|
79
|
+
const response = await loadedFunc(request);
|
|
80
|
+
const streamPipeline = promisify(pipeline);
|
|
81
|
+
if (response) {
|
|
82
|
+
// 1️⃣ Set status code
|
|
83
|
+
res.status(response.status);
|
|
84
|
+
// 2️⃣ Copy headers
|
|
85
|
+
response.headers.forEach((value, key) => {
|
|
86
|
+
res.setHeader(key, value);
|
|
87
|
+
});
|
|
88
|
+
// 3️⃣ Pipe body if present
|
|
89
|
+
if (response.body) {
|
|
90
|
+
const nodeStream = Readable.fromWeb(response.body);
|
|
91
|
+
await streamPipeline(nodeStream, res);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
res.end();
|
|
95
|
+
}
|
|
81
96
|
}
|
|
82
97
|
});
|
|
83
98
|
if (isPreview) {
|
|
@@ -94,12 +109,12 @@ else {
|
|
|
94
109
|
/* Production mode */
|
|
95
110
|
app.use(`/${pulseConfig.id}/${pulseConfig.version}`, express.static('dist'));
|
|
96
111
|
app.listen(3030, '0.0.0.0', () => {
|
|
97
|
-
console.log(`\
|
|
98
|
-
🎉 Your Pulse extension \x1b[1m${pulseConfig.displayName}\x1b[0m is LIVE!
|
|
99
|
-
|
|
100
|
-
⚡️ Local: http://localhost:3030/${pulseConfig.id}/${pulseConfig.version}/
|
|
101
|
-
⚡️ Network: http://${getLocalNetworkIP()}:3030/${pulseConfig.id}/${pulseConfig.version}/
|
|
102
|
-
|
|
112
|
+
console.log(`\
|
|
113
|
+
🎉 Your Pulse extension \x1b[1m${pulseConfig.displayName}\x1b[0m is LIVE!
|
|
114
|
+
|
|
115
|
+
⚡️ Local: http://localhost:3030/${pulseConfig.id}/${pulseConfig.version}/
|
|
116
|
+
⚡️ Network: http://${getLocalNetworkIP()}:3030/${pulseConfig.id}/${pulseConfig.version}/
|
|
117
|
+
|
|
103
118
|
✨ Try it out in the Pulse Editor and let the magic happen! 🚀`);
|
|
104
119
|
});
|
|
105
120
|
}
|
|
@@ -1,23 +1,33 @@
|
|
|
1
|
-
const {
|
|
2
|
-
|
|
3
|
-
async function
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
1
|
+
const {createInstance} = require('@module-federation/runtime');
|
|
2
|
+
|
|
3
|
+
async function importRemoteModule(func, appId, origin, version) {
|
|
4
|
+
const instance = createInstance({
|
|
5
|
+
name: 'server_function_runner',
|
|
6
|
+
remotes: [
|
|
7
|
+
{
|
|
8
|
+
name: appId + '_server',
|
|
9
|
+
entry: `${origin}/${appId}/${version}/server/remoteEntry.js`,
|
|
10
|
+
},
|
|
11
|
+
],
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
const loadedModule = await instance.loadRemote(`${appId}_server/${func}`);
|
|
15
|
+
return loadedModule;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async function loadFunc(func, appId, origin, version) {
|
|
19
|
+
// here we assign the return value of the init() function, which can be used to do some more complex
|
|
20
|
+
// things with the module federation runtime
|
|
21
|
+
const module = await importRemoteModule(func, appId, origin, version);
|
|
22
|
+
const loadedFunc = module.default;
|
|
23
|
+
|
|
24
|
+
return loadedFunc;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async function loadPrice(func, appId, origin, version) {
|
|
28
|
+
const module = await importRemoteModule(func, appId, origin, version);
|
|
29
|
+
const price = module._CREDIT_PER_CALL;
|
|
30
|
+
return price;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
module.exports = {loadFunc, loadPrice};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>Pulse App</title>
|
|
7
|
-
</head>
|
|
8
|
-
<body style="height: 100vh; width: 100vw">
|
|
9
|
-
<div id="root" style="height: 100%; width: 100%"></div>
|
|
10
|
-
</body>
|
|
11
|
-
</html>
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>Pulse App</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body style="height: 100vh; width: 100vw">
|
|
9
|
+
<div id="root" style="height: 100%; width: 100%"></div>
|
|
10
|
+
</body>
|
|
11
|
+
</html>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import webpack from 'webpack';
|
|
2
|
+
import { createWebpackConfig } from '../../lib/webpack/webpack.config.js';
|
|
3
|
+
export async function webpackCompile(mode, buildTarget, isWatchMode = false) {
|
|
4
|
+
const configs = await createWebpackConfig(mode === 'preview', buildTarget ?? 'both', mode === 'development'
|
|
5
|
+
? 'development'
|
|
6
|
+
: mode === 'preview'
|
|
7
|
+
? 'development'
|
|
8
|
+
: 'production');
|
|
9
|
+
const compiler = webpack(configs);
|
|
10
|
+
if (isWatchMode) {
|
|
11
|
+
compiler.watch({}, (err, stats) => {
|
|
12
|
+
if (err) {
|
|
13
|
+
console.error('❌ Webpack build failed', err);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
return compiler;
|
|
18
|
+
}
|
|
19
|
+
return new Promise((resolve, reject) => {
|
|
20
|
+
compiler.run(err => {
|
|
21
|
+
if (err) {
|
|
22
|
+
reject(err);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
resolve();
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { MultiServerMCPClient } from "@langchain/mcp-adapters";
|
|
2
|
+
import { MessageStreamController } from "../streaming/message-stream-controller";
|
|
3
|
+
export declare function runVibeCoding(mcpClient: MultiServerMCPClient, userPrompt: string, controller: MessageStreamController): Promise<void>;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { MultiServerMCPClient } from "@langchain/mcp-adapters";
|
|
2
|
+
export declare function writeFileToFS(mcpClient: MultiServerMCPClient, uri: string, content: string): Promise<string>;
|
|
3
|
+
export declare function callTerminal(mcpClient: MultiServerMCPClient, command: string): Promise<string>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { AgentTaskMessageData } from "../types";
|
|
2
|
+
export declare class MessageStreamController {
|
|
3
|
+
private controller;
|
|
4
|
+
private msgCounter;
|
|
5
|
+
private messages;
|
|
6
|
+
private timeCountMap;
|
|
7
|
+
constructor(controller: ReadableStreamDefaultController);
|
|
8
|
+
enqueueNew(data: AgentTaskMessageData, isFinal: boolean): number;
|
|
9
|
+
enqueueUpdate(data: AgentTaskMessageData, isFinal: boolean): void;
|
|
10
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export type VibeDevFlowNode = {
|
|
2
|
+
id: string;
|
|
3
|
+
children: VibeDevFlowNode[];
|
|
4
|
+
};
|
|
5
|
+
export declare enum AgentTaskMessageType {
|
|
6
|
+
Creation = "creation",
|
|
7
|
+
Update = "update"
|
|
8
|
+
}
|
|
9
|
+
export declare enum AgentTaskMessageDataType {
|
|
10
|
+
Notification = "notification",
|
|
11
|
+
ToolCall = "toolCall",
|
|
12
|
+
ArtifactOutput = "artifactOutput"
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Data associated with an AgentTaskItem.
|
|
16
|
+
* The fields included depend on the type of the task item.
|
|
17
|
+
*
|
|
18
|
+
* @property type - The type of the task item, defined by the AgentTaskItemType enum.
|
|
19
|
+
* @property title - (Optional) A brief title or summary of the task item.
|
|
20
|
+
* @property description - (Optional) A detailed description of the task item.
|
|
21
|
+
* @property toolName - (Optional) The name of the tool being called (if applicable).
|
|
22
|
+
* @property parameters - (Optional) A record of parameters associated with the tool call (if applicable).
|
|
23
|
+
* @property error - (Optional) An error message if the task item represents an error.
|
|
24
|
+
* @property result - (Optional) The result or output of the task item (if applicable).
|
|
25
|
+
*/
|
|
26
|
+
export type AgentTaskMessageData = {
|
|
27
|
+
type?: AgentTaskMessageDataType;
|
|
28
|
+
title?: string;
|
|
29
|
+
description?: string;
|
|
30
|
+
toolName?: string;
|
|
31
|
+
parameters?: Record<string, unknown>;
|
|
32
|
+
error?: string;
|
|
33
|
+
result?: string;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Represents a single task item generated by the agent.
|
|
37
|
+
* Each task item can be of different types such as tool calls, notifications, or errors.
|
|
38
|
+
*
|
|
39
|
+
* @property type - The type of the task item, defined by the AgentTaskItemType enum.
|
|
40
|
+
* @property messageId - The unique identifier for the task item.
|
|
41
|
+
* This is an incremental number representing the n-th task item.
|
|
42
|
+
* @property data - The data associated with the task item, which varies based on the type.
|
|
43
|
+
* @property isFinal - (Optional) Indicates if the task item is final and no further updates are expected.
|
|
44
|
+
*/
|
|
45
|
+
export type AgentTaskMessage = {
|
|
46
|
+
type: AgentTaskMessageType;
|
|
47
|
+
messageId: number;
|
|
48
|
+
data: AgentTaskMessageData;
|
|
49
|
+
isFinal?: boolean;
|
|
50
|
+
};
|
|
51
|
+
export type AgentTaskMessageUpdate = {
|
|
52
|
+
type: AgentTaskMessageType;
|
|
53
|
+
messageId: number;
|
|
54
|
+
updateType: "append";
|
|
55
|
+
delta: AgentTaskMessageData;
|
|
56
|
+
isFinal?: boolean;
|
|
57
|
+
timeUsedSec?: string;
|
|
58
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function handler(req: Request): Promise<Response>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"module": "esnext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"strict": true,
|
|
7
|
+
"declaration": true,
|
|
8
|
+
"outDir": "dist",
|
|
9
|
+
},
|
|
10
|
+
"include": [
|
|
11
|
+
"../../../../../../src/server-function/**/*",
|
|
12
|
+
"../../../../../../pulse.config.ts",
|
|
13
|
+
"../../../../../../global.d.ts",
|
|
14
|
+
],
|
|
15
|
+
"exclude": [
|
|
16
|
+
"../../../../../../node_modules",
|
|
17
|
+
"../../../../../../dist",
|
|
18
|
+
]
|
|
19
|
+
}
|