sootsim 0.1.291 → 0.1.293
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/detox/expectations.ts +32 -12
- package/dist-cli/bin.js +5 -5
- package/dist-cli/chunks/{agent-EDS4HRKB.js → agent-YWI2NWL7.js} +2 -2
- package/dist-cli/chunks/{agent-wrapper-ZCSAPGFF.js → agent-wrapper-IYJ7UZOA.js} +2 -2
- package/dist-cli/chunks/{app-fonts-4WW4EQEW.js → app-fonts-FQFUC4LR.js} +2 -2
- package/dist-cli/chunks/{assert-XEWAR4HT.js → assert-XUCELWAC.js} +2 -2
- package/dist-cli/chunks/{auth-SAYME64O.js → auth-4DQTV3OW.js} +2 -2
- package/dist-cli/chunks/beta-CFDAW6UN.js +2 -0
- package/dist-cli/chunks/{camera-2AHKTJ5I.js → camera-RYOHBVZA.js} +2 -2
- package/dist-cli/chunks/{chunk-7CU7FXRN.js → chunk-2M57EAWS.js} +1 -1
- package/dist-cli/chunks/{chunk-LJU4JU3N.js → chunk-2VKTOZQ5.js} +2 -2
- package/dist-cli/chunks/{chunk-NGPK2CLP.js → chunk-2XYCSFGN.js} +3 -3
- package/dist-cli/chunks/{chunk-UQLIMTO6.js → chunk-3UX6AY2B.js} +1 -1
- package/dist-cli/chunks/{chunk-R36NUSCM.js → chunk-4B4VFT73.js} +2 -2
- package/dist-cli/chunks/{chunk-KQKLLUX5.js → chunk-547W23BB.js} +2 -2
- package/dist-cli/chunks/{chunk-KSN2WTV6.js → chunk-67CIS55C.js} +1 -1
- package/dist-cli/chunks/{chunk-VK3IISND.js → chunk-6IFJLHDA.js} +1 -1
- package/dist-cli/chunks/{chunk-NRXMKMIJ.js → chunk-6VVLDYPV.js} +2 -2
- package/dist-cli/chunks/{chunk-LD5ZN4ZU.js → chunk-7B6RGFTM.js} +2 -2
- package/dist-cli/chunks/{chunk-HFJEB4UJ.js → chunk-7H34H74K.js} +2 -2
- package/dist-cli/chunks/{chunk-HQRKN435.js → chunk-7H5G4HUK.js} +2 -2
- package/dist-cli/chunks/{chunk-OC6PU44E.js → chunk-ACSTEPSD.js} +1 -1
- package/dist-cli/chunks/chunk-AFRXWKTA.js +118 -0
- package/dist-cli/chunks/{chunk-7GKJ3U2Z.js → chunk-B7TX4WFB.js} +2 -2
- package/dist-cli/chunks/{chunk-EFTPP4W3.js → chunk-BQT5YDTV.js} +3 -3
- package/dist-cli/chunks/{chunk-NPP6ZJLD.js → chunk-DE4ZA3NL.js} +2 -2
- package/dist-cli/chunks/{chunk-462J7KLI.js → chunk-E5WYXRGV.js} +3 -3
- package/dist-cli/chunks/chunk-HKMWUN7F.js +2 -0
- package/dist-cli/chunks/{chunk-5CJQNMXY.js → chunk-J6P2UPXH.js} +2 -2
- package/dist-cli/chunks/{chunk-GJDCBMAP.js → chunk-JOPKZVOW.js} +1 -1
- package/dist-cli/chunks/{chunk-EPJO7YNS.js → chunk-K5JEUI5G.js} +1 -1
- package/dist-cli/chunks/{chunk-5D5XSE5V.js → chunk-KC5SCOGS.js} +2 -2
- package/dist-cli/chunks/{chunk-FWC4J42U.js → chunk-LA5DIO33.js} +1 -1
- package/dist-cli/chunks/{chunk-653O3F3M.js → chunk-LOQLZFRK.js} +2 -2
- package/dist-cli/chunks/{chunk-QOIOK64H.js → chunk-MOU2WLO4.js} +1 -1
- package/dist-cli/chunks/{chunk-LHBU5QMM.js → chunk-NCCMRFXU.js} +1 -1
- package/dist-cli/chunks/{chunk-5IBT7JOS.js → chunk-PCAPHXN3.js} +2 -2
- package/dist-cli/chunks/chunk-QXDXUDJD.js +1 -0
- package/dist-cli/chunks/{chunk-NN4CZ2QW.js → chunk-RKXHQ2Q3.js} +1 -1
- package/dist-cli/chunks/{chunk-Z6I5M7VJ.js → chunk-RMLJXP7T.js} +2 -2
- package/dist-cli/chunks/chunk-RV67J726.js +2 -0
- package/dist-cli/chunks/{chunk-UZA3Q67P.js → chunk-TJS5IMOH.js} +1 -1
- package/dist-cli/chunks/{chunk-KTTLGU7Y.js → chunk-U3564F2Y.js} +2 -2
- package/dist-cli/chunks/{chunk-3FBFOGQJ.js → chunk-UOHGYYSO.js} +1 -1
- package/dist-cli/chunks/{chunk-DLMAMKWL.js → chunk-UPKYK52K.js} +2 -2
- package/dist-cli/chunks/{chunk-GZON2OYB.js → chunk-USJTVC7T.js} +1 -1
- package/dist-cli/chunks/{chunk-U6GFEFUD.js → chunk-VO74GDXL.js} +3 -3
- package/dist-cli/chunks/{chunk-76O3ZWTI.js → chunk-VZ44FQDG.js} +1 -1
- package/dist-cli/chunks/chunk-WI36YJ23.js +2 -0
- package/dist-cli/chunks/{chunk-5NGZRMTN.js → chunk-WOWLO4LL.js} +1 -1
- package/dist-cli/chunks/chunk-WP3TFHFL.js +10 -0
- package/dist-cli/chunks/{chunk-KBG6WN24.js → chunk-WPPMUUML.js} +2 -2
- package/dist-cli/chunks/{chunk-ZYS5SEB2.js → chunk-WVMYRKSS.js} +2 -2
- package/dist-cli/chunks/chunk-YNG4C3ZS.js +2 -0
- package/dist-cli/chunks/{chunk-JTZNB4PB.js → chunk-YRFWATLA.js} +2 -2
- package/dist-cli/chunks/{cleanup-KXX5W42A.js → cleanup-BLFDJSFS.js} +2 -2
- package/dist-cli/chunks/cli-version-TQHZOK4L.js +2 -0
- package/dist-cli/chunks/{compat-VDVJ2I74.js → compat-Q3WCSTB7.js} +3 -3
- package/dist-cli/chunks/{config-FIQQP5FR.js → config-NHNMRRNB.js} +2 -2
- package/dist-cli/chunks/control-I7YBDRJT.js +2 -0
- package/dist-cli/chunks/daemon-4R3SZLZY.js +2 -0
- package/dist-cli/chunks/{debug-LPLH46JF.js → debug-PGRMZFXA.js} +3 -3
- package/dist-cli/chunks/{desktop-4HDRWKMN.js → desktop-NVTQ37LH.js} +3 -3
- package/dist-cli/chunks/{detox-U23WKW23.js → detox-W3JDXS76.js} +2 -2
- package/dist-cli/chunks/{device-HZKTA7ZV.js → device-KQYN3EVK.js} +2 -2
- package/dist-cli/chunks/{diagnose-M64QUWBW.js → diagnose-CPUKSGNO.js} +2 -2
- package/dist-cli/chunks/disk-cleanup-2COWZWBC.js +2 -0
- package/dist-cli/chunks/drivers-RRZM6E72.js +2 -0
- package/dist-cli/chunks/{film-4IB44CT3.js → film-VZGAZ2YY.js} +3 -3
- package/dist-cli/chunks/flow-VH6DFDQ4.js +2 -0
- package/dist-cli/chunks/help-3HQ2RINO.js +2 -0
- package/dist-cli/chunks/{hidden-runtime-alias-UEU5POA4.js → hidden-runtime-alias-KWHABCNZ.js} +2 -2
- package/dist-cli/chunks/{home-paths-2C4YKPPX.js → home-paths-O4CGYVHF.js} +2 -2
- package/dist-cli/chunks/inspect-PKMJGXDH.js +2 -0
- package/dist-cli/chunks/install-desktop-K5TP3ZHJ.js +2 -0
- package/dist-cli/chunks/{login-MY54AOXW.js → login-KPN4Z26Q.js} +4 -4
- package/dist-cli/chunks/{logout-LYR2RDJY.js → logout-E3UCJAMC.js} +2 -2
- package/dist-cli/chunks/{maestro-4RAMCNZQ.js → maestro-PYA4AHTS.js} +3 -3
- package/dist-cli/chunks/{maestro-generate-CBSUR73A.js → maestro-generate-KCMYWPWL.js} +3 -3
- package/dist-cli/chunks/{mode-2KATMMXB.js → mode-AEB7G2SJ.js} +2 -2
- package/dist-cli/chunks/optional-demo-registry-AIWOBAAA.js +2 -0
- package/dist-cli/chunks/{perf-FVL2ZRQW.js → perf-YLXGZI3E.js} +2 -2
- package/dist-cli/chunks/permissions-7VMVZOUV.js +11 -0
- package/dist-cli/chunks/{record-TCD4VLNH.js → record-AVQO45PE.js} +3 -3
- package/dist-cli/chunks/runtime-HOGETVVD.js +2 -0
- package/dist-cli/chunks/{screenshot-command-ENCJ4W2W.js → screenshot-command-LACQLA4N.js} +3 -3
- package/dist-cli/chunks/{screenshots-capture-FVVMZPFO.js → screenshots-capture-PROOBSGB.js} +2 -2
- package/dist-cli/chunks/{serve-HNHS3QBP.js → serve-FJN2FRGW.js} +2 -2
- package/dist-cli/chunks/{setup-MRLIGVU4.js → setup-IVV4NRYQ.js} +3 -3
- package/dist-cli/chunks/{skills-2LW5BE7P.js → skills-WYR3PJOH.js} +2 -2
- package/dist-cli/chunks/{storage-KH5HQF3V.js → storage-GM7K4MGM.js} +2 -2
- package/dist-cli/chunks/store-YLVHPKG7.js +2 -0
- package/dist-cli/chunks/telemetry-MQKB6PFX.js +2 -0
- package/dist-cli/chunks/{timeline-BWFBU4VM.js → timeline-R5UL3N4T.js} +2 -2
- package/dist-cli/chunks/{upgrade-GZFX4JEO.js → upgrade-RWHSFZRX.js} +2 -2
- package/dist-cli/chunks/upload-RBH4XGJ2.js +2 -0
- package/dist-cli/chunks/{version-OKMVZCP5.js → version-7K6TVQOW.js} +2 -2
- package/dist-cli/chunks/web-46ZPQCAL.js +2 -0
- package/dist-cli/chunks/{what-happened-MC7JDW6C.js → what-happened-K24TSJZX.js} +2 -2
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-identity.cjs +1 -1
- package/dist-lib/agent-sessions.cjs +1 -1
- package/dist-lib/attached-projects.cjs +1 -1
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +1 -1
- package/dist-lib/beta.cjs +1 -1
- package/dist-lib/beta.mjs +1 -1
- package/dist-lib/bridge-constants.cjs +1 -1
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/detox/index.cjs +24 -6
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +411 -66
- package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +1 -1
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/menu.cjs +38 -2
- package/dist-lib/menu.mjs +38 -2
- package/dist-lib/metro.cjs +1 -1
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/render-mode.cjs +1 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +354 -2
- package/dist-lib/sdk.cjs +1 -1
- package/dist-lib/sdk.mjs +1 -1
- package/dist-lib/skills.cjs +443 -91
- package/dist-lib/vite.cjs +1 -1
- package/package.json +2 -1
- package/scripts/dev-server-scanner.ts +27 -1
- package/skills/contrast/SKILL.md +1 -0
- package/src/menu.ts +38 -1
- package/src/settings-bundle.ts +439 -0
- package/dist-cli/chunks/beta-HKVUNMLY.js +0 -2
- package/dist-cli/chunks/chunk-5ZBUNUUE.js +0 -2
- package/dist-cli/chunks/chunk-7NW75BHD.js +0 -5
- package/dist-cli/chunks/chunk-H7F2BILD.js +0 -118
- package/dist-cli/chunks/chunk-IDZP6WN5.js +0 -2
- package/dist-cli/chunks/chunk-IGPDVTHJ.js +0 -2
- package/dist-cli/chunks/chunk-KU3T3N2W.js +0 -1
- package/dist-cli/chunks/chunk-ZEYCE3XJ.js +0 -2
- package/dist-cli/chunks/cli-version-IQXVYN67.js +0 -2
- package/dist-cli/chunks/control-GDBZBVQC.js +0 -2
- package/dist-cli/chunks/daemon-Y76JSFGV.js +0 -2
- package/dist-cli/chunks/disk-cleanup-P662TT6J.js +0 -2
- package/dist-cli/chunks/drivers-CKWEDYVG.js +0 -2
- package/dist-cli/chunks/flow-WDFYSQKC.js +0 -2
- package/dist-cli/chunks/help-2S3OHQLT.js +0 -2
- package/dist-cli/chunks/inspect-SKU24VE3.js +0 -2
- package/dist-cli/chunks/install-desktop-RKURHJ34.js +0 -2
- package/dist-cli/chunks/optional-demo-registry-26Q7AW7X.js +0 -2
- package/dist-cli/chunks/runtime-Z3D53UGW.js +0 -2
- package/dist-cli/chunks/store-IBEI6PK4.js +0 -2
- package/dist-cli/chunks/telemetry-3T56HLDZ.js +0 -2
- package/dist-cli/chunks/upload-PCXRS5D7.js +0 -2
- package/dist-cli/chunks/web-ZHCP6WFY.js +0 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.293 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -142,6 +142,339 @@ function normalizeNativeDevBundleUrl(bundleUrl) {
|
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
+
// src/settings-bundle.ts
|
|
146
|
+
var import_promises = require("node:fs/promises");
|
|
147
|
+
var import_node_path = require("node:path");
|
|
148
|
+
var import_plist = __toESM(require("@expo/plist"), 1);
|
|
149
|
+
var MAX_PLIST_BYTES = 1048576;
|
|
150
|
+
var MAX_CHILD_DEPTH = 8;
|
|
151
|
+
var MAX_PLIST_FILES = 32;
|
|
152
|
+
var MAX_SPECIFIERS = 512;
|
|
153
|
+
var settingsBundleCache = /* @__PURE__ */ new Map();
|
|
154
|
+
function isRecord(value) {
|
|
155
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
156
|
+
}
|
|
157
|
+
function resolvePlistParser(value) {
|
|
158
|
+
if (!isRecord(value)) return null;
|
|
159
|
+
const direct = value.parse;
|
|
160
|
+
if (typeof direct === "function") {
|
|
161
|
+
return (source) => Reflect.apply(direct, value, [source]);
|
|
162
|
+
}
|
|
163
|
+
const nested = value.default;
|
|
164
|
+
if (!isRecord(nested)) return null;
|
|
165
|
+
const nestedParse = nested.parse;
|
|
166
|
+
return typeof nestedParse === "function" ? (source) => Reflect.apply(nestedParse, nested, [source]) : null;
|
|
167
|
+
}
|
|
168
|
+
var parsePlist = resolvePlistParser(import_plist.default);
|
|
169
|
+
function optionalString(value) {
|
|
170
|
+
return typeof value === "string" ? value : void 0;
|
|
171
|
+
}
|
|
172
|
+
function requiredString(value) {
|
|
173
|
+
if (typeof value !== "string") return null;
|
|
174
|
+
const normalized = value.trim();
|
|
175
|
+
return normalized ? normalized : null;
|
|
176
|
+
}
|
|
177
|
+
function finiteNumber(value) {
|
|
178
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
179
|
+
}
|
|
180
|
+
function preferenceValue(value) {
|
|
181
|
+
if (typeof value === "string" || typeof value === "boolean") return value;
|
|
182
|
+
return finiteNumber(value);
|
|
183
|
+
}
|
|
184
|
+
function keyboardType(value) {
|
|
185
|
+
if (typeof value !== "string") return void 0;
|
|
186
|
+
switch (value.replaceAll(/[-_\s]/g, "").toLowerCase()) {
|
|
187
|
+
case "alphabet":
|
|
188
|
+
return "alphabet";
|
|
189
|
+
case "numbersandpunctuation":
|
|
190
|
+
return "numbers-and-punctuation";
|
|
191
|
+
case "numberpad":
|
|
192
|
+
return "number-pad";
|
|
193
|
+
case "url":
|
|
194
|
+
return "url";
|
|
195
|
+
case "emailaddress":
|
|
196
|
+
return "email-address";
|
|
197
|
+
case "namephonepad":
|
|
198
|
+
return "name-phone-pad";
|
|
199
|
+
case "asciicapable":
|
|
200
|
+
return "ascii-capable";
|
|
201
|
+
default:
|
|
202
|
+
return void 0;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
function autocapitalization(value) {
|
|
206
|
+
if (typeof value !== "string") return void 0;
|
|
207
|
+
switch (value.replaceAll(/[-_\s]/g, "").toLowerCase()) {
|
|
208
|
+
case "none":
|
|
209
|
+
return "none";
|
|
210
|
+
case "sentences":
|
|
211
|
+
return "sentences";
|
|
212
|
+
case "words":
|
|
213
|
+
return "words";
|
|
214
|
+
case "allcharacters":
|
|
215
|
+
return "all-characters";
|
|
216
|
+
default:
|
|
217
|
+
return void 0;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
function autocorrection(value) {
|
|
221
|
+
if (typeof value === "boolean") return value;
|
|
222
|
+
if (typeof value !== "string") return void 0;
|
|
223
|
+
switch (value.trim().toLowerCase()) {
|
|
224
|
+
case "yes":
|
|
225
|
+
return true;
|
|
226
|
+
case "no":
|
|
227
|
+
return false;
|
|
228
|
+
default:
|
|
229
|
+
return void 0;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
function safeChildPlistName(value) {
|
|
233
|
+
const file = requiredString(value);
|
|
234
|
+
if (!file || file.includes("/") || file.includes("\\") || file.includes("..")) {
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
return {
|
|
238
|
+
file,
|
|
239
|
+
name: file.toLowerCase().endsWith(".plist") ? file : `${file}.plist`
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
async function readableSettingsBundle(path9) {
|
|
243
|
+
try {
|
|
244
|
+
const root = await (0, import_promises.stat)((0, import_node_path.join)(path9, "Root.plist"));
|
|
245
|
+
return root.isFile() && root.size <= MAX_PLIST_BYTES;
|
|
246
|
+
} catch {
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
async function findSettingsBundle(projectRoot) {
|
|
251
|
+
const directCandidates = [
|
|
252
|
+
(0, import_node_path.join)(projectRoot, "Settings.bundle"),
|
|
253
|
+
(0, import_node_path.join)(projectRoot, "ios", "Settings.bundle")
|
|
254
|
+
];
|
|
255
|
+
for (const candidate of directCandidates) {
|
|
256
|
+
if (await readableSettingsBundle(candidate)) return candidate;
|
|
257
|
+
}
|
|
258
|
+
try {
|
|
259
|
+
const iosRoot = (0, import_node_path.join)(projectRoot, "ios");
|
|
260
|
+
const children = await (0, import_promises.readdir)(iosRoot, { withFileTypes: true });
|
|
261
|
+
const candidates = children.filter(
|
|
262
|
+
(entry) => entry.isDirectory() && entry.name !== "Pods" && entry.name !== "build" && !entry.name.startsWith(".")
|
|
263
|
+
).map((entry) => (0, import_node_path.join)(iosRoot, entry.name, "Settings.bundle")).sort();
|
|
264
|
+
for (const candidate of candidates) {
|
|
265
|
+
if (await readableSettingsBundle(candidate)) return candidate;
|
|
266
|
+
}
|
|
267
|
+
} catch {
|
|
268
|
+
}
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
async function settingsBundleFingerprint(bundlePath) {
|
|
272
|
+
try {
|
|
273
|
+
const entries = await (0, import_promises.readdir)(bundlePath, { withFileTypes: true });
|
|
274
|
+
const names = entries.filter((entry) => entry.isFile() && entry.name.toLowerCase().endsWith(".plist")).map((entry) => entry.name).sort().slice(0, MAX_PLIST_FILES + 1);
|
|
275
|
+
if (names.length === 0 || names.length > MAX_PLIST_FILES) return null;
|
|
276
|
+
const parts = await Promise.all(
|
|
277
|
+
names.map(async (name) => {
|
|
278
|
+
const metadata = await (0, import_promises.stat)((0, import_node_path.join)(bundlePath, name));
|
|
279
|
+
if (!metadata.isFile() || metadata.size > MAX_PLIST_BYTES) return null;
|
|
280
|
+
return `${name}:${metadata.size}:${metadata.mtimeMs}:${metadata.ctimeMs}`;
|
|
281
|
+
})
|
|
282
|
+
);
|
|
283
|
+
if (parts.some((part) => part === null)) return null;
|
|
284
|
+
return parts.join("|");
|
|
285
|
+
} catch {
|
|
286
|
+
return null;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
async function parsePlistRecord(path9) {
|
|
290
|
+
try {
|
|
291
|
+
if (!parsePlist) return null;
|
|
292
|
+
const metadata = await (0, import_promises.stat)(path9);
|
|
293
|
+
if (!metadata.isFile() || metadata.size > MAX_PLIST_BYTES) return null;
|
|
294
|
+
const source = await (0, import_promises.readFile)(path9, "utf8");
|
|
295
|
+
const parsed = parsePlist(source);
|
|
296
|
+
return isRecord(parsed) ? parsed : null;
|
|
297
|
+
} catch {
|
|
298
|
+
return null;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
function normalizeMultiValue(raw, key, title) {
|
|
302
|
+
if (!Array.isArray(raw.Values) || !Array.isArray(raw.Titles)) return null;
|
|
303
|
+
const values = [];
|
|
304
|
+
const titles = [];
|
|
305
|
+
let optionType;
|
|
306
|
+
const pairCount = Math.min(raw.Values.length, raw.Titles.length);
|
|
307
|
+
for (let index = 0; index < pairCount; index++) {
|
|
308
|
+
const value = preferenceValue(raw.Values[index]);
|
|
309
|
+
const optionTitle = optionalString(raw.Titles[index]);
|
|
310
|
+
if (value === null || optionTitle === void 0) continue;
|
|
311
|
+
const valueType = typeof value === "string" ? "string" : typeof value === "number" ? "number" : "boolean";
|
|
312
|
+
if (optionType !== void 0 && valueType !== optionType) continue;
|
|
313
|
+
optionType = valueType;
|
|
314
|
+
values.push(value);
|
|
315
|
+
titles.push(optionTitle);
|
|
316
|
+
}
|
|
317
|
+
const firstValue = values[0];
|
|
318
|
+
if (firstValue === void 0) return null;
|
|
319
|
+
const declaredDefault = preferenceValue(raw.DefaultValue);
|
|
320
|
+
const defaultValue = declaredDefault !== null && values.includes(declaredDefault) ? declaredDefault : firstValue;
|
|
321
|
+
return {
|
|
322
|
+
type: "multi-value",
|
|
323
|
+
key,
|
|
324
|
+
title,
|
|
325
|
+
defaultValue,
|
|
326
|
+
currentValue: defaultValue,
|
|
327
|
+
values,
|
|
328
|
+
titles
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
async function normalizeSpecifier(raw, context) {
|
|
332
|
+
if (!isRecord(raw)) return null;
|
|
333
|
+
if (context.budget.specifiers >= MAX_SPECIFIERS) return null;
|
|
334
|
+
const type = requiredString(raw.Type);
|
|
335
|
+
if (!type) return null;
|
|
336
|
+
context.budget.specifiers += 1;
|
|
337
|
+
if (type === "PSGroupSpecifier") {
|
|
338
|
+
const title2 = optionalString(raw.Title);
|
|
339
|
+
const footer = optionalString(raw.FooterText);
|
|
340
|
+
return {
|
|
341
|
+
type: "group",
|
|
342
|
+
...title2 !== void 0 ? { title: title2 } : null,
|
|
343
|
+
...footer !== void 0 ? { footer } : null
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
const key = requiredString(raw.Key);
|
|
347
|
+
if (type === "PSSliderSpecifier") {
|
|
348
|
+
if (!key) return null;
|
|
349
|
+
const minimumValue = finiteNumber(raw.MinimumValue);
|
|
350
|
+
const maximumValue = finiteNumber(raw.MaximumValue);
|
|
351
|
+
if (minimumValue === null || maximumValue === null || maximumValue <= minimumValue) {
|
|
352
|
+
return null;
|
|
353
|
+
}
|
|
354
|
+
const declaredDefault = finiteNumber(raw.DefaultValue);
|
|
355
|
+
const defaultValue = Math.min(
|
|
356
|
+
maximumValue,
|
|
357
|
+
Math.max(minimumValue, declaredDefault ?? minimumValue)
|
|
358
|
+
);
|
|
359
|
+
const title2 = optionalString(raw.Title);
|
|
360
|
+
const minimumValueImage = optionalString(raw.MinimumValueImage);
|
|
361
|
+
const maximumValueImage = optionalString(raw.MaximumValueImage);
|
|
362
|
+
return {
|
|
363
|
+
type: "slider",
|
|
364
|
+
key,
|
|
365
|
+
defaultValue,
|
|
366
|
+
currentValue: defaultValue,
|
|
367
|
+
minimumValue,
|
|
368
|
+
maximumValue,
|
|
369
|
+
...title2 !== void 0 ? { title: title2 } : null,
|
|
370
|
+
...minimumValueImage !== void 0 ? { minimumValueImage } : null,
|
|
371
|
+
...maximumValueImage !== void 0 ? { maximumValueImage } : null
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
if (type === "PSChildPaneSpecifier") {
|
|
375
|
+
const title2 = requiredString(raw.Title);
|
|
376
|
+
const child = safeChildPlistName(raw.File);
|
|
377
|
+
if (!title2 || !child || context.depth >= MAX_CHILD_DEPTH) return null;
|
|
378
|
+
const childSpecifiers = await parseSpecifierFile(child.name, {
|
|
379
|
+
...context,
|
|
380
|
+
depth: context.depth + 1
|
|
381
|
+
});
|
|
382
|
+
if (!childSpecifiers || childSpecifiers.length === 0) return null;
|
|
383
|
+
return {
|
|
384
|
+
type: "child-pane",
|
|
385
|
+
title: title2,
|
|
386
|
+
file: child.file,
|
|
387
|
+
specifiers: childSpecifiers
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
if (!key) return null;
|
|
391
|
+
const title = requiredString(raw.Title) ?? key;
|
|
392
|
+
if (type === "PSToggleSwitchSpecifier") {
|
|
393
|
+
const defaultValue = typeof raw.DefaultValue === "boolean" ? raw.DefaultValue : false;
|
|
394
|
+
return {
|
|
395
|
+
type: "toggle",
|
|
396
|
+
key,
|
|
397
|
+
title,
|
|
398
|
+
defaultValue,
|
|
399
|
+
currentValue: defaultValue
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
if (type === "PSTextFieldSpecifier") {
|
|
403
|
+
const defaultValue = optionalString(raw.DefaultValue) ?? "";
|
|
404
|
+
const placeholder = optionalString(raw.Placeholder);
|
|
405
|
+
const resolvedKeyboardType = keyboardType(raw.KeyboardType);
|
|
406
|
+
const resolvedAutocapitalization = autocapitalization(raw.AutocapitalizationType);
|
|
407
|
+
const resolvedAutocorrection = autocorrection(raw.AutocorrectionType);
|
|
408
|
+
return {
|
|
409
|
+
type: "text",
|
|
410
|
+
key,
|
|
411
|
+
title,
|
|
412
|
+
defaultValue,
|
|
413
|
+
currentValue: defaultValue,
|
|
414
|
+
...placeholder !== void 0 ? { placeholder } : null,
|
|
415
|
+
...typeof raw.IsSecure === "boolean" ? { secure: raw.IsSecure } : null,
|
|
416
|
+
...resolvedKeyboardType ? { keyboardType: resolvedKeyboardType } : null,
|
|
417
|
+
...resolvedAutocapitalization ? { autocapitalization: resolvedAutocapitalization } : null,
|
|
418
|
+
...resolvedAutocorrection !== void 0 ? { autocorrection: resolvedAutocorrection } : null
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
if (type === "PSMultiValueSpecifier" || type === "PSRadioGroupSpecifier") {
|
|
422
|
+
return normalizeMultiValue(raw, key, title);
|
|
423
|
+
}
|
|
424
|
+
if (type === "PSTitleValueSpecifier") {
|
|
425
|
+
const defaultValue = preferenceValue(raw.DefaultValue) ?? "";
|
|
426
|
+
return {
|
|
427
|
+
type: "title-value",
|
|
428
|
+
key,
|
|
429
|
+
title,
|
|
430
|
+
defaultValue,
|
|
431
|
+
currentValue: defaultValue
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
return null;
|
|
435
|
+
}
|
|
436
|
+
async function parseSpecifierFile(fileName, context) {
|
|
437
|
+
const cached3 = context.fileCache.get(fileName);
|
|
438
|
+
if (cached3 !== void 0) return cached3;
|
|
439
|
+
if (context.stack.has(fileName) || context.budget.files >= MAX_PLIST_FILES) {
|
|
440
|
+
return null;
|
|
441
|
+
}
|
|
442
|
+
context.budget.files += 1;
|
|
443
|
+
const root = await parsePlistRecord((0, import_node_path.join)(context.bundlePath, fileName));
|
|
444
|
+
if (!root || !Array.isArray(root.PreferenceSpecifiers)) {
|
|
445
|
+
context.fileCache.set(fileName, null);
|
|
446
|
+
return null;
|
|
447
|
+
}
|
|
448
|
+
const stack = new Set(context.stack);
|
|
449
|
+
stack.add(fileName);
|
|
450
|
+
const specifiers = [];
|
|
451
|
+
for (const raw of root.PreferenceSpecifiers) {
|
|
452
|
+
if (context.budget.specifiers >= MAX_SPECIFIERS) break;
|
|
453
|
+
const specifier = await normalizeSpecifier(raw, { ...context, stack });
|
|
454
|
+
if (specifier) specifiers.push(specifier);
|
|
455
|
+
}
|
|
456
|
+
context.fileCache.set(fileName, specifiers);
|
|
457
|
+
return specifiers;
|
|
458
|
+
}
|
|
459
|
+
async function readAppSettingsBundle(projectRoot) {
|
|
460
|
+
const bundlePath = await findSettingsBundle(projectRoot);
|
|
461
|
+
if (!bundlePath) return null;
|
|
462
|
+
const fingerprint = await settingsBundleFingerprint(bundlePath);
|
|
463
|
+
if (!fingerprint) return null;
|
|
464
|
+
const cached3 = settingsBundleCache.get(bundlePath);
|
|
465
|
+
if (cached3?.fingerprint === fingerprint) return cached3.specifiers;
|
|
466
|
+
const specifiers = await parseSpecifierFile("Root.plist", {
|
|
467
|
+
bundlePath,
|
|
468
|
+
depth: 0,
|
|
469
|
+
budget: { files: 0, specifiers: 0 },
|
|
470
|
+
stack: /* @__PURE__ */ new Set(),
|
|
471
|
+
fileCache: /* @__PURE__ */ new Map()
|
|
472
|
+
});
|
|
473
|
+
const normalized = specifiers && specifiers.length > 0 ? specifiers : null;
|
|
474
|
+
settingsBundleCache.set(bundlePath, { fingerprint, specifiers: normalized });
|
|
475
|
+
return normalized;
|
|
476
|
+
}
|
|
477
|
+
|
|
145
478
|
// scripts/dev-server-scanner.ts
|
|
146
479
|
init_optional_demo_registry();
|
|
147
480
|
var execP = (0, import_util.promisify)(import_child_process.exec);
|
|
@@ -508,6 +841,16 @@ function __shouldReuseScannerCacheEntry(entry, pid, now = Date.now()) {
|
|
|
508
841
|
if (isWeakCachedResult(entry.result) && ageMs >= WEAK_RESULT_CACHE_TTL_MS) return false;
|
|
509
842
|
return true;
|
|
510
843
|
}
|
|
844
|
+
async function attachAppSettingsBundle(result, projectRoot) {
|
|
845
|
+
const settingsBundle = await readAppSettingsBundle(projectRoot);
|
|
846
|
+
if (settingsBundle) {
|
|
847
|
+
result.settingsBundle = settingsBundle;
|
|
848
|
+
result.settingsStorageScopeUrl = result.bundleUrl;
|
|
849
|
+
} else {
|
|
850
|
+
delete result.settingsBundle;
|
|
851
|
+
delete result.settingsStorageScopeUrl;
|
|
852
|
+
}
|
|
853
|
+
}
|
|
511
854
|
async function scanDevServers(opts = {}) {
|
|
512
855
|
await loadOptionalDemoApps();
|
|
513
856
|
const processes = await discoverListeningProcesses(opts.excludePorts);
|
|
@@ -563,7 +906,9 @@ async function scanDevServers(opts = {}) {
|
|
|
563
906
|
if (!pid) return;
|
|
564
907
|
result.pid = pid;
|
|
565
908
|
const cwd = await resolveProcessCwd(pid);
|
|
566
|
-
if (cwd)
|
|
909
|
+
if (!cwd) return;
|
|
910
|
+
result.cwd = cwd;
|
|
911
|
+
await attachAppSettingsBundle(result, cwd);
|
|
567
912
|
})
|
|
568
913
|
);
|
|
569
914
|
const livePids = new Set(pidByPort.values());
|
|
@@ -606,7 +951,7 @@ function getCliVersion() {
|
|
|
606
951
|
// src/home-paths.ts
|
|
607
952
|
var import_node_fs2 = __toESM(require("node:fs"), 1);
|
|
608
953
|
var import_node_os = require("node:os");
|
|
609
|
-
var
|
|
954
|
+
var import_node_path2 = __toESM(require("node:path"), 1);
|
|
610
955
|
var SOOTSIM_HOME_ENV = "SOOTSIM_HOME";
|
|
611
956
|
var ACTIVE_RUNTIME_FILE = "active";
|
|
612
957
|
var DAEMON_LOCKFILE = "daemon.json";
|
|
@@ -615,8 +960,8 @@ var CONFIG_FILE = "config.json";
|
|
|
615
960
|
var DAEMON_HEARTBEAT_STALE_MS = 3e4;
|
|
616
961
|
function sootsimHomeDir() {
|
|
617
962
|
const override = process.env[SOOTSIM_HOME_ENV];
|
|
618
|
-
if (override && override.length > 0) return
|
|
619
|
-
return
|
|
963
|
+
if (override && override.length > 0) return import_node_path2.default.resolve(override);
|
|
964
|
+
return import_node_path2.default.join((0, import_node_os.homedir)(), ".sootsim");
|
|
620
965
|
}
|
|
621
966
|
function isSootsimDevCheckout() {
|
|
622
967
|
if (process.env.SOOTSIM_FORCE_DAEMON_INSTALL === "1") return false;
|
|
@@ -627,40 +972,40 @@ function isSootsimDevCheckout() {
|
|
|
627
972
|
if (!argv1) return false;
|
|
628
973
|
try {
|
|
629
974
|
const real = import_node_fs2.default.realpathSync(argv1);
|
|
630
|
-
return real.includes(`${
|
|
975
|
+
return real.includes(`${import_node_path2.default.sep}packages${import_node_path2.default.sep}sootsim${import_node_path2.default.sep}`);
|
|
631
976
|
} catch {
|
|
632
977
|
return false;
|
|
633
978
|
}
|
|
634
979
|
}
|
|
635
980
|
function runtimesDir() {
|
|
636
|
-
return
|
|
981
|
+
return import_node_path2.default.join(sootsimHomeDir(), "runtimes");
|
|
637
982
|
}
|
|
638
983
|
function runtimeDir(version) {
|
|
639
|
-
return
|
|
984
|
+
return import_node_path2.default.join(runtimesDir(), version);
|
|
640
985
|
}
|
|
641
986
|
function activeRuntimeFile() {
|
|
642
|
-
return
|
|
987
|
+
return import_node_path2.default.join(runtimesDir(), ACTIVE_RUNTIME_FILE);
|
|
643
988
|
}
|
|
644
989
|
function electronDir() {
|
|
645
|
-
return
|
|
990
|
+
return import_node_path2.default.join(sootsimHomeDir(), "electron");
|
|
646
991
|
}
|
|
647
992
|
function electronUserDataDir() {
|
|
648
|
-
return
|
|
993
|
+
return import_node_path2.default.join(electronDir(), "userData");
|
|
649
994
|
}
|
|
650
995
|
function profilesDir() {
|
|
651
|
-
return
|
|
996
|
+
return import_node_path2.default.join(sootsimHomeDir(), "profiles");
|
|
652
997
|
}
|
|
653
998
|
function cacheDir() {
|
|
654
|
-
return
|
|
999
|
+
return import_node_path2.default.join(sootsimHomeDir(), "cache");
|
|
655
1000
|
}
|
|
656
1001
|
function daemonLockfilePath() {
|
|
657
|
-
return
|
|
1002
|
+
return import_node_path2.default.join(sootsimHomeDir(), DAEMON_LOCKFILE);
|
|
658
1003
|
}
|
|
659
1004
|
function devBridgeLockfilePath() {
|
|
660
|
-
return
|
|
1005
|
+
return import_node_path2.default.join(sootsimHomeDir(), DEV_BRIDGE_LOCKFILE);
|
|
661
1006
|
}
|
|
662
1007
|
function configFilePath() {
|
|
663
|
-
return
|
|
1008
|
+
return import_node_path2.default.join(sootsimHomeDir(), CONFIG_FILE);
|
|
664
1009
|
}
|
|
665
1010
|
function readSharedConfig() {
|
|
666
1011
|
try {
|
|
@@ -688,7 +1033,7 @@ function writeSharedConfig(patch) {
|
|
|
688
1033
|
return next;
|
|
689
1034
|
}
|
|
690
1035
|
function runtimeUpgradeNoticePath() {
|
|
691
|
-
return
|
|
1036
|
+
return import_node_path2.default.join(sootsimHomeDir(), "runtime-upgraded.json");
|
|
692
1037
|
}
|
|
693
1038
|
function writeRuntimeUpgradeNotice(notice) {
|
|
694
1039
|
ensureSootsimHome();
|
|
@@ -826,13 +1171,13 @@ function resolveDevCheckoutRuntimeRoot() {
|
|
|
826
1171
|
var import_node_child_process = require("node:child_process");
|
|
827
1172
|
var import_node_crypto = __toESM(require("node:crypto"), 1);
|
|
828
1173
|
var import_node_fs4 = __toESM(require("node:fs"), 1);
|
|
829
|
-
var
|
|
1174
|
+
var import_node_path4 = __toESM(require("node:path"), 1);
|
|
830
1175
|
var import_node_stream = require("node:stream");
|
|
831
|
-
var
|
|
1176
|
+
var import_promises2 = require("node:stream/promises");
|
|
832
1177
|
|
|
833
1178
|
// ../contrast-runtime-delivery/src/product.ts
|
|
834
1179
|
var import_node_fs3 = __toESM(require("node:fs"), 1);
|
|
835
|
-
var
|
|
1180
|
+
var import_node_path3 = __toESM(require("node:path"), 1);
|
|
836
1181
|
function listInstalledRuntimes(product) {
|
|
837
1182
|
try {
|
|
838
1183
|
return import_node_fs3.default.readdirSync(product.runtimesDir(), { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name).sort(compareSemver);
|
|
@@ -841,7 +1186,7 @@ function listInstalledRuntimes(product) {
|
|
|
841
1186
|
}
|
|
842
1187
|
}
|
|
843
1188
|
function runtimeTarballCacheName(product, version) {
|
|
844
|
-
return
|
|
1189
|
+
return import_node_path3.default.posix.basename(product.tarballPath(version));
|
|
845
1190
|
}
|
|
846
1191
|
function compareSemver(a, b) {
|
|
847
1192
|
const parse = (v) => {
|
|
@@ -933,7 +1278,7 @@ function createRuntimeDelivery(product) {
|
|
|
933
1278
|
const destDir = product.runtimeDir(version);
|
|
934
1279
|
const setActive = opts.setActive !== false;
|
|
935
1280
|
pruneLocalRetention({ protectVersions: [version] });
|
|
936
|
-
if (!opts.force && import_node_fs4.default.existsSync(
|
|
1281
|
+
if (!opts.force && import_node_fs4.default.existsSync(import_node_path4.default.join(destDir, product.installedMarker))) {
|
|
937
1282
|
if (setActive) product.writeActiveRuntime(version);
|
|
938
1283
|
pruneLocalRetention({ protectVersions: [version] });
|
|
939
1284
|
return {
|
|
@@ -947,7 +1292,7 @@ function createRuntimeDelivery(product) {
|
|
|
947
1292
|
};
|
|
948
1293
|
}
|
|
949
1294
|
const tarUrl = entry.tarball || tarballUrl(version, cdnOrigin);
|
|
950
|
-
const tarCachePath =
|
|
1295
|
+
const tarCachePath = import_node_path4.default.join(
|
|
951
1296
|
product.cacheDir(),
|
|
952
1297
|
runtimeTarballCacheName(product, version)
|
|
953
1298
|
);
|
|
@@ -956,8 +1301,8 @@ function createRuntimeDelivery(product) {
|
|
|
956
1301
|
await downloadToFile(tarUrl, tarCachePath);
|
|
957
1302
|
process.stderr.write(`${product.id}: extracting runtime ${version}\u2026
|
|
958
1303
|
`);
|
|
959
|
-
const tmpDir =
|
|
960
|
-
|
|
1304
|
+
const tmpDir = import_node_path4.default.join(
|
|
1305
|
+
import_node_path4.default.dirname(destDir),
|
|
961
1306
|
`.installing-${version}-${process.pid}`
|
|
962
1307
|
);
|
|
963
1308
|
import_node_fs4.default.rmSync(tmpDir, { recursive: true, force: true });
|
|
@@ -970,7 +1315,7 @@ function createRuntimeDelivery(product) {
|
|
|
970
1315
|
}
|
|
971
1316
|
import_node_fs4.default.mkdirSync(tmpDir, { recursive: true });
|
|
972
1317
|
await extractTarball(tarCachePath, tmpDir);
|
|
973
|
-
if (!import_node_fs4.default.existsSync(
|
|
1318
|
+
if (!import_node_fs4.default.existsSync(import_node_path4.default.join(tmpDir, product.installedMarker))) {
|
|
974
1319
|
throw new Error(
|
|
975
1320
|
`extracted tarball for runtime ${version} is missing ${product.installedMarker}`
|
|
976
1321
|
);
|
|
@@ -1004,7 +1349,7 @@ function createRuntimeDelivery(product) {
|
|
|
1004
1349
|
if (pin) {
|
|
1005
1350
|
const activeVersion2 = product.readActiveRuntime();
|
|
1006
1351
|
const pinInstalled = import_node_fs4.default.existsSync(
|
|
1007
|
-
|
|
1352
|
+
import_node_path4.default.join(product.runtimeDir(pin), product.installedMarker)
|
|
1008
1353
|
);
|
|
1009
1354
|
if (activeVersion2 === pin && pinInstalled) {
|
|
1010
1355
|
return {
|
|
@@ -1052,7 +1397,7 @@ function createRuntimeDelivery(product) {
|
|
|
1052
1397
|
}
|
|
1053
1398
|
const activeVersion = product.readActiveRuntime();
|
|
1054
1399
|
const activeDir = activeVersion ? product.runtimeDir(activeVersion) : null;
|
|
1055
|
-
const activeInstalled = activeDir ? import_node_fs4.default.existsSync(
|
|
1400
|
+
const activeInstalled = activeDir ? import_node_fs4.default.existsSync(import_node_path4.default.join(activeDir, product.installedMarker)) : false;
|
|
1056
1401
|
const shouldInstall = !activeVersion || !activeInstalled || compareSemver(latestVersion, activeVersion) > 0;
|
|
1057
1402
|
if (!shouldInstall) {
|
|
1058
1403
|
return {
|
|
@@ -1128,7 +1473,7 @@ function createRuntimeDelivery(product) {
|
|
|
1128
1473
|
const complete = entry.name.startsWith(cachePrefix) && entry.name.endsWith(cacheSuffix);
|
|
1129
1474
|
const partial = entry.name.startsWith(cachePrefix) && entry.name.endsWith(`${cacheSuffix}.partial`);
|
|
1130
1475
|
return complete || partial;
|
|
1131
|
-
}).map((entry) =>
|
|
1476
|
+
}).map((entry) => import_node_path4.default.join(product.cacheDir(), entry.name)).sort();
|
|
1132
1477
|
} catch {
|
|
1133
1478
|
}
|
|
1134
1479
|
}
|
|
@@ -1172,10 +1517,10 @@ async function downloadToFile(url, destPath) {
|
|
|
1172
1517
|
if (!res.ok || !res.body) {
|
|
1173
1518
|
throw new Error(`download failed: ${res.status} ${res.statusText} (${url})`);
|
|
1174
1519
|
}
|
|
1175
|
-
import_node_fs4.default.mkdirSync(
|
|
1520
|
+
import_node_fs4.default.mkdirSync(import_node_path4.default.dirname(destPath), { recursive: true });
|
|
1176
1521
|
const tmp = `${destPath}.partial`;
|
|
1177
1522
|
try {
|
|
1178
|
-
await (0,
|
|
1523
|
+
await (0, import_promises2.pipeline)(
|
|
1179
1524
|
import_node_stream.Readable.fromWeb(res.body),
|
|
1180
1525
|
import_node_fs4.default.createWriteStream(tmp)
|
|
1181
1526
|
);
|
|
@@ -1238,13 +1583,13 @@ var sootsimRuntime = createRuntimeDelivery(SOOTSIM_RUNTIME_PRODUCT);
|
|
|
1238
1583
|
|
|
1239
1584
|
// src/host/agent-host.ts
|
|
1240
1585
|
var import_node_fs7 = __toESM(require("node:fs"), 1);
|
|
1241
|
-
var
|
|
1586
|
+
var import_node_path7 = __toESM(require("node:path"), 1);
|
|
1242
1587
|
|
|
1243
1588
|
// src/agent-sessions.ts
|
|
1244
1589
|
var import_node_child_process2 = require("node:child_process");
|
|
1245
1590
|
var import_node_crypto3 = require("node:crypto");
|
|
1246
1591
|
var import_node_fs6 = __toESM(require("node:fs"), 1);
|
|
1247
|
-
var
|
|
1592
|
+
var import_node_path6 = __toESM(require("node:path"), 1);
|
|
1248
1593
|
var import_node_readline = __toESM(require("node:readline"), 1);
|
|
1249
1594
|
|
|
1250
1595
|
// src/agent-events.ts
|
|
@@ -1289,7 +1634,7 @@ function encodeAgentPromptEnvelope(input) {
|
|
|
1289
1634
|
// src/attached-projects.ts
|
|
1290
1635
|
var import_node_crypto2 = require("node:crypto");
|
|
1291
1636
|
var import_node_fs5 = __toESM(require("node:fs"), 1);
|
|
1292
|
-
var
|
|
1637
|
+
var import_node_path5 = __toESM(require("node:path"), 1);
|
|
1293
1638
|
var overrideDir = null;
|
|
1294
1639
|
function userDataDir() {
|
|
1295
1640
|
if (overrideDir) return overrideDir;
|
|
@@ -1301,7 +1646,7 @@ function getUserDataDir() {
|
|
|
1301
1646
|
return userDataDir();
|
|
1302
1647
|
}
|
|
1303
1648
|
function storeFile() {
|
|
1304
|
-
return
|
|
1649
|
+
return import_node_path5.default.join(userDataDir(), "attached-projects.json");
|
|
1305
1650
|
}
|
|
1306
1651
|
function cloneEmpty() {
|
|
1307
1652
|
return {
|
|
@@ -1343,7 +1688,7 @@ function loadStore() {
|
|
|
1343
1688
|
}
|
|
1344
1689
|
function writeStore(store) {
|
|
1345
1690
|
const file = storeFile();
|
|
1346
|
-
import_node_fs5.default.mkdirSync(
|
|
1691
|
+
import_node_fs5.default.mkdirSync(import_node_path5.default.dirname(file), { recursive: true });
|
|
1347
1692
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
1348
1693
|
const fd = import_node_fs5.default.openSync(tmp, "w", 384);
|
|
1349
1694
|
try {
|
|
@@ -1361,13 +1706,13 @@ function mutateStore(fn) {
|
|
|
1361
1706
|
return store;
|
|
1362
1707
|
}
|
|
1363
1708
|
function projectIdForCwd(cwd) {
|
|
1364
|
-
return (0, import_node_crypto2.createHash)("sha256").update(
|
|
1709
|
+
return (0, import_node_crypto2.createHash)("sha256").update(import_node_path5.default.resolve(cwd)).digest("hex").slice(0, 16);
|
|
1365
1710
|
}
|
|
1366
1711
|
function newSessionId() {
|
|
1367
1712
|
return `s_${(0, import_node_crypto2.randomBytes)(10).toString("hex")}`;
|
|
1368
1713
|
}
|
|
1369
1714
|
function upsertProject(input) {
|
|
1370
|
-
const cwd =
|
|
1715
|
+
const cwd = import_node_path5.default.resolve(input.cwd);
|
|
1371
1716
|
const id = projectIdForCwd(cwd);
|
|
1372
1717
|
let result;
|
|
1373
1718
|
mutateStore((store) => {
|
|
@@ -1393,7 +1738,7 @@ function upsertProject(input) {
|
|
|
1393
1738
|
const now = Date.now();
|
|
1394
1739
|
const created = {
|
|
1395
1740
|
id,
|
|
1396
|
-
name: input.name ??
|
|
1741
|
+
name: input.name ?? import_node_path5.default.basename(cwd),
|
|
1397
1742
|
cwd,
|
|
1398
1743
|
repoRoot: input.repoRoot,
|
|
1399
1744
|
sourceRoots: input.sourceRoots ?? [cwd],
|
|
@@ -1540,7 +1885,7 @@ async function seedFromDemoAppRegistry() {
|
|
|
1540
1885
|
mutateStore((store) => {
|
|
1541
1886
|
for (const app of apps) {
|
|
1542
1887
|
if (!import_node_fs5.default.existsSync(app.dir)) continue;
|
|
1543
|
-
const cwd =
|
|
1888
|
+
const cwd = import_node_path5.default.resolve(app.dir);
|
|
1544
1889
|
const id = projectIdForCwd(cwd);
|
|
1545
1890
|
if (store.attachedProjects.some((p) => p.id === id)) continue;
|
|
1546
1891
|
const now = Date.now();
|
|
@@ -1564,16 +1909,16 @@ async function seedFromDemoAppRegistry() {
|
|
|
1564
1909
|
|
|
1565
1910
|
// src/agent-sessions.ts
|
|
1566
1911
|
function sessionDir(sessionId) {
|
|
1567
|
-
return
|
|
1912
|
+
return import_node_path6.default.join(getUserDataDir(), "sessions", sessionId);
|
|
1568
1913
|
}
|
|
1569
1914
|
function promptFifoPath(sessionId) {
|
|
1570
|
-
return
|
|
1915
|
+
return import_node_path6.default.join(sessionDir(sessionId), "prompt.in");
|
|
1571
1916
|
}
|
|
1572
1917
|
function eventsFifoPath(sessionId) {
|
|
1573
|
-
return
|
|
1918
|
+
return import_node_path6.default.join(sessionDir(sessionId), "events.out");
|
|
1574
1919
|
}
|
|
1575
1920
|
function transcriptPath(sessionId) {
|
|
1576
|
-
return
|
|
1921
|
+
return import_node_path6.default.join(getUserDataDir(), "transcripts", `${sessionId}.log`);
|
|
1577
1922
|
}
|
|
1578
1923
|
function pidIsAlive(pid, sessionId) {
|
|
1579
1924
|
if (!pid) return false;
|
|
@@ -1595,8 +1940,8 @@ function resolveSootsimInvocation() {
|
|
|
1595
1940
|
const resourcesPath = process.resourcesPath;
|
|
1596
1941
|
if (resourcesPath) {
|
|
1597
1942
|
const candidates = [
|
|
1598
|
-
|
|
1599
|
-
|
|
1943
|
+
import_node_path6.default.join(resourcesPath, "bin", "sootsim"),
|
|
1944
|
+
import_node_path6.default.join(resourcesPath, "bin", `sootsim-${process.platform}-${process.arch}`)
|
|
1600
1945
|
];
|
|
1601
1946
|
for (const c of candidates) {
|
|
1602
1947
|
if (import_node_fs6.default.existsSync(c)) return { cmd: c, prefixArgs: [] };
|
|
@@ -1622,12 +1967,12 @@ function tryWorkspaceSootsim() {
|
|
|
1622
1967
|
const sootsimDir = resolveSootsimPackageDir();
|
|
1623
1968
|
if (!sootsimDir) return null;
|
|
1624
1969
|
const binaryName = `sootsim-${process.platform}-${process.arch}`;
|
|
1625
|
-
const distBinary =
|
|
1970
|
+
const distBinary = import_node_path6.default.join(sootsimDir, "dist-bin", binaryName);
|
|
1626
1971
|
if (import_node_fs6.default.existsSync(distBinary)) return { cmd: distBinary, prefixArgs: [] };
|
|
1627
|
-
const distBin =
|
|
1972
|
+
const distBin = import_node_path6.default.join(sootsimDir, "dist-cli", "bin.js");
|
|
1628
1973
|
if (import_node_fs6.default.existsSync(distBin)) {
|
|
1629
1974
|
try {
|
|
1630
|
-
const src =
|
|
1975
|
+
const src = import_node_path6.default.join(sootsimDir, "cli", "commands", "agent-wrapper.ts");
|
|
1631
1976
|
if (import_node_fs6.default.existsSync(src)) {
|
|
1632
1977
|
const srcMtime = import_node_fs6.default.statSync(src).mtimeMs;
|
|
1633
1978
|
const buildMtime = import_node_fs6.default.statSync(distBin).mtimeMs;
|
|
@@ -1649,14 +1994,14 @@ function tryWorkspaceSootsim() {
|
|
|
1649
1994
|
function resolveSootsimPackageDir() {
|
|
1650
1995
|
try {
|
|
1651
1996
|
const resolved = require.resolve("sootsim/package.json");
|
|
1652
|
-
return
|
|
1997
|
+
return import_node_path6.default.dirname(resolved);
|
|
1653
1998
|
} catch {
|
|
1654
1999
|
}
|
|
1655
2000
|
const here = fileFromImportMeta();
|
|
1656
2001
|
if (!here) return null;
|
|
1657
|
-
let cur =
|
|
2002
|
+
let cur = import_node_path6.default.dirname(here);
|
|
1658
2003
|
for (let i = 0; i < 8; i++) {
|
|
1659
|
-
const pkg =
|
|
2004
|
+
const pkg = import_node_path6.default.join(cur, "package.json");
|
|
1660
2005
|
try {
|
|
1661
2006
|
if (import_node_fs6.default.existsSync(pkg)) {
|
|
1662
2007
|
const parsed = JSON.parse(import_node_fs6.default.readFileSync(pkg, "utf8"));
|
|
@@ -1664,7 +2009,7 @@ function resolveSootsimPackageDir() {
|
|
|
1664
2009
|
}
|
|
1665
2010
|
} catch {
|
|
1666
2011
|
}
|
|
1667
|
-
const parent =
|
|
2012
|
+
const parent = import_node_path6.default.dirname(cur);
|
|
1668
2013
|
if (parent === cur) break;
|
|
1669
2014
|
cur = parent;
|
|
1670
2015
|
}
|
|
@@ -1680,13 +2025,13 @@ function fileFromImportMeta() {
|
|
|
1680
2025
|
}
|
|
1681
2026
|
}
|
|
1682
2027
|
async function withStartLock(projectId, provider, fn) {
|
|
1683
|
-
const lockDir =
|
|
2028
|
+
const lockDir = import_node_path6.default.join(getUserDataDir(), "locks");
|
|
1684
2029
|
import_node_fs6.default.mkdirSync(lockDir, { recursive: true });
|
|
1685
2030
|
try {
|
|
1686
2031
|
import_node_fs6.default.chmodSync(lockDir, 448);
|
|
1687
2032
|
} catch {
|
|
1688
2033
|
}
|
|
1689
|
-
const lockPath =
|
|
2034
|
+
const lockPath = import_node_path6.default.join(lockDir, `start-${projectId}-${provider}.lock`);
|
|
1690
2035
|
const deadline = Date.now() + 4e3;
|
|
1691
2036
|
let fd = null;
|
|
1692
2037
|
while (fd === null) {
|
|
@@ -1737,7 +2082,7 @@ function isProcessAlive(pid) {
|
|
|
1737
2082
|
}
|
|
1738
2083
|
}
|
|
1739
2084
|
function mkfifoSync(p) {
|
|
1740
|
-
const parent =
|
|
2085
|
+
const parent = import_node_path6.default.dirname(p);
|
|
1741
2086
|
import_node_fs6.default.mkdirSync(parent, { recursive: true });
|
|
1742
2087
|
try {
|
|
1743
2088
|
import_node_fs6.default.chmodSync(parent, 448);
|
|
@@ -1745,8 +2090,8 @@ function mkfifoSync(p) {
|
|
|
1745
2090
|
}
|
|
1746
2091
|
if (import_node_fs6.default.existsSync(p)) {
|
|
1747
2092
|
try {
|
|
1748
|
-
const
|
|
1749
|
-
if (
|
|
2093
|
+
const stat2 = import_node_fs6.default.statSync(p);
|
|
2094
|
+
if (stat2.isFIFO()) {
|
|
1750
2095
|
try {
|
|
1751
2096
|
import_node_fs6.default.chmodSync(p, 384);
|
|
1752
2097
|
} catch {
|
|
@@ -1802,7 +2147,7 @@ async function startSession(opts) {
|
|
|
1802
2147
|
const transcript = transcriptPath(session.id);
|
|
1803
2148
|
mkfifoSync(promptIn);
|
|
1804
2149
|
mkfifoSync(eventsOut);
|
|
1805
|
-
const transcriptDir =
|
|
2150
|
+
const transcriptDir = import_node_path6.default.dirname(transcript);
|
|
1806
2151
|
import_node_fs6.default.mkdirSync(transcriptDir, { recursive: true });
|
|
1807
2152
|
try {
|
|
1808
2153
|
import_node_fs6.default.chmodSync(transcriptDir, 448);
|
|
@@ -2260,7 +2605,7 @@ var AgentHost = class {
|
|
|
2260
2605
|
);
|
|
2261
2606
|
const project = upsertProject({
|
|
2262
2607
|
cwd: match.cwd,
|
|
2263
|
-
name: match.projectName ??
|
|
2608
|
+
name: match.projectName ?? import_node_path7.default.basename(match.cwd),
|
|
2264
2609
|
preferredProvider: input.provider ?? existing?.preferredProvider,
|
|
2265
2610
|
sourceRoots: existing?.sourceRoots ?? [match.cwd],
|
|
2266
2611
|
knownBundleUrls,
|
|
@@ -2280,9 +2625,9 @@ var AgentHost = class {
|
|
|
2280
2625
|
const dir = getUserDataDir();
|
|
2281
2626
|
return {
|
|
2282
2627
|
userDataDir: dir,
|
|
2283
|
-
storeFile:
|
|
2284
|
-
sessionsDir:
|
|
2285
|
-
transcriptsDir:
|
|
2628
|
+
storeFile: import_node_path7.default.join(dir, "attached-projects.json"),
|
|
2629
|
+
sessionsDir: import_node_path7.default.join(dir, "sessions"),
|
|
2630
|
+
transcriptsDir: import_node_path7.default.join(dir, "transcripts")
|
|
2286
2631
|
};
|
|
2287
2632
|
}
|
|
2288
2633
|
// --- subscription management ---
|
|
@@ -2580,7 +2925,7 @@ function mapFrameworkToProjectFramework(fw) {
|
|
|
2580
2925
|
// src/host/fetch-proxy-handler.ts
|
|
2581
2926
|
var import_http2 = __toESM(require("http"), 1);
|
|
2582
2927
|
var import_https = __toESM(require("https"), 1);
|
|
2583
|
-
var
|
|
2928
|
+
var import_promises3 = require("stream/promises");
|
|
2584
2929
|
|
|
2585
2930
|
// src/backend-origin.ts
|
|
2586
2931
|
function normalizeHostname(hostname) {
|
|
@@ -2792,7 +3137,7 @@ async function handleFetchProxyRequest(req, res) {
|
|
|
2792
3137
|
const switchToGet = (status === 301 || status === 302) && method === "POST" || status === 303 && method !== "GET" && method !== "HEAD";
|
|
2793
3138
|
const redirectUrl = new URL(location, targetUrl2);
|
|
2794
3139
|
proxyRes.resume();
|
|
2795
|
-
await (0,
|
|
3140
|
+
await (0, import_promises3.finished)(proxyRes);
|
|
2796
3141
|
await proxy(
|
|
2797
3142
|
redirectUrl,
|
|
2798
3143
|
switchToGet ? "GET" : method,
|
|
@@ -2817,7 +3162,7 @@ async function handleFetchProxyRequest(req, res) {
|
|
|
2817
3162
|
);
|
|
2818
3163
|
}
|
|
2819
3164
|
res.statusCode = status;
|
|
2820
|
-
await (0,
|
|
3165
|
+
await (0, import_promises3.pipeline)(proxyRes, res);
|
|
2821
3166
|
};
|
|
2822
3167
|
try {
|
|
2823
3168
|
await proxy(upstreamUrl, originalMethod, body, 0);
|