vmlive 1.0.15 → 1.0.18
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 +3 -3
- package/package.json +1 -1
- package/src/cli.js +16 -16
- package/src/string-shim.js +39 -1
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# @vmlive/cli
|
|
2
2
|
|
|
3
|
-
Local emulation sandbox
|
|
3
|
+
Local emulation sandbox, deployment CLI, and AI Edge toolkit for vm.live.
|
|
4
4
|
|
|
5
|
-
This CLI provides a local development environment for serverless edge functions running on vm.live, including local emulation for DB, KV, and
|
|
5
|
+
This CLI provides a local development environment for serverless edge functions running on vm.live, including local emulation for DB, KV, Bucket storage, and Native AI capabilities.
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
@@ -30,7 +30,7 @@ Interactively scaffolds additional serverless endpoints natively into your `src/
|
|
|
30
30
|
Starts the local emulation environment.
|
|
31
31
|
- Iteratively hosts your entire multi-function footprint locally via predictable slugs: `http://<workspace_id>-<project_id>-<function_name>.localhost:8787`.
|
|
32
32
|
- **Local Dashboard:** Automatically spawns a web dashboard at `http://dashboard.localhost:8787` for visualizing offline databases, global KV, and Object Storage.
|
|
33
|
-
- Provides local proxy bindings for your SQL Database (`env.DB`), Global KV (`env.KV`),
|
|
33
|
+
- Provides local proxy bindings for your SQL Database (`env.DB`), Global KV (`env.KV`), Object Storage (`env.BUCKET`), and AI/Memory Models (`env.AI`) using the `.vmlive/` directory for persistent storage.
|
|
34
34
|
- Supports hot-reloading for `.js` and `.ts` files.
|
|
35
35
|
|
|
36
36
|
|
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -761,17 +761,17 @@ const runDb = async () => {
|
|
|
761
761
|
|
|
762
762
|
if (envArg === 'local') {
|
|
763
763
|
console.log('\x1b[90mSyncing Local V8 Emulator D1...\x1b[0m');
|
|
764
|
-
const mf = new Emulator({
|
|
764
|
+
const mf = new Emulator({
|
|
765
765
|
modules: true,
|
|
766
|
-
script: 'export default { fetch: () => new Response("ok") }',
|
|
767
|
-
d1Databases: ["DB"]
|
|
766
|
+
script: 'export default { fetch: () => new Response("ok") }',
|
|
767
|
+
d1Databases: ["DB"]
|
|
768
768
|
});
|
|
769
769
|
try {
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
} catch(e) {
|
|
774
|
-
|
|
770
|
+
const db = await mf.getD1Database("DB");
|
|
771
|
+
await db.exec(combinedSql);
|
|
772
|
+
console.log('\x1b[32m✔ Local Database push successful.\x1b[0m');
|
|
773
|
+
} catch (e) {
|
|
774
|
+
console.error('\n\x1b[31m❌ Local execute failed:\x1b[0m', e.message);
|
|
775
775
|
}
|
|
776
776
|
await mf.dispose();
|
|
777
777
|
} else {
|
|
@@ -789,18 +789,18 @@ const runDb = async () => {
|
|
|
789
789
|
|
|
790
790
|
const { projectId } = vmConf;
|
|
791
791
|
console.log(`\x1b[90mSyncing Cloudflare Edge D1 [${projectId}]...\x1b[0m`);
|
|
792
|
-
|
|
792
|
+
|
|
793
793
|
try {
|
|
794
794
|
const res = await fetch(`${GATEKEEPER_URL}/api/projects/${projectId}/database/migrate`, {
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
795
|
+
method: 'POST',
|
|
796
|
+
headers: { 'Authorization': `Bearer ${jwtToken}`, 'Content-Type': 'application/json' },
|
|
797
|
+
body: JSON.stringify({ sql: combinedSql })
|
|
798
798
|
});
|
|
799
|
-
|
|
799
|
+
|
|
800
800
|
if (res.ok) {
|
|
801
|
-
|
|
801
|
+
console.log('\n\x1b[32m✔ Cloudflare D1 Remote Pipeline successfully upgraded.\x1b[0m');
|
|
802
802
|
} else {
|
|
803
|
-
|
|
803
|
+
console.error('\n\x1b[31m❌ Remote Migration Error:\x1b[0m', res.status, await res.text());
|
|
804
804
|
}
|
|
805
805
|
} catch (err) {
|
|
806
806
|
console.error('\n\x1b[31m❌ Network Failure:\x1b[0m', err.message);
|
|
@@ -836,7 +836,7 @@ const main = async () => {
|
|
|
836
836
|
console.log(' \x1b[32mlogin\x1b[0m Authenticate your local environment securely via Stripe/OAuth');
|
|
837
837
|
console.log(' \x1b[32mdeploy\x1b[0m Upload your footprint to the vm.live edge platform');
|
|
838
838
|
console.log(' \x1b[32mdb\x1b[0m Manage Cloudflare D1 schema migrations (`db push local|remote`)');
|
|
839
|
-
console.log(' \x1b[32mllm\x1b[0m Download the official AI Context Rules for agentic workflows');
|
|
839
|
+
console.log(' \x1b[32mllm\x1b[0m Download the official AI Edge Context Rules for agentic workflows');
|
|
840
840
|
console.log(' \x1b[32mupdate\x1b[0m Upgrade this CLI engine to the latest published version');
|
|
841
841
|
console.log(' \x1b[32mwhich\x1b[0m Display the currently active CLI version');
|
|
842
842
|
console.log('');
|
package/src/string-shim.js
CHANGED
|
@@ -109,6 +109,43 @@ export default {
|
|
|
109
109
|
}
|
|
110
110
|
};
|
|
111
111
|
|
|
112
|
+
const createRpcProxy = (serviceName) => new Proxy({}, {
|
|
113
|
+
get: (_, method) => async (...args) => {
|
|
114
|
+
console.log(\`\\x1b[35m[\${env.PROJECT_ID || '${projectId}'}]\\x1b[0m ☁️ \${serviceName}.\${method} proxied to vm.live edge\`);
|
|
115
|
+
|
|
116
|
+
let body;
|
|
117
|
+
let contentType = "application/json";
|
|
118
|
+
|
|
119
|
+
if (args.length === 1 && args[0] instanceof ArrayBuffer) {
|
|
120
|
+
body = args[0];
|
|
121
|
+
contentType = "application/octet-stream";
|
|
122
|
+
} else {
|
|
123
|
+
body = JSON.stringify({ args });
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const req = new Request(\`https://vm.live/.internal/rpc/\${serviceName.toLowerCase()}/\${method}\`, {
|
|
127
|
+
method: "POST",
|
|
128
|
+
headers: {
|
|
129
|
+
"Authorization": \`Bearer \${safeEnv.BILLING_TOKEN || 'local'}\`,
|
|
130
|
+
"Content-Type": contentType
|
|
131
|
+
},
|
|
132
|
+
body
|
|
133
|
+
});
|
|
134
|
+
const res = await fetch(req);
|
|
135
|
+
if (!res.ok) throw new Error(\`vm.live RPC Error: \${await res.text()}\`);
|
|
136
|
+
|
|
137
|
+
const isStream = res.headers.get("Content-Type") === "text/event-stream";
|
|
138
|
+
if (isStream) return res.body;
|
|
139
|
+
|
|
140
|
+
const isBuffer = res.headers.get("Content-Type") === "application/octet-stream" || res.headers.get("Content-Type")?.includes("image/");
|
|
141
|
+
if (isBuffer) return await res.arrayBuffer();
|
|
142
|
+
|
|
143
|
+
return await res.json();
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
const AI = createRpcProxy("AI");
|
|
148
|
+
|
|
112
149
|
// 3. Hydrate exact customEnv definition expected by the tenant code
|
|
113
150
|
const customEnv = {
|
|
114
151
|
...safeEnv,
|
|
@@ -117,7 +154,8 @@ export default {
|
|
|
117
154
|
Tasks,
|
|
118
155
|
Channels,
|
|
119
156
|
Discord,
|
|
120
|
-
Slack
|
|
157
|
+
Slack,
|
|
158
|
+
AI
|
|
121
159
|
};
|
|
122
160
|
|
|
123
161
|
// 4. Secure boundary execution
|