@mindexec/cli 0.2.0
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 +275 -0
- package/codex-runtime.js +960 -0
- package/launch-bridge.cjs +162 -0
- package/package.json +61 -0
- package/port-guard.cjs +232 -0
- package/scripts/setup-tree-sitter-grammars.mjs +59 -0
- package/server.js +8422 -0
- package/start-bridge.bat +32 -0
- package/start-bridge.sh +81 -0
- package/tree-sitter-grammars/README.md +18 -0
- package/tree-sitter-grammars/tree-sitter-c_sharp.wasm +0 -0
- package/tree-sitter-grammars/tree-sitter-go.wasm +0 -0
- package/tree-sitter-grammars/tree-sitter-java.wasm +0 -0
- package/tree-sitter-grammars/tree-sitter-javascript.wasm +0 -0
- package/tree-sitter-grammars/tree-sitter-python.wasm +0 -0
- package/tree-sitter-grammars/tree-sitter-rust.wasm +0 -0
- package/tree-sitter-grammars/tree-sitter-tsx.wasm +0 -0
- package/tree-sitter-grammars/tree-sitter-typescript.wasm +0 -0
- package/wwwroot/MindExecution.Web.styles.css +3 -0
- package/wwwroot/_content/MindExecution.Plugins.Admin/css/admin-dashboard.css +546 -0
- package/wwwroot/_content/MindExecution.Plugins.Directory/MindExecution.Plugins.Directory.u7utcng611.bundle.scp.css +7 -0
- package/wwwroot/_content/MindExecution.Plugins.Directory/background.png +0 -0
- package/wwwroot/_content/MindExecution.Plugins.Directory/directory-manager.js +202 -0
- package/wwwroot/_content/MindExecution.Plugins.Directory/exampleJsInterop.js +6 -0
- package/wwwroot/_content/MindExecution.Plugins.YouTube/css/youtube-search.css +251 -0
- package/wwwroot/_content/MindExecution.Shared/MindExecution.Shared.wsano1j4wp.bundle.scp.css +4 -0
- package/wwwroot/_content/MindExecution.Shared/css/admin-dashboard.css +559 -0
- package/wwwroot/_content/MindExecution.Shared/css/app.css +1 -0
- package/wwwroot/_content/MindExecution.Shared/css/mind-map-overrides.css +2936 -0
- package/wwwroot/_content/MindExecution.Shared/fonts/NotoSansKR-Bold.ttf +0 -0
- package/wwwroot/_content/MindExecution.Shared/fonts/NotoSansKR-Regular.ttf +0 -0
- package/wwwroot/_content/MindExecution.Shared/js/agent-visualization.js +359 -0
- package/wwwroot/_content/MindExecution.Shared/js/background-themes.js +1721 -0
- package/wwwroot/_content/MindExecution.Shared/js/code-master.js +8316 -0
- package/wwwroot/_content/MindExecution.Shared/js/file-system-helper.js +639 -0
- package/wwwroot/_content/MindExecution.Shared/js/helpers/InfiniteGridHelper.js +109 -0
- package/wwwroot/_content/MindExecution.Shared/js/marked.min.js +69 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-core.js +7982 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-core.js.backup +1059 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-css3d-manager.js +15803 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-dev-guards.js +325 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-dnd.js +1430 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-dnd.js.bak +434 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-glow-shader.js +260 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-interactions.js +7640 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-lod-plan-worker.js +160 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-lod-renderer.js +9923 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-logic-workers.js +977 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-menu-manager.js +1431 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-multi-select.js +1716 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-node-search-worker.js +553 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-nodes.js +4541 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-object-manager.js +489 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-object-manager.js.backup +372 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-pipeline.js +2075 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-text-lod-system.js +646 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-text-overlay-v2.js +4323 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-texture-factory.js +2260 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-texture-factory.js.backup +1258 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-visibility-worker.js +890 -0
- package/wwwroot/_content/MindExecution.Shared/js/mindmap-toolbar.js +594 -0
- package/wwwroot/_content/MindExecution.Shared/js/native-drop-handler.js +170 -0
- package/wwwroot/_content/MindExecution.Shared/js/plan-master.js +788 -0
- package/wwwroot/_content/MindExecution.Shared/js/renderers/CSS3DRenderer.js +50 -0
- package/wwwroot/_content/MindExecution.Shared/js/texture-worker-manager.js +188 -0
- package/wwwroot/_content/MindExecution.Shared/js/texture-worker.js +208 -0
- package/wwwroot/_content/MindExecution.Shared/js/three.min.js +6 -0
- package/wwwroot/_content/MindExecution.Shared/js/titlebar-handler.js +191 -0
- package/wwwroot/_content/MindExecution.Shared/js/token-manager.js +37 -0
- package/wwwroot/_content/MindExecution.Shared/js/token-worker.js +28 -0
- package/wwwroot/_content/MindExecution.Shared/js/troika-bundle.js +5626 -0
- package/wwwroot/_content/MindExecution.Shared/js/troika-bundle.js.map +7 -0
- package/wwwroot/_content/MindExecution.Shared/lib/font-awesome/css/all.min.css +9 -0
- package/wwwroot/_content/MindExecution.Shared/lib/font-awesome/webfonts/fa-brands-400.ttf +0 -0
- package/wwwroot/_content/MindExecution.Shared/lib/font-awesome/webfonts/fa-brands-400.woff2 +0 -0
- package/wwwroot/_content/MindExecution.Shared/lib/font-awesome/webfonts/fa-regular-400.ttf +0 -0
- package/wwwroot/_content/MindExecution.Shared/lib/font-awesome/webfonts/fa-regular-400.woff2 +0 -0
- package/wwwroot/_content/MindExecution.Shared/lib/font-awesome/webfonts/fa-solid-900.ttf +0 -0
- package/wwwroot/_content/MindExecution.Shared/lib/font-awesome/webfonts/fa-solid-900.woff2 +0 -0
- package/wwwroot/_content/MindExecution.Shared/models/all-MiniLM-L6-v2-quantized.onnx +0 -0
- package/wwwroot/_content/MindExecution.Shared/models/vocab.txt +30522 -0
- package/wwwroot/_framework/Google.Protobuf.9h59ukbel7.dll +0 -0
- package/wwwroot/_framework/Markdig.d1j7v41cl1.dll +0 -0
- package/wwwroot/_framework/MessagePack.Annotations.l6qv48kgpt.dll +0 -0
- package/wwwroot/_framework/MessagePack.eqoptzx9d5.dll +0 -0
- package/wwwroot/_framework/Microsoft.AspNetCore.Authorization.k7dsih5y5g.dll +0 -0
- package/wwwroot/_framework/Microsoft.AspNetCore.Components.6nyje9sa0g.dll +0 -0
- package/wwwroot/_framework/Microsoft.AspNetCore.Components.Authorization.iycd6unprw.dll +0 -0
- package/wwwroot/_framework/Microsoft.AspNetCore.Components.Web.487u3twia4.dll +0 -0
- package/wwwroot/_framework/Microsoft.AspNetCore.Components.WebAssembly.d0gcnmlxxz.dll +0 -0
- package/wwwroot/_framework/Microsoft.AspNetCore.Metadata.h4yevl9adi.dll +0 -0
- package/wwwroot/_framework/Microsoft.CSharp.qrvp77qmhs.dll +0 -0
- package/wwwroot/_framework/Microsoft.Data.Sqlite.jdlxgv2jtg.dll +0 -0
- package/wwwroot/_framework/Microsoft.EntityFrameworkCore.4gjazp7kjf.dll +0 -0
- package/wwwroot/_framework/Microsoft.EntityFrameworkCore.Abstractions.gocudnvz7b.dll +0 -0
- package/wwwroot/_framework/Microsoft.EntityFrameworkCore.Relational.lt4rsvinuo.dll +0 -0
- package/wwwroot/_framework/Microsoft.EntityFrameworkCore.Sqlite.69luj0fa9r.dll +0 -0
- package/wwwroot/_framework/Microsoft.Extensions.Caching.Abstractions.364t4jh3zz.dll +0 -0
- package/wwwroot/_framework/Microsoft.Extensions.Caching.Memory.izlxhpzosu.dll +0 -0
- package/wwwroot/_framework/Microsoft.Extensions.Configuration.8zq7hh41o7.dll +0 -0
- package/wwwroot/_framework/Microsoft.Extensions.Configuration.Abstractions.8if74zs6ea.dll +0 -0
- package/wwwroot/_framework/Microsoft.Extensions.Configuration.Json.duvlngw8i0.dll +0 -0
- package/wwwroot/_framework/Microsoft.Extensions.DependencyInjection.Abstractions.t2hh9kvx0o.dll +0 -0
- package/wwwroot/_framework/Microsoft.Extensions.DependencyInjection.n4tg99oy8l.dll +0 -0
- package/wwwroot/_framework/Microsoft.Extensions.DependencyModel.h0d06ixk3e.dll +0 -0
- package/wwwroot/_framework/Microsoft.Extensions.Logging.Abstractions.rl32bkx2sd.dll +0 -0
- package/wwwroot/_framework/Microsoft.Extensions.Logging.dlht1xei0t.dll +0 -0
- package/wwwroot/_framework/Microsoft.Extensions.Options.qeunebioml.dll +0 -0
- package/wwwroot/_framework/Microsoft.Extensions.Primitives.18cr6vnuuz.dll +0 -0
- package/wwwroot/_framework/Microsoft.IO.RecyclableMemoryStream.r915vovvw4.dll +0 -0
- package/wwwroot/_framework/Microsoft.IdentityModel.Abstractions.1ejljk3erv.dll +0 -0
- package/wwwroot/_framework/Microsoft.IdentityModel.JsonWebTokens.1596zr8gne.dll +0 -0
- package/wwwroot/_framework/Microsoft.IdentityModel.Logging.229uyvpgio.dll +0 -0
- package/wwwroot/_framework/Microsoft.IdentityModel.Tokens.9sibtajc9f.dll +0 -0
- package/wwwroot/_framework/Microsoft.JSInterop.17lq4j1j7g.dll +0 -0
- package/wwwroot/_framework/Microsoft.JSInterop.WebAssembly.ryia5gxiad.dll +0 -0
- package/wwwroot/_framework/Microsoft.ML.OnnxRuntime.w9deo1m5ss.dll +0 -0
- package/wwwroot/_framework/Microsoft.ML.Tokenizers.cm2vuv2z61.dll +0 -0
- package/wwwroot/_framework/Microsoft.NET.StringTools.3qbrf4v2ki.dll +0 -0
- package/wwwroot/_framework/MimeMapping.og9ys58ylm.dll +0 -0
- package/wwwroot/_framework/MindExecution.Core.1q1trifbuu.dll +0 -0
- package/wwwroot/_framework/MindExecution.Kernel.gwwc40sc45.dll +0 -0
- package/wwwroot/_framework/MindExecution.Plugins.Admin.0jgrn1sckv.dll +0 -0
- package/wwwroot/_framework/MindExecution.Plugins.Business.13mme2qcag.dll +0 -0
- package/wwwroot/_framework/MindExecution.Plugins.Concept.dfp2mdt45q.dll +0 -0
- package/wwwroot/_framework/MindExecution.Plugins.Directory.3w4t6n3se0.dll +0 -0
- package/wwwroot/_framework/MindExecution.Plugins.PlanMaster.s0qpntz420.dll +0 -0
- package/wwwroot/_framework/MindExecution.Plugins.YouTube.iu11fq8d16.dll +0 -0
- package/wwwroot/_framework/MindExecution.Shared.7j27dcqnrc.dll +0 -0
- package/wwwroot/_framework/MindExecution.Web.pq1ty8ov2v.dll +0 -0
- package/wwwroot/_framework/Newtonsoft.Json.a56zs13vug.dll +0 -0
- package/wwwroot/_framework/SQLitePCLRaw.batteries_v2.rrd1nzawpp.dll +0 -0
- package/wwwroot/_framework/SQLitePCLRaw.core.1dxloztpfz.dll +0 -0
- package/wwwroot/_framework/SQLitePCLRaw.provider.e_sqlite3.oekyzl53i1.dll +0 -0
- package/wwwroot/_framework/Supabase.Core.s1pkj4aj0l.dll +0 -0
- package/wwwroot/_framework/Supabase.Functions.qz4nu782sg.dll +0 -0
- package/wwwroot/_framework/Supabase.Gotrue.twah27pkik.dll +0 -0
- package/wwwroot/_framework/Supabase.Postgrest.gmuuv369ih.dll +0 -0
- package/wwwroot/_framework/Supabase.Realtime.ox3kchdy3w.dll +0 -0
- package/wwwroot/_framework/Supabase.Storage.fnjnepaowr.dll +0 -0
- package/wwwroot/_framework/Supabase.azmaw5pgcz.dll +0 -0
- package/wwwroot/_framework/System.Collections.Concurrent.y1zmvuyipi.dll +0 -0
- package/wwwroot/_framework/System.Collections.Immutable.ug3j698qms.dll +0 -0
- package/wwwroot/_framework/System.Collections.NonGeneric.h66hj3863h.dll +0 -0
- package/wwwroot/_framework/System.Collections.Specialized.umr3y27ntj.dll +0 -0
- package/wwwroot/_framework/System.Collections.x53e19vfsj.dll +0 -0
- package/wwwroot/_framework/System.ComponentModel.Annotations.tz6gnt4ebt.dll +0 -0
- package/wwwroot/_framework/System.ComponentModel.Primitives.j7tiphu4rg.dll +0 -0
- package/wwwroot/_framework/System.ComponentModel.TypeConverter.ujlztox1gx.dll +0 -0
- package/wwwroot/_framework/System.ComponentModel.x9xz0ojfb6.dll +0 -0
- package/wwwroot/_framework/System.Console.ijzpqmj7ne.dll +0 -0
- package/wwwroot/_framework/System.Data.Common.1r0sqffq1p.dll +0 -0
- package/wwwroot/_framework/System.Diagnostics.DiagnosticSource.9upoqwq09o.dll +0 -0
- package/wwwroot/_framework/System.Diagnostics.Process.m99azzntjm.dll +0 -0
- package/wwwroot/_framework/System.Diagnostics.TraceSource.pl7wv26myr.dll +0 -0
- package/wwwroot/_framework/System.Diagnostics.Tracing.crlhfx6tut.dll +0 -0
- package/wwwroot/_framework/System.Drawing.Primitives.22e4y9ikq9.dll +0 -0
- package/wwwroot/_framework/System.Drawing.mi7d8hwowb.dll +0 -0
- package/wwwroot/_framework/System.Formats.Asn1.jx23sjiqnn.dll +0 -0
- package/wwwroot/_framework/System.IO.Compression.6fyoii3uej.dll +0 -0
- package/wwwroot/_framework/System.IO.Pipelines.vg77t4cd4d.dll +0 -0
- package/wwwroot/_framework/System.IdentityModel.Tokens.Jwt.t67es60z5b.dll +0 -0
- package/wwwroot/_framework/System.Linq.1bkoxlqgmq.dll +0 -0
- package/wwwroot/_framework/System.Linq.Expressions.24xqiypwdt.dll +0 -0
- package/wwwroot/_framework/System.Linq.Queryable.hvd01d6rsa.dll +0 -0
- package/wwwroot/_framework/System.Memory.8dx3lwgym4.dll +0 -0
- package/wwwroot/_framework/System.Net.Http.Json.3mhdm9l1rf.dll +0 -0
- package/wwwroot/_framework/System.Net.Http.eitrz660my.dll +0 -0
- package/wwwroot/_framework/System.Net.NetworkInformation.3pkuofcv9r.dll +0 -0
- package/wwwroot/_framework/System.Net.Ping.8clj5pklrp.dll +0 -0
- package/wwwroot/_framework/System.Net.Primitives.qrp4wcjz1p.dll +0 -0
- package/wwwroot/_framework/System.Net.WebSockets.Client.2u6pv01g69.dll +0 -0
- package/wwwroot/_framework/System.Net.WebSockets.qp6u31zvm5.dll +0 -0
- package/wwwroot/_framework/System.Numerics.Tensors.0c7z4mt3on.dll +0 -0
- package/wwwroot/_framework/System.Numerics.Vectors.kc7ufp2j4l.dll +0 -0
- package/wwwroot/_framework/System.ObjectModel.qv82fot1ib.dll +0 -0
- package/wwwroot/_framework/System.Private.CoreLib.rkafq04oma.dll +0 -0
- package/wwwroot/_framework/System.Private.Uri.t9542hmr6j.dll +0 -0
- package/wwwroot/_framework/System.Private.Xml.Linq.n8n3ptrbwu.dll +0 -0
- package/wwwroot/_framework/System.Private.Xml.rxd3tytisn.dll +0 -0
- package/wwwroot/_framework/System.Reactive.t3fuon548l.dll +0 -0
- package/wwwroot/_framework/System.Reflection.Emit.9tjhp6y0j3.dll +0 -0
- package/wwwroot/_framework/System.Reflection.Emit.ILGeneration.stxyk8zoo1.dll +0 -0
- package/wwwroot/_framework/System.Reflection.Emit.Lightweight.6xrd5v8vg0.dll +0 -0
- package/wwwroot/_framework/System.Reflection.Primitives.wgn8fpwwvv.dll +0 -0
- package/wwwroot/_framework/System.Runtime.InteropServices.JavaScript.sliym526xh.dll +0 -0
- package/wwwroot/_framework/System.Runtime.InteropServices.RuntimeInformation.oji7zut14z.dll +0 -0
- package/wwwroot/_framework/System.Runtime.InteropServices.te07xr2we9.dll +0 -0
- package/wwwroot/_framework/System.Runtime.Intrinsics.507y4h8nzq.dll +0 -0
- package/wwwroot/_framework/System.Runtime.Loader.v7gk4bse0k.dll +0 -0
- package/wwwroot/_framework/System.Runtime.Numerics.eqy5xjv3nd.dll +0 -0
- package/wwwroot/_framework/System.Runtime.Serialization.Formatters.zpkrub8lab.dll +0 -0
- package/wwwroot/_framework/System.Runtime.Serialization.Primitives.vhkpnbxjip.dll +0 -0
- package/wwwroot/_framework/System.Runtime.jn319d5nyg.dll +0 -0
- package/wwwroot/_framework/System.Security.Claims.0ztig1q9vo.dll +0 -0
- package/wwwroot/_framework/System.Security.Cryptography.vttizqc9ho.dll +0 -0
- package/wwwroot/_framework/System.Text.Encoding.Extensions.utdd47ny8f.dll +0 -0
- package/wwwroot/_framework/System.Text.Encodings.Web.wah8r1zoe0.dll +0 -0
- package/wwwroot/_framework/System.Text.Json.kxlfxj0wrs.dll +0 -0
- package/wwwroot/_framework/System.Text.RegularExpressions.dbqn58klox.dll +0 -0
- package/wwwroot/_framework/System.Threading.42ao9vi047.dll +0 -0
- package/wwwroot/_framework/System.Threading.Channels.hfa7j0uv2w.dll +0 -0
- package/wwwroot/_framework/System.Threading.Thread.caul0pdqul.dll +0 -0
- package/wwwroot/_framework/System.Transactions.Local.fimi2hamzo.dll +0 -0
- package/wwwroot/_framework/System.Web.HttpUtility.gq8yz50p2e.dll +0 -0
- package/wwwroot/_framework/System.Xml.Linq.kitin4zjoj.dll +0 -0
- package/wwwroot/_framework/System.Xml.ReaderWriter.kzvw3qgxb0.dll +0 -0
- package/wwwroot/_framework/System.Xml.XDocument.c539ki6cuq.dll +0 -0
- package/wwwroot/_framework/System.m05i39uvk9.dll +0 -0
- package/wwwroot/_framework/Websocket.Client.vapounvmnl.dll +0 -0
- package/wwwroot/_framework/blazor.boot.json +305 -0
- package/wwwroot/_framework/blazor.webassembly.js +1 -0
- package/wwwroot/_framework/dotnet.js +4 -0
- package/wwwroot/_framework/dotnet.native.vz0adxojrz.wasm +0 -0
- package/wwwroot/_framework/dotnet.native.xsn1d6x2kd.js +16 -0
- package/wwwroot/_framework/dotnet.runtime.dstopyvqzi.js +4 -0
- package/wwwroot/_framework/icudt_CJK.tjcz0u77k5.dat +0 -0
- package/wwwroot/_framework/icudt_EFIGS.tptq2av103.dat +0 -0
- package/wwwroot/_framework/icudt_no_CJK.lfu7j35m59.dat +0 -0
- package/wwwroot/_framework/netstandard.0xet7jg7ky.dll +0 -0
- package/wwwroot/_headers +40 -0
- package/wwwroot/_redirects +1 -0
- package/wwwroot/appsettings.json +71 -0
- package/wwwroot/icon-192.png +0 -0
- package/wwwroot/icon-512.png +0 -0
- package/wwwroot/index.html +710 -0
- package/wwwroot/js/marketing-tool.js +180 -0
- package/wwwroot/manifest.webmanifest +22 -0
- package/wwwroot/robots.txt +4 -0
- package/wwwroot/service-worker-assets.js +857 -0
- package/wwwroot/service-worker.js +33 -0
- package/wwwroot/sitemap.xml +27 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const { spawn } = require('child_process');
|
|
5
|
+
const packageInfo = require('./package.json');
|
|
6
|
+
const { normalizePort, releaseBridgePort } = require('./port-guard.cjs');
|
|
7
|
+
|
|
8
|
+
const bridgeRoot = __dirname;
|
|
9
|
+
const serverPath = path.resolve(bridgeRoot, 'server.js');
|
|
10
|
+
const inheritedWorkspacePath = String(process.env.WORKSPACE_PATH || '').trim();
|
|
11
|
+
const workspacePath = inheritedWorkspacePath || path.resolve(bridgeRoot, '..');
|
|
12
|
+
const rawArgs = process.argv.slice(2);
|
|
13
|
+
const appUrl = `http://localhost:${normalizePort(process.env.BRIDGE_PORT)}/mindcanvas`;
|
|
14
|
+
const statusUrl = `http://127.0.0.1:${normalizePort(process.env.BRIDGE_PORT)}/api/status`;
|
|
15
|
+
|
|
16
|
+
function printHelp() {
|
|
17
|
+
console.log(`MindExec CLI ${packageInfo.version}
|
|
18
|
+
|
|
19
|
+
Usage:
|
|
20
|
+
mindexec [start] [node-options]
|
|
21
|
+
npx @mindexec/cli
|
|
22
|
+
|
|
23
|
+
Runs the MindExec local app and bridge on http://localhost:5147/mindcanvas by default.
|
|
24
|
+
|
|
25
|
+
Environment:
|
|
26
|
+
BRIDGE_PORT Local bridge port. Default: 5147
|
|
27
|
+
WORKSPACE_PATH Workspace root. Default: parent of the installed package
|
|
28
|
+
BRIDGE_TOKEN Fixed token for protected REST APIs
|
|
29
|
+
MINDEXEC_WEB_ROOT Published MindCanvas wwwroot override. Default: package wwwroot
|
|
30
|
+
MINDEXEC_NO_OPEN=1
|
|
31
|
+
Do not open the local app in the default browser
|
|
32
|
+
BRIDGE_SKIP_PORT_REAP=1
|
|
33
|
+
Do not stop an existing MindExec bridge on the same port
|
|
34
|
+
BRIDGE_FORCE_KILL_PORT_OWNER=1
|
|
35
|
+
Stop any process that owns BRIDGE_PORT before starting
|
|
36
|
+
|
|
37
|
+
Examples:
|
|
38
|
+
mindexec
|
|
39
|
+
mindexec --no-open
|
|
40
|
+
BRIDGE_PORT=8080 WORKSPACE_PATH=/path/to/work mindexec
|
|
41
|
+
mindexec --watch
|
|
42
|
+
`);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (rawArgs.includes('--help') || rawArgs.includes('-h')) {
|
|
46
|
+
printHelp();
|
|
47
|
+
process.exit(0);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (rawArgs.includes('--version') || rawArgs.includes('-v')) {
|
|
51
|
+
console.log(packageInfo.version);
|
|
52
|
+
process.exit(0);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const command = rawArgs[0];
|
|
56
|
+
const commandArgs = command === 'start' || command === 'bridge'
|
|
57
|
+
? rawArgs.slice(1)
|
|
58
|
+
: rawArgs;
|
|
59
|
+
const shouldOpenApp = !commandArgs.some(arg => arg === '--no-open' || arg === '--no-browser')
|
|
60
|
+
&& !/^(1|true|yes|on)$/i.test(String(process.env.MINDEXEC_NO_OPEN || '').trim())
|
|
61
|
+
&& !/^(0|false|no|off)$/i.test(String(process.env.MINDEXEC_OPEN_APP || '').trim());
|
|
62
|
+
const runtimeArgs = commandArgs.filter(arg => arg !== '--no-open' && arg !== '--no-browser');
|
|
63
|
+
const childArgs = [...runtimeArgs, serverPath];
|
|
64
|
+
const port = normalizePort(process.env.BRIDGE_PORT);
|
|
65
|
+
|
|
66
|
+
function delay(ms) {
|
|
67
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async function waitForBridgeReady(timeoutMs = 15000) {
|
|
71
|
+
const startedAt = Date.now();
|
|
72
|
+
while (Date.now() - startedAt < timeoutMs) {
|
|
73
|
+
try {
|
|
74
|
+
const response = await fetch(statusUrl, { cache: 'no-store' });
|
|
75
|
+
if (response.ok) {
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
} catch {
|
|
79
|
+
// Server is still booting.
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
await delay(300);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function openLocalApp() {
|
|
89
|
+
let child;
|
|
90
|
+
if (process.platform === 'win32') {
|
|
91
|
+
child = spawn('cmd', ['/c', 'start', '', appUrl], {
|
|
92
|
+
detached: true,
|
|
93
|
+
stdio: 'ignore',
|
|
94
|
+
windowsHide: true
|
|
95
|
+
});
|
|
96
|
+
} else if (process.platform === 'darwin') {
|
|
97
|
+
child = spawn('open', [appUrl], {
|
|
98
|
+
detached: true,
|
|
99
|
+
stdio: 'ignore'
|
|
100
|
+
});
|
|
101
|
+
} else {
|
|
102
|
+
child = spawn('xdg-open', [appUrl], {
|
|
103
|
+
detached: true,
|
|
104
|
+
stdio: 'ignore'
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
child.on('error', () => {
|
|
109
|
+
console.log(`[MindExec CLI] Open the app manually: ${appUrl}`);
|
|
110
|
+
});
|
|
111
|
+
child.unref();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async function main() {
|
|
115
|
+
await releaseBridgePort({
|
|
116
|
+
port,
|
|
117
|
+
bridgeRoot,
|
|
118
|
+
log: message => console.log(`[MindExec CLI] ${message}`)
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
const child = spawn(process.execPath, childArgs, {
|
|
122
|
+
cwd: bridgeRoot,
|
|
123
|
+
env: {
|
|
124
|
+
...process.env,
|
|
125
|
+
WORKSPACE_PATH: workspacePath
|
|
126
|
+
},
|
|
127
|
+
stdio: 'inherit',
|
|
128
|
+
windowsHide: false
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
child.on('exit', (code, signal) => {
|
|
132
|
+
if (signal) {
|
|
133
|
+
process.kill(process.pid, signal);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
process.exit(code ?? 0);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
child.on('error', (error) => {
|
|
141
|
+
console.error('[MindExec CLI] Failed to start local bridge:', error);
|
|
142
|
+
process.exit(1);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
if (shouldOpenApp) {
|
|
146
|
+
void (async () => {
|
|
147
|
+
const ready = await waitForBridgeReady();
|
|
148
|
+
if (!ready || child.exitCode !== null) {
|
|
149
|
+
console.log(`[MindExec CLI] Open the app manually: ${appUrl}`);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
console.log(`[MindExec CLI] opening ${appUrl}`);
|
|
154
|
+
openLocalApp();
|
|
155
|
+
})();
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
main().catch(error => {
|
|
160
|
+
console.error('[MindExec CLI] Failed to prepare local bridge port:', error.message || error);
|
|
161
|
+
process.exit(1);
|
|
162
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mindexec/cli",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "MindExec local runtime and bridge CLI",
|
|
5
|
+
"main": "server.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"files": [
|
|
8
|
+
"start-bridge.bat",
|
|
9
|
+
"start-bridge.sh",
|
|
10
|
+
"launch-bridge.cjs",
|
|
11
|
+
"server.js",
|
|
12
|
+
"codex-runtime.js",
|
|
13
|
+
"port-guard.cjs",
|
|
14
|
+
"wwwroot/",
|
|
15
|
+
"scripts/",
|
|
16
|
+
"tree-sitter-grammars/",
|
|
17
|
+
"README.md"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"start": "node launch-bridge.cjs",
|
|
21
|
+
"dev": "node launch-bridge.cjs --watch",
|
|
22
|
+
"test:syntax": "node --check server.js && node --check codex-runtime.js && node --check launch-bridge.cjs && node --check port-guard.cjs && node --check scripts/setup-tree-sitter-grammars.mjs",
|
|
23
|
+
"pack:dry": "npm pack --dry-run",
|
|
24
|
+
"setup:grammars": "node scripts/setup-tree-sitter-grammars.mjs",
|
|
25
|
+
"postinstall": "npm run setup:grammars"
|
|
26
|
+
},
|
|
27
|
+
"keywords": [
|
|
28
|
+
"mindexec",
|
|
29
|
+
"mindcanvas",
|
|
30
|
+
"cli",
|
|
31
|
+
"bridge",
|
|
32
|
+
"local",
|
|
33
|
+
"ai"
|
|
34
|
+
],
|
|
35
|
+
"author": "",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public"
|
|
39
|
+
},
|
|
40
|
+
"engines": {
|
|
41
|
+
"node": ">=20"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"@openai/codex-sdk": "^0.137.0",
|
|
45
|
+
"chokidar": "^3.6.0",
|
|
46
|
+
"cors": "^2.8.5",
|
|
47
|
+
"express": "^4.18.2",
|
|
48
|
+
"multer": "^2.1.1",
|
|
49
|
+
"playwright-core": "^1.53.0",
|
|
50
|
+
"sharp": "^0.33.2",
|
|
51
|
+
"web-tree-sitter": "^0.22.6",
|
|
52
|
+
"ws": "^8.16.0"
|
|
53
|
+
},
|
|
54
|
+
"bin": {
|
|
55
|
+
"mindexec": "launch-bridge.cjs",
|
|
56
|
+
"mind-bridge": "launch-bridge.cjs"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"tree-sitter-wasms": "^0.1.13"
|
|
60
|
+
}
|
|
61
|
+
}
|
package/port-guard.cjs
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
const { execFile } = require('child_process');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { promisify } = require('util');
|
|
4
|
+
|
|
5
|
+
const execFileAsync = promisify(execFile);
|
|
6
|
+
const DEFAULT_WAIT_MS = 3500;
|
|
7
|
+
|
|
8
|
+
function normalizePort(value, fallback = 5147) {
|
|
9
|
+
const parsed = Number.parseInt(String(value || '').trim(), 10);
|
|
10
|
+
return Number.isInteger(parsed) && parsed > 0 && parsed <= 65535
|
|
11
|
+
? parsed
|
|
12
|
+
: fallback;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function normalizePath(value) {
|
|
16
|
+
return String(value || '').replace(/\\/g, '/').toLowerCase();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function isTruthy(value) {
|
|
20
|
+
return /^(1|true|yes|on)$/i.test(String(value || '').trim());
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function endpointUsesPort(endpoint, port) {
|
|
24
|
+
const text = String(endpoint || '').trim();
|
|
25
|
+
return text.endsWith(`:${port}`)
|
|
26
|
+
|| text.endsWith(`.${port}`)
|
|
27
|
+
|| text.includes(`:${port} `)
|
|
28
|
+
|| text.includes(`]:${port}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function getWindowsListeners(port) {
|
|
32
|
+
const { stdout } = await execFileAsync('netstat.exe', ['-ano', '-p', 'tcp'], {
|
|
33
|
+
windowsHide: true,
|
|
34
|
+
maxBuffer: 1024 * 1024
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const pids = new Set();
|
|
38
|
+
for (const rawLine of String(stdout || '').split(/\r?\n/)) {
|
|
39
|
+
const line = rawLine.trim();
|
|
40
|
+
if (!line || !/\bLISTENING\b/i.test(line)) {
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const parts = line.split(/\s+/);
|
|
45
|
+
if (parts.length < 5 || !endpointUsesPort(parts[1], port)) {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const pid = Number.parseInt(parts[parts.length - 1], 10);
|
|
50
|
+
if (Number.isInteger(pid) && pid > 0 && pid !== process.pid) {
|
|
51
|
+
pids.add(pid);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return [...pids];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async function getUnixListeners(port) {
|
|
59
|
+
try {
|
|
60
|
+
const { stdout } = await execFileAsync('lsof', ['-nP', `-iTCP:${port}`, '-sTCP:LISTEN', '-t'], {
|
|
61
|
+
maxBuffer: 256 * 1024
|
|
62
|
+
});
|
|
63
|
+
return String(stdout || '')
|
|
64
|
+
.split(/\r?\n/)
|
|
65
|
+
.map(line => Number.parseInt(line.trim(), 10))
|
|
66
|
+
.filter(pid => Number.isInteger(pid) && pid > 0 && pid !== process.pid);
|
|
67
|
+
} catch {
|
|
68
|
+
return [];
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async function getPortListeners(port) {
|
|
73
|
+
try {
|
|
74
|
+
return process.platform === 'win32'
|
|
75
|
+
? await getWindowsListeners(port)
|
|
76
|
+
: await getUnixListeners(port);
|
|
77
|
+
} catch {
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async function getWindowsProcessDetails(pid) {
|
|
83
|
+
const script = [
|
|
84
|
+
'$ErrorActionPreference = "SilentlyContinue";',
|
|
85
|
+
`$p = Get-CimInstance Win32_Process -Filter "ProcessId=${pid}";`,
|
|
86
|
+
'if ($p) {',
|
|
87
|
+
' [pscustomobject]@{ ProcessId = $p.ProcessId; ExecutablePath = $p.ExecutablePath; CommandLine = $p.CommandLine } | ConvertTo-Json -Compress',
|
|
88
|
+
'}'
|
|
89
|
+
].join(' ');
|
|
90
|
+
const { stdout } = await execFileAsync('powershell.exe', ['-NoProfile', '-Command', script], {
|
|
91
|
+
windowsHide: true,
|
|
92
|
+
maxBuffer: 256 * 1024
|
|
93
|
+
});
|
|
94
|
+
const parsed = JSON.parse(String(stdout || '{}').trim() || '{}');
|
|
95
|
+
return {
|
|
96
|
+
pid,
|
|
97
|
+
executablePath: parsed.ExecutablePath || '',
|
|
98
|
+
commandLine: parsed.CommandLine || ''
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async function getUnixProcessDetails(pid) {
|
|
103
|
+
const { stdout } = await execFileAsync('ps', ['-p', String(pid), '-o', 'comm=', '-o', 'args='], {
|
|
104
|
+
maxBuffer: 256 * 1024
|
|
105
|
+
});
|
|
106
|
+
const text = String(stdout || '').trim();
|
|
107
|
+
return {
|
|
108
|
+
pid,
|
|
109
|
+
executablePath: text.split(/\s+/)[0] || '',
|
|
110
|
+
commandLine: text
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async function getProcessDetails(pid) {
|
|
115
|
+
try {
|
|
116
|
+
return process.platform === 'win32'
|
|
117
|
+
? await getWindowsProcessDetails(pid)
|
|
118
|
+
: await getUnixProcessDetails(pid);
|
|
119
|
+
} catch {
|
|
120
|
+
return {
|
|
121
|
+
pid,
|
|
122
|
+
executablePath: '',
|
|
123
|
+
commandLine: ''
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function looksLikeMindExecBridge(details, bridgeRoot) {
|
|
129
|
+
const text = normalizePath(`${details.executablePath || ''} ${details.commandLine || ''}`);
|
|
130
|
+
const root = normalizePath(bridgeRoot);
|
|
131
|
+
const packageRoot = normalizePath(path.dirname(bridgeRoot));
|
|
132
|
+
|
|
133
|
+
return (root && text.includes(root))
|
|
134
|
+
|| (packageRoot && text.includes(`${packageRoot}/localbridge/`))
|
|
135
|
+
|| text.includes('localbridge/server.js')
|
|
136
|
+
|| text.includes('localbridge/launch-bridge.cjs')
|
|
137
|
+
|| text.includes('/localbridge/server.js')
|
|
138
|
+
|| text.includes('/localbridge/launch-bridge.cjs')
|
|
139
|
+
|| text.includes('@mindexec/cli')
|
|
140
|
+
|| text.includes('mind-bridge')
|
|
141
|
+
|| /\bmindexec(\.cmd|\.ps1|\.exe)?\b/i.test(text);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
async function waitForPortRelease(port, timeoutMs = DEFAULT_WAIT_MS) {
|
|
145
|
+
const started = Date.now();
|
|
146
|
+
while (Date.now() - started < timeoutMs) {
|
|
147
|
+
const listeners = await getPortListeners(port);
|
|
148
|
+
if (listeners.length === 0) {
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
await new Promise(resolve => setTimeout(resolve, 120));
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function killPid(pid, signal) {
|
|
159
|
+
try {
|
|
160
|
+
process.kill(pid, signal);
|
|
161
|
+
return true;
|
|
162
|
+
} catch {
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
async function releaseBridgePort(options = {}) {
|
|
168
|
+
const port = normalizePort(options.port || process.env.BRIDGE_PORT);
|
|
169
|
+
const bridgeRoot = options.bridgeRoot || __dirname;
|
|
170
|
+
const log = typeof options.log === 'function' ? options.log : () => {};
|
|
171
|
+
const force = isTruthy(process.env.BRIDGE_FORCE_KILL_PORT_OWNER)
|
|
172
|
+
|| isTruthy(process.env.BRIDGE_KILL_ANY_PORT_OWNER);
|
|
173
|
+
const disabled = isTruthy(process.env.BRIDGE_SKIP_PORT_REAP);
|
|
174
|
+
|
|
175
|
+
if (disabled) {
|
|
176
|
+
return { port, killed: [], skipped: [], disabled: true };
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const pids = await getPortListeners(port);
|
|
180
|
+
const killed = [];
|
|
181
|
+
const skipped = [];
|
|
182
|
+
|
|
183
|
+
for (const pid of pids) {
|
|
184
|
+
const details = await getProcessDetails(pid);
|
|
185
|
+
const canKill = force || looksLikeMindExecBridge(details, bridgeRoot);
|
|
186
|
+
if (!canKill) {
|
|
187
|
+
skipped.push(details);
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (killPid(pid, 'SIGTERM')) {
|
|
192
|
+
killed.push(details);
|
|
193
|
+
log(`stopping existing LocalBridge listener on port ${port} (pid ${pid})`);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (killed.length > 0) {
|
|
198
|
+
const released = await waitForPortRelease(port);
|
|
199
|
+
if (!released) {
|
|
200
|
+
const remaining = await getPortListeners(port);
|
|
201
|
+
for (const details of killed) {
|
|
202
|
+
if (remaining.includes(details.pid)) {
|
|
203
|
+
killPid(details.pid, 'SIGKILL');
|
|
204
|
+
log(`force-stopping LocalBridge listener on port ${port} (pid ${details.pid})`);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
await waitForPortRelease(port, 1200);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (skipped.length > 0) {
|
|
213
|
+
const owners = skipped
|
|
214
|
+
.map(item => `pid ${item.pid}${item.commandLine ? ` (${item.commandLine})` : ''}`)
|
|
215
|
+
.join('; ');
|
|
216
|
+
const error = new Error(
|
|
217
|
+
`Port ${port} is already in use by a non-MindExec process: ${owners}. ` +
|
|
218
|
+
'Close it or set BRIDGE_FORCE_KILL_PORT_OWNER=1 to terminate any owner of this bridge port.'
|
|
219
|
+
);
|
|
220
|
+
error.code = 'BRIDGE_PORT_IN_USE';
|
|
221
|
+
error.port = port;
|
|
222
|
+
error.skipped = skipped;
|
|
223
|
+
throw error;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return { port, killed, skipped, disabled: false };
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
module.exports = {
|
|
230
|
+
normalizePort,
|
|
231
|
+
releaseBridgePort
|
|
232
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { promises as fs } from 'fs';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
9
|
+
const bridgeRoot = path.resolve(__dirname, '..');
|
|
10
|
+
const sourceDir = path.join(bridgeRoot, 'node_modules', 'tree-sitter-wasms', 'out');
|
|
11
|
+
const destDir = path.join(bridgeRoot, 'tree-sitter-grammars');
|
|
12
|
+
|
|
13
|
+
const requiredFiles = [
|
|
14
|
+
'tree-sitter-javascript.wasm',
|
|
15
|
+
'tree-sitter-typescript.wasm',
|
|
16
|
+
'tree-sitter-tsx.wasm',
|
|
17
|
+
'tree-sitter-c_sharp.wasm',
|
|
18
|
+
'tree-sitter-python.wasm',
|
|
19
|
+
'tree-sitter-java.wasm',
|
|
20
|
+
'tree-sitter-go.wasm',
|
|
21
|
+
'tree-sitter-rust.wasm'
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
async function ensureDirectory(dir) {
|
|
25
|
+
await fs.mkdir(dir, { recursive: true });
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async function copyGrammarFiles() {
|
|
29
|
+
await ensureDirectory(destDir);
|
|
30
|
+
|
|
31
|
+
let copied = 0;
|
|
32
|
+
const missing = [];
|
|
33
|
+
|
|
34
|
+
for (const fileName of requiredFiles) {
|
|
35
|
+
const src = path.join(sourceDir, fileName);
|
|
36
|
+
const dst = path.join(destDir, fileName);
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
await fs.access(src);
|
|
40
|
+
await fs.copyFile(src, dst);
|
|
41
|
+
copied += 1;
|
|
42
|
+
} catch {
|
|
43
|
+
missing.push(fileName);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (copied > 0) {
|
|
48
|
+
console.log(`[setup:grammars] Copied ${copied} grammar files to ${destDir}`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (missing.length > 0) {
|
|
52
|
+
console.warn('[setup:grammars] Missing grammar files:', missing.join(', '));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
copyGrammarFiles().catch((err) => {
|
|
57
|
+
console.error(`[setup:grammars] Failed: ${err?.message || err}`);
|
|
58
|
+
process.exitCode = 1;
|
|
59
|
+
});
|