@swmansion/argent 0.18.0 → 0.18.1-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/argent-android-devtools-0.1.0.apk +0 -0
- package/bin/darwin/ax-service +0 -0
- package/bin/darwin/tvos-ax-service +0 -0
- package/bin/darwin/tvos-hid-daemon +0 -0
- package/bin/tcp/ax-service +0 -0
- package/dist/cli-cmds.mjs +145 -82
- package/dist/installer.mjs +300 -293
- package/dist/mcp-server.mjs +259 -48
- package/dist/tool-server.cjs +6 -3
- package/dylibs/libArgentInjectionBootstrap.dylib +0 -0
- package/dylibs/libKeyboardPatch.dylib +0 -0
- package/dylibs/libNativeDevtoolsIos.dylib +0 -0
- package/dylibs/tcp/libArgentInjectionBootstrap.dylib +0 -0
- package/dylibs/tcp/libKeyboardPatch.dylib +0 -0
- package/dylibs/tcp/libNativeDevtoolsIos.dylib +0 -0
- package/dylibs/tvos/libArgentInjectionBootstrap.dylib +0 -0
- package/dylibs/tvos/libKeyboardPatch.dylib +0 -0
- package/dylibs/tvos/libNativeDevtoolsIos.dylib +0 -0
- package/package.json +1 -1
- package/skills/argent-screen-recording/SKILL.md +1 -1
package/dist/mcp-server.mjs
CHANGED
|
@@ -2984,7 +2984,7 @@ var require_compile = __commonJS({
|
|
|
2984
2984
|
const schOrFunc = root.refs[ref];
|
|
2985
2985
|
if (schOrFunc)
|
|
2986
2986
|
return schOrFunc;
|
|
2987
|
-
let _sch =
|
|
2987
|
+
let _sch = resolve7.call(this, root, ref);
|
|
2988
2988
|
if (_sch === void 0) {
|
|
2989
2989
|
const schema = (_a3 = root.localRefs) === null || _a3 === void 0 ? void 0 : _a3[ref];
|
|
2990
2990
|
const { schemaId } = this.opts;
|
|
@@ -3011,7 +3011,7 @@ var require_compile = __commonJS({
|
|
|
3011
3011
|
function sameSchemaEnv(s1, s2) {
|
|
3012
3012
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
3013
3013
|
}
|
|
3014
|
-
function
|
|
3014
|
+
function resolve7(root, ref) {
|
|
3015
3015
|
let sch;
|
|
3016
3016
|
while (typeof (sch = this.refs[ref]) == "string")
|
|
3017
3017
|
ref = sch;
|
|
@@ -3229,8 +3229,8 @@ var require_utils = __commonJS({
|
|
|
3229
3229
|
}
|
|
3230
3230
|
return ind;
|
|
3231
3231
|
}
|
|
3232
|
-
function removeDotSegments(
|
|
3233
|
-
let input =
|
|
3232
|
+
function removeDotSegments(path12) {
|
|
3233
|
+
let input = path12;
|
|
3234
3234
|
const output = [];
|
|
3235
3235
|
let nextSlash = -1;
|
|
3236
3236
|
let len = 0;
|
|
@@ -3482,8 +3482,8 @@ var require_schemes = __commonJS({
|
|
|
3482
3482
|
wsComponent.secure = void 0;
|
|
3483
3483
|
}
|
|
3484
3484
|
if (wsComponent.resourceName) {
|
|
3485
|
-
const [
|
|
3486
|
-
wsComponent.path =
|
|
3485
|
+
const [path12, query] = wsComponent.resourceName.split("?");
|
|
3486
|
+
wsComponent.path = path12 && path12 !== "/" ? path12 : void 0;
|
|
3487
3487
|
wsComponent.query = query;
|
|
3488
3488
|
wsComponent.resourceName = void 0;
|
|
3489
3489
|
}
|
|
@@ -3642,7 +3642,7 @@ var require_fast_uri = __commonJS({
|
|
|
3642
3642
|
}
|
|
3643
3643
|
return uri;
|
|
3644
3644
|
}
|
|
3645
|
-
function
|
|
3645
|
+
function resolve7(baseURI, relativeURI, options) {
|
|
3646
3646
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
3647
3647
|
const resolved = resolveComponent(parse3(baseURI, schemelessOptions), parse3(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
3648
3648
|
schemelessOptions.skipEscape = true;
|
|
@@ -3900,7 +3900,7 @@ var require_fast_uri = __commonJS({
|
|
|
3900
3900
|
var fastUri = {
|
|
3901
3901
|
SCHEMES,
|
|
3902
3902
|
normalize: normalize2,
|
|
3903
|
-
resolve:
|
|
3903
|
+
resolve: resolve7,
|
|
3904
3904
|
resolveComponent,
|
|
3905
3905
|
equal,
|
|
3906
3906
|
serialize,
|
|
@@ -7137,10 +7137,10 @@ function mergeDefs(...defs) {
|
|
|
7137
7137
|
function cloneDef(schema) {
|
|
7138
7138
|
return mergeDefs(schema._zod.def);
|
|
7139
7139
|
}
|
|
7140
|
-
function getElementAtPath(obj,
|
|
7141
|
-
if (!
|
|
7140
|
+
function getElementAtPath(obj, path12) {
|
|
7141
|
+
if (!path12)
|
|
7142
7142
|
return obj;
|
|
7143
|
-
return
|
|
7143
|
+
return path12.reduce((acc, key) => acc?.[key], obj);
|
|
7144
7144
|
}
|
|
7145
7145
|
function promiseAllObject(promisesObj) {
|
|
7146
7146
|
const keys = Object.keys(promisesObj);
|
|
@@ -7549,11 +7549,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
7549
7549
|
}
|
|
7550
7550
|
return false;
|
|
7551
7551
|
}
|
|
7552
|
-
function prefixIssues(
|
|
7552
|
+
function prefixIssues(path12, issues) {
|
|
7553
7553
|
return issues.map((iss) => {
|
|
7554
7554
|
var _a3;
|
|
7555
7555
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
7556
|
-
iss.path.unshift(
|
|
7556
|
+
iss.path.unshift(path12);
|
|
7557
7557
|
return iss;
|
|
7558
7558
|
});
|
|
7559
7559
|
}
|
|
@@ -7700,16 +7700,16 @@ function flattenError(error2, mapper = (issue2) => issue2.message) {
|
|
|
7700
7700
|
}
|
|
7701
7701
|
function formatError(error2, mapper = (issue2) => issue2.message) {
|
|
7702
7702
|
const fieldErrors = { _errors: [] };
|
|
7703
|
-
const processError = (error3,
|
|
7703
|
+
const processError = (error3, path12 = []) => {
|
|
7704
7704
|
for (const issue2 of error3.issues) {
|
|
7705
7705
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
7706
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
7706
|
+
issue2.errors.map((issues) => processError({ issues }, [...path12, ...issue2.path]));
|
|
7707
7707
|
} else if (issue2.code === "invalid_key") {
|
|
7708
|
-
processError({ issues: issue2.issues }, [...
|
|
7708
|
+
processError({ issues: issue2.issues }, [...path12, ...issue2.path]);
|
|
7709
7709
|
} else if (issue2.code === "invalid_element") {
|
|
7710
|
-
processError({ issues: issue2.issues }, [...
|
|
7710
|
+
processError({ issues: issue2.issues }, [...path12, ...issue2.path]);
|
|
7711
7711
|
} else {
|
|
7712
|
-
const fullpath = [...
|
|
7712
|
+
const fullpath = [...path12, ...issue2.path];
|
|
7713
7713
|
if (fullpath.length === 0) {
|
|
7714
7714
|
fieldErrors._errors.push(mapper(issue2));
|
|
7715
7715
|
} else {
|
|
@@ -13701,12 +13701,12 @@ var StdioServerTransport = class {
|
|
|
13701
13701
|
this.onclose?.();
|
|
13702
13702
|
}
|
|
13703
13703
|
send(message) {
|
|
13704
|
-
return new Promise((
|
|
13704
|
+
return new Promise((resolve7) => {
|
|
13705
13705
|
const json = serializeMessage(message);
|
|
13706
13706
|
if (this._stdout.write(json)) {
|
|
13707
|
-
|
|
13707
|
+
resolve7();
|
|
13708
13708
|
} else {
|
|
13709
|
-
this._stdout.once("drain",
|
|
13709
|
+
this._stdout.once("drain", resolve7);
|
|
13710
13710
|
}
|
|
13711
13711
|
});
|
|
13712
13712
|
}
|
|
@@ -14304,7 +14304,7 @@ var Protocol = class {
|
|
|
14304
14304
|
return;
|
|
14305
14305
|
}
|
|
14306
14306
|
const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
|
|
14307
|
-
await new Promise((
|
|
14307
|
+
await new Promise((resolve7) => setTimeout(resolve7, pollInterval));
|
|
14308
14308
|
options?.signal?.throwIfAborted();
|
|
14309
14309
|
}
|
|
14310
14310
|
} catch (error2) {
|
|
@@ -14321,7 +14321,7 @@ var Protocol = class {
|
|
|
14321
14321
|
*/
|
|
14322
14322
|
request(request, resultSchema, options) {
|
|
14323
14323
|
const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
|
|
14324
|
-
return new Promise((
|
|
14324
|
+
return new Promise((resolve7, reject) => {
|
|
14325
14325
|
const earlyReject = (error2) => {
|
|
14326
14326
|
reject(error2);
|
|
14327
14327
|
};
|
|
@@ -14399,7 +14399,7 @@ var Protocol = class {
|
|
|
14399
14399
|
if (!parseResult.success) {
|
|
14400
14400
|
reject(parseResult.error);
|
|
14401
14401
|
} else {
|
|
14402
|
-
|
|
14402
|
+
resolve7(parseResult.data);
|
|
14403
14403
|
}
|
|
14404
14404
|
} catch (error2) {
|
|
14405
14405
|
reject(error2);
|
|
@@ -14660,12 +14660,12 @@ var Protocol = class {
|
|
|
14660
14660
|
}
|
|
14661
14661
|
} catch {
|
|
14662
14662
|
}
|
|
14663
|
-
return new Promise((
|
|
14663
|
+
return new Promise((resolve7, reject) => {
|
|
14664
14664
|
if (signal.aborted) {
|
|
14665
14665
|
reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
14666
14666
|
return;
|
|
14667
14667
|
}
|
|
14668
|
-
const timeoutId = setTimeout(
|
|
14668
|
+
const timeoutId = setTimeout(resolve7, interval);
|
|
14669
14669
|
signal.addEventListener("abort", () => {
|
|
14670
14670
|
clearTimeout(timeoutId);
|
|
14671
14671
|
reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
@@ -15490,7 +15490,7 @@ function generateToken() {
|
|
|
15490
15490
|
return randomBytes(AUTH_TOKEN_BYTES).toString("hex");
|
|
15491
15491
|
}
|
|
15492
15492
|
function findFreePort() {
|
|
15493
|
-
return new Promise((
|
|
15493
|
+
return new Promise((resolve7, reject) => {
|
|
15494
15494
|
const srv = net.createServer();
|
|
15495
15495
|
srv.listen(0, "127.0.0.1", () => {
|
|
15496
15496
|
const addr = srv.address();
|
|
@@ -15501,7 +15501,7 @@ function findFreePort() {
|
|
|
15501
15501
|
const port = addr.port;
|
|
15502
15502
|
srv.close((err) => {
|
|
15503
15503
|
if (err) reject(err);
|
|
15504
|
-
else
|
|
15504
|
+
else resolve7(port);
|
|
15505
15505
|
});
|
|
15506
15506
|
});
|
|
15507
15507
|
srv.on("error", reject);
|
|
@@ -15599,7 +15599,7 @@ function killSpawnedChild(child, pid) {
|
|
|
15599
15599
|
}
|
|
15600
15600
|
}
|
|
15601
15601
|
function spawnToolsServer(paths, port, options = {}) {
|
|
15602
|
-
return new Promise((
|
|
15602
|
+
return new Promise((resolve7, reject) => {
|
|
15603
15603
|
let logFd;
|
|
15604
15604
|
try {
|
|
15605
15605
|
fs.mkdirSync(STATE_DIR, { recursive: true });
|
|
@@ -15636,7 +15636,7 @@ function spawnToolsServer(paths, port, options = {}) {
|
|
|
15636
15636
|
rl.close();
|
|
15637
15637
|
child.stdout?.resume();
|
|
15638
15638
|
child.stdout?.unref?.();
|
|
15639
|
-
settle(() =>
|
|
15639
|
+
settle(() => resolve7({ port: actualPort, pid }));
|
|
15640
15640
|
}
|
|
15641
15641
|
});
|
|
15642
15642
|
child.on("error", (err) => {
|
|
@@ -16085,9 +16085,9 @@ async function tarball(sourcePath) {
|
|
|
16085
16085
|
return tarPath;
|
|
16086
16086
|
}
|
|
16087
16087
|
function sha256File(filePath) {
|
|
16088
|
-
return new Promise((
|
|
16088
|
+
return new Promise((resolve7, reject) => {
|
|
16089
16089
|
const hash = createHash2("sha256");
|
|
16090
|
-
createReadStream(filePath).on("data", (chunk) => hash.update(chunk)).on("end", () =>
|
|
16090
|
+
createReadStream(filePath).on("data", (chunk) => hash.update(chunk)).on("end", () => resolve7(hash.digest("hex"))).on("error", reject);
|
|
16091
16091
|
});
|
|
16092
16092
|
}
|
|
16093
16093
|
async function uploadTar(tarPath, endpoint) {
|
|
@@ -16206,7 +16206,7 @@ async function applyClientFileDirectives(result) {
|
|
|
16206
16206
|
import { copyFile, mkdir as mkdir4, readFile as readFile4, realpath, rm as rm3, stat as stat2, writeFile as writeFile4 } from "node:fs/promises";
|
|
16207
16207
|
import { constants as fsConstants } from "node:fs";
|
|
16208
16208
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
16209
|
-
import { basename as basename3, dirname as dirname5, extname, isAbsolute as isAbsolute3, join as join8, normalize, sep as sep2 } from "node:path";
|
|
16209
|
+
import { basename as basename3, dirname as dirname5, extname, isAbsolute as isAbsolute3, join as join8, normalize, resolve as resolve5, sep as sep2 } from "node:path";
|
|
16210
16210
|
import { createHash as createHash3 } from "node:crypto";
|
|
16211
16211
|
|
|
16212
16212
|
// ../configuration-core/src/flags.ts
|
|
@@ -16277,13 +16277,16 @@ function nonEmpty(value) {
|
|
|
16277
16277
|
const trimmed = value.trim();
|
|
16278
16278
|
return trimmed === "" ? null : value;
|
|
16279
16279
|
}
|
|
16280
|
+
function resolveHomeDir(options = {}) {
|
|
16281
|
+
if (options.homeDir) return options.homeDir;
|
|
16282
|
+
return process.platform === "win32" ? nonEmpty(process.env.USERPROFILE) ?? os.homedir() : nonEmpty(process.env.HOME) ?? os.homedir();
|
|
16283
|
+
}
|
|
16280
16284
|
function argentHomeDir() {
|
|
16281
|
-
|
|
16282
|
-
return path5.join(home, ".argent");
|
|
16285
|
+
return path5.join(resolveHomeDir(), ".argent");
|
|
16283
16286
|
}
|
|
16284
16287
|
function configDir(scope = "global", options = {}) {
|
|
16285
16288
|
if (scope === "global") {
|
|
16286
|
-
return
|
|
16289
|
+
return path5.join(resolveHomeDir(options), ".argent");
|
|
16287
16290
|
}
|
|
16288
16291
|
const cwd = options.cwd ?? process.cwd();
|
|
16289
16292
|
return path5.join(resolveProjectRoot(cwd), ".argent");
|
|
@@ -16307,6 +16310,31 @@ function readConfigObject(scope = "global", options = {}) {
|
|
|
16307
16310
|
}
|
|
16308
16311
|
return {};
|
|
16309
16312
|
}
|
|
16313
|
+
var FORBIDDEN_SEGMENTS = /* @__PURE__ */ new Set(["__proto__", "prototype", "constructor"]);
|
|
16314
|
+
function splitKey(dottedKey) {
|
|
16315
|
+
const parts = dottedKey.split(".");
|
|
16316
|
+
if (parts.length === 0 || parts.some((p) => p === "")) {
|
|
16317
|
+
throw new Error(`Invalid config key "${dottedKey}": empty path segment`);
|
|
16318
|
+
}
|
|
16319
|
+
for (const p of parts) {
|
|
16320
|
+
if (FORBIDDEN_SEGMENTS.has(p)) {
|
|
16321
|
+
throw new Error(`Invalid config key "${dottedKey}": forbidden segment "${p}"`);
|
|
16322
|
+
}
|
|
16323
|
+
}
|
|
16324
|
+
return parts;
|
|
16325
|
+
}
|
|
16326
|
+
function isPlainObject3(value) {
|
|
16327
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
16328
|
+
}
|
|
16329
|
+
function getAtPath(obj, dottedKey) {
|
|
16330
|
+
const parts = splitKey(dottedKey);
|
|
16331
|
+
let cur = obj;
|
|
16332
|
+
for (const part of parts) {
|
|
16333
|
+
if (!isPlainObject3(cur)) return void 0;
|
|
16334
|
+
cur = cur[part];
|
|
16335
|
+
}
|
|
16336
|
+
return cur;
|
|
16337
|
+
}
|
|
16310
16338
|
var LOCK_STALE_MS2 = 1e4;
|
|
16311
16339
|
var LOCK_MAX_WAIT_MS = 2e3;
|
|
16312
16340
|
var LOCK_RETRY_MS = 25;
|
|
@@ -16379,6 +16407,163 @@ function updateConfig(mutate, scope = "global", options = {}) {
|
|
|
16379
16407
|
}
|
|
16380
16408
|
}
|
|
16381
16409
|
|
|
16410
|
+
// ../configuration-core/src/merge.ts
|
|
16411
|
+
function mergeRestrictive(local, global2) {
|
|
16412
|
+
if (local === void 0) return global2;
|
|
16413
|
+
if (global2 === void 0) return local;
|
|
16414
|
+
if (typeof local === "boolean" && typeof global2 === "boolean") {
|
|
16415
|
+
return local && global2;
|
|
16416
|
+
}
|
|
16417
|
+
if (typeof local === "number" && typeof global2 === "number") {
|
|
16418
|
+
return Math.min(local, global2);
|
|
16419
|
+
}
|
|
16420
|
+
return local;
|
|
16421
|
+
}
|
|
16422
|
+
function toArray(value) {
|
|
16423
|
+
return Array.isArray(value) ? value : null;
|
|
16424
|
+
}
|
|
16425
|
+
function mergeUnion(local, global2) {
|
|
16426
|
+
const l = toArray(local);
|
|
16427
|
+
const g = toArray(global2);
|
|
16428
|
+
if (l === null && g === null) return local ?? global2;
|
|
16429
|
+
const merged = [...g ?? [], ...l ?? []];
|
|
16430
|
+
return Array.from(new Set(merged));
|
|
16431
|
+
}
|
|
16432
|
+
function mergeIntersection(local, global2) {
|
|
16433
|
+
const l = toArray(local);
|
|
16434
|
+
const g = toArray(global2);
|
|
16435
|
+
if (l === null && g === null) return local ?? global2;
|
|
16436
|
+
if (l === null) return global2;
|
|
16437
|
+
if (g === null) return local;
|
|
16438
|
+
const globalSet = new Set(g);
|
|
16439
|
+
return l.filter((item) => globalSet.has(item));
|
|
16440
|
+
}
|
|
16441
|
+
function applyMergePolicy(policy, local, global2) {
|
|
16442
|
+
if (typeof policy === "function") return policy({ local, global: global2 });
|
|
16443
|
+
switch (policy) {
|
|
16444
|
+
case "prioritize-local":
|
|
16445
|
+
return local ?? global2;
|
|
16446
|
+
case "prioritize-global":
|
|
16447
|
+
return global2 ?? local;
|
|
16448
|
+
case "prioritize-restrictive":
|
|
16449
|
+
return mergeRestrictive(local, global2);
|
|
16450
|
+
case "union":
|
|
16451
|
+
return mergeUnion(local, global2);
|
|
16452
|
+
case "intersection":
|
|
16453
|
+
return mergeIntersection(local, global2);
|
|
16454
|
+
default: {
|
|
16455
|
+
const _exhaustive = policy;
|
|
16456
|
+
return _exhaustive;
|
|
16457
|
+
}
|
|
16458
|
+
}
|
|
16459
|
+
}
|
|
16460
|
+
|
|
16461
|
+
// ../configuration-core/src/config-schema.ts
|
|
16462
|
+
function asBoolean(raw) {
|
|
16463
|
+
return typeof raw === "boolean" ? raw : void 0;
|
|
16464
|
+
}
|
|
16465
|
+
function asString(raw) {
|
|
16466
|
+
if (typeof raw !== "string") return void 0;
|
|
16467
|
+
const trimmed = raw.trim();
|
|
16468
|
+
return trimmed === "" ? void 0 : trimmed;
|
|
16469
|
+
}
|
|
16470
|
+
function asStringArray(raw) {
|
|
16471
|
+
if (!Array.isArray(raw)) return void 0;
|
|
16472
|
+
const out = [];
|
|
16473
|
+
for (const item of raw) {
|
|
16474
|
+
if (typeof item === "string" && item.trim() !== "") out.push(item.trim());
|
|
16475
|
+
}
|
|
16476
|
+
return out;
|
|
16477
|
+
}
|
|
16478
|
+
var CONFIG_SCHEMA = [
|
|
16479
|
+
{
|
|
16480
|
+
key: "telemetry.enabled",
|
|
16481
|
+
description: "Whether anonymous opt-out telemetry is enabled (on by default; environment opt-outs like DO_NOT_TRACK are not reflected here \u2014 `argent telemetry status` shows effective consent).",
|
|
16482
|
+
scopes: ["global"],
|
|
16483
|
+
parse: asBoolean,
|
|
16484
|
+
// A committed project file must never re-enable telemetry a user disabled
|
|
16485
|
+
// globally, so the more-restrictive (opt-out) value always wins.
|
|
16486
|
+
merge: "prioritize-restrictive",
|
|
16487
|
+
// Telemetry is opt-out: with nothing stored, consent.ts treats it as
|
|
16488
|
+
// enabled, and the config surface must report the same instead of "(unset)".
|
|
16489
|
+
default: true,
|
|
16490
|
+
// Read-only under `argent config`: opt-in/out goes through the dedicated
|
|
16491
|
+
// command so the live client is drained/reset, not just the file rewritten.
|
|
16492
|
+
manageCommand: "argent telemetry"
|
|
16493
|
+
},
|
|
16494
|
+
{
|
|
16495
|
+
key: "lens.agent",
|
|
16496
|
+
description: "Coding-agent id remembered by `argent lens` to skip the picker.",
|
|
16497
|
+
scopes: ["project", "global"],
|
|
16498
|
+
parse: asString,
|
|
16499
|
+
// A repo can pin the agent its screenshots should use; falls back to the
|
|
16500
|
+
// user's global remembered choice.
|
|
16501
|
+
merge: "prioritize-local",
|
|
16502
|
+
example: "claude"
|
|
16503
|
+
},
|
|
16504
|
+
{
|
|
16505
|
+
key: "ios.additionalDeviceSets",
|
|
16506
|
+
description: "Additional CoreSimulator device-set directories whose simulators argent should see alongside the default set. Absolute paths (or ~/\u2026); relative entries resolve against the project root (project scope) or home (global scope).",
|
|
16507
|
+
scopes: ["project", "global"],
|
|
16508
|
+
parse: asStringArray,
|
|
16509
|
+
// Additive: the scopes extend each other rather than shadow — a repo's
|
|
16510
|
+
// committed device sets are appended to the user's global ones (global
|
|
16511
|
+
// baseline first, project extras after, deduplicated). Note that
|
|
16512
|
+
// `getAdditionalIosDeviceSets` re-implements this union (path resolution
|
|
16513
|
+
// must precede dedup) and guards on the preset staying "union".
|
|
16514
|
+
merge: "union",
|
|
16515
|
+
example: '["~/DeviceSets/ci"]'
|
|
16516
|
+
},
|
|
16517
|
+
{
|
|
16518
|
+
key: "recordings.directory",
|
|
16519
|
+
description: "Directory where finished screen recordings (mp4) are saved on the client host. Absolute, `~`-prefixed, or relative to the project root (home dir when not in a project). Unset \u21D2 `.argent/recordings` under the project root.",
|
|
16520
|
+
scopes: ["project", "global"],
|
|
16521
|
+
parse: asString,
|
|
16522
|
+
// A repo can pin where its recordings land; falls back to the user's global
|
|
16523
|
+
// preference. Resolution happens on the client (the machine the mp4 is
|
|
16524
|
+
// persisted to), so with a remote `argent link` tool-server it is the
|
|
16525
|
+
// *client's* config that decides.
|
|
16526
|
+
merge: "prioritize-local",
|
|
16527
|
+
example: "~/Movies/argent"
|
|
16528
|
+
}
|
|
16529
|
+
];
|
|
16530
|
+
function getConfigDefinition(key, registry2 = CONFIG_SCHEMA) {
|
|
16531
|
+
return registry2.find((def) => def.key === key);
|
|
16532
|
+
}
|
|
16533
|
+
|
|
16534
|
+
// ../configuration-core/src/config-access.ts
|
|
16535
|
+
import * as path7 from "node:path";
|
|
16536
|
+
function readScopeValue(def, scope, options) {
|
|
16537
|
+
if (!def.scopes.includes(scope)) return void 0;
|
|
16538
|
+
const raw = getAtPath(readConfigObject(scope, options), def.key);
|
|
16539
|
+
return raw === void 0 ? void 0 : def.parse(raw);
|
|
16540
|
+
}
|
|
16541
|
+
function getConfigValue(def, options = {}) {
|
|
16542
|
+
const local = readScopeValue(def, "project", options);
|
|
16543
|
+
const global2 = readScopeValue(def, "global", options);
|
|
16544
|
+
const merged = applyMergePolicy(def.merge, local, global2);
|
|
16545
|
+
return merged ?? def.default;
|
|
16546
|
+
}
|
|
16547
|
+
function getConfigValueByKey(key, options = {}, registry2 = CONFIG_SCHEMA) {
|
|
16548
|
+
const def = requireDefinition(key, registry2);
|
|
16549
|
+
return getConfigValue(def, options);
|
|
16550
|
+
}
|
|
16551
|
+
function requireDefinition(key, registry2 = CONFIG_SCHEMA) {
|
|
16552
|
+
const def = getConfigDefinition(key, registry2);
|
|
16553
|
+
if (!def) {
|
|
16554
|
+
throw new UnknownConfigKeyError(key);
|
|
16555
|
+
}
|
|
16556
|
+
return def;
|
|
16557
|
+
}
|
|
16558
|
+
var UnknownConfigKeyError = class extends Error {
|
|
16559
|
+
constructor(key) {
|
|
16560
|
+
super(`Unknown configuration key "${key}".`);
|
|
16561
|
+
this.key = key;
|
|
16562
|
+
this.name = "UnknownConfigKeyError";
|
|
16563
|
+
}
|
|
16564
|
+
key;
|
|
16565
|
+
};
|
|
16566
|
+
|
|
16382
16567
|
// ../argent-tools-client/src/artifacts.ts
|
|
16383
16568
|
var ARTIFACT_MARKER = "__argentArtifact";
|
|
16384
16569
|
function isArtifactHandle(value) {
|
|
@@ -16414,6 +16599,21 @@ function durableBaseDir() {
|
|
|
16414
16599
|
return projectRoot ?? dirname5(argentHomeDir());
|
|
16415
16600
|
}
|
|
16416
16601
|
var ALLOWED_SAVE_DIRS = /* @__PURE__ */ new Set([normalize(".argent/recordings")]);
|
|
16602
|
+
var RECORDINGS_SAVE_DIR = normalize(".argent/recordings");
|
|
16603
|
+
function configuredRecordingsDir() {
|
|
16604
|
+
let value;
|
|
16605
|
+
try {
|
|
16606
|
+
value = getConfigValueByKey("recordings.directory");
|
|
16607
|
+
} catch {
|
|
16608
|
+
return null;
|
|
16609
|
+
}
|
|
16610
|
+
if (typeof value !== "string") return null;
|
|
16611
|
+
const trimmed = value.trim();
|
|
16612
|
+
if (trimmed === "") return null;
|
|
16613
|
+
const home = dirname5(argentHomeDir());
|
|
16614
|
+
const expanded = trimmed === "~" ? home : trimmed.startsWith("~/") || trimmed.startsWith(`~${sep2}`) ? join8(home, trimmed.slice(2)) : trimmed;
|
|
16615
|
+
return resolve5(durableBaseDir(), expanded);
|
|
16616
|
+
}
|
|
16417
16617
|
var MAX_DURABLE_BYTES = 2 * 1024 * 1024 * 1024;
|
|
16418
16618
|
async function readCapped(res, cap) {
|
|
16419
16619
|
const headers = res.headers;
|
|
@@ -16445,10 +16645,10 @@ async function writeDurableUnique(dir, filename, write) {
|
|
|
16445
16645
|
const stem = filename.slice(0, filename.length - ext.length);
|
|
16446
16646
|
for (let i = 1; i <= 1e3; i++) {
|
|
16447
16647
|
const candidate = i === 1 ? filename : `${stem} (${i})${ext}`;
|
|
16448
|
-
const
|
|
16648
|
+
const path12 = join8(dir, candidate);
|
|
16449
16649
|
try {
|
|
16450
|
-
await write(
|
|
16451
|
-
return
|
|
16650
|
+
await write(path12);
|
|
16651
|
+
return path12;
|
|
16452
16652
|
} catch (err) {
|
|
16453
16653
|
if (err?.code === "EEXIST") continue;
|
|
16454
16654
|
throw err;
|
|
@@ -16463,6 +16663,17 @@ function durableSaveTarget(handle) {
|
|
|
16463
16663
|
return null;
|
|
16464
16664
|
}
|
|
16465
16665
|
if (!ALLOWED_SAVE_DIRS.has(rel)) return null;
|
|
16666
|
+
if (rel === RECORDINGS_SAVE_DIR) {
|
|
16667
|
+
const configured = configuredRecordingsDir();
|
|
16668
|
+
if (configured) {
|
|
16669
|
+
return {
|
|
16670
|
+
dir: configured,
|
|
16671
|
+
path: join8(configured, sanitizeSegment(handle.filename)),
|
|
16672
|
+
base: configured,
|
|
16673
|
+
rel: ""
|
|
16674
|
+
};
|
|
16675
|
+
}
|
|
16676
|
+
}
|
|
16466
16677
|
const base = durableBaseDir();
|
|
16467
16678
|
const dir = join8(base, rel);
|
|
16468
16679
|
return { dir, path: join8(dir, sanitizeSegment(handle.filename)), base, rel };
|
|
@@ -18794,21 +19005,21 @@ var SESSION_ID2 = randomUUID5();
|
|
|
18794
19005
|
// ../telemetry/src/identity.ts
|
|
18795
19006
|
import * as crypto2 from "node:crypto";
|
|
18796
19007
|
import * as fs4 from "node:fs";
|
|
18797
|
-
import * as
|
|
19008
|
+
import * as path9 from "node:path";
|
|
18798
19009
|
|
|
18799
19010
|
// ../telemetry/src/paths.ts
|
|
18800
|
-
import * as
|
|
19011
|
+
import * as path8 from "node:path";
|
|
18801
19012
|
|
|
18802
19013
|
// ../telemetry/src/fingerprint.ts
|
|
18803
19014
|
import { execFileSync as execFileSync2, spawn as spawn2 } from "node:child_process";
|
|
18804
19015
|
|
|
18805
19016
|
// ../native-devtools-ios/src/index.ts
|
|
18806
|
-
import * as
|
|
19017
|
+
import * as path10 from "node:path";
|
|
18807
19018
|
import * as fs5 from "node:fs";
|
|
18808
|
-
var DYLIB_DIR = process.env.ARGENT_NATIVE_DEVTOOLS_DIR ??
|
|
18809
|
-
var BIN_DIR = process.env.ARGENT_SIMULATOR_SERVER_DIR ??
|
|
18810
|
-
var DYLIB_TCP_DIR = process.env.ARGENT_NATIVE_DEVTOOLS_TCP_DIR ??
|
|
18811
|
-
var DYLIB_TVOS_DIR =
|
|
19019
|
+
var DYLIB_DIR = process.env.ARGENT_NATIVE_DEVTOOLS_DIR ?? path10.join(__dirname, "..", "dylibs");
|
|
19020
|
+
var BIN_DIR = process.env.ARGENT_SIMULATOR_SERVER_DIR ?? path10.join(__dirname, "..", "bin");
|
|
19021
|
+
var DYLIB_TCP_DIR = process.env.ARGENT_NATIVE_DEVTOOLS_TCP_DIR ?? path10.join(DYLIB_DIR, "tcp");
|
|
19022
|
+
var DYLIB_TVOS_DIR = path10.join(DYLIB_DIR, "tvos");
|
|
18812
19023
|
|
|
18813
19024
|
// ../telemetry/src/consent.ts
|
|
18814
19025
|
import * as fs6 from "node:fs";
|
|
@@ -19198,10 +19409,10 @@ function toMcpTool(t) {
|
|
|
19198
19409
|
|
|
19199
19410
|
// ../argent-mcp/src/installed-version.ts
|
|
19200
19411
|
import * as fs8 from "node:fs";
|
|
19201
|
-
import * as
|
|
19412
|
+
import * as path11 from "node:path";
|
|
19202
19413
|
function getInstalledVersion() {
|
|
19203
19414
|
try {
|
|
19204
|
-
const pkgPath =
|
|
19415
|
+
const pkgPath = path11.resolve(import.meta.dirname, "..", "package.json");
|
|
19205
19416
|
const pkg = JSON.parse(fs8.readFileSync(pkgPath, "utf8"));
|
|
19206
19417
|
return pkg.version ?? "unknown";
|
|
19207
19418
|
} catch {
|
package/dist/tool-server.cjs
CHANGED
|
@@ -98853,13 +98853,16 @@ function nonEmpty(value) {
|
|
|
98853
98853
|
const trimmed = value.trim();
|
|
98854
98854
|
return trimmed === "" ? null : value;
|
|
98855
98855
|
}
|
|
98856
|
+
function resolveHomeDir(options = {}) {
|
|
98857
|
+
if (options.homeDir) return options.homeDir;
|
|
98858
|
+
return process.platform === "win32" ? nonEmpty(process.env.USERPROFILE) ?? os.homedir() : nonEmpty(process.env.HOME) ?? os.homedir();
|
|
98859
|
+
}
|
|
98856
98860
|
function argentHomeDir() {
|
|
98857
|
-
|
|
98858
|
-
return path2.join(home, ".argent");
|
|
98861
|
+
return path2.join(resolveHomeDir(), ".argent");
|
|
98859
98862
|
}
|
|
98860
98863
|
function configDir(scope = "global", options = {}) {
|
|
98861
98864
|
if (scope === "global") {
|
|
98862
|
-
return
|
|
98865
|
+
return path2.join(resolveHomeDir(options), ".argent");
|
|
98863
98866
|
}
|
|
98864
98867
|
const cwd = options.cwd ?? process.cwd();
|
|
98865
98868
|
return path2.join(resolveProjectRoot(cwd), ".argent");
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -30,7 +30,7 @@ A recording does not stop itself before its `timeLimitSeconds` cap, so a forgott
|
|
|
30
30
|
5. Call `screen-recording-stop` with the same `udid`. It returns `{ video, durationMs, wallClockMs?, trimmedMs?, warning? }`; `video` is an artifact whose resolved path points at the durably-saved file (see below). The video is already final when stop returns (the watermark is stamped during capture, not in a second pass), so stop takes well under a second.
|
|
31
31
|
6. Check `warning`: it reports cap-triggered stops, early encoder exits, a dropped frame stream, and possibly-truncated containers. Verify the file plays (or at least has a sane size) before presenting it to the user.
|
|
32
32
|
|
|
33
|
-
**Where the file lands (durable, not scratch).** Unlike most argent artifacts (which live in a disposable temp cache the OS reclaims), a finished recording is saved durably on the **client** into `<project>/.argent/recordings/` — the project being the nearest ancestor of the client's working directory with a `.git`/`package.json`/`.argent`, or `~/.argent/recordings/` when the client isn't inside a project. This holds even for a remote `argent link` tool-server: the mp4 is written on the client host, not the server. The saved name is `screen-recording-<device>-<timestamp>.mp4`; if that name is already taken the new file lands beside it as `… (2).mp4` rather than overwriting. Because these files persist in the working tree, mention the path to the user (and note that they are untracked — add them to `.gitignore` or clean them up if they shouldn't be committed).
|
|
33
|
+
**Where the file lands (durable, not scratch).** Unlike most argent artifacts (which live in a disposable temp cache the OS reclaims), a finished recording is saved durably on the **client** into `<project>/.argent/recordings/` — the project being the nearest ancestor of the client's working directory with a `.git`/`package.json`/`.argent`, or `~/.argent/recordings/` when the client isn't inside a project. This holds even for a remote `argent link` tool-server: the mp4 is written on the client host, not the server. The destination can be changed with the `recordings.directory` configuration (`argent config set recordings.directory <dir>`, global by default, `--scope project` for a per-repo choice; project wins when both are set) — the value may be absolute, `~`-prefixed, or relative to the project root, and is always resolved on the client host. The saved name is `screen-recording-<device>-<timestamp>.mp4`; if that name is already taken the new file lands beside it as `… (2).mp4` rather than overwriting. Because these files persist in the working tree, mention the path to the user (and note that they are untracked — add them to `.gitignore` or clean them up if they shouldn't be committed).
|
|
34
34
|
|
|
35
35
|
**Static-frame trimming (on by default).** Stretches where the screen does not change are collapsed: the first second of each still stretch is kept so pauses read naturally, then unchanged frames are dropped until something moves again (a change of even a couple of pixels counts). So you can leave a recording running across slow steps, waits, or thinking time without padding the clip with dead air — a 40-second session with 5 seconds of real activity comes back as a ~5-7 second video. When trimming removed anything, stop also returns `wallClockMs` (real elapsed time) and `trimmedMs` (how much was cut); `durationMs` is always the length of the video you actually get. Pass `trimStatic: false` to `screen-recording-start` when you want a faithful real-time recording (e.g. to measure how long something took on screen).
|
|
36
36
|
|