sproutkit-code 1.7.0 → 1.9.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 +8 -4
- package/dist/index.js +2024 -873
- package/dist/skill/SKILL.md +11 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6,9 +6,16 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __getProtoOf = Object.getPrototypeOf;
|
|
8
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __esm = (fn, res) => function __init() {
|
|
10
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
11
|
+
};
|
|
9
12
|
var __commonJS = (cb, mod) => function __require() {
|
|
10
13
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
11
14
|
};
|
|
15
|
+
var __export = (target, all) => {
|
|
16
|
+
for (var name in all)
|
|
17
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
18
|
+
};
|
|
12
19
|
var __copyProps = (to, from, except, desc) => {
|
|
13
20
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
21
|
for (let key of __getOwnPropNames(from))
|
|
@@ -29,19 +36,19 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
29
36
|
// ../../node_modules/electron/index.js
|
|
30
37
|
var require_electron = __commonJS({
|
|
31
38
|
"../../node_modules/electron/index.js"(exports2, module2) {
|
|
32
|
-
var
|
|
33
|
-
var
|
|
34
|
-
var pathFile =
|
|
39
|
+
var fs4 = require("fs");
|
|
40
|
+
var path4 = require("path");
|
|
41
|
+
var pathFile = path4.join(__dirname, "path.txt");
|
|
35
42
|
function getElectronPath() {
|
|
36
43
|
let executablePath;
|
|
37
|
-
if (
|
|
38
|
-
executablePath =
|
|
44
|
+
if (fs4.existsSync(pathFile)) {
|
|
45
|
+
executablePath = fs4.readFileSync(pathFile, "utf-8");
|
|
39
46
|
}
|
|
40
47
|
if (process.env.ELECTRON_OVERRIDE_DIST_PATH) {
|
|
41
|
-
return
|
|
48
|
+
return path4.join(process.env.ELECTRON_OVERRIDE_DIST_PATH, executablePath || "electron");
|
|
42
49
|
}
|
|
43
50
|
if (executablePath) {
|
|
44
|
-
return
|
|
51
|
+
return path4.join(__dirname, "dist", executablePath);
|
|
45
52
|
} else {
|
|
46
53
|
throw new Error("Electron failed to install correctly, please delete node_modules/electron and try installing again");
|
|
47
54
|
}
|
|
@@ -59,6 +66,7 @@ var require_runtime = __commonJS({
|
|
|
59
66
|
};
|
|
60
67
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
61
68
|
exports2.userDataDir = userDataDir;
|
|
69
|
+
exports2.isSecretSetting = isSecretSetting;
|
|
62
70
|
exports2.decryptSettingValue = decryptSettingValue;
|
|
63
71
|
exports2.runningHeadless = runningHeadless;
|
|
64
72
|
var path_1 = __importDefault(require("path"));
|
|
@@ -80,9 +88,21 @@ var require_runtime = __commonJS({
|
|
|
80
88
|
}
|
|
81
89
|
return process.env.SPROUTKIT_DATA_DIR || path_1.default.join(os_1.default.homedir(), ".sproutkit");
|
|
82
90
|
}
|
|
91
|
+
var SECRET_SETTINGS = /* @__PURE__ */ new Set([
|
|
92
|
+
"anthropic_key",
|
|
93
|
+
"places_key",
|
|
94
|
+
"vercel_token",
|
|
95
|
+
"blob_token",
|
|
96
|
+
"resend_key",
|
|
97
|
+
"report_key",
|
|
98
|
+
"smtp_pass",
|
|
99
|
+
"imap_pass"
|
|
100
|
+
]);
|
|
101
|
+
function isSecretSetting(key) {
|
|
102
|
+
return SECRET_SETTINGS.has(key);
|
|
103
|
+
}
|
|
83
104
|
function decryptSettingValue(key, stored) {
|
|
84
|
-
|
|
85
|
-
if (!isSecret)
|
|
105
|
+
if (!isSecretSetting(key))
|
|
86
106
|
return stored;
|
|
87
107
|
if (!isHeadless && electronSafeStorage) {
|
|
88
108
|
try {
|
|
@@ -107,6 +127,7 @@ var require_db = __commonJS({
|
|
|
107
127
|
return mod && mod.__esModule ? mod : { "default": mod };
|
|
108
128
|
};
|
|
109
129
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
130
|
+
exports2.databasePath = databasePath;
|
|
110
131
|
exports2.initDatabase = initDatabase2;
|
|
111
132
|
exports2.getDb = getDb2;
|
|
112
133
|
var node_sqlite3_wasm_1 = require("node-sqlite3-wasm");
|
|
@@ -114,11 +135,14 @@ var require_db = __commonJS({
|
|
|
114
135
|
var fs_1 = __importDefault(require("fs"));
|
|
115
136
|
var runtime_1 = require_runtime();
|
|
116
137
|
var db2;
|
|
138
|
+
function databasePath() {
|
|
139
|
+
return path_1.default.join((0, runtime_1.userDataDir)(), "data", "sproutio.db");
|
|
140
|
+
}
|
|
117
141
|
function initDatabase2() {
|
|
118
142
|
const dataDir = path_1.default.join((0, runtime_1.userDataDir)(), "data");
|
|
119
143
|
if (!fs_1.default.existsSync(dataDir))
|
|
120
144
|
fs_1.default.mkdirSync(dataDir, { recursive: true });
|
|
121
|
-
db2 = new node_sqlite3_wasm_1.Database(
|
|
145
|
+
db2 = new node_sqlite3_wasm_1.Database(databasePath());
|
|
122
146
|
db2.exec(`
|
|
123
147
|
CREATE TABLE IF NOT EXISTS settings (
|
|
124
148
|
key TEXT PRIMARY KEY,
|
|
@@ -229,6 +253,12 @@ var require_db = __commonJS({
|
|
|
229
253
|
// WITHOUT the client's password. Means handing the client full ownership
|
|
230
254
|
// doesn't cost the agency its reporting.
|
|
231
255
|
"report_key TEXT",
|
|
256
|
+
// `sproutkit audit` findings: how bad the business's EXISTING site is, and
|
|
257
|
+
// the specific problems to lead outreach with. Distinct from lead_kind's
|
|
258
|
+
// absence-based gaps.
|
|
259
|
+
"site_score INTEGER",
|
|
260
|
+
"site_issues TEXT",
|
|
261
|
+
"audited_at TEXT",
|
|
232
262
|
// Reply loop: when we last contacted them, and the latest outcome. Kept on
|
|
233
263
|
// the lead (as well as contact_log) so `followups` is a single cheap query.
|
|
234
264
|
"last_contacted_at TEXT",
|
|
@@ -263,6 +293,28 @@ var require_db = __commonJS({
|
|
|
263
293
|
} catch {
|
|
264
294
|
}
|
|
265
295
|
}
|
|
296
|
+
for (const col of ["last_email_message_id TEXT", "last_reply_snippet TEXT"]) {
|
|
297
|
+
try {
|
|
298
|
+
db2.exec(`ALTER TABLE leads ADD COLUMN ${col}`);
|
|
299
|
+
} catch {
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
db2.exec(`
|
|
303
|
+
CREATE TABLE IF NOT EXISTS schedules (
|
|
304
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
305
|
+
name TEXT NOT NULL,
|
|
306
|
+
action TEXT NOT NULL,
|
|
307
|
+
cadence TEXT NOT NULL DEFAULT 'daily',
|
|
308
|
+
days TEXT,
|
|
309
|
+
at_hour INTEGER NOT NULL DEFAULT 9,
|
|
310
|
+
at_minute INTEGER NOT NULL DEFAULT 0,
|
|
311
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
312
|
+
max_items INTEGER NOT NULL DEFAULT 10,
|
|
313
|
+
last_run_at TEXT,
|
|
314
|
+
last_result TEXT,
|
|
315
|
+
created_at TEXT DEFAULT (datetime('now'))
|
|
316
|
+
);
|
|
317
|
+
`);
|
|
266
318
|
}
|
|
267
319
|
function getDb2() {
|
|
268
320
|
return db2;
|
|
@@ -1058,14 +1110,14 @@ var require_url_state_machine = __commonJS({
|
|
|
1058
1110
|
return url.replace(/\u0009|\u000A|\u000D/g, "");
|
|
1059
1111
|
}
|
|
1060
1112
|
function shortenPath(url) {
|
|
1061
|
-
const
|
|
1062
|
-
if (
|
|
1113
|
+
const path4 = url.path;
|
|
1114
|
+
if (path4.length === 0) {
|
|
1063
1115
|
return;
|
|
1064
1116
|
}
|
|
1065
|
-
if (url.scheme === "file" &&
|
|
1117
|
+
if (url.scheme === "file" && path4.length === 1 && isNormalizedWindowsDriveLetter(path4[0])) {
|
|
1066
1118
|
return;
|
|
1067
1119
|
}
|
|
1068
|
-
|
|
1120
|
+
path4.pop();
|
|
1069
1121
|
}
|
|
1070
1122
|
function includesCredentials(url) {
|
|
1071
1123
|
return url.username !== "" || url.password !== "";
|
|
@@ -6781,7 +6833,7 @@ var require_lib3 = __commonJS({
|
|
|
6781
6833
|
return new fetch2.Promise(function(resolve, reject) {
|
|
6782
6834
|
const request = new Request2(url, opts);
|
|
6783
6835
|
const options = getNodeRequestOptions(request);
|
|
6784
|
-
const
|
|
6836
|
+
const send2 = (options.protocol === "https:" ? https : http).request;
|
|
6785
6837
|
const signal = request.signal;
|
|
6786
6838
|
let response = null;
|
|
6787
6839
|
const abort = function abort2() {
|
|
@@ -6801,7 +6853,7 @@ var require_lib3 = __commonJS({
|
|
|
6801
6853
|
abort();
|
|
6802
6854
|
finalize();
|
|
6803
6855
|
};
|
|
6804
|
-
const req =
|
|
6856
|
+
const req = send2(options);
|
|
6805
6857
|
let reqTimeout;
|
|
6806
6858
|
if (signal) {
|
|
6807
6859
|
signal.addEventListener("abort", abortAndFinalize);
|
|
@@ -10900,14 +10952,14 @@ var require_fileFromPath = __commonJS({
|
|
|
10900
10952
|
return "File";
|
|
10901
10953
|
}
|
|
10902
10954
|
};
|
|
10903
|
-
function createFileFromPath(
|
|
10955
|
+
function createFileFromPath(path4, { mtimeMs, size }, filenameOrOptions, options = {}) {
|
|
10904
10956
|
let filename;
|
|
10905
10957
|
if ((0, isPlainObject_1.default)(filenameOrOptions)) {
|
|
10906
10958
|
[options, filename] = [filenameOrOptions, void 0];
|
|
10907
10959
|
} else {
|
|
10908
10960
|
filename = filenameOrOptions;
|
|
10909
10961
|
}
|
|
10910
|
-
const file = new FileFromPath({ path:
|
|
10962
|
+
const file = new FileFromPath({ path: path4, size, lastModified: mtimeMs });
|
|
10911
10963
|
if (!filename) {
|
|
10912
10964
|
filename = file.name;
|
|
10913
10965
|
}
|
|
@@ -10916,14 +10968,14 @@ var require_fileFromPath = __commonJS({
|
|
|
10916
10968
|
lastModified: file.lastModified
|
|
10917
10969
|
});
|
|
10918
10970
|
}
|
|
10919
|
-
function fileFromPathSync(
|
|
10920
|
-
const stats = (0, fs_1.statSync)(
|
|
10921
|
-
return createFileFromPath(
|
|
10971
|
+
function fileFromPathSync(path4, filenameOrOptions, options = {}) {
|
|
10972
|
+
const stats = (0, fs_1.statSync)(path4);
|
|
10973
|
+
return createFileFromPath(path4, stats, filenameOrOptions, options);
|
|
10922
10974
|
}
|
|
10923
10975
|
exports2.fileFromPathSync = fileFromPathSync;
|
|
10924
|
-
async function fileFromPath(
|
|
10925
|
-
const stats = await fs_1.promises.stat(
|
|
10926
|
-
return createFileFromPath(
|
|
10976
|
+
async function fileFromPath(path4, filenameOrOptions, options) {
|
|
10977
|
+
const stats = await fs_1.promises.stat(path4);
|
|
10978
|
+
return createFileFromPath(path4, stats, filenameOrOptions, options);
|
|
10927
10979
|
}
|
|
10928
10980
|
exports2.fileFromPath = fileFromPath;
|
|
10929
10981
|
}
|
|
@@ -10975,13 +11027,13 @@ var require_node_runtime = __commonJS({
|
|
|
10975
11027
|
var MultipartBody_1 = require_MultipartBody();
|
|
10976
11028
|
var web_1 = require("node:stream/web");
|
|
10977
11029
|
var fileFromPathWarned = false;
|
|
10978
|
-
async function fileFromPath(
|
|
11030
|
+
async function fileFromPath(path4, ...args) {
|
|
10979
11031
|
const { fileFromPath: _fileFromPath } = await Promise.resolve().then(() => __importStar(require_fileFromPath()));
|
|
10980
11032
|
if (!fileFromPathWarned) {
|
|
10981
|
-
console.warn(`fileFromPath is deprecated; use fs.createReadStream(${JSON.stringify(
|
|
11033
|
+
console.warn(`fileFromPath is deprecated; use fs.createReadStream(${JSON.stringify(path4)}) instead`);
|
|
10982
11034
|
fileFromPathWarned = true;
|
|
10983
11035
|
}
|
|
10984
|
-
return await _fileFromPath(
|
|
11036
|
+
return await _fileFromPath(path4, ...args);
|
|
10985
11037
|
}
|
|
10986
11038
|
var defaultHttpAgent = new agentkeepalive_1.default({ keepAlive: true, timeout: 5 * 60 * 1e3 });
|
|
10987
11039
|
var defaultHttpsAgent = new agentkeepalive_1.default.HttpsAgent({ keepAlive: true, timeout: 5 * 60 * 1e3 });
|
|
@@ -11746,29 +11798,29 @@ var require_core = __commonJS({
|
|
|
11746
11798
|
defaultIdempotencyKey() {
|
|
11747
11799
|
return `stainless-node-retry-${uuid4()}`;
|
|
11748
11800
|
}
|
|
11749
|
-
get(
|
|
11750
|
-
return this.methodRequest("get",
|
|
11801
|
+
get(path4, opts) {
|
|
11802
|
+
return this.methodRequest("get", path4, opts);
|
|
11751
11803
|
}
|
|
11752
|
-
post(
|
|
11753
|
-
return this.methodRequest("post",
|
|
11804
|
+
post(path4, opts) {
|
|
11805
|
+
return this.methodRequest("post", path4, opts);
|
|
11754
11806
|
}
|
|
11755
|
-
patch(
|
|
11756
|
-
return this.methodRequest("patch",
|
|
11807
|
+
patch(path4, opts) {
|
|
11808
|
+
return this.methodRequest("patch", path4, opts);
|
|
11757
11809
|
}
|
|
11758
|
-
put(
|
|
11759
|
-
return this.methodRequest("put",
|
|
11810
|
+
put(path4, opts) {
|
|
11811
|
+
return this.methodRequest("put", path4, opts);
|
|
11760
11812
|
}
|
|
11761
|
-
delete(
|
|
11762
|
-
return this.methodRequest("delete",
|
|
11813
|
+
delete(path4, opts) {
|
|
11814
|
+
return this.methodRequest("delete", path4, opts);
|
|
11763
11815
|
}
|
|
11764
|
-
methodRequest(method,
|
|
11816
|
+
methodRequest(method, path4, opts) {
|
|
11765
11817
|
return this.request(Promise.resolve(opts).then(async (opts2) => {
|
|
11766
11818
|
const body = opts2 && (0, uploads_1.isBlobLike)(opts2?.body) ? new DataView(await opts2.body.arrayBuffer()) : opts2?.body instanceof DataView ? opts2.body : opts2?.body instanceof ArrayBuffer ? new DataView(opts2.body) : opts2 && ArrayBuffer.isView(opts2?.body) ? new DataView(opts2.body.buffer) : opts2?.body;
|
|
11767
|
-
return { method, path:
|
|
11819
|
+
return { method, path: path4, ...opts2, body };
|
|
11768
11820
|
}));
|
|
11769
11821
|
}
|
|
11770
|
-
getAPIList(
|
|
11771
|
-
return this.requestAPIList(Page, { method: "get", path:
|
|
11822
|
+
getAPIList(path4, Page, opts) {
|
|
11823
|
+
return this.requestAPIList(Page, { method: "get", path: path4, ...opts });
|
|
11772
11824
|
}
|
|
11773
11825
|
calculateContentLength(body) {
|
|
11774
11826
|
if (typeof body === "string") {
|
|
@@ -11786,10 +11838,10 @@ var require_core = __commonJS({
|
|
|
11786
11838
|
return null;
|
|
11787
11839
|
}
|
|
11788
11840
|
buildRequest(options, { retryCount = 0 } = {}) {
|
|
11789
|
-
const { method, path:
|
|
11841
|
+
const { method, path: path4, query, headers = {} } = options;
|
|
11790
11842
|
const body = ArrayBuffer.isView(options.body) || options.__binaryRequest && typeof options.body === "string" ? options.body : (0, uploads_1.isMultipartBody)(options.body) ? options.body.body : options.body ? JSON.stringify(options.body, null, 2) : null;
|
|
11791
11843
|
const contentLength = this.calculateContentLength(body);
|
|
11792
|
-
const url = this.buildURL(
|
|
11844
|
+
const url = this.buildURL(path4, query);
|
|
11793
11845
|
if ("timeout" in options)
|
|
11794
11846
|
validatePositiveInteger("timeout", options.timeout);
|
|
11795
11847
|
const timeout = options.timeout ?? this.timeout;
|
|
@@ -11902,8 +11954,8 @@ var require_core = __commonJS({
|
|
|
11902
11954
|
const request = this.makeRequest(options, null);
|
|
11903
11955
|
return new PagePromise(this, request, Page);
|
|
11904
11956
|
}
|
|
11905
|
-
buildURL(
|
|
11906
|
-
const url = isAbsoluteURL(
|
|
11957
|
+
buildURL(path4, query) {
|
|
11958
|
+
const url = isAbsoluteURL(path4) ? new URL(path4) : new URL(this.baseURL + (this.baseURL.endsWith("/") && path4.startsWith("/") ? path4.slice(1) : path4));
|
|
11907
11959
|
const defaultQuery = this.defaultQuery();
|
|
11908
11960
|
if (!isEmptyObj(defaultQuery)) {
|
|
11909
11961
|
query = { ...defaultQuery, ...query };
|
|
@@ -13196,9 +13248,9 @@ var require_PromptCachingBetaMessageStream = __commonJS({
|
|
|
13196
13248
|
_addPromptCachingBetaMessageParam(message) {
|
|
13197
13249
|
this.messages.push(message);
|
|
13198
13250
|
}
|
|
13199
|
-
_addPromptCachingBetaMessage(message,
|
|
13251
|
+
_addPromptCachingBetaMessage(message, emit2 = true) {
|
|
13200
13252
|
this.receivedMessages.push(message);
|
|
13201
|
-
if (
|
|
13253
|
+
if (emit2) {
|
|
13202
13254
|
this._emit("message", message);
|
|
13203
13255
|
}
|
|
13204
13256
|
}
|
|
@@ -13820,9 +13872,9 @@ var require_MessageStream = __commonJS({
|
|
|
13820
13872
|
_addMessageParam(message) {
|
|
13821
13873
|
this.messages.push(message);
|
|
13822
13874
|
}
|
|
13823
|
-
_addMessage(message,
|
|
13875
|
+
_addMessage(message, emit2 = true) {
|
|
13824
13876
|
this.receivedMessages.push(message);
|
|
13825
|
-
if (
|
|
13877
|
+
if (emit2) {
|
|
13826
13878
|
this._emit("message", message);
|
|
13827
13879
|
}
|
|
13828
13880
|
}
|
|
@@ -23240,11 +23292,11 @@ var require_mime_types = __commonJS({
|
|
|
23240
23292
|
}
|
|
23241
23293
|
return exts[0];
|
|
23242
23294
|
}
|
|
23243
|
-
function lookup(
|
|
23244
|
-
if (!
|
|
23295
|
+
function lookup(path4) {
|
|
23296
|
+
if (!path4 || typeof path4 !== "string") {
|
|
23245
23297
|
return false;
|
|
23246
23298
|
}
|
|
23247
|
-
var extension2 = extname("x." +
|
|
23299
|
+
var extension2 = extname("x." + path4).toLowerCase().substr(1);
|
|
23248
23300
|
if (!extension2) {
|
|
23249
23301
|
return false;
|
|
23250
23302
|
}
|
|
@@ -24349,11 +24401,11 @@ var require_form_data = __commonJS({
|
|
|
24349
24401
|
"use strict";
|
|
24350
24402
|
var CombinedStream = require_combined_stream();
|
|
24351
24403
|
var util = require("util");
|
|
24352
|
-
var
|
|
24404
|
+
var path4 = require("path");
|
|
24353
24405
|
var http = require("http");
|
|
24354
24406
|
var https = require("https");
|
|
24355
24407
|
var parseUrl = require("url").parse;
|
|
24356
|
-
var
|
|
24408
|
+
var fs4 = require("fs");
|
|
24357
24409
|
var Stream = require("stream").Stream;
|
|
24358
24410
|
var crypto2 = require("crypto");
|
|
24359
24411
|
var mime = require_mime_types();
|
|
@@ -24420,7 +24472,7 @@ var require_form_data = __commonJS({
|
|
|
24420
24472
|
if (value.end != void 0 && value.end != Infinity && value.start != void 0) {
|
|
24421
24473
|
callback(null, value.end + 1 - (value.start ? value.start : 0));
|
|
24422
24474
|
} else {
|
|
24423
|
-
|
|
24475
|
+
fs4.stat(value.path, function(err, stat) {
|
|
24424
24476
|
if (err) {
|
|
24425
24477
|
callback(err);
|
|
24426
24478
|
return;
|
|
@@ -24477,11 +24529,11 @@ var require_form_data = __commonJS({
|
|
|
24477
24529
|
FormData2.prototype._getContentDisposition = function(value, options) {
|
|
24478
24530
|
var filename;
|
|
24479
24531
|
if (typeof options.filepath === "string") {
|
|
24480
|
-
filename =
|
|
24532
|
+
filename = path4.normalize(options.filepath).replace(/\\/g, "/");
|
|
24481
24533
|
} else if (options.filename || value && (value.name || value.path)) {
|
|
24482
|
-
filename =
|
|
24534
|
+
filename = path4.basename(options.filename || value && (value.name || value.path));
|
|
24483
24535
|
} else if (value && value.readable && hasOwn(value, "httpVersion")) {
|
|
24484
|
-
filename =
|
|
24536
|
+
filename = path4.basename(value.client._httpMessage.path || "");
|
|
24485
24537
|
}
|
|
24486
24538
|
if (filename) {
|
|
24487
24539
|
return 'filename="' + filename + '"';
|
|
@@ -25026,7 +25078,7 @@ var require_has_flag = __commonJS({
|
|
|
25026
25078
|
var require_supports_color = __commonJS({
|
|
25027
25079
|
"../../node_modules/supports-color/index.js"(exports2, module2) {
|
|
25028
25080
|
"use strict";
|
|
25029
|
-
var
|
|
25081
|
+
var os5 = require("os");
|
|
25030
25082
|
var tty = require("tty");
|
|
25031
25083
|
var hasFlag = require_has_flag();
|
|
25032
25084
|
var { env } = process;
|
|
@@ -25074,7 +25126,7 @@ var require_supports_color = __commonJS({
|
|
|
25074
25126
|
return min;
|
|
25075
25127
|
}
|
|
25076
25128
|
if (process.platform === "win32") {
|
|
25077
|
-
const osRelease =
|
|
25129
|
+
const osRelease = os5.release().split(".");
|
|
25078
25130
|
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
25079
25131
|
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
25080
25132
|
}
|
|
@@ -26302,7 +26354,7 @@ var require_axios = __commonJS({
|
|
|
26302
26354
|
var https = require("https");
|
|
26303
26355
|
var http2 = require("http2");
|
|
26304
26356
|
var util = require("util");
|
|
26305
|
-
var
|
|
26357
|
+
var path4 = require("path");
|
|
26306
26358
|
var followRedirects = require_follow_redirects();
|
|
26307
26359
|
var zlib = require("zlib");
|
|
26308
26360
|
var stream = require("stream");
|
|
@@ -27189,9 +27241,9 @@ var require_axios = __commonJS({
|
|
|
27189
27241
|
function removeBrackets(key) {
|
|
27190
27242
|
return utils$1.endsWith(key, "[]") ? key.slice(0, -2) : key;
|
|
27191
27243
|
}
|
|
27192
|
-
function renderKey(
|
|
27193
|
-
if (!
|
|
27194
|
-
return
|
|
27244
|
+
function renderKey(path5, key, dots) {
|
|
27245
|
+
if (!path5) return key;
|
|
27246
|
+
return path5.concat(key).map(function each(token, i) {
|
|
27195
27247
|
token = removeBrackets(token);
|
|
27196
27248
|
return !dots && i ? "[" + token + "]" : token;
|
|
27197
27249
|
}).join(dots ? "." : "");
|
|
@@ -27240,13 +27292,13 @@ var require_axios = __commonJS({
|
|
|
27240
27292
|
}
|
|
27241
27293
|
return value;
|
|
27242
27294
|
}
|
|
27243
|
-
function defaultVisitor(value, key,
|
|
27295
|
+
function defaultVisitor(value, key, path5) {
|
|
27244
27296
|
let arr = value;
|
|
27245
27297
|
if (utils$1.isReactNative(formData) && utils$1.isReactNativeBlob(value)) {
|
|
27246
|
-
formData.append(renderKey(
|
|
27298
|
+
formData.append(renderKey(path5, key, dots), convertValue(value));
|
|
27247
27299
|
return false;
|
|
27248
27300
|
}
|
|
27249
|
-
if (value && !
|
|
27301
|
+
if (value && !path5 && typeof value === "object") {
|
|
27250
27302
|
if (utils$1.endsWith(key, "{}")) {
|
|
27251
27303
|
key = metaTokens ? key : key.slice(0, -2);
|
|
27252
27304
|
value = JSON.stringify(value);
|
|
@@ -27265,7 +27317,7 @@ var require_axios = __commonJS({
|
|
|
27265
27317
|
if (isVisitable(value)) {
|
|
27266
27318
|
return true;
|
|
27267
27319
|
}
|
|
27268
|
-
formData.append(renderKey(
|
|
27320
|
+
formData.append(renderKey(path5, key, dots), convertValue(value));
|
|
27269
27321
|
return false;
|
|
27270
27322
|
}
|
|
27271
27323
|
const stack = [];
|
|
@@ -27274,19 +27326,19 @@ var require_axios = __commonJS({
|
|
|
27274
27326
|
convertValue,
|
|
27275
27327
|
isVisitable
|
|
27276
27328
|
});
|
|
27277
|
-
function build(value,
|
|
27329
|
+
function build(value, path5, depth = 0) {
|
|
27278
27330
|
if (utils$1.isUndefined(value)) return;
|
|
27279
27331
|
if (depth > maxDepth) {
|
|
27280
27332
|
throw new AxiosError("Object is too deeply nested (" + depth + " levels). Max depth: " + maxDepth, AxiosError.ERR_FORM_DATA_DEPTH_EXCEEDED);
|
|
27281
27333
|
}
|
|
27282
27334
|
if (stack.indexOf(value) !== -1) {
|
|
27283
|
-
throw Error("Circular reference detected in " +
|
|
27335
|
+
throw Error("Circular reference detected in " + path5.join("."));
|
|
27284
27336
|
}
|
|
27285
27337
|
stack.push(value);
|
|
27286
27338
|
utils$1.forEach(value, function each(el, key) {
|
|
27287
|
-
const result = !(utils$1.isUndefined(el) || el === null) && visitor.call(formData, el, utils$1.isString(key) ? key.trim() : key,
|
|
27339
|
+
const result = !(utils$1.isUndefined(el) || el === null) && visitor.call(formData, el, utils$1.isString(key) ? key.trim() : key, path5, exposedHelpers);
|
|
27288
27340
|
if (result === true) {
|
|
27289
|
-
build(el,
|
|
27341
|
+
build(el, path5 ? path5.concat(key) : [key], depth + 1);
|
|
27290
27342
|
}
|
|
27291
27343
|
});
|
|
27292
27344
|
stack.pop();
|
|
@@ -27474,7 +27526,7 @@ var require_axios = __commonJS({
|
|
|
27474
27526
|
};
|
|
27475
27527
|
function toURLEncodedForm(data, options) {
|
|
27476
27528
|
return toFormData(data, new platform.classes.URLSearchParams(), {
|
|
27477
|
-
visitor: function(value, key,
|
|
27529
|
+
visitor: function(value, key, path5, helpers) {
|
|
27478
27530
|
if (platform.isNode && utils$1.isBuffer(value)) {
|
|
27479
27531
|
this.append(key, value.toString("base64"));
|
|
27480
27532
|
return false;
|
|
@@ -27502,11 +27554,11 @@ var require_axios = __commonJS({
|
|
|
27502
27554
|
return obj;
|
|
27503
27555
|
}
|
|
27504
27556
|
function formDataToJSON(formData) {
|
|
27505
|
-
function buildPath(
|
|
27506
|
-
let name =
|
|
27557
|
+
function buildPath(path5, value, target, index) {
|
|
27558
|
+
let name = path5[index++];
|
|
27507
27559
|
if (name === "__proto__") return true;
|
|
27508
27560
|
const isNumericKey = Number.isFinite(+name);
|
|
27509
|
-
const isLast = index >=
|
|
27561
|
+
const isLast = index >= path5.length;
|
|
27510
27562
|
name = !name && utils$1.isArray(target) ? target.length : name;
|
|
27511
27563
|
if (isLast) {
|
|
27512
27564
|
if (utils$1.hasOwnProp(target, name)) {
|
|
@@ -27519,7 +27571,7 @@ var require_axios = __commonJS({
|
|
|
27519
27571
|
if (!utils$1.hasOwnProp(target, name) || !utils$1.isObject(target[name])) {
|
|
27520
27572
|
target[name] = [];
|
|
27521
27573
|
}
|
|
27522
|
-
const result = buildPath(
|
|
27574
|
+
const result = buildPath(path5, value, target[name], index);
|
|
27523
27575
|
if (result && utils$1.isArray(target[name])) {
|
|
27524
27576
|
target[name] = arrayToObject(target[name]);
|
|
27525
27577
|
}
|
|
@@ -28889,8 +28941,8 @@ var require_axios = __commonJS({
|
|
|
28889
28941
|
}
|
|
28890
28942
|
if (config.allowedSocketPaths != null) {
|
|
28891
28943
|
const allowed = Array.isArray(config.allowedSocketPaths) ? config.allowedSocketPaths : [config.allowedSocketPaths];
|
|
28892
|
-
const resolvedSocket =
|
|
28893
|
-
const isAllowed = allowed.some((entry) => typeof entry === "string" &&
|
|
28944
|
+
const resolvedSocket = path4.resolve(config.socketPath);
|
|
28945
|
+
const isAllowed = allowed.some((entry) => typeof entry === "string" && path4.resolve(entry) === resolvedSocket);
|
|
28894
28946
|
if (!isAllowed) {
|
|
28895
28947
|
return reject(new AxiosError(`socketPath "${config.socketPath}" is not permitted by allowedSocketPaths`, AxiosError.ERR_BAD_OPTION_VALUE, config));
|
|
28896
28948
|
}
|
|
@@ -29144,14 +29196,14 @@ var require_axios = __commonJS({
|
|
|
29144
29196
|
var cookies = platform.hasStandardBrowserEnv ? (
|
|
29145
29197
|
// Standard browser envs support document.cookie
|
|
29146
29198
|
{
|
|
29147
|
-
write(name, value, expires,
|
|
29199
|
+
write(name, value, expires, path5, domain, secure, sameSite) {
|
|
29148
29200
|
if (typeof document === "undefined") return;
|
|
29149
29201
|
const cookie = [`${name}=${encodeURIComponent(value)}`];
|
|
29150
29202
|
if (utils$1.isNumber(expires)) {
|
|
29151
29203
|
cookie.push(`expires=${new Date(expires).toUTCString()}`);
|
|
29152
29204
|
}
|
|
29153
|
-
if (utils$1.isString(
|
|
29154
|
-
cookie.push(`path=${
|
|
29205
|
+
if (utils$1.isString(path5)) {
|
|
29206
|
+
cookie.push(`path=${path5}`);
|
|
29155
29207
|
}
|
|
29156
29208
|
if (utils$1.isString(domain)) {
|
|
29157
29209
|
cookie.push(`domain=${domain}`);
|
|
@@ -31232,12 +31284,21 @@ var require_agency = __commonJS({
|
|
|
31232
31284
|
"../desktop/dist/main/lib/agency.js"(exports2) {
|
|
31233
31285
|
"use strict";
|
|
31234
31286
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
31287
|
+
exports2.DEFAULT_CURRENCY = exports2.CURRENCIES = void 0;
|
|
31235
31288
|
exports2.getAgencyProfile = getAgencyProfile2;
|
|
31236
31289
|
exports2.setAgencyProfile = setAgencyProfile2;
|
|
31237
31290
|
exports2.agencyConfigured = agencyConfigured2;
|
|
31238
31291
|
exports2.siteCredit = siteCredit;
|
|
31239
31292
|
exports2.formatMoney = formatMoney2;
|
|
31240
31293
|
var db_1 = require_db();
|
|
31294
|
+
exports2.CURRENCIES = [
|
|
31295
|
+
{ code: "USD", symbol: "$", label: "US dollar" },
|
|
31296
|
+
{ code: "GBP", symbol: "\xA3", label: "Pound sterling" },
|
|
31297
|
+
{ code: "EUR", symbol: "\u20AC", label: "Euro" },
|
|
31298
|
+
{ code: "CAD", symbol: "CA$", label: "Canadian dollar" },
|
|
31299
|
+
{ code: "AUD", symbol: "A$", label: "Australian dollar" }
|
|
31300
|
+
];
|
|
31301
|
+
exports2.DEFAULT_CURRENCY = "USD";
|
|
31241
31302
|
var KEYS = {
|
|
31242
31303
|
name: "agency_name",
|
|
31243
31304
|
logoPath: "agency_logo_path",
|
|
@@ -31283,7 +31344,7 @@ var require_agency = __commonJS({
|
|
|
31283
31344
|
bankAccount: read(KEYS.bankAccount),
|
|
31284
31345
|
bankSortCode: read(KEYS.bankSortCode),
|
|
31285
31346
|
paymentTerms: read(KEYS.paymentTerms),
|
|
31286
|
-
currency: read("agency_currency") ??
|
|
31347
|
+
currency: read("agency_currency") ?? exports2.DEFAULT_CURRENCY
|
|
31287
31348
|
};
|
|
31288
31349
|
}
|
|
31289
31350
|
function setAgencyProfile2(patch) {
|
|
@@ -31307,9 +31368,8 @@ var require_agency = __commonJS({
|
|
|
31307
31368
|
return { label: "Sproutkit", url: "https://sproutkit.app" };
|
|
31308
31369
|
return { label: p.name, url: p.website };
|
|
31309
31370
|
}
|
|
31310
|
-
function formatMoney2(pence, currency =
|
|
31311
|
-
const
|
|
31312
|
-
const sym = symbols[currency] ?? "";
|
|
31371
|
+
function formatMoney2(pence, currency = exports2.DEFAULT_CURRENCY) {
|
|
31372
|
+
const sym = exports2.CURRENCIES.find((c2) => c2.code === currency)?.symbol ?? "";
|
|
31313
31373
|
const value = (pence / 100).toFixed(2);
|
|
31314
31374
|
return `${sym}${value}`;
|
|
31315
31375
|
}
|
|
@@ -35805,7 +35865,7 @@ var require_lib4 = __commonJS({
|
|
|
35805
35865
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
35806
35866
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
35807
35867
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
35808
|
-
var
|
|
35868
|
+
var __export2 = (target, all) => {
|
|
35809
35869
|
for (var name in all)
|
|
35810
35870
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
35811
35871
|
};
|
|
@@ -35819,7 +35879,7 @@ var require_lib4 = __commonJS({
|
|
|
35819
35879
|
};
|
|
35820
35880
|
var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
35821
35881
|
var src_exports = {};
|
|
35822
|
-
|
|
35882
|
+
__export2(src_exports, {
|
|
35823
35883
|
isNodeProcess: () => isNodeProcess
|
|
35824
35884
|
});
|
|
35825
35885
|
module2.exports = __toCommonJS(src_exports);
|
|
@@ -35856,7 +35916,7 @@ var require_version2 = __commonJS({
|
|
|
35856
35916
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
35857
35917
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
35858
35918
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
35859
|
-
var
|
|
35919
|
+
var __export2 = (target, all) => {
|
|
35860
35920
|
for (var name in all)
|
|
35861
35921
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
35862
35922
|
};
|
|
@@ -35870,7 +35930,7 @@ var require_version2 = __commonJS({
|
|
|
35870
35930
|
};
|
|
35871
35931
|
var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
35872
35932
|
var version_exports = {};
|
|
35873
|
-
|
|
35933
|
+
__export2(version_exports, {
|
|
35874
35934
|
version: () => version
|
|
35875
35935
|
});
|
|
35876
35936
|
module2.exports = __toCommonJS(version_exports);
|
|
@@ -35886,7 +35946,7 @@ var require_exchange_vercel_oidc_token = __commonJS({
|
|
|
35886
35946
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
35887
35947
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
35888
35948
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
35889
|
-
var
|
|
35949
|
+
var __export2 = (target, all) => {
|
|
35890
35950
|
for (var name in all)
|
|
35891
35951
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
35892
35952
|
};
|
|
@@ -35900,7 +35960,7 @@ var require_exchange_vercel_oidc_token = __commonJS({
|
|
|
35900
35960
|
};
|
|
35901
35961
|
var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
35902
35962
|
var exchange_vercel_oidc_token_exports = {};
|
|
35903
|
-
|
|
35963
|
+
__export2(exchange_vercel_oidc_token_exports, {
|
|
35904
35964
|
exchangeVercelOidcToken: () => exchangeVercelOidcToken2
|
|
35905
35965
|
});
|
|
35906
35966
|
module2.exports = __toCommonJS(exchange_vercel_oidc_token_exports);
|
|
@@ -36025,7 +36085,7 @@ var require_get_context = __commonJS({
|
|
|
36025
36085
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
36026
36086
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
36027
36087
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
36028
|
-
var
|
|
36088
|
+
var __export2 = (target, all) => {
|
|
36029
36089
|
for (var name in all)
|
|
36030
36090
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
36031
36091
|
};
|
|
@@ -36039,7 +36099,7 @@ var require_get_context = __commonJS({
|
|
|
36039
36099
|
};
|
|
36040
36100
|
var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
36041
36101
|
var get_context_exports = {};
|
|
36042
|
-
|
|
36102
|
+
__export2(get_context_exports, {
|
|
36043
36103
|
SYMBOL_FOR_REQ_CONTEXT: () => SYMBOL_FOR_REQ_CONTEXT,
|
|
36044
36104
|
getContext: () => getContext2
|
|
36045
36105
|
});
|
|
@@ -36060,7 +36120,7 @@ var require_get_vercel_oidc_token_sync = __commonJS({
|
|
|
36060
36120
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
36061
36121
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
36062
36122
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
36063
|
-
var
|
|
36123
|
+
var __export2 = (target, all) => {
|
|
36064
36124
|
for (var name in all)
|
|
36065
36125
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
36066
36126
|
};
|
|
@@ -36074,7 +36134,7 @@ var require_get_vercel_oidc_token_sync = __commonJS({
|
|
|
36074
36134
|
};
|
|
36075
36135
|
var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
36076
36136
|
var get_vercel_oidc_token_sync_exports = {};
|
|
36077
|
-
|
|
36137
|
+
__export2(get_vercel_oidc_token_sync_exports, {
|
|
36078
36138
|
getVercelOidcTokenSync: () => getVercelOidcTokenSync2
|
|
36079
36139
|
});
|
|
36080
36140
|
module2.exports = __toCommonJS(get_vercel_oidc_token_sync_exports);
|
|
@@ -36099,7 +36159,7 @@ var require_token_error = __commonJS({
|
|
|
36099
36159
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
36100
36160
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
36101
36161
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
36102
|
-
var
|
|
36162
|
+
var __export2 = (target, all) => {
|
|
36103
36163
|
for (var name in all)
|
|
36104
36164
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
36105
36165
|
};
|
|
@@ -36113,7 +36173,7 @@ var require_token_error = __commonJS({
|
|
|
36113
36173
|
};
|
|
36114
36174
|
var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
36115
36175
|
var token_error_exports = {};
|
|
36116
|
-
|
|
36176
|
+
__export2(token_error_exports, {
|
|
36117
36177
|
VercelOidcTokenError: () => VercelOidcTokenError
|
|
36118
36178
|
});
|
|
36119
36179
|
module2.exports = __toCommonJS(token_error_exports);
|
|
@@ -36141,7 +36201,7 @@ var require_errors = __commonJS({
|
|
|
36141
36201
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
36142
36202
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
36143
36203
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
36144
|
-
var
|
|
36204
|
+
var __export2 = (target, all) => {
|
|
36145
36205
|
for (var name in all)
|
|
36146
36206
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
36147
36207
|
};
|
|
@@ -36155,7 +36215,7 @@ var require_errors = __commonJS({
|
|
|
36155
36215
|
};
|
|
36156
36216
|
var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
36157
36217
|
var errors_exports = {};
|
|
36158
|
-
|
|
36218
|
+
__export2(errors_exports, {
|
|
36159
36219
|
VercelCliError: () => VercelCliError2,
|
|
36160
36220
|
assertValidCwd: () => assertValidCwd,
|
|
36161
36221
|
getCliNotFoundMessage: () => getCliNotFoundMessage,
|
|
@@ -36294,8 +36354,8 @@ var require_windows = __commonJS({
|
|
|
36294
36354
|
"../../node_modules/isexe/windows.js"(exports2, module2) {
|
|
36295
36355
|
module2.exports = isexe;
|
|
36296
36356
|
isexe.sync = sync;
|
|
36297
|
-
var
|
|
36298
|
-
function checkPathExt(
|
|
36357
|
+
var fs4 = require("fs");
|
|
36358
|
+
function checkPathExt(path4, options) {
|
|
36299
36359
|
var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
|
|
36300
36360
|
if (!pathext) {
|
|
36301
36361
|
return true;
|
|
@@ -36306,25 +36366,25 @@ var require_windows = __commonJS({
|
|
|
36306
36366
|
}
|
|
36307
36367
|
for (var i = 0; i < pathext.length; i++) {
|
|
36308
36368
|
var p = pathext[i].toLowerCase();
|
|
36309
|
-
if (p &&
|
|
36369
|
+
if (p && path4.substr(-p.length).toLowerCase() === p) {
|
|
36310
36370
|
return true;
|
|
36311
36371
|
}
|
|
36312
36372
|
}
|
|
36313
36373
|
return false;
|
|
36314
36374
|
}
|
|
36315
|
-
function checkStat(stat,
|
|
36375
|
+
function checkStat(stat, path4, options) {
|
|
36316
36376
|
if (!stat.isSymbolicLink() && !stat.isFile()) {
|
|
36317
36377
|
return false;
|
|
36318
36378
|
}
|
|
36319
|
-
return checkPathExt(
|
|
36379
|
+
return checkPathExt(path4, options);
|
|
36320
36380
|
}
|
|
36321
|
-
function isexe(
|
|
36322
|
-
|
|
36323
|
-
cb(er, er ? false : checkStat(stat,
|
|
36381
|
+
function isexe(path4, options, cb) {
|
|
36382
|
+
fs4.stat(path4, function(er, stat) {
|
|
36383
|
+
cb(er, er ? false : checkStat(stat, path4, options));
|
|
36324
36384
|
});
|
|
36325
36385
|
}
|
|
36326
|
-
function sync(
|
|
36327
|
-
return checkStat(
|
|
36386
|
+
function sync(path4, options) {
|
|
36387
|
+
return checkStat(fs4.statSync(path4), path4, options);
|
|
36328
36388
|
}
|
|
36329
36389
|
}
|
|
36330
36390
|
});
|
|
@@ -36334,14 +36394,14 @@ var require_mode = __commonJS({
|
|
|
36334
36394
|
"../../node_modules/isexe/mode.js"(exports2, module2) {
|
|
36335
36395
|
module2.exports = isexe;
|
|
36336
36396
|
isexe.sync = sync;
|
|
36337
|
-
var
|
|
36338
|
-
function isexe(
|
|
36339
|
-
|
|
36397
|
+
var fs4 = require("fs");
|
|
36398
|
+
function isexe(path4, options, cb) {
|
|
36399
|
+
fs4.stat(path4, function(er, stat) {
|
|
36340
36400
|
cb(er, er ? false : checkStat(stat, options));
|
|
36341
36401
|
});
|
|
36342
36402
|
}
|
|
36343
|
-
function sync(
|
|
36344
|
-
return checkStat(
|
|
36403
|
+
function sync(path4, options) {
|
|
36404
|
+
return checkStat(fs4.statSync(path4), options);
|
|
36345
36405
|
}
|
|
36346
36406
|
function checkStat(stat, options) {
|
|
36347
36407
|
return stat.isFile() && checkMode(stat, options);
|
|
@@ -36365,7 +36425,7 @@ var require_mode = __commonJS({
|
|
|
36365
36425
|
// ../../node_modules/isexe/index.js
|
|
36366
36426
|
var require_isexe = __commonJS({
|
|
36367
36427
|
"../../node_modules/isexe/index.js"(exports2, module2) {
|
|
36368
|
-
var
|
|
36428
|
+
var fs4 = require("fs");
|
|
36369
36429
|
var core;
|
|
36370
36430
|
if (process.platform === "win32" || global.TESTING_WINDOWS) {
|
|
36371
36431
|
core = require_windows();
|
|
@@ -36374,7 +36434,7 @@ var require_isexe = __commonJS({
|
|
|
36374
36434
|
}
|
|
36375
36435
|
module2.exports = isexe;
|
|
36376
36436
|
isexe.sync = sync;
|
|
36377
|
-
function isexe(
|
|
36437
|
+
function isexe(path4, options, cb) {
|
|
36378
36438
|
if (typeof options === "function") {
|
|
36379
36439
|
cb = options;
|
|
36380
36440
|
options = {};
|
|
@@ -36384,7 +36444,7 @@ var require_isexe = __commonJS({
|
|
|
36384
36444
|
throw new TypeError("callback not provided");
|
|
36385
36445
|
}
|
|
36386
36446
|
return new Promise(function(resolve, reject) {
|
|
36387
|
-
isexe(
|
|
36447
|
+
isexe(path4, options || {}, function(er, is) {
|
|
36388
36448
|
if (er) {
|
|
36389
36449
|
reject(er);
|
|
36390
36450
|
} else {
|
|
@@ -36393,7 +36453,7 @@ var require_isexe = __commonJS({
|
|
|
36393
36453
|
});
|
|
36394
36454
|
});
|
|
36395
36455
|
}
|
|
36396
|
-
core(
|
|
36456
|
+
core(path4, options || {}, function(er, is) {
|
|
36397
36457
|
if (er) {
|
|
36398
36458
|
if (er.code === "EACCES" || options && options.ignoreErrors) {
|
|
36399
36459
|
er = null;
|
|
@@ -36403,9 +36463,9 @@ var require_isexe = __commonJS({
|
|
|
36403
36463
|
cb(er, is);
|
|
36404
36464
|
});
|
|
36405
36465
|
}
|
|
36406
|
-
function sync(
|
|
36466
|
+
function sync(path4, options) {
|
|
36407
36467
|
try {
|
|
36408
|
-
return core.sync(
|
|
36468
|
+
return core.sync(path4, options || {});
|
|
36409
36469
|
} catch (er) {
|
|
36410
36470
|
if (options && options.ignoreErrors || er.code === "EACCES") {
|
|
36411
36471
|
return false;
|
|
@@ -36421,7 +36481,7 @@ var require_isexe = __commonJS({
|
|
|
36421
36481
|
var require_which = __commonJS({
|
|
36422
36482
|
"../../node_modules/which/which.js"(exports2, module2) {
|
|
36423
36483
|
var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
|
|
36424
|
-
var
|
|
36484
|
+
var path4 = require("path");
|
|
36425
36485
|
var COLON = isWindows ? ";" : ":";
|
|
36426
36486
|
var isexe = require_isexe();
|
|
36427
36487
|
var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
|
|
@@ -36459,7 +36519,7 @@ var require_which = __commonJS({
|
|
|
36459
36519
|
return opt.all && found.length ? resolve(found) : reject(getNotFoundError(cmd));
|
|
36460
36520
|
const ppRaw = pathEnv[i];
|
|
36461
36521
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
36462
|
-
const pCmd =
|
|
36522
|
+
const pCmd = path4.join(pathPart, cmd);
|
|
36463
36523
|
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
36464
36524
|
resolve(subStep(p, i, 0));
|
|
36465
36525
|
});
|
|
@@ -36486,7 +36546,7 @@ var require_which = __commonJS({
|
|
|
36486
36546
|
for (let i = 0; i < pathEnv.length; i++) {
|
|
36487
36547
|
const ppRaw = pathEnv[i];
|
|
36488
36548
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
36489
|
-
const pCmd =
|
|
36549
|
+
const pCmd = path4.join(pathPart, cmd);
|
|
36490
36550
|
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
36491
36551
|
for (let j = 0; j < pathExt.length; j++) {
|
|
36492
36552
|
const cur = p + pathExt[j];
|
|
@@ -36534,7 +36594,7 @@ var require_path_key = __commonJS({
|
|
|
36534
36594
|
var require_resolveCommand = __commonJS({
|
|
36535
36595
|
"../../node_modules/cross-spawn/lib/util/resolveCommand.js"(exports2, module2) {
|
|
36536
36596
|
"use strict";
|
|
36537
|
-
var
|
|
36597
|
+
var path4 = require("path");
|
|
36538
36598
|
var which = require_which();
|
|
36539
36599
|
var getPathKey = require_path_key();
|
|
36540
36600
|
function resolveCommandAttempt(parsed, withoutPathExt) {
|
|
@@ -36552,7 +36612,7 @@ var require_resolveCommand = __commonJS({
|
|
|
36552
36612
|
try {
|
|
36553
36613
|
resolved = which.sync(parsed.command, {
|
|
36554
36614
|
path: env[getPathKey({ env })],
|
|
36555
|
-
pathExt: withoutPathExt ?
|
|
36615
|
+
pathExt: withoutPathExt ? path4.delimiter : void 0
|
|
36556
36616
|
});
|
|
36557
36617
|
} catch (e) {
|
|
36558
36618
|
} finally {
|
|
@@ -36561,7 +36621,7 @@ var require_resolveCommand = __commonJS({
|
|
|
36561
36621
|
}
|
|
36562
36622
|
}
|
|
36563
36623
|
if (resolved) {
|
|
36564
|
-
resolved =
|
|
36624
|
+
resolved = path4.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
|
|
36565
36625
|
}
|
|
36566
36626
|
return resolved;
|
|
36567
36627
|
}
|
|
@@ -36615,8 +36675,8 @@ var require_shebang_command = __commonJS({
|
|
|
36615
36675
|
if (!match) {
|
|
36616
36676
|
return null;
|
|
36617
36677
|
}
|
|
36618
|
-
const [
|
|
36619
|
-
const binary =
|
|
36678
|
+
const [path4, argument] = match[0].replace(/#! ?/, "").split(" ");
|
|
36679
|
+
const binary = path4.split("/").pop();
|
|
36620
36680
|
if (binary === "env") {
|
|
36621
36681
|
return argument;
|
|
36622
36682
|
}
|
|
@@ -36629,16 +36689,16 @@ var require_shebang_command = __commonJS({
|
|
|
36629
36689
|
var require_readShebang = __commonJS({
|
|
36630
36690
|
"../../node_modules/cross-spawn/lib/util/readShebang.js"(exports2, module2) {
|
|
36631
36691
|
"use strict";
|
|
36632
|
-
var
|
|
36692
|
+
var fs4 = require("fs");
|
|
36633
36693
|
var shebangCommand = require_shebang_command();
|
|
36634
36694
|
function readShebang(command) {
|
|
36635
36695
|
const size = 150;
|
|
36636
36696
|
const buffer = Buffer.alloc(size);
|
|
36637
36697
|
let fd;
|
|
36638
36698
|
try {
|
|
36639
|
-
fd =
|
|
36640
|
-
|
|
36641
|
-
|
|
36699
|
+
fd = fs4.openSync(command, "r");
|
|
36700
|
+
fs4.readSync(fd, buffer, 0, size, 0);
|
|
36701
|
+
fs4.closeSync(fd);
|
|
36642
36702
|
} catch (e) {
|
|
36643
36703
|
}
|
|
36644
36704
|
return shebangCommand(buffer.toString());
|
|
@@ -36651,7 +36711,7 @@ var require_readShebang = __commonJS({
|
|
|
36651
36711
|
var require_parse = __commonJS({
|
|
36652
36712
|
"../../node_modules/cross-spawn/lib/parse.js"(exports2, module2) {
|
|
36653
36713
|
"use strict";
|
|
36654
|
-
var
|
|
36714
|
+
var path4 = require("path");
|
|
36655
36715
|
var resolveCommand = require_resolveCommand();
|
|
36656
36716
|
var escape = require_escape();
|
|
36657
36717
|
var readShebang = require_readShebang();
|
|
@@ -36676,7 +36736,7 @@ var require_parse = __commonJS({
|
|
|
36676
36736
|
const needsShell = !isExecutableRegExp.test(commandFile);
|
|
36677
36737
|
if (parsed.options.forceShell || needsShell) {
|
|
36678
36738
|
const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
|
|
36679
|
-
parsed.command =
|
|
36739
|
+
parsed.command = path4.normalize(parsed.command);
|
|
36680
36740
|
parsed.command = escape.command(parsed.command);
|
|
36681
36741
|
parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars));
|
|
36682
36742
|
const shellCommand = [parsed.command].concat(parsed.args).join(" ");
|
|
@@ -36772,7 +36832,7 @@ var require_cross_spawn = __commonJS({
|
|
|
36772
36832
|
enoent.hookChildProcess(spawned, parsed);
|
|
36773
36833
|
return spawned;
|
|
36774
36834
|
}
|
|
36775
|
-
function
|
|
36835
|
+
function spawnSync5(command, args, options) {
|
|
36776
36836
|
const parsed = parse(command, args, options);
|
|
36777
36837
|
const result = cp.spawnSync(parsed.command, parsed.args, parsed.options);
|
|
36778
36838
|
result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
|
|
@@ -36780,7 +36840,7 @@ var require_cross_spawn = __commonJS({
|
|
|
36780
36840
|
}
|
|
36781
36841
|
module2.exports = spawn2;
|
|
36782
36842
|
module2.exports.spawn = spawn2;
|
|
36783
|
-
module2.exports.sync =
|
|
36843
|
+
module2.exports.sync = spawnSync5;
|
|
36784
36844
|
module2.exports._parse = parse;
|
|
36785
36845
|
module2.exports._enoent = enoent;
|
|
36786
36846
|
}
|
|
@@ -36808,7 +36868,7 @@ var require_strip_final_newline = __commonJS({
|
|
|
36808
36868
|
var require_npm_run_path = __commonJS({
|
|
36809
36869
|
"../../node_modules/npm-run-path/index.js"(exports2, module2) {
|
|
36810
36870
|
"use strict";
|
|
36811
|
-
var
|
|
36871
|
+
var path4 = require("path");
|
|
36812
36872
|
var pathKey = require_path_key();
|
|
36813
36873
|
var npmRunPath = (options) => {
|
|
36814
36874
|
options = {
|
|
@@ -36818,16 +36878,16 @@ var require_npm_run_path = __commonJS({
|
|
|
36818
36878
|
...options
|
|
36819
36879
|
};
|
|
36820
36880
|
let previous;
|
|
36821
|
-
let cwdPath =
|
|
36881
|
+
let cwdPath = path4.resolve(options.cwd);
|
|
36822
36882
|
const result = [];
|
|
36823
36883
|
while (previous !== cwdPath) {
|
|
36824
|
-
result.push(
|
|
36884
|
+
result.push(path4.join(cwdPath, "node_modules/.bin"));
|
|
36825
36885
|
previous = cwdPath;
|
|
36826
|
-
cwdPath =
|
|
36886
|
+
cwdPath = path4.resolve(cwdPath, "..");
|
|
36827
36887
|
}
|
|
36828
|
-
const execPathDir =
|
|
36888
|
+
const execPathDir = path4.resolve(options.cwd, options.execPath, "..");
|
|
36829
36889
|
result.push(execPathDir);
|
|
36830
|
-
return result.concat(options.path).join(
|
|
36890
|
+
return result.concat(options.path).join(path4.delimiter);
|
|
36831
36891
|
};
|
|
36832
36892
|
module2.exports = npmRunPath;
|
|
36833
36893
|
module2.exports.default = npmRunPath;
|
|
@@ -36837,9 +36897,9 @@ var require_npm_run_path = __commonJS({
|
|
|
36837
36897
|
...options
|
|
36838
36898
|
};
|
|
36839
36899
|
const env = { ...options.env };
|
|
36840
|
-
const
|
|
36841
|
-
options.path = env[
|
|
36842
|
-
env[
|
|
36900
|
+
const path5 = pathKey({ env });
|
|
36901
|
+
options.path = env[path5];
|
|
36902
|
+
env[path5] = module2.exports(options);
|
|
36843
36903
|
return env;
|
|
36844
36904
|
};
|
|
36845
36905
|
}
|
|
@@ -37521,7 +37581,7 @@ var require_signal_exit = __commonJS({
|
|
|
37521
37581
|
emitter.count -= 1;
|
|
37522
37582
|
};
|
|
37523
37583
|
module2.exports.unload = unload;
|
|
37524
|
-
|
|
37584
|
+
emit2 = function emit3(event, code, signal) {
|
|
37525
37585
|
if (emitter.emitted[event]) {
|
|
37526
37586
|
return;
|
|
37527
37587
|
}
|
|
@@ -37537,8 +37597,8 @@ var require_signal_exit = __commonJS({
|
|
|
37537
37597
|
var listeners = process2.listeners(sig);
|
|
37538
37598
|
if (listeners.length === emitter.count) {
|
|
37539
37599
|
unload();
|
|
37540
|
-
|
|
37541
|
-
|
|
37600
|
+
emit2("exit", null, sig);
|
|
37601
|
+
emit2("afterexit", null, sig);
|
|
37542
37602
|
if (isWin && sig === "SIGHUP") {
|
|
37543
37603
|
sig = "SIGINT";
|
|
37544
37604
|
}
|
|
@@ -37575,8 +37635,8 @@ var require_signal_exit = __commonJS({
|
|
|
37575
37635
|
}
|
|
37576
37636
|
process2.exitCode = code || /* istanbul ignore next */
|
|
37577
37637
|
0;
|
|
37578
|
-
|
|
37579
|
-
|
|
37638
|
+
emit2("exit", process2.exitCode, null);
|
|
37639
|
+
emit2("afterexit", process2.exitCode, null);
|
|
37580
37640
|
originalProcessReallyExit.call(process2, process2.exitCode);
|
|
37581
37641
|
};
|
|
37582
37642
|
originalProcessEmit = process2.emit;
|
|
@@ -37586,8 +37646,8 @@ var require_signal_exit = __commonJS({
|
|
|
37586
37646
|
process2.exitCode = arg;
|
|
37587
37647
|
}
|
|
37588
37648
|
var ret = originalProcessEmit.apply(this, arguments);
|
|
37589
|
-
|
|
37590
|
-
|
|
37649
|
+
emit2("exit", process2.exitCode, null);
|
|
37650
|
+
emit2("afterexit", process2.exitCode, null);
|
|
37591
37651
|
return ret;
|
|
37592
37652
|
} else {
|
|
37593
37653
|
return originalProcessEmit.apply(this, arguments);
|
|
@@ -37600,7 +37660,7 @@ var require_signal_exit = __commonJS({
|
|
|
37600
37660
|
var EE;
|
|
37601
37661
|
var emitter;
|
|
37602
37662
|
var unload;
|
|
37603
|
-
var
|
|
37663
|
+
var emit2;
|
|
37604
37664
|
var sigListeners;
|
|
37605
37665
|
var loaded;
|
|
37606
37666
|
var load;
|
|
@@ -37615,7 +37675,7 @@ var require_signal_exit = __commonJS({
|
|
|
37615
37675
|
var require_kill = __commonJS({
|
|
37616
37676
|
"../../node_modules/execa/lib/kill.js"(exports2, module2) {
|
|
37617
37677
|
"use strict";
|
|
37618
|
-
var
|
|
37678
|
+
var os5 = require("os");
|
|
37619
37679
|
var onExit = require_signal_exit();
|
|
37620
37680
|
var DEFAULT_FORCE_KILL_TIMEOUT = 1e3 * 5;
|
|
37621
37681
|
var spawnedKill = (kill, signal = "SIGTERM", options = {}) => {
|
|
@@ -37639,7 +37699,7 @@ var require_kill = __commonJS({
|
|
|
37639
37699
|
return isSigterm(signal) && forceKillAfterTimeout !== false && killResult;
|
|
37640
37700
|
};
|
|
37641
37701
|
var isSigterm = (signal) => {
|
|
37642
|
-
return signal ===
|
|
37702
|
+
return signal === os5.constants.signals.SIGTERM || typeof signal === "string" && signal.toUpperCase() === "SIGTERM";
|
|
37643
37703
|
};
|
|
37644
37704
|
var getForceKillAfterTimeout = ({ forceKillAfterTimeout = true }) => {
|
|
37645
37705
|
if (forceKillAfterTimeout === true) {
|
|
@@ -38021,7 +38081,7 @@ var require_command = __commonJS({
|
|
|
38021
38081
|
var require_execa = __commonJS({
|
|
38022
38082
|
"../../node_modules/execa/index.js"(exports2, module2) {
|
|
38023
38083
|
"use strict";
|
|
38024
|
-
var
|
|
38084
|
+
var path4 = require("path");
|
|
38025
38085
|
var childProcess = require("child_process");
|
|
38026
38086
|
var crossSpawn = require_cross_spawn();
|
|
38027
38087
|
var stripFinalNewline = require_strip_final_newline();
|
|
@@ -38063,7 +38123,7 @@ var require_execa = __commonJS({
|
|
|
38063
38123
|
};
|
|
38064
38124
|
options.env = getEnv(options);
|
|
38065
38125
|
options.stdio = normalizeStdio(options);
|
|
38066
|
-
if (process.platform === "win32" &&
|
|
38126
|
+
if (process.platform === "win32" && path4.basename(file, ".exe") === "cmd") {
|
|
38067
38127
|
args.unshift("/q");
|
|
38068
38128
|
}
|
|
38069
38129
|
return { file, args, options, parsed };
|
|
@@ -38255,7 +38315,7 @@ var require_envpath = __commonJS({
|
|
|
38255
38315
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
38256
38316
|
var __getProtoOf2 = Object.getPrototypeOf;
|
|
38257
38317
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
38258
|
-
var
|
|
38318
|
+
var __export2 = (target, all) => {
|
|
38259
38319
|
for (var name in all)
|
|
38260
38320
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
38261
38321
|
};
|
|
@@ -38277,7 +38337,7 @@ var require_envpath = __commonJS({
|
|
|
38277
38337
|
));
|
|
38278
38338
|
var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
38279
38339
|
var envpath_exports = {};
|
|
38280
|
-
|
|
38340
|
+
__export2(envpath_exports, {
|
|
38281
38341
|
getEnvPath: () => getEnvPath,
|
|
38282
38342
|
prependPathEntries: () => prependPathEntries,
|
|
38283
38343
|
setEnvPath: () => setEnvPath,
|
|
@@ -38341,7 +38401,7 @@ var require_errutils = __commonJS({
|
|
|
38341
38401
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
38342
38402
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
38343
38403
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
38344
|
-
var
|
|
38404
|
+
var __export2 = (target, all) => {
|
|
38345
38405
|
for (var name in all)
|
|
38346
38406
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
38347
38407
|
};
|
|
@@ -38355,7 +38415,7 @@ var require_errutils = __commonJS({
|
|
|
38355
38415
|
};
|
|
38356
38416
|
var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
38357
38417
|
var errutils_exports = {};
|
|
38358
|
-
|
|
38418
|
+
__export2(errutils_exports, {
|
|
38359
38419
|
getErrorMessage: () => getErrorMessage,
|
|
38360
38420
|
isMissingPathError: () => isMissingPathError
|
|
38361
38421
|
});
|
|
@@ -38382,7 +38442,7 @@ var require_fsutils = __commonJS({
|
|
|
38382
38442
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
38383
38443
|
var __getProtoOf2 = Object.getPrototypeOf;
|
|
38384
38444
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
38385
|
-
var
|
|
38445
|
+
var __export2 = (target, all) => {
|
|
38386
38446
|
for (var name in all)
|
|
38387
38447
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
38388
38448
|
};
|
|
@@ -38404,7 +38464,7 @@ var require_fsutils = __commonJS({
|
|
|
38404
38464
|
));
|
|
38405
38465
|
var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
38406
38466
|
var fsutils_exports = {};
|
|
38407
|
-
|
|
38467
|
+
__export2(fsutils_exports, {
|
|
38408
38468
|
getCanonicalPath: () => getCanonicalPath,
|
|
38409
38469
|
getCommandBase: () => getCommandBase,
|
|
38410
38470
|
getDirectoriesBetween: () => getDirectoriesBetween,
|
|
@@ -38476,7 +38536,7 @@ var require_safety = __commonJS({
|
|
|
38476
38536
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
38477
38537
|
var __getProtoOf2 = Object.getPrototypeOf;
|
|
38478
38538
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
38479
|
-
var
|
|
38539
|
+
var __export2 = (target, all) => {
|
|
38480
38540
|
for (var name in all)
|
|
38481
38541
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
38482
38542
|
};
|
|
@@ -38498,7 +38558,7 @@ var require_safety = __commonJS({
|
|
|
38498
38558
|
));
|
|
38499
38559
|
var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
38500
38560
|
var safety_exports = {};
|
|
38501
|
-
|
|
38561
|
+
__export2(safety_exports, {
|
|
38502
38562
|
getSkippedNodeModulesReason: () => getSkippedNodeModulesReason,
|
|
38503
38563
|
getUnsafeDirectoryReason: () => getUnsafeDirectoryReason,
|
|
38504
38564
|
getUnsafePackageBinReason: () => getUnsafePackageBinReason,
|
|
@@ -38644,7 +38704,7 @@ var require_lookup = __commonJS({
|
|
|
38644
38704
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
38645
38705
|
var __getProtoOf2 = Object.getPrototypeOf;
|
|
38646
38706
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
38647
|
-
var
|
|
38707
|
+
var __export2 = (target, all) => {
|
|
38648
38708
|
for (var name in all)
|
|
38649
38709
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
38650
38710
|
};
|
|
@@ -38666,7 +38726,7 @@ var require_lookup = __commonJS({
|
|
|
38666
38726
|
));
|
|
38667
38727
|
var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
38668
38728
|
var lookup_exports = {};
|
|
38669
|
-
|
|
38729
|
+
__export2(lookup_exports, {
|
|
38670
38730
|
clearCachedCliInvocation: () => clearCachedCliInvocation,
|
|
38671
38731
|
clearVercelCliLookupCache: () => clearVercelCliLookupCache2,
|
|
38672
38732
|
findVercelCli: () => findVercelCli2,
|
|
@@ -39112,7 +39172,7 @@ var require_exec = __commonJS({
|
|
|
39112
39172
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
39113
39173
|
var __getProtoOf2 = Object.getPrototypeOf;
|
|
39114
39174
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
39115
|
-
var
|
|
39175
|
+
var __export2 = (target, all) => {
|
|
39116
39176
|
for (var name in all)
|
|
39117
39177
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
39118
39178
|
};
|
|
@@ -39134,7 +39194,7 @@ var require_exec = __commonJS({
|
|
|
39134
39194
|
));
|
|
39135
39195
|
var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
39136
39196
|
var exec_exports = {};
|
|
39137
|
-
|
|
39197
|
+
__export2(exec_exports, {
|
|
39138
39198
|
execVercelCli: () => execVercelCli2
|
|
39139
39199
|
});
|
|
39140
39200
|
module2.exports = __toCommonJS(exec_exports);
|
|
@@ -39225,7 +39285,7 @@ var require_dist2 = __commonJS({
|
|
|
39225
39285
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
39226
39286
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
39227
39287
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
39228
|
-
var
|
|
39288
|
+
var __export2 = (target, all) => {
|
|
39229
39289
|
for (var name in all)
|
|
39230
39290
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
39231
39291
|
};
|
|
@@ -39239,7 +39299,7 @@ var require_dist2 = __commonJS({
|
|
|
39239
39299
|
};
|
|
39240
39300
|
var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
39241
39301
|
var src_exports = {};
|
|
39242
|
-
|
|
39302
|
+
__export2(src_exports, {
|
|
39243
39303
|
VercelCliError: () => import_errors.VercelCliError,
|
|
39244
39304
|
clearVercelCliLookupCache: () => import_lookup.clearVercelCliLookupCache,
|
|
39245
39305
|
execVercelCli: () => import_exec.execVercelCli,
|
|
@@ -39509,10 +39569,10 @@ var require_util = __commonJS({
|
|
|
39509
39569
|
function cloneDef(schema) {
|
|
39510
39570
|
return mergeDefs(schema._zod.def);
|
|
39511
39571
|
}
|
|
39512
|
-
function getElementAtPath(obj,
|
|
39513
|
-
if (!
|
|
39572
|
+
function getElementAtPath(obj, path4) {
|
|
39573
|
+
if (!path4)
|
|
39514
39574
|
return obj;
|
|
39515
|
-
return
|
|
39575
|
+
return path4.reduce((acc, key) => acc?.[key], obj);
|
|
39516
39576
|
}
|
|
39517
39577
|
function promiseAllObject(promisesObj) {
|
|
39518
39578
|
const keys = Object.keys(promisesObj);
|
|
@@ -39874,11 +39934,11 @@ var require_util = __commonJS({
|
|
|
39874
39934
|
}
|
|
39875
39935
|
return false;
|
|
39876
39936
|
}
|
|
39877
|
-
function prefixIssues(
|
|
39937
|
+
function prefixIssues(path4, issues) {
|
|
39878
39938
|
return issues.map((iss) => {
|
|
39879
39939
|
var _a;
|
|
39880
39940
|
(_a = iss).path ?? (_a.path = []);
|
|
39881
|
-
iss.path.unshift(
|
|
39941
|
+
iss.path.unshift(path4);
|
|
39882
39942
|
return iss;
|
|
39883
39943
|
});
|
|
39884
39944
|
}
|
|
@@ -40088,7 +40148,7 @@ var require_errors2 = __commonJS({
|
|
|
40088
40148
|
return issue.message;
|
|
40089
40149
|
};
|
|
40090
40150
|
const result = { errors: [] };
|
|
40091
|
-
const processError = (error2,
|
|
40151
|
+
const processError = (error2, path4 = []) => {
|
|
40092
40152
|
var _a, _b;
|
|
40093
40153
|
for (const issue of error2.issues) {
|
|
40094
40154
|
if (issue.code === "invalid_union" && issue.errors.length) {
|
|
@@ -40098,7 +40158,7 @@ var require_errors2 = __commonJS({
|
|
|
40098
40158
|
} else if (issue.code === "invalid_element") {
|
|
40099
40159
|
processError({ issues: issue.issues }, issue.path);
|
|
40100
40160
|
} else {
|
|
40101
|
-
const fullpath = [...
|
|
40161
|
+
const fullpath = [...path4, ...issue.path];
|
|
40102
40162
|
if (fullpath.length === 0) {
|
|
40103
40163
|
result.errors.push(mapper(issue));
|
|
40104
40164
|
continue;
|
|
@@ -40130,8 +40190,8 @@ var require_errors2 = __commonJS({
|
|
|
40130
40190
|
}
|
|
40131
40191
|
function toDotPath(_path) {
|
|
40132
40192
|
const segs = [];
|
|
40133
|
-
const
|
|
40134
|
-
for (const seg of
|
|
40193
|
+
const path4 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
40194
|
+
for (const seg of path4) {
|
|
40135
40195
|
if (typeof seg === "number")
|
|
40136
40196
|
segs.push(`[${seg}]`);
|
|
40137
40197
|
else if (typeof seg === "symbol")
|
|
@@ -53975,27 +54035,27 @@ var require_schema = __commonJS({
|
|
|
53975
54035
|
var require_lib5 = __commonJS({
|
|
53976
54036
|
"../../node_modules/os-paths/src/lib/index.js"(exports2, module2) {
|
|
53977
54037
|
"use strict";
|
|
53978
|
-
var
|
|
54038
|
+
var os5 = require("os");
|
|
53979
54039
|
var paths = require("path");
|
|
53980
54040
|
var isWinOS = /^win/i.test(process.platform);
|
|
53981
|
-
function normalize_path(
|
|
53982
|
-
return paths.normalize(paths.join(
|
|
54041
|
+
function normalize_path(path4) {
|
|
54042
|
+
return paths.normalize(paths.join(path4, "."));
|
|
53983
54043
|
}
|
|
53984
54044
|
var base = () => {
|
|
53985
54045
|
const { env } = process;
|
|
53986
54046
|
const object = {};
|
|
53987
|
-
object.home = () => normalize_path(
|
|
53988
|
-
object.temp = () => normalize_path(
|
|
54047
|
+
object.home = () => normalize_path(os5.homedir ? os5.homedir() : env.HOME);
|
|
54048
|
+
object.temp = () => normalize_path(os5.tmpdir ? os5.tmpdir() : env.TMPDIR || env.TEMP || env.TMP);
|
|
53989
54049
|
return object;
|
|
53990
54050
|
};
|
|
53991
54051
|
var windows = () => {
|
|
53992
54052
|
const { env } = process;
|
|
53993
54053
|
const object = {};
|
|
53994
54054
|
object.home = () => normalize_path(
|
|
53995
|
-
|
|
54055
|
+
os5.homedir ? os5.homedir() : env.USERPROFILE || paths.join(env.HOMEDRIVE, env.HOMEPATH) || env.HOME
|
|
53996
54056
|
);
|
|
53997
54057
|
object.temp = () => normalize_path(
|
|
53998
|
-
|
|
54058
|
+
os5.tmpdir ? os5.tmpdir() : env.TEMP || env.TMP || paths.join(env.LOCALAPPDATA || env.SystemRoot || env.windir, "Temp")
|
|
53999
54059
|
);
|
|
54000
54060
|
return object;
|
|
54001
54061
|
};
|
|
@@ -54020,44 +54080,44 @@ var require_lib5 = __commonJS({
|
|
|
54020
54080
|
var require_lib6 = __commonJS({
|
|
54021
54081
|
"../../node_modules/xdg-portable/src/lib/index.js"(exports2, module2) {
|
|
54022
54082
|
"use strict";
|
|
54023
|
-
var
|
|
54083
|
+
var path4 = require("path");
|
|
54024
54084
|
var osPaths = require_lib5();
|
|
54025
54085
|
var linux = () => {
|
|
54026
54086
|
const object = {};
|
|
54027
|
-
object.cache = () => process.env.XDG_CACHE_HOME ||
|
|
54028
|
-
object.config = () => process.env.XDG_CONFIG_HOME ||
|
|
54029
|
-
object.data = () => process.env.XDG_DATA_HOME ||
|
|
54087
|
+
object.cache = () => process.env.XDG_CACHE_HOME || path4.join(osPaths.home() || osPaths.temp(), ".cache");
|
|
54088
|
+
object.config = () => process.env.XDG_CONFIG_HOME || path4.join(osPaths.home() || osPaths.temp(), ".config");
|
|
54089
|
+
object.data = () => process.env.XDG_DATA_HOME || path4.join(osPaths.home() || osPaths.temp(), ".local", "share");
|
|
54030
54090
|
object.runtime = () => process.env.XDG_RUNTIME_DIR || void 0;
|
|
54031
|
-
object.state = () => process.env.XDG_STATE_HOME ||
|
|
54091
|
+
object.state = () => process.env.XDG_STATE_HOME || path4.join(osPaths.home() || osPaths.temp(), ".local", "state");
|
|
54032
54092
|
return object;
|
|
54033
54093
|
};
|
|
54034
54094
|
var macos = () => {
|
|
54035
54095
|
const object = {};
|
|
54036
|
-
object.cache = () => process.env.XDG_CACHE_HOME ||
|
|
54037
|
-
object.config = () => process.env.XDG_CONFIG_HOME ||
|
|
54038
|
-
object.data = () => process.env.XDG_DATA_HOME ||
|
|
54096
|
+
object.cache = () => process.env.XDG_CACHE_HOME || path4.join(path4.join(osPaths.home() || osPaths.temp(), "Library"), "Caches");
|
|
54097
|
+
object.config = () => process.env.XDG_CONFIG_HOME || path4.join(path4.join(osPaths.home() || osPaths.temp(), "Library"), "Preferences");
|
|
54098
|
+
object.data = () => process.env.XDG_DATA_HOME || path4.join(path4.join(osPaths.home() || osPaths.temp(), "Library"), "Application Support");
|
|
54039
54099
|
object.runtime = () => process.env.XDG_RUNTIME_DIR || void 0;
|
|
54040
|
-
object.state = () => process.env.XDG_STATE_HOME ||
|
|
54100
|
+
object.state = () => process.env.XDG_STATE_HOME || path4.join(path4.join(osPaths.home() || osPaths.temp(), "Library"), "State");
|
|
54041
54101
|
return object;
|
|
54042
54102
|
};
|
|
54043
54103
|
var windows = () => {
|
|
54044
54104
|
const object = {};
|
|
54045
54105
|
object.cache = () => {
|
|
54046
|
-
const localAppData = process.env.LOCALAPPDATA ||
|
|
54047
|
-
return process.env.XDG_CACHE_HOME ||
|
|
54106
|
+
const localAppData = process.env.LOCALAPPDATA || path4.join(osPaths.home() || osPaths.temp(), "AppData", "Local");
|
|
54107
|
+
return process.env.XDG_CACHE_HOME || path4.join(localAppData, "xdg.cache");
|
|
54048
54108
|
};
|
|
54049
54109
|
object.config = () => {
|
|
54050
|
-
const appData = process.env.APPDATA ||
|
|
54051
|
-
return process.env.XDG_CONFIG_HOME ||
|
|
54110
|
+
const appData = process.env.APPDATA || path4.join(osPaths.home() || osPaths.temp(), "AppData", "Roaming");
|
|
54111
|
+
return process.env.XDG_CONFIG_HOME || path4.join(appData, "xdg.config");
|
|
54052
54112
|
};
|
|
54053
54113
|
object.data = () => {
|
|
54054
|
-
const appData = process.env.APPDATA ||
|
|
54055
|
-
return process.env.XDG_DATA_HOME ||
|
|
54114
|
+
const appData = process.env.APPDATA || path4.join(osPaths.home() || osPaths.temp(), "AppData", "Roaming");
|
|
54115
|
+
return process.env.XDG_DATA_HOME || path4.join(appData, "xdg.data");
|
|
54056
54116
|
};
|
|
54057
54117
|
object.runtime = () => process.env.XDG_RUNTIME_DIR || void 0;
|
|
54058
54118
|
object.state = () => {
|
|
54059
|
-
const localAppData = process.env.LOCALAPPDATA ||
|
|
54060
|
-
return process.env.XDG_STATE_HOME ||
|
|
54119
|
+
const localAppData = process.env.LOCALAPPDATA || path4.join(osPaths.home() || osPaths.temp(), "AppData", "Local");
|
|
54120
|
+
return process.env.XDG_STATE_HOME || path4.join(localAppData, "xdg.state");
|
|
54061
54121
|
};
|
|
54062
54122
|
return object;
|
|
54063
54123
|
};
|
|
@@ -54077,7 +54137,7 @@ var require_lib6 = __commonJS({
|
|
|
54077
54137
|
const dirs = [];
|
|
54078
54138
|
dirs.push(extension.config());
|
|
54079
54139
|
if (process.env.XDG_CONFIG_DIRS) {
|
|
54080
|
-
dirs.push(...process.env.XDG_CONFIG_DIRS.split(
|
|
54140
|
+
dirs.push(...process.env.XDG_CONFIG_DIRS.split(path4.delimiter));
|
|
54081
54141
|
}
|
|
54082
54142
|
return dirs;
|
|
54083
54143
|
};
|
|
@@ -54085,7 +54145,7 @@ var require_lib6 = __commonJS({
|
|
|
54085
54145
|
const dirs = [];
|
|
54086
54146
|
dirs.push(extension.data());
|
|
54087
54147
|
if (process.env.XDG_DATA_DIRS) {
|
|
54088
|
-
dirs.push(...process.env.XDG_DATA_DIRS.split(
|
|
54148
|
+
dirs.push(...process.env.XDG_DATA_DIRS.split(path4.delimiter));
|
|
54089
54149
|
}
|
|
54090
54150
|
return dirs;
|
|
54091
54151
|
};
|
|
@@ -54102,7 +54162,7 @@ var require_lib6 = __commonJS({
|
|
|
54102
54162
|
var require_lib7 = __commonJS({
|
|
54103
54163
|
"../../node_modules/xdg-app-paths/src/lib/index.js"(exports2, module2) {
|
|
54104
54164
|
"use strict";
|
|
54105
|
-
var
|
|
54165
|
+
var path4 = require("path");
|
|
54106
54166
|
var xdg = require_lib6();
|
|
54107
54167
|
function normalizeOptions_(options, isolated) {
|
|
54108
54168
|
if (!isObject(options)) {
|
|
@@ -54154,38 +54214,38 @@ var require_lib7 = __commonJS({
|
|
|
54154
54214
|
throw new TypeError(`Expected string for "name" argument, got ${typeOf(name_)}`);
|
|
54155
54215
|
}
|
|
54156
54216
|
if (!name_) {
|
|
54157
|
-
name_ =
|
|
54217
|
+
name_ = path4.parse(require.main && require.main.filename || process.execPath).name;
|
|
54158
54218
|
}
|
|
54159
54219
|
name_ += suffix_ || "";
|
|
54160
54220
|
XDGAppPaths.$name = () => name_;
|
|
54161
54221
|
XDGAppPaths.$isolated = () => isolated_;
|
|
54162
54222
|
XDGAppPaths.cache = (dirOptions = null) => {
|
|
54163
54223
|
dirOptions = normalizeOptions_(dirOptions, isolated_);
|
|
54164
|
-
return
|
|
54224
|
+
return path4.join(xdg.cache(), dirOptions.isolated ? name_ : "");
|
|
54165
54225
|
};
|
|
54166
54226
|
XDGAppPaths.config = function(dirOptions = null) {
|
|
54167
54227
|
dirOptions = normalizeOptions_(dirOptions, isolated_);
|
|
54168
|
-
return
|
|
54228
|
+
return path4.join(xdg.config(), dirOptions.isolated ? name_ : "");
|
|
54169
54229
|
};
|
|
54170
54230
|
XDGAppPaths.data = function(dirOptions = null) {
|
|
54171
54231
|
dirOptions = normalizeOptions_(dirOptions, isolated_);
|
|
54172
|
-
return
|
|
54232
|
+
return path4.join(xdg.data(), dirOptions.isolated ? name_ : "");
|
|
54173
54233
|
};
|
|
54174
54234
|
XDGAppPaths.runtime = function(dirOptions = null) {
|
|
54175
54235
|
dirOptions = normalizeOptions_(dirOptions, isolated_);
|
|
54176
|
-
return xdg.runtime() ?
|
|
54236
|
+
return xdg.runtime() ? path4.join(xdg.runtime(), dirOptions.isolated ? name_ : "") : void 0;
|
|
54177
54237
|
};
|
|
54178
54238
|
XDGAppPaths.state = function(dirOptions = null) {
|
|
54179
54239
|
dirOptions = normalizeOptions_(dirOptions, isolated_);
|
|
54180
|
-
return
|
|
54240
|
+
return path4.join(xdg.state(), dirOptions.isolated ? name_ : "");
|
|
54181
54241
|
};
|
|
54182
54242
|
XDGAppPaths.configDirs = function(dirOptions = null) {
|
|
54183
54243
|
dirOptions = normalizeOptions_(dirOptions, isolated_);
|
|
54184
|
-
return xdg.configDirs().map((s) =>
|
|
54244
|
+
return xdg.configDirs().map((s) => path4.join(s, dirOptions.isolated ? name_ : ""));
|
|
54185
54245
|
};
|
|
54186
54246
|
XDGAppPaths.dataDirs = function(dirOptions = null) {
|
|
54187
54247
|
dirOptions = normalizeOptions_(dirOptions, isolated_);
|
|
54188
|
-
return xdg.dataDirs().map((s) =>
|
|
54248
|
+
return xdg.dataDirs().map((s) => path4.join(s, dirOptions.isolated ? name_ : ""));
|
|
54189
54249
|
};
|
|
54190
54250
|
this.fn = XDGAppPaths;
|
|
54191
54251
|
}
|
|
@@ -54479,7 +54539,7 @@ var require_token_io = __commonJS({
|
|
|
54479
54539
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
54480
54540
|
var __getProtoOf2 = Object.getPrototypeOf;
|
|
54481
54541
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
54482
|
-
var
|
|
54542
|
+
var __export2 = (target, all) => {
|
|
54483
54543
|
for (var name in all)
|
|
54484
54544
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
54485
54545
|
};
|
|
@@ -54501,24 +54561,24 @@ var require_token_io = __commonJS({
|
|
|
54501
54561
|
));
|
|
54502
54562
|
var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
54503
54563
|
var token_io_exports = {};
|
|
54504
|
-
|
|
54564
|
+
__export2(token_io_exports, {
|
|
54505
54565
|
findRootDir: () => findRootDir,
|
|
54506
54566
|
getUserDataDir: () => getUserDataDir
|
|
54507
54567
|
});
|
|
54508
54568
|
module2.exports = __toCommonJS(token_io_exports);
|
|
54509
|
-
var
|
|
54510
|
-
var
|
|
54511
|
-
var
|
|
54569
|
+
var import_path4 = __toESM2(require("path"));
|
|
54570
|
+
var import_fs4 = __toESM2(require("fs"));
|
|
54571
|
+
var import_os5 = __toESM2(require("os"));
|
|
54512
54572
|
var import_token_error = require_token_error();
|
|
54513
54573
|
function findRootDir() {
|
|
54514
54574
|
try {
|
|
54515
54575
|
let dir = process.cwd();
|
|
54516
|
-
while (dir !==
|
|
54517
|
-
const pkgPath =
|
|
54518
|
-
if (
|
|
54576
|
+
while (dir !== import_path4.default.dirname(dir)) {
|
|
54577
|
+
const pkgPath = import_path4.default.join(dir, ".vercel");
|
|
54578
|
+
if (import_fs4.default.existsSync(pkgPath)) {
|
|
54519
54579
|
return dir;
|
|
54520
54580
|
}
|
|
54521
|
-
dir =
|
|
54581
|
+
dir = import_path4.default.dirname(dir);
|
|
54522
54582
|
}
|
|
54523
54583
|
} catch (_e) {
|
|
54524
54584
|
throw new import_token_error.VercelOidcTokenError(
|
|
@@ -54531,11 +54591,11 @@ var require_token_io = __commonJS({
|
|
|
54531
54591
|
if (process.env.XDG_DATA_HOME) {
|
|
54532
54592
|
return process.env.XDG_DATA_HOME;
|
|
54533
54593
|
}
|
|
54534
|
-
switch (
|
|
54594
|
+
switch (import_os5.default.platform()) {
|
|
54535
54595
|
case "darwin":
|
|
54536
|
-
return
|
|
54596
|
+
return import_path4.default.join(import_os5.default.homedir(), "Library/Application Support");
|
|
54537
54597
|
case "linux":
|
|
54538
|
-
return
|
|
54598
|
+
return import_path4.default.join(import_os5.default.homedir(), ".local/share");
|
|
54539
54599
|
case "win32":
|
|
54540
54600
|
if (process.env.LOCALAPPDATA) {
|
|
54541
54601
|
return process.env.LOCALAPPDATA;
|
|
@@ -54556,7 +54616,7 @@ var require_oauth = __commonJS({
|
|
|
54556
54616
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
54557
54617
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
54558
54618
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
54559
|
-
var
|
|
54619
|
+
var __export2 = (target, all) => {
|
|
54560
54620
|
for (var name in all)
|
|
54561
54621
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
54562
54622
|
};
|
|
@@ -54570,15 +54630,15 @@ var require_oauth = __commonJS({
|
|
|
54570
54630
|
};
|
|
54571
54631
|
var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
54572
54632
|
var oauth_exports = {};
|
|
54573
|
-
|
|
54633
|
+
__export2(oauth_exports, {
|
|
54574
54634
|
processTokenResponse: () => processTokenResponse,
|
|
54575
54635
|
refreshTokenRequest: () => refreshTokenRequest
|
|
54576
54636
|
});
|
|
54577
54637
|
module2.exports = __toCommonJS(oauth_exports);
|
|
54578
|
-
var
|
|
54638
|
+
var import_os5 = require("os");
|
|
54579
54639
|
var VERCEL_ISSUER = "https://vercel.com";
|
|
54580
54640
|
var VERCEL_CLI_CLIENT_ID = "cl_HYyOPBNtFMfHhaUn9L4QPfTZz6TP47bp";
|
|
54581
|
-
var userAgent = `@vercel/oidc node-${process.version} ${(0,
|
|
54641
|
+
var userAgent = `@vercel/oidc node-${process.version} ${(0, import_os5.platform)()} (${(0, import_os5.arch)()}) ${(0, import_os5.hostname)()}`;
|
|
54582
54642
|
var _tokenEndpoint = null;
|
|
54583
54643
|
async function getTokenEndpoint() {
|
|
54584
54644
|
if (_tokenEndpoint) {
|
|
@@ -54645,7 +54705,7 @@ var require_auth_errors = __commonJS({
|
|
|
54645
54705
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
54646
54706
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
54647
54707
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
54648
|
-
var
|
|
54708
|
+
var __export2 = (target, all) => {
|
|
54649
54709
|
for (var name in all)
|
|
54650
54710
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
54651
54711
|
};
|
|
@@ -54659,7 +54719,7 @@ var require_auth_errors = __commonJS({
|
|
|
54659
54719
|
};
|
|
54660
54720
|
var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
54661
54721
|
var auth_errors_exports = {};
|
|
54662
|
-
|
|
54722
|
+
__export2(auth_errors_exports, {
|
|
54663
54723
|
AccessTokenMissingError: () => AccessTokenMissingError2,
|
|
54664
54724
|
RefreshAccessTokenFailedError: () => RefreshAccessTokenFailedError2
|
|
54665
54725
|
});
|
|
@@ -54694,7 +54754,7 @@ var require_token_util = __commonJS({
|
|
|
54694
54754
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
54695
54755
|
var __getProtoOf2 = Object.getPrototypeOf;
|
|
54696
54756
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
54697
|
-
var
|
|
54757
|
+
var __export2 = (target, all) => {
|
|
54698
54758
|
for (var name in all)
|
|
54699
54759
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
54700
54760
|
};
|
|
@@ -54716,7 +54776,7 @@ var require_token_util = __commonJS({
|
|
|
54716
54776
|
));
|
|
54717
54777
|
var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
54718
54778
|
var token_util_exports = {};
|
|
54719
|
-
|
|
54779
|
+
__export2(token_util_exports, {
|
|
54720
54780
|
assertVercelOidcTokenResponse: () => assertVercelOidcTokenResponse,
|
|
54721
54781
|
findProjectInfo: () => findProjectInfo,
|
|
54722
54782
|
getTokenPayload: () => getTokenPayload,
|
|
@@ -54728,8 +54788,8 @@ var require_token_util = __commonJS({
|
|
|
54728
54788
|
saveToken: () => saveToken
|
|
54729
54789
|
});
|
|
54730
54790
|
module2.exports = __toCommonJS(token_util_exports);
|
|
54731
|
-
var
|
|
54732
|
-
var
|
|
54791
|
+
var path4 = __toESM2(require("path"));
|
|
54792
|
+
var fs4 = __toESM2(require("fs"));
|
|
54733
54793
|
var import_cli_exec = require_dist2();
|
|
54734
54794
|
var import_cli_config = require_dist3();
|
|
54735
54795
|
var import_token_error = require_token_error();
|
|
@@ -54853,13 +54913,13 @@ ${stderr}`.trim();
|
|
|
54853
54913
|
"Unable to find project root directory. Have you linked your project with `vc link?`"
|
|
54854
54914
|
);
|
|
54855
54915
|
}
|
|
54856
|
-
const prjPath =
|
|
54857
|
-
if (!
|
|
54916
|
+
const prjPath = path4.join(dir, ".vercel", "project.json");
|
|
54917
|
+
if (!fs4.existsSync(prjPath)) {
|
|
54858
54918
|
throw new import_token_error.VercelOidcTokenError(
|
|
54859
54919
|
"project.json not found, have you linked your project with `vc link?`"
|
|
54860
54920
|
);
|
|
54861
54921
|
}
|
|
54862
|
-
const prj = JSON.parse(
|
|
54922
|
+
const prj = JSON.parse(fs4.readFileSync(prjPath, "utf8"));
|
|
54863
54923
|
if (typeof prj.projectId !== "string" && typeof prj.orgId !== "string") {
|
|
54864
54924
|
throw new TypeError(
|
|
54865
54925
|
"Expected a string-valued projectId property. Try running `vc link` to re-link your project."
|
|
@@ -54874,11 +54934,11 @@ ${stderr}`.trim();
|
|
|
54874
54934
|
"Unable to find user data directory. Please reach out to Vercel support."
|
|
54875
54935
|
);
|
|
54876
54936
|
}
|
|
54877
|
-
const tokenPath =
|
|
54937
|
+
const tokenPath = path4.join(dir, "com.vercel.token", `${projectId}.json`);
|
|
54878
54938
|
const tokenJson = JSON.stringify(token);
|
|
54879
|
-
|
|
54880
|
-
|
|
54881
|
-
|
|
54939
|
+
fs4.mkdirSync(path4.dirname(tokenPath), { mode: 504, recursive: true });
|
|
54940
|
+
fs4.writeFileSync(tokenPath, tokenJson);
|
|
54941
|
+
fs4.chmodSync(tokenPath, 432);
|
|
54882
54942
|
return;
|
|
54883
54943
|
}
|
|
54884
54944
|
function loadToken(projectId) {
|
|
@@ -54888,11 +54948,11 @@ ${stderr}`.trim();
|
|
|
54888
54948
|
"Unable to find user data directory. Please reach out to Vercel support."
|
|
54889
54949
|
);
|
|
54890
54950
|
}
|
|
54891
|
-
const tokenPath =
|
|
54892
|
-
if (!
|
|
54951
|
+
const tokenPath = path4.join(dir, "com.vercel.token", `${projectId}.json`);
|
|
54952
|
+
if (!fs4.existsSync(tokenPath)) {
|
|
54893
54953
|
return null;
|
|
54894
54954
|
}
|
|
54895
|
-
const token = JSON.parse(
|
|
54955
|
+
const token = JSON.parse(fs4.readFileSync(tokenPath, "utf8"));
|
|
54896
54956
|
assertVercelOidcTokenResponse(token);
|
|
54897
54957
|
return token;
|
|
54898
54958
|
}
|
|
@@ -54922,7 +54982,7 @@ var require_token = __commonJS({
|
|
|
54922
54982
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
54923
54983
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
54924
54984
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
54925
|
-
var
|
|
54985
|
+
var __export2 = (target, all) => {
|
|
54926
54986
|
for (var name in all)
|
|
54927
54987
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
54928
54988
|
};
|
|
@@ -54936,7 +54996,7 @@ var require_token = __commonJS({
|
|
|
54936
54996
|
};
|
|
54937
54997
|
var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
54938
54998
|
var token_exports = {};
|
|
54939
|
-
|
|
54999
|
+
__export2(token_exports, {
|
|
54940
55000
|
refreshToken: () => refreshToken
|
|
54941
55001
|
});
|
|
54942
55002
|
module2.exports = __toCommonJS(token_exports);
|
|
@@ -54990,7 +55050,7 @@ var require_get_vercel_oidc_token_with_refresh = __commonJS({
|
|
|
54990
55050
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
54991
55051
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
54992
55052
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
54993
|
-
var
|
|
55053
|
+
var __export2 = (target, all) => {
|
|
54994
55054
|
for (var name in all)
|
|
54995
55055
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
54996
55056
|
};
|
|
@@ -55004,7 +55064,7 @@ var require_get_vercel_oidc_token_with_refresh = __commonJS({
|
|
|
55004
55064
|
};
|
|
55005
55065
|
var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
55006
55066
|
var get_vercel_oidc_token_with_refresh_exports = {};
|
|
55007
|
-
|
|
55067
|
+
__export2(get_vercel_oidc_token_with_refresh_exports, {
|
|
55008
55068
|
getVercelOidcToken: () => getVercelOidcToken2
|
|
55009
55069
|
});
|
|
55010
55070
|
module2.exports = __toCommonJS(get_vercel_oidc_token_with_refresh_exports);
|
|
@@ -59478,7 +59538,7 @@ var require_verify_vercel_oidc_token = __commonJS({
|
|
|
59478
59538
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
59479
59539
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
59480
59540
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
59481
|
-
var
|
|
59541
|
+
var __export2 = (target, all) => {
|
|
59482
59542
|
for (var name in all)
|
|
59483
59543
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
59484
59544
|
};
|
|
@@ -59492,7 +59552,7 @@ var require_verify_vercel_oidc_token = __commonJS({
|
|
|
59492
59552
|
};
|
|
59493
59553
|
var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
59494
59554
|
var verify_vercel_oidc_token_exports = {};
|
|
59495
|
-
|
|
59555
|
+
__export2(verify_vercel_oidc_token_exports, {
|
|
59496
59556
|
verifyVercelOidcToken: () => verifyVercelOidcToken2
|
|
59497
59557
|
});
|
|
59498
59558
|
module2.exports = __toCommonJS(verify_vercel_oidc_token_exports);
|
|
@@ -59601,7 +59661,7 @@ var require_dist4 = __commonJS({
|
|
|
59601
59661
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
59602
59662
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
59603
59663
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
59604
|
-
var
|
|
59664
|
+
var __export2 = (target, all) => {
|
|
59605
59665
|
for (var name in all)
|
|
59606
59666
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
59607
59667
|
};
|
|
@@ -59615,7 +59675,7 @@ var require_dist4 = __commonJS({
|
|
|
59615
59675
|
};
|
|
59616
59676
|
var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
59617
59677
|
var src_exports = {};
|
|
59618
|
-
|
|
59678
|
+
__export2(src_exports, {
|
|
59619
59679
|
AccessTokenMissingError: () => import_auth_errors.AccessTokenMissingError,
|
|
59620
59680
|
RefreshAccessTokenFailedError: () => import_auth_errors.RefreshAccessTokenFailedError,
|
|
59621
59681
|
exchangeVercelOidcToken: () => import_exchange_vercel_oidc_token.exchangeVercelOidcToken,
|
|
@@ -59869,7 +59929,7 @@ var require_lib8 = __commonJS({
|
|
|
59869
59929
|
"../../node_modules/async-retry/lib/index.js"(exports2, module2) {
|
|
59870
59930
|
var retrier = require_retry2();
|
|
59871
59931
|
function retry(fn, opts) {
|
|
59872
|
-
function
|
|
59932
|
+
function run2(resolve, reject) {
|
|
59873
59933
|
var options = opts || {};
|
|
59874
59934
|
var op;
|
|
59875
59935
|
if (!("randomize" in options)) {
|
|
@@ -59904,7 +59964,7 @@ var require_lib8 = __commonJS({
|
|
|
59904
59964
|
}
|
|
59905
59965
|
op.attempt(runAttempt);
|
|
59906
59966
|
}
|
|
59907
|
-
return new Promise(
|
|
59967
|
+
return new Promise(run2);
|
|
59908
59968
|
}
|
|
59909
59969
|
module2.exports = retry;
|
|
59910
59970
|
}
|
|
@@ -60712,14 +60772,14 @@ var require_util2 = __commonJS({
|
|
|
60712
60772
|
}
|
|
60713
60773
|
const port = url.port != null ? url.port : url.protocol === "https:" ? 443 : 80;
|
|
60714
60774
|
let origin = url.origin != null ? url.origin : `${url.protocol || ""}//${url.hostname || ""}:${port}`;
|
|
60715
|
-
let
|
|
60775
|
+
let path4 = url.path != null ? url.path : `${url.pathname || ""}${url.search || ""}`;
|
|
60716
60776
|
if (origin[origin.length - 1] === "/") {
|
|
60717
60777
|
origin = origin.slice(0, origin.length - 1);
|
|
60718
60778
|
}
|
|
60719
|
-
if (
|
|
60720
|
-
|
|
60779
|
+
if (path4 && path4[0] !== "/") {
|
|
60780
|
+
path4 = `/${path4}`;
|
|
60721
60781
|
}
|
|
60722
|
-
return new URL(`${origin}${
|
|
60782
|
+
return new URL(`${origin}${path4}`);
|
|
60723
60783
|
}
|
|
60724
60784
|
if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) {
|
|
60725
60785
|
throw new InvalidArgumentError("Invalid URL protocol: the URL must start with `http:` or `https:`.");
|
|
@@ -61170,39 +61230,39 @@ var require_diagnostics = __commonJS({
|
|
|
61170
61230
|
});
|
|
61171
61231
|
diagnosticsChannel.channel("undici:client:sendHeaders").subscribe((evt) => {
|
|
61172
61232
|
const {
|
|
61173
|
-
request: { method, path:
|
|
61233
|
+
request: { method, path: path4, origin }
|
|
61174
61234
|
} = evt;
|
|
61175
|
-
debuglog("sending request to %s %s/%s", method, origin,
|
|
61235
|
+
debuglog("sending request to %s %s/%s", method, origin, path4);
|
|
61176
61236
|
});
|
|
61177
61237
|
diagnosticsChannel.channel("undici:request:headers").subscribe((evt) => {
|
|
61178
61238
|
const {
|
|
61179
|
-
request: { method, path:
|
|
61239
|
+
request: { method, path: path4, origin },
|
|
61180
61240
|
response: { statusCode }
|
|
61181
61241
|
} = evt;
|
|
61182
61242
|
debuglog(
|
|
61183
61243
|
"received response to %s %s/%s - HTTP %d",
|
|
61184
61244
|
method,
|
|
61185
61245
|
origin,
|
|
61186
|
-
|
|
61246
|
+
path4,
|
|
61187
61247
|
statusCode
|
|
61188
61248
|
);
|
|
61189
61249
|
});
|
|
61190
61250
|
diagnosticsChannel.channel("undici:request:trailers").subscribe((evt) => {
|
|
61191
61251
|
const {
|
|
61192
|
-
request: { method, path:
|
|
61252
|
+
request: { method, path: path4, origin }
|
|
61193
61253
|
} = evt;
|
|
61194
|
-
debuglog("trailers received from %s %s/%s", method, origin,
|
|
61254
|
+
debuglog("trailers received from %s %s/%s", method, origin, path4);
|
|
61195
61255
|
});
|
|
61196
61256
|
diagnosticsChannel.channel("undici:request:error").subscribe((evt) => {
|
|
61197
61257
|
const {
|
|
61198
|
-
request: { method, path:
|
|
61258
|
+
request: { method, path: path4, origin },
|
|
61199
61259
|
error
|
|
61200
61260
|
} = evt;
|
|
61201
61261
|
debuglog(
|
|
61202
61262
|
"request to %s %s/%s errored - %s",
|
|
61203
61263
|
method,
|
|
61204
61264
|
origin,
|
|
61205
|
-
|
|
61265
|
+
path4,
|
|
61206
61266
|
error.message
|
|
61207
61267
|
);
|
|
61208
61268
|
});
|
|
@@ -61251,9 +61311,9 @@ var require_diagnostics = __commonJS({
|
|
|
61251
61311
|
});
|
|
61252
61312
|
diagnosticsChannel.channel("undici:client:sendHeaders").subscribe((evt) => {
|
|
61253
61313
|
const {
|
|
61254
|
-
request: { method, path:
|
|
61314
|
+
request: { method, path: path4, origin }
|
|
61255
61315
|
} = evt;
|
|
61256
|
-
debuglog("sending request to %s %s/%s", method, origin,
|
|
61316
|
+
debuglog("sending request to %s %s/%s", method, origin, path4);
|
|
61257
61317
|
});
|
|
61258
61318
|
}
|
|
61259
61319
|
diagnosticsChannel.channel("undici:websocket:open").subscribe((evt) => {
|
|
@@ -61316,7 +61376,7 @@ var require_request = __commonJS({
|
|
|
61316
61376
|
var kHandler = Symbol("handler");
|
|
61317
61377
|
var Request2 = class {
|
|
61318
61378
|
constructor(origin, {
|
|
61319
|
-
path:
|
|
61379
|
+
path: path4,
|
|
61320
61380
|
method,
|
|
61321
61381
|
body,
|
|
61322
61382
|
headers,
|
|
@@ -61331,11 +61391,11 @@ var require_request = __commonJS({
|
|
|
61331
61391
|
expectContinue,
|
|
61332
61392
|
servername
|
|
61333
61393
|
}, handler) {
|
|
61334
|
-
if (typeof
|
|
61394
|
+
if (typeof path4 !== "string") {
|
|
61335
61395
|
throw new InvalidArgumentError("path must be a string");
|
|
61336
|
-
} else if (
|
|
61396
|
+
} else if (path4[0] !== "/" && !(path4.startsWith("http://") || path4.startsWith("https://")) && method !== "CONNECT") {
|
|
61337
61397
|
throw new InvalidArgumentError("path must be an absolute URL or start with a slash");
|
|
61338
|
-
} else if (invalidPathRegex.test(
|
|
61398
|
+
} else if (invalidPathRegex.test(path4)) {
|
|
61339
61399
|
throw new InvalidArgumentError("invalid request path");
|
|
61340
61400
|
}
|
|
61341
61401
|
if (typeof method !== "string") {
|
|
@@ -61401,7 +61461,7 @@ var require_request = __commonJS({
|
|
|
61401
61461
|
this.completed = false;
|
|
61402
61462
|
this.aborted = false;
|
|
61403
61463
|
this.upgrade = upgrade || null;
|
|
61404
|
-
this.path = query ? buildURL(
|
|
61464
|
+
this.path = query ? buildURL(path4, query) : path4;
|
|
61405
61465
|
this.origin = origin;
|
|
61406
61466
|
this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent;
|
|
61407
61467
|
this.blocking = blocking == null ? false : blocking;
|
|
@@ -66023,7 +66083,7 @@ var require_client_h1 = __commonJS({
|
|
|
66023
66083
|
return method !== "GET" && method !== "HEAD" && method !== "OPTIONS" && method !== "TRACE" && method !== "CONNECT";
|
|
66024
66084
|
}
|
|
66025
66085
|
function writeH1(client, request) {
|
|
66026
|
-
const { method, path:
|
|
66086
|
+
const { method, path: path4, host, upgrade, blocking, reset } = request;
|
|
66027
66087
|
let { body, headers, contentLength } = request;
|
|
66028
66088
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH" || method === "QUERY" || method === "PROPFIND" || method === "PROPPATCH";
|
|
66029
66089
|
if (util.isFormDataLike(body)) {
|
|
@@ -66090,7 +66150,7 @@ var require_client_h1 = __commonJS({
|
|
|
66090
66150
|
if (blocking) {
|
|
66091
66151
|
socket[kBlocking] = true;
|
|
66092
66152
|
}
|
|
66093
|
-
let header = `${method} ${
|
|
66153
|
+
let header = `${method} ${path4} HTTP/1.1\r
|
|
66094
66154
|
`;
|
|
66095
66155
|
if (typeof host === "string") {
|
|
66096
66156
|
header += `host: ${host}\r
|
|
@@ -66616,7 +66676,7 @@ var require_client_h2 = __commonJS({
|
|
|
66616
66676
|
}
|
|
66617
66677
|
function writeH2(client, request) {
|
|
66618
66678
|
const session = client[kHTTP2Session];
|
|
66619
|
-
const { method, path:
|
|
66679
|
+
const { method, path: path4, host, upgrade, expectContinue, signal, headers: reqHeaders } = request;
|
|
66620
66680
|
let { body } = request;
|
|
66621
66681
|
if (upgrade) {
|
|
66622
66682
|
util.errorRequest(client, request, new Error("Upgrade not supported for H2"));
|
|
@@ -66683,7 +66743,7 @@ var require_client_h2 = __commonJS({
|
|
|
66683
66743
|
});
|
|
66684
66744
|
return true;
|
|
66685
66745
|
}
|
|
66686
|
-
headers[HTTP2_HEADER_PATH] =
|
|
66746
|
+
headers[HTTP2_HEADER_PATH] = path4;
|
|
66687
66747
|
headers[HTTP2_HEADER_SCHEME] = "https";
|
|
66688
66748
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
|
|
66689
66749
|
if (body && typeof body.read === "function") {
|
|
@@ -67036,9 +67096,9 @@ var require_redirect_handler = __commonJS({
|
|
|
67036
67096
|
return this.handler.onHeaders(statusCode, headers, resume, statusText);
|
|
67037
67097
|
}
|
|
67038
67098
|
const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
|
|
67039
|
-
const
|
|
67099
|
+
const path4 = search ? `${pathname}${search}` : pathname;
|
|
67040
67100
|
this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin);
|
|
67041
|
-
this.opts.path =
|
|
67101
|
+
this.opts.path = path4;
|
|
67042
67102
|
this.opts.origin = origin;
|
|
67043
67103
|
this.opts.maxRedirections = 0;
|
|
67044
67104
|
this.opts.query = null;
|
|
@@ -68273,10 +68333,10 @@ var require_proxy_agent = __commonJS({
|
|
|
68273
68333
|
};
|
|
68274
68334
|
const {
|
|
68275
68335
|
origin,
|
|
68276
|
-
path:
|
|
68336
|
+
path: path4 = "/",
|
|
68277
68337
|
headers = {}
|
|
68278
68338
|
} = opts;
|
|
68279
|
-
opts.path = origin +
|
|
68339
|
+
opts.path = origin + path4;
|
|
68280
68340
|
if (!("host" in headers) && !("Host" in headers)) {
|
|
68281
68341
|
const { host } = new URL2(origin);
|
|
68282
68342
|
headers.host = host;
|
|
@@ -70197,20 +70257,20 @@ var require_mock_utils = __commonJS({
|
|
|
70197
70257
|
}
|
|
70198
70258
|
return true;
|
|
70199
70259
|
}
|
|
70200
|
-
function safeUrl(
|
|
70201
|
-
if (typeof
|
|
70202
|
-
return
|
|
70260
|
+
function safeUrl(path4) {
|
|
70261
|
+
if (typeof path4 !== "string") {
|
|
70262
|
+
return path4;
|
|
70203
70263
|
}
|
|
70204
|
-
const pathSegments =
|
|
70264
|
+
const pathSegments = path4.split("?");
|
|
70205
70265
|
if (pathSegments.length !== 2) {
|
|
70206
|
-
return
|
|
70266
|
+
return path4;
|
|
70207
70267
|
}
|
|
70208
70268
|
const qp = new URLSearchParams(pathSegments.pop());
|
|
70209
70269
|
qp.sort();
|
|
70210
70270
|
return [...pathSegments, qp.toString()].join("?");
|
|
70211
70271
|
}
|
|
70212
|
-
function matchKey(mockDispatch2, { path:
|
|
70213
|
-
const pathMatch = matchValue(mockDispatch2.path,
|
|
70272
|
+
function matchKey(mockDispatch2, { path: path4, method, body, headers }) {
|
|
70273
|
+
const pathMatch = matchValue(mockDispatch2.path, path4);
|
|
70214
70274
|
const methodMatch = matchValue(mockDispatch2.method, method);
|
|
70215
70275
|
const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true;
|
|
70216
70276
|
const headersMatch = matchHeaders(mockDispatch2, headers);
|
|
@@ -70232,7 +70292,7 @@ var require_mock_utils = __commonJS({
|
|
|
70232
70292
|
function getMockDispatch(mockDispatches, key) {
|
|
70233
70293
|
const basePath = key.query ? buildURL(key.path, key.query) : key.path;
|
|
70234
70294
|
const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath;
|
|
70235
|
-
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path:
|
|
70295
|
+
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path4 }) => matchValue(safeUrl(path4), resolvedPath));
|
|
70236
70296
|
if (matchedMockDispatches.length === 0) {
|
|
70237
70297
|
throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
|
|
70238
70298
|
}
|
|
@@ -70270,9 +70330,9 @@ var require_mock_utils = __commonJS({
|
|
|
70270
70330
|
}
|
|
70271
70331
|
}
|
|
70272
70332
|
function buildKey(opts) {
|
|
70273
|
-
const { path:
|
|
70333
|
+
const { path: path4, method, body, headers, query } = opts;
|
|
70274
70334
|
return {
|
|
70275
|
-
path:
|
|
70335
|
+
path: path4,
|
|
70276
70336
|
method,
|
|
70277
70337
|
body,
|
|
70278
70338
|
headers,
|
|
@@ -70735,10 +70795,10 @@ var require_pending_interceptors_formatter = __commonJS({
|
|
|
70735
70795
|
}
|
|
70736
70796
|
format(pendingInterceptors) {
|
|
70737
70797
|
const withPrettyHeaders = pendingInterceptors.map(
|
|
70738
|
-
({ method, path:
|
|
70798
|
+
({ method, path: path4, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
|
|
70739
70799
|
Method: method,
|
|
70740
70800
|
Origin: origin,
|
|
70741
|
-
Path:
|
|
70801
|
+
Path: path4,
|
|
70742
70802
|
"Status code": statusCode,
|
|
70743
70803
|
Persistent: persist ? PERSISTENT : NOT_PERSISTENT,
|
|
70744
70804
|
Invocations: timesInvoked,
|
|
@@ -75619,9 +75679,9 @@ var require_util7 = __commonJS({
|
|
|
75619
75679
|
}
|
|
75620
75680
|
}
|
|
75621
75681
|
}
|
|
75622
|
-
function validateCookiePath(
|
|
75623
|
-
for (let i = 0; i <
|
|
75624
|
-
const code =
|
|
75682
|
+
function validateCookiePath(path4) {
|
|
75683
|
+
for (let i = 0; i < path4.length; ++i) {
|
|
75684
|
+
const code = path4.charCodeAt(i);
|
|
75625
75685
|
if (code < 32 || // exclude CTLs (0-31)
|
|
75626
75686
|
code === 127 || // DEL
|
|
75627
75687
|
code === 59) {
|
|
@@ -78314,11 +78374,11 @@ var require_undici = __commonJS({
|
|
|
78314
78374
|
if (typeof opts.path !== "string") {
|
|
78315
78375
|
throw new InvalidArgumentError("invalid opts.path");
|
|
78316
78376
|
}
|
|
78317
|
-
let
|
|
78377
|
+
let path4 = opts.path;
|
|
78318
78378
|
if (!opts.path.startsWith("/")) {
|
|
78319
|
-
|
|
78379
|
+
path4 = `/${path4}`;
|
|
78320
78380
|
}
|
|
78321
|
-
url = new URL(util.parseOrigin(url).origin +
|
|
78381
|
+
url = new URL(util.parseOrigin(url).origin + path4);
|
|
78322
78382
|
} else {
|
|
78323
78383
|
if (!opts) {
|
|
78324
78384
|
opts = typeof url === "object" ? url : {};
|
|
@@ -80902,8 +80962,8 @@ var require_builder = __commonJS({
|
|
|
80902
80962
|
var db_1 = require_db();
|
|
80903
80963
|
var llm_1 = require_llm();
|
|
80904
80964
|
var qa_1 = require_qa();
|
|
80905
|
-
var
|
|
80906
|
-
var
|
|
80965
|
+
var fs4 = __importStar(require("fs"));
|
|
80966
|
+
var path4 = __importStar(require("path"));
|
|
80907
80967
|
var models_1 = require_models();
|
|
80908
80968
|
var cms_template_1 = require_cms_template();
|
|
80909
80969
|
var vercel_domains_1 = require_vercel_domains();
|
|
@@ -81027,44 +81087,44 @@ var require_builder = __commonJS({
|
|
|
81027
81087
|
</div>`;
|
|
81028
81088
|
}
|
|
81029
81089
|
function snapshotDir(leadId) {
|
|
81030
|
-
return
|
|
81090
|
+
return path4.join((0, runtime_1.userDataDir)(), "data", "sites", String(leadId));
|
|
81031
81091
|
}
|
|
81032
81092
|
function saveSnapshot(leadId, files) {
|
|
81033
81093
|
const dir = snapshotDir(leadId);
|
|
81034
81094
|
try {
|
|
81035
|
-
|
|
81095
|
+
fs4.mkdirSync(dir, { recursive: true });
|
|
81036
81096
|
for (const f of files) {
|
|
81037
|
-
const target =
|
|
81038
|
-
|
|
81097
|
+
const target = path4.join(dir, f.file);
|
|
81098
|
+
fs4.mkdirSync(path4.dirname(target), { recursive: true });
|
|
81039
81099
|
if (f.encoding === "base64") {
|
|
81040
|
-
|
|
81100
|
+
fs4.writeFileSync(target, Buffer.from(f.data, "base64"));
|
|
81041
81101
|
} else {
|
|
81042
|
-
|
|
81102
|
+
fs4.writeFileSync(target, f.data, "utf-8");
|
|
81043
81103
|
}
|
|
81044
81104
|
}
|
|
81045
|
-
|
|
81105
|
+
fs4.writeFileSync(path4.join(dir, ".snapshot.json"), JSON.stringify({ savedAt: Date.now() }));
|
|
81046
81106
|
} catch {
|
|
81047
81107
|
}
|
|
81048
81108
|
}
|
|
81049
81109
|
function loadSnapshot(leadId) {
|
|
81050
81110
|
const dir = snapshotDir(leadId);
|
|
81051
|
-
if (!
|
|
81111
|
+
if (!fs4.existsSync(dir))
|
|
81052
81112
|
return null;
|
|
81053
81113
|
const out = [];
|
|
81054
81114
|
function walk(rel) {
|
|
81055
|
-
const abs =
|
|
81056
|
-
const stat =
|
|
81115
|
+
const abs = path4.join(dir, rel);
|
|
81116
|
+
const stat = fs4.statSync(abs);
|
|
81057
81117
|
if (stat.isDirectory()) {
|
|
81058
|
-
for (const child of
|
|
81118
|
+
for (const child of fs4.readdirSync(abs)) {
|
|
81059
81119
|
if (child.startsWith("."))
|
|
81060
81120
|
continue;
|
|
81061
81121
|
walk(rel ? `${rel}/${child}` : child);
|
|
81062
81122
|
}
|
|
81063
81123
|
} else if (stat.isFile()) {
|
|
81064
81124
|
if (/\.(jpg|jpeg|png|gif|webp|avif)$/i.test(rel)) {
|
|
81065
|
-
out.push({ file: rel, data:
|
|
81125
|
+
out.push({ file: rel, data: fs4.readFileSync(abs).toString("base64"), encoding: "base64" });
|
|
81066
81126
|
} else {
|
|
81067
|
-
out.push({ file: rel, data:
|
|
81127
|
+
out.push({ file: rel, data: fs4.readFileSync(abs, "utf-8"), encoding: "utf-8" });
|
|
81068
81128
|
}
|
|
81069
81129
|
}
|
|
81070
81130
|
}
|
|
@@ -82790,6 +82850,389 @@ var require_booking_detect = __commonJS({
|
|
|
82790
82850
|
}
|
|
82791
82851
|
});
|
|
82792
82852
|
|
|
82853
|
+
// ../desktop/dist/main/lib/site-audit.js
|
|
82854
|
+
var require_site_audit = __commonJS({
|
|
82855
|
+
"../desktop/dist/main/lib/site-audit.js"(exports2) {
|
|
82856
|
+
"use strict";
|
|
82857
|
+
var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
82858
|
+
if (k2 === void 0) k2 = k;
|
|
82859
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
82860
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
82861
|
+
desc = { enumerable: true, get: function() {
|
|
82862
|
+
return m[k];
|
|
82863
|
+
} };
|
|
82864
|
+
}
|
|
82865
|
+
Object.defineProperty(o, k2, desc);
|
|
82866
|
+
}) : (function(o, m, k, k2) {
|
|
82867
|
+
if (k2 === void 0) k2 = k;
|
|
82868
|
+
o[k2] = m[k];
|
|
82869
|
+
}));
|
|
82870
|
+
var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) {
|
|
82871
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
82872
|
+
}) : function(o, v) {
|
|
82873
|
+
o["default"] = v;
|
|
82874
|
+
});
|
|
82875
|
+
var __importStar = exports2 && exports2.__importStar || /* @__PURE__ */ (function() {
|
|
82876
|
+
var ownKeys = function(o) {
|
|
82877
|
+
ownKeys = Object.getOwnPropertyNames || function(o2) {
|
|
82878
|
+
var ar = [];
|
|
82879
|
+
for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
|
|
82880
|
+
return ar;
|
|
82881
|
+
};
|
|
82882
|
+
return ownKeys(o);
|
|
82883
|
+
};
|
|
82884
|
+
return function(mod) {
|
|
82885
|
+
if (mod && mod.__esModule) return mod;
|
|
82886
|
+
var result = {};
|
|
82887
|
+
if (mod != null) {
|
|
82888
|
+
for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
82889
|
+
}
|
|
82890
|
+
__setModuleDefault(result, mod);
|
|
82891
|
+
return result;
|
|
82892
|
+
};
|
|
82893
|
+
})();
|
|
82894
|
+
var __importDefault = exports2 && exports2.__importDefault || function(mod) {
|
|
82895
|
+
return mod && mod.__esModule ? mod : { "default": mod };
|
|
82896
|
+
};
|
|
82897
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
82898
|
+
exports2.auditSite = auditSite;
|
|
82899
|
+
exports2.isRebuildProspect = isRebuildProspect;
|
|
82900
|
+
exports2.headlineIssues = headlineIssues;
|
|
82901
|
+
var axios_1 = __importDefault(require_axios());
|
|
82902
|
+
var tls = __importStar(require("tls"));
|
|
82903
|
+
var url_1 = require("url");
|
|
82904
|
+
var WEIGHT = {
|
|
82905
|
+
critical: 30,
|
|
82906
|
+
major: 15,
|
|
82907
|
+
minor: 6
|
|
82908
|
+
};
|
|
82909
|
+
async function checkTls(hostname) {
|
|
82910
|
+
return new Promise((resolve) => {
|
|
82911
|
+
let settled = false;
|
|
82912
|
+
const done = (r) => {
|
|
82913
|
+
if (settled)
|
|
82914
|
+
return;
|
|
82915
|
+
settled = true;
|
|
82916
|
+
socket.destroy();
|
|
82917
|
+
resolve(r);
|
|
82918
|
+
};
|
|
82919
|
+
const socket = tls.connect({ host: hostname, port: 443, servername: hostname, timeout: 12e3 }, () => {
|
|
82920
|
+
if (!socket.authorized) {
|
|
82921
|
+
done({
|
|
82922
|
+
ok: false,
|
|
82923
|
+
issue: {
|
|
82924
|
+
code: "tls_invalid",
|
|
82925
|
+
label: "The security certificate isn\u2019t valid \u2014 browsers warn visitors before they can see the site",
|
|
82926
|
+
severity: "critical",
|
|
82927
|
+
detail: socket.authorizationError ? String(socket.authorizationError) : void 0
|
|
82928
|
+
}
|
|
82929
|
+
});
|
|
82930
|
+
return;
|
|
82931
|
+
}
|
|
82932
|
+
const cert = socket.getPeerCertificate();
|
|
82933
|
+
if (!cert || !cert.valid_to) {
|
|
82934
|
+
done({ ok: true });
|
|
82935
|
+
return;
|
|
82936
|
+
}
|
|
82937
|
+
const days = Math.round((new Date(cert.valid_to).getTime() - Date.now()) / 864e5);
|
|
82938
|
+
if (days < 0) {
|
|
82939
|
+
done({
|
|
82940
|
+
ok: false,
|
|
82941
|
+
daysToExpiry: days,
|
|
82942
|
+
issue: {
|
|
82943
|
+
code: "tls_expired",
|
|
82944
|
+
label: "The security certificate has expired \u2014 visitors see a full-page warning",
|
|
82945
|
+
severity: "critical",
|
|
82946
|
+
detail: `expired ${Math.abs(days)} days ago`
|
|
82947
|
+
}
|
|
82948
|
+
});
|
|
82949
|
+
return;
|
|
82950
|
+
}
|
|
82951
|
+
if (days <= 14) {
|
|
82952
|
+
done({
|
|
82953
|
+
ok: true,
|
|
82954
|
+
daysToExpiry: days,
|
|
82955
|
+
issue: {
|
|
82956
|
+
code: "tls_expiring",
|
|
82957
|
+
label: "The security certificate expires within two weeks",
|
|
82958
|
+
severity: "major",
|
|
82959
|
+
detail: `${days} days left`
|
|
82960
|
+
}
|
|
82961
|
+
});
|
|
82962
|
+
return;
|
|
82963
|
+
}
|
|
82964
|
+
done({ ok: true, daysToExpiry: days });
|
|
82965
|
+
});
|
|
82966
|
+
socket.on("error", (err) => {
|
|
82967
|
+
const msg = err.message || "";
|
|
82968
|
+
const code = err.code ?? "";
|
|
82969
|
+
let issue;
|
|
82970
|
+
if (/certificate has expired|CERT_HAS_EXPIRED/i.test(msg + code)) {
|
|
82971
|
+
issue = {
|
|
82972
|
+
code: "tls_expired",
|
|
82973
|
+
label: "The security certificate has expired \u2014 visitors see a full-page browser warning before they reach the site",
|
|
82974
|
+
severity: "critical",
|
|
82975
|
+
detail: msg
|
|
82976
|
+
};
|
|
82977
|
+
} else if (/self.signed|SELF_SIGNED/i.test(msg + code)) {
|
|
82978
|
+
issue = {
|
|
82979
|
+
code: "tls_self_signed",
|
|
82980
|
+
label: "The security certificate isn\u2019t from a recognised authority, so browsers warn visitors away",
|
|
82981
|
+
severity: "critical",
|
|
82982
|
+
detail: msg
|
|
82983
|
+
};
|
|
82984
|
+
} else if (/altnames|hostname\/ip does not match|ERR_TLS_CERT_ALTNAME/i.test(msg + code)) {
|
|
82985
|
+
issue = {
|
|
82986
|
+
code: "tls_wrong_host",
|
|
82987
|
+
label: "The security certificate was issued for a different domain, so browsers reject it",
|
|
82988
|
+
severity: "critical",
|
|
82989
|
+
detail: msg
|
|
82990
|
+
};
|
|
82991
|
+
} else if (/ECONNREFUSED|ENOTFOUND|EHOSTUNREACH|ECONNRESET/i.test(msg + code)) {
|
|
82992
|
+
issue = {
|
|
82993
|
+
code: "tls_unavailable",
|
|
82994
|
+
label: "The site has no working HTTPS \u2014 Chrome labels it \u201CNot secure\u201D to every visitor",
|
|
82995
|
+
severity: "critical",
|
|
82996
|
+
detail: msg
|
|
82997
|
+
};
|
|
82998
|
+
} else {
|
|
82999
|
+
issue = {
|
|
83000
|
+
code: "tls_error",
|
|
83001
|
+
label: "Secure connections to the site fail",
|
|
83002
|
+
severity: "major",
|
|
83003
|
+
detail: msg
|
|
83004
|
+
};
|
|
83005
|
+
}
|
|
83006
|
+
done({ ok: false, issue });
|
|
83007
|
+
});
|
|
83008
|
+
socket.on("timeout", () => {
|
|
83009
|
+
done({
|
|
83010
|
+
ok: false,
|
|
83011
|
+
issue: {
|
|
83012
|
+
code: "tls_timeout",
|
|
83013
|
+
label: "Secure connections to the site time out",
|
|
83014
|
+
severity: "major"
|
|
83015
|
+
}
|
|
83016
|
+
});
|
|
83017
|
+
});
|
|
83018
|
+
});
|
|
83019
|
+
}
|
|
83020
|
+
function markupIssues(html, finalUrl) {
|
|
83021
|
+
const issues = [];
|
|
83022
|
+
const head = html.slice(0, 6e4);
|
|
83023
|
+
if (!/<meta[^>]+name=["']?viewport/i.test(head)) {
|
|
83024
|
+
issues.push({
|
|
83025
|
+
code: "not_mobile",
|
|
83026
|
+
label: "Not built for phones \u2014 the page loads zoomed out and has to be pinched to read",
|
|
83027
|
+
severity: "critical"
|
|
83028
|
+
});
|
|
83029
|
+
}
|
|
83030
|
+
const tableCount = (html.match(/<table/gi) ?? []).length;
|
|
83031
|
+
if (tableCount >= 3 || /<table[^>]*>[\s\S]{0,400}<table/i.test(html)) {
|
|
83032
|
+
issues.push({
|
|
83033
|
+
code: "table_layout",
|
|
83034
|
+
label: "Built with table layouts, a technique abandoned around 2010",
|
|
83035
|
+
severity: "major",
|
|
83036
|
+
detail: `${tableCount} tables`
|
|
83037
|
+
});
|
|
83038
|
+
}
|
|
83039
|
+
if (/<(font|center|marquee|blink)\b/i.test(html)) {
|
|
83040
|
+
const tag = html.match(/<(font|center|marquee|blink)\b/i)?.[1]?.toLowerCase();
|
|
83041
|
+
issues.push({
|
|
83042
|
+
code: "obsolete_tags",
|
|
83043
|
+
label: `Uses HTML tags (<${tag}>) that have been removed from the web standard`,
|
|
83044
|
+
severity: "major"
|
|
83045
|
+
});
|
|
83046
|
+
}
|
|
83047
|
+
if (/\.swf\b|application\/x-shockwave-flash|<embed[^>]+flash/i.test(html)) {
|
|
83048
|
+
issues.push({
|
|
83049
|
+
code: "flash",
|
|
83050
|
+
label: "Contains Flash content, which no browser has supported since 2020 \u2014 that part of the site is invisible",
|
|
83051
|
+
severity: "critical"
|
|
83052
|
+
});
|
|
83053
|
+
}
|
|
83054
|
+
const jq = html.match(/jquery[.-]?(\d+)\.(\d+)(?:\.(\d+))?(?:\.min)?\.js/i);
|
|
83055
|
+
if (jq) {
|
|
83056
|
+
const major = Number(jq[1]);
|
|
83057
|
+
if (major < 3) {
|
|
83058
|
+
issues.push({
|
|
83059
|
+
code: "old_jquery",
|
|
83060
|
+
label: "Runs a jQuery version with publicly known security vulnerabilities",
|
|
83061
|
+
severity: "major",
|
|
83062
|
+
detail: `jQuery ${jq[1]}.${jq[2]}${jq[3] ? "." + jq[3] : ""}`
|
|
83063
|
+
});
|
|
83064
|
+
}
|
|
83065
|
+
}
|
|
83066
|
+
const year = (/* @__PURE__ */ new Date()).getFullYear();
|
|
83067
|
+
const years = [...html.matchAll(/(?:©|©|copyright)\s*(?:\d{4}\s*[-–]\s*)?(\d{4})/gi)].map((m) => Number(m[1])).filter((y) => y >= 1995 && y <= year);
|
|
83068
|
+
if (years.length) {
|
|
83069
|
+
const newest = Math.max(...years);
|
|
83070
|
+
const age = year - newest;
|
|
83071
|
+
if (age >= 2) {
|
|
83072
|
+
issues.push({
|
|
83073
|
+
code: "stale_copyright",
|
|
83074
|
+
label: `The footer still says ${newest} \u2014 visitors read that as \u201Cpossibly closed down\u201D`,
|
|
83075
|
+
severity: age >= 5 ? "major" : "minor",
|
|
83076
|
+
detail: `${age} years out of date`
|
|
83077
|
+
});
|
|
83078
|
+
}
|
|
83079
|
+
}
|
|
83080
|
+
if (/under construction|coming soon|website is being (?:built|updated)/i.test(head)) {
|
|
83081
|
+
issues.push({
|
|
83082
|
+
code: "under_construction",
|
|
83083
|
+
label: "Still shows an \u201Cunder construction\u201D placeholder",
|
|
83084
|
+
severity: "critical"
|
|
83085
|
+
});
|
|
83086
|
+
}
|
|
83087
|
+
if (/this domain (?:is|may be) for sale|parked (?:free )?(?:at|by)|godaddy\.com\/domainfind|default web page/i.test(head)) {
|
|
83088
|
+
issues.push({
|
|
83089
|
+
code: "parked",
|
|
83090
|
+
label: "The domain shows a parking page rather than a real website",
|
|
83091
|
+
severity: "critical"
|
|
83092
|
+
});
|
|
83093
|
+
}
|
|
83094
|
+
if (finalUrl.startsWith("https://")) {
|
|
83095
|
+
const insecure = html.match(/(?:src|href)=["']http:\/\/(?!localhost)/gi);
|
|
83096
|
+
if (insecure && insecure.length >= 2) {
|
|
83097
|
+
issues.push({
|
|
83098
|
+
code: "mixed_content",
|
|
83099
|
+
label: "Loads images or scripts insecurely, so browsers block them and parts of the page break",
|
|
83100
|
+
severity: "major",
|
|
83101
|
+
detail: `${insecure.length} insecure references`
|
|
83102
|
+
});
|
|
83103
|
+
}
|
|
83104
|
+
}
|
|
83105
|
+
const title = html.match(/<title[^>]*>([\s\S]{0,200}?)<\/title>/i)?.[1]?.trim();
|
|
83106
|
+
if (!title) {
|
|
83107
|
+
issues.push({
|
|
83108
|
+
code: "no_title",
|
|
83109
|
+
label: "The page has no title, so search results show a bare web address",
|
|
83110
|
+
severity: "major"
|
|
83111
|
+
});
|
|
83112
|
+
} else if (/^(home|untitled|new page \d*|document|index|website)$/i.test(title)) {
|
|
83113
|
+
issues.push({
|
|
83114
|
+
code: "default_title",
|
|
83115
|
+
label: `The page title is still the template default (\u201C${title}\u201D), which is what Google shows`,
|
|
83116
|
+
severity: "major"
|
|
83117
|
+
});
|
|
83118
|
+
}
|
|
83119
|
+
if (!/<meta[^>]+name=["']?description/i.test(head)) {
|
|
83120
|
+
issues.push({
|
|
83121
|
+
code: "no_description",
|
|
83122
|
+
label: "No search description, so Google invents one from whatever text it finds",
|
|
83123
|
+
severity: "minor"
|
|
83124
|
+
});
|
|
83125
|
+
}
|
|
83126
|
+
if (/<frameset|<frame\b/i.test(html)) {
|
|
83127
|
+
issues.push({
|
|
83128
|
+
code: "frames",
|
|
83129
|
+
label: "Built with frames, which search engines cannot index properly",
|
|
83130
|
+
severity: "critical"
|
|
83131
|
+
});
|
|
83132
|
+
}
|
|
83133
|
+
return issues;
|
|
83134
|
+
}
|
|
83135
|
+
async function auditSite(websiteUrl) {
|
|
83136
|
+
const raw = (websiteUrl ?? "").trim();
|
|
83137
|
+
if (!raw)
|
|
83138
|
+
return { url: raw, reachable: false, score: 0, issues: [], error: "No URL" };
|
|
83139
|
+
const withScheme = /^https?:\/\//i.test(raw) ? raw : `https://${raw}`;
|
|
83140
|
+
let hostname;
|
|
83141
|
+
try {
|
|
83142
|
+
hostname = new url_1.URL(withScheme).hostname;
|
|
83143
|
+
} catch {
|
|
83144
|
+
return { url: raw, reachable: false, score: 0, issues: [], error: "Unparseable URL" };
|
|
83145
|
+
}
|
|
83146
|
+
const issues = [];
|
|
83147
|
+
const listedAsHttp = /^http:\/\//i.test(raw);
|
|
83148
|
+
const [tlsResult, page] = await Promise.all([
|
|
83149
|
+
checkTls(hostname).catch(() => ({ ok: true })),
|
|
83150
|
+
fetchPage(withScheme)
|
|
83151
|
+
]);
|
|
83152
|
+
if (tlsResult.issue)
|
|
83153
|
+
issues.push(tlsResult.issue);
|
|
83154
|
+
if (listedAsHttp && !tlsResult.issue) {
|
|
83155
|
+
issues.push({
|
|
83156
|
+
code: "listed_insecure",
|
|
83157
|
+
label: "The address the business gives out starts with http:// \u2014 visitors following it get a \u201CNot secure\u201D warning",
|
|
83158
|
+
severity: "major"
|
|
83159
|
+
});
|
|
83160
|
+
}
|
|
83161
|
+
if (!page.ok) {
|
|
83162
|
+
return {
|
|
83163
|
+
url: raw,
|
|
83164
|
+
reachable: false,
|
|
83165
|
+
score: scoreOf(issues),
|
|
83166
|
+
issues,
|
|
83167
|
+
error: page.error
|
|
83168
|
+
};
|
|
83169
|
+
}
|
|
83170
|
+
if (page.finalUrl.startsWith("http://") && !tlsResult.issue) {
|
|
83171
|
+
issues.push({
|
|
83172
|
+
code: "no_https_redirect",
|
|
83173
|
+
label: "The site falls back to an unencrypted connection instead of staying secure",
|
|
83174
|
+
severity: "major"
|
|
83175
|
+
});
|
|
83176
|
+
}
|
|
83177
|
+
issues.push(...markupIssues(page.html, page.finalUrl));
|
|
83178
|
+
const htmlKb = Math.round(page.html.length / 1024);
|
|
83179
|
+
if (htmlKb > 600) {
|
|
83180
|
+
issues.push({
|
|
83181
|
+
code: "heavy_page",
|
|
83182
|
+
label: "The page is unusually heavy, so it loads slowly on mobile data",
|
|
83183
|
+
severity: "minor",
|
|
83184
|
+
detail: `${htmlKb} KB of HTML`
|
|
83185
|
+
});
|
|
83186
|
+
}
|
|
83187
|
+
return { url: raw, reachable: true, score: scoreOf(issues), issues, htmlKb };
|
|
83188
|
+
}
|
|
83189
|
+
async function fetchPage(url) {
|
|
83190
|
+
try {
|
|
83191
|
+
const res = await axios_1.default.get(url, {
|
|
83192
|
+
timeout: 2e4,
|
|
83193
|
+
maxRedirects: 5,
|
|
83194
|
+
responseType: "text",
|
|
83195
|
+
// Some hosts serve a stripped page to a bare client.
|
|
83196
|
+
headers: {
|
|
83197
|
+
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120 Safari/537.36",
|
|
83198
|
+
Accept: "text/html,application/xhtml+xml"
|
|
83199
|
+
},
|
|
83200
|
+
maxContentLength: 5e6,
|
|
83201
|
+
validateStatus: () => true,
|
|
83202
|
+
// We want to inspect a broken-cert site's markup too; the cert problem is
|
|
83203
|
+
// reported separately by checkTls, so this doesn't hide anything.
|
|
83204
|
+
httpsAgent: void 0
|
|
83205
|
+
});
|
|
83206
|
+
if (res.status >= 400) {
|
|
83207
|
+
return { ok: false, error: `HTTP ${res.status}` };
|
|
83208
|
+
}
|
|
83209
|
+
const html = typeof res.data === "string" ? res.data : String(res.data ?? "");
|
|
83210
|
+
if (!html)
|
|
83211
|
+
return { ok: false, error: "Empty response" };
|
|
83212
|
+
const finalUrl = res.request?.res?.responseUrl || url;
|
|
83213
|
+
return { ok: true, html, finalUrl };
|
|
83214
|
+
} catch (e) {
|
|
83215
|
+
return { ok: false, error: e.message };
|
|
83216
|
+
}
|
|
83217
|
+
}
|
|
83218
|
+
function scoreOf(issues) {
|
|
83219
|
+
const total = issues.reduce((sum, i) => sum + WEIGHT[i.severity], 0);
|
|
83220
|
+
return Math.min(100, total);
|
|
83221
|
+
}
|
|
83222
|
+
function isRebuildProspect(audit) {
|
|
83223
|
+
if (!audit.issues.length)
|
|
83224
|
+
return false;
|
|
83225
|
+
const critical = audit.issues.filter((i) => i.severity === "critical").length;
|
|
83226
|
+
const major = audit.issues.filter((i) => i.severity === "major").length;
|
|
83227
|
+
return critical >= 1 || major >= 2;
|
|
83228
|
+
}
|
|
83229
|
+
function headlineIssues(audit, limit = 3) {
|
|
83230
|
+
const rank = { critical: 0, major: 1, minor: 2 };
|
|
83231
|
+
return [...audit.issues].sort((a, b) => rank[a.severity] - rank[b.severity]).slice(0, limit);
|
|
83232
|
+
}
|
|
83233
|
+
}
|
|
83234
|
+
});
|
|
83235
|
+
|
|
82793
83236
|
// ../desktop/dist/main/lib/lead-search.js
|
|
82794
83237
|
var require_lead_search = __commonJS({
|
|
82795
83238
|
"../desktop/dist/main/lib/lead-search.js"(exports2) {
|
|
@@ -82800,11 +83243,14 @@ var require_lead_search = __commonJS({
|
|
|
82800
83243
|
var db_1 = require_db();
|
|
82801
83244
|
var places_1 = require_places();
|
|
82802
83245
|
var booking_detect_1 = require_booking_detect();
|
|
83246
|
+
var site_audit_1 = require_site_audit();
|
|
82803
83247
|
async function searchAndSaveLeadsStream(args, onLead) {
|
|
82804
83248
|
const db2 = (0, db_1.getDb)();
|
|
82805
83249
|
const cap = args.maxResults ?? 50;
|
|
82806
83250
|
const seen = /* @__PURE__ */ new Set();
|
|
82807
83251
|
const bookingMode = args.mode === "no_booking";
|
|
83252
|
+
const auditMode = args.mode === "outdated";
|
|
83253
|
+
const wantsSiteHavers = bookingMode || auditMode;
|
|
82808
83254
|
let saved = 0;
|
|
82809
83255
|
let found = 0;
|
|
82810
83256
|
await (0, places_1.searchPlacesStream)({
|
|
@@ -82813,8 +83259,8 @@ var require_lead_search = __commonJS({
|
|
|
82813
83259
|
types: args.types,
|
|
82814
83260
|
center: args.center,
|
|
82815
83261
|
radiusMeters: args.radiusMeters,
|
|
82816
|
-
// Booking
|
|
82817
|
-
includeWithWebsite:
|
|
83262
|
+
// Booking and audit modes need the businesses that DO have a website.
|
|
83263
|
+
includeWithWebsite: wantsSiteHavers
|
|
82818
83264
|
}, async (batch) => {
|
|
82819
83265
|
for (const r of batch) {
|
|
82820
83266
|
found++;
|
|
@@ -82829,7 +83275,19 @@ var require_lead_search = __commonJS({
|
|
|
82829
83275
|
let leadKind = "no_website";
|
|
82830
83276
|
let bookingStatus = null;
|
|
82831
83277
|
let bookingPlatform = null;
|
|
82832
|
-
|
|
83278
|
+
let siteScore = null;
|
|
83279
|
+
let siteIssues = null;
|
|
83280
|
+
if (auditMode) {
|
|
83281
|
+
if (!r.website)
|
|
83282
|
+
continue;
|
|
83283
|
+
args.onProgress?.(`Auditing ${r.name}'s website\u2026`);
|
|
83284
|
+
const audit = await (0, site_audit_1.auditSite)(r.website);
|
|
83285
|
+
if (!(0, site_audit_1.isRebuildProspect)(audit))
|
|
83286
|
+
continue;
|
|
83287
|
+
siteScore = audit.score;
|
|
83288
|
+
siteIssues = JSON.stringify(audit.issues);
|
|
83289
|
+
leadKind = "outdated";
|
|
83290
|
+
} else if (bookingMode) {
|
|
82833
83291
|
if (!r.website)
|
|
82834
83292
|
continue;
|
|
82835
83293
|
args.onProgress?.(`Checking ${r.name}'s booking setup\u2026`);
|
|
@@ -82843,8 +83301,8 @@ var require_lead_search = __commonJS({
|
|
|
82843
83301
|
continue;
|
|
82844
83302
|
}
|
|
82845
83303
|
db2.run(`INSERT INTO leads
|
|
82846
|
-
(place_id, name, type, city, address, phone, website, rating, review_count, lat, lng, score, price_level, business_status, status, lead_kind, booking_status, booking_platform)
|
|
82847
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'discovered', ?, ?, ?)`, [
|
|
83304
|
+
(place_id, name, type, city, address, phone, website, rating, review_count, lat, lng, score, price_level, business_status, status, lead_kind, booking_status, booking_platform, site_score, site_issues, audited_at)
|
|
83305
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'discovered', ?, ?, ?, ?, ?, ?)`, [
|
|
82848
83306
|
r.place_id,
|
|
82849
83307
|
r.name,
|
|
82850
83308
|
r.type,
|
|
@@ -82861,7 +83319,10 @@ var require_lead_search = __commonJS({
|
|
|
82861
83319
|
r.business_status,
|
|
82862
83320
|
leadKind,
|
|
82863
83321
|
bookingStatus,
|
|
82864
|
-
bookingPlatform
|
|
83322
|
+
bookingPlatform,
|
|
83323
|
+
siteScore,
|
|
83324
|
+
siteIssues,
|
|
83325
|
+
siteScore === null ? null : (/* @__PURE__ */ new Date()).toISOString()
|
|
82865
83326
|
]);
|
|
82866
83327
|
const row = db2.get("SELECT id FROM leads WHERE place_id = ?", [r.place_id]);
|
|
82867
83328
|
saved++;
|
|
@@ -83057,8 +83518,8 @@ var require_invoicing = __commonJS({
|
|
|
83057
83518
|
exports2.renderInvoicePdf = renderInvoicePdf;
|
|
83058
83519
|
exports2.renderLetterPdf = renderLetterPdf2;
|
|
83059
83520
|
var pdfkit_1 = __importDefault(require("pdfkit"));
|
|
83060
|
-
var
|
|
83061
|
-
var
|
|
83521
|
+
var fs4 = __importStar(require("fs"));
|
|
83522
|
+
var path4 = __importStar(require("path"));
|
|
83062
83523
|
var db_1 = require_db();
|
|
83063
83524
|
var runtime_1 = require_runtime();
|
|
83064
83525
|
var agency_1 = require_agency();
|
|
@@ -83108,8 +83569,8 @@ var require_invoicing = __commonJS({
|
|
|
83108
83569
|
return prefix + String(n).padStart(3, "0");
|
|
83109
83570
|
}
|
|
83110
83571
|
function invoiceDir() {
|
|
83111
|
-
const dir =
|
|
83112
|
-
|
|
83572
|
+
const dir = path4.join((0, runtime_1.userDataDir)(), "data", "invoices");
|
|
83573
|
+
fs4.mkdirSync(dir, { recursive: true });
|
|
83113
83574
|
return dir;
|
|
83114
83575
|
}
|
|
83115
83576
|
function addDays(iso, days) {
|
|
@@ -83186,7 +83647,7 @@ var require_invoicing = __commonJS({
|
|
|
83186
83647
|
const accent = hexOrDefault(p.accent, "#556B45");
|
|
83187
83648
|
const right = doc.page.width - PAGE_MARGIN;
|
|
83188
83649
|
let leftBottom = PAGE_MARGIN;
|
|
83189
|
-
if (p.logoPath &&
|
|
83650
|
+
if (p.logoPath && fs4.existsSync(p.logoPath)) {
|
|
83190
83651
|
try {
|
|
83191
83652
|
doc.image(p.logoPath, PAGE_MARGIN, PAGE_MARGIN, { fit: [150, 50] });
|
|
83192
83653
|
leftBottom = PAGE_MARGIN + 50;
|
|
@@ -83226,12 +83687,12 @@ var require_invoicing = __commonJS({
|
|
|
83226
83687
|
}
|
|
83227
83688
|
const accent = hexOrDefault(p.accent, "#556B45");
|
|
83228
83689
|
const items = JSON.parse(invoice.line_items);
|
|
83229
|
-
const file = outPath ??
|
|
83690
|
+
const file = outPath ?? path4.join(invoiceDir(), `${invoice.number}.pdf`);
|
|
83230
83691
|
const doc = new pdfkit_1.default({ size: "A4", margin: PAGE_MARGIN, info: {
|
|
83231
83692
|
Title: `Invoice ${invoice.number}`,
|
|
83232
83693
|
Author: p.name
|
|
83233
83694
|
} });
|
|
83234
|
-
const stream =
|
|
83695
|
+
const stream = fs4.createWriteStream(file);
|
|
83235
83696
|
doc.pipe(stream);
|
|
83236
83697
|
let y = drawLetterhead(doc, p);
|
|
83237
83698
|
const right = doc.page.width - PAGE_MARGIN;
|
|
@@ -83339,15 +83800,15 @@ var require_invoicing = __commonJS({
|
|
|
83339
83800
|
if (!p.name) {
|
|
83340
83801
|
throw new Error("No agency details set \u2014 run `sproutkit brand` first.");
|
|
83341
83802
|
}
|
|
83342
|
-
const dir =
|
|
83343
|
-
|
|
83803
|
+
const dir = path4.join((0, runtime_1.userDataDir)(), "data", "letters");
|
|
83804
|
+
fs4.mkdirSync(dir, { recursive: true });
|
|
83344
83805
|
const safe = args.to.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 40);
|
|
83345
|
-
const file = args.outPath ??
|
|
83806
|
+
const file = args.outPath ?? path4.join(dir, `letter-${safe}-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}.pdf`);
|
|
83346
83807
|
const doc = new pdfkit_1.default({ size: "A4", margin: PAGE_MARGIN, info: {
|
|
83347
83808
|
Title: args.subject ?? `Letter to ${args.to}`,
|
|
83348
83809
|
Author: p.name
|
|
83349
83810
|
} });
|
|
83350
|
-
const stream =
|
|
83811
|
+
const stream = fs4.createWriteStream(file);
|
|
83351
83812
|
doc.pipe(stream);
|
|
83352
83813
|
let y = drawLetterhead(doc, p);
|
|
83353
83814
|
const width = doc.page.width - PAGE_MARGIN * 2;
|
|
@@ -83612,8 +84073,8 @@ var require_cookies2 = __commonJS({
|
|
|
83612
84073
|
if (urlparts.hostname !== cookie.domain && (cookie.domain.charAt(0) !== "." || ("." + urlparts.hostname).substr(-cookie.domain.length) !== cookie.domain)) {
|
|
83613
84074
|
return false;
|
|
83614
84075
|
}
|
|
83615
|
-
const
|
|
83616
|
-
if (
|
|
84076
|
+
const path4 = this.getPath(urlparts.pathname);
|
|
84077
|
+
if (path4.substr(0, cookie.path.length) !== cookie.path) {
|
|
83617
84078
|
return false;
|
|
83618
84079
|
}
|
|
83619
84080
|
if (cookie.secure && urlparts.protocol !== "https:") {
|
|
@@ -83671,16 +84132,16 @@ var require_cookies2 = __commonJS({
|
|
|
83671
84132
|
* @returns {String} Normalized path
|
|
83672
84133
|
*/
|
|
83673
84134
|
getPath(pathname) {
|
|
83674
|
-
let
|
|
83675
|
-
|
|
83676
|
-
|
|
83677
|
-
if (
|
|
83678
|
-
|
|
84135
|
+
let path4 = (pathname || "/").split("/");
|
|
84136
|
+
path4.pop();
|
|
84137
|
+
path4 = path4.join("/").trim();
|
|
84138
|
+
if (path4.charAt(0) !== "/") {
|
|
84139
|
+
path4 = "/" + path4;
|
|
83679
84140
|
}
|
|
83680
|
-
if (
|
|
83681
|
-
|
|
84141
|
+
if (path4.substr(-1) !== "/") {
|
|
84142
|
+
path4 += "/";
|
|
83682
84143
|
}
|
|
83683
|
-
return
|
|
84144
|
+
return path4;
|
|
83684
84145
|
}
|
|
83685
84146
|
};
|
|
83686
84147
|
module2.exports = Cookies;
|
|
@@ -84024,12 +84485,12 @@ var require_shared = __commonJS({
|
|
|
84024
84485
|
"use strict";
|
|
84025
84486
|
var urllib = require("url");
|
|
84026
84487
|
var util = require("util");
|
|
84027
|
-
var
|
|
84488
|
+
var fs4 = require("fs");
|
|
84028
84489
|
var nmfetch = require_fetch2();
|
|
84029
84490
|
var errors = require_errors6();
|
|
84030
84491
|
var dns = require("dns");
|
|
84031
84492
|
var net = require("net");
|
|
84032
|
-
var
|
|
84493
|
+
var os5 = require("os");
|
|
84033
84494
|
var DNS_TTL = 5 * 60 * 1e3;
|
|
84034
84495
|
var CACHE_CLEANUP_INTERVAL = 30 * 1e3;
|
|
84035
84496
|
var MAX_CACHE_SIZE = 1e3;
|
|
@@ -84040,7 +84501,7 @@ var require_shared = __commonJS({
|
|
|
84040
84501
|
};
|
|
84041
84502
|
var networkInterfaces;
|
|
84042
84503
|
try {
|
|
84043
|
-
networkInterfaces =
|
|
84504
|
+
networkInterfaces = os5.networkInterfaces();
|
|
84044
84505
|
} catch (_err) {
|
|
84045
84506
|
}
|
|
84046
84507
|
module2.exports.networkInterfaces = networkInterfaces;
|
|
@@ -84452,7 +84913,7 @@ var require_shared = __commonJS({
|
|
|
84452
84913
|
callback(err);
|
|
84453
84914
|
});
|
|
84454
84915
|
}
|
|
84455
|
-
return resolveStream(
|
|
84916
|
+
return resolveStream(fs4.createReadStream(content.path), callback);
|
|
84456
84917
|
}
|
|
84457
84918
|
}
|
|
84458
84919
|
if (typeof data[key].content === "string" && !["utf8", "usascii", "ascii"].includes(encoding)) {
|
|
@@ -84565,7 +85026,7 @@ var require_shared = __commonJS({
|
|
|
84565
85026
|
var require_mime_types2 = __commonJS({
|
|
84566
85027
|
"../../node_modules/nodemailer/lib/mime-funcs/mime-types.js"(exports2, module2) {
|
|
84567
85028
|
"use strict";
|
|
84568
|
-
var
|
|
85029
|
+
var path4 = require("path");
|
|
84569
85030
|
var defaultMimeType = "application/octet-stream";
|
|
84570
85031
|
var defaultExtension = "bin";
|
|
84571
85032
|
var mimeTypes = /* @__PURE__ */ new Map([
|
|
@@ -86632,7 +87093,7 @@ var require_mime_types2 = __commonJS({
|
|
|
86632
87093
|
if (!filename) {
|
|
86633
87094
|
return defaultMimeType;
|
|
86634
87095
|
}
|
|
86635
|
-
const parsed =
|
|
87096
|
+
const parsed = path4.parse(filename);
|
|
86636
87097
|
const extension = (parsed.ext.substr(1) || parsed.name || "").split("?").shift().trim().toLowerCase();
|
|
86637
87098
|
const value = extensions.has(extension) ? extensions.get(extension) : defaultMimeType;
|
|
86638
87099
|
if (Array.isArray(value)) {
|
|
@@ -88060,7 +88521,7 @@ var require_mime_node = __commonJS({
|
|
|
88060
88521
|
"../../node_modules/nodemailer/lib/mime-node/index.js"(exports2, module2) {
|
|
88061
88522
|
"use strict";
|
|
88062
88523
|
var crypto2 = require("crypto");
|
|
88063
|
-
var
|
|
88524
|
+
var fs4 = require("fs");
|
|
88064
88525
|
var punycode = require_punycode();
|
|
88065
88526
|
var { PassThrough } = require("stream");
|
|
88066
88527
|
var shared = require_shared();
|
|
@@ -88782,7 +89243,7 @@ var require_mime_node = __commonJS({
|
|
|
88782
89243
|
});
|
|
88783
89244
|
return contentStream;
|
|
88784
89245
|
}
|
|
88785
|
-
return
|
|
89246
|
+
return fs4.createReadStream(content.path);
|
|
88786
89247
|
}
|
|
88787
89248
|
if (content && typeof content.href === "string") {
|
|
88788
89249
|
if (this.disableUrlAccess) {
|
|
@@ -89848,8 +90309,8 @@ var require_dkim = __commonJS({
|
|
|
89848
90309
|
var RelaxedBody = require_relaxed_body();
|
|
89849
90310
|
var sign = require_sign7();
|
|
89850
90311
|
var { PassThrough } = require("stream");
|
|
89851
|
-
var
|
|
89852
|
-
var
|
|
90312
|
+
var fs4 = require("fs");
|
|
90313
|
+
var path4 = require("path");
|
|
89853
90314
|
var crypto2 = require("crypto");
|
|
89854
90315
|
var DKIM_ALGO = "sha256";
|
|
89855
90316
|
var MAX_MESSAGE_SIZE = 2 * 1024 * 1024;
|
|
@@ -89863,7 +90324,7 @@ var require_dkim = __commonJS({
|
|
|
89863
90324
|
this.chunks = [];
|
|
89864
90325
|
this.chunklen = 0;
|
|
89865
90326
|
this.readPos = 0;
|
|
89866
|
-
this.cachePath = this.cacheDir ?
|
|
90327
|
+
this.cachePath = this.cacheDir ? path4.join(this.cacheDir, "message." + Date.now() + "-" + crypto2.randomBytes(14).toString("hex")) : false;
|
|
89867
90328
|
this.cache = false;
|
|
89868
90329
|
this.headers = false;
|
|
89869
90330
|
this.bodyHash = false;
|
|
@@ -89883,10 +90344,10 @@ var require_dkim = __commonJS({
|
|
|
89883
90344
|
if (!this.cache || !this.cachePath) {
|
|
89884
90345
|
return;
|
|
89885
90346
|
}
|
|
89886
|
-
|
|
90347
|
+
fs4.unlink(this.cachePath, () => false);
|
|
89887
90348
|
}
|
|
89888
90349
|
createReadCache() {
|
|
89889
|
-
this.cache =
|
|
90350
|
+
this.cache = fs4.createReadStream(this.cachePath);
|
|
89890
90351
|
this.cache.once("error", (err) => {
|
|
89891
90352
|
this.cleanup();
|
|
89892
90353
|
this.output.emit("error", err);
|
|
@@ -89942,7 +90403,7 @@ var require_dkim = __commonJS({
|
|
|
89942
90403
|
}
|
|
89943
90404
|
createWriteCache() {
|
|
89944
90405
|
this.output.usingCache = true;
|
|
89945
|
-
this.cache =
|
|
90406
|
+
this.cache = fs4.createWriteStream(this.cachePath);
|
|
89946
90407
|
this.cache.once("error", (err) => {
|
|
89947
90408
|
this.cleanup();
|
|
89948
90409
|
this.relaxedBody.unpipe(this.cache);
|
|
@@ -90883,7 +91344,7 @@ var require_smtp_connection = __commonJS({
|
|
|
90883
91344
|
var { EventEmitter } = require("events");
|
|
90884
91345
|
var net = require("net");
|
|
90885
91346
|
var tls = require("tls");
|
|
90886
|
-
var
|
|
91347
|
+
var os5 = require("os");
|
|
90887
91348
|
var crypto2 = require("crypto");
|
|
90888
91349
|
var DataStream = require_data_stream();
|
|
90889
91350
|
var { PassThrough } = require("stream");
|
|
@@ -92334,7 +92795,7 @@ var require_smtp_connection = __commonJS({
|
|
|
92334
92795
|
_getHostname() {
|
|
92335
92796
|
let defaultHostname;
|
|
92336
92797
|
try {
|
|
92337
|
-
defaultHostname =
|
|
92798
|
+
defaultHostname = os5.hostname() || "";
|
|
92338
92799
|
} catch (_err) {
|
|
92339
92800
|
defaultHostname = "localhost";
|
|
92340
92801
|
}
|
|
@@ -95146,13 +95607,13 @@ var require_email = __commonJS({
|
|
|
95146
95607
|
secure: cfg.port === 465,
|
|
95147
95608
|
auth: { user: cfg.user, pass: cfg.pass }
|
|
95148
95609
|
});
|
|
95149
|
-
await transporter.sendMail({
|
|
95610
|
+
const info = await transporter.sendMail({
|
|
95150
95611
|
from: cfg.from,
|
|
95151
95612
|
to: args.to,
|
|
95152
95613
|
subject: args.subject,
|
|
95153
95614
|
text: args.text
|
|
95154
95615
|
});
|
|
95155
|
-
return { ok: true };
|
|
95616
|
+
return { ok: true, messageId: info.messageId };
|
|
95156
95617
|
} catch (e) {
|
|
95157
95618
|
return { ok: false, error: e.message };
|
|
95158
95619
|
}
|
|
@@ -95251,6 +95712,7 @@ var require_chat_tools = __commonJS({
|
|
|
95251
95712
|
"use strict";
|
|
95252
95713
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
95253
95714
|
exports2.TOOLS = void 0;
|
|
95715
|
+
exports2.normaliseChannel = normaliseChannel;
|
|
95254
95716
|
exports2.runTool = runTool2;
|
|
95255
95717
|
var db_1 = require_db();
|
|
95256
95718
|
var runtime_1 = require_runtime();
|
|
@@ -95258,6 +95720,7 @@ var require_chat_tools = __commonJS({
|
|
|
95258
95720
|
var lead_search_1 = require_lead_search();
|
|
95259
95721
|
var places_1 = require_places();
|
|
95260
95722
|
var booking_detect_1 = require_booking_detect();
|
|
95723
|
+
var site_audit_1 = require_site_audit();
|
|
95261
95724
|
var followup_1 = require_followup();
|
|
95262
95725
|
var invoicing_1 = require_invoicing();
|
|
95263
95726
|
var agency_1 = require_agency();
|
|
@@ -95358,7 +95821,7 @@ var require_chat_tools = __commonJS({
|
|
|
95358
95821
|
},
|
|
95359
95822
|
{
|
|
95360
95823
|
name: "prepare_outreach",
|
|
95361
|
-
description: "
|
|
95824
|
+
description: "Send or prepare outreach for one or more leads that have a website built. Fills in the user's outreach template (name + demo site URL) and moves each lead to the 'contacted' column. Behaviour depends on the channel: on 'email' (the default) it ACTUALLY SENDS via the user's SMTP \u2014 report exactly who was emailed; on 'whatsapp'/'sms' it returns a ready-to-open messaging link the user opens themselves, because messaging apps can't be auto-sent. Leads with no address on file get one looked up automatically where possible; any lead we can't reach at all is reported as such rather than skipped silently. Use it for 'message everyone I just built', 'send outreach to the ready column', etc.",
|
|
95362
95825
|
input_schema: {
|
|
95363
95826
|
type: "object",
|
|
95364
95827
|
properties: {
|
|
@@ -95369,8 +95832,8 @@ var require_chat_tools = __commonJS({
|
|
|
95369
95832
|
},
|
|
95370
95833
|
channel: {
|
|
95371
95834
|
type: "string",
|
|
95372
|
-
enum: ["whatsapp", "sms"],
|
|
95373
|
-
description: "
|
|
95835
|
+
enum: ["email", "whatsapp", "sms"],
|
|
95836
|
+
description: "Preferred channel. 'email' (default) sends via the user's SMTP \u2014 the only channel that works unattended on every platform \u2014 falling back to a WhatsApp link for leads with no email address. 'whatsapp' opens WhatsApp and 'sms' opens the device's Messages app (Messages on macOS, Phone Link on Windows); both fall back to email when a lead has no phone. Omit to use the saved preference."
|
|
95374
95837
|
}
|
|
95375
95838
|
}
|
|
95376
95839
|
},
|
|
@@ -95449,6 +95912,44 @@ var require_chat_tools = __commonJS({
|
|
|
95449
95912
|
required: ["id"]
|
|
95450
95913
|
}
|
|
95451
95914
|
},
|
|
95915
|
+
{
|
|
95916
|
+
name: "audit_sites",
|
|
95917
|
+
description: "AUDIT existing websites in an area and save the bad ones as rebuild prospects. Unlike find_leads (which looks for businesses with NO website), this finds businesses that DO have a website and checks it for real, nameable faults: expired or missing HTTPS certificates, no mobile support, table layouts, Flash, obsolete jQuery, parked or under-construction pages, stale copyright years. Each prospect is scored (higher = worse) and its specific problems are stored so outreach can cite them. Use this when the user wants to find outdated, insecure or badly built websites to pitch a rebuild against. Costs the same Places lookup as find_leads plus one fetch per site.",
|
|
95918
|
+
input_schema: {
|
|
95919
|
+
type: "object",
|
|
95920
|
+
properties: {
|
|
95921
|
+
location: {
|
|
95922
|
+
type: "string",
|
|
95923
|
+
description: "Town, postcode, area or address to search, e.g. 'Leeds LS1' or 'Shoreditch, London'."
|
|
95924
|
+
},
|
|
95925
|
+
categories: {
|
|
95926
|
+
type: "array",
|
|
95927
|
+
items: { type: "string" },
|
|
95928
|
+
description: "Business types to search, e.g. ['barber shop','cafe','plumber']."
|
|
95929
|
+
},
|
|
95930
|
+
radiusMeters: {
|
|
95931
|
+
type: "number",
|
|
95932
|
+
description: "Search radius in metres. Defaults to 10000."
|
|
95933
|
+
},
|
|
95934
|
+
limit: {
|
|
95935
|
+
type: "number",
|
|
95936
|
+
description: "Maximum prospects to save. Defaults to 25."
|
|
95937
|
+
}
|
|
95938
|
+
},
|
|
95939
|
+
required: ["location", "categories"]
|
|
95940
|
+
}
|
|
95941
|
+
},
|
|
95942
|
+
{
|
|
95943
|
+
name: "audit_one_site",
|
|
95944
|
+
description: "Audit a SINGLE website by URL and report its faults, without saving anything. Use this when the user names a specific site and asks what's wrong with it, or to check a business's site before pitching them.",
|
|
95945
|
+
input_schema: {
|
|
95946
|
+
type: "object",
|
|
95947
|
+
properties: {
|
|
95948
|
+
url: { type: "string", description: "The website to audit, e.g. 'thebarbers.co.uk'." },
|
|
95949
|
+
id: { type: "number", description: "Or a lead id \u2014 audits that lead's website and stores the result." }
|
|
95950
|
+
}
|
|
95951
|
+
}
|
|
95952
|
+
},
|
|
95452
95953
|
{
|
|
95453
95954
|
name: "hand_over_site",
|
|
95454
95955
|
description: "HAND OVER a finished site to the paying client: removes the DEMO/preview banner, optionally attaches the client's own domain, and returns every credential in one place (site URL, /admin panel + password, booking page + its password, and the DNS records the client must set at their registrar). This is the paid-deliverable step \u2014 the banner exists to stop clients using a free demo as their real site, so only run this when the user says the client has paid / signed off / is going live. Requires the lead to already have a built site or booking page.",
|
|
@@ -95707,6 +96208,21 @@ It's not fully live yet. We can make it live for \xA3199 \u2014 your own domain,
|
|
|
95707
96208
|
|
|
95708
96209
|
Interested?`;
|
|
95709
96210
|
}
|
|
96211
|
+
function normaliseChannel(value) {
|
|
96212
|
+
switch (String(value ?? "").toLowerCase()) {
|
|
96213
|
+
case "email":
|
|
96214
|
+
return "email";
|
|
96215
|
+
case "sms":
|
|
96216
|
+
case "messages_mac":
|
|
96217
|
+
case "phone_link_win":
|
|
96218
|
+
case "manual":
|
|
96219
|
+
return "sms";
|
|
96220
|
+
case "whatsapp":
|
|
96221
|
+
return "whatsapp";
|
|
96222
|
+
default:
|
|
96223
|
+
return null;
|
|
96224
|
+
}
|
|
96225
|
+
}
|
|
95710
96226
|
function outreachLink(channel, e164, message) {
|
|
95711
96227
|
if (channel === "whatsapp") {
|
|
95712
96228
|
return `https://wa.me/${e164.replace(/^\+/, "")}?text=${encodeURIComponent(message)}`;
|
|
@@ -95863,10 +96379,11 @@ Interested?`;
|
|
|
95863
96379
|
};
|
|
95864
96380
|
}
|
|
95865
96381
|
const channelRow = db2.get("SELECT value FROM settings WHERE key = ?", ["outreach_channel"]);
|
|
95866
|
-
const
|
|
95867
|
-
const channel = requested === "sms" || requested === "whatsapp" ? requested : channelRow?.value || "whatsapp";
|
|
96382
|
+
const channel = normaliseChannel(input.channel) ?? normaliseChannel(channelRow?.value) ?? "email";
|
|
95868
96383
|
const template = outreachTemplate(db2);
|
|
95869
96384
|
const bookingTemplate = bookingOutreachTemplate(db2);
|
|
96385
|
+
const preferEmail = channel === "email";
|
|
96386
|
+
const linkChannel = channel === "email" ? "whatsapp" : channel;
|
|
95870
96387
|
const smtp = (0, email_1.smtpFromSettings)((k) => getDecryptedSetting(k));
|
|
95871
96388
|
const emailSubject = getDecryptedSetting("outreach_email_subject") || "A free demo website for {name}";
|
|
95872
96389
|
const prepared = [];
|
|
@@ -95875,7 +96392,7 @@ Interested?`;
|
|
|
95875
96392
|
const isBookingLead = r.lead_kind === "no_booking";
|
|
95876
96393
|
const message = (isBookingLead ? bookingTemplate : template).replace(/\{name\}/g, r.name).replace(/\{site_url\}/g, (isBookingLead ? r.booking_url : r.site_url) ?? r.site_url ?? "").replace(/\{booking_how\}/g, r.booking_platform || "WhatsApp/phone");
|
|
95877
96394
|
const e164 = toE164(r.phone ?? "");
|
|
95878
|
-
if (!
|
|
96395
|
+
if (!r.email && smtp && (preferEmail || !e164)) {
|
|
95879
96396
|
ctx.emitProgress?.({
|
|
95880
96397
|
channel: "outreach:progress",
|
|
95881
96398
|
payload: { msg: `Looking up an email for ${r.name}\u2026` }
|
|
@@ -95892,23 +96409,31 @@ Interested?`;
|
|
|
95892
96409
|
harvested++;
|
|
95893
96410
|
}
|
|
95894
96411
|
}
|
|
95895
|
-
|
|
96412
|
+
const leadEmail = smtp && r.email ? r.email : null;
|
|
96413
|
+
const useEmail = leadEmail !== null && (preferEmail || !e164);
|
|
96414
|
+
if (!useEmail && e164) {
|
|
95896
96415
|
prepared.push({
|
|
95897
96416
|
id: r.id,
|
|
95898
96417
|
name: r.name,
|
|
95899
96418
|
via: "phone",
|
|
95900
96419
|
phone: e164,
|
|
95901
|
-
url: outreachLink(
|
|
96420
|
+
url: outreachLink(linkChannel, e164, message),
|
|
95902
96421
|
message
|
|
95903
96422
|
});
|
|
95904
|
-
} else if (
|
|
96423
|
+
} else if (useEmail && smtp && leadEmail) {
|
|
95905
96424
|
const subject = emailSubject.replace(/\{name\}/g, r.name);
|
|
95906
|
-
const res = await (0, email_1.sendEmail)(smtp, { to:
|
|
96425
|
+
const res = await (0, email_1.sendEmail)(smtp, { to: leadEmail, subject, text: message });
|
|
96426
|
+
if (res.ok && res.messageId) {
|
|
96427
|
+
db2.run("UPDATE leads SET last_email_message_id = ? WHERE id = ?", [
|
|
96428
|
+
res.messageId,
|
|
96429
|
+
r.id
|
|
96430
|
+
]);
|
|
96431
|
+
}
|
|
95907
96432
|
prepared.push({
|
|
95908
96433
|
id: r.id,
|
|
95909
96434
|
name: r.name,
|
|
95910
96435
|
via: "email",
|
|
95911
|
-
email:
|
|
96436
|
+
email: leadEmail,
|
|
95912
96437
|
emailSent: res.ok,
|
|
95913
96438
|
emailError: res.ok ? void 0 : res.error,
|
|
95914
96439
|
message
|
|
@@ -95922,7 +96447,8 @@ Interested?`;
|
|
|
95922
96447
|
message
|
|
95923
96448
|
});
|
|
95924
96449
|
}
|
|
95925
|
-
const
|
|
96450
|
+
const last = prepared[prepared.length - 1];
|
|
96451
|
+
const reached = last.via === "phone" || last.via === "email" && last.emailSent;
|
|
95926
96452
|
if (reached) {
|
|
95927
96453
|
db2.run("UPDATE leads SET status = 'contacted', contacted_at = ? WHERE id = ?", [
|
|
95928
96454
|
(/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -95931,7 +96457,7 @@ Interested?`;
|
|
|
95931
96457
|
(0, followup_1.logContact)({
|
|
95932
96458
|
leadId: r.id,
|
|
95933
96459
|
direction: "out",
|
|
95934
|
-
channel:
|
|
96460
|
+
channel: last.via === "email" ? "email" : linkChannel
|
|
95935
96461
|
});
|
|
95936
96462
|
}
|
|
95937
96463
|
}
|
|
@@ -95939,7 +96465,7 @@ Interested?`;
|
|
|
95939
96465
|
const emailsSent = prepared.filter((p) => p.via === "email" && p.emailSent).length;
|
|
95940
96466
|
const emailsFailed = prepared.filter((p) => p.via === "email" && !p.emailSent).length;
|
|
95941
96467
|
const unreachable = prepared.filter((p) => p.via === "none").length;
|
|
95942
|
-
const smtpMissing = eligible.some((r) => !toE164(r.phone ?? "")
|
|
96468
|
+
const smtpMissing = !smtp && (preferEmail || eligible.some((r) => !toE164(r.phone ?? "")));
|
|
95943
96469
|
return {
|
|
95944
96470
|
ok: true,
|
|
95945
96471
|
channel,
|
|
@@ -95949,8 +96475,8 @@ Interested?`;
|
|
|
95949
96475
|
emailsFailed,
|
|
95950
96476
|
emailsFound: harvested,
|
|
95951
96477
|
unreachable,
|
|
95952
|
-
// Guide the user if
|
|
95953
|
-
note: smtpMissing ? "
|
|
96478
|
+
// Guide the user if leads were skipped for want of SMTP.
|
|
96479
|
+
note: smtpMissing ? "Email outreach needs SMTP, which isn't set up yet \u2014 add it in Sproutkit \u2192 Settings \u2192 Email outreach, or run 'sproutkit setup'." : void 0,
|
|
95954
96480
|
outreach: prepared
|
|
95955
96481
|
};
|
|
95956
96482
|
}
|
|
@@ -96206,7 +96732,9 @@ Interested?`;
|
|
|
96206
96732
|
paid: r.paid_at,
|
|
96207
96733
|
pdf: r.pdf_path
|
|
96208
96734
|
})),
|
|
96209
|
-
|
|
96735
|
+
// Use the agency's currency, not formatMoney's fallback — otherwise a
|
|
96736
|
+
// non-default agency sees the wrong symbol on their own total.
|
|
96737
|
+
outstanding: (0, agency_1.formatMoney)(outstanding, (0, agency_1.getAgencyProfile)().currency)
|
|
96210
96738
|
};
|
|
96211
96739
|
}
|
|
96212
96740
|
case "mark_invoice_paid": {
|
|
@@ -96241,6 +96769,77 @@ Interested?`;
|
|
|
96241
96769
|
return { ok: false, error: stats.error, business: lead.name };
|
|
96242
96770
|
return { ok: true, id, business: lead.name, url: base, ...stats.data };
|
|
96243
96771
|
}
|
|
96772
|
+
case "audit_sites": {
|
|
96773
|
+
const location = String(input.location ?? "").trim();
|
|
96774
|
+
const categories = input.categories ?? [];
|
|
96775
|
+
if (!location || categories.length === 0) {
|
|
96776
|
+
return { ok: false, error: "Give me a location and at least one business category." };
|
|
96777
|
+
}
|
|
96778
|
+
const placesKey = getDecryptedSetting("places_key");
|
|
96779
|
+
if (!placesKey)
|
|
96780
|
+
throw new Error("Google Places API key not set in Settings");
|
|
96781
|
+
ctx.emitProgress?.({
|
|
96782
|
+
channel: "leads:searching",
|
|
96783
|
+
payload: { msg: `Auditing websites in ${location}\u2026` }
|
|
96784
|
+
});
|
|
96785
|
+
const matches = await (0, places_1.geocodeForward)(location, 1);
|
|
96786
|
+
const place = matches[0];
|
|
96787
|
+
const result = await (0, lead_search_1.searchAndSaveLeadsStream)({
|
|
96788
|
+
placesKey,
|
|
96789
|
+
city: location,
|
|
96790
|
+
types: categories,
|
|
96791
|
+
maxResults: Math.min(Number(input.limit ?? 25), 100),
|
|
96792
|
+
center: place ? { lat: place.lat, lng: place.lng } : void 0,
|
|
96793
|
+
radiusMeters: Number(input.radiusMeters ?? 1e4),
|
|
96794
|
+
mode: "outdated"
|
|
96795
|
+
}, (lead) => ctx.emitProgress?.({ channel: "leads:found", payload: { lead } }));
|
|
96796
|
+
ctx.emitProgress?.({ channel: "leads:changed", payload: { reason: "audit_sites" } });
|
|
96797
|
+
const saved = db2.all(`SELECT id, name, website, site_score, site_issues
|
|
96798
|
+
FROM leads
|
|
96799
|
+
WHERE lead_kind = 'outdated' AND audited_at IS NOT NULL
|
|
96800
|
+
ORDER BY audited_at DESC, site_score DESC
|
|
96801
|
+
LIMIT ?`, [Number(input.limit ?? 25)]);
|
|
96802
|
+
return {
|
|
96803
|
+
ok: true,
|
|
96804
|
+
found: result.found,
|
|
96805
|
+
saved: result.saved,
|
|
96806
|
+
prospects: saved.map((r) => ({
|
|
96807
|
+
id: r.id,
|
|
96808
|
+
business: r.name,
|
|
96809
|
+
website: r.website,
|
|
96810
|
+
score: r.site_score,
|
|
96811
|
+
issues: JSON.parse(r.site_issues || "[]").slice(0, 3).map((i) => `${i.severity}: ${i.label}`)
|
|
96812
|
+
}))
|
|
96813
|
+
};
|
|
96814
|
+
}
|
|
96815
|
+
case "audit_one_site": {
|
|
96816
|
+
let url = input.url ?? "";
|
|
96817
|
+
let leadId = null;
|
|
96818
|
+
if (input.id != null) {
|
|
96819
|
+
leadId = Number(input.id);
|
|
96820
|
+
const lead = db2.get("SELECT id, name, website FROM leads WHERE id = ?", [leadId]);
|
|
96821
|
+
if (!lead)
|
|
96822
|
+
throw new Error(`Lead #${leadId} not found`);
|
|
96823
|
+
if (!lead.website)
|
|
96824
|
+
return { ok: false, error: `#${leadId} ${lead.name} has no website on record.` };
|
|
96825
|
+
url = lead.website;
|
|
96826
|
+
}
|
|
96827
|
+
if (!url)
|
|
96828
|
+
return { ok: false, error: "Give me a website URL or a lead id." };
|
|
96829
|
+
const audit = await (0, site_audit_1.auditSite)(url);
|
|
96830
|
+
if (leadId !== null) {
|
|
96831
|
+
db2.run("UPDATE leads SET site_score = ?, site_issues = ?, audited_at = ? WHERE id = ?", [audit.score, JSON.stringify(audit.issues), (/* @__PURE__ */ new Date()).toISOString(), leadId]);
|
|
96832
|
+
}
|
|
96833
|
+
return {
|
|
96834
|
+
ok: true,
|
|
96835
|
+
url: audit.url,
|
|
96836
|
+
reachable: audit.reachable,
|
|
96837
|
+
score: audit.score,
|
|
96838
|
+
worthRebuilding: (0, site_audit_1.isRebuildProspect)(audit),
|
|
96839
|
+
issues: audit.issues,
|
|
96840
|
+
error: audit.error
|
|
96841
|
+
};
|
|
96842
|
+
}
|
|
96244
96843
|
case "hand_over_site": {
|
|
96245
96844
|
const id = Number(input.id);
|
|
96246
96845
|
const lead = db2.get("SELECT id, name, site_url, booking_url FROM leads WHERE id = ?", [id]);
|
|
@@ -97269,111 +97868,59 @@ var require_vercel_store = __commonJS({
|
|
|
97269
97868
|
}
|
|
97270
97869
|
});
|
|
97271
97870
|
|
|
97272
|
-
//
|
|
97273
|
-
var
|
|
97274
|
-
|
|
97275
|
-
|
|
97276
|
-
|
|
97277
|
-
|
|
97278
|
-
|
|
97279
|
-
|
|
97280
|
-
|
|
97281
|
-
|
|
97282
|
-
|
|
97283
|
-
|
|
97284
|
-
|
|
97285
|
-
|
|
97286
|
-
|
|
97287
|
-
|
|
97288
|
-
|
|
97289
|
-
|
|
97290
|
-
|
|
97291
|
-
|
|
97292
|
-
|
|
97293
|
-
|
|
97294
|
-
|
|
97295
|
-
|
|
97296
|
-
|
|
97297
|
-
|
|
97298
|
-
|
|
97299
|
-
|
|
97300
|
-
|
|
97301
|
-
|
|
97302
|
-
|
|
97303
|
-
|
|
97304
|
-
|
|
97305
|
-
|
|
97306
|
-
|
|
97307
|
-
|
|
97308
|
-
|
|
97309
|
-
|
|
97310
|
-
|
|
97311
|
-
|
|
97312
|
-
|
|
97313
|
-
|
|
97871
|
+
// src/engine.ts
|
|
97872
|
+
var db, chat, chatTools, autoMode, cms, bookingPreset, builder, vercelStore, agency, followup, invoicing, models, llm, initDatabase, getDb, chatWithTools, runTool, TOOLS, startAutoJob, cancelAutoJob, provisionCmsForLead, generatePreset, deployBookingOnly, deployStandaloneBooking, handoverSite, createBlobStore, refreshModels, refreshIfStale, listCachedModels, getPreferredModel, getAgencyProfile, setAgencyProfile, agencyConfigured, formatMoney, dueFollowUps, outreachStats, contactHistory, renderLetterPdf, listInvoicesRaw, checkClaudeCodeAuth, llmBackend, claudeBin, CLAUDE_CODE_MODELS, getClaudeCodeModel;
|
|
97873
|
+
var init_engine = __esm({
|
|
97874
|
+
"src/engine.ts"() {
|
|
97875
|
+
"use strict";
|
|
97876
|
+
db = require_db();
|
|
97877
|
+
chat = require_chat();
|
|
97878
|
+
chatTools = require_chat_tools();
|
|
97879
|
+
autoMode = require_auto_mode();
|
|
97880
|
+
cms = require_cms_provision();
|
|
97881
|
+
bookingPreset = require_booking_preset();
|
|
97882
|
+
builder = require_builder();
|
|
97883
|
+
vercelStore = require_vercel_store();
|
|
97884
|
+
agency = require_agency();
|
|
97885
|
+
followup = require_followup();
|
|
97886
|
+
invoicing = require_invoicing();
|
|
97887
|
+
models = require_models();
|
|
97888
|
+
llm = require_llm();
|
|
97889
|
+
initDatabase = db.initDatabase;
|
|
97890
|
+
getDb = db.getDb;
|
|
97891
|
+
chatWithTools = chat.chatWithTools;
|
|
97892
|
+
runTool = chatTools.runTool;
|
|
97893
|
+
TOOLS = chatTools.TOOLS;
|
|
97894
|
+
startAutoJob = autoMode.startAutoJob;
|
|
97895
|
+
cancelAutoJob = autoMode.cancelAutoJob;
|
|
97896
|
+
provisionCmsForLead = cms.provisionCmsForLead;
|
|
97897
|
+
generatePreset = bookingPreset.generatePreset;
|
|
97898
|
+
deployBookingOnly = builder.deployBookingOnly;
|
|
97899
|
+
deployStandaloneBooking = builder.deployStandaloneBooking;
|
|
97900
|
+
handoverSite = builder.handoverSite;
|
|
97901
|
+
createBlobStore = vercelStore.createBlobStore;
|
|
97902
|
+
refreshModels = models.refreshModels;
|
|
97903
|
+
refreshIfStale = models.refreshIfStale;
|
|
97904
|
+
listCachedModels = models.listCachedModels;
|
|
97905
|
+
getPreferredModel = models.getPreferredModel;
|
|
97906
|
+
getAgencyProfile = agency.getAgencyProfile;
|
|
97907
|
+
setAgencyProfile = agency.setAgencyProfile;
|
|
97908
|
+
agencyConfigured = agency.agencyConfigured;
|
|
97909
|
+
formatMoney = agency.formatMoney;
|
|
97910
|
+
dueFollowUps = followup.dueFollowUps;
|
|
97911
|
+
outreachStats = followup.outreachStats;
|
|
97912
|
+
contactHistory = followup.contactHistory;
|
|
97913
|
+
renderLetterPdf = invoicing.renderLetterPdf;
|
|
97914
|
+
listInvoicesRaw = invoicing.listInvoices;
|
|
97915
|
+
checkClaudeCodeAuth = llm.checkClaudeCodeAuth;
|
|
97916
|
+
llmBackend = llm.getBackend;
|
|
97917
|
+
claudeBin = llm.claudeBin;
|
|
97918
|
+
CLAUDE_CODE_MODELS = llm.CLAUDE_CODE_MODELS;
|
|
97919
|
+
getClaudeCodeModel = llm.getClaudeCodeModel;
|
|
97314
97920
|
}
|
|
97315
97921
|
});
|
|
97316
97922
|
|
|
97317
|
-
// src/engine.ts
|
|
97318
|
-
var db = require_db();
|
|
97319
|
-
var chat = require_chat();
|
|
97320
|
-
var chatTools = require_chat_tools();
|
|
97321
|
-
var autoMode = require_auto_mode();
|
|
97322
|
-
var cms = require_cms_provision();
|
|
97323
|
-
var bookingPreset = require_booking_preset();
|
|
97324
|
-
var builder = require_builder();
|
|
97325
|
-
var vercelStore = require_vercel_store();
|
|
97326
|
-
var agency = require_agency();
|
|
97327
|
-
var followup = require_followup();
|
|
97328
|
-
var invoicing = require_invoicing();
|
|
97329
|
-
var models = require_models();
|
|
97330
|
-
var llm = require_llm();
|
|
97331
|
-
var initDatabase = db.initDatabase;
|
|
97332
|
-
var getDb = db.getDb;
|
|
97333
|
-
var chatWithTools = chat.chatWithTools;
|
|
97334
|
-
var runTool = chatTools.runTool;
|
|
97335
|
-
var startAutoJob = autoMode.startAutoJob;
|
|
97336
|
-
var cancelAutoJob = autoMode.cancelAutoJob;
|
|
97337
|
-
var provisionCmsForLead = cms.provisionCmsForLead;
|
|
97338
|
-
var generatePreset = bookingPreset.generatePreset;
|
|
97339
|
-
var deployBookingOnly = builder.deployBookingOnly;
|
|
97340
|
-
var deployStandaloneBooking = builder.deployStandaloneBooking;
|
|
97341
|
-
var handoverSite = builder.handoverSite;
|
|
97342
|
-
var createBlobStore = vercelStore.createBlobStore;
|
|
97343
|
-
var refreshModels = models.refreshModels;
|
|
97344
|
-
var refreshIfStale = models.refreshIfStale;
|
|
97345
|
-
var listCachedModels = models.listCachedModels;
|
|
97346
|
-
var getPreferredModel = models.getPreferredModel;
|
|
97347
|
-
var getAgencyProfile = agency.getAgencyProfile;
|
|
97348
|
-
var setAgencyProfile = agency.setAgencyProfile;
|
|
97349
|
-
var agencyConfigured = agency.agencyConfigured;
|
|
97350
|
-
var formatMoney = agency.formatMoney;
|
|
97351
|
-
var dueFollowUps = followup.dueFollowUps;
|
|
97352
|
-
var outreachStats = followup.outreachStats;
|
|
97353
|
-
var contactHistory = followup.contactHistory;
|
|
97354
|
-
var renderLetterPdf = invoicing.renderLetterPdf;
|
|
97355
|
-
var listInvoicesRaw = invoicing.listInvoices;
|
|
97356
|
-
var checkClaudeCodeAuth = llm.checkClaudeCodeAuth;
|
|
97357
|
-
var llmBackend = llm.getBackend;
|
|
97358
|
-
var claudeBin = llm.claudeBin;
|
|
97359
|
-
var CLAUDE_CODE_MODELS = llm.CLAUDE_CODE_MODELS;
|
|
97360
|
-
var getClaudeCodeModel = llm.getClaudeCodeModel;
|
|
97361
|
-
|
|
97362
97923
|
// src/config.ts
|
|
97363
|
-
var REQUIRED_KEYS = [
|
|
97364
|
-
{ key: "anthropic_key", label: "Anthropic API key", hint: "sk-ant-\u2026 \u2014 powers the chat + site generation", required: true, apiBackendOnly: true },
|
|
97365
|
-
{ key: "places_key", label: "Google Places API key", hint: "finds businesses, photos, reviews", required: true },
|
|
97366
|
-
{ key: "vercel_token", label: "Vercel token", hint: "deploys the generated sites", required: true },
|
|
97367
|
-
{ key: "blob_token", label: "Vercel Blob token", hint: "required for booking sites & CMS (stores form config/submissions)", required: false },
|
|
97368
|
-
{ key: "resend_key", label: "Resend API key", hint: "optional \u2014 emails the business owner when a booking comes in", required: false },
|
|
97369
|
-
// SMTP for email outreach — used per-lead when a business has no phone. All
|
|
97370
|
-
// optional; without them, email-only leads are simply skipped.
|
|
97371
|
-
{ key: "smtp_host", label: "SMTP host", hint: "optional \u2014 for email outreach, e.g. smtp.gmail.com", required: false },
|
|
97372
|
-
{ key: "smtp_port", label: "SMTP port", hint: "optional \u2014 587 (STARTTLS) or 465 (TLS); default 587", required: false },
|
|
97373
|
-
{ key: "smtp_user", label: "SMTP username", hint: "optional \u2014 your email login", required: false },
|
|
97374
|
-
{ key: "smtp_pass", label: "SMTP password", hint: "optional \u2014 password or app-password", required: false },
|
|
97375
|
-
{ key: "smtp_from", label: "Email 'From'", hint: "optional \u2014 e.g. You <you@domain.com>; defaults to the username", required: false }
|
|
97376
|
-
];
|
|
97377
97924
|
function getSetting(key) {
|
|
97378
97925
|
const row = getDb().get("SELECT value FROM settings WHERE key = ?", [key]);
|
|
97379
97926
|
return row?.value ?? null;
|
|
@@ -97398,81 +97945,29 @@ function missingRequiredKeys() {
|
|
|
97398
97945
|
return !getSetting(k.key);
|
|
97399
97946
|
}).map((k) => ({ key: k.key, label: k.label, hint: k.hint }));
|
|
97400
97947
|
}
|
|
97401
|
-
|
|
97402
|
-
|
|
97403
|
-
|
|
97404
|
-
|
|
97405
|
-
|
|
97406
|
-
|
|
97407
|
-
|
|
97408
|
-
}
|
|
97409
|
-
|
|
97410
|
-
|
|
97411
|
-
|
|
97412
|
-
|
|
97413
|
-
|
|
97414
|
-
|
|
97415
|
-
|
|
97416
|
-
|
|
97417
|
-
|
|
97418
|
-
|
|
97419
|
-
|
|
97420
|
-
});
|
|
97421
|
-
if (!r.ok) return null;
|
|
97422
|
-
return await r.json();
|
|
97423
|
-
} catch {
|
|
97424
|
-
return null;
|
|
97425
|
-
}
|
|
97426
|
-
}
|
|
97427
|
-
async function activate(key) {
|
|
97428
|
-
const trimmed = key.trim();
|
|
97429
|
-
const result = await callValidate(trimmed);
|
|
97430
|
-
if (!result) return { status: "missing" };
|
|
97431
|
-
if (!result.valid) {
|
|
97432
|
-
return {
|
|
97433
|
-
status: result.reason === "revoked" ? "revoked" : result.reason === "refunded" ? "refunded" : "missing",
|
|
97434
|
-
email: result.email
|
|
97435
|
-
};
|
|
97436
|
-
}
|
|
97437
|
-
setSetting("license_key", trimmed);
|
|
97438
|
-
setSetting("license_email", result.email ?? "");
|
|
97439
|
-
setSetting("license_validated_at", String(Date.now()));
|
|
97440
|
-
return { status: "active", email: result.email };
|
|
97441
|
-
}
|
|
97442
|
-
async function check() {
|
|
97443
|
-
const key = getSetting("license_key");
|
|
97444
|
-
if (!key) return { status: "missing" };
|
|
97445
|
-
const result = await callValidate(key);
|
|
97446
|
-
if (result) {
|
|
97447
|
-
if (result.valid) {
|
|
97448
|
-
setSetting("license_validated_at", String(Date.now()));
|
|
97449
|
-
return { status: "active", email: result.email };
|
|
97450
|
-
}
|
|
97451
|
-
return {
|
|
97452
|
-
status: result.reason === "revoked" ? "revoked" : result.reason === "refunded" ? "refunded" : "missing",
|
|
97453
|
-
email: result.email
|
|
97454
|
-
};
|
|
97948
|
+
var REQUIRED_KEYS;
|
|
97949
|
+
var init_config = __esm({
|
|
97950
|
+
"src/config.ts"() {
|
|
97951
|
+
"use strict";
|
|
97952
|
+
init_engine();
|
|
97953
|
+
REQUIRED_KEYS = [
|
|
97954
|
+
{ key: "anthropic_key", label: "Anthropic API key", hint: "sk-ant-\u2026 \u2014 powers the chat + site generation", required: true, apiBackendOnly: true },
|
|
97955
|
+
{ key: "places_key", label: "Google Places API key", hint: "finds businesses, photos, reviews", required: true },
|
|
97956
|
+
{ key: "vercel_token", label: "Vercel token", hint: "deploys the generated sites", required: true },
|
|
97957
|
+
{ key: "blob_token", label: "Vercel Blob token", hint: "required for booking sites & CMS (stores form config/submissions)", required: false },
|
|
97958
|
+
{ key: "resend_key", label: "Resend API key", hint: "optional \u2014 emails the business owner when a booking comes in", required: false },
|
|
97959
|
+
// SMTP for email outreach — used per-lead when a business has no phone. All
|
|
97960
|
+
// optional; without them, email-only leads are simply skipped.
|
|
97961
|
+
{ key: "smtp_host", label: "SMTP host", hint: "optional \u2014 for email outreach, e.g. smtp.gmail.com", required: false },
|
|
97962
|
+
{ key: "smtp_port", label: "SMTP port", hint: "optional \u2014 587 (STARTTLS) or 465 (TLS); default 587", required: false },
|
|
97963
|
+
{ key: "smtp_user", label: "SMTP username", hint: "optional \u2014 your email login", required: false },
|
|
97964
|
+
{ key: "smtp_pass", label: "SMTP password", hint: "optional \u2014 password or app-password", required: false },
|
|
97965
|
+
{ key: "smtp_from", label: "Email 'From'", hint: "optional \u2014 e.g. You <you@domain.com>; defaults to the username", required: false }
|
|
97966
|
+
];
|
|
97455
97967
|
}
|
|
97456
|
-
|
|
97457
|
-
if (Date.now() - last < GRACE_MS) return { status: "active" };
|
|
97458
|
-
return { status: "offline_grace_expired" };
|
|
97459
|
-
}
|
|
97968
|
+
});
|
|
97460
97969
|
|
|
97461
97970
|
// src/tty.ts
|
|
97462
|
-
var import_readline = __toESM(require("readline"));
|
|
97463
|
-
var useColor = process.stdout.isTTY && !process.env.NO_COLOR;
|
|
97464
|
-
var wrap = (code) => (s) => useColor ? `\x1B[${code}m${s}\x1B[0m` : s;
|
|
97465
|
-
var c = {
|
|
97466
|
-
green: wrap("38;5;65"),
|
|
97467
|
-
// moss, matches the brand
|
|
97468
|
-
greenBold: wrap("1;38;5;65"),
|
|
97469
|
-
dim: wrap("2"),
|
|
97470
|
-
bold: wrap("1"),
|
|
97471
|
-
red: wrap("31"),
|
|
97472
|
-
amber: wrap("33"),
|
|
97473
|
-
cyan: wrap("36")
|
|
97474
|
-
};
|
|
97475
|
-
var rl = null;
|
|
97476
97971
|
function iface() {
|
|
97477
97972
|
if (!rl) rl = import_readline.default.createInterface({ input: process.stdin, output: process.stdout });
|
|
97478
97973
|
return rl;
|
|
@@ -97543,124 +98038,718 @@ function onStopRequested(onStop) {
|
|
|
97543
98038
|
function say(msg = "") {
|
|
97544
98039
|
process.stdout.write(msg + "\n");
|
|
97545
98040
|
}
|
|
97546
|
-
var
|
|
97547
|
-
var
|
|
97548
|
-
|
|
97549
|
-
|
|
97550
|
-
|
|
97551
|
-
|
|
97552
|
-
|
|
97553
|
-
|
|
97554
|
-
|
|
97555
|
-
|
|
97556
|
-
|
|
97557
|
-
|
|
97558
|
-
|
|
98041
|
+
var import_readline, useColor, wrap, c, rl, FRAMES, Status, STATE_MARK, StatusBoard;
|
|
98042
|
+
var init_tty = __esm({
|
|
98043
|
+
"src/tty.ts"() {
|
|
98044
|
+
"use strict";
|
|
98045
|
+
import_readline = __toESM(require("readline"));
|
|
98046
|
+
useColor = process.stdout.isTTY && !process.env.NO_COLOR;
|
|
98047
|
+
wrap = (code) => (s) => useColor ? `\x1B[${code}m${s}\x1B[0m` : s;
|
|
98048
|
+
c = {
|
|
98049
|
+
green: wrap("38;5;65"),
|
|
98050
|
+
// moss, matches the brand
|
|
98051
|
+
greenBold: wrap("1;38;5;65"),
|
|
98052
|
+
dim: wrap("2"),
|
|
98053
|
+
bold: wrap("1"),
|
|
98054
|
+
red: wrap("31"),
|
|
98055
|
+
amber: wrap("33"),
|
|
98056
|
+
cyan: wrap("36")
|
|
98057
|
+
};
|
|
98058
|
+
rl = null;
|
|
98059
|
+
FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
98060
|
+
Status = class {
|
|
98061
|
+
timer = null;
|
|
98062
|
+
frame = 0;
|
|
98063
|
+
label = "";
|
|
98064
|
+
stage = "";
|
|
98065
|
+
tty = process.stdout.isTTY && useColor;
|
|
98066
|
+
start(label) {
|
|
98067
|
+
this.label = label;
|
|
98068
|
+
this.stage = "";
|
|
98069
|
+
if (!this.tty) {
|
|
98070
|
+
say(c.cyan(` \u27F3 ${label}`));
|
|
98071
|
+
return;
|
|
98072
|
+
}
|
|
98073
|
+
this.render();
|
|
98074
|
+
this.timer = setInterval(() => {
|
|
98075
|
+
this.frame = (this.frame + 1) % FRAMES.length;
|
|
98076
|
+
this.render();
|
|
98077
|
+
}, 80);
|
|
98078
|
+
}
|
|
98079
|
+
// Update the current stage (e.g. "Generating site with Claude…").
|
|
98080
|
+
update(stage) {
|
|
98081
|
+
this.stage = stage;
|
|
98082
|
+
if (!this.tty) {
|
|
98083
|
+
say(c.dim(` \u2026 ${stage}`));
|
|
98084
|
+
return;
|
|
98085
|
+
}
|
|
98086
|
+
this.render();
|
|
98087
|
+
}
|
|
98088
|
+
render() {
|
|
98089
|
+
const spin = c.cyan(FRAMES[this.frame]);
|
|
98090
|
+
const stage = this.stage ? c.dim(` \xB7 ${this.stage}`) : "";
|
|
98091
|
+
process.stdout.write(`\r\x1B[2K ${spin} ${this.label}${stage}`);
|
|
98092
|
+
}
|
|
98093
|
+
// Stop with a terminal state, leaving one clean line behind.
|
|
98094
|
+
done(ok, finalLabel) {
|
|
98095
|
+
if (this.timer) {
|
|
98096
|
+
clearInterval(this.timer);
|
|
98097
|
+
this.timer = null;
|
|
98098
|
+
}
|
|
98099
|
+
const label = finalLabel ?? this.label;
|
|
98100
|
+
const mark2 = ok ? c.green("\u2713") : c.red("\u2717");
|
|
98101
|
+
if (this.tty) process.stdout.write(`\r\x1B[2K ${mark2} ${label}
|
|
98102
|
+
`);
|
|
98103
|
+
else say(` ${mark2} ${label}`);
|
|
98104
|
+
}
|
|
98105
|
+
};
|
|
98106
|
+
STATE_MARK = {
|
|
98107
|
+
queued: () => c.dim("\xB7"),
|
|
98108
|
+
building: () => c.cyan(""),
|
|
98109
|
+
// spinner frame filled in at render time
|
|
98110
|
+
built: () => c.green("\u2713"),
|
|
98111
|
+
failed: () => c.red("\u2717"),
|
|
98112
|
+
skipped: () => c.dim("\u2013")
|
|
98113
|
+
};
|
|
98114
|
+
StatusBoard = class {
|
|
98115
|
+
rows = [];
|
|
98116
|
+
frame = 0;
|
|
98117
|
+
timer = null;
|
|
98118
|
+
lastLineCount = 0;
|
|
98119
|
+
tty = process.stdout.isTTY && useColor;
|
|
98120
|
+
// Non-TTY: remember the last printed signature per row so we only log changes.
|
|
98121
|
+
lastSig = /* @__PURE__ */ new Map();
|
|
98122
|
+
header = "";
|
|
98123
|
+
start(header, rows) {
|
|
98124
|
+
this.header = header;
|
|
98125
|
+
this.rows = rows;
|
|
98126
|
+
if (!this.tty) {
|
|
98127
|
+
say(c.cyan(` \u27F3 ${header}`));
|
|
98128
|
+
this.rows.forEach((r) => this.logRowIfChanged(r));
|
|
98129
|
+
return;
|
|
98130
|
+
}
|
|
98131
|
+
say(c.cyan(` \u27F3 ${header}`));
|
|
98132
|
+
this.render();
|
|
98133
|
+
this.timer = setInterval(() => {
|
|
98134
|
+
this.frame = (this.frame + 1) % FRAMES.length;
|
|
98135
|
+
this.render();
|
|
98136
|
+
}, 90);
|
|
98137
|
+
}
|
|
98138
|
+
update(row) {
|
|
98139
|
+
const i = this.rows.findIndex((r) => r.key === row.key);
|
|
98140
|
+
if (i >= 0) this.rows[i] = row;
|
|
98141
|
+
else this.rows.push(row);
|
|
98142
|
+
if (!this.tty) this.logRowIfChanged(row);
|
|
98143
|
+
else this.render();
|
|
98144
|
+
}
|
|
98145
|
+
// Replace the whole set at once (e.g. from a job snapshot).
|
|
98146
|
+
set(rows) {
|
|
98147
|
+
this.rows = rows;
|
|
98148
|
+
if (!this.tty) rows.forEach((r) => this.logRowIfChanged(r));
|
|
98149
|
+
else this.render();
|
|
98150
|
+
}
|
|
98151
|
+
line(r) {
|
|
98152
|
+
const mark2 = r.state === "building" ? c.cyan(FRAMES[this.frame]) : STATE_MARK[r.state]();
|
|
98153
|
+
const detail = r.detail ? c.dim(` \xB7 ${r.detail}`) : "";
|
|
98154
|
+
return ` ${mark2} ${r.label}${detail}`;
|
|
98155
|
+
}
|
|
98156
|
+
logRowIfChanged(r) {
|
|
98157
|
+
const sig = `${r.state}:${r.detail ?? ""}`;
|
|
98158
|
+
if (this.lastSig.get(r.key) === sig) return;
|
|
98159
|
+
this.lastSig.set(r.key, sig);
|
|
98160
|
+
const mark2 = r.state === "built" ? "\u2713" : r.state === "failed" ? "\u2717" : r.state === "skipped" ? "\u2013" : "\u2026";
|
|
98161
|
+
say(` ${mark2} ${r.label}${r.detail ? ` \xB7 ${r.detail}` : ""}`);
|
|
98162
|
+
}
|
|
98163
|
+
render() {
|
|
98164
|
+
if (this.lastLineCount > 0) process.stdout.write(`\x1B[${this.lastLineCount}A`);
|
|
98165
|
+
const out = this.rows.map((r) => `\x1B[2K${this.line(r)}`).join("\n");
|
|
98166
|
+
process.stdout.write(out + "\n");
|
|
98167
|
+
this.lastLineCount = this.rows.length;
|
|
98168
|
+
}
|
|
98169
|
+
stop() {
|
|
98170
|
+
if (this.timer) {
|
|
98171
|
+
clearInterval(this.timer);
|
|
98172
|
+
this.timer = null;
|
|
98173
|
+
}
|
|
98174
|
+
if (this.tty) this.render();
|
|
98175
|
+
}
|
|
98176
|
+
};
|
|
98177
|
+
}
|
|
98178
|
+
});
|
|
98179
|
+
|
|
98180
|
+
// src/desktop-install.ts
|
|
98181
|
+
var desktop_install_exports = {};
|
|
98182
|
+
__export(desktop_install_exports, {
|
|
98183
|
+
desktopInstallPath: () => desktopInstallPath,
|
|
98184
|
+
desktopSupported: () => desktopSupported,
|
|
98185
|
+
installDesktop: () => installDesktop,
|
|
98186
|
+
openDesktop: () => openDesktop,
|
|
98187
|
+
runDesktopCommand: () => runDesktopCommand
|
|
98188
|
+
});
|
|
98189
|
+
function installCandidates() {
|
|
98190
|
+
const home = import_os3.default.homedir();
|
|
98191
|
+
if (process.platform === "darwin") {
|
|
98192
|
+
const override = process.env.SPROUTKIT_DESKTOP_DIR;
|
|
98193
|
+
if (override) return [import_path2.default.join(override, "Sproutkit.app")];
|
|
98194
|
+
return ["/Applications/Sproutkit.app", import_path2.default.join(home, "Applications", "Sproutkit.app")];
|
|
98195
|
+
}
|
|
98196
|
+
if (process.platform === "win32") {
|
|
98197
|
+
const local = process.env.LOCALAPPDATA || import_path2.default.join(home, "AppData", "Local");
|
|
98198
|
+
const progs = [process.env.ProgramFiles, process.env["ProgramFiles(x86)"]].filter(Boolean);
|
|
98199
|
+
return [
|
|
98200
|
+
import_path2.default.join(local, "Programs", "Sproutkit", "Sproutkit.exe"),
|
|
98201
|
+
...progs.map((p) => import_path2.default.join(p, "Sproutkit", "Sproutkit.exe"))
|
|
98202
|
+
];
|
|
98203
|
+
}
|
|
98204
|
+
return [];
|
|
98205
|
+
}
|
|
98206
|
+
function desktopSupported() {
|
|
98207
|
+
return process.platform === "darwin" || process.platform === "win32";
|
|
98208
|
+
}
|
|
98209
|
+
function desktopInstallPath() {
|
|
98210
|
+
return installCandidates().find((p) => import_fs2.default.existsSync(p)) ?? null;
|
|
98211
|
+
}
|
|
98212
|
+
function pickAsset(assets) {
|
|
98213
|
+
if (process.platform === "darwin") {
|
|
98214
|
+
const dmgs = assets.filter((a) => a.name.endsWith(".dmg"));
|
|
98215
|
+
return process.arch === "arm64" ? dmgs.find((a) => a.name.includes("arm64")) : dmgs.find((a) => !a.name.includes("arm64"));
|
|
98216
|
+
}
|
|
98217
|
+
if (process.platform === "win32") return assets.find((a) => a.name.endsWith(".exe"));
|
|
98218
|
+
return void 0;
|
|
98219
|
+
}
|
|
98220
|
+
async function latestRelease() {
|
|
98221
|
+
try {
|
|
98222
|
+
const r = await fetch(RELEASES_API, {
|
|
98223
|
+
headers: { Accept: "application/vnd.github+json", "User-Agent": "sproutkit-code" },
|
|
98224
|
+
signal: AbortSignal.timeout(1e4)
|
|
98225
|
+
});
|
|
98226
|
+
if (!r.ok) return { error: `GitHub answered ${r.status}` };
|
|
98227
|
+
const j = await r.json();
|
|
98228
|
+
const asset = pickAsset(j.assets ?? []);
|
|
98229
|
+
if (!asset) return { error: `No ${process.platform}/${process.arch} build in release ${j.tag_name}` };
|
|
98230
|
+
return { version: j.tag_name.replace(/^v/, ""), asset };
|
|
98231
|
+
} catch (e) {
|
|
98232
|
+
return { error: e.message };
|
|
98233
|
+
}
|
|
98234
|
+
}
|
|
98235
|
+
async function download(url, dest, total) {
|
|
98236
|
+
const r = await fetch(url, { redirect: "follow" });
|
|
98237
|
+
if (!r.ok || !r.body) throw new Error(`download failed (${r.status})`);
|
|
98238
|
+
const out = import_fs2.default.createWriteStream(dest);
|
|
98239
|
+
const tty = process.stdout.isTTY;
|
|
98240
|
+
let got = 0;
|
|
98241
|
+
let lastPct = -1;
|
|
98242
|
+
const reader = r.body.getReader();
|
|
98243
|
+
try {
|
|
98244
|
+
while (true) {
|
|
98245
|
+
const { done, value } = await reader.read();
|
|
98246
|
+
if (done) break;
|
|
98247
|
+
got += value.length;
|
|
98248
|
+
if (!out.write(value)) await new Promise((res) => out.once("drain", () => res()));
|
|
98249
|
+
const pct = total ? Math.floor(got / total * 100) : 0;
|
|
98250
|
+
if (tty && pct !== lastPct) {
|
|
98251
|
+
lastPct = pct;
|
|
98252
|
+
const mb = (n) => (n / 1048576).toFixed(0);
|
|
98253
|
+
process.stdout.write(`\r ${c.dim(`Downloading\u2026 ${pct}% (${mb(got)} / ${mb(total)} MB)`)}`);
|
|
98254
|
+
}
|
|
97559
98255
|
}
|
|
97560
|
-
|
|
97561
|
-
|
|
97562
|
-
|
|
97563
|
-
|
|
97564
|
-
|
|
97565
|
-
|
|
97566
|
-
|
|
97567
|
-
|
|
97568
|
-
|
|
97569
|
-
|
|
97570
|
-
|
|
97571
|
-
|
|
98256
|
+
} finally {
|
|
98257
|
+
await new Promise((res, rej) => out.end((err) => err ? rej(err) : res()));
|
|
98258
|
+
if (tty) process.stdout.write("\n");
|
|
98259
|
+
}
|
|
98260
|
+
if (total && got !== total) throw new Error(`download incomplete (${got} of ${total} bytes)`);
|
|
98261
|
+
}
|
|
98262
|
+
function run(cmd, args) {
|
|
98263
|
+
const r = (0, import_child_process.spawnSync)(cmd, args, { encoding: "utf-8" });
|
|
98264
|
+
return { ok: r.status === 0, out: `${r.stdout ?? ""}${r.stderr ?? ""}`.trim() };
|
|
98265
|
+
}
|
|
98266
|
+
function canWrite(dir) {
|
|
98267
|
+
try {
|
|
98268
|
+
import_fs2.default.accessSync(dir, import_fs2.default.constants.W_OK);
|
|
98269
|
+
return true;
|
|
98270
|
+
} catch {
|
|
98271
|
+
return false;
|
|
98272
|
+
}
|
|
98273
|
+
}
|
|
98274
|
+
function installMac(dmg) {
|
|
98275
|
+
const mount = import_fs2.default.mkdtempSync(import_path2.default.join(import_os3.default.tmpdir(), "sproutkit-mnt-"));
|
|
98276
|
+
const attach = run("hdiutil", ["attach", dmg, "-nobrowse", "-readonly", "-mountpoint", mount]);
|
|
98277
|
+
if (!attach.ok) throw new Error(`couldn't open the disk image: ${attach.out}`);
|
|
98278
|
+
try {
|
|
98279
|
+
const src = import_path2.default.join(mount, "Sproutkit.app");
|
|
98280
|
+
if (!import_fs2.default.existsSync(src)) throw new Error("Sproutkit.app not found in the disk image");
|
|
98281
|
+
const destDir = process.env.SPROUTKIT_DESKTOP_DIR || (canWrite("/Applications") ? "/Applications" : import_path2.default.join(import_os3.default.homedir(), "Applications"));
|
|
98282
|
+
import_fs2.default.mkdirSync(destDir, { recursive: true });
|
|
98283
|
+
const dest = import_path2.default.join(destDir, "Sproutkit.app");
|
|
98284
|
+
import_fs2.default.rmSync(dest, { recursive: true, force: true });
|
|
98285
|
+
const copy = run("ditto", [src, dest]);
|
|
98286
|
+
if (!copy.ok) throw new Error(`couldn't copy the app: ${copy.out}`);
|
|
98287
|
+
run("xattr", ["-cr", dest]);
|
|
98288
|
+
return dest;
|
|
98289
|
+
} finally {
|
|
98290
|
+
run("hdiutil", ["detach", mount, "-quiet"]);
|
|
98291
|
+
import_fs2.default.rmSync(mount, { recursive: true, force: true });
|
|
98292
|
+
}
|
|
98293
|
+
}
|
|
98294
|
+
function installWindows(exe) {
|
|
98295
|
+
const r = run(exe, ["/S"]);
|
|
98296
|
+
if (!r.ok) throw new Error(`installer exited with an error${r.out ? `: ${r.out}` : ""}`);
|
|
98297
|
+
const p = desktopInstallPath();
|
|
98298
|
+
if (!p) throw new Error("installer finished but Sproutkit.exe wasn't found");
|
|
98299
|
+
return p;
|
|
98300
|
+
}
|
|
98301
|
+
async function installDesktop() {
|
|
98302
|
+
if (!desktopSupported()) {
|
|
98303
|
+
return { ok: false, error: "The desktop app is only available for macOS and Windows." };
|
|
98304
|
+
}
|
|
98305
|
+
say(c.dim(" Finding the latest desktop release\u2026"));
|
|
98306
|
+
const rel = await latestRelease();
|
|
98307
|
+
if ("error" in rel) return { ok: false, error: `Couldn't find a download: ${rel.error}` };
|
|
98308
|
+
const tmp = import_fs2.default.mkdtempSync(import_path2.default.join(import_os3.default.tmpdir(), "sproutkit-dl-"));
|
|
98309
|
+
const file = import_path2.default.join(tmp, rel.asset.name);
|
|
98310
|
+
try {
|
|
98311
|
+
await download(rel.asset.browser_download_url, file, rel.asset.size);
|
|
98312
|
+
say(c.dim(" Installing\u2026"));
|
|
98313
|
+
const dest = process.platform === "darwin" ? installMac(file) : installWindows(file);
|
|
98314
|
+
return { ok: true, path: dest, version: rel.version };
|
|
98315
|
+
} catch (e) {
|
|
98316
|
+
return { ok: false, error: e.message };
|
|
98317
|
+
} finally {
|
|
98318
|
+
import_fs2.default.rmSync(tmp, { recursive: true, force: true });
|
|
98319
|
+
}
|
|
98320
|
+
}
|
|
98321
|
+
function openDesktop() {
|
|
98322
|
+
const p = desktopInstallPath();
|
|
98323
|
+
if (!p) return false;
|
|
98324
|
+
const r = process.platform === "darwin" ? (0, import_child_process.spawnSync)("open", [p], { stdio: "ignore" }) : (0, import_child_process.spawnSync)("cmd", ["/c", "start", "", p], { stdio: "ignore" });
|
|
98325
|
+
return r.status === 0;
|
|
98326
|
+
}
|
|
98327
|
+
async function runDesktopCommand(args) {
|
|
98328
|
+
const existing = desktopInstallPath();
|
|
98329
|
+
if (existing && !args.includes("--update")) {
|
|
98330
|
+
say(c.green(` \u2713 The desktop app is installed (${existing}).`));
|
|
98331
|
+
if (!args.includes("--no-open") && openDesktop()) say(c.dim(" Opening it now."));
|
|
98332
|
+
say(c.dim(" Run 'sproutkit desktop --update' to reinstall the latest version."));
|
|
98333
|
+
return;
|
|
98334
|
+
}
|
|
98335
|
+
const res = await installDesktop();
|
|
98336
|
+
if (!res.ok) {
|
|
98337
|
+
say(c.red(` ${res.error}`));
|
|
98338
|
+
say(c.dim(" You can also download it from https://sproutkit.app/install"));
|
|
98339
|
+
process.exitCode = 1;
|
|
98340
|
+
return;
|
|
98341
|
+
}
|
|
98342
|
+
say(c.green(` \u2713 Sproutkit ${res.version} installed to ${res.path}`));
|
|
98343
|
+
if (!args.includes("--no-open") && openDesktop()) say(c.dim(" Opening it now."));
|
|
98344
|
+
}
|
|
98345
|
+
var import_fs2, import_os3, import_path2, import_child_process, RELEASES_API;
|
|
98346
|
+
var init_desktop_install = __esm({
|
|
98347
|
+
"src/desktop-install.ts"() {
|
|
98348
|
+
"use strict";
|
|
98349
|
+
import_fs2 = __toESM(require("fs"));
|
|
98350
|
+
import_os3 = __toESM(require("os"));
|
|
98351
|
+
import_path2 = __toESM(require("path"));
|
|
98352
|
+
import_child_process = require("child_process");
|
|
98353
|
+
init_tty();
|
|
98354
|
+
RELEASES_API = "https://api.github.com/repos/shaz2k/sproutkit-downloads/releases/latest";
|
|
98355
|
+
}
|
|
98356
|
+
});
|
|
98357
|
+
|
|
98358
|
+
// package.json
|
|
98359
|
+
var require_package2 = __commonJS({
|
|
98360
|
+
"package.json"(exports2, module2) {
|
|
98361
|
+
module2.exports = {
|
|
98362
|
+
name: "sproutkit-code",
|
|
98363
|
+
version: "1.9.0",
|
|
98364
|
+
description: "Sproutkit in your terminal \u2014 find leads, build sites, run outreach, all via chat.",
|
|
98365
|
+
bin: {
|
|
98366
|
+
sproutkit: "./dist/index.js"
|
|
98367
|
+
},
|
|
98368
|
+
type: "commonjs",
|
|
98369
|
+
files: [
|
|
98370
|
+
"dist",
|
|
98371
|
+
"README.md"
|
|
98372
|
+
],
|
|
98373
|
+
engines: {
|
|
98374
|
+
node: ">=18"
|
|
98375
|
+
},
|
|
98376
|
+
keywords: [
|
|
98377
|
+
"sproutkit",
|
|
98378
|
+
"leads",
|
|
98379
|
+
"websites",
|
|
98380
|
+
"cli",
|
|
98381
|
+
"ai"
|
|
98382
|
+
],
|
|
98383
|
+
scripts: {
|
|
98384
|
+
dev: "tsc && node dist/index.js",
|
|
98385
|
+
build: "node build.mjs && chmod +x dist/index.js",
|
|
98386
|
+
typecheck: "tsc --noEmit",
|
|
98387
|
+
prepublishOnly: "cd ../desktop && npm run build:main && cd ../sproutkit-code && npm run build"
|
|
98388
|
+
},
|
|
98389
|
+
dependencies: {
|
|
98390
|
+
"@anthropic-ai/sdk": "^0.30.1",
|
|
98391
|
+
axios: "^1.7.1",
|
|
98392
|
+
"node-sqlite3-wasm": "^0.8.20",
|
|
98393
|
+
pdfkit: "^0.20.1"
|
|
98394
|
+
},
|
|
98395
|
+
devDependencies: {
|
|
98396
|
+
"@types/node": "^20.14.0",
|
|
98397
|
+
typescript: "^5.4.0"
|
|
98398
|
+
}
|
|
98399
|
+
};
|
|
98400
|
+
}
|
|
98401
|
+
});
|
|
98402
|
+
|
|
98403
|
+
// src/invoke-ipc.ts
|
|
98404
|
+
async function requireBlobToken(vercelToken, emit2, leadId) {
|
|
98405
|
+
const existing = getSetting("blob_token");
|
|
98406
|
+
if (existing) return existing;
|
|
98407
|
+
emit2("bookings:progress", { leadId, msg: "No Blob token yet \u2014 creating a Blob store for you\u2026" });
|
|
98408
|
+
const created = await createBlobStore({ vercelToken, name: "sproutkit" });
|
|
98409
|
+
if (created.ok) {
|
|
98410
|
+
throw new Error(
|
|
98411
|
+
"Created a Vercel Blob store for you \u2713 \u2014 one last one-time step: open " + (created.dashboardUrl || "https://vercel.com/dashboard/stores") + " , open the 'sproutkit' store, copy its BLOB_READ_WRITE_TOKEN, then run 'sproutkit setup' and paste it. You only do this once \u2014 it's reused for every booking site."
|
|
98412
|
+
);
|
|
98413
|
+
}
|
|
98414
|
+
if (created.alreadyExists) {
|
|
98415
|
+
throw new Error(
|
|
98416
|
+
"You already have a Blob store. Open https://vercel.com/dashboard/stores , copy its BLOB_READ_WRITE_TOKEN, and run 'sproutkit setup' to paste it (one-time \u2014 reused for all sites)."
|
|
98417
|
+
);
|
|
98418
|
+
}
|
|
98419
|
+
throw new Error(
|
|
98420
|
+
`Booking needs a Vercel Blob token and I couldn't auto-create a store (${created.error ?? "unknown"}). Create one at https://vercel.com/dashboard/stores (Create \u2192 Blob), copy BLOB_READ_WRITE_TOKEN, then 'sproutkit setup'.`
|
|
98421
|
+
);
|
|
98422
|
+
}
|
|
98423
|
+
function makeInvokeIpc(emit2) {
|
|
98424
|
+
return async (channel, payload) => {
|
|
98425
|
+
if (channel === "auto:build:start") {
|
|
98426
|
+
const args = payload;
|
|
98427
|
+
const anthropicKey = getSetting("anthropic_key");
|
|
98428
|
+
const vercelToken = getSetting("vercel_token");
|
|
98429
|
+
const placesKey = getSetting("places_key");
|
|
98430
|
+
if (!anthropicKey) throw new Error("Anthropic API key not set");
|
|
98431
|
+
if (!vercelToken) throw new Error("Vercel token not set");
|
|
98432
|
+
return startAutoJob({
|
|
98433
|
+
leadIds: args.leadIds,
|
|
98434
|
+
concurrency: args.concurrency,
|
|
98435
|
+
anthropicKey,
|
|
98436
|
+
vercelToken,
|
|
98437
|
+
placesKey,
|
|
98438
|
+
emit: emit2
|
|
98439
|
+
});
|
|
97572
98440
|
}
|
|
97573
|
-
|
|
98441
|
+
if (channel === "cms:provision") {
|
|
98442
|
+
const leadId = Number(payload);
|
|
98443
|
+
const db2 = getDb();
|
|
98444
|
+
const lead = db2.get("SELECT * FROM leads WHERE id = ?", [leadId]);
|
|
98445
|
+
if (!lead) throw new Error("Lead not found");
|
|
98446
|
+
const placesKey = getSetting("places_key");
|
|
98447
|
+
const vercelToken = getSetting("vercel_token");
|
|
98448
|
+
const licenseKey = getSetting("license_key");
|
|
98449
|
+
const apiBaseUrl = process.env.SPROUTKIT_API_BASE_URL ?? "https://sproutkit.app";
|
|
98450
|
+
if (!vercelToken) throw new Error("Vercel token not set");
|
|
98451
|
+
emit2("cms:progress", { leadId, msg: "Starting\u2026" });
|
|
98452
|
+
const result = await provisionCmsForLead({
|
|
98453
|
+
lead,
|
|
98454
|
+
placesKey,
|
|
98455
|
+
vercelToken,
|
|
98456
|
+
apiBaseUrl,
|
|
98457
|
+
licenseKey,
|
|
98458
|
+
onProgress: (msg) => emit2("cms:progress", { leadId, msg })
|
|
98459
|
+
});
|
|
98460
|
+
db2.run("UPDATE leads SET site_url = ?, status = 'won' WHERE id = ?", [
|
|
98461
|
+
result.publicUrl,
|
|
98462
|
+
leadId
|
|
98463
|
+
]);
|
|
98464
|
+
emit2("cms:done", { leadId, ok: true, ...result });
|
|
98465
|
+
return result;
|
|
98466
|
+
}
|
|
98467
|
+
if (channel === "bookings:provision") {
|
|
98468
|
+
const p = payload;
|
|
98469
|
+
const db2 = getDb();
|
|
98470
|
+
const lead = db2.get("SELECT * FROM leads WHERE id = ?", [p.leadId]);
|
|
98471
|
+
if (!lead) throw new Error("Lead not found");
|
|
98472
|
+
const anthropicKey = getSetting("anthropic_key");
|
|
98473
|
+
const vercelToken = getSetting("vercel_token");
|
|
98474
|
+
const resendKey = getSetting("resend_key");
|
|
98475
|
+
if (!anthropicKey) throw new Error("Anthropic API key not set");
|
|
98476
|
+
if (!vercelToken) throw new Error("Vercel token not set");
|
|
98477
|
+
const blobToken = await requireBlobToken(vercelToken, emit2, p.leadId);
|
|
98478
|
+
emit2("bookings:progress", { leadId: p.leadId, msg: "Designing the booking form\u2026" });
|
|
98479
|
+
const leadInfo = lead;
|
|
98480
|
+
const config = await generatePreset({
|
|
98481
|
+
anthropicKey,
|
|
98482
|
+
lead: { name: leadInfo.name, type: leadInfo.type, city: leadInfo.city },
|
|
98483
|
+
instructions: p.instructions,
|
|
98484
|
+
archetypeOverride: p.archetypeOverride
|
|
98485
|
+
});
|
|
98486
|
+
const result = await deployBookingOnly({
|
|
98487
|
+
lead,
|
|
98488
|
+
vercelToken,
|
|
98489
|
+
blobToken,
|
|
98490
|
+
resendKey: resendKey || "",
|
|
98491
|
+
ownerEmail: p.ownerEmail ?? "",
|
|
98492
|
+
bookingConfig: config,
|
|
98493
|
+
anthropicKey,
|
|
98494
|
+
onProgress: (msg) => emit2("bookings:progress", { leadId: p.leadId, msg })
|
|
98495
|
+
});
|
|
98496
|
+
db2.run(
|
|
98497
|
+
"UPDATE leads SET booking_url = ?, owner_email = ?, booking_archetype = ?, booking_config = ? WHERE id = ?",
|
|
98498
|
+
[
|
|
98499
|
+
result.bookingUrl,
|
|
98500
|
+
p.ownerEmail ?? "",
|
|
98501
|
+
config.archetype,
|
|
98502
|
+
JSON.stringify(config),
|
|
98503
|
+
p.leadId
|
|
98504
|
+
]
|
|
98505
|
+
);
|
|
98506
|
+
emit2("bookings:done", { leadId: p.leadId, ...result });
|
|
98507
|
+
return result;
|
|
98508
|
+
}
|
|
98509
|
+
if (channel === "bookings:provision-standalone") {
|
|
98510
|
+
const p = payload;
|
|
98511
|
+
const db2 = getDb();
|
|
98512
|
+
const lead = db2.get("SELECT * FROM leads WHERE id = ?", [p.leadId]);
|
|
98513
|
+
if (!lead) throw new Error("Lead not found");
|
|
98514
|
+
const vercelToken = getSetting("vercel_token");
|
|
98515
|
+
const resendKey = getSetting("resend_key");
|
|
98516
|
+
if (!vercelToken) throw new Error("Vercel token not set");
|
|
98517
|
+
const blobToken = await requireBlobToken(vercelToken, emit2, p.leadId);
|
|
98518
|
+
emit2("bookings:progress", { leadId: p.leadId, msg: "Designing the booking form\u2026" });
|
|
98519
|
+
const leadInfo = lead;
|
|
98520
|
+
const config = await generatePreset({
|
|
98521
|
+
anthropicKey: getSetting("anthropic_key") ?? "",
|
|
98522
|
+
lead: { name: leadInfo.name, type: leadInfo.type, city: leadInfo.city },
|
|
98523
|
+
instructions: p.instructions,
|
|
98524
|
+
archetypeOverride: p.archetypeOverride
|
|
98525
|
+
});
|
|
98526
|
+
const result = await deployStandaloneBooking({
|
|
98527
|
+
lead,
|
|
98528
|
+
vercelToken,
|
|
98529
|
+
blobToken,
|
|
98530
|
+
resendKey: resendKey || "",
|
|
98531
|
+
ownerEmail: p.ownerEmail ?? "",
|
|
98532
|
+
bookingConfig: config,
|
|
98533
|
+
reuseAdminPassword: lead.booking_admin_password ?? null,
|
|
98534
|
+
onProgress: (msg) => emit2("bookings:progress", { leadId: p.leadId, msg })
|
|
98535
|
+
});
|
|
98536
|
+
db2.run(
|
|
98537
|
+
`UPDATE leads SET booking_url = ?, owner_email = ?, booking_archetype = ?, booking_config = ?,
|
|
98538
|
+
booking_admin_url = ?, booking_admin_password = ?,
|
|
98539
|
+
status = CASE WHEN status = 'discovered' THEN 'site_built' ELSE status END
|
|
98540
|
+
WHERE id = ?`,
|
|
98541
|
+
[
|
|
98542
|
+
result.bookingUrl,
|
|
98543
|
+
p.ownerEmail ?? "",
|
|
98544
|
+
config.archetype,
|
|
98545
|
+
JSON.stringify(config),
|
|
98546
|
+
result.admin.url,
|
|
98547
|
+
result.admin.password,
|
|
98548
|
+
p.leadId
|
|
98549
|
+
]
|
|
98550
|
+
);
|
|
98551
|
+
emit2("bookings:done", { leadId: p.leadId, ...result });
|
|
98552
|
+
return result;
|
|
98553
|
+
}
|
|
98554
|
+
if (channel === "site:handover") {
|
|
98555
|
+
const p = payload;
|
|
98556
|
+
const db2 = getDb();
|
|
98557
|
+
const lead = db2.get("SELECT * FROM leads WHERE id = ?", [p.leadId]);
|
|
98558
|
+
if (!lead) throw new Error("Lead not found");
|
|
98559
|
+
const vercelToken = getSetting("vercel_token");
|
|
98560
|
+
if (!vercelToken) throw new Error("Vercel token not set");
|
|
98561
|
+
return await handoverSite({
|
|
98562
|
+
lead,
|
|
98563
|
+
vercelToken,
|
|
98564
|
+
blobToken: getSetting("blob_token"),
|
|
98565
|
+
domain: p.domain ?? null,
|
|
98566
|
+
onProgress: (msg) => emit2("sites:progress", { leadId: p.leadId, msg })
|
|
98567
|
+
});
|
|
98568
|
+
}
|
|
98569
|
+
throw new Error(`channel not supported in CLI: ${channel}`);
|
|
98570
|
+
};
|
|
98571
|
+
}
|
|
98572
|
+
var init_invoke_ipc = __esm({
|
|
98573
|
+
"src/invoke-ipc.ts"() {
|
|
98574
|
+
"use strict";
|
|
98575
|
+
init_engine();
|
|
98576
|
+
init_config();
|
|
97574
98577
|
}
|
|
97575
|
-
|
|
97576
|
-
|
|
97577
|
-
|
|
97578
|
-
|
|
98578
|
+
});
|
|
98579
|
+
|
|
98580
|
+
// src/mcp.ts
|
|
98581
|
+
var mcp_exports = {};
|
|
98582
|
+
__export(mcp_exports, {
|
|
98583
|
+
runMcpServer: () => runMcpServer
|
|
98584
|
+
});
|
|
98585
|
+
function send(msg) {
|
|
98586
|
+
process.stdout.write(JSON.stringify(msg) + "\n");
|
|
98587
|
+
}
|
|
98588
|
+
function reply(id, result) {
|
|
98589
|
+
if (id === void 0 || id === null) return;
|
|
98590
|
+
send({ jsonrpc: "2.0", id, result });
|
|
98591
|
+
}
|
|
98592
|
+
function replyError(id, code, message) {
|
|
98593
|
+
if (id === void 0 || id === null) return;
|
|
98594
|
+
send({ jsonrpc: "2.0", id, error: { code, message } });
|
|
98595
|
+
}
|
|
98596
|
+
async function handle(req) {
|
|
98597
|
+
switch (req.method) {
|
|
98598
|
+
case "initialize":
|
|
98599
|
+
reply(req.id, {
|
|
98600
|
+
protocolVersion: PROTOCOL_VERSION,
|
|
98601
|
+
capabilities: { tools: {} },
|
|
98602
|
+
serverInfo: { name: "sproutkit", version: "1.0.0" }
|
|
98603
|
+
});
|
|
98604
|
+
return;
|
|
98605
|
+
case "notifications/initialized":
|
|
98606
|
+
return;
|
|
98607
|
+
case "tools/list":
|
|
98608
|
+
reply(req.id, {
|
|
98609
|
+
tools: TOOLS.map((t) => ({
|
|
98610
|
+
name: t.name,
|
|
98611
|
+
description: t.description,
|
|
98612
|
+
inputSchema: t.input_schema
|
|
98613
|
+
}))
|
|
98614
|
+
});
|
|
98615
|
+
return;
|
|
98616
|
+
case "tools/call": {
|
|
98617
|
+
const name = String(req.params?.name ?? "");
|
|
98618
|
+
const args = req.params?.arguments ?? {};
|
|
98619
|
+
if (!TOOLS.some((t) => t.name === name)) {
|
|
98620
|
+
replyError(req.id, -32602, `Unknown tool: ${name}`);
|
|
98621
|
+
return;
|
|
98622
|
+
}
|
|
98623
|
+
try {
|
|
98624
|
+
const out = await runTool(name, args, {
|
|
98625
|
+
invokeIpc: makeInvokeIpc(emit),
|
|
98626
|
+
emitProgress: (e) => emit(e.channel, e.payload)
|
|
98627
|
+
});
|
|
98628
|
+
reply(req.id, {
|
|
98629
|
+
content: [{ type: "text", text: JSON.stringify(out ?? { ok: true }, null, 2) }]
|
|
98630
|
+
});
|
|
98631
|
+
} catch (e) {
|
|
98632
|
+
reply(req.id, {
|
|
98633
|
+
content: [{ type: "text", text: `Error: ${e.message}` }],
|
|
98634
|
+
isError: true
|
|
98635
|
+
});
|
|
98636
|
+
}
|
|
98637
|
+
return;
|
|
98638
|
+
}
|
|
98639
|
+
default:
|
|
98640
|
+
replyError(req.id, -32601, `Method not found: ${req.method}`);
|
|
97579
98641
|
}
|
|
97580
|
-
|
|
97581
|
-
|
|
97582
|
-
|
|
97583
|
-
|
|
97584
|
-
|
|
98642
|
+
}
|
|
98643
|
+
async function runMcpServer() {
|
|
98644
|
+
process.stdin.setEncoding("utf-8");
|
|
98645
|
+
let buffer = "";
|
|
98646
|
+
process.stdin.on("data", (chunk) => {
|
|
98647
|
+
buffer += chunk;
|
|
98648
|
+
let idx;
|
|
98649
|
+
while ((idx = buffer.indexOf("\n")) !== -1) {
|
|
98650
|
+
const line = buffer.slice(0, idx).trim();
|
|
98651
|
+
buffer = buffer.slice(idx + 1);
|
|
98652
|
+
if (!line) continue;
|
|
98653
|
+
let req;
|
|
98654
|
+
try {
|
|
98655
|
+
req = JSON.parse(line);
|
|
98656
|
+
} catch {
|
|
98657
|
+
process.stderr.write(`[sproutkit-mcp] bad JSON: ${line.slice(0, 200)}
|
|
98658
|
+
`);
|
|
98659
|
+
continue;
|
|
98660
|
+
}
|
|
98661
|
+
void handle(req).catch((e) => {
|
|
98662
|
+
process.stderr.write(`[sproutkit-mcp] handler failed: ${e.message}
|
|
98663
|
+
`);
|
|
98664
|
+
replyError(req.id, -32603, e.message);
|
|
98665
|
+
});
|
|
97585
98666
|
}
|
|
97586
|
-
|
|
97587
|
-
|
|
97588
|
-
|
|
98667
|
+
});
|
|
98668
|
+
await new Promise((resolve) => process.stdin.on("end", resolve));
|
|
98669
|
+
}
|
|
98670
|
+
var PROTOCOL_VERSION, emit;
|
|
98671
|
+
var init_mcp = __esm({
|
|
98672
|
+
"src/mcp.ts"() {
|
|
98673
|
+
"use strict";
|
|
98674
|
+
init_engine();
|
|
98675
|
+
init_invoke_ipc();
|
|
98676
|
+
PROTOCOL_VERSION = "2024-11-05";
|
|
98677
|
+
emit = (channel, payload) => {
|
|
98678
|
+
process.stderr.write(`[sproutkit-mcp] ${channel} ${JSON.stringify(payload)}
|
|
97589
98679
|
`);
|
|
97590
|
-
|
|
98680
|
+
};
|
|
97591
98681
|
}
|
|
97592
|
-
};
|
|
97593
|
-
|
|
97594
|
-
|
|
97595
|
-
|
|
97596
|
-
|
|
97597
|
-
|
|
97598
|
-
|
|
97599
|
-
|
|
97600
|
-
|
|
97601
|
-
var
|
|
97602
|
-
|
|
97603
|
-
|
|
97604
|
-
|
|
97605
|
-
|
|
97606
|
-
|
|
97607
|
-
|
|
97608
|
-
|
|
97609
|
-
|
|
97610
|
-
|
|
97611
|
-
|
|
97612
|
-
|
|
97613
|
-
|
|
97614
|
-
|
|
97615
|
-
|
|
97616
|
-
|
|
98682
|
+
});
|
|
98683
|
+
|
|
98684
|
+
// src/index.ts
|
|
98685
|
+
init_engine();
|
|
98686
|
+
|
|
98687
|
+
// src/onboarding.ts
|
|
98688
|
+
init_config();
|
|
98689
|
+
|
|
98690
|
+
// src/license.ts
|
|
98691
|
+
var import_os = __toESM(require("os"));
|
|
98692
|
+
var import_crypto = require("crypto");
|
|
98693
|
+
init_config();
|
|
98694
|
+
var GRACE_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
98695
|
+
function apiBase() {
|
|
98696
|
+
return process.env.SPROUTKIT_API_BASE_URL ?? "https://sproutkit.app";
|
|
98697
|
+
}
|
|
98698
|
+
function deviceId() {
|
|
98699
|
+
const macs = Object.values(import_os.default.networkInterfaces()).flat().filter((i) => !!i && !i.internal).map((i) => i.mac).filter((m) => m && m !== "00:00:00:00:00:00");
|
|
98700
|
+
return (0, import_crypto.createHash)("sha256").update(`${macs[0] ?? "unknown"}|${import_os.default.hostname()}`).digest("hex").slice(0, 32);
|
|
98701
|
+
}
|
|
98702
|
+
async function callValidate(key) {
|
|
98703
|
+
try {
|
|
98704
|
+
const r = await fetch(`${apiBase()}/api/licenses/validate`, {
|
|
98705
|
+
method: "POST",
|
|
98706
|
+
headers: { "Content-Type": "application/json" },
|
|
98707
|
+
body: JSON.stringify({ key, deviceId: deviceId() }),
|
|
98708
|
+
signal: AbortSignal.timeout(8e3)
|
|
98709
|
+
});
|
|
98710
|
+
if (!r.ok) return null;
|
|
98711
|
+
return await r.json();
|
|
98712
|
+
} catch {
|
|
98713
|
+
return null;
|
|
98714
|
+
}
|
|
98715
|
+
}
|
|
98716
|
+
async function activate(key) {
|
|
98717
|
+
const trimmed = key.trim();
|
|
98718
|
+
const result = await callValidate(trimmed);
|
|
98719
|
+
if (!result) return { status: "missing" };
|
|
98720
|
+
if (!result.valid) {
|
|
98721
|
+
return {
|
|
98722
|
+
status: result.reason === "revoked" ? "revoked" : result.reason === "refunded" ? "refunded" : result.reason === "expired" ? "expired" : "missing",
|
|
98723
|
+
email: result.email
|
|
98724
|
+
};
|
|
98725
|
+
}
|
|
98726
|
+
setSetting("license_key", trimmed);
|
|
98727
|
+
setSetting("license_email", result.email ?? "");
|
|
98728
|
+
setSetting("license_validated_at", String(Date.now()));
|
|
98729
|
+
return { status: "active", email: result.email };
|
|
98730
|
+
}
|
|
98731
|
+
async function check() {
|
|
98732
|
+
const key = getSetting("license_key");
|
|
98733
|
+
if (!key) return { status: "missing" };
|
|
98734
|
+
const result = await callValidate(key);
|
|
98735
|
+
if (result) {
|
|
98736
|
+
if (result.valid) {
|
|
98737
|
+
setSetting("license_validated_at", String(Date.now()));
|
|
98738
|
+
return { status: "active", email: result.email };
|
|
97617
98739
|
}
|
|
97618
|
-
|
|
97619
|
-
|
|
97620
|
-
|
|
97621
|
-
|
|
97622
|
-
this.render();
|
|
97623
|
-
}, 90);
|
|
97624
|
-
}
|
|
97625
|
-
update(row) {
|
|
97626
|
-
const i = this.rows.findIndex((r) => r.key === row.key);
|
|
97627
|
-
if (i >= 0) this.rows[i] = row;
|
|
97628
|
-
else this.rows.push(row);
|
|
97629
|
-
if (!this.tty) this.logRowIfChanged(row);
|
|
97630
|
-
else this.render();
|
|
97631
|
-
}
|
|
97632
|
-
// Replace the whole set at once (e.g. from a job snapshot).
|
|
97633
|
-
set(rows) {
|
|
97634
|
-
this.rows = rows;
|
|
97635
|
-
if (!this.tty) rows.forEach((r) => this.logRowIfChanged(r));
|
|
97636
|
-
else this.render();
|
|
97637
|
-
}
|
|
97638
|
-
line(r) {
|
|
97639
|
-
const mark2 = r.state === "building" ? c.cyan(FRAMES[this.frame]) : STATE_MARK[r.state]();
|
|
97640
|
-
const detail = r.detail ? c.dim(` \xB7 ${r.detail}`) : "";
|
|
97641
|
-
return ` ${mark2} ${r.label}${detail}`;
|
|
97642
|
-
}
|
|
97643
|
-
logRowIfChanged(r) {
|
|
97644
|
-
const sig = `${r.state}:${r.detail ?? ""}`;
|
|
97645
|
-
if (this.lastSig.get(r.key) === sig) return;
|
|
97646
|
-
this.lastSig.set(r.key, sig);
|
|
97647
|
-
const mark2 = r.state === "built" ? "\u2713" : r.state === "failed" ? "\u2717" : r.state === "skipped" ? "\u2013" : "\u2026";
|
|
97648
|
-
say(` ${mark2} ${r.label}${r.detail ? ` \xB7 ${r.detail}` : ""}`);
|
|
97649
|
-
}
|
|
97650
|
-
render() {
|
|
97651
|
-
if (this.lastLineCount > 0) process.stdout.write(`\x1B[${this.lastLineCount}A`);
|
|
97652
|
-
const out = this.rows.map((r) => `\x1B[2K${this.line(r)}`).join("\n");
|
|
97653
|
-
process.stdout.write(out + "\n");
|
|
97654
|
-
this.lastLineCount = this.rows.length;
|
|
97655
|
-
}
|
|
97656
|
-
stop() {
|
|
97657
|
-
if (this.timer) {
|
|
97658
|
-
clearInterval(this.timer);
|
|
97659
|
-
this.timer = null;
|
|
97660
|
-
}
|
|
97661
|
-
if (this.tty) this.render();
|
|
98740
|
+
return {
|
|
98741
|
+
status: result.reason === "revoked" ? "revoked" : result.reason === "refunded" ? "refunded" : result.reason === "expired" ? "expired" : "missing",
|
|
98742
|
+
email: result.email
|
|
98743
|
+
};
|
|
97662
98744
|
}
|
|
97663
|
-
|
|
98745
|
+
const last = Number(getSetting("license_validated_at") ?? 0);
|
|
98746
|
+
if (Date.now() - last < GRACE_MS) return { status: "active" };
|
|
98747
|
+
return { status: "offline_grace_expired" };
|
|
98748
|
+
}
|
|
98749
|
+
|
|
98750
|
+
// src/onboarding.ts
|
|
98751
|
+
init_engine();
|
|
98752
|
+
init_tty();
|
|
97664
98753
|
|
|
97665
98754
|
// src/skill-install.ts
|
|
97666
98755
|
var import_fs = __toESM(require("fs"));
|
|
@@ -97738,11 +98827,12 @@ function installSkill() {
|
|
|
97738
98827
|
}
|
|
97739
98828
|
|
|
97740
98829
|
// src/onboarding.ts
|
|
97741
|
-
|
|
98830
|
+
init_desktop_install();
|
|
98831
|
+
var import_child_process2 = require("child_process");
|
|
97742
98832
|
function claudeCliPresent() {
|
|
97743
98833
|
try {
|
|
97744
98834
|
const bin = process.env.SPROUTKIT_CLAUDE_BIN || "claude";
|
|
97745
|
-
const r = (0,
|
|
98835
|
+
const r = (0, import_child_process2.spawnSync)(bin, ["--version"], { stdio: "ignore", timeout: 1e4 });
|
|
97746
98836
|
return r.status === 0;
|
|
97747
98837
|
} catch {
|
|
97748
98838
|
return false;
|
|
@@ -97824,6 +98914,26 @@ async function offerSkillInstall(force) {
|
|
|
97824
98914
|
}
|
|
97825
98915
|
say();
|
|
97826
98916
|
}
|
|
98917
|
+
async function offerDesktopInstall() {
|
|
98918
|
+
if (!desktopSupported() || desktopInstallPath()) return;
|
|
98919
|
+
say(` ${c.bold("Desktop app")}`);
|
|
98920
|
+
say(c.dim(" The map, pipeline board and Workflows live in the desktop app, and your"));
|
|
98921
|
+
say(c.dim(" terminal leads sync into it. It's about a 100 MB download."));
|
|
98922
|
+
const ans = (await ask(c.green(" Install it now? [Y/n] "))).trim().toLowerCase();
|
|
98923
|
+
if (ans === "n" || ans === "no") {
|
|
98924
|
+
say(c.dim(" Skipped \u2014 install it any time with 'sproutkit desktop'."));
|
|
98925
|
+
say();
|
|
98926
|
+
return;
|
|
98927
|
+
}
|
|
98928
|
+
const res = await installDesktop();
|
|
98929
|
+
if (res.ok) {
|
|
98930
|
+
say(c.green(` \u2713 Sproutkit ${res.version} installed to ${res.path}`));
|
|
98931
|
+
} else {
|
|
98932
|
+
say(c.amber(` Couldn't install the desktop app: ${res.error}`));
|
|
98933
|
+
say(c.dim(" Try again with 'sproutkit desktop', or download it from https://sproutkit.app/install"));
|
|
98934
|
+
}
|
|
98935
|
+
say();
|
|
98936
|
+
}
|
|
97827
98937
|
async function onboardLicense(force) {
|
|
97828
98938
|
if (!force) {
|
|
97829
98939
|
const state = await check();
|
|
@@ -97845,7 +98955,7 @@ async function onboardLicense(force) {
|
|
|
97845
98955
|
say();
|
|
97846
98956
|
return true;
|
|
97847
98957
|
}
|
|
97848
|
-
const msg = state.status === "revoked" ? "That licence has been revoked." : state.status === "refunded" ? "That licence was refunded." : "Couldn't validate that key (check it, or your connection).";
|
|
98958
|
+
const msg = state.status === "revoked" ? "That licence has been revoked." : state.status === "refunded" ? "That licence was refunded." : state.status === "expired" ? "That subscription has ended \u2014 renew at https://sproutkit.app/#pricing." : "Couldn't validate that key (check it, or your connection).";
|
|
97849
98959
|
say(c.red(` ${msg} Try again, or press Enter to quit.`));
|
|
97850
98960
|
}
|
|
97851
98961
|
}
|
|
@@ -97881,6 +98991,7 @@ async function runOnboarding(force = false) {
|
|
|
97881
98991
|
} catch {
|
|
97882
98992
|
}
|
|
97883
98993
|
}
|
|
98994
|
+
await offerDesktopInstall();
|
|
97884
98995
|
const stillMissing = missingRequiredKeys();
|
|
97885
98996
|
if (stillMissing.length > 0) {
|
|
97886
98997
|
say(c.amber(` Still missing: ${stillMissing.map((m) => m.label).join(", ")}.`));
|
|
@@ -97894,9 +99005,11 @@ async function runOnboarding(force = false) {
|
|
|
97894
99005
|
}
|
|
97895
99006
|
|
|
97896
99007
|
// src/update.ts
|
|
97897
|
-
var
|
|
99008
|
+
var import_child_process3 = require("child_process");
|
|
97898
99009
|
var import_util = require("util");
|
|
97899
|
-
|
|
99010
|
+
init_config();
|
|
99011
|
+
init_tty();
|
|
99012
|
+
var execFileP = (0, import_util.promisify)(import_child_process3.execFile);
|
|
97900
99013
|
var PKG = "sproutkit-code";
|
|
97901
99014
|
var CURRENT_VERSION = require_package2().version;
|
|
97902
99015
|
async function latestOnRegistry() {
|
|
@@ -97959,10 +99072,12 @@ async function notifyIfOutdated() {
|
|
|
97959
99072
|
}
|
|
97960
99073
|
|
|
97961
99074
|
// src/sync.ts
|
|
97962
|
-
var
|
|
97963
|
-
var
|
|
97964
|
-
var
|
|
97965
|
-
|
|
99075
|
+
var import_os4 = __toESM(require("os"));
|
|
99076
|
+
var import_path3 = __toESM(require("path"));
|
|
99077
|
+
var import_fs3 = __toESM(require("fs"));
|
|
99078
|
+
init_engine();
|
|
99079
|
+
init_tty();
|
|
99080
|
+
var WANTED_COLS = [
|
|
97966
99081
|
"place_id",
|
|
97967
99082
|
"name",
|
|
97968
99083
|
"type",
|
|
@@ -97981,50 +99096,79 @@ var COLS = [
|
|
|
97981
99096
|
"notes",
|
|
97982
99097
|
"score",
|
|
97983
99098
|
"price_level",
|
|
97984
|
-
"business_status"
|
|
99099
|
+
"business_status",
|
|
99100
|
+
// Deliverables and stage timestamps — without these the desktop board can't
|
|
99101
|
+
// show booking pages, attached domains, delivered status or stalled leads.
|
|
99102
|
+
"booking_url",
|
|
99103
|
+
"custom_domain",
|
|
99104
|
+
"handed_over_at",
|
|
99105
|
+
"replied_at",
|
|
99106
|
+
"dead_at",
|
|
99107
|
+
"email"
|
|
99108
|
+
];
|
|
99109
|
+
var UPDATE_COLS = [
|
|
99110
|
+
"status",
|
|
99111
|
+
"site_url",
|
|
99112
|
+
"site_built_at",
|
|
99113
|
+
"score",
|
|
99114
|
+
"booking_url",
|
|
99115
|
+
"custom_domain",
|
|
99116
|
+
"handed_over_at",
|
|
99117
|
+
"replied_at",
|
|
99118
|
+
"dead_at",
|
|
99119
|
+
"email"
|
|
97985
99120
|
];
|
|
99121
|
+
function columnsOf(db2, table) {
|
|
99122
|
+
const rows = db2.all(`PRAGMA table_info(${table})`);
|
|
99123
|
+
return new Set(rows.map((r) => r.name));
|
|
99124
|
+
}
|
|
97986
99125
|
function desktopDbPath() {
|
|
97987
|
-
const home =
|
|
99126
|
+
const home = import_os4.default.homedir();
|
|
97988
99127
|
const candidates = [];
|
|
97989
99128
|
if (process.platform === "darwin") {
|
|
97990
|
-
candidates.push(
|
|
99129
|
+
candidates.push(import_path3.default.join(home, "Library", "Application Support", "Sproutkit", "data", "sproutio.db"));
|
|
97991
99130
|
} else if (process.platform === "win32") {
|
|
97992
|
-
const appData = process.env.APPDATA ||
|
|
97993
|
-
candidates.push(
|
|
99131
|
+
const appData = process.env.APPDATA || import_path3.default.join(home, "AppData", "Roaming");
|
|
99132
|
+
candidates.push(import_path3.default.join(appData, "Sproutkit", "data", "sproutio.db"));
|
|
97994
99133
|
} else {
|
|
97995
|
-
const cfg = process.env.XDG_CONFIG_HOME ||
|
|
97996
|
-
candidates.push(
|
|
99134
|
+
const cfg = process.env.XDG_CONFIG_HOME || import_path3.default.join(home, ".config");
|
|
99135
|
+
candidates.push(import_path3.default.join(cfg, "Sproutkit", "data", "sproutio.db"));
|
|
97997
99136
|
}
|
|
97998
|
-
return candidates.find((p) =>
|
|
99137
|
+
return candidates.find((p) => import_fs3.default.existsSync(p)) ?? null;
|
|
97999
99138
|
}
|
|
98000
99139
|
function syncToDesktop(opts = {}) {
|
|
98001
99140
|
const dest = desktopDbPath();
|
|
98002
99141
|
if (!dest) return { ok: false, reason: "no_desktop_db", inserted: 0, updated: 0 };
|
|
98003
|
-
const cliLeads = getDb().all(
|
|
98004
|
-
`SELECT ${COLS.join(", ")} FROM leads WHERE place_id IS NOT NULL AND place_id != ''`,
|
|
98005
|
-
[]
|
|
98006
|
-
);
|
|
98007
|
-
if (cliLeads.length === 0) return { ok: true, inserted: 0, updated: 0 };
|
|
98008
99142
|
const { Database } = require("node-sqlite3-wasm");
|
|
98009
99143
|
const ddb = new Database(dest);
|
|
98010
99144
|
let inserted = 0;
|
|
98011
99145
|
let updated = 0;
|
|
98012
99146
|
try {
|
|
99147
|
+
const shared = new Set(
|
|
99148
|
+
[...columnsOf(getDb(), "leads")].filter((n) => columnsOf(ddb, "leads").has(n))
|
|
99149
|
+
);
|
|
99150
|
+
const cols = WANTED_COLS.filter((c2) => shared.has(c2));
|
|
99151
|
+
const updateCols = UPDATE_COLS.filter((c2) => shared.has(c2));
|
|
99152
|
+
const cliLeads = getDb().all(
|
|
99153
|
+
`SELECT ${cols.join(", ")} FROM leads WHERE place_id IS NOT NULL AND place_id != ''`,
|
|
99154
|
+
[]
|
|
99155
|
+
);
|
|
99156
|
+
if (cliLeads.length === 0) return { ok: true, inserted: 0, updated: 0 };
|
|
98013
99157
|
for (const lead of cliLeads) {
|
|
98014
99158
|
const existing = ddb.get("SELECT id FROM leads WHERE place_id = ?", [lead.place_id]);
|
|
98015
99159
|
if (existing) {
|
|
98016
99160
|
ddb.run(
|
|
98017
|
-
|
|
98018
|
-
[
|
|
99161
|
+
`UPDATE leads SET ${updateCols.map((k) => `${k} = ?`).join(", ")} WHERE place_id = ?`,
|
|
99162
|
+
[...updateCols.map((k) => lead[k]), lead.place_id].map(
|
|
98019
99163
|
(v) => v ?? null
|
|
98020
99164
|
)
|
|
98021
99165
|
);
|
|
98022
99166
|
updated++;
|
|
98023
99167
|
} else {
|
|
98024
|
-
const placeholders =
|
|
99168
|
+
const placeholders = cols.map(() => "?").join(", ");
|
|
98025
99169
|
ddb.run(
|
|
98026
|
-
`INSERT INTO leads (${
|
|
98027
|
-
|
|
99170
|
+
`INSERT INTO leads (${cols.join(", ")}) VALUES (${placeholders})`,
|
|
99171
|
+
cols.map((k) => lead[k] ?? null)
|
|
98028
99172
|
);
|
|
98029
99173
|
inserted++;
|
|
98030
99174
|
}
|
|
@@ -98050,6 +99194,9 @@ function autoSync() {
|
|
|
98050
99194
|
}
|
|
98051
99195
|
|
|
98052
99196
|
// src/models-cmd.ts
|
|
99197
|
+
init_engine();
|
|
99198
|
+
init_config();
|
|
99199
|
+
init_tty();
|
|
98053
99200
|
async function runModelsClaudeCode() {
|
|
98054
99201
|
const current = getClaudeCodeModel();
|
|
98055
99202
|
say();
|
|
@@ -98122,187 +99269,21 @@ async function runModels() {
|
|
|
98122
99269
|
say(c.green(` \u2713 Now using ${models2[idx].display_name ?? models2[idx].id}.`));
|
|
98123
99270
|
}
|
|
98124
99271
|
|
|
98125
|
-
// src/invoke-ipc.ts
|
|
98126
|
-
async function requireBlobToken(vercelToken, emit, leadId) {
|
|
98127
|
-
const existing = getSetting("blob_token");
|
|
98128
|
-
if (existing) return existing;
|
|
98129
|
-
emit("bookings:progress", { leadId, msg: "No Blob token yet \u2014 creating a Blob store for you\u2026" });
|
|
98130
|
-
const created = await createBlobStore({ vercelToken, name: "sproutkit" });
|
|
98131
|
-
if (created.ok) {
|
|
98132
|
-
throw new Error(
|
|
98133
|
-
"Created a Vercel Blob store for you \u2713 \u2014 one last one-time step: open " + (created.dashboardUrl || "https://vercel.com/dashboard/stores") + " , open the 'sproutkit' store, copy its BLOB_READ_WRITE_TOKEN, then run 'sproutkit setup' and paste it. You only do this once \u2014 it's reused for every booking site."
|
|
98134
|
-
);
|
|
98135
|
-
}
|
|
98136
|
-
if (created.alreadyExists) {
|
|
98137
|
-
throw new Error(
|
|
98138
|
-
"You already have a Blob store. Open https://vercel.com/dashboard/stores , copy its BLOB_READ_WRITE_TOKEN, and run 'sproutkit setup' to paste it (one-time \u2014 reused for all sites)."
|
|
98139
|
-
);
|
|
98140
|
-
}
|
|
98141
|
-
throw new Error(
|
|
98142
|
-
`Booking needs a Vercel Blob token and I couldn't auto-create a store (${created.error ?? "unknown"}). Create one at https://vercel.com/dashboard/stores (Create \u2192 Blob), copy BLOB_READ_WRITE_TOKEN, then 'sproutkit setup'.`
|
|
98143
|
-
);
|
|
98144
|
-
}
|
|
98145
|
-
function makeInvokeIpc(emit) {
|
|
98146
|
-
return async (channel, payload) => {
|
|
98147
|
-
if (channel === "auto:build:start") {
|
|
98148
|
-
const args = payload;
|
|
98149
|
-
const anthropicKey = getSetting("anthropic_key");
|
|
98150
|
-
const vercelToken = getSetting("vercel_token");
|
|
98151
|
-
const placesKey = getSetting("places_key");
|
|
98152
|
-
if (!anthropicKey) throw new Error("Anthropic API key not set");
|
|
98153
|
-
if (!vercelToken) throw new Error("Vercel token not set");
|
|
98154
|
-
return startAutoJob({
|
|
98155
|
-
leadIds: args.leadIds,
|
|
98156
|
-
concurrency: args.concurrency,
|
|
98157
|
-
anthropicKey,
|
|
98158
|
-
vercelToken,
|
|
98159
|
-
placesKey,
|
|
98160
|
-
emit
|
|
98161
|
-
});
|
|
98162
|
-
}
|
|
98163
|
-
if (channel === "cms:provision") {
|
|
98164
|
-
const leadId = Number(payload);
|
|
98165
|
-
const db2 = getDb();
|
|
98166
|
-
const lead = db2.get("SELECT * FROM leads WHERE id = ?", [leadId]);
|
|
98167
|
-
if (!lead) throw new Error("Lead not found");
|
|
98168
|
-
const placesKey = getSetting("places_key");
|
|
98169
|
-
const vercelToken = getSetting("vercel_token");
|
|
98170
|
-
const licenseKey = getSetting("license_key");
|
|
98171
|
-
const apiBaseUrl = process.env.SPROUTKIT_API_BASE_URL ?? "https://sproutkit.app";
|
|
98172
|
-
if (!vercelToken) throw new Error("Vercel token not set");
|
|
98173
|
-
emit("cms:progress", { leadId, msg: "Starting\u2026" });
|
|
98174
|
-
const result = await provisionCmsForLead({
|
|
98175
|
-
lead,
|
|
98176
|
-
placesKey,
|
|
98177
|
-
vercelToken,
|
|
98178
|
-
apiBaseUrl,
|
|
98179
|
-
licenseKey,
|
|
98180
|
-
onProgress: (msg) => emit("cms:progress", { leadId, msg })
|
|
98181
|
-
});
|
|
98182
|
-
db2.run("UPDATE leads SET site_url = ?, status = 'won' WHERE id = ?", [
|
|
98183
|
-
result.publicUrl,
|
|
98184
|
-
leadId
|
|
98185
|
-
]);
|
|
98186
|
-
emit("cms:done", { leadId, ok: true, ...result });
|
|
98187
|
-
return result;
|
|
98188
|
-
}
|
|
98189
|
-
if (channel === "bookings:provision") {
|
|
98190
|
-
const p = payload;
|
|
98191
|
-
const db2 = getDb();
|
|
98192
|
-
const lead = db2.get("SELECT * FROM leads WHERE id = ?", [p.leadId]);
|
|
98193
|
-
if (!lead) throw new Error("Lead not found");
|
|
98194
|
-
const anthropicKey = getSetting("anthropic_key");
|
|
98195
|
-
const vercelToken = getSetting("vercel_token");
|
|
98196
|
-
const resendKey = getSetting("resend_key");
|
|
98197
|
-
if (!anthropicKey) throw new Error("Anthropic API key not set");
|
|
98198
|
-
if (!vercelToken) throw new Error("Vercel token not set");
|
|
98199
|
-
const blobToken = await requireBlobToken(vercelToken, emit, p.leadId);
|
|
98200
|
-
emit("bookings:progress", { leadId: p.leadId, msg: "Designing the booking form\u2026" });
|
|
98201
|
-
const leadInfo = lead;
|
|
98202
|
-
const config = await generatePreset({
|
|
98203
|
-
anthropicKey,
|
|
98204
|
-
lead: { name: leadInfo.name, type: leadInfo.type, city: leadInfo.city },
|
|
98205
|
-
instructions: p.instructions,
|
|
98206
|
-
archetypeOverride: p.archetypeOverride
|
|
98207
|
-
});
|
|
98208
|
-
const result = await deployBookingOnly({
|
|
98209
|
-
lead,
|
|
98210
|
-
vercelToken,
|
|
98211
|
-
blobToken,
|
|
98212
|
-
resendKey: resendKey || "",
|
|
98213
|
-
ownerEmail: p.ownerEmail ?? "",
|
|
98214
|
-
bookingConfig: config,
|
|
98215
|
-
anthropicKey,
|
|
98216
|
-
onProgress: (msg) => emit("bookings:progress", { leadId: p.leadId, msg })
|
|
98217
|
-
});
|
|
98218
|
-
db2.run(
|
|
98219
|
-
"UPDATE leads SET booking_url = ?, owner_email = ?, booking_archetype = ?, booking_config = ? WHERE id = ?",
|
|
98220
|
-
[
|
|
98221
|
-
result.bookingUrl,
|
|
98222
|
-
p.ownerEmail ?? "",
|
|
98223
|
-
config.archetype,
|
|
98224
|
-
JSON.stringify(config),
|
|
98225
|
-
p.leadId
|
|
98226
|
-
]
|
|
98227
|
-
);
|
|
98228
|
-
emit("bookings:done", { leadId: p.leadId, ...result });
|
|
98229
|
-
return result;
|
|
98230
|
-
}
|
|
98231
|
-
if (channel === "bookings:provision-standalone") {
|
|
98232
|
-
const p = payload;
|
|
98233
|
-
const db2 = getDb();
|
|
98234
|
-
const lead = db2.get("SELECT * FROM leads WHERE id = ?", [p.leadId]);
|
|
98235
|
-
if (!lead) throw new Error("Lead not found");
|
|
98236
|
-
const vercelToken = getSetting("vercel_token");
|
|
98237
|
-
const resendKey = getSetting("resend_key");
|
|
98238
|
-
if (!vercelToken) throw new Error("Vercel token not set");
|
|
98239
|
-
const blobToken = await requireBlobToken(vercelToken, emit, p.leadId);
|
|
98240
|
-
emit("bookings:progress", { leadId: p.leadId, msg: "Designing the booking form\u2026" });
|
|
98241
|
-
const leadInfo = lead;
|
|
98242
|
-
const config = await generatePreset({
|
|
98243
|
-
anthropicKey: getSetting("anthropic_key") ?? "",
|
|
98244
|
-
lead: { name: leadInfo.name, type: leadInfo.type, city: leadInfo.city },
|
|
98245
|
-
instructions: p.instructions,
|
|
98246
|
-
archetypeOverride: p.archetypeOverride
|
|
98247
|
-
});
|
|
98248
|
-
const result = await deployStandaloneBooking({
|
|
98249
|
-
lead,
|
|
98250
|
-
vercelToken,
|
|
98251
|
-
blobToken,
|
|
98252
|
-
resendKey: resendKey || "",
|
|
98253
|
-
ownerEmail: p.ownerEmail ?? "",
|
|
98254
|
-
bookingConfig: config,
|
|
98255
|
-
reuseAdminPassword: lead.booking_admin_password ?? null,
|
|
98256
|
-
onProgress: (msg) => emit("bookings:progress", { leadId: p.leadId, msg })
|
|
98257
|
-
});
|
|
98258
|
-
db2.run(
|
|
98259
|
-
`UPDATE leads SET booking_url = ?, owner_email = ?, booking_archetype = ?, booking_config = ?,
|
|
98260
|
-
booking_admin_url = ?, booking_admin_password = ?,
|
|
98261
|
-
status = CASE WHEN status = 'discovered' THEN 'site_built' ELSE status END
|
|
98262
|
-
WHERE id = ?`,
|
|
98263
|
-
[
|
|
98264
|
-
result.bookingUrl,
|
|
98265
|
-
p.ownerEmail ?? "",
|
|
98266
|
-
config.archetype,
|
|
98267
|
-
JSON.stringify(config),
|
|
98268
|
-
result.admin.url,
|
|
98269
|
-
result.admin.password,
|
|
98270
|
-
p.leadId
|
|
98271
|
-
]
|
|
98272
|
-
);
|
|
98273
|
-
emit("bookings:done", { leadId: p.leadId, ...result });
|
|
98274
|
-
return result;
|
|
98275
|
-
}
|
|
98276
|
-
if (channel === "site:handover") {
|
|
98277
|
-
const p = payload;
|
|
98278
|
-
const db2 = getDb();
|
|
98279
|
-
const lead = db2.get("SELECT * FROM leads WHERE id = ?", [p.leadId]);
|
|
98280
|
-
if (!lead) throw new Error("Lead not found");
|
|
98281
|
-
const vercelToken = getSetting("vercel_token");
|
|
98282
|
-
if (!vercelToken) throw new Error("Vercel token not set");
|
|
98283
|
-
return await handoverSite({
|
|
98284
|
-
lead,
|
|
98285
|
-
vercelToken,
|
|
98286
|
-
blobToken: getSetting("blob_token"),
|
|
98287
|
-
domain: p.domain ?? null,
|
|
98288
|
-
onProgress: (msg) => emit("sites:progress", { leadId: p.leadId, msg })
|
|
98289
|
-
});
|
|
98290
|
-
}
|
|
98291
|
-
throw new Error(`channel not supported in CLI: ${channel}`);
|
|
98292
|
-
};
|
|
98293
|
-
}
|
|
98294
|
-
|
|
98295
99272
|
// src/commands.ts
|
|
99273
|
+
init_engine();
|
|
99274
|
+
init_invoke_ipc();
|
|
99275
|
+
init_config();
|
|
99276
|
+
init_tty();
|
|
98296
99277
|
function makeCtx(opts) {
|
|
98297
|
-
const
|
|
99278
|
+
const emit2 = (channel, payload) => {
|
|
98298
99279
|
opts.onEvent?.(channel, payload);
|
|
98299
99280
|
if (opts.json) return;
|
|
98300
99281
|
const p = payload;
|
|
98301
99282
|
if (p?.msg && opts.status) opts.status.update(p.msg);
|
|
98302
99283
|
};
|
|
98303
99284
|
return {
|
|
98304
|
-
invokeIpc: makeInvokeIpc(
|
|
98305
|
-
emitProgress: (e) =>
|
|
99285
|
+
invokeIpc: makeInvokeIpc(emit2),
|
|
99286
|
+
emitProgress: (e) => emit2(e.channel, e.payload)
|
|
98306
99287
|
};
|
|
98307
99288
|
}
|
|
98308
99289
|
function parseArgs(argv) {
|
|
@@ -99146,6 +100127,135 @@ async function cmdReport(argv) {
|
|
|
99146
100127
|
process.exitCode = 1;
|
|
99147
100128
|
}
|
|
99148
100129
|
}
|
|
100130
|
+
async function cmdAudit(argv) {
|
|
100131
|
+
const { flags, rest } = parseArgs(argv);
|
|
100132
|
+
const json = !!flags.json;
|
|
100133
|
+
const SEV_COLOUR = {
|
|
100134
|
+
critical: c.red,
|
|
100135
|
+
major: c.amber,
|
|
100136
|
+
minor: c.dim
|
|
100137
|
+
};
|
|
100138
|
+
const asId = Number(flags.id ?? rest[0]);
|
|
100139
|
+
const singleUrl = flags.url ? String(flags.url) : void 0;
|
|
100140
|
+
const looksLikeUrl = singleUrl || rest[0] && /\./.test(String(rest[0])) && !flags.categories;
|
|
100141
|
+
if (singleUrl || !Number.isNaN(asId) && rest.length === 1 && !flags.categories || looksLikeUrl) {
|
|
100142
|
+
const status2 = json ? void 0 : new Status();
|
|
100143
|
+
const target = singleUrl ?? (Number.isNaN(asId) ? String(rest[0]) : `lead #${asId}`);
|
|
100144
|
+
if (status2) status2.start(`Auditing ${target}`);
|
|
100145
|
+
try {
|
|
100146
|
+
const r = await runTool(
|
|
100147
|
+
"audit_one_site",
|
|
100148
|
+
Number.isNaN(asId) || singleUrl ? { url: singleUrl ?? String(rest[0]) } : { id: asId },
|
|
100149
|
+
makeCtx({ json, status: status2 })
|
|
100150
|
+
);
|
|
100151
|
+
if (r && r.ok === false) {
|
|
100152
|
+
if (status2) status2.done(false, r.error ?? "Couldn't audit it");
|
|
100153
|
+
if (json) emitJson(r);
|
|
100154
|
+
process.exitCode = 1;
|
|
100155
|
+
return;
|
|
100156
|
+
}
|
|
100157
|
+
if (status2) {
|
|
100158
|
+
status2.done(
|
|
100159
|
+
true,
|
|
100160
|
+
r.issues && r.issues.length ? `${r.issues.length} issue${r.issues.length === 1 ? "" : "s"} \xB7 score ${r.score}` : "No problems found"
|
|
100161
|
+
);
|
|
100162
|
+
}
|
|
100163
|
+
if (json) {
|
|
100164
|
+
emitJson(r);
|
|
100165
|
+
return;
|
|
100166
|
+
}
|
|
100167
|
+
say();
|
|
100168
|
+
say(` ${c.bold(String(r.url))}` + c.dim(` \xB7 score ${r.score}/100`));
|
|
100169
|
+
if (!r.issues?.length) {
|
|
100170
|
+
say(c.dim(" Nothing worth pitching against \u2014 this site is in decent shape."));
|
|
100171
|
+
say();
|
|
100172
|
+
return;
|
|
100173
|
+
}
|
|
100174
|
+
say();
|
|
100175
|
+
for (const i of r.issues) {
|
|
100176
|
+
const tint = SEV_COLOUR[i.severity] ?? c.dim;
|
|
100177
|
+
say(` ${tint("\u25CF")} ${i.label}${i.detail ? c.dim(` (${i.detail})`) : ""}`);
|
|
100178
|
+
}
|
|
100179
|
+
say();
|
|
100180
|
+
say(
|
|
100181
|
+
r.worthRebuilding ? c.green(" Worth approaching \u2014 these are concrete problems you can name.") : c.dim(" Minor only. Probably not worth a rebuild pitch.")
|
|
100182
|
+
);
|
|
100183
|
+
say();
|
|
100184
|
+
} catch (e) {
|
|
100185
|
+
if (status2) status2.done(false, "Audit failed");
|
|
100186
|
+
json ? emitJson({ ok: false, error: e.message }) : say(c.red(" " + e.message));
|
|
100187
|
+
process.exitCode = 1;
|
|
100188
|
+
}
|
|
100189
|
+
return;
|
|
100190
|
+
}
|
|
100191
|
+
const location = rest.join(" ").trim() || (flags.location ? String(flags.location) : "");
|
|
100192
|
+
if (!location) {
|
|
100193
|
+
const err = 'Usage: sproutkit audit "<area>" --categories "barber shop,cafe"\n single site: sproutkit audit <leadId> \xB7 sproutkit audit --url thebarbers.co.uk';
|
|
100194
|
+
json ? emitJson({ ok: false, error: err }) : say(c.red(" " + err));
|
|
100195
|
+
process.exitCode = 1;
|
|
100196
|
+
return;
|
|
100197
|
+
}
|
|
100198
|
+
const categories = flags.categories ? String(flags.categories).split(",").map((t) => t.trim()).filter(Boolean) : [];
|
|
100199
|
+
if (categories.length === 0) {
|
|
100200
|
+
const err = 'Which trades? e.g. --categories "barber shop,cafe,plumber"';
|
|
100201
|
+
json ? emitJson({ ok: false, error: err }) : say(c.red(" " + err));
|
|
100202
|
+
process.exitCode = 1;
|
|
100203
|
+
return;
|
|
100204
|
+
}
|
|
100205
|
+
const status = json ? void 0 : new Status();
|
|
100206
|
+
if (status) status.start(`Auditing websites in ${location}`);
|
|
100207
|
+
try {
|
|
100208
|
+
const r = await runTool(
|
|
100209
|
+
"audit_sites",
|
|
100210
|
+
{
|
|
100211
|
+
location,
|
|
100212
|
+
categories,
|
|
100213
|
+
radiusMeters: flags.radius ? Number(flags.radius) : void 0,
|
|
100214
|
+
limit: flags.limit ? Number(flags.limit) : void 0
|
|
100215
|
+
},
|
|
100216
|
+
makeCtx({ json, status })
|
|
100217
|
+
);
|
|
100218
|
+
if (r && r.ok === false) {
|
|
100219
|
+
if (status) status.done(false, r.error ?? "Audit failed");
|
|
100220
|
+
if (json) emitJson(r);
|
|
100221
|
+
process.exitCode = 1;
|
|
100222
|
+
return;
|
|
100223
|
+
}
|
|
100224
|
+
if (status) status.done(true, `${r.saved} rebuild prospect${r.saved === 1 ? "" : "s"} from ${r.found} checked`);
|
|
100225
|
+
autoSync();
|
|
100226
|
+
if (json) {
|
|
100227
|
+
emitJson(r);
|
|
100228
|
+
return;
|
|
100229
|
+
}
|
|
100230
|
+
const list = r.prospects ?? [];
|
|
100231
|
+
if (!list.length) {
|
|
100232
|
+
say();
|
|
100233
|
+
say(c.dim(` Checked ${r.found} businesses \u2014 none had a site bad enough to pitch against.`));
|
|
100234
|
+
say(c.dim(" That's a good sign for the area; try a different trade or a wider radius."));
|
|
100235
|
+
say();
|
|
100236
|
+
return;
|
|
100237
|
+
}
|
|
100238
|
+
say();
|
|
100239
|
+
say(c.dim(" Worst first \u2014 these are the easiest conversations to start."));
|
|
100240
|
+
say();
|
|
100241
|
+
for (const p of list) {
|
|
100242
|
+
say(` ${c.greenBold("#" + p.id)} ${c.bold(p.business)} ${c.dim(p.website.replace(/^https?:\/\//, ""))}`);
|
|
100243
|
+
say(` ${c.amber("score " + p.score + "/100")}`);
|
|
100244
|
+
for (const issue of p.issues) {
|
|
100245
|
+
const [sev, ...restText] = issue.split(": ");
|
|
100246
|
+
const tint = SEV_COLOUR[sev] ?? c.dim;
|
|
100247
|
+
say(` ${tint("\u25CF")} ${restText.join(": ")}`);
|
|
100248
|
+
}
|
|
100249
|
+
say();
|
|
100250
|
+
}
|
|
100251
|
+
say(c.dim(" Build one: sproutkit build <id> \xB7 see everything: sproutkit audit <id>"));
|
|
100252
|
+
say();
|
|
100253
|
+
} catch (e) {
|
|
100254
|
+
if (status) status.done(false, "Audit failed");
|
|
100255
|
+
json ? emitJson({ ok: false, error: e.message }) : say(c.red(" " + e.message));
|
|
100256
|
+
process.exitCode = 1;
|
|
100257
|
+
}
|
|
100258
|
+
}
|
|
99149
100259
|
async function cmdRegenerate(argv) {
|
|
99150
100260
|
const { flags, rest } = parseArgs(argv);
|
|
99151
100261
|
const json = !!flags.json;
|
|
@@ -99336,7 +100446,7 @@ async function cmdBuildAll(argv) {
|
|
|
99336
100446
|
detail: l.status === "built" ? l.siteUrl : l.status === "failed" ? l.error : l.message
|
|
99337
100447
|
});
|
|
99338
100448
|
await new Promise((resolve) => {
|
|
99339
|
-
const
|
|
100449
|
+
const emit2 = (channel, payload) => {
|
|
99340
100450
|
const snap2 = payload;
|
|
99341
100451
|
if (channel === "auto:progress" && board) board.set(snap2.leads.map(stateToRow));
|
|
99342
100452
|
if (channel === "auto:done") {
|
|
@@ -99363,7 +100473,7 @@ async function cmdBuildAll(argv) {
|
|
|
99363
100473
|
anthropicKey: anthropicKey ?? "",
|
|
99364
100474
|
vercelToken,
|
|
99365
100475
|
placesKey: getSetting("places_key"),
|
|
99366
|
-
emit
|
|
100476
|
+
emit: emit2
|
|
99367
100477
|
});
|
|
99368
100478
|
if (board) {
|
|
99369
100479
|
board.start(`Building ${leadIds.length} sites (up to ${concurrency} at once)`, snap.leads.map(stateToRow));
|
|
@@ -99408,6 +100518,8 @@ When a request is missing information the command needs, ask a SHORT, STRUCTURED
|
|
|
99408
100518
|
COMMANDS:
|
|
99409
100519
|
- sproutkit find "<area>" --categories "<type>,<type>" --json \u2014 find website-less leads
|
|
99410
100520
|
- sproutkit find "<area>" --categories "\u2026" --booking --json \u2014 find businesses that HAVE a site but take bookings via WhatsApp/phone only (booking-page prospects)
|
|
100521
|
+
- sproutkit audit "<area>" --categories "\u2026" --json \u2014 find businesses whose EXISTING site is insecure/outdated
|
|
100522
|
+
- sproutkit audit <id> | --url <site> --json \u2014 audit one site, list its faults
|
|
99411
100523
|
- sproutkit list [--status <s>] [--city <c>] [--limit 100] \u2014 formatted table; SHOW IT VERBATIM
|
|
99412
100524
|
- sproutkit list --json \u2014 same data as JSON, for reading ids only
|
|
99413
100525
|
- sproutkit build <id> --json [--instructions "..."] [--cms] [--multipage] \u2014 build a demo site (--multipage = real Home/Services/About/Contact pages, not one scroll)
|
|
@@ -99429,7 +100541,11 @@ COMMANDS:
|
|
|
99429
100541
|
If no command fits the request, say so in one line and name the closest thing you can do. Never invent results.`;
|
|
99430
100542
|
|
|
99431
100543
|
// src/doctor.ts
|
|
99432
|
-
|
|
100544
|
+
init_config();
|
|
100545
|
+
init_engine();
|
|
100546
|
+
init_desktop_install();
|
|
100547
|
+
init_tty();
|
|
100548
|
+
var import_child_process4 = require("child_process");
|
|
99433
100549
|
function mark(l) {
|
|
99434
100550
|
return l === "ok" ? c.green("\u2713") : l === "warn" ? c.amber("!") : c.red("\u2717");
|
|
99435
100551
|
}
|
|
@@ -99448,7 +100564,7 @@ async function runDoctor() {
|
|
|
99448
100564
|
if (backend === "claude_code") {
|
|
99449
100565
|
const present = (() => {
|
|
99450
100566
|
try {
|
|
99451
|
-
return (0,
|
|
100567
|
+
return (0, import_child_process4.spawnSync)(claudeBin(), ["--version"], { stdio: "ignore", timeout: 1e4 }).status === 0;
|
|
99452
100568
|
} catch {
|
|
99453
100569
|
return false;
|
|
99454
100570
|
}
|
|
@@ -99534,6 +100650,17 @@ async function runDoctor() {
|
|
|
99534
100650
|
fix: "Run 'sproutkit setup' and say yes to installing the skill, so `claude` can drive Sproutkit."
|
|
99535
100651
|
}
|
|
99536
100652
|
);
|
|
100653
|
+
if (desktopSupported()) {
|
|
100654
|
+
const desktop = desktopInstallPath();
|
|
100655
|
+
rows.push(
|
|
100656
|
+
desktop ? { level: "ok", label: "Desktop app", detail: desktop } : {
|
|
100657
|
+
level: "warn",
|
|
100658
|
+
label: "Desktop app",
|
|
100659
|
+
detail: "not installed",
|
|
100660
|
+
fix: "Run 'sproutkit desktop' to install it \u2014 your terminal leads sync into its map and board."
|
|
100661
|
+
}
|
|
100662
|
+
);
|
|
100663
|
+
}
|
|
99537
100664
|
rows.push(
|
|
99538
100665
|
commandsInstalled() ? { level: "ok", label: "Slash commands", detail: commandsTargetDir() } : {
|
|
99539
100666
|
level: "warn",
|
|
@@ -99560,12 +100687,13 @@ async function runDoctor() {
|
|
|
99560
100687
|
}
|
|
99561
100688
|
|
|
99562
100689
|
// src/index.ts
|
|
99563
|
-
|
|
100690
|
+
init_tty();
|
|
100691
|
+
var import_child_process5 = require("child_process");
|
|
99564
100692
|
process.env.SPROUTKIT_HEADLESS = "1";
|
|
99565
100693
|
function claudePresent() {
|
|
99566
100694
|
try {
|
|
99567
100695
|
const bin = process.env.SPROUTKIT_CLAUDE_BIN || "claude";
|
|
99568
|
-
return (0,
|
|
100696
|
+
return (0, import_child_process5.spawnSync)(bin, ["--version"], { stdio: "ignore", timeout: 1e4 }).status === 0;
|
|
99569
100697
|
} catch {
|
|
99570
100698
|
return false;
|
|
99571
100699
|
}
|
|
@@ -99573,6 +100701,11 @@ function claudePresent() {
|
|
|
99573
100701
|
async function main() {
|
|
99574
100702
|
const arg = process.argv[2];
|
|
99575
100703
|
initDatabase();
|
|
100704
|
+
if (arg === "mcp") {
|
|
100705
|
+
const { runMcpServer: runMcpServer2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
|
|
100706
|
+
await runMcpServer2();
|
|
100707
|
+
return;
|
|
100708
|
+
}
|
|
99576
100709
|
if (arg === "update") {
|
|
99577
100710
|
await runUpdate();
|
|
99578
100711
|
closeTty();
|
|
@@ -99592,11 +100725,17 @@ async function main() {
|
|
|
99592
100725
|
const r = syncToDesktop();
|
|
99593
100726
|
if (!r.ok && r.reason === "no_desktop_db") {
|
|
99594
100727
|
say(c.dim(" No desktop Sproutkit database found \u2014 nothing to sync to."));
|
|
99595
|
-
say(c.dim(" Install
|
|
100728
|
+
say(c.dim(" Install it with 'sproutkit desktop' and open it once to create it."));
|
|
99596
100729
|
}
|
|
99597
100730
|
closeTty();
|
|
99598
100731
|
return;
|
|
99599
100732
|
}
|
|
100733
|
+
if (arg === "desktop") {
|
|
100734
|
+
const { runDesktopCommand: runDesktopCommand2 } = await Promise.resolve().then(() => (init_desktop_install(), desktop_install_exports));
|
|
100735
|
+
await runDesktopCommand2(process.argv.slice(3));
|
|
100736
|
+
closeTty();
|
|
100737
|
+
return;
|
|
100738
|
+
}
|
|
99600
100739
|
if (arg === "setup") {
|
|
99601
100740
|
await runOnboarding(true);
|
|
99602
100741
|
closeTty();
|
|
@@ -99607,7 +100746,7 @@ async function main() {
|
|
|
99607
100746
|
closeTty();
|
|
99608
100747
|
return;
|
|
99609
100748
|
}
|
|
99610
|
-
if (arg === "find" || arg === "list" || arg === "build" || arg === "build-all" || arg === "regenerate" || arg === "cms" || arg === "book" || arg === "handover" || arg === "brand" || arg === "invoice" || arg === "letter" || arg === "reply" || arg === "followups" || arg === "report" || arg === "outreach" || arg === "pipeline") {
|
|
100749
|
+
if (arg === "find" || arg === "list" || arg === "build" || arg === "build-all" || arg === "regenerate" || arg === "cms" || arg === "book" || arg === "handover" || arg === "audit" || arg === "brand" || arg === "invoice" || arg === "letter" || arg === "reply" || arg === "followups" || arg === "report" || arg === "outreach" || arg === "pipeline") {
|
|
99611
100750
|
const subArgs = process.argv.slice(3);
|
|
99612
100751
|
if (subArgs.includes("--help") || subArgs.includes("-h")) {
|
|
99613
100752
|
const USAGE = {
|
|
@@ -99647,6 +100786,16 @@ async function main() {
|
|
|
99647
100786
|
' --instructions "\u2026" e.g. "45-min slots, add beard trim \xA312"',
|
|
99648
100787
|
" --email <addr> owner email for booking notifications"
|
|
99649
100788
|
],
|
|
100789
|
+
audit: [
|
|
100790
|
+
'sproutkit audit "<area>" --categories "barber shop,cafe"',
|
|
100791
|
+
" finds businesses that HAVE a website but whose site is costing them",
|
|
100792
|
+
" work \u2014 no HTTPS, unusable on phones, built in 2008 \u2014 and scores it",
|
|
100793
|
+
" --radius <m> search radius (default 10000)",
|
|
100794
|
+
" --limit <n> max prospects to save (default 25)",
|
|
100795
|
+
"",
|
|
100796
|
+
" one site: sproutkit audit <leadId>",
|
|
100797
|
+
" sproutkit audit --url thebarbers.co.uk"
|
|
100798
|
+
],
|
|
99650
100799
|
brand: [
|
|
99651
100800
|
'sproutkit brand --name "Your Studio" --email you@x.com [--vat-rate 20]',
|
|
99652
100801
|
" your agency identity \u2014 goes on invoices, letters, the site footer",
|
|
@@ -99709,7 +100858,7 @@ async function main() {
|
|
|
99709
100858
|
}
|
|
99710
100859
|
const lic2 = await check();
|
|
99711
100860
|
if (lic2.status !== "active") {
|
|
99712
|
-
const msg = lic2.status === "offline_grace_expired" ? "Licence check offline and grace expired \u2014 reconnect and retry." : "No active licence. Run 'sproutkit setup' first.";
|
|
100861
|
+
const msg = lic2.status === "expired" ? "Your Sproutkit subscription has ended. Renew at https://sproutkit.app/#pricing." : lic2.status === "offline_grace_expired" ? "Licence check offline and grace expired \u2014 reconnect and retry." : "No active licence. Run 'sproutkit setup' first.";
|
|
99713
100862
|
if (subArgs.includes("--json")) process.stdout.write(JSON.stringify({ ok: false, error: msg }) + "\n");
|
|
99714
100863
|
else say(c.red(` ${msg}`));
|
|
99715
100864
|
closeTty();
|
|
@@ -99724,6 +100873,7 @@ async function main() {
|
|
|
99724
100873
|
else if (arg === "cms") await cmdCms(subArgs);
|
|
99725
100874
|
else if (arg === "book") await cmdBook(subArgs);
|
|
99726
100875
|
else if (arg === "handover") await cmdHandover(subArgs);
|
|
100876
|
+
else if (arg === "audit") await cmdAudit(subArgs);
|
|
99727
100877
|
else if (arg === "brand") await cmdBrand(subArgs);
|
|
99728
100878
|
else if (arg === "invoice") await cmdInvoice(subArgs);
|
|
99729
100879
|
else if (arg === "letter") await cmdLetter(subArgs);
|
|
@@ -99753,6 +100903,7 @@ async function main() {
|
|
|
99753
100903
|
say(` ${c.bold("sproutkit setup")} set or update keys, licence, backend`);
|
|
99754
100904
|
say(` ${c.bold("sproutkit doctor")} check everything is wired up`);
|
|
99755
100905
|
say(` ${c.bold("sproutkit models")} list Claude models and pick one`);
|
|
100906
|
+
say(` ${c.bold("sproutkit desktop")} install and open the desktop app (--update)`);
|
|
99756
100907
|
say(` ${c.bold("sproutkit sync")} push your leads into the desktop app`);
|
|
99757
100908
|
say(` ${c.bold("sproutkit update")} update to the latest version`);
|
|
99758
100909
|
say(` ${c.bold("sproutkit version")} show the installed version`);
|
|
@@ -99772,7 +100923,7 @@ async function main() {
|
|
|
99772
100923
|
}
|
|
99773
100924
|
const lic = await check();
|
|
99774
100925
|
if (lic.status !== "active") {
|
|
99775
|
-
const why = lic.status === "revoked" ? "Your licence has been revoked." : lic.status === "refunded" ? "Your licence was refunded." : lic.status === "offline_grace_expired" ? "Can't reach the licence server and your offline grace period has expired. Reconnect and try again." : "No active licence. Run 'sproutkit setup' to enter your key, or buy one at https://sproutkit.app";
|
|
100926
|
+
const why = lic.status === "revoked" ? "Your licence has been revoked." : lic.status === "refunded" ? "Your licence was refunded." : lic.status === "expired" ? "Your Sproutkit subscription has ended. Renew at https://sproutkit.app/#pricing, then run 'sproutkit setup' with your new key." : lic.status === "offline_grace_expired" ? "Can't reach the licence server and your offline grace period has expired. Reconnect and try again." : "No active licence. Run 'sproutkit setup' to enter your key, or buy one at https://sproutkit.app";
|
|
99776
100927
|
say(c.red(` ${why}`));
|
|
99777
100928
|
closeTty();
|
|
99778
100929
|
return;
|
|
@@ -99813,7 +100964,7 @@ async function main() {
|
|
|
99813
100964
|
];
|
|
99814
100965
|
if (oneShot) claudeArgs.push(oneShot);
|
|
99815
100966
|
closeTty();
|
|
99816
|
-
const child = (0,
|
|
100967
|
+
const child = (0, import_child_process5.spawn)(claudeBin(), claudeArgs, { stdio: "inherit" });
|
|
99817
100968
|
child.on("error", (e) => {
|
|
99818
100969
|
say(c.red(` Couldn't start Claude Code: ${e.message}`));
|
|
99819
100970
|
process.exitCode = 1;
|