nstantpage-agent 0.6.0 → 0.6.1
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/cli.bundle.js +887 -176
- package/dist/cli.js +6 -0
- package/dist/commands/run.d.ts +13 -0
- package/dist/commands/run.js +82 -0
- package/package.json +1 -1
package/dist/cli.bundle.js
CHANGED
|
@@ -972,8 +972,8 @@ var require_command = __commonJS({
|
|
|
972
972
|
"node_modules/commander/lib/command.js"(exports) {
|
|
973
973
|
var EventEmitter = __require("node:events").EventEmitter;
|
|
974
974
|
var childProcess2 = __require("node:child_process");
|
|
975
|
-
var
|
|
976
|
-
var
|
|
975
|
+
var path20 = __require("node:path");
|
|
976
|
+
var fs21 = __require("node:fs");
|
|
977
977
|
var process15 = __require("node:process");
|
|
978
978
|
var { Argument: Argument2, humanReadableArgName } = require_argument();
|
|
979
979
|
var { CommanderError: CommanderError2 } = require_error();
|
|
@@ -1905,11 +1905,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1905
1905
|
let launchWithNode = false;
|
|
1906
1906
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
1907
1907
|
function findFile(baseDir, baseName) {
|
|
1908
|
-
const localBin =
|
|
1909
|
-
if (
|
|
1910
|
-
if (sourceExt.includes(
|
|
1908
|
+
const localBin = path20.resolve(baseDir, baseName);
|
|
1909
|
+
if (fs21.existsSync(localBin)) return localBin;
|
|
1910
|
+
if (sourceExt.includes(path20.extname(baseName))) return void 0;
|
|
1911
1911
|
const foundExt = sourceExt.find(
|
|
1912
|
-
(ext) =>
|
|
1912
|
+
(ext) => fs21.existsSync(`${localBin}${ext}`)
|
|
1913
1913
|
);
|
|
1914
1914
|
if (foundExt) return `${localBin}${foundExt}`;
|
|
1915
1915
|
return void 0;
|
|
@@ -1921,21 +1921,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1921
1921
|
if (this._scriptPath) {
|
|
1922
1922
|
let resolvedScriptPath;
|
|
1923
1923
|
try {
|
|
1924
|
-
resolvedScriptPath =
|
|
1924
|
+
resolvedScriptPath = fs21.realpathSync(this._scriptPath);
|
|
1925
1925
|
} catch (err) {
|
|
1926
1926
|
resolvedScriptPath = this._scriptPath;
|
|
1927
1927
|
}
|
|
1928
|
-
executableDir =
|
|
1929
|
-
|
|
1928
|
+
executableDir = path20.resolve(
|
|
1929
|
+
path20.dirname(resolvedScriptPath),
|
|
1930
1930
|
executableDir
|
|
1931
1931
|
);
|
|
1932
1932
|
}
|
|
1933
1933
|
if (executableDir) {
|
|
1934
1934
|
let localFile = findFile(executableDir, executableFile);
|
|
1935
1935
|
if (!localFile && !subcommand._executableFile && this._scriptPath) {
|
|
1936
|
-
const legacyName =
|
|
1936
|
+
const legacyName = path20.basename(
|
|
1937
1937
|
this._scriptPath,
|
|
1938
|
-
|
|
1938
|
+
path20.extname(this._scriptPath)
|
|
1939
1939
|
);
|
|
1940
1940
|
if (legacyName !== this._name) {
|
|
1941
1941
|
localFile = findFile(
|
|
@@ -1946,7 +1946,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1946
1946
|
}
|
|
1947
1947
|
executableFile = localFile || executableFile;
|
|
1948
1948
|
}
|
|
1949
|
-
launchWithNode = sourceExt.includes(
|
|
1949
|
+
launchWithNode = sourceExt.includes(path20.extname(executableFile));
|
|
1950
1950
|
let proc;
|
|
1951
1951
|
if (process15.platform !== "win32") {
|
|
1952
1952
|
if (launchWithNode) {
|
|
@@ -2786,7 +2786,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2786
2786
|
* @return {Command}
|
|
2787
2787
|
*/
|
|
2788
2788
|
nameFromFilename(filename) {
|
|
2789
|
-
this._name =
|
|
2789
|
+
this._name = path20.basename(filename, path20.extname(filename));
|
|
2790
2790
|
return this;
|
|
2791
2791
|
}
|
|
2792
2792
|
/**
|
|
@@ -2800,9 +2800,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2800
2800
|
* @param {string} [path]
|
|
2801
2801
|
* @return {(string|null|Command)}
|
|
2802
2802
|
*/
|
|
2803
|
-
executableDir(
|
|
2804
|
-
if (
|
|
2805
|
-
this._executableDir =
|
|
2803
|
+
executableDir(path21) {
|
|
2804
|
+
if (path21 === void 0) return this._executableDir;
|
|
2805
|
+
this._executableDir = path21;
|
|
2806
2806
|
return this;
|
|
2807
2807
|
}
|
|
2808
2808
|
/**
|
|
@@ -3033,12 +3033,12 @@ var require_commander = __commonJS({
|
|
|
3033
3033
|
});
|
|
3034
3034
|
|
|
3035
3035
|
// node_modules/dot-prop/index.js
|
|
3036
|
-
function getPathSegments(
|
|
3036
|
+
function getPathSegments(path20) {
|
|
3037
3037
|
const parts = [];
|
|
3038
3038
|
let currentSegment = "";
|
|
3039
3039
|
let currentPart = "start";
|
|
3040
3040
|
let isIgnoring = false;
|
|
3041
|
-
for (const character of
|
|
3041
|
+
for (const character of path20) {
|
|
3042
3042
|
switch (character) {
|
|
3043
3043
|
case "\\": {
|
|
3044
3044
|
if (currentPart === "index") {
|
|
@@ -3160,11 +3160,11 @@ function assertNotStringIndex(object, key) {
|
|
|
3160
3160
|
throw new Error("Cannot use string index");
|
|
3161
3161
|
}
|
|
3162
3162
|
}
|
|
3163
|
-
function getProperty(object,
|
|
3164
|
-
if (!isObject(object) || typeof
|
|
3163
|
+
function getProperty(object, path20, value) {
|
|
3164
|
+
if (!isObject(object) || typeof path20 !== "string") {
|
|
3165
3165
|
return value === void 0 ? object : value;
|
|
3166
3166
|
}
|
|
3167
|
-
const pathArray = getPathSegments(
|
|
3167
|
+
const pathArray = getPathSegments(path20);
|
|
3168
3168
|
if (pathArray.length === 0) {
|
|
3169
3169
|
return value;
|
|
3170
3170
|
}
|
|
@@ -3184,12 +3184,12 @@ function getProperty(object, path17, value) {
|
|
|
3184
3184
|
}
|
|
3185
3185
|
return object === void 0 ? value : object;
|
|
3186
3186
|
}
|
|
3187
|
-
function setProperty(object,
|
|
3188
|
-
if (!isObject(object) || typeof
|
|
3187
|
+
function setProperty(object, path20, value) {
|
|
3188
|
+
if (!isObject(object) || typeof path20 !== "string") {
|
|
3189
3189
|
return object;
|
|
3190
3190
|
}
|
|
3191
3191
|
const root = object;
|
|
3192
|
-
const pathArray = getPathSegments(
|
|
3192
|
+
const pathArray = getPathSegments(path20);
|
|
3193
3193
|
for (let index = 0; index < pathArray.length; index++) {
|
|
3194
3194
|
const key = pathArray[index];
|
|
3195
3195
|
assertNotStringIndex(object, key);
|
|
@@ -3202,11 +3202,11 @@ function setProperty(object, path17, value) {
|
|
|
3202
3202
|
}
|
|
3203
3203
|
return root;
|
|
3204
3204
|
}
|
|
3205
|
-
function deleteProperty(object,
|
|
3206
|
-
if (!isObject(object) || typeof
|
|
3205
|
+
function deleteProperty(object, path20) {
|
|
3206
|
+
if (!isObject(object) || typeof path20 !== "string") {
|
|
3207
3207
|
return false;
|
|
3208
3208
|
}
|
|
3209
|
-
const pathArray = getPathSegments(
|
|
3209
|
+
const pathArray = getPathSegments(path20);
|
|
3210
3210
|
for (let index = 0; index < pathArray.length; index++) {
|
|
3211
3211
|
const key = pathArray[index];
|
|
3212
3212
|
assertNotStringIndex(object, key);
|
|
@@ -3220,11 +3220,11 @@ function deleteProperty(object, path17) {
|
|
|
3220
3220
|
}
|
|
3221
3221
|
}
|
|
3222
3222
|
}
|
|
3223
|
-
function hasProperty(object,
|
|
3224
|
-
if (!isObject(object) || typeof
|
|
3223
|
+
function hasProperty(object, path20) {
|
|
3224
|
+
if (!isObject(object) || typeof path20 !== "string") {
|
|
3225
3225
|
return false;
|
|
3226
3226
|
}
|
|
3227
|
-
const pathArray = getPathSegments(
|
|
3227
|
+
const pathArray = getPathSegments(path20);
|
|
3228
3228
|
if (pathArray.length === 0) {
|
|
3229
3229
|
return false;
|
|
3230
3230
|
}
|
|
@@ -7006,8 +7006,8 @@ var require_utils = __commonJS({
|
|
|
7006
7006
|
}
|
|
7007
7007
|
return ind;
|
|
7008
7008
|
}
|
|
7009
|
-
function removeDotSegments(
|
|
7010
|
-
let input =
|
|
7009
|
+
function removeDotSegments(path20) {
|
|
7010
|
+
let input = path20;
|
|
7011
7011
|
const output = [];
|
|
7012
7012
|
let nextSlash = -1;
|
|
7013
7013
|
let len = 0;
|
|
@@ -7206,8 +7206,8 @@ var require_schemes = __commonJS({
|
|
|
7206
7206
|
wsComponent.secure = void 0;
|
|
7207
7207
|
}
|
|
7208
7208
|
if (wsComponent.resourceName) {
|
|
7209
|
-
const [
|
|
7210
|
-
wsComponent.path =
|
|
7209
|
+
const [path20, query] = wsComponent.resourceName.split("?");
|
|
7210
|
+
wsComponent.path = path20 && path20 !== "/" ? path20 : void 0;
|
|
7211
7211
|
wsComponent.query = query;
|
|
7212
7212
|
wsComponent.resourceName = void 0;
|
|
7213
7213
|
}
|
|
@@ -11393,12 +11393,12 @@ var require_dist = __commonJS({
|
|
|
11393
11393
|
throw new Error(`Unknown format "${name}"`);
|
|
11394
11394
|
return f;
|
|
11395
11395
|
};
|
|
11396
|
-
function addFormats(ajv, list,
|
|
11396
|
+
function addFormats(ajv, list, fs21, exportName) {
|
|
11397
11397
|
var _a;
|
|
11398
11398
|
var _b;
|
|
11399
11399
|
(_a = (_b = ajv.opts.code).formats) !== null && _a !== void 0 ? _a : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
|
|
11400
11400
|
for (const f of list)
|
|
11401
|
-
ajv.addFormat(f,
|
|
11401
|
+
ajv.addFormat(f, fs21[f]);
|
|
11402
11402
|
}
|
|
11403
11403
|
module.exports = exports = formatsPlugin;
|
|
11404
11404
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -19294,15 +19294,15 @@ var require_pg_connection_string = __commonJS({
|
|
|
19294
19294
|
if (config.sslcert || config.sslkey || config.sslrootcert || config.sslmode) {
|
|
19295
19295
|
config.ssl = {};
|
|
19296
19296
|
}
|
|
19297
|
-
const
|
|
19297
|
+
const fs21 = config.sslcert || config.sslkey || config.sslrootcert ? __require("fs") : null;
|
|
19298
19298
|
if (config.sslcert) {
|
|
19299
|
-
config.ssl.cert =
|
|
19299
|
+
config.ssl.cert = fs21.readFileSync(config.sslcert).toString();
|
|
19300
19300
|
}
|
|
19301
19301
|
if (config.sslkey) {
|
|
19302
|
-
config.ssl.key =
|
|
19302
|
+
config.ssl.key = fs21.readFileSync(config.sslkey).toString();
|
|
19303
19303
|
}
|
|
19304
19304
|
if (config.sslrootcert) {
|
|
19305
|
-
config.ssl.ca =
|
|
19305
|
+
config.ssl.ca = fs21.readFileSync(config.sslrootcert).toString();
|
|
19306
19306
|
}
|
|
19307
19307
|
if (options.useLibpqCompat && config.uselibpqcompat) {
|
|
19308
19308
|
throw new Error("Both useLibpqCompat and uselibpqcompat are set. Please use only one of them.");
|
|
@@ -21067,7 +21067,7 @@ var require_split2 = __commonJS({
|
|
|
21067
21067
|
var require_helper = __commonJS({
|
|
21068
21068
|
"node_modules/pgpass/lib/helper.js"(exports, module) {
|
|
21069
21069
|
"use strict";
|
|
21070
|
-
var
|
|
21070
|
+
var path20 = __require("path");
|
|
21071
21071
|
var Stream = __require("stream").Stream;
|
|
21072
21072
|
var split = require_split2();
|
|
21073
21073
|
var util = __require("util");
|
|
@@ -21106,7 +21106,7 @@ var require_helper = __commonJS({
|
|
|
21106
21106
|
};
|
|
21107
21107
|
module.exports.getFileName = function(rawEnv) {
|
|
21108
21108
|
var env3 = rawEnv || process.env;
|
|
21109
|
-
var file = env3.PGPASSFILE || (isWin ?
|
|
21109
|
+
var file = env3.PGPASSFILE || (isWin ? path20.join(env3.APPDATA || "./", "postgresql", "pgpass.conf") : path20.join(env3.HOME || "./", ".pgpass"));
|
|
21110
21110
|
return file;
|
|
21111
21111
|
};
|
|
21112
21112
|
module.exports.usePgPass = function(stats, fname) {
|
|
@@ -21238,16 +21238,16 @@ var require_helper = __commonJS({
|
|
|
21238
21238
|
var require_lib = __commonJS({
|
|
21239
21239
|
"node_modules/pgpass/lib/index.js"(exports, module) {
|
|
21240
21240
|
"use strict";
|
|
21241
|
-
var
|
|
21242
|
-
var
|
|
21241
|
+
var path20 = __require("path");
|
|
21242
|
+
var fs21 = __require("fs");
|
|
21243
21243
|
var helper = require_helper();
|
|
21244
21244
|
module.exports = function(connInfo, cb) {
|
|
21245
21245
|
var file = helper.getFileName();
|
|
21246
|
-
|
|
21246
|
+
fs21.stat(file, function(err, stat) {
|
|
21247
21247
|
if (err || !helper.usePgPass(stat, file)) {
|
|
21248
21248
|
return cb(void 0);
|
|
21249
21249
|
}
|
|
21250
|
-
var st =
|
|
21250
|
+
var st = fs21.createReadStream(file);
|
|
21251
21251
|
helper.getPassword(connInfo, st, cb);
|
|
21252
21252
|
});
|
|
21253
21253
|
};
|
|
@@ -23989,8 +23989,8 @@ async function logoutCommand() {
|
|
|
23989
23989
|
|
|
23990
23990
|
// dist/commands/start.js
|
|
23991
23991
|
init_config();
|
|
23992
|
-
import
|
|
23993
|
-
import
|
|
23992
|
+
import path16 from "path";
|
|
23993
|
+
import fs17 from "fs";
|
|
23994
23994
|
import os10 from "os";
|
|
23995
23995
|
import { execSync as execSync2 } from "child_process";
|
|
23996
23996
|
|
|
@@ -24009,8 +24009,8 @@ init_config();
|
|
|
24009
24009
|
|
|
24010
24010
|
// dist/localServer.js
|
|
24011
24011
|
import http3 from "http";
|
|
24012
|
-
import
|
|
24013
|
-
import
|
|
24012
|
+
import fs15 from "fs";
|
|
24013
|
+
import path14 from "path";
|
|
24014
24014
|
import os7 from "os";
|
|
24015
24015
|
import { createRequire } from "module";
|
|
24016
24016
|
import { spawn as spawn4 } from "child_process";
|
|
@@ -24816,7 +24816,16 @@ var PackageInstaller = class {
|
|
|
24816
24816
|
console.log(` [Installer] Installing project dependencies...`);
|
|
24817
24817
|
const pm = this.detectPackageManager();
|
|
24818
24818
|
const args = this.buildFastInstallArgs(pm);
|
|
24819
|
-
|
|
24819
|
+
try {
|
|
24820
|
+
await this.runCommand(pm, args, 3e5);
|
|
24821
|
+
} catch (err) {
|
|
24822
|
+
if (String(err.message || err).includes("ERR_PNPM_OUTDATED_LOCKFILE") || String(err.message || err).includes("frozen-lockfile")) {
|
|
24823
|
+
console.log(` [Installer] Lockfile outdated \u2014 retrying without frozen-lockfile...`);
|
|
24824
|
+
await this.runCommand(pm, ["install", "--no-frozen-lockfile"], 3e5);
|
|
24825
|
+
} else {
|
|
24826
|
+
throw err;
|
|
24827
|
+
}
|
|
24828
|
+
}
|
|
24820
24829
|
this.writeDepsHash();
|
|
24821
24830
|
console.log(` [Installer] Dependencies installed`);
|
|
24822
24831
|
} finally {
|
|
@@ -25736,11 +25745,40 @@ var AgentSync = class {
|
|
|
25736
25745
|
}
|
|
25737
25746
|
};
|
|
25738
25747
|
|
|
25748
|
+
// dist/version.js
|
|
25749
|
+
import fs14 from "fs";
|
|
25750
|
+
import path13 from "path";
|
|
25751
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
25752
|
+
var __filename_esm = fileURLToPath2(import.meta.url);
|
|
25753
|
+
var __dirname_esm = path13.dirname(__filename_esm);
|
|
25754
|
+
var _version = null;
|
|
25755
|
+
function getPackageVersion() {
|
|
25756
|
+
if (_version)
|
|
25757
|
+
return _version;
|
|
25758
|
+
let dir = __dirname_esm;
|
|
25759
|
+
for (let i = 0; i < 5; i++) {
|
|
25760
|
+
const pkgPath = path13.join(dir, "package.json");
|
|
25761
|
+
if (fs14.existsSync(pkgPath)) {
|
|
25762
|
+
try {
|
|
25763
|
+
const pkg = JSON.parse(fs14.readFileSync(pkgPath, "utf-8"));
|
|
25764
|
+
if (pkg.name === "nstantpage-agent") {
|
|
25765
|
+
_version = pkg.version;
|
|
25766
|
+
return _version;
|
|
25767
|
+
}
|
|
25768
|
+
} catch {
|
|
25769
|
+
}
|
|
25770
|
+
}
|
|
25771
|
+
dir = path13.dirname(dir);
|
|
25772
|
+
}
|
|
25773
|
+
_version = "0.0.0";
|
|
25774
|
+
return _version;
|
|
25775
|
+
}
|
|
25776
|
+
|
|
25739
25777
|
// dist/localServer.js
|
|
25740
25778
|
var ptyModule = null;
|
|
25741
25779
|
try {
|
|
25742
|
-
const
|
|
25743
|
-
ptyModule =
|
|
25780
|
+
const _require2 = createRequire(import.meta.url);
|
|
25781
|
+
ptyModule = _require2("node-pty");
|
|
25744
25782
|
} catch {
|
|
25745
25783
|
}
|
|
25746
25784
|
var terminalSessions = /* @__PURE__ */ new Map();
|
|
@@ -26028,7 +26066,7 @@ Access-Control-Allow-Origin: *\r
|
|
|
26028
26066
|
res.end(JSON.stringify({ error: `Unknown endpoint: ${pathOnly}` }));
|
|
26029
26067
|
}
|
|
26030
26068
|
}
|
|
26031
|
-
getHandler(
|
|
26069
|
+
getHandler(path20) {
|
|
26032
26070
|
const handlers = {
|
|
26033
26071
|
"/live/sync": this.handleSync,
|
|
26034
26072
|
"/live/files": this.handleFiles,
|
|
@@ -26080,10 +26118,10 @@ Access-Control-Allow-Origin: *\r
|
|
|
26080
26118
|
"/live/save-file": this.handleSaveFile,
|
|
26081
26119
|
"/health": this.handleHealth
|
|
26082
26120
|
};
|
|
26083
|
-
if (handlers[
|
|
26084
|
-
return handlers[
|
|
26121
|
+
if (handlers[path20])
|
|
26122
|
+
return handlers[path20];
|
|
26085
26123
|
for (const [route, handler] of Object.entries(handlers)) {
|
|
26086
|
-
if (
|
|
26124
|
+
if (path20.startsWith(route + "/"))
|
|
26087
26125
|
return handler;
|
|
26088
26126
|
}
|
|
26089
26127
|
return null;
|
|
@@ -26305,7 +26343,7 @@ Access-Control-Allow-Origin: *\r
|
|
|
26305
26343
|
const label = parsed.label || `Terminal ${sessionCounter}`;
|
|
26306
26344
|
let shell = null;
|
|
26307
26345
|
let ptyProcess = null;
|
|
26308
|
-
const spawnCwd =
|
|
26346
|
+
const spawnCwd = fs15.existsSync(this.options.projectDir) ? this.options.projectDir : process.cwd();
|
|
26309
26347
|
if (ptyModule) {
|
|
26310
26348
|
try {
|
|
26311
26349
|
ptyProcess = ptyModule.spawn(shellCmd, [], {
|
|
@@ -26467,7 +26505,7 @@ Access-Control-Allow-Origin: *\r
|
|
|
26467
26505
|
connected: true,
|
|
26468
26506
|
projectId: this.options.projectId,
|
|
26469
26507
|
agent: {
|
|
26470
|
-
version:
|
|
26508
|
+
version: getPackageVersion(),
|
|
26471
26509
|
hostname: os7.hostname(),
|
|
26472
26510
|
platform: `${os7.platform()} ${os7.arch()}`
|
|
26473
26511
|
}
|
|
@@ -26729,7 +26767,7 @@ Access-Control-Allow-Origin: *\r
|
|
|
26729
26767
|
const projectDir = this.options.projectDir;
|
|
26730
26768
|
console.log(` [LocalServer] Running production build for project ${this.options.projectId}...`);
|
|
26731
26769
|
try {
|
|
26732
|
-
const hasBuildScript =
|
|
26770
|
+
const hasBuildScript = fs15.existsSync(path14.join(projectDir, "script", "build.ts"));
|
|
26733
26771
|
const buildCmd = hasBuildScript ? "npx tsx script/build.ts" : "npx vite build";
|
|
26734
26772
|
const buildResult = await new Promise((resolve) => {
|
|
26735
26773
|
const proc = spawn4("sh", ["-c", buildCmd], {
|
|
@@ -26753,32 +26791,32 @@ Access-Control-Allow-Origin: *\r
|
|
|
26753
26791
|
this.json(res, { success: false, error: errorMsg });
|
|
26754
26792
|
return;
|
|
26755
26793
|
}
|
|
26756
|
-
const distDir =
|
|
26757
|
-
if (!
|
|
26794
|
+
const distDir = path14.join(projectDir, "dist");
|
|
26795
|
+
if (!fs15.existsSync(distDir)) {
|
|
26758
26796
|
this.json(res, { success: false, error: "dist/ not found after build" });
|
|
26759
26797
|
return;
|
|
26760
26798
|
}
|
|
26761
26799
|
const files = {};
|
|
26762
26800
|
const collectFiles = (dir, prefix) => {
|
|
26763
|
-
const entries =
|
|
26801
|
+
const entries = fs15.readdirSync(dir, { withFileTypes: true });
|
|
26764
26802
|
for (const entry of entries) {
|
|
26765
|
-
const fullPath =
|
|
26803
|
+
const fullPath = path14.join(dir, entry.name);
|
|
26766
26804
|
const relPath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
26767
26805
|
if (entry.isDirectory()) {
|
|
26768
26806
|
collectFiles(fullPath, relPath);
|
|
26769
26807
|
} else {
|
|
26770
|
-
const ext =
|
|
26808
|
+
const ext = path14.extname(entry.name).toLowerCase();
|
|
26771
26809
|
const isBinary = [".png", ".jpg", ".jpeg", ".gif", ".webp", ".ico", ".woff", ".woff2", ".ttf", ".eot", ".mp3", ".mp4", ".ogg", ".wav"].includes(ext);
|
|
26772
26810
|
if (isBinary) {
|
|
26773
|
-
files[relPath] = "base64:" +
|
|
26811
|
+
files[relPath] = "base64:" + fs15.readFileSync(fullPath).toString("base64");
|
|
26774
26812
|
} else {
|
|
26775
|
-
files[relPath] =
|
|
26813
|
+
files[relPath] = fs15.readFileSync(fullPath, "utf-8");
|
|
26776
26814
|
}
|
|
26777
26815
|
}
|
|
26778
26816
|
}
|
|
26779
26817
|
};
|
|
26780
26818
|
collectFiles(distDir, "");
|
|
26781
|
-
const hasBackend =
|
|
26819
|
+
const hasBackend = fs15.existsSync(path14.join(projectDir, "server", "index.ts")) || fs15.existsSync(path14.join(projectDir, "server", "index.js"));
|
|
26782
26820
|
console.log(` [LocalServer] Build completed: ${Object.keys(files).length} files (backend=${hasBackend})`);
|
|
26783
26821
|
this.json(res, {
|
|
26784
26822
|
success: true,
|
|
@@ -27204,7 +27242,7 @@ var TunnelClient = class {
|
|
|
27204
27242
|
this.emitStatus("connected");
|
|
27205
27243
|
this.send({
|
|
27206
27244
|
type: "agent-info",
|
|
27207
|
-
version:
|
|
27245
|
+
version: getPackageVersion(),
|
|
27208
27246
|
hostname: os8.hostname(),
|
|
27209
27247
|
platform: `${os8.platform()} ${os8.arch()}`,
|
|
27210
27248
|
deviceId: getDeviceId(),
|
|
@@ -27649,11 +27687,21 @@ var TunnelClient = class {
|
|
|
27649
27687
|
|
|
27650
27688
|
// dist/statusServer.js
|
|
27651
27689
|
import http5 from "http";
|
|
27652
|
-
import
|
|
27653
|
-
import
|
|
27690
|
+
import fs16 from "fs";
|
|
27691
|
+
import path15 from "path";
|
|
27654
27692
|
import os9 from "os";
|
|
27693
|
+
import { spawn as spawn5 } from "child_process";
|
|
27694
|
+
import { createRequire as createRequire2 } from "module";
|
|
27655
27695
|
var STATUS_PORT = 18999;
|
|
27656
|
-
var STATUS_FILE =
|
|
27696
|
+
var STATUS_FILE = path15.join(os9.homedir(), ".nstantpage", "status.json");
|
|
27697
|
+
var _require = createRequire2(import.meta.url);
|
|
27698
|
+
var ptyModule2 = null;
|
|
27699
|
+
try {
|
|
27700
|
+
ptyModule2 = _require("node-pty");
|
|
27701
|
+
} catch {
|
|
27702
|
+
}
|
|
27703
|
+
var repoTerminalSessions = /* @__PURE__ */ new Map();
|
|
27704
|
+
var repoSessionCounter = 0;
|
|
27657
27705
|
var StatusServer = class {
|
|
27658
27706
|
server = null;
|
|
27659
27707
|
getStatus;
|
|
@@ -27668,8 +27716,8 @@ var StatusServer = class {
|
|
|
27668
27716
|
return new Promise((resolve, reject) => {
|
|
27669
27717
|
this.server = http5.createServer((req, res) => {
|
|
27670
27718
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
27671
|
-
res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
27672
|
-
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
27719
|
+
res.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS");
|
|
27720
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, x-project-id");
|
|
27673
27721
|
res.setHeader("Content-Type", "application/json");
|
|
27674
27722
|
if (req.method === "OPTIONS") {
|
|
27675
27723
|
res.writeHead(204);
|
|
@@ -27732,13 +27780,13 @@ var StatusServer = class {
|
|
|
27732
27780
|
const parsedUrl = new URL(req.url || "/", `http://localhost:${STATUS_PORT}`);
|
|
27733
27781
|
if (req.method === "GET" && url === "/browse/tree") {
|
|
27734
27782
|
const dir = parsedUrl.searchParams.get("dir");
|
|
27735
|
-
if (!dir || !
|
|
27783
|
+
if (!dir || !fs16.existsSync(dir)) {
|
|
27736
27784
|
res.writeHead(400);
|
|
27737
27785
|
res.end(JSON.stringify({ error: "Missing or invalid dir parameter" }));
|
|
27738
27786
|
return;
|
|
27739
27787
|
}
|
|
27740
27788
|
try {
|
|
27741
|
-
const tree = buildFileTree(dir,
|
|
27789
|
+
const tree = buildFileTree(dir, path15.basename(dir));
|
|
27742
27790
|
res.writeHead(200);
|
|
27743
27791
|
res.end(JSON.stringify(tree));
|
|
27744
27792
|
} catch (err) {
|
|
@@ -27755,19 +27803,19 @@ var StatusServer = class {
|
|
|
27755
27803
|
res.end(JSON.stringify({ error: "dir and path parameters required" }));
|
|
27756
27804
|
return;
|
|
27757
27805
|
}
|
|
27758
|
-
const fullPath =
|
|
27759
|
-
if (!fullPath.startsWith(
|
|
27806
|
+
const fullPath = path15.resolve(dir, filePath);
|
|
27807
|
+
if (!fullPath.startsWith(path15.resolve(dir))) {
|
|
27760
27808
|
res.writeHead(403);
|
|
27761
27809
|
res.end(JSON.stringify({ error: "Path traversal not allowed" }));
|
|
27762
27810
|
return;
|
|
27763
27811
|
}
|
|
27764
27812
|
try {
|
|
27765
|
-
if (!
|
|
27813
|
+
if (!fs16.existsSync(fullPath)) {
|
|
27766
27814
|
res.writeHead(404);
|
|
27767
27815
|
res.end(JSON.stringify({ error: "File not found" }));
|
|
27768
27816
|
return;
|
|
27769
27817
|
}
|
|
27770
|
-
const content =
|
|
27818
|
+
const content = fs16.readFileSync(fullPath, "utf-8");
|
|
27771
27819
|
res.writeHead(200);
|
|
27772
27820
|
res.end(JSON.stringify({ content }));
|
|
27773
27821
|
} catch (err) {
|
|
@@ -27789,16 +27837,16 @@ var StatusServer = class {
|
|
|
27789
27837
|
res.end(JSON.stringify({ error: "dir, filePath, and content required" }));
|
|
27790
27838
|
return;
|
|
27791
27839
|
}
|
|
27792
|
-
const fullPath =
|
|
27793
|
-
if (!fullPath.startsWith(
|
|
27840
|
+
const fullPath = path15.resolve(dir, filePath);
|
|
27841
|
+
if (!fullPath.startsWith(path15.resolve(dir))) {
|
|
27794
27842
|
res.writeHead(403);
|
|
27795
27843
|
res.end(JSON.stringify({ error: "Path traversal not allowed" }));
|
|
27796
27844
|
return;
|
|
27797
27845
|
}
|
|
27798
|
-
const parentDir =
|
|
27799
|
-
if (!
|
|
27800
|
-
|
|
27801
|
-
|
|
27846
|
+
const parentDir = path15.dirname(fullPath);
|
|
27847
|
+
if (!fs16.existsSync(parentDir))
|
|
27848
|
+
fs16.mkdirSync(parentDir, { recursive: true });
|
|
27849
|
+
fs16.writeFileSync(fullPath, content, "utf-8");
|
|
27802
27850
|
res.writeHead(200);
|
|
27803
27851
|
res.end(JSON.stringify({ success: true }));
|
|
27804
27852
|
} catch (err) {
|
|
@@ -27808,9 +27856,470 @@ var StatusServer = class {
|
|
|
27808
27856
|
});
|
|
27809
27857
|
return;
|
|
27810
27858
|
}
|
|
27859
|
+
if (req.method === "GET" && url === "/browse/list-files") {
|
|
27860
|
+
const dir = parsedUrl.searchParams.get("dir");
|
|
27861
|
+
if (!dir || !fs16.existsSync(dir)) {
|
|
27862
|
+
res.writeHead(400);
|
|
27863
|
+
res.end(JSON.stringify({ error: "Missing or invalid dir parameter" }));
|
|
27864
|
+
return;
|
|
27865
|
+
}
|
|
27866
|
+
try {
|
|
27867
|
+
const files = [];
|
|
27868
|
+
collectFilesRecursive(dir, dir, files);
|
|
27869
|
+
res.writeHead(200);
|
|
27870
|
+
res.end(JSON.stringify({ files }));
|
|
27871
|
+
} catch (err) {
|
|
27872
|
+
res.writeHead(500);
|
|
27873
|
+
res.end(JSON.stringify({ error: err.message }));
|
|
27874
|
+
}
|
|
27875
|
+
return;
|
|
27876
|
+
}
|
|
27877
|
+
if (req.method === "POST" && url === "/browse/search") {
|
|
27878
|
+
let body = "";
|
|
27879
|
+
req.on("data", (chunk) => {
|
|
27880
|
+
body += chunk.toString();
|
|
27881
|
+
});
|
|
27882
|
+
req.on("end", () => {
|
|
27883
|
+
try {
|
|
27884
|
+
const { dir, query, isRegex, filePattern } = JSON.parse(body);
|
|
27885
|
+
if (!dir || !query) {
|
|
27886
|
+
res.writeHead(400);
|
|
27887
|
+
res.end(JSON.stringify({ error: "dir and query required" }));
|
|
27888
|
+
return;
|
|
27889
|
+
}
|
|
27890
|
+
if (!fs16.existsSync(dir)) {
|
|
27891
|
+
res.writeHead(400);
|
|
27892
|
+
res.end(JSON.stringify({ error: "dir does not exist" }));
|
|
27893
|
+
return;
|
|
27894
|
+
}
|
|
27895
|
+
const files = [];
|
|
27896
|
+
collectFilesRecursive(dir, dir, files);
|
|
27897
|
+
const regex = isRegex ? new RegExp(query, "gi") : null;
|
|
27898
|
+
const results = [];
|
|
27899
|
+
const maxResults = 100;
|
|
27900
|
+
for (const f of files) {
|
|
27901
|
+
if (results.length >= maxResults)
|
|
27902
|
+
break;
|
|
27903
|
+
if (filePattern && !matchGlob(f.filePath, filePattern))
|
|
27904
|
+
continue;
|
|
27905
|
+
const fullPath = path15.resolve(dir, f.filePath);
|
|
27906
|
+
let content;
|
|
27907
|
+
try {
|
|
27908
|
+
content = fs16.readFileSync(fullPath, "utf-8");
|
|
27909
|
+
} catch {
|
|
27910
|
+
continue;
|
|
27911
|
+
}
|
|
27912
|
+
const lines = content.split("\n");
|
|
27913
|
+
for (let i = 0; i < lines.length && results.length < maxResults; i++) {
|
|
27914
|
+
const matched = regex ? regex.test(lines[i]) : lines[i].toLowerCase().includes(query.toLowerCase());
|
|
27915
|
+
if (regex)
|
|
27916
|
+
regex.lastIndex = 0;
|
|
27917
|
+
if (matched) {
|
|
27918
|
+
results.push({ filePath: f.filePath, line: i + 1, content: lines[i] });
|
|
27919
|
+
}
|
|
27920
|
+
}
|
|
27921
|
+
}
|
|
27922
|
+
res.writeHead(200);
|
|
27923
|
+
res.end(JSON.stringify({ results }));
|
|
27924
|
+
} catch (err) {
|
|
27925
|
+
res.writeHead(500);
|
|
27926
|
+
res.end(JSON.stringify({ error: err.message }));
|
|
27927
|
+
}
|
|
27928
|
+
});
|
|
27929
|
+
return;
|
|
27930
|
+
}
|
|
27931
|
+
if (req.method === "POST" && url === "/browse/delete") {
|
|
27932
|
+
let body = "";
|
|
27933
|
+
req.on("data", (chunk) => {
|
|
27934
|
+
body += chunk.toString();
|
|
27935
|
+
});
|
|
27936
|
+
req.on("end", () => {
|
|
27937
|
+
try {
|
|
27938
|
+
const { dir, filePath } = JSON.parse(body);
|
|
27939
|
+
if (!dir || !filePath) {
|
|
27940
|
+
res.writeHead(400);
|
|
27941
|
+
res.end(JSON.stringify({ error: "dir and filePath required" }));
|
|
27942
|
+
return;
|
|
27943
|
+
}
|
|
27944
|
+
const fullPath = path15.resolve(dir, filePath);
|
|
27945
|
+
if (!fullPath.startsWith(path15.resolve(dir))) {
|
|
27946
|
+
res.writeHead(403);
|
|
27947
|
+
res.end(JSON.stringify({ error: "Path traversal not allowed" }));
|
|
27948
|
+
return;
|
|
27949
|
+
}
|
|
27950
|
+
if (!fs16.existsSync(fullPath)) {
|
|
27951
|
+
res.writeHead(404);
|
|
27952
|
+
res.end(JSON.stringify({ error: "File not found" }));
|
|
27953
|
+
return;
|
|
27954
|
+
}
|
|
27955
|
+
fs16.unlinkSync(fullPath);
|
|
27956
|
+
res.writeHead(200);
|
|
27957
|
+
res.end(JSON.stringify({ success: true }));
|
|
27958
|
+
} catch (err) {
|
|
27959
|
+
res.writeHead(500);
|
|
27960
|
+
res.end(JSON.stringify({ error: err.message }));
|
|
27961
|
+
}
|
|
27962
|
+
});
|
|
27963
|
+
return;
|
|
27964
|
+
}
|
|
27965
|
+
if (url === "/live/container-status") {
|
|
27966
|
+
res.writeHead(200);
|
|
27967
|
+
res.end(JSON.stringify({ status: "idle", projectId: parsedUrl.searchParams.get("projectId") || "repo" }));
|
|
27968
|
+
return;
|
|
27969
|
+
}
|
|
27970
|
+
if (req.method === "POST" && url === "/live/terminal") {
|
|
27971
|
+
let body = "";
|
|
27972
|
+
req.on("data", (chunk) => {
|
|
27973
|
+
body += chunk.toString();
|
|
27974
|
+
});
|
|
27975
|
+
req.on("end", () => {
|
|
27976
|
+
try {
|
|
27977
|
+
const parsed = body ? JSON.parse(body) : {};
|
|
27978
|
+
const command = parsed.command || "";
|
|
27979
|
+
const cwd = parsed.cwd || os9.homedir();
|
|
27980
|
+
const timeoutSeconds = Math.min(parsed.timeoutSeconds || 120, 600);
|
|
27981
|
+
const projectId = parsed.projectId || "repo";
|
|
27982
|
+
if (!command) {
|
|
27983
|
+
res.writeHead(400);
|
|
27984
|
+
res.end(JSON.stringify({ success: false, error: "command is required" }));
|
|
27985
|
+
return;
|
|
27986
|
+
}
|
|
27987
|
+
const spawnCwd = fs16.existsSync(cwd) ? cwd : os9.homedir();
|
|
27988
|
+
const shellCmd = process.platform === "win32" ? "cmd.exe" : process.env.SHELL || "/bin/bash";
|
|
27989
|
+
const shellEnv = { ...process.env, TERM: "xterm-256color", COLORTERM: "truecolor", FORCE_COLOR: "3" };
|
|
27990
|
+
const aiSession = Array.from(repoTerminalSessions.values()).find((s) => s.projectId === projectId && s.isAiSession && !s.exited);
|
|
27991
|
+
let stdout = "";
|
|
27992
|
+
let stderr = "";
|
|
27993
|
+
let finished = false;
|
|
27994
|
+
const child = spawn5(shellCmd, ["-c", command], {
|
|
27995
|
+
cwd: spawnCwd,
|
|
27996
|
+
env: shellEnv,
|
|
27997
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
27998
|
+
});
|
|
27999
|
+
child.stdout?.on("data", (d) => {
|
|
28000
|
+
const str = d.toString();
|
|
28001
|
+
stdout += str;
|
|
28002
|
+
if (aiSession) {
|
|
28003
|
+
for (const listener of aiSession.dataListeners) {
|
|
28004
|
+
try {
|
|
28005
|
+
listener(`\x1B[90m$ ${command}\x1B[0m
|
|
28006
|
+
`);
|
|
28007
|
+
} catch {
|
|
28008
|
+
}
|
|
28009
|
+
}
|
|
28010
|
+
for (const listener of aiSession.dataListeners) {
|
|
28011
|
+
try {
|
|
28012
|
+
listener(str);
|
|
28013
|
+
} catch {
|
|
28014
|
+
}
|
|
28015
|
+
}
|
|
28016
|
+
}
|
|
28017
|
+
});
|
|
28018
|
+
child.stderr?.on("data", (d) => {
|
|
28019
|
+
const str = d.toString();
|
|
28020
|
+
stderr += str;
|
|
28021
|
+
if (aiSession) {
|
|
28022
|
+
for (const listener of aiSession.dataListeners) {
|
|
28023
|
+
try {
|
|
28024
|
+
listener(str);
|
|
28025
|
+
} catch {
|
|
28026
|
+
}
|
|
28027
|
+
}
|
|
28028
|
+
}
|
|
28029
|
+
});
|
|
28030
|
+
const timeout = setTimeout(() => {
|
|
28031
|
+
if (!finished) {
|
|
28032
|
+
finished = true;
|
|
28033
|
+
try {
|
|
28034
|
+
child.kill("SIGKILL");
|
|
28035
|
+
} catch {
|
|
28036
|
+
}
|
|
28037
|
+
res.writeHead(200);
|
|
28038
|
+
res.end(JSON.stringify({
|
|
28039
|
+
success: false,
|
|
28040
|
+
exitCode: 124,
|
|
28041
|
+
stdout: stdout.slice(-5e4),
|
|
28042
|
+
stderr: stderr.slice(-5e4),
|
|
28043
|
+
error: `Timeout after ${timeoutSeconds}s`
|
|
28044
|
+
}));
|
|
28045
|
+
}
|
|
28046
|
+
}, timeoutSeconds * 1e3);
|
|
28047
|
+
child.on("exit", (code) => {
|
|
28048
|
+
if (finished)
|
|
28049
|
+
return;
|
|
28050
|
+
finished = true;
|
|
28051
|
+
clearTimeout(timeout);
|
|
28052
|
+
res.writeHead(200);
|
|
28053
|
+
res.end(JSON.stringify({
|
|
28054
|
+
success: code === 0,
|
|
28055
|
+
exitCode: code ?? -1,
|
|
28056
|
+
stdout: stdout.slice(-5e4),
|
|
28057
|
+
stderr: stderr.slice(-5e4),
|
|
28058
|
+
error: null
|
|
28059
|
+
}));
|
|
28060
|
+
});
|
|
28061
|
+
child.on("error", (err) => {
|
|
28062
|
+
if (finished)
|
|
28063
|
+
return;
|
|
28064
|
+
finished = true;
|
|
28065
|
+
clearTimeout(timeout);
|
|
28066
|
+
res.writeHead(200);
|
|
28067
|
+
res.end(JSON.stringify({
|
|
28068
|
+
success: false,
|
|
28069
|
+
exitCode: -1,
|
|
28070
|
+
stdout: "",
|
|
28071
|
+
stderr: "",
|
|
28072
|
+
error: err.message
|
|
28073
|
+
}));
|
|
28074
|
+
});
|
|
28075
|
+
} catch (err) {
|
|
28076
|
+
res.writeHead(500);
|
|
28077
|
+
res.end(JSON.stringify({ error: err.message }));
|
|
28078
|
+
}
|
|
28079
|
+
});
|
|
28080
|
+
return;
|
|
28081
|
+
}
|
|
28082
|
+
if (url === "/live/terminal/sessions") {
|
|
28083
|
+
if (req.method === "GET") {
|
|
28084
|
+
const pid = parsedUrl.searchParams.get("projectId") || "repo";
|
|
28085
|
+
const sessions = Array.from(repoTerminalSessions.values()).filter((s) => s.projectId === pid).map((s) => ({
|
|
28086
|
+
id: s.id,
|
|
28087
|
+
projectId: s.projectId,
|
|
28088
|
+
isAiSession: s.isAiSession,
|
|
28089
|
+
label: s.label,
|
|
28090
|
+
createdAt: s.createdAt,
|
|
28091
|
+
lastActivity: s.lastActivity,
|
|
28092
|
+
exited: s.exited,
|
|
28093
|
+
exitCode: s.exitCode,
|
|
28094
|
+
cols: s.cols,
|
|
28095
|
+
rows: s.rows
|
|
28096
|
+
}));
|
|
28097
|
+
res.writeHead(200);
|
|
28098
|
+
res.end(JSON.stringify({ success: true, sessions }));
|
|
28099
|
+
return;
|
|
28100
|
+
}
|
|
28101
|
+
if (req.method === "POST") {
|
|
28102
|
+
let body = "";
|
|
28103
|
+
req.on("data", (chunk) => {
|
|
28104
|
+
body += chunk.toString();
|
|
28105
|
+
});
|
|
28106
|
+
req.on("end", () => {
|
|
28107
|
+
try {
|
|
28108
|
+
const parsed = body ? JSON.parse(body) : {};
|
|
28109
|
+
const projectId = parsed.projectId || "repo";
|
|
28110
|
+
const cwd = parsed.cwd || os9.homedir();
|
|
28111
|
+
const cols = parsed.cols || 120;
|
|
28112
|
+
const rows = parsed.rows || 30;
|
|
28113
|
+
repoSessionCounter++;
|
|
28114
|
+
const sessionId = `repo-${Date.now()}-${repoSessionCounter}`;
|
|
28115
|
+
const label = parsed.label || `Terminal ${repoSessionCounter}`;
|
|
28116
|
+
const shellCmd = process.platform === "win32" ? "cmd.exe" : process.env.SHELL || "/bin/bash";
|
|
28117
|
+
const shellEnv = { ...process.env, TERM: "xterm-256color", COLORTERM: "truecolor", FORCE_COLOR: "3", COLUMNS: String(cols), LINES: String(rows) };
|
|
28118
|
+
const spawnCwd = fs16.existsSync(cwd) ? cwd : os9.homedir();
|
|
28119
|
+
let shell = null;
|
|
28120
|
+
let ptyProcess = null;
|
|
28121
|
+
if (ptyModule2) {
|
|
28122
|
+
try {
|
|
28123
|
+
ptyProcess = ptyModule2.spawn(shellCmd, [], { name: "xterm-256color", cols, rows, cwd: spawnCwd, env: shellEnv });
|
|
28124
|
+
} catch {
|
|
28125
|
+
ptyProcess = null;
|
|
28126
|
+
}
|
|
28127
|
+
}
|
|
28128
|
+
if (!ptyProcess) {
|
|
28129
|
+
try {
|
|
28130
|
+
shell = spawn5(shellCmd, ["-i"], { cwd: spawnCwd, env: shellEnv, stdio: ["pipe", "pipe", "pipe"] });
|
|
28131
|
+
} catch {
|
|
28132
|
+
shell = spawn5(shellCmd, [], { cwd: spawnCwd, env: shellEnv, stdio: ["pipe", "pipe", "pipe"] });
|
|
28133
|
+
}
|
|
28134
|
+
}
|
|
28135
|
+
const session = {
|
|
28136
|
+
id: sessionId,
|
|
28137
|
+
projectId,
|
|
28138
|
+
cwd: spawnCwd,
|
|
28139
|
+
shell,
|
|
28140
|
+
ptyProcess,
|
|
28141
|
+
outputBuffer: [],
|
|
28142
|
+
createdAt: Date.now(),
|
|
28143
|
+
lastActivity: Date.now(),
|
|
28144
|
+
cols,
|
|
28145
|
+
rows,
|
|
28146
|
+
isAiSession: parsed.isAiSession || false,
|
|
28147
|
+
label,
|
|
28148
|
+
exited: false,
|
|
28149
|
+
exitCode: null,
|
|
28150
|
+
dataListeners: /* @__PURE__ */ new Set(),
|
|
28151
|
+
exitListeners: /* @__PURE__ */ new Set()
|
|
28152
|
+
};
|
|
28153
|
+
const pushOutput = (str) => {
|
|
28154
|
+
session.outputBuffer.push(str);
|
|
28155
|
+
session.lastActivity = Date.now();
|
|
28156
|
+
while (session.outputBuffer.length > 500)
|
|
28157
|
+
session.outputBuffer.shift();
|
|
28158
|
+
for (const listener of session.dataListeners) {
|
|
28159
|
+
try {
|
|
28160
|
+
listener(str);
|
|
28161
|
+
} catch {
|
|
28162
|
+
}
|
|
28163
|
+
}
|
|
28164
|
+
};
|
|
28165
|
+
const handleExit = (code) => {
|
|
28166
|
+
session.exited = true;
|
|
28167
|
+
session.exitCode = code;
|
|
28168
|
+
for (const listener of session.exitListeners) {
|
|
28169
|
+
try {
|
|
28170
|
+
listener(code);
|
|
28171
|
+
} catch {
|
|
28172
|
+
}
|
|
28173
|
+
}
|
|
28174
|
+
};
|
|
28175
|
+
if (ptyProcess) {
|
|
28176
|
+
ptyProcess.onData((data) => pushOutput(data));
|
|
28177
|
+
ptyProcess.onExit(({ exitCode }) => handleExit(exitCode));
|
|
28178
|
+
} else if (shell) {
|
|
28179
|
+
shell.stdout?.on("data", (d) => pushOutput(d.toString()));
|
|
28180
|
+
shell.stderr?.on("data", (d) => pushOutput(d.toString()));
|
|
28181
|
+
shell.on("exit", (code) => handleExit(code));
|
|
28182
|
+
}
|
|
28183
|
+
repoTerminalSessions.set(sessionId, session);
|
|
28184
|
+
res.writeHead(200);
|
|
28185
|
+
res.end(JSON.stringify({
|
|
28186
|
+
success: true,
|
|
28187
|
+
session: { id: sessionId, projectId, isAiSession: session.isAiSession, label, createdAt: session.createdAt, lastActivity: session.lastActivity, exited: false, exitCode: null, cols, rows }
|
|
28188
|
+
}));
|
|
28189
|
+
} catch (err) {
|
|
28190
|
+
res.writeHead(500);
|
|
28191
|
+
res.end(JSON.stringify({ error: err.message }));
|
|
28192
|
+
}
|
|
28193
|
+
});
|
|
28194
|
+
return;
|
|
28195
|
+
}
|
|
28196
|
+
}
|
|
28197
|
+
if (req.method === "DELETE" && url?.startsWith("/live/terminal/sessions/")) {
|
|
28198
|
+
const sessionId = url.split("/").pop();
|
|
28199
|
+
const session = repoTerminalSessions.get(sessionId);
|
|
28200
|
+
if (session) {
|
|
28201
|
+
if (session.ptyProcess) {
|
|
28202
|
+
try {
|
|
28203
|
+
session.ptyProcess.kill();
|
|
28204
|
+
} catch {
|
|
28205
|
+
}
|
|
28206
|
+
}
|
|
28207
|
+
if (session.shell) {
|
|
28208
|
+
try {
|
|
28209
|
+
session.shell.kill();
|
|
28210
|
+
} catch {
|
|
28211
|
+
}
|
|
28212
|
+
}
|
|
28213
|
+
repoTerminalSessions.delete(sessionId);
|
|
28214
|
+
}
|
|
28215
|
+
res.writeHead(200);
|
|
28216
|
+
res.end(JSON.stringify({ success: true }));
|
|
28217
|
+
return;
|
|
28218
|
+
}
|
|
28219
|
+
if (req.method === "POST" && url === "/live/terminal/destroy") {
|
|
28220
|
+
let body = "";
|
|
28221
|
+
req.on("data", (chunk) => {
|
|
28222
|
+
body += chunk.toString();
|
|
28223
|
+
});
|
|
28224
|
+
req.on("end", () => {
|
|
28225
|
+
try {
|
|
28226
|
+
const { sessionId } = JSON.parse(body);
|
|
28227
|
+
const session = repoTerminalSessions.get(sessionId);
|
|
28228
|
+
if (session) {
|
|
28229
|
+
if (session.ptyProcess) {
|
|
28230
|
+
try {
|
|
28231
|
+
session.ptyProcess.kill();
|
|
28232
|
+
} catch {
|
|
28233
|
+
}
|
|
28234
|
+
}
|
|
28235
|
+
if (session.shell) {
|
|
28236
|
+
try {
|
|
28237
|
+
session.shell.kill();
|
|
28238
|
+
} catch {
|
|
28239
|
+
}
|
|
28240
|
+
}
|
|
28241
|
+
repoTerminalSessions.delete(sessionId);
|
|
28242
|
+
}
|
|
28243
|
+
res.writeHead(200);
|
|
28244
|
+
res.end(JSON.stringify({ success: true }));
|
|
28245
|
+
} catch (err) {
|
|
28246
|
+
res.writeHead(500);
|
|
28247
|
+
res.end(JSON.stringify({ error: err.message }));
|
|
28248
|
+
}
|
|
28249
|
+
});
|
|
28250
|
+
return;
|
|
28251
|
+
}
|
|
28252
|
+
if (req.headers.upgrade && req.headers.upgrade.toLowerCase() === "websocket") {
|
|
28253
|
+
return;
|
|
28254
|
+
}
|
|
27811
28255
|
res.writeHead(404);
|
|
27812
28256
|
res.end(JSON.stringify({ error: "Not found" }));
|
|
27813
28257
|
});
|
|
28258
|
+
const wss = new import_websocket_server.default({ noServer: true });
|
|
28259
|
+
this.server.on("upgrade", (req, socket, head) => {
|
|
28260
|
+
const urlMatch = req.url?.match(/^\/live\/terminal\/ws\/([^/]+)\/([^/?]+)/);
|
|
28261
|
+
if (!urlMatch) {
|
|
28262
|
+
socket.destroy();
|
|
28263
|
+
return;
|
|
28264
|
+
}
|
|
28265
|
+
const sessionId = urlMatch[2];
|
|
28266
|
+
const session = repoTerminalSessions.get(sessionId);
|
|
28267
|
+
if (!session) {
|
|
28268
|
+
socket.destroy();
|
|
28269
|
+
return;
|
|
28270
|
+
}
|
|
28271
|
+
wss.handleUpgrade(req, socket, head, (ws) => {
|
|
28272
|
+
if (session.outputBuffer.length > 0) {
|
|
28273
|
+
ws.send(JSON.stringify({ type: "scrollback", data: session.outputBuffer.join("") }));
|
|
28274
|
+
}
|
|
28275
|
+
ws.send(JSON.stringify({ type: "connected", sessionId: session.id, projectId: session.projectId }));
|
|
28276
|
+
const dataListener = (data) => {
|
|
28277
|
+
try {
|
|
28278
|
+
if (ws.readyState === import_websocket.default.OPEN)
|
|
28279
|
+
ws.send(JSON.stringify({ type: "output", data }));
|
|
28280
|
+
} catch {
|
|
28281
|
+
}
|
|
28282
|
+
};
|
|
28283
|
+
const exitListener = (code) => {
|
|
28284
|
+
try {
|
|
28285
|
+
if (ws.readyState === import_websocket.default.OPEN)
|
|
28286
|
+
ws.send(JSON.stringify({ type: "exit", exitCode: code }));
|
|
28287
|
+
} catch {
|
|
28288
|
+
}
|
|
28289
|
+
};
|
|
28290
|
+
session.dataListeners.add(dataListener);
|
|
28291
|
+
session.exitListeners.add(exitListener);
|
|
28292
|
+
ws.on("message", (raw) => {
|
|
28293
|
+
try {
|
|
28294
|
+
const msg = JSON.parse(typeof raw === "string" ? raw : raw.toString());
|
|
28295
|
+
if (msg.type === "input" && msg.data) {
|
|
28296
|
+
if (session.ptyProcess)
|
|
28297
|
+
session.ptyProcess.write(msg.data);
|
|
28298
|
+
else if (session.shell?.stdin)
|
|
28299
|
+
session.shell.stdin.write(msg.data);
|
|
28300
|
+
} else if (msg.type === "resize" && msg.cols && msg.rows) {
|
|
28301
|
+
session.cols = msg.cols;
|
|
28302
|
+
session.rows = msg.rows;
|
|
28303
|
+
if (session.ptyProcess) {
|
|
28304
|
+
try {
|
|
28305
|
+
session.ptyProcess.resize(msg.cols, msg.rows);
|
|
28306
|
+
} catch {
|
|
28307
|
+
}
|
|
28308
|
+
}
|
|
28309
|
+
}
|
|
28310
|
+
} catch {
|
|
28311
|
+
}
|
|
28312
|
+
});
|
|
28313
|
+
ws.on("close", () => {
|
|
28314
|
+
session.dataListeners.delete(dataListener);
|
|
28315
|
+
session.exitListeners.delete(exitListener);
|
|
28316
|
+
});
|
|
28317
|
+
ws.on("error", () => {
|
|
28318
|
+
session.dataListeners.delete(dataListener);
|
|
28319
|
+
session.exitListeners.delete(exitListener);
|
|
28320
|
+
});
|
|
28321
|
+
});
|
|
28322
|
+
});
|
|
27814
28323
|
this.server.on("error", (err) => {
|
|
27815
28324
|
if (err.code === "EADDRINUSE") {
|
|
27816
28325
|
console.log(` [Status] Port ${STATUS_PORT} in use \u2014 status server skipped`);
|
|
@@ -27819,7 +28328,7 @@ var StatusServer = class {
|
|
|
27819
28328
|
}
|
|
27820
28329
|
reject(err);
|
|
27821
28330
|
});
|
|
27822
|
-
this.server.listen(STATUS_PORT,
|
|
28331
|
+
this.server.listen(STATUS_PORT, () => {
|
|
27823
28332
|
this.writeStatusFile();
|
|
27824
28333
|
resolve();
|
|
27825
28334
|
});
|
|
@@ -27831,16 +28340,16 @@ var StatusServer = class {
|
|
|
27831
28340
|
this.server = null;
|
|
27832
28341
|
}
|
|
27833
28342
|
try {
|
|
27834
|
-
if (
|
|
27835
|
-
|
|
28343
|
+
if (fs16.existsSync(STATUS_FILE))
|
|
28344
|
+
fs16.unlinkSync(STATUS_FILE);
|
|
27836
28345
|
} catch {
|
|
27837
28346
|
}
|
|
27838
28347
|
}
|
|
27839
28348
|
writeStatusFile() {
|
|
27840
|
-
const dir =
|
|
27841
|
-
if (!
|
|
27842
|
-
|
|
27843
|
-
|
|
28349
|
+
const dir = path15.dirname(STATUS_FILE);
|
|
28350
|
+
if (!fs16.existsSync(dir))
|
|
28351
|
+
fs16.mkdirSync(dir, { recursive: true });
|
|
28352
|
+
fs16.writeFileSync(STATUS_FILE, JSON.stringify({
|
|
27844
28353
|
port: STATUS_PORT,
|
|
27845
28354
|
pid: process.pid,
|
|
27846
28355
|
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -27863,7 +28372,7 @@ function buildFileTree(dirPath, name, relativePath = "") {
|
|
|
27863
28372
|
const node = { name, path: relativePath, isDirectory: true, children: [] };
|
|
27864
28373
|
let entries;
|
|
27865
28374
|
try {
|
|
27866
|
-
entries =
|
|
28375
|
+
entries = fs16.readdirSync(dirPath, { withFileTypes: true });
|
|
27867
28376
|
} catch {
|
|
27868
28377
|
return node;
|
|
27869
28378
|
}
|
|
@@ -27876,7 +28385,7 @@ function buildFileTree(dirPath, name, relativePath = "") {
|
|
|
27876
28385
|
if (entry.isDirectory()) {
|
|
27877
28386
|
if (SKIP_DIRS2.has(entry.name))
|
|
27878
28387
|
continue;
|
|
27879
|
-
dirs.push(buildFileTree(
|
|
28388
|
+
dirs.push(buildFileTree(path15.join(dirPath, entry.name), entry.name, childRelative));
|
|
27880
28389
|
} else {
|
|
27881
28390
|
files.push({ name: entry.name, path: childRelative, isDirectory: false, children: [] });
|
|
27882
28391
|
}
|
|
@@ -27886,9 +28395,79 @@ function buildFileTree(dirPath, name, relativePath = "") {
|
|
|
27886
28395
|
node.children = [...dirs, ...files];
|
|
27887
28396
|
return node;
|
|
27888
28397
|
}
|
|
28398
|
+
var BINARY_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
28399
|
+
".png",
|
|
28400
|
+
".jpg",
|
|
28401
|
+
".jpeg",
|
|
28402
|
+
".gif",
|
|
28403
|
+
".webp",
|
|
28404
|
+
".ico",
|
|
28405
|
+
".svg",
|
|
28406
|
+
".bmp",
|
|
28407
|
+
".woff",
|
|
28408
|
+
".woff2",
|
|
28409
|
+
".ttf",
|
|
28410
|
+
".eot",
|
|
28411
|
+
".otf",
|
|
28412
|
+
".zip",
|
|
28413
|
+
".tar",
|
|
28414
|
+
".gz",
|
|
28415
|
+
".rar",
|
|
28416
|
+
".7z",
|
|
28417
|
+
".pdf",
|
|
28418
|
+
".doc",
|
|
28419
|
+
".docx",
|
|
28420
|
+
".xls",
|
|
28421
|
+
".xlsx",
|
|
28422
|
+
".mp3",
|
|
28423
|
+
".mp4",
|
|
28424
|
+
".wav",
|
|
28425
|
+
".avi",
|
|
28426
|
+
".mov",
|
|
28427
|
+
".exe",
|
|
28428
|
+
".dll",
|
|
28429
|
+
".so",
|
|
28430
|
+
".dylib",
|
|
28431
|
+
".o"
|
|
28432
|
+
]);
|
|
28433
|
+
function collectFilesRecursive(baseDir, currentDir, out) {
|
|
28434
|
+
let entries;
|
|
28435
|
+
try {
|
|
28436
|
+
entries = fs16.readdirSync(currentDir, { withFileTypes: true });
|
|
28437
|
+
} catch {
|
|
28438
|
+
return;
|
|
28439
|
+
}
|
|
28440
|
+
for (const entry of entries) {
|
|
28441
|
+
if (entry.name.startsWith(".") && entry.name !== ".env")
|
|
28442
|
+
continue;
|
|
28443
|
+
const fullPath = path15.join(currentDir, entry.name);
|
|
28444
|
+
const relativePath = path15.relative(baseDir, fullPath);
|
|
28445
|
+
if (entry.isDirectory()) {
|
|
28446
|
+
if (SKIP_DIRS2.has(entry.name))
|
|
28447
|
+
continue;
|
|
28448
|
+
collectFilesRecursive(baseDir, fullPath, out);
|
|
28449
|
+
} else {
|
|
28450
|
+
const ext = path15.extname(entry.name).toLowerCase();
|
|
28451
|
+
if (BINARY_EXTENSIONS.has(ext)) {
|
|
28452
|
+
out.push({ filePath: relativePath, totalLines: 0 });
|
|
28453
|
+
} else {
|
|
28454
|
+
try {
|
|
28455
|
+
const content = fs16.readFileSync(fullPath, "utf-8");
|
|
28456
|
+
out.push({ filePath: relativePath, totalLines: content.split("\n").length });
|
|
28457
|
+
} catch {
|
|
28458
|
+
out.push({ filePath: relativePath, totalLines: 0 });
|
|
28459
|
+
}
|
|
28460
|
+
}
|
|
28461
|
+
}
|
|
28462
|
+
}
|
|
28463
|
+
}
|
|
28464
|
+
function matchGlob(filePath, pattern) {
|
|
28465
|
+
const regexPattern = "^" + pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, "<<<GLOBSTAR>>>").replace(/\*/g, "[^/]*").replace(/<<<GLOBSTAR>>>/g, ".*").replace(/\?/g, ".") + "$";
|
|
28466
|
+
return new RegExp(regexPattern, "i").test(filePath);
|
|
28467
|
+
}
|
|
27889
28468
|
|
|
27890
28469
|
// dist/commands/start.js
|
|
27891
|
-
var VERSION =
|
|
28470
|
+
var VERSION = getPackageVersion();
|
|
27892
28471
|
function resolveBackendUrl(options) {
|
|
27893
28472
|
if (options.backend)
|
|
27894
28473
|
return options.backend.replace(/\/$/, "");
|
|
@@ -27897,10 +28476,10 @@ function resolveBackendUrl(options) {
|
|
|
27897
28476
|
}
|
|
27898
28477
|
function resolveProjectDir(directory, projectId, customDir) {
|
|
27899
28478
|
if (customDir)
|
|
27900
|
-
return
|
|
28479
|
+
return path16.resolve(customDir);
|
|
27901
28480
|
if (directory !== ".")
|
|
27902
|
-
return
|
|
27903
|
-
const defaultBase =
|
|
28481
|
+
return path16.resolve(directory);
|
|
28482
|
+
const defaultBase = path16.join(os10.homedir(), ".nstantpage", "projects", projectId);
|
|
27904
28483
|
return defaultBase;
|
|
27905
28484
|
}
|
|
27906
28485
|
async function fetchProjectFiles(backendUrl, projectId, projectDir, token) {
|
|
@@ -27920,20 +28499,20 @@ async function fetchProjectFiles(backendUrl, projectId, projectDir, token) {
|
|
|
27920
28499
|
if (!data.files || data.files.length === 0) {
|
|
27921
28500
|
throw new Error("No files returned from backend. Is the project ID correct?");
|
|
27922
28501
|
}
|
|
27923
|
-
const versionFile =
|
|
27924
|
-
const existingVersion =
|
|
28502
|
+
const versionFile = path16.join(projectDir, ".nstantpage-version");
|
|
28503
|
+
const existingVersion = fs17.existsSync(versionFile) ? fs17.readFileSync(versionFile, "utf-8").trim() : null;
|
|
27925
28504
|
if (existingVersion === String(data.versionId)) {
|
|
27926
28505
|
console.log(source_default.gray(` Files up-to-date (version ${data.version})`));
|
|
27927
28506
|
return { fileCount: data.files.length, isNew: false, versionId: String(data.versionId) };
|
|
27928
28507
|
}
|
|
27929
28508
|
const dirsToCreate = /* @__PURE__ */ new Set();
|
|
27930
28509
|
for (const file of data.files) {
|
|
27931
|
-
const filePath =
|
|
27932
|
-
dirsToCreate.add(
|
|
28510
|
+
const filePath = path16.join(projectDir, file.path);
|
|
28511
|
+
dirsToCreate.add(path16.dirname(filePath));
|
|
27933
28512
|
}
|
|
27934
28513
|
for (const dir of dirsToCreate) {
|
|
27935
|
-
if (!
|
|
27936
|
-
|
|
28514
|
+
if (!fs17.existsSync(dir)) {
|
|
28515
|
+
fs17.mkdirSync(dir, { recursive: true });
|
|
27937
28516
|
}
|
|
27938
28517
|
}
|
|
27939
28518
|
const BATCH_SIZE = 50;
|
|
@@ -27941,12 +28520,12 @@ async function fetchProjectFiles(backendUrl, projectId, projectDir, token) {
|
|
|
27941
28520
|
for (let i = 0; i < data.files.length; i += BATCH_SIZE) {
|
|
27942
28521
|
const batch = data.files.slice(i, i + BATCH_SIZE);
|
|
27943
28522
|
await Promise.all(batch.map(async (file) => {
|
|
27944
|
-
const filePath =
|
|
27945
|
-
await
|
|
28523
|
+
const filePath = path16.join(projectDir, file.path);
|
|
28524
|
+
await fs17.promises.writeFile(filePath, file.content, "utf-8");
|
|
27946
28525
|
}));
|
|
27947
28526
|
written += batch.length;
|
|
27948
28527
|
}
|
|
27949
|
-
|
|
28528
|
+
fs17.writeFileSync(versionFile, String(data.versionId), "utf-8");
|
|
27950
28529
|
console.log(source_default.green(` \u2713 ${written} files downloaded (version ${data.version})`));
|
|
27951
28530
|
return { fileCount: written, isNew: true, versionId: String(data.versionId) };
|
|
27952
28531
|
}
|
|
@@ -28050,8 +28629,8 @@ async function startCommand(directory, options) {
|
|
|
28050
28629
|
apiPort = allocated.apiPort;
|
|
28051
28630
|
}
|
|
28052
28631
|
const projectDir = resolveProjectDir(directory, projectId, options.dir);
|
|
28053
|
-
if (!
|
|
28054
|
-
|
|
28632
|
+
if (!fs17.existsSync(projectDir)) {
|
|
28633
|
+
fs17.mkdirSync(projectDir, { recursive: true });
|
|
28055
28634
|
}
|
|
28056
28635
|
conf.set("projectId", projectId);
|
|
28057
28636
|
cleanupPreviousAgent(projectId, apiPort, devPort);
|
|
@@ -28073,7 +28652,7 @@ async function startCommand(directory, options) {
|
|
|
28073
28652
|
const { fileCount, isNew, versionId } = await fetchProjectFiles(backendUrl, projectId, projectDir, token);
|
|
28074
28653
|
fetchedVersionId = versionId;
|
|
28075
28654
|
if (!installer.areDependenciesInstalled()) {
|
|
28076
|
-
if (
|
|
28655
|
+
if (fs17.existsSync(path16.join(projectDir, "package.json"))) {
|
|
28077
28656
|
console.log(source_default.gray(" Installing dependencies..."));
|
|
28078
28657
|
try {
|
|
28079
28658
|
await installer.ensureDependencies();
|
|
@@ -28089,16 +28668,16 @@ async function startCommand(directory, options) {
|
|
|
28089
28668
|
} catch (err) {
|
|
28090
28669
|
console.log(source_default.yellow(` \u26A0 Could not fetch project files: ${err.message}`));
|
|
28091
28670
|
console.log(source_default.gray(" Continuing with existing local files (if any)..."));
|
|
28092
|
-
if (!
|
|
28671
|
+
if (!fs17.existsSync(path16.join(projectDir, "package.json"))) {
|
|
28093
28672
|
console.log(source_default.red(`
|
|
28094
28673
|
\u2717 No package.json found and cannot fetch files from backend.`));
|
|
28095
28674
|
console.log(source_default.gray(" Check your project ID and authentication."));
|
|
28096
28675
|
process.exit(1);
|
|
28097
28676
|
}
|
|
28098
28677
|
}
|
|
28099
|
-
const localConfigPath =
|
|
28100
|
-
if (!
|
|
28101
|
-
|
|
28678
|
+
const localConfigPath = path16.join(projectDir, ".nstantpage.json");
|
|
28679
|
+
if (!fs17.existsSync(localConfigPath)) {
|
|
28680
|
+
fs17.writeFileSync(localConfigPath, JSON.stringify({ projectId }, null, 2), "utf-8");
|
|
28102
28681
|
}
|
|
28103
28682
|
let databaseUrl = null;
|
|
28104
28683
|
try {
|
|
@@ -28322,9 +28901,9 @@ async function startStandbyMode(token, options, backendUrl, deviceId) {
|
|
|
28322
28901
|
await existing.localServer.stop();
|
|
28323
28902
|
activeProjects.delete(pid);
|
|
28324
28903
|
const projectDir = resolveProjectDir(".", pid);
|
|
28325
|
-
if (
|
|
28904
|
+
if (fs17.existsSync(projectDir)) {
|
|
28326
28905
|
console.log(source_default.gray(` Wiping project directory: ${projectDir}`));
|
|
28327
|
-
|
|
28906
|
+
fs17.rmSync(projectDir, { recursive: true, force: true });
|
|
28328
28907
|
}
|
|
28329
28908
|
} else if (activeProjects.has(pid)) {
|
|
28330
28909
|
console.log(source_default.yellow(` Project ${pid} is already running`));
|
|
@@ -28487,8 +29066,8 @@ async function startAdditionalProject(projectId, opts) {
|
|
|
28487
29066
|
try {
|
|
28488
29067
|
const allocated = allocatePortsForProject(projectId);
|
|
28489
29068
|
const projectDir = resolveProjectDir(".", projectId);
|
|
28490
|
-
if (!
|
|
28491
|
-
|
|
29069
|
+
if (!fs17.existsSync(projectDir))
|
|
29070
|
+
fs17.mkdirSync(projectDir, { recursive: true });
|
|
28492
29071
|
cleanupPreviousAgent(projectId, allocated.apiPort, allocated.devPort);
|
|
28493
29072
|
await new Promise((r) => setTimeout(r, 50));
|
|
28494
29073
|
progress("fetching-files", "Fetching project files...");
|
|
@@ -28561,7 +29140,7 @@ async function startAdditionalProject(projectId, opts) {
|
|
|
28561
29140
|
localServer.markSynced(fetchedVersionId);
|
|
28562
29141
|
}
|
|
28563
29142
|
const installer = new PackageInstaller({ projectDir });
|
|
28564
|
-
const needsInstall = !installer.areDependenciesInstalled() &&
|
|
29143
|
+
const needsInstall = !installer.areDependenciesInstalled() && fs17.existsSync(path16.join(projectDir, "package.json"));
|
|
28565
29144
|
if (needsInstall) {
|
|
28566
29145
|
const installStart = Date.now();
|
|
28567
29146
|
console.log(source_default.gray(` Installing dependencies...`));
|
|
@@ -28672,13 +29251,13 @@ async function statusCommand() {
|
|
|
28672
29251
|
|
|
28673
29252
|
// dist/commands/service.js
|
|
28674
29253
|
init_config();
|
|
28675
|
-
import
|
|
28676
|
-
import
|
|
29254
|
+
import fs18 from "fs";
|
|
29255
|
+
import path17 from "path";
|
|
28677
29256
|
import os11 from "os";
|
|
28678
29257
|
import { execSync as execSync3 } from "child_process";
|
|
28679
|
-
import { fileURLToPath as
|
|
28680
|
-
var
|
|
28681
|
-
var
|
|
29258
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
29259
|
+
var __filename_esm2 = fileURLToPath3(import.meta.url);
|
|
29260
|
+
var __dirname_esm2 = path17.dirname(__filename_esm2);
|
|
28682
29261
|
var PLIST_LABEL = "com.nstantpage.agent";
|
|
28683
29262
|
var SYSTEMD_SERVICE = "nstantpage-agent";
|
|
28684
29263
|
var WIN_TASK_NAME = "NstantpageAgent";
|
|
@@ -28705,8 +29284,8 @@ async function serviceStopCommand() {
|
|
|
28705
29284
|
const platform2 = os11.platform();
|
|
28706
29285
|
let stopped = false;
|
|
28707
29286
|
if (platform2 === "darwin") {
|
|
28708
|
-
const plistPath =
|
|
28709
|
-
if (
|
|
29287
|
+
const plistPath = path17.join(os11.homedir(), "Library", "LaunchAgents", `${PLIST_LABEL}.plist`);
|
|
29288
|
+
if (fs18.existsSync(plistPath)) {
|
|
28710
29289
|
try {
|
|
28711
29290
|
execSync3(`launchctl unload "${plistPath}" 2>/dev/null`, { encoding: "utf-8" });
|
|
28712
29291
|
console.log(source_default.green(" \u2713 Background service stopped"));
|
|
@@ -28767,7 +29346,7 @@ async function serviceInstallCommand(options = {}) {
|
|
|
28767
29346
|
return;
|
|
28768
29347
|
}
|
|
28769
29348
|
if (electronAppPath === null) {
|
|
28770
|
-
console.log(source_default.gray(
|
|
29349
|
+
console.log(source_default.gray(' Tip: Run "nstantpage update --desktop" to download the desktop app with tray icon.'));
|
|
28771
29350
|
}
|
|
28772
29351
|
if (platform2 === "darwin") {
|
|
28773
29352
|
await installLaunchd(gateway, token);
|
|
@@ -28834,12 +29413,12 @@ async function serviceStatusCommand() {
|
|
|
28834
29413
|
} else {
|
|
28835
29414
|
console.log(source_default.gray(" Service status not available on this platform"));
|
|
28836
29415
|
}
|
|
28837
|
-
const logPath =
|
|
28838
|
-
if (
|
|
28839
|
-
const stats =
|
|
29416
|
+
const logPath = path17.join(os11.homedir(), ".nstantpage", "agent.log");
|
|
29417
|
+
if (fs18.existsSync(logPath)) {
|
|
29418
|
+
const stats = fs18.statSync(logPath);
|
|
28840
29419
|
console.log(source_default.gray(` Log file: ${logPath} (${(stats.size / 1024).toFixed(1)}KB)`));
|
|
28841
29420
|
try {
|
|
28842
|
-
const content =
|
|
29421
|
+
const content = fs18.readFileSync(logPath, "utf-8");
|
|
28843
29422
|
const lines = content.trim().split("\n").slice(-5);
|
|
28844
29423
|
if (lines.length > 0) {
|
|
28845
29424
|
console.log(source_default.gray(" Last log lines:"));
|
|
@@ -28853,35 +29432,39 @@ function findElectronApp() {
|
|
|
28853
29432
|
const platform2 = os11.platform();
|
|
28854
29433
|
if (platform2 === "darwin") {
|
|
28855
29434
|
const candidates = [
|
|
29435
|
+
// Downloaded by postinstall (npm i -g nstantpage-agent)
|
|
29436
|
+
path17.join(os11.homedir(), ".nstantpage", "desktop", "nstantpage.app"),
|
|
28856
29437
|
"/Applications/nstantpage.app",
|
|
28857
|
-
|
|
29438
|
+
path17.join(os11.homedir(), "Applications", "nstantpage.app"),
|
|
28858
29439
|
// Dev build location (from electron-builder --dir)
|
|
28859
|
-
|
|
28860
|
-
|
|
29440
|
+
path17.join(__dirname_esm2, "..", "..", "tray", "dist", "mac-arm64", "nstantpage.app"),
|
|
29441
|
+
path17.join(__dirname_esm2, "..", "..", "tray", "dist", "mac", "nstantpage.app")
|
|
28861
29442
|
];
|
|
28862
29443
|
for (const p of candidates) {
|
|
28863
|
-
if (
|
|
29444
|
+
if (fs18.existsSync(p))
|
|
28864
29445
|
return p;
|
|
28865
29446
|
}
|
|
28866
29447
|
} else if (platform2 === "win32") {
|
|
28867
29448
|
const candidates = [
|
|
28868
|
-
|
|
28869
|
-
|
|
29449
|
+
// Downloaded by postinstall (npm i -g nstantpage-agent)
|
|
29450
|
+
path17.join(os11.homedir(), ".nstantpage", "desktop", "nstantpage.exe"),
|
|
29451
|
+
path17.join(os11.homedir(), "AppData", "Local", "Programs", "nstantpage", "nstantpage.exe"),
|
|
29452
|
+
path17.join("C:\\Program Files", "nstantpage", "nstantpage.exe")
|
|
28870
29453
|
];
|
|
28871
29454
|
for (const p of candidates) {
|
|
28872
|
-
if (
|
|
29455
|
+
if (fs18.existsSync(p))
|
|
28873
29456
|
return p;
|
|
28874
29457
|
}
|
|
28875
29458
|
}
|
|
28876
29459
|
return null;
|
|
28877
29460
|
}
|
|
28878
29461
|
async function installElectronLaunchd(appPath) {
|
|
28879
|
-
const plistDir =
|
|
28880
|
-
const plistPath =
|
|
28881
|
-
const logPath =
|
|
28882
|
-
const errPath =
|
|
28883
|
-
|
|
28884
|
-
|
|
29462
|
+
const plistDir = path17.join(os11.homedir(), "Library", "LaunchAgents");
|
|
29463
|
+
const plistPath = path17.join(plistDir, `${PLIST_LABEL}.plist`);
|
|
29464
|
+
const logPath = path17.join(os11.homedir(), ".nstantpage", "agent.log");
|
|
29465
|
+
const errPath = path17.join(os11.homedir(), ".nstantpage", "agent.err.log");
|
|
29466
|
+
fs18.mkdirSync(plistDir, { recursive: true });
|
|
29467
|
+
fs18.mkdirSync(path17.dirname(logPath), { recursive: true });
|
|
28885
29468
|
const plist = `<?xml version="1.0" encoding="UTF-8"?>
|
|
28886
29469
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
28887
29470
|
<plist version="1.0">
|
|
@@ -28916,7 +29499,7 @@ async function installElectronLaunchd(appPath) {
|
|
|
28916
29499
|
<integer>10</integer>
|
|
28917
29500
|
</dict>
|
|
28918
29501
|
</plist>`;
|
|
28919
|
-
|
|
29502
|
+
fs18.writeFileSync(plistPath, plist, "utf-8");
|
|
28920
29503
|
try {
|
|
28921
29504
|
execSync3(`launchctl unload "${plistPath}" 2>/dev/null`, { encoding: "utf-8" });
|
|
28922
29505
|
} catch {
|
|
@@ -28933,8 +29516,8 @@ async function installElectronLaunchd(appPath) {
|
|
|
28933
29516
|
console.log(source_default.blue(" Right-click the tray icon for options. Open nstantpage.com to connect projects.\n"));
|
|
28934
29517
|
}
|
|
28935
29518
|
async function installElectronWindowsTask(appPath) {
|
|
28936
|
-
const logPath =
|
|
28937
|
-
|
|
29519
|
+
const logPath = path17.join(os11.homedir(), ".nstantpage", "agent.log");
|
|
29520
|
+
fs18.mkdirSync(path17.dirname(logPath), { recursive: true });
|
|
28938
29521
|
try {
|
|
28939
29522
|
execSync3(`schtasks /delete /tn "${WIN_TASK_NAME}" /f 2>nul`, { encoding: "utf-8" });
|
|
28940
29523
|
} catch {
|
|
@@ -28963,8 +29546,8 @@ function getAgentBinPath() {
|
|
|
28963
29546
|
}
|
|
28964
29547
|
try {
|
|
28965
29548
|
const npmRoot = execSync3("npm root -g", { encoding: "utf-8" }).trim();
|
|
28966
|
-
const bin =
|
|
28967
|
-
if (
|
|
29549
|
+
const bin = path17.join(npmRoot, ".bin", "nstantpage");
|
|
29550
|
+
if (fs18.existsSync(bin))
|
|
28968
29551
|
return bin;
|
|
28969
29552
|
} catch {
|
|
28970
29553
|
}
|
|
@@ -28980,12 +29563,12 @@ function getNodePath() {
|
|
|
28980
29563
|
async function installLaunchd(gateway, token) {
|
|
28981
29564
|
const binPath = getAgentBinPath();
|
|
28982
29565
|
const nodePath = getNodePath();
|
|
28983
|
-
const plistDir =
|
|
28984
|
-
const plistPath =
|
|
28985
|
-
const logPath =
|
|
28986
|
-
const errPath =
|
|
28987
|
-
|
|
28988
|
-
|
|
29566
|
+
const plistDir = path17.join(os11.homedir(), "Library", "LaunchAgents");
|
|
29567
|
+
const plistPath = path17.join(plistDir, `${PLIST_LABEL}.plist`);
|
|
29568
|
+
const logPath = path17.join(os11.homedir(), ".nstantpage", "agent.log");
|
|
29569
|
+
const errPath = path17.join(os11.homedir(), ".nstantpage", "agent.err.log");
|
|
29570
|
+
fs18.mkdirSync(plistDir, { recursive: true });
|
|
29571
|
+
fs18.mkdirSync(path17.dirname(logPath), { recursive: true });
|
|
28989
29572
|
const plist = `<?xml version="1.0" encoding="UTF-8"?>
|
|
28990
29573
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
28991
29574
|
<plist version="1.0">
|
|
@@ -29025,7 +29608,7 @@ async function installLaunchd(gateway, token) {
|
|
|
29025
29608
|
<integer>-5</integer>
|
|
29026
29609
|
</dict>
|
|
29027
29610
|
</plist>`;
|
|
29028
|
-
|
|
29611
|
+
fs18.writeFileSync(plistPath, plist, "utf-8");
|
|
29029
29612
|
try {
|
|
29030
29613
|
execSync3(`launchctl unload "${plistPath}" 2>/dev/null`, { encoding: "utf-8" });
|
|
29031
29614
|
} catch {
|
|
@@ -29041,8 +29624,8 @@ async function installLaunchd(gateway, token) {
|
|
|
29041
29624
|
console.log(source_default.blue(' Open any project on nstantpage.com and click "Connect" to use it.\n'));
|
|
29042
29625
|
}
|
|
29043
29626
|
async function uninstallLaunchd() {
|
|
29044
|
-
const plistPath =
|
|
29045
|
-
if (!
|
|
29627
|
+
const plistPath = path17.join(os11.homedir(), "Library", "LaunchAgents", `${PLIST_LABEL}.plist`);
|
|
29628
|
+
if (!fs18.existsSync(plistPath)) {
|
|
29046
29629
|
console.log(source_default.yellow(" \u26A0 Service is not installed"));
|
|
29047
29630
|
return;
|
|
29048
29631
|
}
|
|
@@ -29050,15 +29633,15 @@ async function uninstallLaunchd() {
|
|
|
29050
29633
|
execSync3(`launchctl unload "${plistPath}" 2>/dev/null`, { encoding: "utf-8" });
|
|
29051
29634
|
} catch {
|
|
29052
29635
|
}
|
|
29053
|
-
|
|
29636
|
+
fs18.unlinkSync(plistPath);
|
|
29054
29637
|
console.log(source_default.green(" \u2713 Agent service uninstalled (launchd)"));
|
|
29055
29638
|
console.log(source_default.gray(" The agent will no longer start automatically."));
|
|
29056
29639
|
}
|
|
29057
29640
|
async function installSystemd(gateway, token) {
|
|
29058
29641
|
const binPath = getAgentBinPath();
|
|
29059
|
-
const serviceDir =
|
|
29060
|
-
const servicePath =
|
|
29061
|
-
|
|
29642
|
+
const serviceDir = path17.join(os11.homedir(), ".config", "systemd", "user");
|
|
29643
|
+
const servicePath = path17.join(serviceDir, `${SYSTEMD_SERVICE}.service`);
|
|
29644
|
+
fs18.mkdirSync(serviceDir, { recursive: true });
|
|
29062
29645
|
const unit = `[Unit]
|
|
29063
29646
|
Description=nstantpage Local Development Agent
|
|
29064
29647
|
After=network-online.target
|
|
@@ -29075,7 +29658,7 @@ Environment=HOME=${os11.homedir()}
|
|
|
29075
29658
|
[Install]
|
|
29076
29659
|
WantedBy=default.target
|
|
29077
29660
|
`;
|
|
29078
|
-
|
|
29661
|
+
fs18.writeFileSync(servicePath, unit, "utf-8");
|
|
29079
29662
|
try {
|
|
29080
29663
|
execSync3("systemctl --user daemon-reload", { encoding: "utf-8" });
|
|
29081
29664
|
execSync3(`systemctl --user enable ${SYSTEMD_SERVICE}`, { encoding: "utf-8" });
|
|
@@ -29094,8 +29677,8 @@ WantedBy=default.target
|
|
|
29094
29677
|
console.log(source_default.blue(' Open any project on nstantpage.com and click "Connect" to use it.\n'));
|
|
29095
29678
|
}
|
|
29096
29679
|
async function uninstallSystemd() {
|
|
29097
|
-
const servicePath =
|
|
29098
|
-
if (!
|
|
29680
|
+
const servicePath = path17.join(os11.homedir(), ".config", "systemd", "user", `${SYSTEMD_SERVICE}.service`);
|
|
29681
|
+
if (!fs18.existsSync(servicePath)) {
|
|
29099
29682
|
console.log(source_default.yellow(" \u26A0 Service is not installed"));
|
|
29100
29683
|
return;
|
|
29101
29684
|
}
|
|
@@ -29104,7 +29687,7 @@ async function uninstallSystemd() {
|
|
|
29104
29687
|
execSync3(`systemctl --user disable ${SYSTEMD_SERVICE} 2>/dev/null`, { encoding: "utf-8" });
|
|
29105
29688
|
} catch {
|
|
29106
29689
|
}
|
|
29107
|
-
|
|
29690
|
+
fs18.unlinkSync(servicePath);
|
|
29108
29691
|
try {
|
|
29109
29692
|
execSync3("systemctl --user daemon-reload", { encoding: "utf-8" });
|
|
29110
29693
|
} catch {
|
|
@@ -29115,14 +29698,14 @@ async function uninstallSystemd() {
|
|
|
29115
29698
|
async function installWindowsTask(gateway, token) {
|
|
29116
29699
|
const binPath = getAgentBinPath();
|
|
29117
29700
|
const nodePath = getNodePath();
|
|
29118
|
-
const logPath =
|
|
29119
|
-
|
|
29120
|
-
const batchDir =
|
|
29121
|
-
const batchPath =
|
|
29701
|
+
const logPath = path17.join(os11.homedir(), ".nstantpage", "agent.log");
|
|
29702
|
+
fs18.mkdirSync(path17.dirname(logPath), { recursive: true });
|
|
29703
|
+
const batchDir = path17.join(os11.homedir(), ".nstantpage");
|
|
29704
|
+
const batchPath = path17.join(batchDir, "agent-service.cmd");
|
|
29122
29705
|
const batchContent = `@echo off\r
|
|
29123
29706
|
"${nodePath}" "${binPath}" start --gateway ${gateway} --token ${token} >> "${logPath}" 2>&1\r
|
|
29124
29707
|
`;
|
|
29125
|
-
|
|
29708
|
+
fs18.writeFileSync(batchPath, batchContent, "utf-8");
|
|
29126
29709
|
try {
|
|
29127
29710
|
execSync3(`schtasks /delete /tn "${WIN_TASK_NAME}" /f 2>nul`, { encoding: "utf-8" });
|
|
29128
29711
|
} catch {
|
|
@@ -29152,21 +29735,148 @@ async function uninstallWindowsTask() {
|
|
|
29152
29735
|
} catch {
|
|
29153
29736
|
console.log(source_default.yellow(" \u26A0 Task is not installed or could not be removed"));
|
|
29154
29737
|
}
|
|
29155
|
-
const batchPath =
|
|
29738
|
+
const batchPath = path17.join(os11.homedir(), ".nstantpage", "agent-service.cmd");
|
|
29156
29739
|
try {
|
|
29157
|
-
if (
|
|
29158
|
-
|
|
29740
|
+
if (fs18.existsSync(batchPath))
|
|
29741
|
+
fs18.unlinkSync(batchPath);
|
|
29159
29742
|
} catch {
|
|
29160
29743
|
}
|
|
29161
29744
|
console.log(source_default.gray(" The agent will no longer start automatically."));
|
|
29162
29745
|
}
|
|
29163
29746
|
|
|
29747
|
+
// dist/commands/update.js
|
|
29748
|
+
import fs19 from "fs";
|
|
29749
|
+
import path18 from "path";
|
|
29750
|
+
import os12 from "os";
|
|
29751
|
+
import { execSync as execSync4 } from "child_process";
|
|
29752
|
+
var DESKTOP_DIR = path18.join(os12.homedir(), ".nstantpage", "desktop");
|
|
29753
|
+
var VERSION_FILE = path18.join(DESKTOP_DIR, ".version");
|
|
29754
|
+
async function updateCommand(options = {}) {
|
|
29755
|
+
const updateBoth = !options.cli && !options.desktop;
|
|
29756
|
+
const currentVersion = getPackageVersion();
|
|
29757
|
+
console.log(source_default.blue(`
|
|
29758
|
+
nstantpage v${currentVersion}
|
|
29759
|
+
`));
|
|
29760
|
+
if (updateBoth || options.cli) {
|
|
29761
|
+
await updateCli(currentVersion);
|
|
29762
|
+
}
|
|
29763
|
+
if (updateBoth || options.desktop) {
|
|
29764
|
+
await updateDesktop();
|
|
29765
|
+
}
|
|
29766
|
+
console.log("");
|
|
29767
|
+
}
|
|
29768
|
+
async function updateCli(currentVersion) {
|
|
29769
|
+
console.log(source_default.gray(" Checking npm for CLI updates..."));
|
|
29770
|
+
try {
|
|
29771
|
+
const latest = execSync4("npm view nstantpage-agent version 2>/dev/null", {
|
|
29772
|
+
encoding: "utf-8"
|
|
29773
|
+
}).trim();
|
|
29774
|
+
if (latest === currentVersion) {
|
|
29775
|
+
console.log(source_default.green(` \u2713 CLI is up to date (${currentVersion})`));
|
|
29776
|
+
return;
|
|
29777
|
+
}
|
|
29778
|
+
console.log(source_default.yellow(` Updating CLI: ${currentVersion} \u2192 ${latest}`));
|
|
29779
|
+
execSync4("npm install -g nstantpage-agent@latest", {
|
|
29780
|
+
stdio: "inherit"
|
|
29781
|
+
});
|
|
29782
|
+
console.log(source_default.green(` \u2713 CLI updated to ${latest}`));
|
|
29783
|
+
} catch (err) {
|
|
29784
|
+
console.log(source_default.red(` \u2717 CLI update failed: ${err.message}`));
|
|
29785
|
+
console.log(source_default.gray(" Try manually: npm install -g nstantpage-agent@latest"));
|
|
29786
|
+
}
|
|
29787
|
+
}
|
|
29788
|
+
async function updateDesktop() {
|
|
29789
|
+
console.log(source_default.gray(" Checking GitHub for desktop updates..."));
|
|
29790
|
+
try {
|
|
29791
|
+
const scriptPath = path18.join(path18.dirname(new URL(import.meta.url).pathname), "..", "..", "scripts", "postinstall.mjs");
|
|
29792
|
+
if (fs19.existsSync(scriptPath)) {
|
|
29793
|
+
execSync4(`node "${scriptPath}"`, { stdio: "inherit" });
|
|
29794
|
+
} else {
|
|
29795
|
+
const altPath = path18.join(path18.dirname(new URL(import.meta.url).pathname), "..", "scripts", "postinstall.mjs");
|
|
29796
|
+
if (fs19.existsSync(altPath)) {
|
|
29797
|
+
execSync4(`node "${altPath}"`, { stdio: "inherit" });
|
|
29798
|
+
} else {
|
|
29799
|
+
console.log(source_default.yellow(" \u26A0 Desktop updater script not found. Reinstall to fix: npm i -g nstantpage-agent"));
|
|
29800
|
+
}
|
|
29801
|
+
}
|
|
29802
|
+
} catch (err) {
|
|
29803
|
+
console.log(source_default.red(` \u2717 Desktop update failed: ${err.message}`));
|
|
29804
|
+
}
|
|
29805
|
+
}
|
|
29806
|
+
|
|
29807
|
+
// dist/commands/run.js
|
|
29808
|
+
import fs20 from "fs";
|
|
29809
|
+
import path19 from "path";
|
|
29810
|
+
import os13 from "os";
|
|
29811
|
+
import { execSync as execSync5 } from "child_process";
|
|
29812
|
+
function findElectronApp2() {
|
|
29813
|
+
const platform2 = os13.platform();
|
|
29814
|
+
if (platform2 === "darwin") {
|
|
29815
|
+
const candidates = [
|
|
29816
|
+
path19.join(os13.homedir(), ".nstantpage", "desktop", "nstantpage.app"),
|
|
29817
|
+
"/Applications/nstantpage.app",
|
|
29818
|
+
path19.join(os13.homedir(), "Applications", "nstantpage.app")
|
|
29819
|
+
];
|
|
29820
|
+
for (const p of candidates) {
|
|
29821
|
+
if (fs20.existsSync(p))
|
|
29822
|
+
return p;
|
|
29823
|
+
}
|
|
29824
|
+
} else if (platform2 === "win32") {
|
|
29825
|
+
const candidates = [
|
|
29826
|
+
path19.join(os13.homedir(), ".nstantpage", "desktop", "nstantpage.exe"),
|
|
29827
|
+
path19.join(os13.homedir(), "AppData", "Local", "Programs", "nstantpage", "nstantpage.exe"),
|
|
29828
|
+
path19.join("C:\\Program Files", "nstantpage", "nstantpage.exe")
|
|
29829
|
+
];
|
|
29830
|
+
for (const p of candidates) {
|
|
29831
|
+
if (fs20.existsSync(p))
|
|
29832
|
+
return p;
|
|
29833
|
+
}
|
|
29834
|
+
}
|
|
29835
|
+
return null;
|
|
29836
|
+
}
|
|
29837
|
+
async function runCommand(options = {}) {
|
|
29838
|
+
const appPath = findElectronApp2();
|
|
29839
|
+
if (!appPath) {
|
|
29840
|
+
console.log(source_default.red(" \u2717 Desktop app not found."));
|
|
29841
|
+
console.log(source_default.gray(' Run "nstantpage update --desktop" to download it.'));
|
|
29842
|
+
process.exit(1);
|
|
29843
|
+
}
|
|
29844
|
+
const platform2 = os13.platform();
|
|
29845
|
+
const extraArgs = [];
|
|
29846
|
+
if (options.local !== void 0 && options.local !== false) {
|
|
29847
|
+
const port = typeof options.local === "string" ? options.local : "5001";
|
|
29848
|
+
extraArgs.push(`--local-url=http://localhost:${port}`);
|
|
29849
|
+
}
|
|
29850
|
+
console.log(source_default.blue(`
|
|
29851
|
+
Opening nstantpage desktop app...`));
|
|
29852
|
+
if (extraArgs.length) {
|
|
29853
|
+
console.log(source_default.gray(` Args: ${extraArgs.join(" ")}`));
|
|
29854
|
+
}
|
|
29855
|
+
try {
|
|
29856
|
+
if (platform2 === "darwin") {
|
|
29857
|
+
const argsStr = extraArgs.length ? ` --args ${extraArgs.join(" ")}` : "";
|
|
29858
|
+
execSync5(`open -a "${appPath}"${argsStr}`, { stdio: "inherit" });
|
|
29859
|
+
} else if (platform2 === "win32") {
|
|
29860
|
+
const argsStr = extraArgs.join(" ");
|
|
29861
|
+
execSync5(`"${appPath}" ${argsStr}`, { stdio: "inherit" });
|
|
29862
|
+
} else {
|
|
29863
|
+
console.log(source_default.yellow(" \u26A0 Desktop app not supported on this platform yet."));
|
|
29864
|
+
process.exit(1);
|
|
29865
|
+
}
|
|
29866
|
+
console.log(source_default.green(" \u2713 App launched\n"));
|
|
29867
|
+
} catch (err) {
|
|
29868
|
+
console.log(source_default.red(` \u2717 Failed to launch: ${err.message}`));
|
|
29869
|
+
process.exit(1);
|
|
29870
|
+
}
|
|
29871
|
+
}
|
|
29872
|
+
|
|
29164
29873
|
// dist/cli.js
|
|
29165
29874
|
var program2 = new Command();
|
|
29166
|
-
program2.name("nstantpage").description("Local development agent for nstantpage.com \u2014 run projects on your machine, preview in the cloud").version(
|
|
29875
|
+
program2.name("nstantpage").description("Local development agent for nstantpage.com \u2014 run projects on your machine, preview in the cloud").version(getPackageVersion());
|
|
29167
29876
|
program2.command("login").description("Authenticate with nstantpage.com").option("--gateway <url>", "Gateway URL (auto-detects local vs production)").option("--force", "Re-authenticate even if already logged in").action(loginCommand);
|
|
29168
29877
|
program2.command("logout").description("Sign out and clear stored credentials").action(logoutCommand);
|
|
29169
29878
|
program2.command("start").description("Start the agent for a project (replaces cloud containers)").argument("[directory]", "Project directory (defaults to ~/.nstantpage/projects/<id>)", ".").option("-p, --port <port>", "Local dev server port", "3000").option("-a, --api-port <port>", "Local API server port (internal)", "18924").option("--project-id <id>", "Link to a specific project ID").option("--gateway <url>", "Gateway URL (default: from login)").option("--backend <url>", "Backend API URL (auto-detected from gateway)").option("--token <token>", "Auth token (skip login flow)").option("--dir <path>", "Project directory override").option("--no-dev", "Skip starting the dev server (start manually later)").action(startCommand);
|
|
29879
|
+
program2.command("run").description("Open the nstantpage desktop app").option("--local [port]", "Connect to local backend (default: 5001)").action(runCommand);
|
|
29170
29880
|
program2.command("stop").description("Stop the running agent").action(async () => {
|
|
29171
29881
|
console.log(source_default.yellow("Stopping agent..."));
|
|
29172
29882
|
const { getConfig: getConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
@@ -29192,4 +29902,5 @@ service.command("stop").description("Stop the running agent").action(serviceStop
|
|
|
29192
29902
|
service.command("install").description("Install as a background service (auto-starts on boot)").option("--gateway <url>", "Gateway URL", "wss://webprev.live").action(serviceInstallCommand);
|
|
29193
29903
|
service.command("uninstall").description("Remove the background service").action(serviceUninstallCommand);
|
|
29194
29904
|
service.command("status").description("Check if the background service is running").action(serviceStatusCommand);
|
|
29905
|
+
program2.command("update").description("Update CLI and desktop app to the latest version").option("--cli", "Update only the CLI package").option("--desktop", "Update only the desktop app").action(updateCommand);
|
|
29195
29906
|
program2.parse();
|