@swmansion/argent 0.18.1-next.0 → 0.18.1-next.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli-cmds.mjs +67 -29
- package/dist/installer.mjs +30 -29
- package/dist/mcp-server.mjs +224 -19
- package/package.json +2 -1
- package/skills/argent-screen-recording/SKILL.md +1 -1
package/dist/cli-cmds.mjs
CHANGED
|
@@ -204,7 +204,7 @@ function generateAuthToken() {
|
|
|
204
204
|
return generateToken();
|
|
205
205
|
}
|
|
206
206
|
function findFreePort() {
|
|
207
|
-
return new Promise((
|
|
207
|
+
return new Promise((resolve9, reject) => {
|
|
208
208
|
const srv = net.createServer();
|
|
209
209
|
srv.listen(0, "127.0.0.1", () => {
|
|
210
210
|
const addr = srv.address();
|
|
@@ -215,7 +215,7 @@ function findFreePort() {
|
|
|
215
215
|
const port = addr.port;
|
|
216
216
|
srv.close((err) => {
|
|
217
217
|
if (err) reject(err);
|
|
218
|
-
else
|
|
218
|
+
else resolve9(port);
|
|
219
219
|
});
|
|
220
220
|
});
|
|
221
221
|
srv.on("error", reject);
|
|
@@ -316,7 +316,7 @@ function killSpawnedChild(child, pid) {
|
|
|
316
316
|
}
|
|
317
317
|
}
|
|
318
318
|
function spawnToolsServer(paths, port, options = {}) {
|
|
319
|
-
return new Promise((
|
|
319
|
+
return new Promise((resolve9, reject) => {
|
|
320
320
|
let logFd;
|
|
321
321
|
try {
|
|
322
322
|
fs.mkdirSync(STATE_DIR, { recursive: true });
|
|
@@ -353,7 +353,7 @@ function spawnToolsServer(paths, port, options = {}) {
|
|
|
353
353
|
rl.close();
|
|
354
354
|
child.stdout?.resume();
|
|
355
355
|
child.stdout?.unref?.();
|
|
356
|
-
settle(() =>
|
|
356
|
+
settle(() => resolve9({ port: actualPort, pid }));
|
|
357
357
|
}
|
|
358
358
|
});
|
|
359
359
|
child.on("error", (err) => {
|
|
@@ -879,9 +879,9 @@ async function tarball(sourcePath) {
|
|
|
879
879
|
return tarPath;
|
|
880
880
|
}
|
|
881
881
|
function sha256File(filePath) {
|
|
882
|
-
return new Promise((
|
|
882
|
+
return new Promise((resolve9, reject) => {
|
|
883
883
|
const hash = createHash2("sha256");
|
|
884
|
-
createReadStream(filePath).on("data", (chunk) => hash.update(chunk)).on("end", () =>
|
|
884
|
+
createReadStream(filePath).on("data", (chunk) => hash.update(chunk)).on("end", () => resolve9(hash.digest("hex"))).on("error", reject);
|
|
885
885
|
});
|
|
886
886
|
}
|
|
887
887
|
async function uploadTar(tarPath, endpoint) {
|
|
@@ -1103,7 +1103,7 @@ function createToolsClient(options = {}) {
|
|
|
1103
1103
|
import { copyFile, mkdir as mkdir4, readFile as readFile4, realpath, rm as rm3, stat as stat2, writeFile as writeFile4 } from "node:fs/promises";
|
|
1104
1104
|
import { constants as fsConstants } from "node:fs";
|
|
1105
1105
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
1106
|
-
import { basename as basename3, dirname as dirname5, extname, isAbsolute as isAbsolute3, join as join8, normalize, sep as sep2 } from "node:path";
|
|
1106
|
+
import { basename as basename3, dirname as dirname5, extname, isAbsolute as isAbsolute3, join as join8, normalize, resolve as resolve5, sep as sep2 } from "node:path";
|
|
1107
1107
|
import { createHash as createHash3 } from "node:crypto";
|
|
1108
1108
|
|
|
1109
1109
|
// ../configuration-core/src/flags.ts
|
|
@@ -1493,6 +1493,18 @@ var CONFIG_SCHEMA = [
|
|
|
1493
1493
|
// must precede dedup) and guards on the preset staying "union".
|
|
1494
1494
|
merge: "union",
|
|
1495
1495
|
example: '["~/DeviceSets/ci"]'
|
|
1496
|
+
},
|
|
1497
|
+
{
|
|
1498
|
+
key: "recordings.directory",
|
|
1499
|
+
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.",
|
|
1500
|
+
scopes: ["project", "global"],
|
|
1501
|
+
parse: asString,
|
|
1502
|
+
// A repo can pin where its recordings land; falls back to the user's global
|
|
1503
|
+
// preference. Resolution happens on the client (the machine the mp4 is
|
|
1504
|
+
// persisted to), so with a remote `argent link` tool-server it is the
|
|
1505
|
+
// *client's* config that decides.
|
|
1506
|
+
merge: "prioritize-local",
|
|
1507
|
+
example: "~/Movies/argent"
|
|
1496
1508
|
}
|
|
1497
1509
|
];
|
|
1498
1510
|
function getConfigDefinition(key, registry = CONFIG_SCHEMA) {
|
|
@@ -1654,6 +1666,21 @@ function durableBaseDir() {
|
|
|
1654
1666
|
return projectRoot ?? dirname5(argentHomeDir());
|
|
1655
1667
|
}
|
|
1656
1668
|
var ALLOWED_SAVE_DIRS = /* @__PURE__ */ new Set([normalize(".argent/recordings")]);
|
|
1669
|
+
var RECORDINGS_SAVE_DIR = normalize(".argent/recordings");
|
|
1670
|
+
function configuredRecordingsDir() {
|
|
1671
|
+
let value;
|
|
1672
|
+
try {
|
|
1673
|
+
value = getConfigValueByKey("recordings.directory");
|
|
1674
|
+
} catch {
|
|
1675
|
+
return null;
|
|
1676
|
+
}
|
|
1677
|
+
if (typeof value !== "string") return null;
|
|
1678
|
+
const trimmed = value.trim();
|
|
1679
|
+
if (trimmed === "") return null;
|
|
1680
|
+
const home = dirname5(argentHomeDir());
|
|
1681
|
+
const expanded = trimmed === "~" ? home : trimmed.startsWith("~/") || trimmed.startsWith(`~${sep2}`) ? join8(home, trimmed.slice(2)) : trimmed;
|
|
1682
|
+
return resolve5(durableBaseDir(), expanded);
|
|
1683
|
+
}
|
|
1657
1684
|
var MAX_DURABLE_BYTES = 2 * 1024 * 1024 * 1024;
|
|
1658
1685
|
async function readCapped(res, cap) {
|
|
1659
1686
|
const headers = res.headers;
|
|
@@ -1703,6 +1730,17 @@ function durableSaveTarget(handle) {
|
|
|
1703
1730
|
return null;
|
|
1704
1731
|
}
|
|
1705
1732
|
if (!ALLOWED_SAVE_DIRS.has(rel)) return null;
|
|
1733
|
+
if (rel === RECORDINGS_SAVE_DIR) {
|
|
1734
|
+
const configured = configuredRecordingsDir();
|
|
1735
|
+
if (configured) {
|
|
1736
|
+
return {
|
|
1737
|
+
dir: configured,
|
|
1738
|
+
path: join8(configured, sanitizeSegment(handle.filename)),
|
|
1739
|
+
base: configured,
|
|
1740
|
+
rel: ""
|
|
1741
|
+
};
|
|
1742
|
+
}
|
|
1743
|
+
}
|
|
1706
1744
|
const base = durableBaseDir();
|
|
1707
1745
|
const dir = join8(base, rel);
|
|
1708
1746
|
return { dir, path: join8(dir, sanitizeSegment(handle.filename)), base, rel };
|
|
@@ -4438,14 +4476,14 @@ async function addSourceContext(frames) {
|
|
|
4438
4476
|
return frames;
|
|
4439
4477
|
}
|
|
4440
4478
|
function getContextLinesFromFile(path16, ranges, output) {
|
|
4441
|
-
return new Promise((
|
|
4479
|
+
return new Promise((resolve9) => {
|
|
4442
4480
|
const stream = createReadStream2(path16);
|
|
4443
4481
|
const lineReaded = createInterface2({
|
|
4444
4482
|
input: stream
|
|
4445
4483
|
});
|
|
4446
4484
|
function destroyStreamAndResolve() {
|
|
4447
4485
|
stream.destroy();
|
|
4448
|
-
|
|
4486
|
+
resolve9();
|
|
4449
4487
|
}
|
|
4450
4488
|
let lineNumber = 0;
|
|
4451
4489
|
let currentRangeIndex = 0;
|
|
@@ -5742,9 +5780,9 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
|
|
|
5742
5780
|
if (!waitUntil) return;
|
|
5743
5781
|
if (this.disabled || this.optedOut) return;
|
|
5744
5782
|
if (!this._waitUntilCycle) {
|
|
5745
|
-
let
|
|
5783
|
+
let resolve9;
|
|
5746
5784
|
const promise = new Promise((r2) => {
|
|
5747
|
-
|
|
5785
|
+
resolve9 = r2;
|
|
5748
5786
|
});
|
|
5749
5787
|
try {
|
|
5750
5788
|
waitUntil(promise);
|
|
@@ -5752,7 +5790,7 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
|
|
|
5752
5790
|
return;
|
|
5753
5791
|
}
|
|
5754
5792
|
this._waitUntilCycle = {
|
|
5755
|
-
resolve:
|
|
5793
|
+
resolve: resolve9,
|
|
5756
5794
|
startedAt: Date.now(),
|
|
5757
5795
|
timer: void 0
|
|
5758
5796
|
};
|
|
@@ -5776,12 +5814,12 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
|
|
|
5776
5814
|
return cycle?.resolve;
|
|
5777
5815
|
}
|
|
5778
5816
|
async resolveWaitUntilFlush() {
|
|
5779
|
-
const
|
|
5817
|
+
const resolve9 = this._consumeWaitUntilCycle();
|
|
5780
5818
|
try {
|
|
5781
5819
|
await super.flush();
|
|
5782
5820
|
} catch {
|
|
5783
5821
|
} finally {
|
|
5784
|
-
|
|
5822
|
+
resolve9?.();
|
|
5785
5823
|
}
|
|
5786
5824
|
}
|
|
5787
5825
|
getPersistedProperty(key) {
|
|
@@ -5902,15 +5940,15 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
|
|
|
5902
5940
|
async waitForLocalEvaluationReady(timeoutMs = THIRTY_SECONDS) {
|
|
5903
5941
|
if (this.isLocalEvaluationReady()) return true;
|
|
5904
5942
|
if (void 0 === this.featureFlagsPoller) return false;
|
|
5905
|
-
return new Promise((
|
|
5943
|
+
return new Promise((resolve9) => {
|
|
5906
5944
|
const timeout = setTimeout(() => {
|
|
5907
5945
|
cleanup();
|
|
5908
|
-
|
|
5946
|
+
resolve9(false);
|
|
5909
5947
|
}, timeoutMs);
|
|
5910
5948
|
const cleanup = this._events.on("localEvaluationFlagsLoaded", (count) => {
|
|
5911
5949
|
clearTimeout(timeout);
|
|
5912
5950
|
cleanup();
|
|
5913
|
-
|
|
5951
|
+
resolve9(count > 0);
|
|
5914
5952
|
});
|
|
5915
5953
|
});
|
|
5916
5954
|
}
|
|
@@ -6365,14 +6403,14 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
|
|
|
6365
6403
|
this.context?.enter(data, options);
|
|
6366
6404
|
}
|
|
6367
6405
|
async _shutdown(shutdownTimeoutMs) {
|
|
6368
|
-
const
|
|
6406
|
+
const resolve9 = this._consumeWaitUntilCycle();
|
|
6369
6407
|
await this.featureFlagsPoller?.stopPoller(shutdownTimeoutMs);
|
|
6370
6408
|
this.errorTracking.shutdown();
|
|
6371
6409
|
try {
|
|
6372
6410
|
return await super._shutdown(shutdownTimeoutMs);
|
|
6373
6411
|
} finally {
|
|
6374
6412
|
this.distinctIdHasSentFlagCalls = {};
|
|
6375
|
-
|
|
6413
|
+
resolve9?.();
|
|
6376
6414
|
}
|
|
6377
6415
|
}
|
|
6378
6416
|
async _requestRemoteConfigPayload(flagKey) {
|
|
@@ -8106,12 +8144,12 @@ function resolveHostFingerprint() {
|
|
|
8106
8144
|
}
|
|
8107
8145
|
}
|
|
8108
8146
|
function resolveHostFingerprintAsync() {
|
|
8109
|
-
return new Promise((
|
|
8147
|
+
return new Promise((resolve9) => {
|
|
8110
8148
|
let binary;
|
|
8111
8149
|
try {
|
|
8112
8150
|
binary = simulatorServerBinaryPath();
|
|
8113
8151
|
} catch {
|
|
8114
|
-
|
|
8152
|
+
resolve9(null);
|
|
8115
8153
|
return;
|
|
8116
8154
|
}
|
|
8117
8155
|
let settled = false;
|
|
@@ -8124,7 +8162,7 @@ function resolveHostFingerprintAsync() {
|
|
|
8124
8162
|
child?.kill("SIGKILL");
|
|
8125
8163
|
} catch {
|
|
8126
8164
|
}
|
|
8127
|
-
|
|
8165
|
+
resolve9(value);
|
|
8128
8166
|
};
|
|
8129
8167
|
const watchdog = setTimeout(() => finish(null), FINGERPRINT_TIMEOUT_MS);
|
|
8130
8168
|
watchdog.unref?.();
|
|
@@ -8366,7 +8404,7 @@ async function shutdown(timeoutMs = SHORT_FLUSH_TIMEOUT_MS) {
|
|
|
8366
8404
|
try {
|
|
8367
8405
|
await Promise.race([
|
|
8368
8406
|
client2.shutdown(timeoutMs),
|
|
8369
|
-
new Promise((
|
|
8407
|
+
new Promise((resolve9) => setTimeout(resolve9, timeoutMs + 250).unref())
|
|
8370
8408
|
]);
|
|
8371
8409
|
} catch (err) {
|
|
8372
8410
|
emitDebugError("shutdown failed", err);
|
|
@@ -8386,7 +8424,7 @@ async function markDisabled() {
|
|
|
8386
8424
|
try {
|
|
8387
8425
|
await Promise.race([
|
|
8388
8426
|
client2.shutdown(SHORT_FLUSH_TIMEOUT_MS),
|
|
8389
|
-
new Promise((
|
|
8427
|
+
new Promise((resolve9) => setTimeout(resolve9, SHORT_FLUSH_TIMEOUT_MS).unref())
|
|
8390
8428
|
]);
|
|
8391
8429
|
} catch {
|
|
8392
8430
|
}
|
|
@@ -8628,13 +8666,13 @@ function splitOptions(argv) {
|
|
|
8628
8666
|
return { json, outPath, argvForFlags: rest };
|
|
8629
8667
|
}
|
|
8630
8668
|
async function readStdin() {
|
|
8631
|
-
return new Promise((
|
|
8669
|
+
return new Promise((resolve9, reject) => {
|
|
8632
8670
|
let data = "";
|
|
8633
8671
|
process.stdin.setEncoding("utf8");
|
|
8634
8672
|
process.stdin.on("data", (chunk) => {
|
|
8635
8673
|
data += chunk;
|
|
8636
8674
|
});
|
|
8637
|
-
process.stdin.on("end", () =>
|
|
8675
|
+
process.stdin.on("end", () => resolve9(data));
|
|
8638
8676
|
process.stdin.on("error", reject);
|
|
8639
8677
|
});
|
|
8640
8678
|
}
|
|
@@ -8996,7 +9034,7 @@ function resolveArtifactDisplayPaths(report) {
|
|
|
8996
9034
|
}
|
|
8997
9035
|
function exitAfterFlush(code, streams = [process.stdout, process.stderr]) {
|
|
8998
9036
|
return Promise.all(
|
|
8999
|
-
streams.map((s) => new Promise((
|
|
9037
|
+
streams.map((s) => new Promise((resolve9) => s.write("", () => resolve9())))
|
|
9000
9038
|
).then(() => process.exit(code));
|
|
9001
9039
|
}
|
|
9002
9040
|
function renderReport(report) {
|
|
@@ -9881,7 +9919,7 @@ function ptyInjectBeats(text2) {
|
|
|
9881
9919
|
];
|
|
9882
9920
|
}
|
|
9883
9921
|
function sleep(ms) {
|
|
9884
|
-
return new Promise((
|
|
9922
|
+
return new Promise((resolve9) => setTimeout(resolve9, ms));
|
|
9885
9923
|
}
|
|
9886
9924
|
var DEFAULT_COLS = 80;
|
|
9887
9925
|
var DEFAULT_ROWS = 24;
|
|
@@ -10102,7 +10140,7 @@ var SPAWN_GRACE_MS = 8e3;
|
|
|
10102
10140
|
var DEATH_CONFIRMATIONS = 3;
|
|
10103
10141
|
var SSE_RECONNECT_MS = 1e3;
|
|
10104
10142
|
function sleep2(ms) {
|
|
10105
|
-
return new Promise((
|
|
10143
|
+
return new Promise((resolve9) => setTimeout(resolve9, ms));
|
|
10106
10144
|
}
|
|
10107
10145
|
var TRUST_PROMPT_RE = /trust this folder|do you trust|yes,? i trust|trust the files in this/i;
|
|
10108
10146
|
async function dismissTrustPrompt(session) {
|
package/dist/installer.mjs
CHANGED
|
@@ -9593,13 +9593,13 @@ var require_min_release_age = __commonJS({
|
|
|
9593
9593
|
return Number.isFinite(days) && days > 0 ? days * config_parse_1.DAY_MS : 0;
|
|
9594
9594
|
}
|
|
9595
9595
|
function probe(p) {
|
|
9596
|
-
return new Promise((
|
|
9596
|
+
return new Promise((resolve12) => {
|
|
9597
9597
|
(0, node_child_process_1.exec)(p.command, { timeout: PROBE_TIMEOUT_MS2, windowsHide: true }, (err, stdout2) => {
|
|
9598
9598
|
if (err) {
|
|
9599
|
-
|
|
9599
|
+
resolve12(0);
|
|
9600
9600
|
return;
|
|
9601
9601
|
}
|
|
9602
|
-
|
|
9602
|
+
resolve12(p.parse(stdout2));
|
|
9603
9603
|
});
|
|
9604
9604
|
});
|
|
9605
9605
|
}
|
|
@@ -9632,12 +9632,12 @@ var require_registry = __commonJS({
|
|
|
9632
9632
|
var node_https_1 = __importDefault(__require("node:https"));
|
|
9633
9633
|
var REQUEST_TIMEOUT_MS = 1e4;
|
|
9634
9634
|
function fetchRegistryInfo2(url) {
|
|
9635
|
-
return new Promise((
|
|
9635
|
+
return new Promise((resolve12) => {
|
|
9636
9636
|
let resolved = false;
|
|
9637
9637
|
const safeResolve = (value) => {
|
|
9638
9638
|
if (!resolved) {
|
|
9639
9639
|
resolved = true;
|
|
9640
|
-
|
|
9640
|
+
resolve12(value);
|
|
9641
9641
|
}
|
|
9642
9642
|
};
|
|
9643
9643
|
const req = node_https_1.default.get(url, { timeout: REQUEST_TIMEOUT_MS }, (res) => {
|
|
@@ -13702,14 +13702,14 @@ async function addSourceContext(frames) {
|
|
|
13702
13702
|
return frames;
|
|
13703
13703
|
}
|
|
13704
13704
|
function getContextLinesFromFile(path20, ranges, output) {
|
|
13705
|
-
return new Promise((
|
|
13705
|
+
return new Promise((resolve12) => {
|
|
13706
13706
|
const stream = createReadStream(path20);
|
|
13707
13707
|
const lineReaded = createInterface2({
|
|
13708
13708
|
input: stream
|
|
13709
13709
|
});
|
|
13710
13710
|
function destroyStreamAndResolve() {
|
|
13711
13711
|
stream.destroy();
|
|
13712
|
-
|
|
13712
|
+
resolve12();
|
|
13713
13713
|
}
|
|
13714
13714
|
let lineNumber = 0;
|
|
13715
13715
|
let currentRangeIndex = 0;
|
|
@@ -15006,9 +15006,9 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
|
|
|
15006
15006
|
if (!waitUntil) return;
|
|
15007
15007
|
if (this.disabled || this.optedOut) return;
|
|
15008
15008
|
if (!this._waitUntilCycle) {
|
|
15009
|
-
let
|
|
15009
|
+
let resolve12;
|
|
15010
15010
|
const promise = new Promise((r2) => {
|
|
15011
|
-
|
|
15011
|
+
resolve12 = r2;
|
|
15012
15012
|
});
|
|
15013
15013
|
try {
|
|
15014
15014
|
waitUntil(promise);
|
|
@@ -15016,7 +15016,7 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
|
|
|
15016
15016
|
return;
|
|
15017
15017
|
}
|
|
15018
15018
|
this._waitUntilCycle = {
|
|
15019
|
-
resolve:
|
|
15019
|
+
resolve: resolve12,
|
|
15020
15020
|
startedAt: Date.now(),
|
|
15021
15021
|
timer: void 0
|
|
15022
15022
|
};
|
|
@@ -15040,12 +15040,12 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
|
|
|
15040
15040
|
return cycle?.resolve;
|
|
15041
15041
|
}
|
|
15042
15042
|
async resolveWaitUntilFlush() {
|
|
15043
|
-
const
|
|
15043
|
+
const resolve12 = this._consumeWaitUntilCycle();
|
|
15044
15044
|
try {
|
|
15045
15045
|
await super.flush();
|
|
15046
15046
|
} catch {
|
|
15047
15047
|
} finally {
|
|
15048
|
-
|
|
15048
|
+
resolve12?.();
|
|
15049
15049
|
}
|
|
15050
15050
|
}
|
|
15051
15051
|
getPersistedProperty(key) {
|
|
@@ -15166,15 +15166,15 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
|
|
|
15166
15166
|
async waitForLocalEvaluationReady(timeoutMs = THIRTY_SECONDS) {
|
|
15167
15167
|
if (this.isLocalEvaluationReady()) return true;
|
|
15168
15168
|
if (void 0 === this.featureFlagsPoller) return false;
|
|
15169
|
-
return new Promise((
|
|
15169
|
+
return new Promise((resolve12) => {
|
|
15170
15170
|
const timeout = setTimeout(() => {
|
|
15171
15171
|
cleanup();
|
|
15172
|
-
|
|
15172
|
+
resolve12(false);
|
|
15173
15173
|
}, timeoutMs);
|
|
15174
15174
|
const cleanup = this._events.on("localEvaluationFlagsLoaded", (count) => {
|
|
15175
15175
|
clearTimeout(timeout);
|
|
15176
15176
|
cleanup();
|
|
15177
|
-
|
|
15177
|
+
resolve12(count > 0);
|
|
15178
15178
|
});
|
|
15179
15179
|
});
|
|
15180
15180
|
}
|
|
@@ -15629,14 +15629,14 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
|
|
|
15629
15629
|
this.context?.enter(data, options);
|
|
15630
15630
|
}
|
|
15631
15631
|
async _shutdown(shutdownTimeoutMs) {
|
|
15632
|
-
const
|
|
15632
|
+
const resolve12 = this._consumeWaitUntilCycle();
|
|
15633
15633
|
await this.featureFlagsPoller?.stopPoller(shutdownTimeoutMs);
|
|
15634
15634
|
this.errorTracking.shutdown();
|
|
15635
15635
|
try {
|
|
15636
15636
|
return await super._shutdown(shutdownTimeoutMs);
|
|
15637
15637
|
} finally {
|
|
15638
15638
|
this.distinctIdHasSentFlagCalls = {};
|
|
15639
|
-
|
|
15639
|
+
resolve12?.();
|
|
15640
15640
|
}
|
|
15641
15641
|
}
|
|
15642
15642
|
async _requestRemoteConfigPayload(flagKey) {
|
|
@@ -17524,12 +17524,12 @@ function resolveHostFingerprint() {
|
|
|
17524
17524
|
}
|
|
17525
17525
|
}
|
|
17526
17526
|
function resolveHostFingerprintAsync() {
|
|
17527
|
-
return new Promise((
|
|
17527
|
+
return new Promise((resolve12) => {
|
|
17528
17528
|
let binary;
|
|
17529
17529
|
try {
|
|
17530
17530
|
binary = simulatorServerBinaryPath();
|
|
17531
17531
|
} catch {
|
|
17532
|
-
|
|
17532
|
+
resolve12(null);
|
|
17533
17533
|
return;
|
|
17534
17534
|
}
|
|
17535
17535
|
let settled = false;
|
|
@@ -17542,7 +17542,7 @@ function resolveHostFingerprintAsync() {
|
|
|
17542
17542
|
child?.kill("SIGKILL");
|
|
17543
17543
|
} catch {
|
|
17544
17544
|
}
|
|
17545
|
-
|
|
17545
|
+
resolve12(value);
|
|
17546
17546
|
};
|
|
17547
17547
|
const watchdog = setTimeout(() => finish(null), FINGERPRINT_TIMEOUT_MS);
|
|
17548
17548
|
watchdog.unref?.();
|
|
@@ -17840,7 +17840,7 @@ async function shutdown(timeoutMs = SHORT_FLUSH_TIMEOUT_MS) {
|
|
|
17840
17840
|
try {
|
|
17841
17841
|
await Promise.race([
|
|
17842
17842
|
client2.shutdown(timeoutMs),
|
|
17843
|
-
new Promise((
|
|
17843
|
+
new Promise((resolve12) => setTimeout(resolve12, timeoutMs + 250).unref())
|
|
17844
17844
|
]);
|
|
17845
17845
|
} catch (err) {
|
|
17846
17846
|
emitDebugError("shutdown failed", err);
|
|
@@ -20678,12 +20678,12 @@ async function isOnline(timeoutMs = PROBE_TIMEOUT_MS) {
|
|
|
20678
20678
|
} catch {
|
|
20679
20679
|
return false;
|
|
20680
20680
|
}
|
|
20681
|
-
return new Promise((
|
|
20682
|
-
const timer = setTimeout(() =>
|
|
20681
|
+
return new Promise((resolve12) => {
|
|
20682
|
+
const timer = setTimeout(() => resolve12(false), timeoutMs);
|
|
20683
20683
|
timer.unref();
|
|
20684
20684
|
dns.lookup(host, (err) => {
|
|
20685
20685
|
clearTimeout(timer);
|
|
20686
|
-
|
|
20686
|
+
resolve12(!err);
|
|
20687
20687
|
});
|
|
20688
20688
|
});
|
|
20689
20689
|
}
|
|
@@ -22303,7 +22303,7 @@ var ShellCommandError = class extends Error {
|
|
|
22303
22303
|
signal;
|
|
22304
22304
|
};
|
|
22305
22305
|
function runShellCommand(cmd, opts = {}) {
|
|
22306
|
-
return new Promise((
|
|
22306
|
+
return new Promise((resolve12, reject) => {
|
|
22307
22307
|
const child = spawn2(cmd.bin, cmd.args, {
|
|
22308
22308
|
stdio: ["ignore", "pipe", "pipe"],
|
|
22309
22309
|
shell: process.platform === "win32",
|
|
@@ -22314,7 +22314,7 @@ function runShellCommand(cmd, opts = {}) {
|
|
|
22314
22314
|
stderr += chunk.toString();
|
|
22315
22315
|
});
|
|
22316
22316
|
child.on("close", (code, signal) => {
|
|
22317
|
-
if (code === 0)
|
|
22317
|
+
if (code === 0) resolve12();
|
|
22318
22318
|
else
|
|
22319
22319
|
reject(
|
|
22320
22320
|
new ShellCommandError(
|
|
@@ -23189,7 +23189,7 @@ async function runSkillsStep(args) {
|
|
|
23189
23189
|
return skillsMethod;
|
|
23190
23190
|
}
|
|
23191
23191
|
function runNpxSkills(args, interactive, cwd) {
|
|
23192
|
-
return new Promise((
|
|
23192
|
+
return new Promise((resolve12, reject) => {
|
|
23193
23193
|
const npxCmd = process.platform === "win32" ? "npx.cmd" : "npx";
|
|
23194
23194
|
const child = spawn3(npxCmd, args, {
|
|
23195
23195
|
stdio: interactive ? "inherit" : ["ignore", "pipe", "pipe"],
|
|
@@ -23208,7 +23208,7 @@ function runNpxSkills(args, interactive, cwd) {
|
|
|
23208
23208
|
}
|
|
23209
23209
|
child.on("close", (code) => {
|
|
23210
23210
|
if (code === 0) {
|
|
23211
|
-
|
|
23211
|
+
resolve12();
|
|
23212
23212
|
} else {
|
|
23213
23213
|
const output = [stderr, stdout2].filter(Boolean).join("\n").trim();
|
|
23214
23214
|
reject(new Error(output || `npx skills exited with code ${code}`));
|
|
@@ -23685,9 +23685,10 @@ var MAX_CONTENT_BYTES = 32 * 1024 * 1024;
|
|
|
23685
23685
|
import { copyFile, mkdir as mkdir4, readFile as readFile4, realpath, rm as rm3, stat as stat3, writeFile as writeFile4 } from "node:fs/promises";
|
|
23686
23686
|
import { constants as fsConstants } from "node:fs";
|
|
23687
23687
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
23688
|
-
import { basename as basename4, dirname as dirname13, extname as extname2, isAbsolute as isAbsolute5, join as join19, normalize, sep as sep6 } from "node:path";
|
|
23688
|
+
import { basename as basename4, dirname as dirname13, extname as extname2, isAbsolute as isAbsolute5, join as join19, normalize, resolve as resolve10, sep as sep6 } from "node:path";
|
|
23689
23689
|
import { createHash as createHash4 } from "node:crypto";
|
|
23690
23690
|
var ALLOWED_SAVE_DIRS = /* @__PURE__ */ new Set([normalize(".argent/recordings")]);
|
|
23691
|
+
var RECORDINGS_SAVE_DIR = normalize(".argent/recordings");
|
|
23691
23692
|
var MAX_DURABLE_BYTES = 2 * 1024 * 1024 * 1024;
|
|
23692
23693
|
|
|
23693
23694
|
// ../argent-installer/src/update.ts
|
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;
|
|
@@ -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,
|
|
@@ -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
|
|
@@ -16310,6 +16310,31 @@ function readConfigObject(scope = "global", options = {}) {
|
|
|
16310
16310
|
}
|
|
16311
16311
|
return {};
|
|
16312
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
|
+
}
|
|
16313
16338
|
var LOCK_STALE_MS2 = 1e4;
|
|
16314
16339
|
var LOCK_MAX_WAIT_MS = 2e3;
|
|
16315
16340
|
var LOCK_RETRY_MS = 25;
|
|
@@ -16382,8 +16407,162 @@ function updateConfig(mutate, scope = "global", options = {}) {
|
|
|
16382
16407
|
}
|
|
16383
16408
|
}
|
|
16384
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
|
+
|
|
16385
16534
|
// ../configuration-core/src/config-access.ts
|
|
16386
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
|
+
};
|
|
16387
16566
|
|
|
16388
16567
|
// ../argent-tools-client/src/artifacts.ts
|
|
16389
16568
|
var ARTIFACT_MARKER = "__argentArtifact";
|
|
@@ -16420,6 +16599,21 @@ function durableBaseDir() {
|
|
|
16420
16599
|
return projectRoot ?? dirname5(argentHomeDir());
|
|
16421
16600
|
}
|
|
16422
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
|
+
}
|
|
16423
16617
|
var MAX_DURABLE_BYTES = 2 * 1024 * 1024 * 1024;
|
|
16424
16618
|
async function readCapped(res, cap) {
|
|
16425
16619
|
const headers = res.headers;
|
|
@@ -16469,6 +16663,17 @@ function durableSaveTarget(handle) {
|
|
|
16469
16663
|
return null;
|
|
16470
16664
|
}
|
|
16471
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
|
+
}
|
|
16472
16677
|
const base = durableBaseDir();
|
|
16473
16678
|
const dir = join8(base, rel);
|
|
16474
16679
|
return { dir, path: join8(dir, sanitizeSegment(handle.filename)), base, rel };
|
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
|
|