@osfactory/har 0.21.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.js +1021 -597
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -765,14 +765,14 @@ var require_url_state_machine = __commonJS({
|
|
|
765
765
|
return url.replace(/\u0009|\u000A|\u000D/g, "");
|
|
766
766
|
}
|
|
767
767
|
function shortenPath(url) {
|
|
768
|
-
const
|
|
769
|
-
if (
|
|
768
|
+
const path54 = url.path;
|
|
769
|
+
if (path54.length === 0) {
|
|
770
770
|
return;
|
|
771
771
|
}
|
|
772
|
-
if (url.scheme === "file" &&
|
|
772
|
+
if (url.scheme === "file" && path54.length === 1 && isNormalizedWindowsDriveLetter(path54[0])) {
|
|
773
773
|
return;
|
|
774
774
|
}
|
|
775
|
-
|
|
775
|
+
path54.pop();
|
|
776
776
|
}
|
|
777
777
|
function includesCredentials(url) {
|
|
778
778
|
return url.username !== "" || url.password !== "";
|
|
@@ -1811,7 +1811,7 @@ var require_lib2 = __commonJS({
|
|
|
1811
1811
|
return ex && typeof ex === "object" && "default" in ex ? ex["default"] : ex;
|
|
1812
1812
|
}
|
|
1813
1813
|
var Stream2 = _interopDefault(require("stream"));
|
|
1814
|
-
var
|
|
1814
|
+
var http2 = _interopDefault(require("http"));
|
|
1815
1815
|
var Url = _interopDefault(require("url"));
|
|
1816
1816
|
var whatwgUrl = _interopDefault(require_public_api());
|
|
1817
1817
|
var https = _interopDefault(require("https"));
|
|
@@ -2092,7 +2092,7 @@ var require_lib2 = __commonJS({
|
|
|
2092
2092
|
let accum = [];
|
|
2093
2093
|
let accumBytes = 0;
|
|
2094
2094
|
let abort = false;
|
|
2095
|
-
return new Body.Promise(function(
|
|
2095
|
+
return new Body.Promise(function(resolve38, reject) {
|
|
2096
2096
|
let resTimeout;
|
|
2097
2097
|
if (_this4.timeout) {
|
|
2098
2098
|
resTimeout = setTimeout(function() {
|
|
@@ -2126,7 +2126,7 @@ var require_lib2 = __commonJS({
|
|
|
2126
2126
|
}
|
|
2127
2127
|
clearTimeout(resTimeout);
|
|
2128
2128
|
try {
|
|
2129
|
-
|
|
2129
|
+
resolve38(Buffer.concat(accum, accumBytes));
|
|
2130
2130
|
} catch (err) {
|
|
2131
2131
|
reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, "system", err));
|
|
2132
2132
|
}
|
|
@@ -2551,7 +2551,7 @@ var require_lib2 = __commonJS({
|
|
|
2551
2551
|
return headers;
|
|
2552
2552
|
}
|
|
2553
2553
|
var INTERNALS$1 = Symbol("Response internals");
|
|
2554
|
-
var STATUS_CODES =
|
|
2554
|
+
var STATUS_CODES = http2.STATUS_CODES;
|
|
2555
2555
|
var Response3 = class _Response {
|
|
2556
2556
|
constructor() {
|
|
2557
2557
|
let body = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : null;
|
|
@@ -2801,10 +2801,10 @@ var require_lib2 = __commonJS({
|
|
|
2801
2801
|
throw new Error("native promise missing, set fetch.Promise to your favorite alternative");
|
|
2802
2802
|
}
|
|
2803
2803
|
Body.Promise = fetch3.Promise;
|
|
2804
|
-
return new fetch3.Promise(function(
|
|
2804
|
+
return new fetch3.Promise(function(resolve38, reject) {
|
|
2805
2805
|
const request = new Request3(url, opts);
|
|
2806
2806
|
const options = getNodeRequestOptions(request);
|
|
2807
|
-
const send = (options.protocol === "https:" ? https :
|
|
2807
|
+
const send = (options.protocol === "https:" ? https : http2).request;
|
|
2808
2808
|
const signal = request.signal;
|
|
2809
2809
|
let response = null;
|
|
2810
2810
|
const abort = function abort2() {
|
|
@@ -2934,7 +2934,7 @@ var require_lib2 = __commonJS({
|
|
|
2934
2934
|
requestOpts.body = void 0;
|
|
2935
2935
|
requestOpts.headers.delete("content-length");
|
|
2936
2936
|
}
|
|
2937
|
-
|
|
2937
|
+
resolve38(fetch3(new Request3(locationURL, requestOpts)));
|
|
2938
2938
|
finalize();
|
|
2939
2939
|
return;
|
|
2940
2940
|
}
|
|
@@ -2955,7 +2955,7 @@ var require_lib2 = __commonJS({
|
|
|
2955
2955
|
const codings = headers.get("Content-Encoding");
|
|
2956
2956
|
if (!request.compress || request.method === "HEAD" || codings === null || res.statusCode === 204 || res.statusCode === 304) {
|
|
2957
2957
|
response = new Response3(body, response_options);
|
|
2958
|
-
|
|
2958
|
+
resolve38(response);
|
|
2959
2959
|
return;
|
|
2960
2960
|
}
|
|
2961
2961
|
const zlibOptions = {
|
|
@@ -2965,7 +2965,7 @@ var require_lib2 = __commonJS({
|
|
|
2965
2965
|
if (codings == "gzip" || codings == "x-gzip") {
|
|
2966
2966
|
body = body.pipe(zlib.createGunzip(zlibOptions));
|
|
2967
2967
|
response = new Response3(body, response_options);
|
|
2968
|
-
|
|
2968
|
+
resolve38(response);
|
|
2969
2969
|
return;
|
|
2970
2970
|
}
|
|
2971
2971
|
if (codings == "deflate" || codings == "x-deflate") {
|
|
@@ -2977,12 +2977,12 @@ var require_lib2 = __commonJS({
|
|
|
2977
2977
|
body = body.pipe(zlib.createInflateRaw());
|
|
2978
2978
|
}
|
|
2979
2979
|
response = new Response3(body, response_options);
|
|
2980
|
-
|
|
2980
|
+
resolve38(response);
|
|
2981
2981
|
});
|
|
2982
2982
|
raw.on("end", function() {
|
|
2983
2983
|
if (!response) {
|
|
2984
2984
|
response = new Response3(body, response_options);
|
|
2985
|
-
|
|
2985
|
+
resolve38(response);
|
|
2986
2986
|
}
|
|
2987
2987
|
});
|
|
2988
2988
|
return;
|
|
@@ -2990,11 +2990,11 @@ var require_lib2 = __commonJS({
|
|
|
2990
2990
|
if (codings == "br" && typeof zlib.createBrotliDecompress === "function") {
|
|
2991
2991
|
body = body.pipe(zlib.createBrotliDecompress());
|
|
2992
2992
|
response = new Response3(body, response_options);
|
|
2993
|
-
|
|
2993
|
+
resolve38(response);
|
|
2994
2994
|
return;
|
|
2995
2995
|
}
|
|
2996
2996
|
response = new Response3(body, response_options);
|
|
2997
|
-
|
|
2997
|
+
resolve38(response);
|
|
2998
2998
|
});
|
|
2999
2999
|
writeToStream(req, request);
|
|
3000
3000
|
});
|
|
@@ -6351,14 +6351,14 @@ __export(fileFromPath_exports, {
|
|
|
6351
6351
|
fileFromPathSync: () => fileFromPathSync,
|
|
6352
6352
|
isFile: () => isFile
|
|
6353
6353
|
});
|
|
6354
|
-
function createFileFromPath(
|
|
6354
|
+
function createFileFromPath(path54, { mtimeMs, size }, filenameOrOptions, options = {}) {
|
|
6355
6355
|
let filename;
|
|
6356
6356
|
if (isPlainObject_default2(filenameOrOptions)) {
|
|
6357
6357
|
[options, filename] = [filenameOrOptions, void 0];
|
|
6358
6358
|
} else {
|
|
6359
6359
|
filename = filenameOrOptions;
|
|
6360
6360
|
}
|
|
6361
|
-
const file = new FileFromPath({ path:
|
|
6361
|
+
const file = new FileFromPath({ path: path54, size, lastModified: mtimeMs });
|
|
6362
6362
|
if (!filename) {
|
|
6363
6363
|
filename = file.name;
|
|
6364
6364
|
}
|
|
@@ -6367,13 +6367,13 @@ function createFileFromPath(path53, { mtimeMs, size }, filenameOrOptions, option
|
|
|
6367
6367
|
lastModified: file.lastModified
|
|
6368
6368
|
});
|
|
6369
6369
|
}
|
|
6370
|
-
function fileFromPathSync(
|
|
6371
|
-
const stats = (0, import_fs5.statSync)(
|
|
6372
|
-
return createFileFromPath(
|
|
6370
|
+
function fileFromPathSync(path54, filenameOrOptions, options = {}) {
|
|
6371
|
+
const stats = (0, import_fs5.statSync)(path54);
|
|
6372
|
+
return createFileFromPath(path54, stats, filenameOrOptions, options);
|
|
6373
6373
|
}
|
|
6374
|
-
async function fileFromPath2(
|
|
6375
|
-
const stats = await import_fs5.promises.stat(
|
|
6376
|
-
return createFileFromPath(
|
|
6374
|
+
async function fileFromPath2(path54, filenameOrOptions, options) {
|
|
6375
|
+
const stats = await import_fs5.promises.stat(path54);
|
|
6376
|
+
return createFileFromPath(path54, stats, filenameOrOptions, options);
|
|
6377
6377
|
}
|
|
6378
6378
|
var import_fs5, import_path5, import_node_domexception, __classPrivateFieldSet5, __classPrivateFieldGet6, _FileFromPath_path, _FileFromPath_start, MESSAGE, FileFromPath;
|
|
6379
6379
|
var init_fileFromPath = __esm({
|
|
@@ -6433,6 +6433,45 @@ var init_fileFromPath = __esm({
|
|
|
6433
6433
|
}
|
|
6434
6434
|
});
|
|
6435
6435
|
|
|
6436
|
+
// src/core/portal-credentials.ts
|
|
6437
|
+
function portalCredentialsPath() {
|
|
6438
|
+
if (process.env.HAR_CREDENTIALS_PATH) {
|
|
6439
|
+
return path25.resolve(process.env.HAR_CREDENTIALS_PATH);
|
|
6440
|
+
}
|
|
6441
|
+
return path25.join(os4.homedir(), ".har", "credentials.json");
|
|
6442
|
+
}
|
|
6443
|
+
function readPortalCredentials() {
|
|
6444
|
+
try {
|
|
6445
|
+
const raw = fs26.readFileSync(portalCredentialsPath(), "utf8");
|
|
6446
|
+
const parsed = JSON.parse(raw);
|
|
6447
|
+
if (!parsed.portalUrl || !parsed.token) return null;
|
|
6448
|
+
return {
|
|
6449
|
+
portalUrl: parsed.portalUrl,
|
|
6450
|
+
token: parsed.token,
|
|
6451
|
+
workspace: parsed.workspace,
|
|
6452
|
+
email: parsed.email,
|
|
6453
|
+
createdAt: parsed.createdAt ?? ""
|
|
6454
|
+
};
|
|
6455
|
+
} catch {
|
|
6456
|
+
return null;
|
|
6457
|
+
}
|
|
6458
|
+
}
|
|
6459
|
+
function writePortalCredentials(creds) {
|
|
6460
|
+
const file = portalCredentialsPath();
|
|
6461
|
+
fs26.mkdirSync(path25.dirname(file), { recursive: true });
|
|
6462
|
+
fs26.writeFileSync(file, JSON.stringify(creds, null, 2), { mode: 384 });
|
|
6463
|
+
fs26.chmodSync(file, 384);
|
|
6464
|
+
}
|
|
6465
|
+
var fs26, os4, path25;
|
|
6466
|
+
var init_portal_credentials = __esm({
|
|
6467
|
+
"src/core/portal-credentials.ts"() {
|
|
6468
|
+
"use strict";
|
|
6469
|
+
fs26 = __toESM(require("fs"));
|
|
6470
|
+
os4 = __toESM(require("os"));
|
|
6471
|
+
path25 = __toESM(require("path"));
|
|
6472
|
+
}
|
|
6473
|
+
});
|
|
6474
|
+
|
|
6436
6475
|
// src/core/control-config.ts
|
|
6437
6476
|
function getControlApiUrl() {
|
|
6438
6477
|
return process.env.HAR_CONTROL_API_URL ?? DEFAULT_CONTROL_API_URL;
|
|
@@ -6440,10 +6479,33 @@ function getControlApiUrl() {
|
|
|
6440
6479
|
function isControlEnabled() {
|
|
6441
6480
|
return process.env.HAR_CONTROL_DISABLED !== "true";
|
|
6442
6481
|
}
|
|
6482
|
+
function normalizeUrl(url) {
|
|
6483
|
+
return url.replace(/\/+$/, "");
|
|
6484
|
+
}
|
|
6485
|
+
function getPortalTarget() {
|
|
6486
|
+
if (process.env.HAR_PORTAL_URL && process.env.HAR_PORTAL_TOKEN) {
|
|
6487
|
+
return {
|
|
6488
|
+
url: normalizeUrl(process.env.HAR_PORTAL_URL),
|
|
6489
|
+
token: process.env.HAR_PORTAL_TOKEN
|
|
6490
|
+
};
|
|
6491
|
+
}
|
|
6492
|
+
const stored = readPortalCredentials();
|
|
6493
|
+
if (stored) {
|
|
6494
|
+
return { url: normalizeUrl(stored.portalUrl), token: stored.token };
|
|
6495
|
+
}
|
|
6496
|
+
if (process.env.HAR_CLOUD_API_URL && process.env.HAR_CLOUD_API_KEY) {
|
|
6497
|
+
return {
|
|
6498
|
+
url: normalizeUrl(process.env.HAR_CLOUD_API_URL),
|
|
6499
|
+
token: process.env.HAR_CLOUD_API_KEY
|
|
6500
|
+
};
|
|
6501
|
+
}
|
|
6502
|
+
return null;
|
|
6503
|
+
}
|
|
6443
6504
|
var DEFAULT_CONTROL_API_URL;
|
|
6444
6505
|
var init_control_config = __esm({
|
|
6445
6506
|
"src/core/control-config.ts"() {
|
|
6446
6507
|
"use strict";
|
|
6508
|
+
init_portal_credentials();
|
|
6447
6509
|
DEFAULT_CONTROL_API_URL = "http://localhost:3847";
|
|
6448
6510
|
}
|
|
6449
6511
|
});
|
|
@@ -6451,9 +6513,9 @@ var init_control_config = __esm({
|
|
|
6451
6513
|
// src/core/telemetry-config.ts
|
|
6452
6514
|
function getPreferencePath() {
|
|
6453
6515
|
if (process.env.HAR_TELEMETRY_CONFIG_PATH) {
|
|
6454
|
-
return
|
|
6516
|
+
return path37.resolve(process.env.HAR_TELEMETRY_CONFIG_PATH);
|
|
6455
6517
|
}
|
|
6456
|
-
return
|
|
6518
|
+
return path37.join(os10.homedir(), ".har", "telemetry.json");
|
|
6457
6519
|
}
|
|
6458
6520
|
function parseEnvOverride(raw) {
|
|
6459
6521
|
if (raw === void 0 || raw === "") return void 0;
|
|
@@ -6474,10 +6536,10 @@ function normalizeSignals(enabled, raw) {
|
|
|
6474
6536
|
function readTelemetryPreference() {
|
|
6475
6537
|
const preferencePath = getPreferencePath();
|
|
6476
6538
|
try {
|
|
6477
|
-
if (!
|
|
6539
|
+
if (!fs37.existsSync(preferencePath)) {
|
|
6478
6540
|
return { enabled: true, signals: { ...DEFAULT_SIGNALS_ON } };
|
|
6479
6541
|
}
|
|
6480
|
-
const parsed = JSON.parse(
|
|
6542
|
+
const parsed = JSON.parse(fs37.readFileSync(preferencePath, "utf8"));
|
|
6481
6543
|
const enabled = parsed.enabled !== false;
|
|
6482
6544
|
return {
|
|
6483
6545
|
enabled,
|
|
@@ -6500,8 +6562,8 @@ function writeTelemetryPreference(enabled, signals2) {
|
|
|
6500
6562
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
6501
6563
|
};
|
|
6502
6564
|
const preferencePath = getPreferencePath();
|
|
6503
|
-
|
|
6504
|
-
|
|
6565
|
+
fs37.mkdirSync(path37.dirname(preferencePath), { recursive: true });
|
|
6566
|
+
fs37.writeFileSync(preferencePath, JSON.stringify(preference, null, 2) + "\n");
|
|
6505
6567
|
return preference;
|
|
6506
6568
|
}
|
|
6507
6569
|
function isTelemetryEnabled() {
|
|
@@ -6516,13 +6578,13 @@ function getTelemetrySignals() {
|
|
|
6516
6578
|
function getTelemetryPreferencePath() {
|
|
6517
6579
|
return getPreferencePath();
|
|
6518
6580
|
}
|
|
6519
|
-
var
|
|
6581
|
+
var fs37, os10, path37, DEFAULT_SIGNALS_ON, DEFAULT_SIGNALS_OFF, TELEMETRY_SIGNALS;
|
|
6520
6582
|
var init_telemetry_config = __esm({
|
|
6521
6583
|
"src/core/telemetry-config.ts"() {
|
|
6522
6584
|
"use strict";
|
|
6523
|
-
|
|
6524
|
-
|
|
6525
|
-
|
|
6585
|
+
fs37 = __toESM(require("fs"));
|
|
6586
|
+
os10 = __toESM(require("os"));
|
|
6587
|
+
path37 = __toESM(require("path"));
|
|
6526
6588
|
DEFAULT_SIGNALS_ON = {
|
|
6527
6589
|
metrics: true,
|
|
6528
6590
|
logs: true,
|
|
@@ -6563,15 +6625,15 @@ __export(otel_hooks_exports, {
|
|
|
6563
6625
|
});
|
|
6564
6626
|
function getOtelHooksHome() {
|
|
6565
6627
|
if (process.env.HAR_OTEL_HOOKS_HOME) {
|
|
6566
|
-
return
|
|
6628
|
+
return path43.resolve(process.env.HAR_OTEL_HOOKS_HOME);
|
|
6567
6629
|
}
|
|
6568
|
-
return
|
|
6630
|
+
return path43.join(os13.homedir(), ".har", "otel-hooks");
|
|
6569
6631
|
}
|
|
6570
6632
|
function getOtelHooksConfigPath(hooksHome = getOtelHooksHome()) {
|
|
6571
|
-
return
|
|
6633
|
+
return path43.join(hooksHome, "otel_config.json");
|
|
6572
6634
|
}
|
|
6573
6635
|
function getOtelHooksWrapperPath(hooksHome = getOtelHooksHome()) {
|
|
6574
|
-
return
|
|
6636
|
+
return path43.join(hooksHome, "run-otel-hook.sh");
|
|
6575
6637
|
}
|
|
6576
6638
|
function buildOtelHooksConfig(options) {
|
|
6577
6639
|
const enabled = options?.enabled ?? isTelemetryEnabled();
|
|
@@ -6590,18 +6652,18 @@ function buildOtelHooksConfig(options) {
|
|
|
6590
6652
|
};
|
|
6591
6653
|
}
|
|
6592
6654
|
function writeOtelHooksConfig(config2, hooksHome = getOtelHooksHome()) {
|
|
6593
|
-
|
|
6655
|
+
fs41.mkdirSync(hooksHome, { recursive: true });
|
|
6594
6656
|
const configPath = getOtelHooksConfigPath(hooksHome);
|
|
6595
6657
|
const payload = {
|
|
6596
6658
|
_comment: "Managed by har telemetry \u2014 do not edit by hand; use: har telemetry on|off",
|
|
6597
6659
|
...config2
|
|
6598
6660
|
};
|
|
6599
|
-
|
|
6661
|
+
fs41.writeFileSync(configPath, `${JSON.stringify(payload, null, 2)}
|
|
6600
6662
|
`);
|
|
6601
6663
|
return configPath;
|
|
6602
6664
|
}
|
|
6603
6665
|
function writeOtelHooksWrapper(otelHookCommand, hooksHome = getOtelHooksHome()) {
|
|
6604
|
-
|
|
6666
|
+
fs41.mkdirSync(hooksHome, { recursive: true });
|
|
6605
6667
|
const wrapperPath = getOtelHooksWrapperPath(hooksHome);
|
|
6606
6668
|
const script = `#!/usr/bin/env bash
|
|
6607
6669
|
# Managed by har telemetry \u2014 invokes opentelemetry-hooks with HAR config home.
|
|
@@ -6609,29 +6671,29 @@ set -euo pipefail
|
|
|
6609
6671
|
export IDE_OTEL_HOOK_HOME="${hooksHome}"
|
|
6610
6672
|
exec "${otelHookCommand}" "$@"
|
|
6611
6673
|
`;
|
|
6612
|
-
|
|
6674
|
+
fs41.writeFileSync(wrapperPath, script, { mode: 493 });
|
|
6613
6675
|
try {
|
|
6614
|
-
|
|
6676
|
+
fs41.chmodSync(wrapperPath, 493);
|
|
6615
6677
|
} catch {
|
|
6616
6678
|
}
|
|
6617
6679
|
return wrapperPath;
|
|
6618
6680
|
}
|
|
6619
|
-
function
|
|
6620
|
-
const result = (0,
|
|
6681
|
+
function commandExists2(command2) {
|
|
6682
|
+
const result = (0, import_child_process10.spawnSync)("sh", ["-c", `command -v ${JSON.stringify(command2)}`], {
|
|
6621
6683
|
encoding: "utf8"
|
|
6622
6684
|
});
|
|
6623
6685
|
return result.status === 0 && Boolean(result.stdout?.trim());
|
|
6624
6686
|
}
|
|
6625
6687
|
function resolveOtelHookCommand() {
|
|
6626
|
-
if (
|
|
6627
|
-
const which = (0,
|
|
6688
|
+
if (commandExists2("otel-hook")) {
|
|
6689
|
+
const which = (0, import_child_process10.spawnSync)("sh", ["-c", "command -v otel-hook"], { encoding: "utf8" });
|
|
6628
6690
|
return which.stdout?.trim() || "otel-hook";
|
|
6629
6691
|
}
|
|
6630
6692
|
return null;
|
|
6631
6693
|
}
|
|
6632
6694
|
function tryInstallPackage() {
|
|
6633
|
-
if (
|
|
6634
|
-
const result = (0,
|
|
6695
|
+
if (commandExists2("uv")) {
|
|
6696
|
+
const result = (0, import_child_process10.spawnSync)(
|
|
6635
6697
|
"uv",
|
|
6636
6698
|
["tool", "install", "--force", OTEL_HOOKS_PACKAGE],
|
|
6637
6699
|
{ encoding: "utf8", timeout: 18e4 }
|
|
@@ -6640,8 +6702,8 @@ function tryInstallPackage() {
|
|
|
6640
6702
|
return { ok: true, detail: `uv tool install ${OTEL_HOOKS_PACKAGE}` };
|
|
6641
6703
|
}
|
|
6642
6704
|
}
|
|
6643
|
-
if (
|
|
6644
|
-
const result = (0,
|
|
6705
|
+
if (commandExists2("pipx")) {
|
|
6706
|
+
const result = (0, import_child_process10.spawnSync)("pipx", ["install", "--force", OTEL_HOOKS_PACKAGE], {
|
|
6645
6707
|
encoding: "utf8",
|
|
6646
6708
|
timeout: 18e4
|
|
6647
6709
|
});
|
|
@@ -6653,9 +6715,9 @@ function tryInstallPackage() {
|
|
|
6653
6715
|
detail: `pipx install failed: ${(result.stderr || result.stdout || "").trim().slice(0, 400)}`
|
|
6654
6716
|
};
|
|
6655
6717
|
}
|
|
6656
|
-
if (
|
|
6657
|
-
const pip =
|
|
6658
|
-
const result = (0,
|
|
6718
|
+
if (commandExists2("pip3") || commandExists2("pip")) {
|
|
6719
|
+
const pip = commandExists2("pip3") ? "pip3" : "pip";
|
|
6720
|
+
const result = (0, import_child_process10.spawnSync)(
|
|
6659
6721
|
pip,
|
|
6660
6722
|
["install", "--user", OTEL_HOOKS_PACKAGE],
|
|
6661
6723
|
{ encoding: "utf8", timeout: 18e4 }
|
|
@@ -6674,7 +6736,7 @@ function tryInstallPackage() {
|
|
|
6674
6736
|
};
|
|
6675
6737
|
}
|
|
6676
6738
|
function runSetupAgent(agent, otelHookCommand, hooksHome) {
|
|
6677
|
-
const result = (0,
|
|
6739
|
+
const result = (0, import_child_process10.spawnSync)(otelHookCommand, ["setup", "--agent", agent], {
|
|
6678
6740
|
encoding: "utf8",
|
|
6679
6741
|
env: {
|
|
6680
6742
|
...process.env,
|
|
@@ -6691,10 +6753,10 @@ function runSetupAgent(agent, otelHookCommand, hooksHome) {
|
|
|
6691
6753
|
};
|
|
6692
6754
|
}
|
|
6693
6755
|
function rewriteHookCommandsToWrapper(filePath, wrapperPath) {
|
|
6694
|
-
if (!
|
|
6756
|
+
if (!fs41.existsSync(filePath)) return false;
|
|
6695
6757
|
let raw;
|
|
6696
6758
|
try {
|
|
6697
|
-
raw =
|
|
6759
|
+
raw = fs41.readFileSync(filePath, "utf8");
|
|
6698
6760
|
} catch {
|
|
6699
6761
|
return false;
|
|
6700
6762
|
}
|
|
@@ -6733,16 +6795,16 @@ function rewriteHookCommandsToWrapper(filePath, wrapperPath) {
|
|
|
6733
6795
|
return changed;
|
|
6734
6796
|
};
|
|
6735
6797
|
if (!walk(parsed)) return false;
|
|
6736
|
-
|
|
6798
|
+
fs41.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
|
|
6737
6799
|
`);
|
|
6738
6800
|
return true;
|
|
6739
6801
|
}
|
|
6740
6802
|
function rewriteKnownHookRegistrations(wrapperPath) {
|
|
6741
|
-
const home =
|
|
6803
|
+
const home = os13.homedir();
|
|
6742
6804
|
const candidates = [
|
|
6743
|
-
|
|
6744
|
-
|
|
6745
|
-
|
|
6805
|
+
path43.join(home, ".cursor", "hooks.json"),
|
|
6806
|
+
path43.join(home, ".claude", "settings.json"),
|
|
6807
|
+
path43.join(home, ".codex", "hooks.json")
|
|
6746
6808
|
];
|
|
6747
6809
|
for (const filePath of candidates) {
|
|
6748
6810
|
try {
|
|
@@ -6755,7 +6817,7 @@ function ensureOtelHooks(options) {
|
|
|
6755
6817
|
const hooksHome = getOtelHooksHome();
|
|
6756
6818
|
const errors = [];
|
|
6757
6819
|
const agentsSetup = [];
|
|
6758
|
-
|
|
6820
|
+
fs41.mkdirSync(hooksHome, { recursive: true });
|
|
6759
6821
|
let otelHookCommand = resolveOtelHookCommand();
|
|
6760
6822
|
if (!otelHookCommand) {
|
|
6761
6823
|
const installed = tryInstallPackage();
|
|
@@ -6824,14 +6886,14 @@ function ensureOtelHooks(options) {
|
|
|
6824
6886
|
function disableOtelHooksExport() {
|
|
6825
6887
|
return writeOtelHooksConfig(buildOtelHooksConfig({ enabled: false }));
|
|
6826
6888
|
}
|
|
6827
|
-
var
|
|
6889
|
+
var import_child_process10, fs41, os13, path43, OTEL_HOOKS_PACKAGE, OTEL_HOOKS_AGENTS;
|
|
6828
6890
|
var init_otel_hooks = __esm({
|
|
6829
6891
|
"src/core/otel-hooks.ts"() {
|
|
6830
6892
|
"use strict";
|
|
6831
|
-
|
|
6832
|
-
|
|
6833
|
-
|
|
6834
|
-
|
|
6893
|
+
import_child_process10 = require("child_process");
|
|
6894
|
+
fs41 = __toESM(require("fs"));
|
|
6895
|
+
os13 = __toESM(require("os"));
|
|
6896
|
+
path43 = __toESM(require("path"));
|
|
6835
6897
|
init_control_config();
|
|
6836
6898
|
init_telemetry_config();
|
|
6837
6899
|
OTEL_HOOKS_PACKAGE = "opentelemetry-hooks==0.14.0";
|
|
@@ -9790,7 +9852,7 @@ var require_compile = __commonJS({
|
|
|
9790
9852
|
const schOrFunc = root.refs[ref];
|
|
9791
9853
|
if (schOrFunc)
|
|
9792
9854
|
return schOrFunc;
|
|
9793
|
-
let _sch =
|
|
9855
|
+
let _sch = resolve38.call(this, root, ref);
|
|
9794
9856
|
if (_sch === void 0) {
|
|
9795
9857
|
const schema = (_a3 = root.localRefs) === null || _a3 === void 0 ? void 0 : _a3[ref];
|
|
9796
9858
|
const { schemaId } = this.opts;
|
|
@@ -9817,7 +9879,7 @@ var require_compile = __commonJS({
|
|
|
9817
9879
|
function sameSchemaEnv(s1, s2) {
|
|
9818
9880
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
9819
9881
|
}
|
|
9820
|
-
function
|
|
9882
|
+
function resolve38(root, ref) {
|
|
9821
9883
|
let sch;
|
|
9822
9884
|
while (typeof (sch = this.refs[ref]) == "string")
|
|
9823
9885
|
ref = sch;
|
|
@@ -10035,8 +10097,8 @@ var require_utils2 = __commonJS({
|
|
|
10035
10097
|
}
|
|
10036
10098
|
return ind;
|
|
10037
10099
|
}
|
|
10038
|
-
function removeDotSegments(
|
|
10039
|
-
let input =
|
|
10100
|
+
function removeDotSegments(path54) {
|
|
10101
|
+
let input = path54;
|
|
10040
10102
|
const output = [];
|
|
10041
10103
|
let nextSlash = -1;
|
|
10042
10104
|
let len = 0;
|
|
@@ -10288,8 +10350,8 @@ var require_schemes = __commonJS({
|
|
|
10288
10350
|
wsComponent.secure = void 0;
|
|
10289
10351
|
}
|
|
10290
10352
|
if (wsComponent.resourceName) {
|
|
10291
|
-
const [
|
|
10292
|
-
wsComponent.path =
|
|
10353
|
+
const [path54, query] = wsComponent.resourceName.split("?");
|
|
10354
|
+
wsComponent.path = path54 && path54 !== "/" ? path54 : void 0;
|
|
10293
10355
|
wsComponent.query = query;
|
|
10294
10356
|
wsComponent.resourceName = void 0;
|
|
10295
10357
|
}
|
|
@@ -10348,7 +10410,7 @@ var require_schemes = __commonJS({
|
|
|
10348
10410
|
urnComponent.nss = (uuidComponent.uuid || "").toLowerCase();
|
|
10349
10411
|
return urnComponent;
|
|
10350
10412
|
}
|
|
10351
|
-
var
|
|
10413
|
+
var http2 = (
|
|
10352
10414
|
/** @type {SchemeHandler} */
|
|
10353
10415
|
{
|
|
10354
10416
|
scheme: "http",
|
|
@@ -10361,7 +10423,7 @@ var require_schemes = __commonJS({
|
|
|
10361
10423
|
/** @type {SchemeHandler} */
|
|
10362
10424
|
{
|
|
10363
10425
|
scheme: "https",
|
|
10364
|
-
domainHost:
|
|
10426
|
+
domainHost: http2.domainHost,
|
|
10365
10427
|
parse: httpParse,
|
|
10366
10428
|
serialize: httpSerialize
|
|
10367
10429
|
}
|
|
@@ -10405,7 +10467,7 @@ var require_schemes = __commonJS({
|
|
|
10405
10467
|
var SCHEMES = (
|
|
10406
10468
|
/** @type {Record<SchemeName, SchemeHandler>} */
|
|
10407
10469
|
{
|
|
10408
|
-
http,
|
|
10470
|
+
http: http2,
|
|
10409
10471
|
https,
|
|
10410
10472
|
ws,
|
|
10411
10473
|
wss,
|
|
@@ -10448,7 +10510,7 @@ var require_fast_uri = __commonJS({
|
|
|
10448
10510
|
}
|
|
10449
10511
|
return uri;
|
|
10450
10512
|
}
|
|
10451
|
-
function
|
|
10513
|
+
function resolve38(baseURI, relativeURI, options) {
|
|
10452
10514
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
10453
10515
|
const resolved = resolveComponent(parse4(baseURI, schemelessOptions), parse4(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
10454
10516
|
schemelessOptions.skipEscape = true;
|
|
@@ -10706,7 +10768,7 @@ var require_fast_uri = __commonJS({
|
|
|
10706
10768
|
var fastUri = {
|
|
10707
10769
|
SCHEMES,
|
|
10708
10770
|
normalize: normalize3,
|
|
10709
|
-
resolve:
|
|
10771
|
+
resolve: resolve38,
|
|
10710
10772
|
resolveComponent,
|
|
10711
10773
|
equal,
|
|
10712
10774
|
serialize,
|
|
@@ -13682,12 +13744,12 @@ var require_dist = __commonJS({
|
|
|
13682
13744
|
throw new Error(`Unknown format "${name}"`);
|
|
13683
13745
|
return f2;
|
|
13684
13746
|
};
|
|
13685
|
-
function addFormats(ajv, list,
|
|
13747
|
+
function addFormats(ajv, list, fs46, exportName) {
|
|
13686
13748
|
var _a3;
|
|
13687
13749
|
var _b2;
|
|
13688
13750
|
(_a3 = (_b2 = ajv.opts.code).formats) !== null && _a3 !== void 0 ? _a3 : _b2.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
|
|
13689
13751
|
for (const f2 of list)
|
|
13690
|
-
ajv.addFormat(f2,
|
|
13752
|
+
ajv.addFormat(f2, fs46[f2]);
|
|
13691
13753
|
}
|
|
13692
13754
|
module2.exports = exports2 = formatsPlugin;
|
|
13693
13755
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -14787,15 +14849,15 @@ var require_route = __commonJS({
|
|
|
14787
14849
|
};
|
|
14788
14850
|
}
|
|
14789
14851
|
function wrapConversion(toModel, graph) {
|
|
14790
|
-
const
|
|
14852
|
+
const path54 = [graph[toModel].parent, toModel];
|
|
14791
14853
|
let fn = conversions[graph[toModel].parent][toModel];
|
|
14792
14854
|
let cur = graph[toModel].parent;
|
|
14793
14855
|
while (graph[cur].parent) {
|
|
14794
|
-
|
|
14856
|
+
path54.unshift(graph[cur].parent);
|
|
14795
14857
|
fn = link(conversions[graph[cur].parent][cur], fn);
|
|
14796
14858
|
cur = graph[cur].parent;
|
|
14797
14859
|
}
|
|
14798
|
-
fn.conversion =
|
|
14860
|
+
fn.conversion = path54;
|
|
14799
14861
|
return fn;
|
|
14800
14862
|
}
|
|
14801
14863
|
module2.exports = function(fromModel) {
|
|
@@ -20725,7 +20787,7 @@ var require_iso2022 = __commonJS({
|
|
|
20725
20787
|
// node_modules/chardet/index.js
|
|
20726
20788
|
var require_chardet = __commonJS({
|
|
20727
20789
|
"node_modules/chardet/index.js"(exports2, module2) {
|
|
20728
|
-
var
|
|
20790
|
+
var fs46 = require("fs");
|
|
20729
20791
|
var utf8 = require_utf8();
|
|
20730
20792
|
var unicode = require_unicode();
|
|
20731
20793
|
var mbcs = require_mbcs();
|
|
@@ -20799,28 +20861,28 @@ var require_chardet = __commonJS({
|
|
|
20799
20861
|
var fd;
|
|
20800
20862
|
var handler = function(err, buffer) {
|
|
20801
20863
|
if (fd) {
|
|
20802
|
-
|
|
20864
|
+
fs46.closeSync(fd);
|
|
20803
20865
|
}
|
|
20804
20866
|
if (err) return cb(err, null);
|
|
20805
20867
|
cb(null, self.detect(buffer, opts));
|
|
20806
20868
|
};
|
|
20807
20869
|
if (opts && opts.sampleSize) {
|
|
20808
|
-
fd =
|
|
20809
|
-
|
|
20870
|
+
fd = fs46.openSync(filepath, "r"), sample = Buffer.allocUnsafe(opts.sampleSize);
|
|
20871
|
+
fs46.read(fd, sample, 0, opts.sampleSize, null, function(err) {
|
|
20810
20872
|
handler(err, sample);
|
|
20811
20873
|
});
|
|
20812
20874
|
return;
|
|
20813
20875
|
}
|
|
20814
|
-
|
|
20876
|
+
fs46.readFile(filepath, handler);
|
|
20815
20877
|
};
|
|
20816
20878
|
module2.exports.detectFileSync = function(filepath, opts) {
|
|
20817
20879
|
if (opts && opts.sampleSize) {
|
|
20818
|
-
var fd =
|
|
20819
|
-
|
|
20820
|
-
|
|
20880
|
+
var fd = fs46.openSync(filepath, "r"), sample2 = Buffer.allocUnsafe(opts.sampleSize);
|
|
20881
|
+
fs46.readSync(fd, sample2, 0, opts.sampleSize);
|
|
20882
|
+
fs46.closeSync(fd);
|
|
20821
20883
|
return self.detect(sample2, opts);
|
|
20822
20884
|
}
|
|
20823
|
-
return self.detect(
|
|
20885
|
+
return self.detect(fs46.readFileSync(filepath), opts);
|
|
20824
20886
|
};
|
|
20825
20887
|
module2.exports.detectAll = function(buffer, opts) {
|
|
20826
20888
|
if (typeof opts !== "object") {
|
|
@@ -24285,16 +24347,16 @@ var require_os_tmpdir = __commonJS({
|
|
|
24285
24347
|
var isWindows = process.platform === "win32";
|
|
24286
24348
|
var trailingSlashRe = isWindows ? /[^:]\\$/ : /.\/$/;
|
|
24287
24349
|
module2.exports = function() {
|
|
24288
|
-
var
|
|
24350
|
+
var path54;
|
|
24289
24351
|
if (isWindows) {
|
|
24290
|
-
|
|
24352
|
+
path54 = process.env.TEMP || process.env.TMP || (process.env.SystemRoot || process.env.windir) + "\\temp";
|
|
24291
24353
|
} else {
|
|
24292
|
-
|
|
24354
|
+
path54 = process.env.TMPDIR || process.env.TMP || process.env.TEMP || "/tmp";
|
|
24293
24355
|
}
|
|
24294
|
-
if (trailingSlashRe.test(
|
|
24295
|
-
|
|
24356
|
+
if (trailingSlashRe.test(path54)) {
|
|
24357
|
+
path54 = path54.slice(0, -1);
|
|
24296
24358
|
}
|
|
24297
|
-
return
|
|
24359
|
+
return path54;
|
|
24298
24360
|
};
|
|
24299
24361
|
}
|
|
24300
24362
|
});
|
|
@@ -24302,8 +24364,8 @@ var require_os_tmpdir = __commonJS({
|
|
|
24302
24364
|
// node_modules/tmp/lib/tmp.js
|
|
24303
24365
|
var require_tmp = __commonJS({
|
|
24304
24366
|
"node_modules/tmp/lib/tmp.js"(exports2, module2) {
|
|
24305
|
-
var
|
|
24306
|
-
var
|
|
24367
|
+
var fs46 = require("fs");
|
|
24368
|
+
var path54 = require("path");
|
|
24307
24369
|
var crypto6 = require("crypto");
|
|
24308
24370
|
var osTmpDir = require_os_tmpdir();
|
|
24309
24371
|
var _c2 = process.binding("constants");
|
|
@@ -24345,7 +24407,7 @@ var require_tmp = __commonJS({
|
|
|
24345
24407
|
}
|
|
24346
24408
|
function _generateTmpName(opts) {
|
|
24347
24409
|
if (opts.name) {
|
|
24348
|
-
return
|
|
24410
|
+
return path54.join(opts.dir || tmpDir, opts.name);
|
|
24349
24411
|
}
|
|
24350
24412
|
if (opts.template) {
|
|
24351
24413
|
return opts.template.replace(TEMPLATE_PATTERN, _randomChars(6));
|
|
@@ -24356,7 +24418,7 @@ var require_tmp = __commonJS({
|
|
|
24356
24418
|
_randomChars(12),
|
|
24357
24419
|
opts.postfix || ""
|
|
24358
24420
|
].join("");
|
|
24359
|
-
return
|
|
24421
|
+
return path54.join(opts.dir || tmpDir, name);
|
|
24360
24422
|
}
|
|
24361
24423
|
function tmpName(options, callback) {
|
|
24362
24424
|
var args = _parseArguments(options, callback), opts = args[0], cb = args[1], tries = opts.name ? 1 : opts.tries || DEFAULT_TRIES;
|
|
@@ -24366,7 +24428,7 @@ var require_tmp = __commonJS({
|
|
|
24366
24428
|
return cb(new Error("Invalid template provided"));
|
|
24367
24429
|
(function _getUniqueName() {
|
|
24368
24430
|
const name = _generateTmpName(opts);
|
|
24369
|
-
|
|
24431
|
+
fs46.stat(name, function(err) {
|
|
24370
24432
|
if (!err) {
|
|
24371
24433
|
if (tries-- > 0) return _getUniqueName();
|
|
24372
24434
|
return cb(new Error("Could not get a unique tmp filename, max tries reached " + name));
|
|
@@ -24384,7 +24446,7 @@ var require_tmp = __commonJS({
|
|
|
24384
24446
|
do {
|
|
24385
24447
|
const name = _generateTmpName(opts);
|
|
24386
24448
|
try {
|
|
24387
|
-
|
|
24449
|
+
fs46.statSync(name);
|
|
24388
24450
|
} catch (e2) {
|
|
24389
24451
|
return name;
|
|
24390
24452
|
}
|
|
@@ -24396,13 +24458,13 @@ var require_tmp = __commonJS({
|
|
|
24396
24458
|
opts.postfix = _isUndefined(opts.postfix) ? ".tmp" : opts.postfix;
|
|
24397
24459
|
tmpName(opts, function _tmpNameCreated(err, name) {
|
|
24398
24460
|
if (err) return cb(err);
|
|
24399
|
-
|
|
24461
|
+
fs46.open(name, CREATE_FLAGS, opts.mode || FILE_MODE, function _fileCreated(err2, fd) {
|
|
24400
24462
|
if (err2) return cb(err2);
|
|
24401
24463
|
if (opts.discardDescriptor) {
|
|
24402
|
-
return
|
|
24464
|
+
return fs46.close(fd, function _discardCallback(err3) {
|
|
24403
24465
|
if (err3) {
|
|
24404
24466
|
try {
|
|
24405
|
-
|
|
24467
|
+
fs46.unlinkSync(name);
|
|
24406
24468
|
} catch (e2) {
|
|
24407
24469
|
if (!isENOENT(e2)) {
|
|
24408
24470
|
err3 = e2;
|
|
@@ -24425,9 +24487,9 @@ var require_tmp = __commonJS({
|
|
|
24425
24487
|
opts.postfix = opts.postfix || ".tmp";
|
|
24426
24488
|
const discardOrDetachDescriptor = opts.discardDescriptor || opts.detachDescriptor;
|
|
24427
24489
|
const name = tmpNameSync(opts);
|
|
24428
|
-
var fd =
|
|
24490
|
+
var fd = fs46.openSync(name, CREATE_FLAGS, opts.mode || FILE_MODE);
|
|
24429
24491
|
if (opts.discardDescriptor) {
|
|
24430
|
-
|
|
24492
|
+
fs46.closeSync(fd);
|
|
24431
24493
|
fd = void 0;
|
|
24432
24494
|
}
|
|
24433
24495
|
return {
|
|
@@ -24439,9 +24501,9 @@ var require_tmp = __commonJS({
|
|
|
24439
24501
|
function _rmdirRecursiveSync(root) {
|
|
24440
24502
|
const dirs = [root];
|
|
24441
24503
|
do {
|
|
24442
|
-
var dir2 = dirs.pop(), deferred = false, files =
|
|
24504
|
+
var dir2 = dirs.pop(), deferred = false, files = fs46.readdirSync(dir2);
|
|
24443
24505
|
for (var i2 = 0, length = files.length; i2 < length; i2++) {
|
|
24444
|
-
var file2 =
|
|
24506
|
+
var file2 = path54.join(dir2, files[i2]), stat = fs46.lstatSync(file2);
|
|
24445
24507
|
if (stat.isDirectory()) {
|
|
24446
24508
|
if (!deferred) {
|
|
24447
24509
|
deferred = true;
|
|
@@ -24449,11 +24511,11 @@ var require_tmp = __commonJS({
|
|
|
24449
24511
|
}
|
|
24450
24512
|
dirs.push(file2);
|
|
24451
24513
|
} else {
|
|
24452
|
-
|
|
24514
|
+
fs46.unlinkSync(file2);
|
|
24453
24515
|
}
|
|
24454
24516
|
}
|
|
24455
24517
|
if (!deferred) {
|
|
24456
|
-
|
|
24518
|
+
fs46.rmdirSync(dir2);
|
|
24457
24519
|
}
|
|
24458
24520
|
} while (dirs.length !== 0);
|
|
24459
24521
|
}
|
|
@@ -24461,7 +24523,7 @@ var require_tmp = __commonJS({
|
|
|
24461
24523
|
var args = _parseArguments(options, callback), opts = args[0], cb = args[1];
|
|
24462
24524
|
tmpName(opts, function _tmpNameCreated(err, name) {
|
|
24463
24525
|
if (err) return cb(err);
|
|
24464
|
-
|
|
24526
|
+
fs46.mkdir(name, opts.mode || DIR_MODE, function _dirCreated(err2) {
|
|
24465
24527
|
if (err2) return cb(err2);
|
|
24466
24528
|
cb(null, name, _prepareTmpDirRemoveCallback(name, opts));
|
|
24467
24529
|
});
|
|
@@ -24470,7 +24532,7 @@ var require_tmp = __commonJS({
|
|
|
24470
24532
|
function dirSync(options) {
|
|
24471
24533
|
var args = _parseArguments(options), opts = args[0];
|
|
24472
24534
|
const name = tmpNameSync(opts);
|
|
24473
|
-
|
|
24535
|
+
fs46.mkdirSync(name, opts.mode || DIR_MODE);
|
|
24474
24536
|
return {
|
|
24475
24537
|
name,
|
|
24476
24538
|
removeCallback: _prepareTmpDirRemoveCallback(name, opts)
|
|
@@ -24480,7 +24542,7 @@ var require_tmp = __commonJS({
|
|
|
24480
24542
|
const removeCallback = _prepareRemoveCallback(function _removeCallback(fdPath) {
|
|
24481
24543
|
try {
|
|
24482
24544
|
if (0 <= fdPath[0]) {
|
|
24483
|
-
|
|
24545
|
+
fs46.closeSync(fdPath[0]);
|
|
24484
24546
|
}
|
|
24485
24547
|
} catch (e2) {
|
|
24486
24548
|
if (!isEBADF(e2) && !isENOENT(e2)) {
|
|
@@ -24488,7 +24550,7 @@ var require_tmp = __commonJS({
|
|
|
24488
24550
|
}
|
|
24489
24551
|
}
|
|
24490
24552
|
try {
|
|
24491
|
-
|
|
24553
|
+
fs46.unlinkSync(fdPath[1]);
|
|
24492
24554
|
} catch (e2) {
|
|
24493
24555
|
if (!isENOENT(e2)) {
|
|
24494
24556
|
throw e2;
|
|
@@ -24501,7 +24563,7 @@ var require_tmp = __commonJS({
|
|
|
24501
24563
|
return removeCallback;
|
|
24502
24564
|
}
|
|
24503
24565
|
function _prepareTmpDirRemoveCallback(name, opts) {
|
|
24504
|
-
const removeFunction = opts.unsafeCleanup ? _rmdirRecursiveSync :
|
|
24566
|
+
const removeFunction = opts.unsafeCleanup ? _rmdirRecursiveSync : fs46.rmdirSync.bind(fs46);
|
|
24505
24567
|
const removeCallback = _prepareRemoveCallback(removeFunction, name);
|
|
24506
24568
|
if (!opts.keep) {
|
|
24507
24569
|
_removeObjects.unshift(removeCallback);
|
|
@@ -25652,7 +25714,7 @@ var require_Observable = __commonJS({
|
|
|
25652
25714
|
Observable2.prototype.forEach = function(next, promiseCtor) {
|
|
25653
25715
|
var _this = this;
|
|
25654
25716
|
promiseCtor = getPromiseCtor(promiseCtor);
|
|
25655
|
-
return new promiseCtor(function(
|
|
25717
|
+
return new promiseCtor(function(resolve38, reject) {
|
|
25656
25718
|
var subscriber = new Subscriber_1.SafeSubscriber({
|
|
25657
25719
|
next: function(value) {
|
|
25658
25720
|
try {
|
|
@@ -25663,7 +25725,7 @@ var require_Observable = __commonJS({
|
|
|
25663
25725
|
}
|
|
25664
25726
|
},
|
|
25665
25727
|
error: reject,
|
|
25666
|
-
complete:
|
|
25728
|
+
complete: resolve38
|
|
25667
25729
|
});
|
|
25668
25730
|
_this.subscribe(subscriber);
|
|
25669
25731
|
});
|
|
@@ -25685,14 +25747,14 @@ var require_Observable = __commonJS({
|
|
|
25685
25747
|
Observable2.prototype.toPromise = function(promiseCtor) {
|
|
25686
25748
|
var _this = this;
|
|
25687
25749
|
promiseCtor = getPromiseCtor(promiseCtor);
|
|
25688
|
-
return new promiseCtor(function(
|
|
25750
|
+
return new promiseCtor(function(resolve38, reject) {
|
|
25689
25751
|
var value;
|
|
25690
25752
|
_this.subscribe(function(x2) {
|
|
25691
25753
|
return value = x2;
|
|
25692
25754
|
}, function(err) {
|
|
25693
25755
|
return reject(err);
|
|
25694
25756
|
}, function() {
|
|
25695
|
-
return
|
|
25757
|
+
return resolve38(value);
|
|
25696
25758
|
});
|
|
25697
25759
|
});
|
|
25698
25760
|
};
|
|
@@ -27788,11 +27850,11 @@ var require_innerFrom = __commonJS({
|
|
|
27788
27850
|
"use strict";
|
|
27789
27851
|
var __awaiter = exports2 && exports2.__awaiter || function(thisArg, _arguments, P2, generator) {
|
|
27790
27852
|
function adopt(value) {
|
|
27791
|
-
return value instanceof P2 ? value : new P2(function(
|
|
27792
|
-
|
|
27853
|
+
return value instanceof P2 ? value : new P2(function(resolve38) {
|
|
27854
|
+
resolve38(value);
|
|
27793
27855
|
});
|
|
27794
27856
|
}
|
|
27795
|
-
return new (P2 || (P2 = Promise))(function(
|
|
27857
|
+
return new (P2 || (P2 = Promise))(function(resolve38, reject) {
|
|
27796
27858
|
function fulfilled(value) {
|
|
27797
27859
|
try {
|
|
27798
27860
|
step(generator.next(value));
|
|
@@ -27808,7 +27870,7 @@ var require_innerFrom = __commonJS({
|
|
|
27808
27870
|
}
|
|
27809
27871
|
}
|
|
27810
27872
|
function step(result) {
|
|
27811
|
-
result.done ?
|
|
27873
|
+
result.done ? resolve38(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
27812
27874
|
}
|
|
27813
27875
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
27814
27876
|
});
|
|
@@ -27890,14 +27952,14 @@ var require_innerFrom = __commonJS({
|
|
|
27890
27952
|
}, i2);
|
|
27891
27953
|
function verb(n2) {
|
|
27892
27954
|
i2[n2] = o2[n2] && function(v2) {
|
|
27893
|
-
return new Promise(function(
|
|
27894
|
-
v2 = o2[n2](v2), settle(
|
|
27955
|
+
return new Promise(function(resolve38, reject) {
|
|
27956
|
+
v2 = o2[n2](v2), settle(resolve38, reject, v2.done, v2.value);
|
|
27895
27957
|
});
|
|
27896
27958
|
};
|
|
27897
27959
|
}
|
|
27898
|
-
function settle(
|
|
27960
|
+
function settle(resolve38, reject, d2, v2) {
|
|
27899
27961
|
Promise.resolve(v2).then(function(v3) {
|
|
27900
|
-
|
|
27962
|
+
resolve38({ value: v3, done: d2 });
|
|
27901
27963
|
}, reject);
|
|
27902
27964
|
}
|
|
27903
27965
|
};
|
|
@@ -28516,7 +28578,7 @@ var require_lastValueFrom = __commonJS({
|
|
|
28516
28578
|
var EmptyError_1 = require_EmptyError();
|
|
28517
28579
|
function lastValueFrom2(source, config2) {
|
|
28518
28580
|
var hasConfig = typeof config2 === "object";
|
|
28519
|
-
return new Promise(function(
|
|
28581
|
+
return new Promise(function(resolve38, reject) {
|
|
28520
28582
|
var _hasValue = false;
|
|
28521
28583
|
var _value;
|
|
28522
28584
|
source.subscribe({
|
|
@@ -28527,9 +28589,9 @@ var require_lastValueFrom = __commonJS({
|
|
|
28527
28589
|
error: reject,
|
|
28528
28590
|
complete: function() {
|
|
28529
28591
|
if (_hasValue) {
|
|
28530
|
-
|
|
28592
|
+
resolve38(_value);
|
|
28531
28593
|
} else if (hasConfig) {
|
|
28532
|
-
|
|
28594
|
+
resolve38(config2.defaultValue);
|
|
28533
28595
|
} else {
|
|
28534
28596
|
reject(new EmptyError_1.EmptyError());
|
|
28535
28597
|
}
|
|
@@ -28551,16 +28613,16 @@ var require_firstValueFrom = __commonJS({
|
|
|
28551
28613
|
var Subscriber_1 = require_Subscriber();
|
|
28552
28614
|
function firstValueFrom(source, config2) {
|
|
28553
28615
|
var hasConfig = typeof config2 === "object";
|
|
28554
|
-
return new Promise(function(
|
|
28616
|
+
return new Promise(function(resolve38, reject) {
|
|
28555
28617
|
var subscriber = new Subscriber_1.SafeSubscriber({
|
|
28556
28618
|
next: function(value) {
|
|
28557
|
-
|
|
28619
|
+
resolve38(value);
|
|
28558
28620
|
subscriber.unsubscribe();
|
|
28559
28621
|
},
|
|
28560
28622
|
error: reject,
|
|
28561
28623
|
complete: function() {
|
|
28562
28624
|
if (hasConfig) {
|
|
28563
|
-
|
|
28625
|
+
resolve38(config2.defaultValue);
|
|
28564
28626
|
} else {
|
|
28565
28627
|
reject(new EmptyError_1.EmptyError());
|
|
28566
28628
|
}
|
|
@@ -34353,14 +34415,14 @@ var require_run_async = __commonJS({
|
|
|
34353
34415
|
return function() {
|
|
34354
34416
|
var args = arguments;
|
|
34355
34417
|
var originalThis = this;
|
|
34356
|
-
var promise = new Promise(function(
|
|
34418
|
+
var promise = new Promise(function(resolve38, reject) {
|
|
34357
34419
|
var resolved = false;
|
|
34358
34420
|
const wrappedResolve = function(value) {
|
|
34359
34421
|
if (resolved) {
|
|
34360
34422
|
console.warn("Run-async promise already resolved.");
|
|
34361
34423
|
}
|
|
34362
34424
|
resolved = true;
|
|
34363
|
-
|
|
34425
|
+
resolve38(value);
|
|
34364
34426
|
};
|
|
34365
34427
|
var rejected = false;
|
|
34366
34428
|
const wrappedReject = function(value) {
|
|
@@ -35714,11 +35776,11 @@ var parser = new YargsParser({
|
|
|
35714
35776
|
resolve: import_path2.resolve,
|
|
35715
35777
|
// TODO: figure out a way to combine ESM and CJS coverage, such that
|
|
35716
35778
|
// we can exercise all the lines below:
|
|
35717
|
-
require: (
|
|
35779
|
+
require: (path54) => {
|
|
35718
35780
|
if (typeof require !== "undefined") {
|
|
35719
|
-
return require(
|
|
35720
|
-
} else if (
|
|
35721
|
-
return JSON.parse((0, import_fs2.readFileSync)(
|
|
35781
|
+
return require(path54);
|
|
35782
|
+
} else if (path54.match(/\.json$/)) {
|
|
35783
|
+
return JSON.parse((0, import_fs2.readFileSync)(path54, "utf8"));
|
|
35722
35784
|
} else {
|
|
35723
35785
|
throw Error("only .json config files are supported in ESM");
|
|
35724
35786
|
}
|
|
@@ -38244,12 +38306,12 @@ var YargsInstance = class {
|
|
|
38244
38306
|
async getCompletion(args, done) {
|
|
38245
38307
|
argsert("<array> [function]", [args, done], arguments.length);
|
|
38246
38308
|
if (!done) {
|
|
38247
|
-
return new Promise((
|
|
38309
|
+
return new Promise((resolve38, reject) => {
|
|
38248
38310
|
__classPrivateFieldGet(this, _YargsInstance_completion, "f").getCompletion(args, (err, completions) => {
|
|
38249
38311
|
if (err)
|
|
38250
38312
|
reject(err);
|
|
38251
38313
|
else
|
|
38252
|
-
|
|
38314
|
+
resolve38(completions);
|
|
38253
38315
|
});
|
|
38254
38316
|
});
|
|
38255
38317
|
} else {
|
|
@@ -40399,8 +40461,8 @@ function getErrorMap() {
|
|
|
40399
40461
|
|
|
40400
40462
|
// node_modules/zod/v3/helpers/parseUtil.js
|
|
40401
40463
|
var makeIssue = (params) => {
|
|
40402
|
-
const { data, path:
|
|
40403
|
-
const fullPath = [...
|
|
40464
|
+
const { data, path: path54, errorMaps, issueData } = params;
|
|
40465
|
+
const fullPath = [...path54, ...issueData.path || []];
|
|
40404
40466
|
const fullIssue = {
|
|
40405
40467
|
...issueData,
|
|
40406
40468
|
path: fullPath
|
|
@@ -40516,11 +40578,11 @@ var errorUtil;
|
|
|
40516
40578
|
|
|
40517
40579
|
// node_modules/zod/v3/types.js
|
|
40518
40580
|
var ParseInputLazyPath = class {
|
|
40519
|
-
constructor(parent, value,
|
|
40581
|
+
constructor(parent, value, path54, key) {
|
|
40520
40582
|
this._cachedPath = [];
|
|
40521
40583
|
this.parent = parent;
|
|
40522
40584
|
this.data = value;
|
|
40523
|
-
this._path =
|
|
40585
|
+
this._path = path54;
|
|
40524
40586
|
this._key = key;
|
|
40525
40587
|
}
|
|
40526
40588
|
get path() {
|
|
@@ -44659,16 +44721,16 @@ async function handleAgentSkills(options) {
|
|
|
44659
44721
|
}
|
|
44660
44722
|
async function askYesNo(question) {
|
|
44661
44723
|
const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
|
|
44662
|
-
return new Promise((
|
|
44724
|
+
return new Promise((resolve38) => {
|
|
44663
44725
|
process.stderr.write(`${question} `);
|
|
44664
44726
|
rl.once("line", (answer) => {
|
|
44665
44727
|
rl.close();
|
|
44666
44728
|
const trimmed = answer.trim();
|
|
44667
44729
|
if (trimmed === "") {
|
|
44668
|
-
|
|
44730
|
+
resolve38(true);
|
|
44669
44731
|
return;
|
|
44670
44732
|
}
|
|
44671
|
-
|
|
44733
|
+
resolve38(/^y(es)?$/i.test(trimmed));
|
|
44672
44734
|
});
|
|
44673
44735
|
});
|
|
44674
44736
|
}
|
|
@@ -44747,7 +44809,7 @@ function handleRemove(argv) {
|
|
|
44747
44809
|
}
|
|
44748
44810
|
|
|
44749
44811
|
// src/cli/commands/env.ts
|
|
44750
|
-
var
|
|
44812
|
+
var path47 = __toESM(require("path"));
|
|
44751
44813
|
|
|
44752
44814
|
// src/core/harness.ts
|
|
44753
44815
|
var fs20 = __toESM(require("fs"));
|
|
@@ -45526,13 +45588,13 @@ var MultipartBody = class {
|
|
|
45526
45588
|
// node_modules/@anthropic-ai/sdk/_shims/node-runtime.mjs
|
|
45527
45589
|
var import_web = require("node:stream/web");
|
|
45528
45590
|
var fileFromPathWarned = false;
|
|
45529
|
-
async function fileFromPath3(
|
|
45591
|
+
async function fileFromPath3(path54, ...args) {
|
|
45530
45592
|
const { fileFromPath: _fileFromPath } = await Promise.resolve().then(() => (init_fileFromPath(), fileFromPath_exports));
|
|
45531
45593
|
if (!fileFromPathWarned) {
|
|
45532
|
-
console.warn(`fileFromPath is deprecated; use fs.createReadStream(${JSON.stringify(
|
|
45594
|
+
console.warn(`fileFromPath is deprecated; use fs.createReadStream(${JSON.stringify(path54)}) instead`);
|
|
45533
45595
|
fileFromPathWarned = true;
|
|
45534
45596
|
}
|
|
45535
|
-
return await _fileFromPath(
|
|
45597
|
+
return await _fileFromPath(path54, ...args);
|
|
45536
45598
|
}
|
|
45537
45599
|
var defaultHttpAgent = new import_agentkeepalive.default({ keepAlive: true, timeout: 5 * 60 * 1e3 });
|
|
45538
45600
|
var defaultHttpsAgent = new import_agentkeepalive.default.HttpsAgent({ keepAlive: true, timeout: 5 * 60 * 1e3 });
|
|
@@ -46028,8 +46090,8 @@ async function defaultParseResponse(props) {
|
|
|
46028
46090
|
}
|
|
46029
46091
|
var APIPromise = class _APIPromise extends Promise {
|
|
46030
46092
|
constructor(responsePromise, parseResponse = defaultParseResponse) {
|
|
46031
|
-
super((
|
|
46032
|
-
|
|
46093
|
+
super((resolve38) => {
|
|
46094
|
+
resolve38(null);
|
|
46033
46095
|
});
|
|
46034
46096
|
this.responsePromise = responsePromise;
|
|
46035
46097
|
this.parseResponse = parseResponse;
|
|
@@ -46129,29 +46191,29 @@ var APIClient = class {
|
|
|
46129
46191
|
defaultIdempotencyKey() {
|
|
46130
46192
|
return `stainless-node-retry-${uuid4()}`;
|
|
46131
46193
|
}
|
|
46132
|
-
get(
|
|
46133
|
-
return this.methodRequest("get",
|
|
46194
|
+
get(path54, opts) {
|
|
46195
|
+
return this.methodRequest("get", path54, opts);
|
|
46134
46196
|
}
|
|
46135
|
-
post(
|
|
46136
|
-
return this.methodRequest("post",
|
|
46197
|
+
post(path54, opts) {
|
|
46198
|
+
return this.methodRequest("post", path54, opts);
|
|
46137
46199
|
}
|
|
46138
|
-
patch(
|
|
46139
|
-
return this.methodRequest("patch",
|
|
46200
|
+
patch(path54, opts) {
|
|
46201
|
+
return this.methodRequest("patch", path54, opts);
|
|
46140
46202
|
}
|
|
46141
|
-
put(
|
|
46142
|
-
return this.methodRequest("put",
|
|
46203
|
+
put(path54, opts) {
|
|
46204
|
+
return this.methodRequest("put", path54, opts);
|
|
46143
46205
|
}
|
|
46144
|
-
delete(
|
|
46145
|
-
return this.methodRequest("delete",
|
|
46206
|
+
delete(path54, opts) {
|
|
46207
|
+
return this.methodRequest("delete", path54, opts);
|
|
46146
46208
|
}
|
|
46147
|
-
methodRequest(method,
|
|
46209
|
+
methodRequest(method, path54, opts) {
|
|
46148
46210
|
return this.request(Promise.resolve(opts).then(async (opts2) => {
|
|
46149
46211
|
const body = opts2 && isBlobLike(opts2?.body) ? new DataView(await opts2.body.arrayBuffer()) : opts2?.body instanceof DataView ? opts2.body : opts2?.body instanceof ArrayBuffer ? new DataView(opts2.body) : opts2 && ArrayBuffer.isView(opts2?.body) ? new DataView(opts2.body.buffer) : opts2?.body;
|
|
46150
|
-
return { method, path:
|
|
46212
|
+
return { method, path: path54, ...opts2, body };
|
|
46151
46213
|
}));
|
|
46152
46214
|
}
|
|
46153
|
-
getAPIList(
|
|
46154
|
-
return this.requestAPIList(Page, { method: "get", path:
|
|
46215
|
+
getAPIList(path54, Page, opts) {
|
|
46216
|
+
return this.requestAPIList(Page, { method: "get", path: path54, ...opts });
|
|
46155
46217
|
}
|
|
46156
46218
|
calculateContentLength(body) {
|
|
46157
46219
|
if (typeof body === "string") {
|
|
@@ -46169,10 +46231,10 @@ var APIClient = class {
|
|
|
46169
46231
|
return null;
|
|
46170
46232
|
}
|
|
46171
46233
|
buildRequest(options) {
|
|
46172
|
-
const { method, path:
|
|
46234
|
+
const { method, path: path54, query, headers = {} } = options;
|
|
46173
46235
|
const body = ArrayBuffer.isView(options.body) || options.__binaryRequest && typeof options.body === "string" ? options.body : isMultipartBody(options.body) ? options.body.body : options.body ? JSON.stringify(options.body, null, 2) : null;
|
|
46174
46236
|
const contentLength = this.calculateContentLength(body);
|
|
46175
|
-
const url = this.buildURL(
|
|
46237
|
+
const url = this.buildURL(path54, query);
|
|
46176
46238
|
if ("timeout" in options)
|
|
46177
46239
|
validatePositiveInteger("timeout", options.timeout);
|
|
46178
46240
|
const timeout = options.timeout ?? this.timeout;
|
|
@@ -46281,8 +46343,8 @@ var APIClient = class {
|
|
|
46281
46343
|
const request = this.makeRequest(options, null);
|
|
46282
46344
|
return new PagePromise(this, request, Page);
|
|
46283
46345
|
}
|
|
46284
|
-
buildURL(
|
|
46285
|
-
const url = isAbsoluteURL(
|
|
46346
|
+
buildURL(path54, query) {
|
|
46347
|
+
const url = isAbsoluteURL(path54) ? new URL(path54) : new URL(this.baseURL + (this.baseURL.endsWith("/") && path54.startsWith("/") ? path54.slice(1) : path54));
|
|
46286
46348
|
const defaultQuery = this.defaultQuery();
|
|
46287
46349
|
if (!isEmptyObj(defaultQuery)) {
|
|
46288
46350
|
query = { ...defaultQuery, ...query };
|
|
@@ -46567,7 +46629,7 @@ var startsWithSchemeRegexp = new RegExp("^(?:[a-z]+:)?//", "i");
|
|
|
46567
46629
|
var isAbsoluteURL = (url) => {
|
|
46568
46630
|
return startsWithSchemeRegexp.test(url);
|
|
46569
46631
|
};
|
|
46570
|
-
var sleep = (ms) => new Promise((
|
|
46632
|
+
var sleep = (ms) => new Promise((resolve38) => setTimeout(resolve38, ms));
|
|
46571
46633
|
var validatePositiveInteger = (name, n2) => {
|
|
46572
46634
|
if (typeof n2 !== "number" || !Number.isInteger(n2)) {
|
|
46573
46635
|
throw new AnthropicError(`${name} must be an integer`);
|
|
@@ -47058,12 +47120,12 @@ var PromptCachingBetaMessageStream = class _PromptCachingBetaMessageStream {
|
|
|
47058
47120
|
}
|
|
47059
47121
|
return this._emit("error", new AnthropicError(String(error3)));
|
|
47060
47122
|
});
|
|
47061
|
-
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_connectedPromise, new Promise((
|
|
47062
|
-
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_resolveConnectedPromise,
|
|
47123
|
+
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_connectedPromise, new Promise((resolve38, reject) => {
|
|
47124
|
+
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_resolveConnectedPromise, resolve38, "f");
|
|
47063
47125
|
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_rejectConnectedPromise, reject, "f");
|
|
47064
47126
|
}), "f");
|
|
47065
|
-
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_endPromise, new Promise((
|
|
47066
|
-
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_resolveEndPromise,
|
|
47127
|
+
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_endPromise, new Promise((resolve38, reject) => {
|
|
47128
|
+
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_resolveEndPromise, resolve38, "f");
|
|
47067
47129
|
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_rejectEndPromise, reject, "f");
|
|
47068
47130
|
}), "f");
|
|
47069
47131
|
__classPrivateFieldGet8(this, _PromptCachingBetaMessageStream_connectedPromise, "f").catch(() => {
|
|
@@ -47192,11 +47254,11 @@ var PromptCachingBetaMessageStream = class _PromptCachingBetaMessageStream {
|
|
|
47192
47254
|
* const message = await stream.emitted('message') // rejects if the stream errors
|
|
47193
47255
|
*/
|
|
47194
47256
|
emitted(event) {
|
|
47195
|
-
return new Promise((
|
|
47257
|
+
return new Promise((resolve38, reject) => {
|
|
47196
47258
|
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_catchingPromiseCreated, true, "f");
|
|
47197
47259
|
if (event !== "error")
|
|
47198
47260
|
this.once("error", reject);
|
|
47199
|
-
this.once(event,
|
|
47261
|
+
this.once(event, resolve38);
|
|
47200
47262
|
});
|
|
47201
47263
|
}
|
|
47202
47264
|
async done() {
|
|
@@ -47423,7 +47485,7 @@ var PromptCachingBetaMessageStream = class _PromptCachingBetaMessageStream {
|
|
|
47423
47485
|
if (done) {
|
|
47424
47486
|
return { value: void 0, done: true };
|
|
47425
47487
|
}
|
|
47426
|
-
return new Promise((
|
|
47488
|
+
return new Promise((resolve38, reject) => readQueue.push({ resolve: resolve38, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
|
|
47427
47489
|
}
|
|
47428
47490
|
const chunk = pushQueue.shift();
|
|
47429
47491
|
return { value: chunk, done: false };
|
|
@@ -47571,12 +47633,12 @@ var MessageStream = class _MessageStream {
|
|
|
47571
47633
|
}
|
|
47572
47634
|
return this._emit("error", new AnthropicError(String(error3)));
|
|
47573
47635
|
});
|
|
47574
|
-
__classPrivateFieldSet8(this, _MessageStream_connectedPromise, new Promise((
|
|
47575
|
-
__classPrivateFieldSet8(this, _MessageStream_resolveConnectedPromise,
|
|
47636
|
+
__classPrivateFieldSet8(this, _MessageStream_connectedPromise, new Promise((resolve38, reject) => {
|
|
47637
|
+
__classPrivateFieldSet8(this, _MessageStream_resolveConnectedPromise, resolve38, "f");
|
|
47576
47638
|
__classPrivateFieldSet8(this, _MessageStream_rejectConnectedPromise, reject, "f");
|
|
47577
47639
|
}), "f");
|
|
47578
|
-
__classPrivateFieldSet8(this, _MessageStream_endPromise, new Promise((
|
|
47579
|
-
__classPrivateFieldSet8(this, _MessageStream_resolveEndPromise,
|
|
47640
|
+
__classPrivateFieldSet8(this, _MessageStream_endPromise, new Promise((resolve38, reject) => {
|
|
47641
|
+
__classPrivateFieldSet8(this, _MessageStream_resolveEndPromise, resolve38, "f");
|
|
47580
47642
|
__classPrivateFieldSet8(this, _MessageStream_rejectEndPromise, reject, "f");
|
|
47581
47643
|
}), "f");
|
|
47582
47644
|
__classPrivateFieldGet9(this, _MessageStream_connectedPromise, "f").catch(() => {
|
|
@@ -47705,11 +47767,11 @@ var MessageStream = class _MessageStream {
|
|
|
47705
47767
|
* const message = await stream.emitted('message') // rejects if the stream errors
|
|
47706
47768
|
*/
|
|
47707
47769
|
emitted(event) {
|
|
47708
|
-
return new Promise((
|
|
47770
|
+
return new Promise((resolve38, reject) => {
|
|
47709
47771
|
__classPrivateFieldSet8(this, _MessageStream_catchingPromiseCreated, true, "f");
|
|
47710
47772
|
if (event !== "error")
|
|
47711
47773
|
this.once("error", reject);
|
|
47712
|
-
this.once(event,
|
|
47774
|
+
this.once(event, resolve38);
|
|
47713
47775
|
});
|
|
47714
47776
|
}
|
|
47715
47777
|
async done() {
|
|
@@ -47936,7 +47998,7 @@ var MessageStream = class _MessageStream {
|
|
|
47936
47998
|
if (done) {
|
|
47937
47999
|
return { value: void 0, done: true };
|
|
47938
48000
|
}
|
|
47939
|
-
return new Promise((
|
|
48001
|
+
return new Promise((resolve38, reject) => readQueue.push({ resolve: resolve38, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
|
|
47940
48002
|
}
|
|
47941
48003
|
const chunk = pushQueue.shift();
|
|
47942
48004
|
return { value: chunk, done: false };
|
|
@@ -48196,11 +48258,11 @@ async function promptApplyAgentMdProposal(repoPath) {
|
|
|
48196
48258
|
}
|
|
48197
48259
|
async function askYesNo2(question) {
|
|
48198
48260
|
const rl = readline2.createInterface({ input: process.stdin, output: process.stderr });
|
|
48199
|
-
return new Promise((
|
|
48261
|
+
return new Promise((resolve38) => {
|
|
48200
48262
|
process.stderr.write(`${question} `);
|
|
48201
48263
|
rl.once("line", (answer) => {
|
|
48202
48264
|
rl.close();
|
|
48203
|
-
|
|
48265
|
+
resolve38(/^y(es)?$/i.test(answer.trim()));
|
|
48204
48266
|
});
|
|
48205
48267
|
});
|
|
48206
48268
|
}
|
|
@@ -48430,7 +48492,7 @@ async function executeAuthoringToolCall(toolName, input, repoPath, harnessDir, c
|
|
|
48430
48492
|
}
|
|
48431
48493
|
async function askUser(question, options) {
|
|
48432
48494
|
const rl = readline3.createInterface({ input: process.stdin, output: process.stderr });
|
|
48433
|
-
return new Promise((
|
|
48495
|
+
return new Promise((resolve38) => {
|
|
48434
48496
|
process.stderr.write("\n");
|
|
48435
48497
|
process.stderr.write(`\u2753 ${question}
|
|
48436
48498
|
`);
|
|
@@ -48441,7 +48503,7 @@ async function askUser(question, options) {
|
|
|
48441
48503
|
process.stderr.write("> ");
|
|
48442
48504
|
rl.once("line", (answer) => {
|
|
48443
48505
|
rl.close();
|
|
48444
|
-
|
|
48506
|
+
resolve38(answer.trim());
|
|
48445
48507
|
});
|
|
48446
48508
|
});
|
|
48447
48509
|
}
|
|
@@ -48585,7 +48647,7 @@ function runScript(scriptPath, args = [], options = {}) {
|
|
|
48585
48647
|
function runScriptCapture(scriptPath, args = [], options = {}) {
|
|
48586
48648
|
const stream = options.stream ?? false;
|
|
48587
48649
|
const { stream: _stream, ...spawnOptions } = options;
|
|
48588
|
-
return new Promise((
|
|
48650
|
+
return new Promise((resolve38) => {
|
|
48589
48651
|
const proc = (0, import_child_process.spawn)("bash", [scriptPath, ...args], {
|
|
48590
48652
|
...spawnOptions,
|
|
48591
48653
|
stdio: ["inherit", "pipe", "pipe"]
|
|
@@ -48600,13 +48662,13 @@ function runScriptCapture(scriptPath, args = [], options = {}) {
|
|
|
48600
48662
|
stderr += d2;
|
|
48601
48663
|
if (stream) process.stderr.write(d2);
|
|
48602
48664
|
});
|
|
48603
|
-
proc.on("close", (code) =>
|
|
48665
|
+
proc.on("close", (code) => resolve38({ stdout, stderr, code: code ?? 0 }));
|
|
48604
48666
|
});
|
|
48605
48667
|
}
|
|
48606
48668
|
function runShellCommand(command2, options = {}) {
|
|
48607
48669
|
const stream = options.stream ?? false;
|
|
48608
48670
|
const { stream: _stream, ...spawnOptions } = options;
|
|
48609
|
-
return new Promise((
|
|
48671
|
+
return new Promise((resolve38) => {
|
|
48610
48672
|
const proc = (0, import_child_process.spawn)("bash", ["-lc", command2], {
|
|
48611
48673
|
...spawnOptions,
|
|
48612
48674
|
stdio: ["inherit", "pipe", "pipe"]
|
|
@@ -48621,7 +48683,7 @@ function runShellCommand(command2, options = {}) {
|
|
|
48621
48683
|
stderr += d2;
|
|
48622
48684
|
if (stream) process.stderr.write(d2);
|
|
48623
48685
|
});
|
|
48624
|
-
proc.on("close", (code) =>
|
|
48686
|
+
proc.on("close", (code) => resolve38({ stdout, stderr, code: code ?? 0 }));
|
|
48625
48687
|
});
|
|
48626
48688
|
}
|
|
48627
48689
|
|
|
@@ -49677,6 +49739,81 @@ function addCustomStage(repoPath, options) {
|
|
|
49677
49739
|
// src/harness/adaptation-prompt.ts
|
|
49678
49740
|
var fs22 = __toESM(require("fs"));
|
|
49679
49741
|
var path21 = __toESM(require("path"));
|
|
49742
|
+
var readline4 = __toESM(require("readline"));
|
|
49743
|
+
|
|
49744
|
+
// src/utils/clipboard.ts
|
|
49745
|
+
var import_child_process2 = require("child_process");
|
|
49746
|
+
function commandExists(command2) {
|
|
49747
|
+
const probe = process.platform === "win32" ? (0, import_child_process2.spawnSync)("where", [command2], { encoding: "utf8", stdio: ["ignore", "ignore", "ignore"] }) : (0, import_child_process2.spawnSync)("which", [command2], { encoding: "utf8", stdio: ["ignore", "ignore", "ignore"] });
|
|
49748
|
+
return probe.status === 0;
|
|
49749
|
+
}
|
|
49750
|
+
function tryPipeCommand(command2, args, text) {
|
|
49751
|
+
const result = (0, import_child_process2.spawnSync)(command2, args, {
|
|
49752
|
+
input: text,
|
|
49753
|
+
encoding: "utf8",
|
|
49754
|
+
stdio: ["pipe", "ignore", "ignore"]
|
|
49755
|
+
});
|
|
49756
|
+
return result.status === 0 && !result.error;
|
|
49757
|
+
}
|
|
49758
|
+
function writeOsc52Clipboard(text, stream = process.stderr) {
|
|
49759
|
+
if (!("isTTY" in stream) || !stream.isTTY) return false;
|
|
49760
|
+
if (Buffer.byteLength(text, "utf8") > 2e5) return false;
|
|
49761
|
+
const b64 = Buffer.from(text, "utf8").toString("base64");
|
|
49762
|
+
stream.write(`\x1B]52;c;${b64}\x07`);
|
|
49763
|
+
return true;
|
|
49764
|
+
}
|
|
49765
|
+
function copyViaPlatformTools(text) {
|
|
49766
|
+
if (process.platform === "darwin" && commandExists("pbcopy")) {
|
|
49767
|
+
if (tryPipeCommand("pbcopy", [], text)) return { ok: true, method: "pbcopy" };
|
|
49768
|
+
}
|
|
49769
|
+
if (process.platform === "win32") {
|
|
49770
|
+
if (commandExists("powershell")) {
|
|
49771
|
+
const result = (0, import_child_process2.spawnSync)(
|
|
49772
|
+
"powershell",
|
|
49773
|
+
[
|
|
49774
|
+
"-NoProfile",
|
|
49775
|
+
"-NonInteractive",
|
|
49776
|
+
"-Command",
|
|
49777
|
+
"$OutputEncoding = [Console]::InputEncoding = [Console]::OutputEncoding = [Text.UTF8Encoding]::new(); Set-Clipboard -Value ([Console]::In.ReadToEnd())"
|
|
49778
|
+
],
|
|
49779
|
+
{
|
|
49780
|
+
input: text,
|
|
49781
|
+
encoding: "utf8",
|
|
49782
|
+
stdio: ["pipe", "ignore", "ignore"]
|
|
49783
|
+
}
|
|
49784
|
+
);
|
|
49785
|
+
if (result.status === 0 && !result.error) return { ok: true, method: "powershell" };
|
|
49786
|
+
}
|
|
49787
|
+
if (commandExists("clip") && tryPipeCommand("clip", [], text)) {
|
|
49788
|
+
return { ok: true, method: "clip" };
|
|
49789
|
+
}
|
|
49790
|
+
}
|
|
49791
|
+
if (process.platform === "linux" || process.platform === "freebsd" || process.platform === "openbsd") {
|
|
49792
|
+
if (commandExists("wl-copy") && tryPipeCommand("wl-copy", [], text)) {
|
|
49793
|
+
return { ok: true, method: "wl-copy" };
|
|
49794
|
+
}
|
|
49795
|
+
if (commandExists("xclip") && tryPipeCommand("xclip", ["-selection", "clipboard"], text)) {
|
|
49796
|
+
return { ok: true, method: "xclip" };
|
|
49797
|
+
}
|
|
49798
|
+
if (commandExists("xsel") && tryPipeCommand("xsel", ["--clipboard", "--input"], text)) {
|
|
49799
|
+
return { ok: true, method: "xsel" };
|
|
49800
|
+
}
|
|
49801
|
+
}
|
|
49802
|
+
return {
|
|
49803
|
+
ok: false,
|
|
49804
|
+
detail: "No system clipboard command available (pbcopy, wl-copy/xclip/xsel, or clip)"
|
|
49805
|
+
};
|
|
49806
|
+
}
|
|
49807
|
+
function copyTextToClipboard(text) {
|
|
49808
|
+
const platform = copyViaPlatformTools(text);
|
|
49809
|
+
if (platform.ok) return platform;
|
|
49810
|
+
if (writeOsc52Clipboard(text)) {
|
|
49811
|
+
return { ok: true, method: "osc52" };
|
|
49812
|
+
}
|
|
49813
|
+
return platform;
|
|
49814
|
+
}
|
|
49815
|
+
|
|
49816
|
+
// src/harness/adaptation-prompt.ts
|
|
49680
49817
|
var ADAPTATION_PROMPT_FILE = "ADAPT-PROMPT.md";
|
|
49681
49818
|
var PROFILE_HINTS = {
|
|
49682
49819
|
default: "Web app profile (SaaS/full-stack) \u2014 Docker Compose for shared infra (HARNESS_INFRA_SERVICES), PM2 for the primary application only, git worktree per agent slot by default. Launch provisions toolchain via harness.env (HARNESS_ECOSYSTEM, HARNESS_INSTALL_CMD) and writes paths to .env.agent.<id>. Identify the primary app agents modify; run supporting services shared.",
|
|
@@ -49727,11 +49864,47 @@ function printAdaptationPrompt(content) {
|
|
|
49727
49864
|
`);
|
|
49728
49865
|
process.stderr.write("\n");
|
|
49729
49866
|
}
|
|
49867
|
+
function askYesNo3(question) {
|
|
49868
|
+
const rl = readline4.createInterface({ input: process.stdin, output: process.stderr });
|
|
49869
|
+
return new Promise((resolve38) => {
|
|
49870
|
+
process.stderr.write(`${question} `);
|
|
49871
|
+
rl.once("line", (answer) => {
|
|
49872
|
+
rl.close();
|
|
49873
|
+
const trimmed = answer.trim();
|
|
49874
|
+
resolve38(trimmed === "" || /^y(es)?$/i.test(trimmed));
|
|
49875
|
+
});
|
|
49876
|
+
});
|
|
49877
|
+
}
|
|
49878
|
+
async function offerAdaptationPromptClipboard(content, options = {}) {
|
|
49879
|
+
const interactive = Boolean(process.stdin.isTTY && process.stderr.isTTY);
|
|
49880
|
+
if (!interactive && !options.autoYes) {
|
|
49881
|
+
info("Prompt also saved to .har/ADAPT-PROMPT.md (open or copy from there)");
|
|
49882
|
+
return false;
|
|
49883
|
+
}
|
|
49884
|
+
let shouldCopy = options.autoYes === true;
|
|
49885
|
+
if (!shouldCopy && interactive) {
|
|
49886
|
+
shouldCopy = await askYesNo3("Copy adaptation prompt to clipboard for your coding agent? [Y/n]");
|
|
49887
|
+
}
|
|
49888
|
+
if (!shouldCopy) {
|
|
49889
|
+
info("Skipped clipboard copy \u2014 prompt is in .har/ADAPT-PROMPT.md");
|
|
49890
|
+
return false;
|
|
49891
|
+
}
|
|
49892
|
+
const result = copyTextToClipboard(content);
|
|
49893
|
+
if (result.ok) {
|
|
49894
|
+
success(
|
|
49895
|
+
result.method === "osc52" ? "Copied adaptation prompt to clipboard (terminal OSC 52) \u2014 paste into your coding agent" : "Copied adaptation prompt to clipboard \u2014 paste into your coding agent"
|
|
49896
|
+
);
|
|
49897
|
+
return true;
|
|
49898
|
+
}
|
|
49899
|
+
warn(`Could not copy to clipboard: ${result.detail}`);
|
|
49900
|
+
info("Open .har/ADAPT-PROMPT.md and paste that into your coding agent instead");
|
|
49901
|
+
return false;
|
|
49902
|
+
}
|
|
49730
49903
|
|
|
49731
49904
|
// src/harness/cursor-rule.ts
|
|
49732
49905
|
var fs23 = __toESM(require("fs"));
|
|
49733
49906
|
var path22 = __toESM(require("path"));
|
|
49734
|
-
var
|
|
49907
|
+
var readline5 = __toESM(require("readline"));
|
|
49735
49908
|
var CURSOR_RULE_RELATIVE_PATH = ".cursor/rules/har-workflow.mdc";
|
|
49736
49909
|
function getCursorRulePath(repoPath) {
|
|
49737
49910
|
return path22.join(repoPath, CURSOR_RULE_RELATIVE_PATH);
|
|
@@ -49781,20 +49954,20 @@ async function handleCursorRule(options) {
|
|
|
49781
49954
|
}
|
|
49782
49955
|
async function promptScaffoldCursorRule(exists) {
|
|
49783
49956
|
const action = exists ? "Update" : "Create";
|
|
49784
|
-
return
|
|
49957
|
+
return askYesNo4(`${action} ${CURSOR_RULE_RELATIVE_PATH}? [Y/n]`);
|
|
49785
49958
|
}
|
|
49786
|
-
async function
|
|
49787
|
-
const rl =
|
|
49788
|
-
return new Promise((
|
|
49959
|
+
async function askYesNo4(question) {
|
|
49960
|
+
const rl = readline5.createInterface({ input: process.stdin, output: process.stderr });
|
|
49961
|
+
return new Promise((resolve38) => {
|
|
49789
49962
|
process.stderr.write(`${question} `);
|
|
49790
49963
|
rl.once("line", (answer) => {
|
|
49791
49964
|
rl.close();
|
|
49792
49965
|
const trimmed = answer.trim();
|
|
49793
49966
|
if (trimmed === "") {
|
|
49794
|
-
|
|
49967
|
+
resolve38(true);
|
|
49795
49968
|
return;
|
|
49796
49969
|
}
|
|
49797
|
-
|
|
49970
|
+
resolve38(/^y(es)?$/i.test(trimmed));
|
|
49798
49971
|
});
|
|
49799
49972
|
});
|
|
49800
49973
|
}
|
|
@@ -50104,19 +50277,19 @@ var LocalScriptExecutor = class {
|
|
|
50104
50277
|
var localScriptExecutor = new LocalScriptExecutor();
|
|
50105
50278
|
|
|
50106
50279
|
// src/core/control-sync.ts
|
|
50107
|
-
var
|
|
50280
|
+
var path41 = __toESM(require("path"));
|
|
50108
50281
|
init_control_config();
|
|
50109
50282
|
|
|
50110
50283
|
// src/core/control-registry.ts
|
|
50111
|
-
var
|
|
50112
|
-
var
|
|
50113
|
-
var
|
|
50284
|
+
var fs28 = __toESM(require("fs"));
|
|
50285
|
+
var os5 = __toESM(require("os"));
|
|
50286
|
+
var path27 = __toESM(require("path"));
|
|
50114
50287
|
|
|
50115
50288
|
// src/core/control-repo-path.ts
|
|
50116
|
-
var
|
|
50117
|
-
var
|
|
50289
|
+
var fs27 = __toESM(require("fs"));
|
|
50290
|
+
var path26 = __toESM(require("path"));
|
|
50118
50291
|
function tryGit(cwd, args) {
|
|
50119
|
-
if (!
|
|
50292
|
+
if (!fs27.existsSync(cwd)) return void 0;
|
|
50120
50293
|
const result = run(`git ${args}`, { cwd });
|
|
50121
50294
|
return result.code === 0 ? result.stdout.trim() : void 0;
|
|
50122
50295
|
}
|
|
@@ -50124,58 +50297,58 @@ function resolveMainWorkingTree(cwd) {
|
|
|
50124
50297
|
const toplevel = tryGit(cwd, "rev-parse --show-toplevel");
|
|
50125
50298
|
if (!toplevel) return void 0;
|
|
50126
50299
|
const commonDirRaw = tryGit(cwd, "rev-parse --git-common-dir");
|
|
50127
|
-
const commonDir = commonDirRaw ?
|
|
50128
|
-
if (!commonDir) return
|
|
50129
|
-
if (
|
|
50130
|
-
return
|
|
50300
|
+
const commonDir = commonDirRaw ? path26.resolve(cwd, commonDirRaw) : void 0;
|
|
50301
|
+
if (!commonDir) return path26.resolve(toplevel);
|
|
50302
|
+
if (path26.basename(commonDir) === ".git") {
|
|
50303
|
+
return path26.dirname(commonDir);
|
|
50131
50304
|
}
|
|
50132
50305
|
const porcelain = tryGit(cwd, "worktree list --porcelain");
|
|
50133
50306
|
if (porcelain) {
|
|
50134
50307
|
for (const line of porcelain.split("\n")) {
|
|
50135
50308
|
if (line.startsWith("worktree ")) {
|
|
50136
|
-
return
|
|
50309
|
+
return path26.resolve(line.slice("worktree ".length));
|
|
50137
50310
|
}
|
|
50138
50311
|
}
|
|
50139
50312
|
}
|
|
50140
|
-
return
|
|
50313
|
+
return path26.resolve(toplevel);
|
|
50141
50314
|
}
|
|
50142
50315
|
function canonicalizeControlRepoPath(repoPath) {
|
|
50143
|
-
const resolved =
|
|
50316
|
+
const resolved = path26.resolve(repoPath);
|
|
50144
50317
|
const toplevel = tryGit(resolved, "rev-parse --show-toplevel");
|
|
50145
50318
|
if (!toplevel) return resolved;
|
|
50146
50319
|
const mainRoot = resolveMainWorkingTree(resolved);
|
|
50147
50320
|
if (!mainRoot) return resolved;
|
|
50148
|
-
const top2 =
|
|
50149
|
-
const main =
|
|
50321
|
+
const top2 = path26.resolve(toplevel);
|
|
50322
|
+
const main = path26.resolve(mainRoot);
|
|
50150
50323
|
if (top2 === main) return resolved;
|
|
50151
|
-
const rel =
|
|
50324
|
+
const rel = path26.relative(top2, resolved);
|
|
50152
50325
|
if (!rel || rel === ".") return main;
|
|
50153
|
-
if (rel.startsWith(`..${
|
|
50326
|
+
if (rel.startsWith(`..${path26.sep}`) || rel === ".." || path26.isAbsolute(rel)) {
|
|
50154
50327
|
return resolved;
|
|
50155
50328
|
}
|
|
50156
|
-
return
|
|
50329
|
+
return path26.resolve(main, rel);
|
|
50157
50330
|
}
|
|
50158
50331
|
|
|
50159
50332
|
// src/core/control-registry.ts
|
|
50160
50333
|
function getRegistryPath() {
|
|
50161
50334
|
if (process.env.HAR_CONTROL_REGISTRY_PATH) {
|
|
50162
|
-
return
|
|
50335
|
+
return path27.resolve(process.env.HAR_CONTROL_REGISTRY_PATH);
|
|
50163
50336
|
}
|
|
50164
|
-
return
|
|
50337
|
+
return path27.join(os5.homedir(), ".har", "repos.json");
|
|
50165
50338
|
}
|
|
50166
50339
|
function readRegistry() {
|
|
50167
50340
|
const registryPath = getRegistryPath();
|
|
50168
50341
|
try {
|
|
50169
|
-
if (!
|
|
50170
|
-
return JSON.parse(
|
|
50342
|
+
if (!fs28.existsSync(registryPath)) return { repos: [] };
|
|
50343
|
+
return JSON.parse(fs28.readFileSync(registryPath, "utf8"));
|
|
50171
50344
|
} catch {
|
|
50172
50345
|
return { repos: [] };
|
|
50173
50346
|
}
|
|
50174
50347
|
}
|
|
50175
50348
|
function writeRegistry(registry2) {
|
|
50176
50349
|
const registryPath = getRegistryPath();
|
|
50177
|
-
|
|
50178
|
-
|
|
50350
|
+
fs28.mkdirSync(path27.dirname(registryPath), { recursive: true });
|
|
50351
|
+
fs28.writeFileSync(registryPath, JSON.stringify(registry2, null, 2) + "\n");
|
|
50179
50352
|
}
|
|
50180
50353
|
function registryChanged(before, after) {
|
|
50181
50354
|
if (before.length !== after.length) return true;
|
|
@@ -50197,7 +50370,7 @@ function removeRegisteredRepo(repoPath) {
|
|
|
50197
50370
|
try {
|
|
50198
50371
|
return canonicalizeControlRepoPath(entry) !== resolved;
|
|
50199
50372
|
} catch {
|
|
50200
|
-
return
|
|
50373
|
+
return path27.resolve(entry) !== resolved;
|
|
50201
50374
|
}
|
|
50202
50375
|
});
|
|
50203
50376
|
if (next.length === registry2.repos.length) return false;
|
|
@@ -50209,9 +50382,9 @@ function listRegisteredRepos() {
|
|
|
50209
50382
|
const kept = [];
|
|
50210
50383
|
const seen = /* @__PURE__ */ new Set();
|
|
50211
50384
|
for (const repoPath of registry2.repos) {
|
|
50212
|
-
if (!
|
|
50385
|
+
if (!fs28.existsSync(repoPath)) continue;
|
|
50213
50386
|
const canonical = canonicalizeControlRepoPath(repoPath);
|
|
50214
|
-
if (!
|
|
50387
|
+
if (!fs28.existsSync(canonical) || !readManifest(canonical)) continue;
|
|
50215
50388
|
if (seen.has(canonical)) continue;
|
|
50216
50389
|
seen.add(canonical);
|
|
50217
50390
|
kept.push(canonical);
|
|
@@ -50222,27 +50395,30 @@ function listRegisteredRepos() {
|
|
|
50222
50395
|
return kept;
|
|
50223
50396
|
}
|
|
50224
50397
|
|
|
50398
|
+
// src/core/control-sync.ts
|
|
50399
|
+
init_portal_credentials();
|
|
50400
|
+
|
|
50225
50401
|
// src/core/slot-status.ts
|
|
50226
|
-
var
|
|
50227
|
-
var
|
|
50228
|
-
var
|
|
50229
|
-
var
|
|
50402
|
+
var fs33 = __toESM(require("fs"));
|
|
50403
|
+
var os8 = __toESM(require("os"));
|
|
50404
|
+
var path33 = __toESM(require("path"));
|
|
50405
|
+
var import_child_process8 = require("child_process");
|
|
50230
50406
|
|
|
50231
50407
|
// src/core/runs.ts
|
|
50232
50408
|
var crypto2 = __toESM(require("crypto"));
|
|
50233
|
-
var
|
|
50234
|
-
var
|
|
50235
|
-
var
|
|
50236
|
-
var
|
|
50409
|
+
var import_child_process3 = require("child_process");
|
|
50410
|
+
var fs29 = __toESM(require("fs"));
|
|
50411
|
+
var os6 = __toESM(require("os"));
|
|
50412
|
+
var path28 = __toESM(require("path"));
|
|
50237
50413
|
var RUNS_DIR = "runs";
|
|
50238
50414
|
function gitCommonDir(cwd) {
|
|
50239
50415
|
try {
|
|
50240
|
-
const out = (0,
|
|
50416
|
+
const out = (0, import_child_process3.execSync)("git rev-parse --git-common-dir", {
|
|
50241
50417
|
cwd,
|
|
50242
50418
|
encoding: "utf8",
|
|
50243
50419
|
stdio: ["pipe", "pipe", "ignore"]
|
|
50244
50420
|
}).trim();
|
|
50245
|
-
return out ?
|
|
50421
|
+
return out ? path28.resolve(cwd, out) : void 0;
|
|
50246
50422
|
} catch {
|
|
50247
50423
|
return void 0;
|
|
50248
50424
|
}
|
|
@@ -50254,7 +50430,7 @@ function sameGitCheckout(a2, b2) {
|
|
|
50254
50430
|
}
|
|
50255
50431
|
function gitPrefix(cwd) {
|
|
50256
50432
|
try {
|
|
50257
|
-
return (0,
|
|
50433
|
+
return (0, import_child_process3.execSync)("git rev-parse --show-prefix", {
|
|
50258
50434
|
cwd,
|
|
50259
50435
|
encoding: "utf8",
|
|
50260
50436
|
stdio: ["pipe", "pipe", "ignore"]
|
|
@@ -50264,7 +50440,7 @@ function gitPrefix(cwd) {
|
|
|
50264
50440
|
}
|
|
50265
50441
|
}
|
|
50266
50442
|
function getRunsDir(harnessRoot) {
|
|
50267
|
-
return
|
|
50443
|
+
return path28.join(getHarnessDir(harnessRoot), RUNS_DIR);
|
|
50268
50444
|
}
|
|
50269
50445
|
function formatLocalDate(d2) {
|
|
50270
50446
|
const y2 = d2.getFullYear();
|
|
@@ -50284,24 +50460,24 @@ function buildRunRelativePath(stageId, agentId, startedAt, runId, runsDir) {
|
|
|
50284
50460
|
const timePart = formatLocalTime(started);
|
|
50285
50461
|
const agentPart = agentId !== void 0 ? `_agent-${agentId}` : "";
|
|
50286
50462
|
let filename = `${timePart}_${stageId}${agentPart}.json`;
|
|
50287
|
-
const fullPath =
|
|
50288
|
-
if (
|
|
50463
|
+
const fullPath = path28.join(runsDir, dateFolder, filename);
|
|
50464
|
+
if (fs29.existsSync(fullPath)) {
|
|
50289
50465
|
filename = `${timePart}_${stageId}${agentPart}-${runId.slice(0, 8)}.json`;
|
|
50290
50466
|
}
|
|
50291
|
-
return
|
|
50467
|
+
return path28.join(dateFolder, filename);
|
|
50292
50468
|
}
|
|
50293
50469
|
function resolveRunFilePath(harnessRoot, run2) {
|
|
50294
50470
|
if (run2.relativePath) {
|
|
50295
|
-
return
|
|
50471
|
+
return path28.join(getRunsDir(harnessRoot), run2.relativePath);
|
|
50296
50472
|
}
|
|
50297
|
-
return
|
|
50473
|
+
return path28.join(getRunsDir(harnessRoot), `${run2.runId}.json`);
|
|
50298
50474
|
}
|
|
50299
50475
|
function collectRunFiles(runsDir) {
|
|
50300
|
-
if (!
|
|
50476
|
+
if (!fs29.existsSync(runsDir)) return [];
|
|
50301
50477
|
const files = [];
|
|
50302
50478
|
const walk = (dir) => {
|
|
50303
|
-
for (const entry of
|
|
50304
|
-
const full =
|
|
50479
|
+
for (const entry of fs29.readdirSync(dir, { withFileTypes: true })) {
|
|
50480
|
+
const full = path28.join(dir, entry.name);
|
|
50305
50481
|
if (entry.isDirectory()) {
|
|
50306
50482
|
walk(full);
|
|
50307
50483
|
} else if (entry.name.endsWith(".json")) {
|
|
@@ -50315,30 +50491,30 @@ function collectRunFiles(runsDir) {
|
|
|
50315
50491
|
function resolveAgentWorkDir(harnessRoot, agentId) {
|
|
50316
50492
|
if (agentId === void 0) return void 0;
|
|
50317
50493
|
const entry = readSlotRegistry(harnessRoot, agentId);
|
|
50318
|
-
if (entry?.workDir &&
|
|
50494
|
+
if (entry?.workDir && fs29.existsSync(entry.workDir)) return entry.workDir;
|
|
50319
50495
|
const env3 = readHarnessEnv(harnessRoot);
|
|
50320
|
-
const projectName = env3.HARNESS_PROJECT_NAME ??
|
|
50321
|
-
const worktreeDir =
|
|
50496
|
+
const projectName = env3.HARNESS_PROJECT_NAME ?? path28.basename(harnessRoot);
|
|
50497
|
+
const worktreeDir = path28.join(os6.homedir(), "worktrees", `${projectName}-agent-${agentId}`);
|
|
50322
50498
|
const relPrefix = gitPrefix(harnessRoot);
|
|
50323
50499
|
const sessionEnvFiles = [];
|
|
50324
|
-
const worktreesRoot =
|
|
50325
|
-
if (
|
|
50500
|
+
const worktreesRoot = path28.join(os6.homedir(), "worktrees");
|
|
50501
|
+
if (fs29.existsSync(worktreesRoot)) {
|
|
50326
50502
|
const suffix = `-har-agent-${agentId}-`;
|
|
50327
|
-
for (const entry2 of
|
|
50503
|
+
for (const entry2 of fs29.readdirSync(worktreesRoot, { withFileTypes: true })) {
|
|
50328
50504
|
if (!entry2.isDirectory() || !entry2.name.includes(suffix)) continue;
|
|
50329
|
-
const sessionDir =
|
|
50505
|
+
const sessionDir = path28.join(worktreesRoot, entry2.name);
|
|
50330
50506
|
if (!sameGitCheckout(harnessRoot, sessionDir)) continue;
|
|
50331
|
-
sessionEnvFiles.push(
|
|
50507
|
+
sessionEnvFiles.push(path28.join(sessionDir, relPrefix, `.env.agent.${agentId}`));
|
|
50332
50508
|
}
|
|
50333
50509
|
}
|
|
50334
50510
|
const candidates = [
|
|
50335
|
-
|
|
50336
|
-
|
|
50511
|
+
path28.join(worktreeDir, `.env.agent.${agentId}`),
|
|
50512
|
+
path28.join(harnessRoot, `.env.agent.${agentId}`),
|
|
50337
50513
|
...sessionEnvFiles.sort()
|
|
50338
50514
|
];
|
|
50339
50515
|
for (const envFile of candidates) {
|
|
50340
|
-
if (!
|
|
50341
|
-
const content =
|
|
50516
|
+
if (!fs29.existsSync(envFile)) continue;
|
|
50517
|
+
const content = fs29.readFileSync(envFile, "utf8");
|
|
50342
50518
|
const match = content.match(/^REPO_ROOT=(.+)$/m);
|
|
50343
50519
|
if (match) return match[1].trim();
|
|
50344
50520
|
}
|
|
@@ -50350,11 +50526,11 @@ function createRun(ctx, meta) {
|
|
|
50350
50526
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
50351
50527
|
const runId = crypto2.randomUUID();
|
|
50352
50528
|
const relativePath = buildRunRelativePath(meta.stageId, meta.agentId, startedAt, runId, runsDir);
|
|
50353
|
-
const runFilePath =
|
|
50354
|
-
|
|
50529
|
+
const runFilePath = path28.join(runsDir, relativePath);
|
|
50530
|
+
fs29.mkdirSync(path28.dirname(runFilePath), { recursive: true });
|
|
50355
50531
|
const run2 = RunRecordSchema.parse({
|
|
50356
50532
|
runId,
|
|
50357
|
-
repoPath:
|
|
50533
|
+
repoPath: path28.resolve(ctx.repoPath),
|
|
50358
50534
|
harnessRoot,
|
|
50359
50535
|
stageId: meta.stageId,
|
|
50360
50536
|
kind: meta.kind,
|
|
@@ -50367,7 +50543,7 @@ function createRun(ctx, meta) {
|
|
|
50367
50543
|
workUnitId: ctx.workUnitId,
|
|
50368
50544
|
attemptId: ctx.attemptId
|
|
50369
50545
|
});
|
|
50370
|
-
|
|
50546
|
+
fs29.writeFileSync(runFilePath, JSON.stringify(run2, null, 2) + "\n");
|
|
50371
50547
|
return run2;
|
|
50372
50548
|
}
|
|
50373
50549
|
function finishRun(repoPath, runId, update) {
|
|
@@ -50386,13 +50562,13 @@ function finishRun(repoPath, runId, update) {
|
|
|
50386
50562
|
finishedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
50387
50563
|
});
|
|
50388
50564
|
const runPath = resolveRunFilePath(harnessRoot, finished);
|
|
50389
|
-
|
|
50565
|
+
fs29.writeFileSync(runPath, JSON.stringify(finished, null, 2) + "\n");
|
|
50390
50566
|
return finished;
|
|
50391
50567
|
}
|
|
50392
50568
|
function findRunRecord(harnessRoot, runId) {
|
|
50393
50569
|
const runsDir = getRunsDir(harnessRoot);
|
|
50394
50570
|
for (const filePath of collectRunFiles(runsDir)) {
|
|
50395
|
-
const parsed = RunRecordSchema.safeParse(JSON.parse(
|
|
50571
|
+
const parsed = RunRecordSchema.safeParse(JSON.parse(fs29.readFileSync(filePath, "utf8")));
|
|
50396
50572
|
if (parsed.success && parsed.data.runId === runId) {
|
|
50397
50573
|
return parsed.data;
|
|
50398
50574
|
}
|
|
@@ -50404,10 +50580,10 @@ function getRun(repoPath, runId) {
|
|
|
50404
50580
|
}
|
|
50405
50581
|
function listRuns(repoPath, filter2 = {}) {
|
|
50406
50582
|
const runsDir = getRunsDir(resolveHarnessRoot(repoPath));
|
|
50407
|
-
if (!
|
|
50583
|
+
if (!fs29.existsSync(runsDir)) return [];
|
|
50408
50584
|
const runs = [];
|
|
50409
50585
|
for (const filePath of collectRunFiles(runsDir)) {
|
|
50410
|
-
const parsed = RunRecordSchema.safeParse(JSON.parse(
|
|
50586
|
+
const parsed = RunRecordSchema.safeParse(JSON.parse(fs29.readFileSync(filePath, "utf8")));
|
|
50411
50587
|
if (!parsed.success) continue;
|
|
50412
50588
|
if (filter2.stageId && parsed.data.stageId !== filter2.stageId) continue;
|
|
50413
50589
|
runs.push(parsed.data);
|
|
@@ -50420,18 +50596,18 @@ function listRuns(repoPath, filter2 = {}) {
|
|
|
50420
50596
|
}
|
|
50421
50597
|
|
|
50422
50598
|
// src/core/slot-preflight.ts
|
|
50423
|
-
var
|
|
50599
|
+
var path32 = __toESM(require("path"));
|
|
50424
50600
|
|
|
50425
50601
|
// src/core/control-port.ts
|
|
50426
|
-
var
|
|
50427
|
-
var
|
|
50428
|
-
var
|
|
50602
|
+
var import_child_process5 = require("child_process");
|
|
50603
|
+
var fs31 = __toESM(require("fs"));
|
|
50604
|
+
var path30 = __toESM(require("path"));
|
|
50429
50605
|
init_control_config();
|
|
50430
50606
|
|
|
50431
50607
|
// src/core/slot-ports.ts
|
|
50432
|
-
var
|
|
50433
|
-
var
|
|
50434
|
-
var
|
|
50608
|
+
var import_child_process4 = require("child_process");
|
|
50609
|
+
var fs30 = __toESM(require("fs"));
|
|
50610
|
+
var path29 = __toESM(require("path"));
|
|
50435
50611
|
function portStep(env3) {
|
|
50436
50612
|
return Number(env3.HARNESS_PORT_STEP ?? 10);
|
|
50437
50613
|
}
|
|
@@ -50443,7 +50619,7 @@ function slotPortLaneEnd(defaultPort, step) {
|
|
|
50443
50619
|
}
|
|
50444
50620
|
function isPortInUse(port, host = "127.0.0.1") {
|
|
50445
50621
|
try {
|
|
50446
|
-
(0,
|
|
50622
|
+
(0, import_child_process4.execSync)(`bash -c 'exec 3<>/dev/tcp/${host}/${port}'`, { stdio: "ignore" });
|
|
50447
50623
|
return true;
|
|
50448
50624
|
} catch {
|
|
50449
50625
|
return false;
|
|
@@ -50487,7 +50663,7 @@ function allocateAppPorts(repoPath, agentId) {
|
|
|
50487
50663
|
}
|
|
50488
50664
|
function harnessUsesPm2(repoPath) {
|
|
50489
50665
|
const harnessRoot = resolveHarnessRoot(repoPath);
|
|
50490
|
-
return
|
|
50666
|
+
return fs30.existsSync(path29.join(harnessRoot, ".har", "ecosystem.agent.template.cjs"));
|
|
50491
50667
|
}
|
|
50492
50668
|
|
|
50493
50669
|
// src/core/control-port.ts
|
|
@@ -50514,7 +50690,7 @@ function controlContainerOnPort(containers, port) {
|
|
|
50514
50690
|
}
|
|
50515
50691
|
function listDockerContainers() {
|
|
50516
50692
|
try {
|
|
50517
|
-
const raw = (0,
|
|
50693
|
+
const raw = (0, import_child_process5.execSync)("docker ps --format {{.Names}}\\t{{.Ports}}", {
|
|
50518
50694
|
encoding: "utf8",
|
|
50519
50695
|
stdio: ["pipe", "pipe", "ignore"],
|
|
50520
50696
|
timeout: 3e3
|
|
@@ -50542,13 +50718,13 @@ function controlDefaultPortWarnings(containers, defaultFrontendPort, allocatedFr
|
|
|
50542
50718
|
return [formatControlDefaultPortWarning(control.name, defaultFrontendPort, allocatedFrontend)];
|
|
50543
50719
|
}
|
|
50544
50720
|
function inspectControlUpReadiness(repoPath) {
|
|
50545
|
-
const resolved =
|
|
50721
|
+
const resolved = path30.resolve(repoPath);
|
|
50546
50722
|
const port = parseControlHostPort();
|
|
50547
50723
|
const containers = listDockerContainers();
|
|
50548
50724
|
const control = controlContainerOnPort(containers, port);
|
|
50549
50725
|
const warnings = [];
|
|
50550
|
-
const controlHarnessDir =
|
|
50551
|
-
const harnessSlot1Active =
|
|
50726
|
+
const controlHarnessDir = path30.join(resolved, "control", ".har");
|
|
50727
|
+
const harnessSlot1Active = fs31.existsSync(controlHarnessDir) && readSlotRegistry(path30.join(resolved, "control"), 1)?.status === "active";
|
|
50552
50728
|
if (control) {
|
|
50553
50729
|
return {
|
|
50554
50730
|
warnings,
|
|
@@ -50579,13 +50755,13 @@ function inspectControlUpReadiness(repoPath) {
|
|
|
50579
50755
|
}
|
|
50580
50756
|
|
|
50581
50757
|
// src/core/slot-launch-guard-occupied.ts
|
|
50582
|
-
var
|
|
50583
|
-
var
|
|
50584
|
-
var
|
|
50585
|
-
var
|
|
50758
|
+
var fs32 = __toESM(require("fs"));
|
|
50759
|
+
var os7 = __toESM(require("os"));
|
|
50760
|
+
var path31 = __toESM(require("path"));
|
|
50761
|
+
var import_child_process6 = require("child_process");
|
|
50586
50762
|
function runGit(cwd, args) {
|
|
50587
50763
|
try {
|
|
50588
|
-
return (0,
|
|
50764
|
+
return (0, import_child_process6.execSync)(`git ${args}`, {
|
|
50589
50765
|
cwd,
|
|
50590
50766
|
encoding: "utf8",
|
|
50591
50767
|
stdio: ["pipe", "pipe", "ignore"]
|
|
@@ -50600,7 +50776,7 @@ function worktreeDirty(worktreePath) {
|
|
|
50600
50776
|
}
|
|
50601
50777
|
function gitCommonDir2(cwd) {
|
|
50602
50778
|
const out = runGit(cwd, "rev-parse --git-common-dir");
|
|
50603
|
-
return out ?
|
|
50779
|
+
return out ? path31.resolve(cwd, out) : void 0;
|
|
50604
50780
|
}
|
|
50605
50781
|
function sameGitCheckout2(a2, b2) {
|
|
50606
50782
|
const left2 = gitCommonDir2(a2);
|
|
@@ -50609,20 +50785,20 @@ function sameGitCheckout2(a2, b2) {
|
|
|
50609
50785
|
}
|
|
50610
50786
|
function discoverWorktree(harnessRoot, agentId, projectName) {
|
|
50611
50787
|
const session = readSlotRegistry(harnessRoot, agentId);
|
|
50612
|
-
if (session?.worktreePath &&
|
|
50788
|
+
if (session?.worktreePath && fs32.existsSync(session.worktreePath)) {
|
|
50613
50789
|
return session.worktreePath;
|
|
50614
50790
|
}
|
|
50615
|
-
const legacy =
|
|
50616
|
-
if (
|
|
50617
|
-
const worktreesRoot =
|
|
50618
|
-
if (!
|
|
50791
|
+
const legacy = path31.join(os7.homedir(), "worktrees", `${projectName}-agent-${agentId}`);
|
|
50792
|
+
if (fs32.existsSync(legacy) && sameGitCheckout2(harnessRoot, legacy)) return legacy;
|
|
50793
|
+
const worktreesRoot = path31.join(os7.homedir(), "worktrees");
|
|
50794
|
+
if (!fs32.existsSync(worktreesRoot)) return void 0;
|
|
50619
50795
|
const suffix = `-har-agent-${agentId}-`;
|
|
50620
50796
|
const relPrefix = runGit(harnessRoot, "rev-parse --show-prefix") ?? "";
|
|
50621
|
-
for (const name of
|
|
50797
|
+
for (const name of fs32.readdirSync(worktreesRoot)) {
|
|
50622
50798
|
if (!name.includes(suffix)) continue;
|
|
50623
|
-
const candidate =
|
|
50799
|
+
const candidate = path31.join(worktreesRoot, name);
|
|
50624
50800
|
if (!sameGitCheckout2(harnessRoot, candidate)) continue;
|
|
50625
|
-
if (!
|
|
50801
|
+
if (!fs32.existsSync(path31.join(candidate, relPrefix, `.env.agent.${agentId}`))) continue;
|
|
50626
50802
|
return candidate;
|
|
50627
50803
|
}
|
|
50628
50804
|
return void 0;
|
|
@@ -50630,13 +50806,13 @@ function discoverWorktree(harnessRoot, agentId, projectName) {
|
|
|
50630
50806
|
function collectOccupiedSlot(repoPath, agentId) {
|
|
50631
50807
|
const harnessRoot = resolveHarnessRoot(repoPath);
|
|
50632
50808
|
const env3 = readHarnessEnv(harnessRoot);
|
|
50633
|
-
const projectName = env3.HARNESS_PROJECT_NAME ??
|
|
50809
|
+
const projectName = env3.HARNESS_PROJECT_NAME ?? path31.basename(harnessRoot);
|
|
50634
50810
|
const session = readSlotRegistry(harnessRoot, agentId);
|
|
50635
50811
|
const worktreePath = discoverWorktree(harnessRoot, agentId, projectName);
|
|
50636
50812
|
const workDir = session?.workDir;
|
|
50637
|
-
const envInWorkDir = workDir ?
|
|
50638
|
-
const envInRoot =
|
|
50639
|
-
const envInWorktree = worktreePath ?
|
|
50813
|
+
const envInWorkDir = workDir ? fs32.existsSync(path31.join(workDir, `.env.agent.${agentId}`)) : false;
|
|
50814
|
+
const envInRoot = fs32.existsSync(path31.join(harnessRoot, `.env.agent.${agentId}`));
|
|
50815
|
+
const envInWorktree = worktreePath ? fs32.existsSync(path31.join(worktreePath, `.env.agent.${agentId}`)) : false;
|
|
50640
50816
|
const active = session !== void 0 && session.status !== "completed" || envInWorkDir || envInRoot || envInWorktree;
|
|
50641
50817
|
if (!active) return void 0;
|
|
50642
50818
|
const dirty = worktreePath ? worktreeDirty(worktreePath) : void 0;
|
|
@@ -50751,10 +50927,10 @@ function checkLaunchGuard(repoPath, agentId, options = {}) {
|
|
|
50751
50927
|
}
|
|
50752
50928
|
|
|
50753
50929
|
// src/core/slot-preflight.ts
|
|
50754
|
-
var
|
|
50930
|
+
var import_child_process7 = require("child_process");
|
|
50755
50931
|
function listPm2Processes() {
|
|
50756
50932
|
try {
|
|
50757
|
-
const raw = (0,
|
|
50933
|
+
const raw = (0, import_child_process7.execSync)("npx --yes pm2 jlist", {
|
|
50758
50934
|
encoding: "utf8",
|
|
50759
50935
|
stdio: ["pipe", "pipe", "ignore"],
|
|
50760
50936
|
timeout: 3e3
|
|
@@ -50802,7 +50978,7 @@ function checkInfraPort(env3, varName, defaultPort, scanStart, scanEnd) {
|
|
|
50802
50978
|
function inspectSlotReadiness(repoPath, agentId, options = {}) {
|
|
50803
50979
|
const harnessRoot = resolveHarnessRoot(repoPath);
|
|
50804
50980
|
const env3 = readHarnessEnv(harnessRoot);
|
|
50805
|
-
const projectName = env3.HARNESS_PROJECT_NAME ??
|
|
50981
|
+
const projectName = env3.HARNESS_PROJECT_NAME ?? path32.basename(harnessRoot);
|
|
50806
50982
|
const usesPm2 = harnessUsesPm2(repoPath);
|
|
50807
50983
|
const blockers = [];
|
|
50808
50984
|
const remediations = [];
|
|
@@ -50978,7 +51154,7 @@ function formatPreflightReport(agentId, readiness) {
|
|
|
50978
51154
|
var BYPASS_WARNING_MS = 15 * 60 * 1e3;
|
|
50979
51155
|
function readGitRemote(repoPath) {
|
|
50980
51156
|
try {
|
|
50981
|
-
const remote = (0,
|
|
51157
|
+
const remote = (0, import_child_process8.execSync)("git remote get-url origin", {
|
|
50982
51158
|
cwd: repoPath,
|
|
50983
51159
|
encoding: "utf8",
|
|
50984
51160
|
stdio: ["pipe", "pipe", "ignore"]
|
|
@@ -50990,7 +51166,7 @@ function readGitRemote(repoPath) {
|
|
|
50990
51166
|
}
|
|
50991
51167
|
function runGit2(cwd, args) {
|
|
50992
51168
|
try {
|
|
50993
|
-
return (0,
|
|
51169
|
+
return (0, import_child_process8.execSync)(`git ${args}`, {
|
|
50994
51170
|
cwd,
|
|
50995
51171
|
encoding: "utf8",
|
|
50996
51172
|
stdio: ["pipe", "pipe", "ignore"]
|
|
@@ -51004,7 +51180,7 @@ function readWorktreeBranch(worktreePath) {
|
|
|
51004
51180
|
}
|
|
51005
51181
|
function gitCommonDir3(cwd) {
|
|
51006
51182
|
const out = runGit2(cwd, "rev-parse --git-common-dir");
|
|
51007
|
-
return out ?
|
|
51183
|
+
return out ? path33.resolve(cwd, out) : void 0;
|
|
51008
51184
|
}
|
|
51009
51185
|
function sameGitCheckout3(a2, b2) {
|
|
51010
51186
|
const left2 = gitCommonDir3(a2);
|
|
@@ -51016,12 +51192,12 @@ function gitPrefix2(cwd) {
|
|
|
51016
51192
|
return out ?? "";
|
|
51017
51193
|
}
|
|
51018
51194
|
function discoverSessionWorktreePath(harnessRoot, agentId) {
|
|
51019
|
-
const worktreesRoot =
|
|
51020
|
-
if (!
|
|
51195
|
+
const worktreesRoot = path33.join(os8.homedir(), "worktrees");
|
|
51196
|
+
if (!fs33.existsSync(worktreesRoot)) return void 0;
|
|
51021
51197
|
const suffix = `-har-agent-${agentId}-`;
|
|
51022
51198
|
const relPrefix = gitPrefix2(harnessRoot);
|
|
51023
|
-
const matches =
|
|
51024
|
-
(candidate) => sameGitCheckout3(harnessRoot, candidate) &&
|
|
51199
|
+
const matches = fs33.readdirSync(worktreesRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory() && entry.name.includes(suffix)).map((entry) => path33.join(worktreesRoot, entry.name)).filter(
|
|
51200
|
+
(candidate) => sameGitCheckout3(harnessRoot, candidate) && fs33.existsSync(path33.join(candidate, relPrefix, `.env.agent.${agentId}`))
|
|
51025
51201
|
);
|
|
51026
51202
|
return matches.sort()[0];
|
|
51027
51203
|
}
|
|
@@ -51066,7 +51242,7 @@ function lastBuildPass(run2) {
|
|
|
51066
51242
|
}
|
|
51067
51243
|
function listPm2Processes2() {
|
|
51068
51244
|
try {
|
|
51069
|
-
const raw = (0,
|
|
51245
|
+
const raw = (0, import_child_process8.execSync)("npx --yes pm2 jlist", {
|
|
51070
51246
|
encoding: "utf8",
|
|
51071
51247
|
stdio: ["pipe", "pipe", "ignore"],
|
|
51072
51248
|
timeout: 3e3
|
|
@@ -51096,18 +51272,18 @@ function detectPm2Issue(projectName, agentId, session, procs) {
|
|
|
51096
51272
|
}
|
|
51097
51273
|
function collectSlotStatus(harnessRoot, agentId, runs, pm2Procs) {
|
|
51098
51274
|
const env3 = readHarnessEnv(harnessRoot);
|
|
51099
|
-
const projectName = env3.HARNESS_PROJECT_NAME ??
|
|
51275
|
+
const projectName = env3.HARNESS_PROJECT_NAME ?? path33.basename(harnessRoot);
|
|
51100
51276
|
const session = readSlotRegistry(harnessRoot, agentId);
|
|
51101
|
-
const legacyWorktreePath =
|
|
51102
|
-
|
|
51277
|
+
const legacyWorktreePath = path33.join(
|
|
51278
|
+
os8.homedir(),
|
|
51103
51279
|
"worktrees",
|
|
51104
51280
|
`${projectName}-agent-${agentId}`
|
|
51105
51281
|
);
|
|
51106
|
-
const worktreePath = session?.worktreePath &&
|
|
51282
|
+
const worktreePath = session?.worktreePath && fs33.existsSync(session.worktreePath) ? session.worktreePath : fs33.existsSync(legacyWorktreePath) ? legacyWorktreePath : discoverSessionWorktreePath(harnessRoot, agentId);
|
|
51107
51283
|
const workDir = resolveAgentWorkDir(harnessRoot, agentId);
|
|
51108
|
-
const envInWorkDir = workDir ?
|
|
51109
|
-
const envInRoot =
|
|
51110
|
-
const envInWorktree = worktreePath ?
|
|
51284
|
+
const envInWorkDir = workDir ? fs33.existsSync(path33.join(workDir, `.env.agent.${agentId}`)) : false;
|
|
51285
|
+
const envInRoot = fs33.existsSync(path33.join(harnessRoot, `.env.agent.${agentId}`));
|
|
51286
|
+
const envInWorktree = worktreePath ? fs33.existsSync(path33.join(worktreePath, `.env.agent.${agentId}`)) : false;
|
|
51111
51287
|
const active = session !== void 0 && session.status !== "completed" || envInWorkDir || envInRoot || envInWorktree;
|
|
51112
51288
|
const latest = latestRunForAgent(runs, agentId);
|
|
51113
51289
|
const verifyRun = runs.find((r2) => r2.agentId === agentId && r2.stageId === "verify");
|
|
@@ -51161,7 +51337,7 @@ function collectEnvironmentStatus(repoPath) {
|
|
|
51161
51337
|
const slotIds = getAgentSlotIds(harnessRoot);
|
|
51162
51338
|
const pm2Procs = listPm2Processes2();
|
|
51163
51339
|
return {
|
|
51164
|
-
repoPath:
|
|
51340
|
+
repoPath: path33.resolve(repoPath),
|
|
51165
51341
|
harnessRoot,
|
|
51166
51342
|
gitRemote: readGitRemote(harnessRoot),
|
|
51167
51343
|
profile: manifest?.profile,
|
|
@@ -51172,13 +51348,13 @@ function collectEnvironmentStatus(repoPath) {
|
|
|
51172
51348
|
|
|
51173
51349
|
// src/core/validations.ts
|
|
51174
51350
|
var crypto3 = __toESM(require("crypto"));
|
|
51175
|
-
var
|
|
51176
|
-
var
|
|
51351
|
+
var fs35 = __toESM(require("fs"));
|
|
51352
|
+
var path35 = __toESM(require("path"));
|
|
51177
51353
|
|
|
51178
51354
|
// src/core/change-batch.ts
|
|
51179
|
-
var
|
|
51180
|
-
var
|
|
51181
|
-
var
|
|
51355
|
+
var fs34 = __toESM(require("fs"));
|
|
51356
|
+
var os9 = __toESM(require("os"));
|
|
51357
|
+
var path34 = __toESM(require("path"));
|
|
51182
51358
|
function git(checkoutDir, args, env3) {
|
|
51183
51359
|
const result = run(`git ${args}`, { cwd: checkoutDir, env: env3 });
|
|
51184
51360
|
if (result.code !== 0) {
|
|
@@ -51194,7 +51370,7 @@ function isCheckoutRoot(checkoutDir) {
|
|
|
51194
51370
|
const toplevel = tryGit2(checkoutDir, "rev-parse --show-toplevel");
|
|
51195
51371
|
if (!toplevel) return false;
|
|
51196
51372
|
try {
|
|
51197
|
-
return
|
|
51373
|
+
return fs34.realpathSync(toplevel) === fs34.realpathSync(checkoutDir);
|
|
51198
51374
|
} catch {
|
|
51199
51375
|
return false;
|
|
51200
51376
|
}
|
|
@@ -51216,7 +51392,7 @@ function isMergeOrRebaseInProgress(checkoutDir) {
|
|
|
51216
51392
|
if (tryGit2(checkoutDir, "rev-parse -q --verify MERGE_HEAD") !== void 0) return true;
|
|
51217
51393
|
for (const dir of ["rebase-merge", "rebase-apply"]) {
|
|
51218
51394
|
const gitPath = tryGit2(checkoutDir, `rev-parse --git-path ${dir}`);
|
|
51219
|
-
if (gitPath &&
|
|
51395
|
+
if (gitPath && fs34.existsSync(path34.resolve(checkoutDir, gitPath))) return true;
|
|
51220
51396
|
}
|
|
51221
51397
|
return false;
|
|
51222
51398
|
}
|
|
@@ -51239,8 +51415,8 @@ function parseNameStatus(output) {
|
|
|
51239
51415
|
return files;
|
|
51240
51416
|
}
|
|
51241
51417
|
function computeWorktreeSnapshot(checkoutDir) {
|
|
51242
|
-
const tmpDir =
|
|
51243
|
-
const tmpIndex =
|
|
51418
|
+
const tmpDir = fs34.mkdtempSync(path34.join(os9.tmpdir(), "har-idx-"));
|
|
51419
|
+
const tmpIndex = path34.join(tmpDir, "index");
|
|
51244
51420
|
const env3 = { GIT_INDEX_FILE: tmpIndex };
|
|
51245
51421
|
try {
|
|
51246
51422
|
const headTree = getHeadTree(checkoutDir);
|
|
@@ -51263,35 +51439,35 @@ function computeWorktreeSnapshot(checkoutDir) {
|
|
|
51263
51439
|
changedFiles: parseNameStatus(diffOutput)
|
|
51264
51440
|
};
|
|
51265
51441
|
} finally {
|
|
51266
|
-
|
|
51442
|
+
fs34.rmSync(tmpDir, { recursive: true, force: true });
|
|
51267
51443
|
}
|
|
51268
51444
|
}
|
|
51269
51445
|
|
|
51270
51446
|
// src/core/validations.ts
|
|
51271
51447
|
var VALIDATIONS_DIR = "validations";
|
|
51272
51448
|
function getValidationsDir(checkoutDir) {
|
|
51273
|
-
return
|
|
51449
|
+
return path35.join(checkoutDir, ".har", VALIDATIONS_DIR);
|
|
51274
51450
|
}
|
|
51275
51451
|
function validationPath(checkoutDir, treeHash) {
|
|
51276
|
-
return
|
|
51452
|
+
return path35.join(getValidationsDir(checkoutDir), `${treeHash}.json`);
|
|
51277
51453
|
}
|
|
51278
51454
|
function writeRecord(checkoutDir, record2) {
|
|
51279
51455
|
const dir = getValidationsDir(checkoutDir);
|
|
51280
|
-
|
|
51281
|
-
|
|
51456
|
+
fs35.mkdirSync(dir, { recursive: true });
|
|
51457
|
+
fs35.writeFileSync(
|
|
51282
51458
|
validationPath(checkoutDir, record2.treeHash),
|
|
51283
51459
|
`${JSON.stringify(record2, null, 2)}
|
|
51284
51460
|
`
|
|
51285
51461
|
);
|
|
51286
51462
|
}
|
|
51287
51463
|
function ensureValidationsIgnored(checkoutDir) {
|
|
51288
|
-
const harDir =
|
|
51289
|
-
if (!
|
|
51290
|
-
const gitignorePath =
|
|
51291
|
-
const content =
|
|
51464
|
+
const harDir = path35.join(checkoutDir, ".har");
|
|
51465
|
+
if (!fs35.existsSync(harDir)) return;
|
|
51466
|
+
const gitignorePath = path35.join(harDir, ".gitignore");
|
|
51467
|
+
const content = fs35.existsSync(gitignorePath) ? fs35.readFileSync(gitignorePath, "utf8") : "";
|
|
51292
51468
|
if (content.split("\n").some((line) => line.trim() === `${VALIDATIONS_DIR}/`)) return;
|
|
51293
51469
|
const suffix = content.length === 0 || content.endsWith("\n") ? "" : "\n";
|
|
51294
|
-
|
|
51470
|
+
fs35.writeFileSync(gitignorePath, `${content}${suffix}${VALIDATIONS_DIR}/
|
|
51295
51471
|
`);
|
|
51296
51472
|
}
|
|
51297
51473
|
function recordValidation(input) {
|
|
@@ -51308,8 +51484,8 @@ function recordValidation(input) {
|
|
|
51308
51484
|
treeHash: snapshot.treeHash,
|
|
51309
51485
|
headSha: snapshot.headSha,
|
|
51310
51486
|
branch: snapshot.branch,
|
|
51311
|
-
workDir:
|
|
51312
|
-
harnessRoot:
|
|
51487
|
+
workDir: path35.resolve(input.checkoutDir),
|
|
51488
|
+
harnessRoot: path35.resolve(input.harnessRoot),
|
|
51313
51489
|
agentId: input.agentId,
|
|
51314
51490
|
status: input.status,
|
|
51315
51491
|
full: input.full,
|
|
@@ -51321,16 +51497,16 @@ function recordValidation(input) {
|
|
|
51321
51497
|
committedAt: existing?.committedAt
|
|
51322
51498
|
});
|
|
51323
51499
|
writeRecord(input.checkoutDir, record2);
|
|
51324
|
-
if (
|
|
51500
|
+
if (path35.resolve(input.harnessRoot) !== path35.resolve(input.checkoutDir)) {
|
|
51325
51501
|
writeRecord(input.harnessRoot, record2);
|
|
51326
51502
|
}
|
|
51327
51503
|
return record2;
|
|
51328
51504
|
}
|
|
51329
51505
|
function findValidation(checkoutDir, treeHash) {
|
|
51330
51506
|
const file = validationPath(checkoutDir, treeHash);
|
|
51331
|
-
if (!
|
|
51507
|
+
if (!fs35.existsSync(file)) return void 0;
|
|
51332
51508
|
try {
|
|
51333
|
-
return ValidationRecordSchema.parse(JSON.parse(
|
|
51509
|
+
return ValidationRecordSchema.parse(JSON.parse(fs35.readFileSync(file, "utf8")));
|
|
51334
51510
|
} catch {
|
|
51335
51511
|
return void 0;
|
|
51336
51512
|
}
|
|
@@ -51345,19 +51521,19 @@ function attachCommit(checkoutDir, treeHash, commitSha) {
|
|
|
51345
51521
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
51346
51522
|
};
|
|
51347
51523
|
writeRecord(checkoutDir, updated);
|
|
51348
|
-
if (record2.harnessRoot &&
|
|
51524
|
+
if (record2.harnessRoot && path35.resolve(record2.harnessRoot) !== path35.resolve(checkoutDir) && fs35.existsSync(path35.join(record2.harnessRoot, ".har"))) {
|
|
51349
51525
|
writeRecord(record2.harnessRoot, updated);
|
|
51350
51526
|
}
|
|
51351
51527
|
return updated;
|
|
51352
51528
|
}
|
|
51353
51529
|
function listValidations(harnessRoot) {
|
|
51354
51530
|
const dir = getValidationsDir(harnessRoot);
|
|
51355
|
-
if (!
|
|
51531
|
+
if (!fs35.existsSync(dir)) return [];
|
|
51356
51532
|
const records = [];
|
|
51357
|
-
for (const entry of
|
|
51533
|
+
for (const entry of fs35.readdirSync(dir)) {
|
|
51358
51534
|
if (!entry.endsWith(".json")) continue;
|
|
51359
51535
|
try {
|
|
51360
|
-
records.push(ValidationRecordSchema.parse(JSON.parse(
|
|
51536
|
+
records.push(ValidationRecordSchema.parse(JSON.parse(fs35.readFileSync(path35.join(dir, entry), "utf8"))));
|
|
51361
51537
|
} catch {
|
|
51362
51538
|
}
|
|
51363
51539
|
}
|
|
@@ -51366,46 +51542,46 @@ function listValidations(harnessRoot) {
|
|
|
51366
51542
|
|
|
51367
51543
|
// src/core/work-units.ts
|
|
51368
51544
|
var crypto4 = __toESM(require("crypto"));
|
|
51369
|
-
var
|
|
51370
|
-
var
|
|
51545
|
+
var fs36 = __toESM(require("fs"));
|
|
51546
|
+
var path36 = __toESM(require("path"));
|
|
51371
51547
|
var WORK_UNITS_DIR = "work-units";
|
|
51372
51548
|
var WORK_ATTEMPTS_DIR = "work-attempts";
|
|
51373
51549
|
var VALIDATION_BINDINGS_DIR = "validation-bindings";
|
|
51374
51550
|
var EVIDENCE_DIRS = [WORK_UNITS_DIR, WORK_ATTEMPTS_DIR, VALIDATION_BINDINGS_DIR];
|
|
51375
51551
|
function harEvidenceDir(harnessRoot, name) {
|
|
51376
|
-
return
|
|
51552
|
+
return path36.join(harnessRoot, ".har", name);
|
|
51377
51553
|
}
|
|
51378
51554
|
function hashedRecordPath(harnessRoot, dir, id) {
|
|
51379
51555
|
const digest = crypto4.createHash("sha256").update(id).digest("hex");
|
|
51380
|
-
return
|
|
51556
|
+
return path36.join(harEvidenceDir(harnessRoot, dir), `${digest}.json`);
|
|
51381
51557
|
}
|
|
51382
51558
|
function writeRecord2(file, value) {
|
|
51383
|
-
|
|
51559
|
+
fs36.mkdirSync(path36.dirname(file), { recursive: true });
|
|
51384
51560
|
const temp = `${file}.${process.pid}.tmp`;
|
|
51385
|
-
|
|
51561
|
+
fs36.writeFileSync(temp, `${JSON.stringify(value, null, 2)}
|
|
51386
51562
|
`);
|
|
51387
|
-
|
|
51563
|
+
fs36.renameSync(temp, file);
|
|
51388
51564
|
}
|
|
51389
51565
|
function ensureWorkEvidenceIgnored(harnessRoot) {
|
|
51390
|
-
const harDir =
|
|
51391
|
-
if (!
|
|
51392
|
-
const gitignorePath =
|
|
51393
|
-
const content =
|
|
51566
|
+
const harDir = path36.join(harnessRoot, ".har");
|
|
51567
|
+
if (!fs36.existsSync(harDir)) return;
|
|
51568
|
+
const gitignorePath = path36.join(harDir, ".gitignore");
|
|
51569
|
+
const content = fs36.existsSync(gitignorePath) ? fs36.readFileSync(gitignorePath, "utf8") : "";
|
|
51394
51570
|
const lines2 = new Set(content.split("\n").map((line) => line.trim()));
|
|
51395
51571
|
const missing = EVIDENCE_DIRS.map((dir) => `${dir}/`).filter((dir) => !lines2.has(dir));
|
|
51396
51572
|
if (missing.length === 0) return;
|
|
51397
51573
|
const separator = content.length === 0 || content.endsWith("\n") ? "" : "\n";
|
|
51398
|
-
|
|
51574
|
+
fs36.writeFileSync(gitignorePath, `${content}${separator}${missing.join("\n")}
|
|
51399
51575
|
`);
|
|
51400
51576
|
}
|
|
51401
51577
|
function listRecords(harnessRoot, dir, parse4) {
|
|
51402
51578
|
const recordDir = harEvidenceDir(harnessRoot, dir);
|
|
51403
|
-
if (!
|
|
51579
|
+
if (!fs36.existsSync(recordDir)) return [];
|
|
51404
51580
|
const records = [];
|
|
51405
|
-
for (const name of
|
|
51581
|
+
for (const name of fs36.readdirSync(recordDir)) {
|
|
51406
51582
|
if (!name.endsWith(".json")) continue;
|
|
51407
51583
|
try {
|
|
51408
|
-
records.push(parse4(JSON.parse(
|
|
51584
|
+
records.push(parse4(JSON.parse(fs36.readFileSync(path36.join(recordDir, name), "utf8"))));
|
|
51409
51585
|
} catch {
|
|
51410
51586
|
}
|
|
51411
51587
|
}
|
|
@@ -51414,9 +51590,9 @@ function listRecords(harnessRoot, dir, parse4) {
|
|
|
51414
51590
|
function findWorkUnit(harnessRoot, workUnitId) {
|
|
51415
51591
|
const metadata = WorkUnitMetadataSchema.parse({ workUnitId });
|
|
51416
51592
|
const file = hashedRecordPath(harnessRoot, WORK_UNITS_DIR, metadata.workUnitId);
|
|
51417
|
-
if (!
|
|
51593
|
+
if (!fs36.existsSync(file)) return void 0;
|
|
51418
51594
|
try {
|
|
51419
|
-
return WorkUnitRecordSchema.parse(JSON.parse(
|
|
51595
|
+
return WorkUnitRecordSchema.parse(JSON.parse(fs36.readFileSync(file, "utf8")));
|
|
51420
51596
|
} catch {
|
|
51421
51597
|
return void 0;
|
|
51422
51598
|
}
|
|
@@ -51493,10 +51669,10 @@ function bindValidationToAttempt(harnessRoot, input) {
|
|
|
51493
51669
|
VALIDATION_BINDINGS_DIR,
|
|
51494
51670
|
stableKey
|
|
51495
51671
|
);
|
|
51496
|
-
if (
|
|
51672
|
+
if (fs36.existsSync(existingFile)) {
|
|
51497
51673
|
try {
|
|
51498
51674
|
return ValidationBindingRecordSchema.parse(
|
|
51499
|
-
JSON.parse(
|
|
51675
|
+
JSON.parse(fs36.readFileSync(existingFile, "utf8"))
|
|
51500
51676
|
);
|
|
51501
51677
|
} catch {
|
|
51502
51678
|
}
|
|
@@ -51557,14 +51733,14 @@ function createRemoteExecutor(apiUrl, apiKey) {
|
|
|
51557
51733
|
init_telemetry_config();
|
|
51558
51734
|
|
|
51559
51735
|
// src/core/usage-harvest/claude.ts
|
|
51560
|
-
var
|
|
51561
|
-
var
|
|
51562
|
-
var
|
|
51736
|
+
var fs39 = __toESM(require("fs"));
|
|
51737
|
+
var os11 = __toESM(require("os"));
|
|
51738
|
+
var path39 = __toESM(require("path"));
|
|
51563
51739
|
init_telemetry_config();
|
|
51564
51740
|
|
|
51565
51741
|
// src/core/telemetry-env.ts
|
|
51566
|
-
var
|
|
51567
|
-
var
|
|
51742
|
+
var fs38 = __toESM(require("fs"));
|
|
51743
|
+
var path38 = __toESM(require("path"));
|
|
51568
51744
|
init_control_config();
|
|
51569
51745
|
function escapeAttrValue(value) {
|
|
51570
51746
|
return value.replace(/[,=]/g, "_");
|
|
@@ -51610,8 +51786,8 @@ function appendTelemetryEnvToFile(envFilePath, attrs) {
|
|
|
51610
51786
|
${TELEMETRY_MARKER_END}
|
|
51611
51787
|
`;
|
|
51612
51788
|
let existing = "";
|
|
51613
|
-
if (
|
|
51614
|
-
existing =
|
|
51789
|
+
if (fs38.existsSync(envFilePath)) {
|
|
51790
|
+
existing = fs38.readFileSync(envFilePath, "utf8");
|
|
51615
51791
|
const start = existing.indexOf(TELEMETRY_MARKER_START);
|
|
51616
51792
|
if (start >= 0) {
|
|
51617
51793
|
const end = existing.indexOf(TELEMETRY_MARKER_END, start);
|
|
@@ -51622,28 +51798,28 @@ ${TELEMETRY_MARKER_END}
|
|
|
51622
51798
|
}
|
|
51623
51799
|
}
|
|
51624
51800
|
}
|
|
51625
|
-
|
|
51801
|
+
fs38.mkdirSync(path38.dirname(envFilePath), { recursive: true });
|
|
51626
51802
|
const combined = (existing.replace(/\n+$/, "\n") + block).replace(/^\n+/, "");
|
|
51627
|
-
|
|
51803
|
+
fs38.writeFileSync(envFilePath, combined.endsWith("\n") ? combined : combined + "\n");
|
|
51628
51804
|
}
|
|
51629
51805
|
|
|
51630
51806
|
// src/core/usage-harvest/claude.ts
|
|
51631
51807
|
function pathsMatch(candidate, targets) {
|
|
51632
|
-
const norm =
|
|
51808
|
+
const norm = path39.resolve(candidate);
|
|
51633
51809
|
return targets.some((t2) => {
|
|
51634
|
-
const target =
|
|
51635
|
-
return norm === target || norm.startsWith(target +
|
|
51810
|
+
const target = path39.resolve(t2);
|
|
51811
|
+
return norm === target || norm.startsWith(target + path39.sep) || target.startsWith(norm + path39.sep);
|
|
51636
51812
|
});
|
|
51637
51813
|
}
|
|
51638
51814
|
function claudeProjectsRoot() {
|
|
51639
|
-
return process.env.HAR_CLAUDE_PROJECTS_DIR ?
|
|
51815
|
+
return process.env.HAR_CLAUDE_PROJECTS_DIR ? path39.resolve(process.env.HAR_CLAUDE_PROJECTS_DIR) : path39.join(os11.homedir(), ".claude", "projects");
|
|
51640
51816
|
}
|
|
51641
51817
|
function encodeClaudeProjectDir(cwd) {
|
|
51642
51818
|
return cwd.replace(/[^a-zA-Z0-9]/g, "-");
|
|
51643
51819
|
}
|
|
51644
51820
|
function readJsonlRecords(filePath) {
|
|
51645
|
-
if (!
|
|
51646
|
-
const lines2 =
|
|
51821
|
+
if (!fs39.existsSync(filePath)) return [];
|
|
51822
|
+
const lines2 = fs39.readFileSync(filePath, "utf8").split(/\r?\n/);
|
|
51647
51823
|
const out = [];
|
|
51648
51824
|
for (const line of lines2) {
|
|
51649
51825
|
const trimmed = line.trim();
|
|
@@ -51661,6 +51837,7 @@ function extractClaudeUsageFromRecords(records) {
|
|
|
51661
51837
|
let tokensCacheRead = 0;
|
|
51662
51838
|
let tokensCacheCreation = 0;
|
|
51663
51839
|
let costUsd = null;
|
|
51840
|
+
const modelBreakdown = {};
|
|
51664
51841
|
for (const record2 of records) {
|
|
51665
51842
|
if (!record2 || typeof record2 !== "object") continue;
|
|
51666
51843
|
const payload = record2;
|
|
@@ -51672,30 +51849,50 @@ function extractClaudeUsageFromRecords(records) {
|
|
|
51672
51849
|
tokensCacheCreation = Number(usage2.cache_creation_input_tokens ?? 0);
|
|
51673
51850
|
if (payload.total_cost_usd != null) costUsd = Number(payload.total_cost_usd);
|
|
51674
51851
|
}
|
|
51675
|
-
const
|
|
51852
|
+
const message = payload.message;
|
|
51853
|
+
const nestedUsage = payload.usage ?? message?.usage;
|
|
51676
51854
|
if (nestedUsage && payload.type !== "result") {
|
|
51677
|
-
|
|
51678
|
-
|
|
51679
|
-
|
|
51680
|
-
|
|
51855
|
+
const i2 = Number(nestedUsage.input_tokens ?? 0);
|
|
51856
|
+
const o2 = Number(nestedUsage.output_tokens ?? 0);
|
|
51857
|
+
const cr2 = Number(nestedUsage.cache_read_input_tokens ?? 0);
|
|
51858
|
+
const cc = Number(nestedUsage.cache_creation_input_tokens ?? 0);
|
|
51859
|
+
tokensInput += i2;
|
|
51860
|
+
tokensOutput += o2;
|
|
51861
|
+
tokensCacheRead += cr2;
|
|
51862
|
+
tokensCacheCreation += cc;
|
|
51863
|
+
const model = typeof message?.model === "string" ? message.model : void 0;
|
|
51864
|
+
if (model && model !== "<synthetic>") {
|
|
51865
|
+
const totals = modelBreakdown[model] ??= {
|
|
51866
|
+
tokensInput: 0,
|
|
51867
|
+
tokensOutput: 0,
|
|
51868
|
+
tokensCacheRead: 0,
|
|
51869
|
+
tokensCacheCreation: 0,
|
|
51870
|
+
tokensTotal: 0
|
|
51871
|
+
};
|
|
51872
|
+
totals.tokensInput += i2;
|
|
51873
|
+
totals.tokensOutput += o2;
|
|
51874
|
+
totals.tokensCacheRead += cr2;
|
|
51875
|
+
totals.tokensCacheCreation += cc;
|
|
51876
|
+
totals.tokensTotal += i2 + o2 + cr2 + cc;
|
|
51877
|
+
}
|
|
51681
51878
|
}
|
|
51682
51879
|
}
|
|
51683
|
-
return { tokensInput, tokensOutput, tokensCacheRead, tokensCacheCreation, costUsd };
|
|
51880
|
+
return { tokensInput, tokensOutput, tokensCacheRead, tokensCacheCreation, costUsd, modelBreakdown };
|
|
51684
51881
|
}
|
|
51685
51882
|
function findMatchingClaudeTranscripts(slot) {
|
|
51686
51883
|
const targets = [slot.workDir, slot.worktreePath].filter(Boolean);
|
|
51687
51884
|
if (targets.length === 0) return [];
|
|
51688
51885
|
const root = claudeProjectsRoot();
|
|
51689
|
-
if (!
|
|
51886
|
+
if (!fs39.existsSync(root)) return [];
|
|
51690
51887
|
const matches = [];
|
|
51691
|
-
for (const entry of
|
|
51888
|
+
for (const entry of fs39.readdirSync(root, { withFileTypes: true })) {
|
|
51692
51889
|
if (!entry.isDirectory()) continue;
|
|
51693
|
-
const projectDir =
|
|
51890
|
+
const projectDir = path39.join(root, entry.name);
|
|
51694
51891
|
const encodedHit = targets.some((t2) => entry.name.includes(encodeClaudeProjectDir(t2).slice(0, 40)));
|
|
51695
|
-
for (const file of
|
|
51892
|
+
for (const file of fs39.readdirSync(projectDir)) {
|
|
51696
51893
|
if (!file.endsWith(".jsonl")) continue;
|
|
51697
|
-
const filePath =
|
|
51698
|
-
const stat =
|
|
51894
|
+
const filePath = path39.join(projectDir, file);
|
|
51895
|
+
const stat = fs39.statSync(filePath);
|
|
51699
51896
|
const records = readJsonlRecords(filePath);
|
|
51700
51897
|
let cwdHit = encodedHit;
|
|
51701
51898
|
for (const record2 of records) {
|
|
@@ -51787,6 +51984,7 @@ function harvestClaudeUsage(slot) {
|
|
|
51787
51984
|
tokensCacheCreation: best.tokensCacheCreation,
|
|
51788
51985
|
tokensTotal,
|
|
51789
51986
|
costUsd: best.costUsd,
|
|
51987
|
+
...Object.keys(best.modelBreakdown).length > 0 ? { modelBreakdown: best.modelBreakdown } : {},
|
|
51790
51988
|
sources: ["harvest"],
|
|
51791
51989
|
firstSeenAt: slot.sessionCreatedAt ?? now,
|
|
51792
51990
|
lastSeenAt: now
|
|
@@ -51806,30 +52004,30 @@ function harvestClaudeEvents(slot) {
|
|
|
51806
52004
|
}
|
|
51807
52005
|
|
|
51808
52006
|
// src/core/usage-harvest/codex.ts
|
|
51809
|
-
var
|
|
51810
|
-
var
|
|
51811
|
-
var
|
|
52007
|
+
var fs40 = __toESM(require("fs"));
|
|
52008
|
+
var os12 = __toESM(require("os"));
|
|
52009
|
+
var path40 = __toESM(require("path"));
|
|
51812
52010
|
function pathsMatch2(candidate, targets) {
|
|
51813
|
-
const norm =
|
|
52011
|
+
const norm = path40.resolve(candidate);
|
|
51814
52012
|
return targets.some((t2) => {
|
|
51815
|
-
const target =
|
|
51816
|
-
return norm === target || norm.startsWith(target +
|
|
52013
|
+
const target = path40.resolve(t2);
|
|
52014
|
+
return norm === target || norm.startsWith(target + path40.sep) || target.startsWith(norm + path40.sep);
|
|
51817
52015
|
});
|
|
51818
52016
|
}
|
|
51819
52017
|
function codexSessionsRoot() {
|
|
51820
|
-
return process.env.HAR_CODEX_SESSIONS_DIR ?
|
|
52018
|
+
return process.env.HAR_CODEX_SESSIONS_DIR ? path40.resolve(process.env.HAR_CODEX_SESSIONS_DIR) : path40.join(os12.homedir(), ".codex", "sessions");
|
|
51821
52019
|
}
|
|
51822
52020
|
function walkJsonlFiles(dir, out = []) {
|
|
51823
|
-
if (!
|
|
51824
|
-
for (const entry of
|
|
51825
|
-
const full =
|
|
52021
|
+
if (!fs40.existsSync(dir)) return out;
|
|
52022
|
+
for (const entry of fs40.readdirSync(dir, { withFileTypes: true })) {
|
|
52023
|
+
const full = path40.join(dir, entry.name);
|
|
51826
52024
|
if (entry.isDirectory()) walkJsonlFiles(full, out);
|
|
51827
52025
|
else if (entry.isFile() && entry.name.endsWith(".jsonl")) out.push(full);
|
|
51828
52026
|
}
|
|
51829
52027
|
return out;
|
|
51830
52028
|
}
|
|
51831
52029
|
function readJsonl(filePath) {
|
|
51832
|
-
const lines2 =
|
|
52030
|
+
const lines2 = fs40.readFileSync(filePath, "utf8").split(/\r?\n/);
|
|
51833
52031
|
const out = [];
|
|
51834
52032
|
for (const line of lines2) {
|
|
51835
52033
|
const trimmed = line.trim();
|
|
@@ -51893,7 +52091,7 @@ function harvestCodexUsage(slot) {
|
|
|
51893
52091
|
const extracted = extractCodexTokens(records);
|
|
51894
52092
|
if (!extracted.cwd || !pathsMatch2(extracted.cwd, targets)) continue;
|
|
51895
52093
|
if (extracted.tokensInput + extracted.tokensOutput + extracted.tokensCacheRead === 0) continue;
|
|
51896
|
-
const mtime =
|
|
52094
|
+
const mtime = fs40.statSync(file).mtimeMs;
|
|
51897
52095
|
if (mtime >= bestMtime) {
|
|
51898
52096
|
bestMtime = mtime;
|
|
51899
52097
|
best = extracted;
|
|
@@ -51948,6 +52146,119 @@ async function postJson(url, body, dryRun) {
|
|
|
51948
52146
|
}
|
|
51949
52147
|
return await response.json();
|
|
51950
52148
|
}
|
|
52149
|
+
async function postPortal(target, endpoint, body, dryRun) {
|
|
52150
|
+
if (dryRun) return;
|
|
52151
|
+
const response = await fetch(`${target.url}${endpoint}`, {
|
|
52152
|
+
method: "POST",
|
|
52153
|
+
headers: {
|
|
52154
|
+
"Content-Type": "application/json",
|
|
52155
|
+
Authorization: `Bearer ${target.token}`
|
|
52156
|
+
},
|
|
52157
|
+
body: JSON.stringify(body)
|
|
52158
|
+
});
|
|
52159
|
+
if (!response.ok) {
|
|
52160
|
+
if (response.status === 401 || response.status === 403) {
|
|
52161
|
+
throw new Error(
|
|
52162
|
+
`har-portal rejected the ingest token (HTTP ${response.status}) \u2014 check HAR_PORTAL_TOKEN.`
|
|
52163
|
+
);
|
|
52164
|
+
}
|
|
52165
|
+
const text = await response.text().catch(() => "");
|
|
52166
|
+
throw new Error(`har-portal sync failed: HTTP ${response.status}${text ? ` \u2014 ${text}` : ""}`);
|
|
52167
|
+
}
|
|
52168
|
+
}
|
|
52169
|
+
function resolvePortalUserEmail() {
|
|
52170
|
+
return readPortalCredentials()?.email || void 0;
|
|
52171
|
+
}
|
|
52172
|
+
function dropNullFields(record2) {
|
|
52173
|
+
return Object.fromEntries(Object.entries(record2).filter(([, value]) => value !== null));
|
|
52174
|
+
}
|
|
52175
|
+
function modelsFromBreakdown(breakdown) {
|
|
52176
|
+
if (!breakdown) return [];
|
|
52177
|
+
return Object.entries(breakdown).map(([model, totals]) => ({
|
|
52178
|
+
model,
|
|
52179
|
+
...totals && typeof totals === "object" ? totals : {}
|
|
52180
|
+
}));
|
|
52181
|
+
}
|
|
52182
|
+
function collectPortalTelemetry(repoPath, slots) {
|
|
52183
|
+
if (!isTelemetryEnabled()) return { usage: [], events: [] };
|
|
52184
|
+
try {
|
|
52185
|
+
const userEmail = resolvePortalUserEmail();
|
|
52186
|
+
const usage2 = slots.flatMap(
|
|
52187
|
+
(slot) => harvestUsageForSlot({
|
|
52188
|
+
agentId: slot.agentId,
|
|
52189
|
+
workDir: slot.workDir,
|
|
52190
|
+
worktreePath: slot.worktreePath,
|
|
52191
|
+
branch: slot.branch,
|
|
52192
|
+
suffix: slot.suffix,
|
|
52193
|
+
sessionCreatedAt: slot.sessionCreatedAt,
|
|
52194
|
+
repoPath
|
|
52195
|
+
}).map((row) => {
|
|
52196
|
+
const models = modelsFromBreakdown(
|
|
52197
|
+
row.modelBreakdown
|
|
52198
|
+
);
|
|
52199
|
+
return {
|
|
52200
|
+
...row,
|
|
52201
|
+
workUnitId: slot.workUnitId ?? row.workUnitId,
|
|
52202
|
+
attemptId: slot.attemptId ?? row.attemptId,
|
|
52203
|
+
sessionKey: row.sessionKey || buildSessionKey({
|
|
52204
|
+
branch: slot.branch,
|
|
52205
|
+
agentId: slot.agentId,
|
|
52206
|
+
suffix: slot.suffix,
|
|
52207
|
+
createdAt: slot.sessionCreatedAt
|
|
52208
|
+
}),
|
|
52209
|
+
...userEmail ? { userEmail } : {},
|
|
52210
|
+
...models.length > 0 ? { models } : {}
|
|
52211
|
+
};
|
|
52212
|
+
})
|
|
52213
|
+
);
|
|
52214
|
+
const events = slots.flatMap(
|
|
52215
|
+
(slot) => harvestEventsForSlot({
|
|
52216
|
+
agentId: slot.agentId,
|
|
52217
|
+
workDir: slot.workDir,
|
|
52218
|
+
worktreePath: slot.worktreePath,
|
|
52219
|
+
branch: slot.branch,
|
|
52220
|
+
suffix: slot.suffix,
|
|
52221
|
+
sessionCreatedAt: slot.sessionCreatedAt,
|
|
52222
|
+
repoPath
|
|
52223
|
+
}).map(
|
|
52224
|
+
(event) => dropNullFields({
|
|
52225
|
+
...event,
|
|
52226
|
+
workUnitId: slot.workUnitId ?? event.workUnitId,
|
|
52227
|
+
attemptId: slot.attemptId ?? event.attemptId
|
|
52228
|
+
})
|
|
52229
|
+
)
|
|
52230
|
+
);
|
|
52231
|
+
return { usage: usage2, events };
|
|
52232
|
+
} catch {
|
|
52233
|
+
return { usage: [], events: [] };
|
|
52234
|
+
}
|
|
52235
|
+
}
|
|
52236
|
+
function buildPortalPayload(repoPath) {
|
|
52237
|
+
const runs = listRuns(repoPath);
|
|
52238
|
+
const status = collectEnvironmentStatus(repoPath);
|
|
52239
|
+
const manifest = readManifest(repoPath);
|
|
52240
|
+
const stagesRegistry = readStageRegistry(repoPath);
|
|
52241
|
+
const harnessRoot = resolveHarnessRoot(repoPath);
|
|
52242
|
+
const validations = listValidations(harnessRoot);
|
|
52243
|
+
const workUnits = listWorkUnits(harnessRoot);
|
|
52244
|
+
const attempts = listWorkAttempts(harnessRoot);
|
|
52245
|
+
const validationBindings = listValidationBindings(harnessRoot);
|
|
52246
|
+
const { usage: usage2, events } = collectPortalTelemetry(repoPath, status.slots);
|
|
52247
|
+
const syncBody = {
|
|
52248
|
+
path: repoPath,
|
|
52249
|
+
...manifest ? { manifest } : {},
|
|
52250
|
+
...stagesRegistry ? { stagesRegistry } : {},
|
|
52251
|
+
runs,
|
|
52252
|
+
slots: status.slots,
|
|
52253
|
+
generatedAt: status.generatedAt,
|
|
52254
|
+
...validations.length > 0 ? { validations } : {},
|
|
52255
|
+
...workUnits.length > 0 ? { workUnits } : {},
|
|
52256
|
+
...attempts.length > 0 ? { attempts } : {},
|
|
52257
|
+
...validationBindings.length > 0 ? { validationBindings } : {},
|
|
52258
|
+
...usage2.length > 0 ? { usage: usage2 } : {}
|
|
52259
|
+
};
|
|
52260
|
+
return { syncBody, events };
|
|
52261
|
+
}
|
|
51951
52262
|
async function isControlApiReachable(apiUrl = getControlApiUrl()) {
|
|
51952
52263
|
try {
|
|
51953
52264
|
const response = await fetch(`${apiUrl}/api/health`, {
|
|
@@ -51963,14 +52274,15 @@ async function waitForControlApi(apiUrl = getControlApiUrl(), timeoutMs = 6e4, i
|
|
|
51963
52274
|
const deadline = Date.now() + timeoutMs;
|
|
51964
52275
|
while (Date.now() < deadline) {
|
|
51965
52276
|
if (await isControlApiReachable(apiUrl)) return true;
|
|
51966
|
-
await new Promise((
|
|
52277
|
+
await new Promise((resolve38) => setTimeout(resolve38, intervalMs));
|
|
51967
52278
|
}
|
|
51968
52279
|
return false;
|
|
51969
52280
|
}
|
|
51970
52281
|
async function syncAllKnownReposWithControl(options) {
|
|
51971
52282
|
if (!isControlEnabled()) return { synced: 0, failed: 0 };
|
|
51972
52283
|
const apiUrl = options?.apiUrl ?? getControlApiUrl();
|
|
51973
|
-
|
|
52284
|
+
const portal = getPortalTarget();
|
|
52285
|
+
if (!await isControlApiReachable(portal ? portal.url : apiUrl)) {
|
|
51974
52286
|
return { synced: 0, failed: 0 };
|
|
51975
52287
|
}
|
|
51976
52288
|
const repoPaths = new Set(listRegisteredRepos());
|
|
@@ -52061,13 +52373,27 @@ async function syncRepoWithControl(options) {
|
|
|
52061
52373
|
}
|
|
52062
52374
|
return;
|
|
52063
52375
|
}
|
|
52376
|
+
const portal = getPortalTarget();
|
|
52377
|
+
if (portal) {
|
|
52378
|
+
const { syncBody, events } = buildPortalPayload(repoPath);
|
|
52379
|
+
await postPortal(portal, "/api/sync", syncBody, options.dryRun);
|
|
52380
|
+
if (events.length > 0) {
|
|
52381
|
+
await postPortal(
|
|
52382
|
+
portal,
|
|
52383
|
+
"/api/otel",
|
|
52384
|
+
{ path: repoPath, events, spans: [] },
|
|
52385
|
+
options.dryRun
|
|
52386
|
+
);
|
|
52387
|
+
}
|
|
52388
|
+
return;
|
|
52389
|
+
}
|
|
52064
52390
|
const registerResult = await registerRepoWithControl({ ...options, repoPath });
|
|
52065
52391
|
const repoId = registerResult?.id;
|
|
52066
52392
|
if (!repoId && !options.dryRun) {
|
|
52067
52393
|
const listResponse = await fetch(`${apiUrl}/api/repos`);
|
|
52068
52394
|
if (!listResponse.ok) throw new Error("Failed to list repos from Control API");
|
|
52069
52395
|
const repos = await listResponse.json();
|
|
52070
|
-
const existing = repos.find((r2) =>
|
|
52396
|
+
const existing = repos.find((r2) => path41.resolve(r2.path) === repoPath);
|
|
52071
52397
|
if (!existing) {
|
|
52072
52398
|
return;
|
|
52073
52399
|
}
|
|
@@ -52175,17 +52501,18 @@ async function syncRepoWithControlAsync(repoPath) {
|
|
|
52175
52501
|
if (process.env.HAR_CONTROL_DISABLED === "true" || process.env.NODE_ENV === "test") return;
|
|
52176
52502
|
const verbose = process.env.HAR_CONTROL_VERBOSE === "true";
|
|
52177
52503
|
try {
|
|
52178
|
-
const
|
|
52179
|
-
|
|
52504
|
+
const portal = getPortalTarget();
|
|
52505
|
+
const healthUrl = portal ? portal.url : getControlApiUrl();
|
|
52506
|
+
if (!await isControlApiReachable(healthUrl)) {
|
|
52180
52507
|
if (verbose) {
|
|
52181
|
-
process.stderr.write(`[har control] sync skipped:
|
|
52508
|
+
process.stderr.write(`[har control] sync skipped: not reachable at ${healthUrl}
|
|
52182
52509
|
`);
|
|
52183
52510
|
}
|
|
52184
52511
|
return;
|
|
52185
52512
|
}
|
|
52186
52513
|
const canonical = canonicalizeControlRepoPath(repoPath);
|
|
52187
52514
|
await withTimeout(
|
|
52188
|
-
syncRepoWithControl({ repoPath: canonical
|
|
52515
|
+
syncRepoWithControl({ repoPath: canonical }),
|
|
52189
52516
|
SYNC_TIMEOUT_MS,
|
|
52190
52517
|
"control sync"
|
|
52191
52518
|
);
|
|
@@ -52218,8 +52545,8 @@ function checkLaunchGuard2(repoPath, agentId, options = {}) {
|
|
|
52218
52545
|
init_control_config();
|
|
52219
52546
|
|
|
52220
52547
|
// src/core/control-lifecycle.ts
|
|
52221
|
-
var
|
|
52222
|
-
var
|
|
52548
|
+
var import_child_process9 = require("child_process");
|
|
52549
|
+
var path42 = __toESM(require("path"));
|
|
52223
52550
|
|
|
52224
52551
|
// src/core/control-image.ts
|
|
52225
52552
|
var DEFAULT_CONTROL_IMAGE = "theosfactory/har-control";
|
|
@@ -52243,10 +52570,10 @@ var CONTROL_DATA_VOLUME = "har_control_data";
|
|
|
52243
52570
|
var CONTROL_CONTAINER_PORT = 3847;
|
|
52244
52571
|
var CONTROL_DATA_DB_URL = "file:/data/har_control.db";
|
|
52245
52572
|
function resolveControlDir() {
|
|
52246
|
-
return
|
|
52573
|
+
return path42.resolve(__dirname, "..", "control");
|
|
52247
52574
|
}
|
|
52248
52575
|
function resolveControlBuildContext() {
|
|
52249
|
-
return
|
|
52576
|
+
return path42.resolve(resolveControlDir(), "..");
|
|
52250
52577
|
}
|
|
52251
52578
|
function buildDockerRunArgs(options) {
|
|
52252
52579
|
const name = options.containerName ?? CONTROL_CONTAINER_NAME;
|
|
@@ -52269,7 +52596,7 @@ function buildDockerRunArgs(options) {
|
|
|
52269
52596
|
return args;
|
|
52270
52597
|
}
|
|
52271
52598
|
function runDocker(args) {
|
|
52272
|
-
const result = (0,
|
|
52599
|
+
const result = (0, import_child_process9.spawnSync)("docker", args, {
|
|
52273
52600
|
stdio: "inherit",
|
|
52274
52601
|
env: process.env
|
|
52275
52602
|
});
|
|
@@ -52279,7 +52606,7 @@ function runDocker(args) {
|
|
|
52279
52606
|
return result.status ?? 1;
|
|
52280
52607
|
}
|
|
52281
52608
|
function controlContainerExists(name = CONTROL_CONTAINER_NAME) {
|
|
52282
|
-
const result = (0,
|
|
52609
|
+
const result = (0, import_child_process9.spawnSync)("docker", ["ps", "-aq", "-f", `name=^${name}$`], {
|
|
52283
52610
|
encoding: "utf8",
|
|
52284
52611
|
stdio: ["pipe", "pipe", "ignore"]
|
|
52285
52612
|
});
|
|
@@ -52302,7 +52629,7 @@ async function startMissionControl(options) {
|
|
|
52302
52629
|
"-t",
|
|
52303
52630
|
imageRef,
|
|
52304
52631
|
"-f",
|
|
52305
|
-
|
|
52632
|
+
path42.join(resolveControlDir(), "Dockerfile"),
|
|
52306
52633
|
resolveControlBuildContext()
|
|
52307
52634
|
]);
|
|
52308
52635
|
if (buildCode !== 0) {
|
|
@@ -52446,7 +52773,7 @@ async function ensureTelemetryInfrastructure(options) {
|
|
|
52446
52773
|
|
|
52447
52774
|
// src/core/run-service.ts
|
|
52448
52775
|
init_telemetry_config();
|
|
52449
|
-
var
|
|
52776
|
+
var path44 = __toESM(require("path"));
|
|
52450
52777
|
function extractShellOutput(result) {
|
|
52451
52778
|
const stdout = result.logs?.find((log) => log.stream === "stdout")?.content ?? result.logs?.find((log) => !log.stream)?.content ?? "";
|
|
52452
52779
|
const stderr = result.logs?.find((log) => log.stream === "stderr")?.content ?? "";
|
|
@@ -52656,12 +52983,12 @@ Usage from Cursor / Claude / Codex (opentelemetry-hooks) will appear under Workt
|
|
|
52656
52983
|
suffix: session.suffix,
|
|
52657
52984
|
createdAt: session.createdAt
|
|
52658
52985
|
});
|
|
52659
|
-
const envFile =
|
|
52986
|
+
const envFile = path44.join(session.workDir, `.env.agent.${options.agentId}`);
|
|
52660
52987
|
try {
|
|
52661
52988
|
appendTelemetryEnvToFile(envFile, {
|
|
52662
52989
|
sessionKey,
|
|
52663
52990
|
agentId: options.agentId,
|
|
52664
|
-
repoPath:
|
|
52991
|
+
repoPath: path44.resolve(options.repoPath),
|
|
52665
52992
|
workDir: session.workDir,
|
|
52666
52993
|
branch: session.branch,
|
|
52667
52994
|
suffix: session.suffix,
|
|
@@ -52890,12 +53217,12 @@ var getEnvironmentStatus = defaultRunService.getEnvironmentStatus.bind(defaultRu
|
|
|
52890
53217
|
var getEnvironmentLogs = defaultRunService.getEnvironmentLogs.bind(defaultRunService);
|
|
52891
53218
|
|
|
52892
53219
|
// src/core/commit-gate-onboarding.ts
|
|
52893
|
-
var
|
|
53220
|
+
var readline6 = __toESM(require("readline"));
|
|
52894
53221
|
|
|
52895
53222
|
// src/core/hooks.ts
|
|
52896
|
-
var
|
|
52897
|
-
var
|
|
52898
|
-
var
|
|
53223
|
+
var fs42 = __toESM(require("fs"));
|
|
53224
|
+
var os14 = __toESM(require("os"));
|
|
53225
|
+
var path45 = __toESM(require("path"));
|
|
52899
53226
|
var MARKER_START = "# >>> har commit gate (managed by `har hooks`) >>>";
|
|
52900
53227
|
var MARKER_END = "# <<< har commit gate <<<";
|
|
52901
53228
|
var PRE_COMMIT_BLOCK = [
|
|
@@ -52920,7 +53247,7 @@ function resolveCheckoutRoot(cwd) {
|
|
|
52920
53247
|
function resolveHooksDir(checkoutDir) {
|
|
52921
53248
|
const hooksPath = tryGit3(checkoutDir, "rev-parse --git-path hooks");
|
|
52922
53249
|
if (!hooksPath) throw new Error(`Not a git checkout: ${checkoutDir}`);
|
|
52923
|
-
return
|
|
53250
|
+
return path45.resolve(checkoutDir, hooksPath);
|
|
52924
53251
|
}
|
|
52925
53252
|
function getConfiguredHooksPath(checkoutDir) {
|
|
52926
53253
|
return tryGit3(checkoutDir, "config core.hooksPath") || void 0;
|
|
@@ -52928,9 +53255,9 @@ function getConfiguredHooksPath(checkoutDir) {
|
|
|
52928
53255
|
function defaultHarInvocation() {
|
|
52929
53256
|
const entry = process.argv[1];
|
|
52930
53257
|
if (entry && entry.endsWith(".js")) {
|
|
52931
|
-
return `"${process.execPath}" "${
|
|
53258
|
+
return `"${process.execPath}" "${path45.resolve(entry)}"`;
|
|
52932
53259
|
}
|
|
52933
|
-
if (entry) return `"${
|
|
53260
|
+
if (entry) return `"${path45.resolve(entry)}"`;
|
|
52934
53261
|
return "har";
|
|
52935
53262
|
}
|
|
52936
53263
|
function buildHookScript(harInvocation, subcommand, failOpenNotice) {
|
|
@@ -52951,40 +53278,40 @@ exit 0
|
|
|
52951
53278
|
`;
|
|
52952
53279
|
}
|
|
52953
53280
|
function upsertMarkedBlock(filePath, block) {
|
|
52954
|
-
if (!
|
|
52955
|
-
|
|
53281
|
+
if (!fs42.existsSync(filePath)) {
|
|
53282
|
+
fs42.writeFileSync(filePath, `#!/bin/sh
|
|
52956
53283
|
${block}
|
|
52957
53284
|
`, { mode: 493 });
|
|
52958
53285
|
return "created";
|
|
52959
53286
|
}
|
|
52960
|
-
const content =
|
|
53287
|
+
const content = fs42.readFileSync(filePath, "utf8");
|
|
52961
53288
|
if (content.includes(MARKER_START)) {
|
|
52962
53289
|
const pattern = new RegExp(
|
|
52963
53290
|
`${escapeRegExp(MARKER_START)}[\\s\\S]*?${escapeRegExp(MARKER_END)}`
|
|
52964
53291
|
);
|
|
52965
|
-
|
|
52966
|
-
|
|
53292
|
+
fs42.writeFileSync(filePath, content.replace(pattern, block));
|
|
53293
|
+
fs42.chmodSync(filePath, 493);
|
|
52967
53294
|
return "updated";
|
|
52968
53295
|
}
|
|
52969
53296
|
const suffix = content.endsWith("\n") ? "" : "\n";
|
|
52970
|
-
|
|
53297
|
+
fs42.writeFileSync(filePath, `${content}${suffix}
|
|
52971
53298
|
${block}
|
|
52972
53299
|
`);
|
|
52973
|
-
|
|
53300
|
+
fs42.chmodSync(filePath, 493);
|
|
52974
53301
|
return "appended";
|
|
52975
53302
|
}
|
|
52976
53303
|
function removeMarkedBlock(filePath) {
|
|
52977
|
-
if (!
|
|
52978
|
-
const content =
|
|
53304
|
+
if (!fs42.existsSync(filePath)) return false;
|
|
53305
|
+
const content = fs42.readFileSync(filePath, "utf8");
|
|
52979
53306
|
if (!content.includes(MARKER_START)) return false;
|
|
52980
53307
|
const pattern = new RegExp(
|
|
52981
53308
|
`\\n?${escapeRegExp(MARKER_START)}[\\s\\S]*?${escapeRegExp(MARKER_END)}\\n?`
|
|
52982
53309
|
);
|
|
52983
53310
|
const stripped = content.replace(pattern, "\n");
|
|
52984
53311
|
if (stripped.replace(/^#!\/bin\/sh\n?/, "").trim() === "") {
|
|
52985
|
-
|
|
53312
|
+
fs42.rmSync(filePath);
|
|
52986
53313
|
} else {
|
|
52987
|
-
|
|
53314
|
+
fs42.writeFileSync(filePath, stripped);
|
|
52988
53315
|
}
|
|
52989
53316
|
return true;
|
|
52990
53317
|
}
|
|
@@ -53006,20 +53333,20 @@ Or re-run with --force to write into that directory anyway.`
|
|
|
53006
53333
|
);
|
|
53007
53334
|
}
|
|
53008
53335
|
const hooksDir = resolveHooksDir(checkout);
|
|
53009
|
-
|
|
53336
|
+
fs42.mkdirSync(hooksDir, { recursive: true });
|
|
53010
53337
|
const invocation = options.harInvocation ?? defaultHarInvocation();
|
|
53011
|
-
|
|
53012
|
-
|
|
53338
|
+
fs42.writeFileSync(
|
|
53339
|
+
path45.join(hooksDir, "har-pre-commit"),
|
|
53013
53340
|
buildHookScript(invocation, "check", "har: binary not found; skipping commit gate (reinstall with har hooks install)"),
|
|
53014
53341
|
{ mode: 493 }
|
|
53015
53342
|
);
|
|
53016
|
-
|
|
53017
|
-
|
|
53343
|
+
fs42.writeFileSync(
|
|
53344
|
+
path45.join(hooksDir, "har-post-commit"),
|
|
53018
53345
|
buildHookScript(invocation, "record-commit", "har: binary not found; skipping commit association"),
|
|
53019
53346
|
{ mode: 493 }
|
|
53020
53347
|
);
|
|
53021
|
-
const preCommit = upsertMarkedBlock(
|
|
53022
|
-
const postCommit = upsertMarkedBlock(
|
|
53348
|
+
const preCommit = upsertMarkedBlock(path45.join(hooksDir, "pre-commit"), PRE_COMMIT_BLOCK);
|
|
53349
|
+
const postCommit = upsertMarkedBlock(path45.join(hooksDir, "post-commit"), POST_COMMIT_BLOCK);
|
|
53023
53350
|
ensureValidationsIgnored(checkout);
|
|
53024
53351
|
return { hooksDir, preCommit, postCommit };
|
|
53025
53352
|
}
|
|
@@ -53028,12 +53355,12 @@ function uninstallHooks(repoPath) {
|
|
|
53028
53355
|
if (!checkout) throw new Error(`Not a git repository: ${repoPath}`);
|
|
53029
53356
|
const hooksDir = resolveHooksDir(checkout);
|
|
53030
53357
|
let removed = false;
|
|
53031
|
-
removed = removeMarkedBlock(
|
|
53032
|
-
removed = removeMarkedBlock(
|
|
53358
|
+
removed = removeMarkedBlock(path45.join(hooksDir, "pre-commit")) || removed;
|
|
53359
|
+
removed = removeMarkedBlock(path45.join(hooksDir, "post-commit")) || removed;
|
|
53033
53360
|
for (const file of ["har-pre-commit", "har-post-commit"]) {
|
|
53034
|
-
const full =
|
|
53035
|
-
if (
|
|
53036
|
-
|
|
53361
|
+
const full = path45.join(hooksDir, file);
|
|
53362
|
+
if (fs42.existsSync(full)) {
|
|
53363
|
+
fs42.rmSync(full);
|
|
53037
53364
|
removed = true;
|
|
53038
53365
|
}
|
|
53039
53366
|
}
|
|
@@ -53052,10 +53379,10 @@ function isAgentWorktree(checkoutDir) {
|
|
|
53052
53379
|
if (branch && (/^har-agent-\d+$/.test(branch) || /-har-agent-\d+-[a-z0-9]+$/.test(branch))) {
|
|
53053
53380
|
return true;
|
|
53054
53381
|
}
|
|
53055
|
-
const worktreesRoot =
|
|
53056
|
-
const resolved =
|
|
53057
|
-
const name =
|
|
53058
|
-
return resolved.startsWith(`${worktreesRoot}${
|
|
53382
|
+
const worktreesRoot = path45.join(os14.homedir(), "worktrees");
|
|
53383
|
+
const resolved = path45.resolve(checkoutDir);
|
|
53384
|
+
const name = path45.basename(resolved);
|
|
53385
|
+
return resolved.startsWith(`${worktreesRoot}${path45.sep}`) && (/-agent-\d+$/.test(name) || /-har-agent-\d+-[a-z0-9]+$/.test(name));
|
|
53059
53386
|
}
|
|
53060
53387
|
function resolveEffectiveMode(checkoutDir, gate) {
|
|
53061
53388
|
if (!gate.enabled) return "off";
|
|
@@ -53068,15 +53395,15 @@ function getHooksStatus(repoPath) {
|
|
|
53068
53395
|
const hooksDir = resolveHooksDir(checkout);
|
|
53069
53396
|
const gate = getCommitGateConfig(checkout);
|
|
53070
53397
|
const hasBlock = (name) => {
|
|
53071
|
-
const file =
|
|
53072
|
-
return
|
|
53398
|
+
const file = path45.join(hooksDir, name);
|
|
53399
|
+
return fs42.existsSync(file) && fs42.readFileSync(file, "utf8").includes(MARKER_START);
|
|
53073
53400
|
};
|
|
53074
53401
|
return {
|
|
53075
53402
|
checkout,
|
|
53076
53403
|
hooksDir,
|
|
53077
53404
|
configuredHooksPath: getConfiguredHooksPath(checkout),
|
|
53078
|
-
preCommitInstalled: hasBlock("pre-commit") &&
|
|
53079
|
-
postCommitInstalled: hasBlock("post-commit") &&
|
|
53405
|
+
preCommitInstalled: hasBlock("pre-commit") && fs42.existsSync(path45.join(hooksDir, "har-pre-commit")),
|
|
53406
|
+
postCommitInstalled: hasBlock("post-commit") && fs42.existsSync(path45.join(hooksDir, "har-post-commit")),
|
|
53080
53407
|
gate,
|
|
53081
53408
|
effectiveMode: resolveEffectiveMode(checkout, gate)
|
|
53082
53409
|
};
|
|
@@ -53087,7 +53414,7 @@ function checkCommitGate(cwd) {
|
|
|
53087
53414
|
}
|
|
53088
53415
|
const checkout = resolveCheckoutRoot(cwd);
|
|
53089
53416
|
if (!checkout) return { exitCode: 0, messages: [] };
|
|
53090
|
-
if (!
|
|
53417
|
+
if (!fs42.existsSync(path45.join(checkout, ".har", "stages.json"))) {
|
|
53091
53418
|
return { exitCode: 0, messages: [] };
|
|
53092
53419
|
}
|
|
53093
53420
|
const gate = getCommitGateConfig(checkout);
|
|
@@ -53158,14 +53485,14 @@ async function recordCommitAssociation(cwd) {
|
|
|
53158
53485
|
}
|
|
53159
53486
|
|
|
53160
53487
|
// src/core/commit-gate-onboarding.ts
|
|
53161
|
-
function
|
|
53162
|
-
const rl =
|
|
53163
|
-
return new Promise((
|
|
53488
|
+
function askYesNo5(question) {
|
|
53489
|
+
const rl = readline6.createInterface({ input: process.stdin, output: process.stderr });
|
|
53490
|
+
return new Promise((resolve38) => {
|
|
53164
53491
|
process.stderr.write(`${question} `);
|
|
53165
53492
|
rl.once("line", (answer) => {
|
|
53166
53493
|
rl.close();
|
|
53167
53494
|
const trimmed = answer.trim();
|
|
53168
|
-
|
|
53495
|
+
resolve38(trimmed === "" || /^y(es)?$/i.test(trimmed));
|
|
53169
53496
|
});
|
|
53170
53497
|
});
|
|
53171
53498
|
}
|
|
@@ -53190,7 +53517,7 @@ async function handleCommitGateOnboarding(options) {
|
|
|
53190
53517
|
const status = getHooksStatus(options.repoPath);
|
|
53191
53518
|
let shouldInstall = status.preCommitInstalled || status.postCommitInstalled || options.install === "always" || options.autoYes === true;
|
|
53192
53519
|
if (!shouldInstall && options.install === "prompt" && process.stdin.isTTY && process.stdout.isTTY) {
|
|
53193
|
-
shouldInstall = await
|
|
53520
|
+
shouldInstall = await askYesNo5("Install the HAR commit gate for this repository? [Y/n]");
|
|
53194
53521
|
}
|
|
53195
53522
|
if (!shouldInstall) {
|
|
53196
53523
|
info("Commit gate is not installed; run `har hooks install` when ready.");
|
|
@@ -53207,20 +53534,20 @@ async function handleCommitGateOnboarding(options) {
|
|
|
53207
53534
|
}
|
|
53208
53535
|
|
|
53209
53536
|
// src/core/onboarding-preferences.ts
|
|
53210
|
-
var
|
|
53211
|
-
var
|
|
53212
|
-
var
|
|
53537
|
+
var fs43 = __toESM(require("fs"));
|
|
53538
|
+
var os15 = __toESM(require("os"));
|
|
53539
|
+
var path46 = __toESM(require("path"));
|
|
53213
53540
|
function getOnboardingPreferencesPath() {
|
|
53214
53541
|
if (process.env.HAR_PREFERENCES_PATH) {
|
|
53215
|
-
return
|
|
53542
|
+
return path46.resolve(process.env.HAR_PREFERENCES_PATH);
|
|
53216
53543
|
}
|
|
53217
|
-
return
|
|
53544
|
+
return path46.join(os15.homedir(), ".har", "preferences.json");
|
|
53218
53545
|
}
|
|
53219
53546
|
function readOnboardingPreferences() {
|
|
53220
53547
|
const preferencePath = getOnboardingPreferencesPath();
|
|
53221
53548
|
try {
|
|
53222
|
-
if (!
|
|
53223
|
-
return OnboardingPreferencesSchema.parse(JSON.parse(
|
|
53549
|
+
if (!fs43.existsSync(preferencePath)) return OnboardingPreferencesSchema.parse({});
|
|
53550
|
+
return OnboardingPreferencesSchema.parse(JSON.parse(fs43.readFileSync(preferencePath, "utf8")));
|
|
53224
53551
|
} catch {
|
|
53225
53552
|
return OnboardingPreferencesSchema.parse({});
|
|
53226
53553
|
}
|
|
@@ -53245,8 +53572,8 @@ function writeOnboardingPreferences(overrides) {
|
|
|
53245
53572
|
};
|
|
53246
53573
|
const parsed = OnboardingPreferencesSchema.parse(preference);
|
|
53247
53574
|
const preferencePath = getOnboardingPreferencesPath();
|
|
53248
|
-
|
|
53249
|
-
|
|
53575
|
+
fs43.mkdirSync(path46.dirname(preferencePath), { recursive: true });
|
|
53576
|
+
fs43.writeFileSync(preferencePath, `${JSON.stringify(parsed, null, 2)}
|
|
53250
53577
|
`);
|
|
53251
53578
|
return parsed;
|
|
53252
53579
|
}
|
|
@@ -53526,7 +53853,7 @@ var envCommand = {
|
|
|
53526
53853
|
}
|
|
53527
53854
|
};
|
|
53528
53855
|
async function handleInit(argv) {
|
|
53529
|
-
const repoPath =
|
|
53856
|
+
const repoPath = path47.resolve(argv.repo);
|
|
53530
53857
|
const onboarding = resolveOnboardingOptions(argv);
|
|
53531
53858
|
header("har env init");
|
|
53532
53859
|
info(`Repository: ${repoPath}`);
|
|
@@ -53560,7 +53887,7 @@ async function handleInit(argv) {
|
|
|
53560
53887
|
if (argv.auto) {
|
|
53561
53888
|
await handleAgentMdProposal(repoPath, argv.yes);
|
|
53562
53889
|
} else {
|
|
53563
|
-
emitManualAdaptationPrompt(repoPath, "init", argv.profile);
|
|
53890
|
+
await emitManualAdaptationPrompt(repoPath, "init", argv.profile, void 0, argv.yes);
|
|
53564
53891
|
}
|
|
53565
53892
|
divider();
|
|
53566
53893
|
success("Harness initialized!");
|
|
@@ -53590,7 +53917,7 @@ async function handleInit(argv) {
|
|
|
53590
53917
|
}
|
|
53591
53918
|
}
|
|
53592
53919
|
async function handleMaintain(argv) {
|
|
53593
|
-
const repoPath =
|
|
53920
|
+
const repoPath = path47.resolve(argv.repo);
|
|
53594
53921
|
const onboarding = resolveOnboardingOptions(argv);
|
|
53595
53922
|
header("har env maintain");
|
|
53596
53923
|
info(`Repository: ${repoPath}`);
|
|
@@ -53632,7 +53959,13 @@ async function handleMaintain(argv) {
|
|
|
53632
53959
|
if (!result.validation.pass) {
|
|
53633
53960
|
warn("Harness has validation errors \u2014 fix them before running --finalize.");
|
|
53634
53961
|
}
|
|
53635
|
-
emitManualAdaptationPrompt(
|
|
53962
|
+
await emitManualAdaptationPrompt(
|
|
53963
|
+
repoPath,
|
|
53964
|
+
"maintain",
|
|
53965
|
+
"default",
|
|
53966
|
+
result.bundle?.report,
|
|
53967
|
+
argv.yes
|
|
53968
|
+
);
|
|
53636
53969
|
info("After your coding agent finishes adapting, record it with: har env maintain --finalize");
|
|
53637
53970
|
}
|
|
53638
53971
|
divider();
|
|
@@ -53684,7 +54017,7 @@ function resolveOnboardingOptions(argv) {
|
|
|
53684
54017
|
}
|
|
53685
54018
|
};
|
|
53686
54019
|
}
|
|
53687
|
-
function emitManualAdaptationPrompt(repoPath, mode, profile = "default", bundleReport) {
|
|
54020
|
+
async function emitManualAdaptationPrompt(repoPath, mode, profile = "default", bundleReport, autoYes = false) {
|
|
53688
54021
|
const prompt2 = mode === "init" ? buildInitAdaptationPrompt(repoPath, profile) : buildMaintainAdaptationPrompt(repoPath, bundleReport);
|
|
53689
54022
|
writeAdaptationPrompt(repoPath, prompt2);
|
|
53690
54023
|
process.stderr.write("\n");
|
|
@@ -53700,12 +54033,13 @@ function emitManualAdaptationPrompt(repoPath, mode, profile = "default", bundleR
|
|
|
53700
54033
|
info(" Reference templates are in .har/maintain/templates/");
|
|
53701
54034
|
}
|
|
53702
54035
|
printAdaptationPrompt(prompt2);
|
|
54036
|
+
await offerAdaptationPromptClipboard(prompt2, { autoYes });
|
|
53703
54037
|
}
|
|
53704
54038
|
async function handleAgentMdProposal(repoPath, autoYes) {
|
|
53705
54039
|
if (autoYes) {
|
|
53706
54040
|
const proposal = readAgentMdProposal(repoPath);
|
|
53707
54041
|
if (proposal) {
|
|
53708
|
-
writeFileSafe(
|
|
54042
|
+
writeFileSafe(path47.join(repoPath, "AGENT.md"), proposal.content);
|
|
53709
54043
|
clearAgentMdProposal(repoPath);
|
|
53710
54044
|
info("Applied AGENT.md proposal (--yes)");
|
|
53711
54045
|
}
|
|
@@ -53714,7 +54048,7 @@ async function handleAgentMdProposal(repoPath, autoYes) {
|
|
|
53714
54048
|
await promptApplyAgentMdProposal(repoPath);
|
|
53715
54049
|
}
|
|
53716
54050
|
async function handleAddStage(argv) {
|
|
53717
|
-
const repoPath =
|
|
54051
|
+
const repoPath = path47.resolve(argv.repo);
|
|
53718
54052
|
const available = listStageTemplateIds();
|
|
53719
54053
|
if (argv.list) {
|
|
53720
54054
|
for (const id of available) {
|
|
@@ -53791,7 +54125,7 @@ async function handleAddStage(argv) {
|
|
|
53791
54125
|
}
|
|
53792
54126
|
}
|
|
53793
54127
|
async function handlePreflight(argv) {
|
|
53794
|
-
const repo =
|
|
54128
|
+
const repo = path47.resolve(argv.repo);
|
|
53795
54129
|
const agentId = validateAgentId(argv.id, repo);
|
|
53796
54130
|
const result = await preflightEnvironment({
|
|
53797
54131
|
repoPath: repo,
|
|
@@ -53809,7 +54143,7 @@ async function handlePreflight(argv) {
|
|
|
53809
54143
|
process.exit(result.code);
|
|
53810
54144
|
}
|
|
53811
54145
|
async function handleLaunch(argv) {
|
|
53812
|
-
const repo =
|
|
54146
|
+
const repo = path47.resolve(argv.repo);
|
|
53813
54147
|
const agentId = validateAgentId(argv.id, repo);
|
|
53814
54148
|
let confirmReplace = argv.replace;
|
|
53815
54149
|
let force = argv.force;
|
|
@@ -53819,10 +54153,10 @@ async function handleLaunch(argv) {
|
|
|
53819
54153
|
if (!confirmReplace && process.stdin.isTTY && process.stdout.isTTY) {
|
|
53820
54154
|
warn("Occupied slot \u2014 review before replacing:");
|
|
53821
54155
|
console.error(guard.reason ?? "");
|
|
53822
|
-
const
|
|
53823
|
-
const rl =
|
|
53824
|
-
const answer = await new Promise((
|
|
53825
|
-
rl.question("Replace this slot? [y/N] ",
|
|
54156
|
+
const readline10 = await import("readline");
|
|
54157
|
+
const rl = readline10.createInterface({ input: process.stdin, output: process.stderr });
|
|
54158
|
+
const answer = await new Promise((resolve38) => {
|
|
54159
|
+
rl.question("Replace this slot? [y/N] ", resolve38);
|
|
53826
54160
|
});
|
|
53827
54161
|
rl.close();
|
|
53828
54162
|
if (!/^[Yy]$/.test(answer.trim())) {
|
|
@@ -53836,10 +54170,10 @@ async function handleLaunch(argv) {
|
|
|
53836
54170
|
if (!guardAfterConfirm.allowed && guardAfterConfirm.blocked && guardAfterConfirm.slot?.dirty) {
|
|
53837
54171
|
if (!force && process.stdin.isTTY && process.stdout.isTTY) {
|
|
53838
54172
|
warn("Worktree has uncommitted changes.");
|
|
53839
|
-
const
|
|
53840
|
-
const rl =
|
|
53841
|
-
const answer = await new Promise((
|
|
53842
|
-
rl.question("Discard uncommitted changes? [y/N] ",
|
|
54173
|
+
const readline10 = await import("readline");
|
|
54174
|
+
const rl = readline10.createInterface({ input: process.stdin, output: process.stderr });
|
|
54175
|
+
const answer = await new Promise((resolve38) => {
|
|
54176
|
+
rl.question("Discard uncommitted changes? [y/N] ", resolve38);
|
|
53843
54177
|
});
|
|
53844
54178
|
rl.close();
|
|
53845
54179
|
if (!/^[Yy]$/.test(answer.trim())) {
|
|
@@ -53903,7 +54237,7 @@ async function handleRecover(argv) {
|
|
|
53903
54237
|
});
|
|
53904
54238
|
}
|
|
53905
54239
|
async function handleVerify(argv) {
|
|
53906
|
-
const repo =
|
|
54240
|
+
const repo = path47.resolve(argv.repo);
|
|
53907
54241
|
const agentId = validateAgentId(argv.id, repo);
|
|
53908
54242
|
const result = await runVerification({
|
|
53909
54243
|
repoPath: repo,
|
|
@@ -53915,7 +54249,7 @@ async function handleVerify(argv) {
|
|
|
53915
54249
|
process.exit(result.code);
|
|
53916
54250
|
}
|
|
53917
54251
|
async function handleTeardown(argv) {
|
|
53918
|
-
const repo =
|
|
54252
|
+
const repo = path47.resolve(argv.repo);
|
|
53919
54253
|
const agentId = validateAgentId(argv.id, repo);
|
|
53920
54254
|
const result = await teardownEnvironment({
|
|
53921
54255
|
repoPath: repo,
|
|
@@ -53926,7 +54260,7 @@ async function handleTeardown(argv) {
|
|
|
53926
54260
|
process.exit(result.code);
|
|
53927
54261
|
}
|
|
53928
54262
|
async function handleComplete(argv) {
|
|
53929
|
-
const repo =
|
|
54263
|
+
const repo = path47.resolve(argv.repo);
|
|
53930
54264
|
const agentId = validateAgentId(argv.id, repo);
|
|
53931
54265
|
const result = await completeEnvironment({
|
|
53932
54266
|
repoPath: repo,
|
|
@@ -53947,7 +54281,7 @@ async function handleComplete(argv) {
|
|
|
53947
54281
|
process.exit(result.code);
|
|
53948
54282
|
}
|
|
53949
54283
|
async function handleStatus(argv) {
|
|
53950
|
-
const repoPath =
|
|
54284
|
+
const repoPath = path47.resolve(argv.repo);
|
|
53951
54285
|
if (argv.json) {
|
|
53952
54286
|
const status = collectEnvironmentStatus(repoPath);
|
|
53953
54287
|
const output = EnvironmentStatusSchema.parse(status);
|
|
@@ -53960,7 +54294,7 @@ async function handleStatus(argv) {
|
|
|
53960
54294
|
});
|
|
53961
54295
|
}
|
|
53962
54296
|
async function handleRunsList(argv) {
|
|
53963
|
-
const repoPath =
|
|
54297
|
+
const repoPath = path47.resolve(argv.repo);
|
|
53964
54298
|
const runs = listRuns(repoPath, { stageId: argv.stage, limit: argv.limit });
|
|
53965
54299
|
if (argv.json) {
|
|
53966
54300
|
process.stdout.write(JSON.stringify({ runs }, null, 2) + "\n");
|
|
@@ -53977,7 +54311,7 @@ async function handleRunsList(argv) {
|
|
|
53977
54311
|
}
|
|
53978
54312
|
}
|
|
53979
54313
|
async function handleRunsGet(argv) {
|
|
53980
|
-
const run2 = getRun(
|
|
54314
|
+
const run2 = getRun(path47.resolve(argv.repo), argv.runId);
|
|
53981
54315
|
if (!run2) {
|
|
53982
54316
|
error(`Run not found: ${argv.runId}`);
|
|
53983
54317
|
process.exit(1);
|
|
@@ -54042,7 +54376,7 @@ function printNextSteps(auto2) {
|
|
|
54042
54376
|
console.error("");
|
|
54043
54377
|
console.error(" Read: .har/README.md");
|
|
54044
54378
|
if (!auto2) {
|
|
54045
|
-
console.error(" Adapt: paste prompt above into your coding agent");
|
|
54379
|
+
console.error(" Adapt: paste clipboard / prompt above into your coding agent");
|
|
54046
54380
|
console.error(" Prompt file: .har/ADAPT-PROMPT.md");
|
|
54047
54381
|
} else {
|
|
54048
54382
|
console.error(" Agent guide: AGENT.md (repo root, if applied)");
|
|
@@ -54056,20 +54390,88 @@ function printNextSteps(auto2) {
|
|
|
54056
54390
|
}
|
|
54057
54391
|
|
|
54058
54392
|
// src/cli/commands/control.ts
|
|
54059
|
-
var
|
|
54393
|
+
var path49 = __toESM(require("path"));
|
|
54060
54394
|
init_control_config();
|
|
54395
|
+
init_portal_credentials();
|
|
54396
|
+
|
|
54397
|
+
// src/core/portal-login.ts
|
|
54398
|
+
var http = __toESM(require("http"));
|
|
54399
|
+
var import_crypto = require("crypto");
|
|
54400
|
+
var import_child_process11 = require("child_process");
|
|
54401
|
+
var CALLBACK_PATH = "/callback";
|
|
54402
|
+
var LOGIN_TIMEOUT_MS = 3 * 6e4;
|
|
54403
|
+
function openBrowser(url) {
|
|
54404
|
+
const [cmd, args] = process.platform === "darwin" ? ["open", [url]] : process.platform === "win32" ? ["cmd", ["/c", "start", "", url]] : ["xdg-open", [url]];
|
|
54405
|
+
try {
|
|
54406
|
+
const child = (0, import_child_process11.spawn)(cmd, args, { stdio: "ignore", detached: true });
|
|
54407
|
+
child.on("error", () => {
|
|
54408
|
+
});
|
|
54409
|
+
child.unref();
|
|
54410
|
+
} catch {
|
|
54411
|
+
}
|
|
54412
|
+
}
|
|
54413
|
+
async function loginViaBrowser(portalUrl, openUrl = openBrowser) {
|
|
54414
|
+
const state = (0, import_crypto.randomUUID)();
|
|
54415
|
+
return new Promise((resolve38, reject) => {
|
|
54416
|
+
let timer;
|
|
54417
|
+
const server = http.createServer((req, res) => {
|
|
54418
|
+
const requestUrl = new URL(req.url ?? "", "http://127.0.0.1");
|
|
54419
|
+
if (requestUrl.pathname !== CALLBACK_PATH) {
|
|
54420
|
+
res.writeHead(404);
|
|
54421
|
+
res.end("Not found");
|
|
54422
|
+
return;
|
|
54423
|
+
}
|
|
54424
|
+
const token = requestUrl.searchParams.get("token");
|
|
54425
|
+
const returnedState = requestUrl.searchParams.get("state");
|
|
54426
|
+
const workspace = requestUrl.searchParams.get("workspace") ?? void 0;
|
|
54427
|
+
const email2 = requestUrl.searchParams.get("email") ?? void 0;
|
|
54428
|
+
if (returnedState !== state || !token) {
|
|
54429
|
+
res.writeHead(400, { "Content-Type": "text/html" });
|
|
54430
|
+
res.end("<h1>Login failed</h1><p>You can close this tab and try again.</p>");
|
|
54431
|
+
cleanup();
|
|
54432
|
+
reject(new Error("state mismatch or missing token"));
|
|
54433
|
+
return;
|
|
54434
|
+
}
|
|
54435
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
54436
|
+
res.end("<h1>Logged in</h1><p>You can close this tab and return to the terminal.</p>");
|
|
54437
|
+
cleanup();
|
|
54438
|
+
resolve38({ portalUrl, token, workspace, email: email2, createdAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
54439
|
+
});
|
|
54440
|
+
const cleanup = () => {
|
|
54441
|
+
clearTimeout(timer);
|
|
54442
|
+
server.close();
|
|
54443
|
+
};
|
|
54444
|
+
server.on("error", (err) => {
|
|
54445
|
+
cleanup();
|
|
54446
|
+
reject(err);
|
|
54447
|
+
});
|
|
54448
|
+
server.listen(0, "127.0.0.1", () => {
|
|
54449
|
+
const { port } = server.address();
|
|
54450
|
+
const callback = `http://127.0.0.1:${port}${CALLBACK_PATH}`;
|
|
54451
|
+
const loginUrl = `${portalUrl}/cli/login?callback=${encodeURIComponent(callback)}&state=${state}`;
|
|
54452
|
+
openUrl(loginUrl);
|
|
54453
|
+
process.stderr.write(`Opening ${loginUrl}
|
|
54454
|
+
If your browser did not open, paste that URL.
|
|
54455
|
+
`);
|
|
54456
|
+
timer = setTimeout(() => {
|
|
54457
|
+
cleanup();
|
|
54458
|
+
reject(new Error("timed out"));
|
|
54459
|
+
}, LOGIN_TIMEOUT_MS);
|
|
54460
|
+
});
|
|
54461
|
+
});
|
|
54462
|
+
}
|
|
54061
54463
|
|
|
54062
54464
|
// src/core/control-unregister.ts
|
|
54063
|
-
var
|
|
54064
|
-
var
|
|
54465
|
+
var fs44 = __toESM(require("fs"));
|
|
54466
|
+
var path48 = __toESM(require("path"));
|
|
54065
54467
|
init_control_config();
|
|
54066
54468
|
function listUnregisterWorktreeCandidates(repoPath) {
|
|
54067
54469
|
const harnessRoot = canonicalizeControlRepoPath(repoPath);
|
|
54068
54470
|
const byPath = /* @__PURE__ */ new Map();
|
|
54069
54471
|
const add = (partial2) => {
|
|
54070
|
-
const resolved =
|
|
54472
|
+
const resolved = path48.resolve(partial2.worktreePath);
|
|
54071
54473
|
if (!resolved || resolved === harnessRoot) return;
|
|
54072
|
-
const exists = partial2.exists ??
|
|
54474
|
+
const exists = partial2.exists ?? fs44.existsSync(resolved);
|
|
54073
54475
|
const prev = byPath.get(resolved);
|
|
54074
54476
|
if (prev) {
|
|
54075
54477
|
byPath.set(resolved, {
|
|
@@ -54116,12 +54518,12 @@ function listUnregisterWorktreeCandidates(repoPath) {
|
|
|
54116
54518
|
}
|
|
54117
54519
|
return [...byPath.values()].sort((a2, b2) => a2.agentId - b2.agentId);
|
|
54118
54520
|
}
|
|
54119
|
-
async function
|
|
54521
|
+
async function askYesNo6(question) {
|
|
54120
54522
|
if (!process.stdin.isTTY || !process.stdout.isTTY) return false;
|
|
54121
|
-
const
|
|
54122
|
-
const rl =
|
|
54123
|
-
const answer = await new Promise((
|
|
54124
|
-
rl.question(question,
|
|
54523
|
+
const readline10 = await import("readline");
|
|
54524
|
+
const rl = readline10.createInterface({ input: process.stdin, output: process.stderr });
|
|
54525
|
+
const answer = await new Promise((resolve38) => {
|
|
54526
|
+
rl.question(question, resolve38);
|
|
54125
54527
|
});
|
|
54126
54528
|
rl.close();
|
|
54127
54529
|
return /^[Yy]$/.test(answer.trim());
|
|
@@ -54133,7 +54535,7 @@ async function confirmUnregister(options) {
|
|
|
54133
54535
|
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
54134
54536
|
throw new Error("Non-interactive terminal \u2014 pass --yes (and optionally --delete-worktrees)");
|
|
54135
54537
|
}
|
|
54136
|
-
const proceed = await
|
|
54538
|
+
const proceed = await askYesNo6("Unregister this repository from Mission Control? [y/N] ");
|
|
54137
54539
|
if (!proceed) return { proceed: false, deleteWorktrees: false };
|
|
54138
54540
|
const existing = options.worktrees.filter((w2) => w2.exists);
|
|
54139
54541
|
if (existing.length === 0) {
|
|
@@ -54145,7 +54547,7 @@ async function confirmUnregister(options) {
|
|
|
54145
54547
|
process.stderr.write(` agent-${wt2.agentId}: ${wt2.worktreePath}${dirty}
|
|
54146
54548
|
`);
|
|
54147
54549
|
}
|
|
54148
|
-
const deleteWorktrees = await
|
|
54550
|
+
const deleteWorktrees = await askYesNo6(
|
|
54149
54551
|
`Also delete ${existing.length} session worktree(s) on disk? [y/N] `
|
|
54150
54552
|
);
|
|
54151
54553
|
return { proceed: true, deleteWorktrees };
|
|
@@ -54183,28 +54585,28 @@ async function teardownWorktrees(repoPath, candidates, dryRun) {
|
|
|
54183
54585
|
trigger: "cli"
|
|
54184
54586
|
});
|
|
54185
54587
|
if (result.code !== 0) {
|
|
54186
|
-
if (
|
|
54187
|
-
|
|
54588
|
+
if (fs44.existsSync(candidate.worktreePath)) {
|
|
54589
|
+
fs44.rmSync(candidate.worktreePath, { recursive: true, force: true });
|
|
54188
54590
|
}
|
|
54189
54591
|
}
|
|
54190
54592
|
outcomes.push({
|
|
54191
54593
|
path: candidate.worktreePath,
|
|
54192
54594
|
agentId: candidate.agentId,
|
|
54193
|
-
deleted: !
|
|
54194
|
-
error: result.code !== 0 &&
|
|
54595
|
+
deleted: !fs44.existsSync(candidate.worktreePath),
|
|
54596
|
+
error: result.code !== 0 && fs44.existsSync(candidate.worktreePath) ? result.stderr : void 0
|
|
54195
54597
|
});
|
|
54196
54598
|
} catch (err) {
|
|
54197
54599
|
const message = err instanceof Error ? err.message : String(err);
|
|
54198
54600
|
try {
|
|
54199
|
-
if (
|
|
54200
|
-
|
|
54601
|
+
if (fs44.existsSync(candidate.worktreePath)) {
|
|
54602
|
+
fs44.rmSync(candidate.worktreePath, { recursive: true, force: true });
|
|
54201
54603
|
}
|
|
54202
54604
|
} catch {
|
|
54203
54605
|
}
|
|
54204
54606
|
outcomes.push({
|
|
54205
54607
|
path: candidate.worktreePath,
|
|
54206
54608
|
agentId: candidate.agentId,
|
|
54207
|
-
deleted: !
|
|
54609
|
+
deleted: !fs44.existsSync(candidate.worktreePath),
|
|
54208
54610
|
error: message
|
|
54209
54611
|
});
|
|
54210
54612
|
}
|
|
@@ -54320,8 +54722,11 @@ var controlCommand = {
|
|
|
54320
54722
|
handleWatch
|
|
54321
54723
|
).command(
|
|
54322
54724
|
"login",
|
|
54323
|
-
"
|
|
54324
|
-
(y2) => y2.option("
|
|
54725
|
+
"Log in to a har-portal (browser SSO) and store an ingest token",
|
|
54726
|
+
(y2) => y2.option("portal", { type: "string", describe: "Portal base URL (or set HAR_PORTAL_URL)" }).option("api-key", {
|
|
54727
|
+
type: "string",
|
|
54728
|
+
describe: "Store this ingest token directly instead of browser login"
|
|
54729
|
+
}),
|
|
54325
54730
|
handleLogin
|
|
54326
54731
|
).demandCommand(
|
|
54327
54732
|
1,
|
|
@@ -54386,7 +54791,7 @@ async function handleDown() {
|
|
|
54386
54791
|
process.exit(code);
|
|
54387
54792
|
}
|
|
54388
54793
|
async function handleRegister(argv) {
|
|
54389
|
-
const repoPath =
|
|
54794
|
+
const repoPath = path49.resolve(argv.repo);
|
|
54390
54795
|
header("har control register");
|
|
54391
54796
|
info(`Repository: ${repoPath}`);
|
|
54392
54797
|
try {
|
|
@@ -54410,7 +54815,7 @@ async function handleRegister(argv) {
|
|
|
54410
54815
|
}
|
|
54411
54816
|
}
|
|
54412
54817
|
async function handleUnregister(argv) {
|
|
54413
|
-
const repoPath =
|
|
54818
|
+
const repoPath = path49.resolve(argv.repo);
|
|
54414
54819
|
const worktrees = listUnregisterWorktreeCandidates(repoPath);
|
|
54415
54820
|
try {
|
|
54416
54821
|
let deleteWorktrees = argv.deleteWorktrees;
|
|
@@ -54479,7 +54884,7 @@ async function handleUnregister(argv) {
|
|
|
54479
54884
|
}
|
|
54480
54885
|
}
|
|
54481
54886
|
async function handleSync(argv) {
|
|
54482
|
-
const repoPath =
|
|
54887
|
+
const repoPath = path49.resolve(argv.repo);
|
|
54483
54888
|
try {
|
|
54484
54889
|
await syncRepoWithControl({
|
|
54485
54890
|
repoPath,
|
|
@@ -54518,7 +54923,7 @@ async function handleWatch(argv) {
|
|
|
54518
54923
|
};
|
|
54519
54924
|
const tick = async () => {
|
|
54520
54925
|
if (argv.repo) {
|
|
54521
|
-
await syncOne(
|
|
54926
|
+
await syncOne(path49.resolve(argv.repo));
|
|
54522
54927
|
return;
|
|
54523
54928
|
}
|
|
54524
54929
|
try {
|
|
@@ -54539,21 +54944,40 @@ async function handleWatch(argv) {
|
|
|
54539
54944
|
}
|
|
54540
54945
|
async function handleLogin(argv) {
|
|
54541
54946
|
header("har control login");
|
|
54542
|
-
|
|
54543
|
-
|
|
54947
|
+
const portalUrl = (argv.portal ?? process.env.HAR_PORTAL_URL ?? "").replace(/\/+$/, "");
|
|
54948
|
+
if (!portalUrl) {
|
|
54949
|
+
error("Provide --portal <url> (or set HAR_PORTAL_URL)");
|
|
54950
|
+
process.exit(1);
|
|
54951
|
+
}
|
|
54952
|
+
if (argv.apiKey) {
|
|
54953
|
+
writePortalCredentials({
|
|
54954
|
+
portalUrl,
|
|
54955
|
+
token: argv.apiKey,
|
|
54956
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
54957
|
+
});
|
|
54958
|
+
success(`Saved ingest token for ${portalUrl}`);
|
|
54959
|
+
info("Sync: har control sync");
|
|
54960
|
+
return;
|
|
54961
|
+
}
|
|
54962
|
+
try {
|
|
54963
|
+
const creds = await loginViaBrowser(portalUrl);
|
|
54964
|
+
writePortalCredentials(creds);
|
|
54965
|
+
success(
|
|
54966
|
+
`Logged in to ${portalUrl}${creds.workspace ? ` (workspace: ${creds.workspace})` : ""}`
|
|
54967
|
+
);
|
|
54968
|
+
info("Sync: har control sync");
|
|
54969
|
+
} catch (err) {
|
|
54970
|
+
error(`Login failed: ${err.message}`);
|
|
54544
54971
|
process.exit(1);
|
|
54545
54972
|
}
|
|
54546
|
-
process.env.HAR_CLOUD_API_KEY = argv.apiKey;
|
|
54547
|
-
success("HAR_CLOUD_API_KEY set for this process. Export it in your shell for persistence.");
|
|
54548
|
-
info("Sync to cloud: har control sync --cloud");
|
|
54549
54973
|
}
|
|
54550
54974
|
|
|
54551
54975
|
// src/cli/commands/hooks.ts
|
|
54552
|
-
var
|
|
54976
|
+
var path51 = __toESM(require("path"));
|
|
54553
54977
|
|
|
54554
54978
|
// src/core/claude-hooks.ts
|
|
54555
|
-
var
|
|
54556
|
-
var
|
|
54979
|
+
var fs45 = __toESM(require("fs"));
|
|
54980
|
+
var path50 = __toESM(require("path"));
|
|
54557
54981
|
var CLAUDE_GUARD_RELATIVE_PATH = ".har/hooks/claude-worktree-guard.sh";
|
|
54558
54982
|
var CLAUDE_SETTINGS_RELATIVE_PATH = ".claude/settings.json";
|
|
54559
54983
|
var GUARD_MATCHER = "Edit|Write|MultiEdit|NotebookEdit";
|
|
@@ -54564,8 +54988,8 @@ function isHarGuardEntry(entry) {
|
|
|
54564
54988
|
);
|
|
54565
54989
|
}
|
|
54566
54990
|
function readSettings(settingsPath) {
|
|
54567
|
-
if (!
|
|
54568
|
-
const raw =
|
|
54991
|
+
if (!fs45.existsSync(settingsPath)) return {};
|
|
54992
|
+
const raw = fs45.readFileSync(settingsPath, "utf8").trim();
|
|
54569
54993
|
if (raw === "") return {};
|
|
54570
54994
|
const parsed = JSON.parse(raw);
|
|
54571
54995
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
@@ -54574,19 +54998,19 @@ function readSettings(settingsPath) {
|
|
|
54574
54998
|
return parsed;
|
|
54575
54999
|
}
|
|
54576
55000
|
function writeSettings(settingsPath, settings) {
|
|
54577
|
-
|
|
54578
|
-
|
|
55001
|
+
fs45.mkdirSync(path50.dirname(settingsPath), { recursive: true });
|
|
55002
|
+
fs45.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
54579
55003
|
}
|
|
54580
55004
|
function installClaudeGuard(repoPath) {
|
|
54581
55005
|
const templatePath = resolveTemplateFile("claude-worktree-guard.sh.template");
|
|
54582
55006
|
if (!templatePath) {
|
|
54583
55007
|
throw new Error("Guard template not found (claude-worktree-guard.sh.template). Run npm run build.");
|
|
54584
55008
|
}
|
|
54585
|
-
const guardScript =
|
|
54586
|
-
|
|
54587
|
-
|
|
54588
|
-
|
|
54589
|
-
const settingsPath =
|
|
55009
|
+
const guardScript = path50.join(repoPath, CLAUDE_GUARD_RELATIVE_PATH);
|
|
55010
|
+
fs45.mkdirSync(path50.dirname(guardScript), { recursive: true });
|
|
55011
|
+
fs45.copyFileSync(templatePath, guardScript);
|
|
55012
|
+
fs45.chmodSync(guardScript, 493);
|
|
55013
|
+
const settingsPath = path50.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
|
|
54590
55014
|
const settings = readSettings(settingsPath);
|
|
54591
55015
|
const hooks = settings.hooks ?? {};
|
|
54592
55016
|
const preToolUse = (hooks.PreToolUse ?? []).filter((entry) => !isHarGuardEntry(entry));
|
|
@@ -54600,15 +55024,15 @@ function installClaudeGuard(repoPath) {
|
|
|
54600
55024
|
}
|
|
54601
55025
|
function uninstallClaudeGuard(repoPath) {
|
|
54602
55026
|
let removed = false;
|
|
54603
|
-
const guardScript =
|
|
54604
|
-
if (
|
|
54605
|
-
|
|
55027
|
+
const guardScript = path50.join(repoPath, CLAUDE_GUARD_RELATIVE_PATH);
|
|
55028
|
+
if (fs45.existsSync(guardScript)) {
|
|
55029
|
+
fs45.rmSync(guardScript);
|
|
54606
55030
|
removed = true;
|
|
54607
|
-
const parent =
|
|
54608
|
-
if (
|
|
55031
|
+
const parent = path50.dirname(guardScript);
|
|
55032
|
+
if (fs45.existsSync(parent) && fs45.readdirSync(parent).length === 0) fs45.rmdirSync(parent);
|
|
54609
55033
|
}
|
|
54610
|
-
const settingsPath =
|
|
54611
|
-
if (
|
|
55034
|
+
const settingsPath = path50.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
|
|
55035
|
+
if (fs45.existsSync(settingsPath)) {
|
|
54612
55036
|
const settings = readSettings(settingsPath);
|
|
54613
55037
|
const preToolUse = settings.hooks?.PreToolUse;
|
|
54614
55038
|
if (preToolUse) {
|
|
@@ -54633,8 +55057,8 @@ function uninstallClaudeGuard(repoPath) {
|
|
|
54633
55057
|
return { removed };
|
|
54634
55058
|
}
|
|
54635
55059
|
function claudeGuardInstalled(repoPath) {
|
|
54636
|
-
const settingsPath =
|
|
54637
|
-
if (!
|
|
55060
|
+
const settingsPath = path50.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
|
|
55061
|
+
if (!fs45.existsSync(settingsPath)) return false;
|
|
54638
55062
|
try {
|
|
54639
55063
|
const settings = readSettings(settingsPath);
|
|
54640
55064
|
return (settings.hooks?.PreToolUse ?? []).some(isHarGuardEntry);
|
|
@@ -54650,7 +55074,7 @@ function repoOption(y2) {
|
|
|
54650
55074
|
function handleInstall2(argv) {
|
|
54651
55075
|
try {
|
|
54652
55076
|
if (argv.claude) {
|
|
54653
|
-
const result2 = installClaudeGuard(
|
|
55077
|
+
const result2 = installClaudeGuard(path51.resolve(argv.repo));
|
|
54654
55078
|
success("Claude Code worktree guard installed.");
|
|
54655
55079
|
info(`Guard script: ${result2.guardScript}`);
|
|
54656
55080
|
info(`Settings: ${result2.settingsPath} (PreToolUse: Edit|Write|MultiEdit|NotebookEdit)`);
|
|
@@ -54658,7 +55082,7 @@ function handleInstall2(argv) {
|
|
|
54658
55082
|
info("Commit both files so the guard travels with the repo.");
|
|
54659
55083
|
return;
|
|
54660
55084
|
}
|
|
54661
|
-
const result = installHooks({ repoPath:
|
|
55085
|
+
const result = installHooks({ repoPath: path51.resolve(argv.repo), force: argv.force });
|
|
54662
55086
|
success(`Commit gate installed in ${result.hooksDir}`);
|
|
54663
55087
|
info(`pre-commit: ${result.preCommit}, post-commit: ${result.postCommit}`);
|
|
54664
55088
|
info("Commits of unverified change batches will be blocked in agent worktrees.");
|
|
@@ -54671,7 +55095,7 @@ function handleInstall2(argv) {
|
|
|
54671
55095
|
function handleUninstall(argv) {
|
|
54672
55096
|
try {
|
|
54673
55097
|
if (argv.claude) {
|
|
54674
|
-
const result2 = uninstallClaudeGuard(
|
|
55098
|
+
const result2 = uninstallClaudeGuard(path51.resolve(argv.repo));
|
|
54675
55099
|
if (result2.removed) {
|
|
54676
55100
|
success("Claude Code worktree guard removed.");
|
|
54677
55101
|
} else {
|
|
@@ -54679,7 +55103,7 @@ function handleUninstall(argv) {
|
|
|
54679
55103
|
}
|
|
54680
55104
|
return;
|
|
54681
55105
|
}
|
|
54682
|
-
const result = uninstallHooks(
|
|
55106
|
+
const result = uninstallHooks(path51.resolve(argv.repo));
|
|
54683
55107
|
if (result.removed) {
|
|
54684
55108
|
success(`Commit gate removed from ${result.hooksDir}`);
|
|
54685
55109
|
} else {
|
|
@@ -54692,7 +55116,7 @@ function handleUninstall(argv) {
|
|
|
54692
55116
|
}
|
|
54693
55117
|
function handleStatus2(argv) {
|
|
54694
55118
|
try {
|
|
54695
|
-
const status = getHooksStatus(
|
|
55119
|
+
const status = getHooksStatus(path51.resolve(argv.repo));
|
|
54696
55120
|
if (argv.json) {
|
|
54697
55121
|
process.stdout.write(`${JSON.stringify(status, null, 2)}
|
|
54698
55122
|
`);
|
|
@@ -54710,7 +55134,7 @@ function handleStatus2(argv) {
|
|
|
54710
55134
|
);
|
|
54711
55135
|
info(`Effective: ${status.effectiveMode} (in this checkout)`);
|
|
54712
55136
|
info(
|
|
54713
|
-
`Claude guard: ${claudeGuardInstalled(
|
|
55137
|
+
`Claude guard: ${claudeGuardInstalled(path51.resolve(argv.repo)) ? `installed (${CLAUDE_GUARD_RELATIVE_PATH})` : "not installed"}`
|
|
54714
55138
|
);
|
|
54715
55139
|
} catch (err) {
|
|
54716
55140
|
error(err instanceof Error ? err.message : String(err));
|
|
@@ -54971,10 +55395,10 @@ function assignProp(target, prop, value) {
|
|
|
54971
55395
|
configurable: true
|
|
54972
55396
|
});
|
|
54973
55397
|
}
|
|
54974
|
-
function getElementAtPath(obj,
|
|
54975
|
-
if (!
|
|
55398
|
+
function getElementAtPath(obj, path54) {
|
|
55399
|
+
if (!path54)
|
|
54976
55400
|
return obj;
|
|
54977
|
-
return
|
|
55401
|
+
return path54.reduce((acc, key) => acc?.[key], obj);
|
|
54978
55402
|
}
|
|
54979
55403
|
function promiseAllObject(promisesObj) {
|
|
54980
55404
|
const keys = Object.keys(promisesObj);
|
|
@@ -55294,11 +55718,11 @@ function aborted(x2, startIndex = 0) {
|
|
|
55294
55718
|
}
|
|
55295
55719
|
return false;
|
|
55296
55720
|
}
|
|
55297
|
-
function prefixIssues(
|
|
55721
|
+
function prefixIssues(path54, issues) {
|
|
55298
55722
|
return issues.map((iss) => {
|
|
55299
55723
|
var _a3;
|
|
55300
55724
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
55301
|
-
iss.path.unshift(
|
|
55725
|
+
iss.path.unshift(path54);
|
|
55302
55726
|
return iss;
|
|
55303
55727
|
});
|
|
55304
55728
|
}
|
|
@@ -60621,7 +61045,7 @@ var Protocol = class {
|
|
|
60621
61045
|
return;
|
|
60622
61046
|
}
|
|
60623
61047
|
const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
|
|
60624
|
-
await new Promise((
|
|
61048
|
+
await new Promise((resolve38) => setTimeout(resolve38, pollInterval));
|
|
60625
61049
|
options?.signal?.throwIfAborted();
|
|
60626
61050
|
}
|
|
60627
61051
|
} catch (error3) {
|
|
@@ -60638,7 +61062,7 @@ var Protocol = class {
|
|
|
60638
61062
|
*/
|
|
60639
61063
|
request(request, resultSchema, options) {
|
|
60640
61064
|
const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
|
|
60641
|
-
return new Promise((
|
|
61065
|
+
return new Promise((resolve38, reject) => {
|
|
60642
61066
|
const earlyReject = (error3) => {
|
|
60643
61067
|
reject(error3);
|
|
60644
61068
|
};
|
|
@@ -60716,7 +61140,7 @@ var Protocol = class {
|
|
|
60716
61140
|
if (!parseResult.success) {
|
|
60717
61141
|
reject(parseResult.error);
|
|
60718
61142
|
} else {
|
|
60719
|
-
|
|
61143
|
+
resolve38(parseResult.data);
|
|
60720
61144
|
}
|
|
60721
61145
|
} catch (error3) {
|
|
60722
61146
|
reject(error3);
|
|
@@ -60977,12 +61401,12 @@ var Protocol = class {
|
|
|
60977
61401
|
}
|
|
60978
61402
|
} catch {
|
|
60979
61403
|
}
|
|
60980
|
-
return new Promise((
|
|
61404
|
+
return new Promise((resolve38, reject) => {
|
|
60981
61405
|
if (signal.aborted) {
|
|
60982
61406
|
reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
60983
61407
|
return;
|
|
60984
61408
|
}
|
|
60985
|
-
const timeoutId = setTimeout(
|
|
61409
|
+
const timeoutId = setTimeout(resolve38, interval);
|
|
60986
61410
|
signal.addEventListener("abort", () => {
|
|
60987
61411
|
clearTimeout(timeoutId);
|
|
60988
61412
|
reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
@@ -61772,7 +62196,7 @@ var Server = class extends Protocol {
|
|
|
61772
62196
|
};
|
|
61773
62197
|
|
|
61774
62198
|
// src/mcp/server.ts
|
|
61775
|
-
var
|
|
62199
|
+
var path52 = __toESM(require("path"));
|
|
61776
62200
|
|
|
61777
62201
|
// node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
|
|
61778
62202
|
var import_node_process2 = __toESM(require("node:process"), 1);
|
|
@@ -61855,12 +62279,12 @@ var StdioServerTransport = class {
|
|
|
61855
62279
|
this.onclose?.();
|
|
61856
62280
|
}
|
|
61857
62281
|
send(message) {
|
|
61858
|
-
return new Promise((
|
|
62282
|
+
return new Promise((resolve38) => {
|
|
61859
62283
|
const json = serializeMessage(message);
|
|
61860
62284
|
if (this._stdout.write(json)) {
|
|
61861
|
-
|
|
62285
|
+
resolve38();
|
|
61862
62286
|
} else {
|
|
61863
|
-
this._stdout.once("drain",
|
|
62287
|
+
this._stdout.once("drain", resolve38);
|
|
61864
62288
|
}
|
|
61865
62289
|
});
|
|
61866
62290
|
}
|
|
@@ -62432,7 +62856,7 @@ async function handleMcpToolCall(toolName, args, defaultRepo = ".") {
|
|
|
62432
62856
|
const input = ControlUpInputSchema.parse({ ...args, repo });
|
|
62433
62857
|
const result = await startControlAndSync({
|
|
62434
62858
|
detach: input.detach,
|
|
62435
|
-
cwd:
|
|
62859
|
+
cwd: path52.resolve(input.repo)
|
|
62436
62860
|
});
|
|
62437
62861
|
if (result.code !== 0) {
|
|
62438
62862
|
return {
|
|
@@ -62573,7 +62997,7 @@ function getStore() {
|
|
|
62573
62997
|
}
|
|
62574
62998
|
return store;
|
|
62575
62999
|
}
|
|
62576
|
-
function
|
|
63000
|
+
function readline7() {
|
|
62577
63001
|
return getStore().rl;
|
|
62578
63002
|
}
|
|
62579
63003
|
function withUpdates(fn) {
|
|
@@ -62618,7 +63042,7 @@ var effectScheduler = {
|
|
|
62618
63042
|
const { index } = store;
|
|
62619
63043
|
store.hooksEffect.push(() => {
|
|
62620
63044
|
store.hooksCleanup[index]?.();
|
|
62621
|
-
const cleanFn = cb(
|
|
63045
|
+
const cleanFn = cb(readline7());
|
|
62622
63046
|
if (cleanFn != null && typeof cleanFn !== "function") {
|
|
62623
63047
|
throw new ValidationError("useEffect return value must be a cleanup function or nothing.");
|
|
62624
63048
|
}
|
|
@@ -63094,7 +63518,7 @@ function breakLines(content, width) {
|
|
|
63094
63518
|
return content.split("\n").flatMap((line) => (0, import_wrap_ansi.default)(line, width, { trim: false, hard: true }).split("\n").map((str) => str.trimEnd())).join("\n");
|
|
63095
63519
|
}
|
|
63096
63520
|
function readlineWidth() {
|
|
63097
|
-
return (0, import_cli_width.default)({ defaultWidth: 80, output:
|
|
63521
|
+
return (0, import_cli_width.default)({ defaultWidth: 80, output: readline7().output });
|
|
63098
63522
|
}
|
|
63099
63523
|
|
|
63100
63524
|
// node_modules/@inquirer/core/dist/esm/lib/pagination/lines.mjs
|
|
@@ -63186,7 +63610,7 @@ function usePagination({ items, active, renderItem, pageSize, loop = true }) {
|
|
|
63186
63610
|
}
|
|
63187
63611
|
|
|
63188
63612
|
// node_modules/@inquirer/core/dist/esm/lib/create-prompt.mjs
|
|
63189
|
-
var
|
|
63613
|
+
var readline8 = __toESM(require("node:readline"), 1);
|
|
63190
63614
|
var import_node_async_hooks3 = require("node:async_hooks");
|
|
63191
63615
|
var import_mute_stream = __toESM(require_lib3(), 1);
|
|
63192
63616
|
|
|
@@ -63512,13 +63936,13 @@ var PromisePolyfill = class extends Promise {
|
|
|
63512
63936
|
// Available starting from Node 22
|
|
63513
63937
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers
|
|
63514
63938
|
static withResolver() {
|
|
63515
|
-
let
|
|
63939
|
+
let resolve38;
|
|
63516
63940
|
let reject;
|
|
63517
63941
|
const promise = new Promise((res, rej) => {
|
|
63518
|
-
|
|
63942
|
+
resolve38 = res;
|
|
63519
63943
|
reject = rej;
|
|
63520
63944
|
});
|
|
63521
|
-
return { promise, resolve:
|
|
63945
|
+
return { promise, resolve: resolve38, reject };
|
|
63522
63946
|
}
|
|
63523
63947
|
};
|
|
63524
63948
|
|
|
@@ -63529,13 +63953,13 @@ function createPrompt(view) {
|
|
|
63529
63953
|
const cleanups = /* @__PURE__ */ new Set();
|
|
63530
63954
|
const output = new import_mute_stream.default();
|
|
63531
63955
|
output.pipe(context.output ?? process.stdout);
|
|
63532
|
-
const rl =
|
|
63956
|
+
const rl = readline8.createInterface({
|
|
63533
63957
|
terminal: true,
|
|
63534
63958
|
input,
|
|
63535
63959
|
output
|
|
63536
63960
|
});
|
|
63537
63961
|
const screen = new ScreenManager(rl);
|
|
63538
|
-
const { promise, resolve:
|
|
63962
|
+
const { promise, resolve: resolve38, reject } = PromisePolyfill.withResolver();
|
|
63539
63963
|
const cancel = () => reject(new CancelPromptError());
|
|
63540
63964
|
if (signal) {
|
|
63541
63965
|
const abort = () => reject(new AbortPromptError({ cause: signal.reason }));
|
|
@@ -63559,7 +63983,7 @@ function createPrompt(view) {
|
|
|
63559
63983
|
cycle(() => {
|
|
63560
63984
|
try {
|
|
63561
63985
|
const nextView = view(config2, (value) => {
|
|
63562
|
-
setImmediate(() =>
|
|
63986
|
+
setImmediate(() => resolve38(value));
|
|
63563
63987
|
});
|
|
63564
63988
|
const [content, bottomContent] = typeof nextView === "string" ? [nextView] : nextView;
|
|
63565
63989
|
screen.render(content, bottomContent);
|
|
@@ -64546,9 +64970,9 @@ var import_run_async = __toESM(require_run_async(), 1);
|
|
|
64546
64970
|
var import_mute_stream2 = __toESM(require_lib3(), 1);
|
|
64547
64971
|
var import_ansi_escapes5 = __toESM(require_ansi_escapes(), 1);
|
|
64548
64972
|
var _2 = {
|
|
64549
|
-
set: (obj,
|
|
64973
|
+
set: (obj, path54 = "", value) => {
|
|
64550
64974
|
let pointer = obj;
|
|
64551
|
-
|
|
64975
|
+
path54.split(".").forEach((key, index, arr) => {
|
|
64552
64976
|
if (key === "__proto__" || key === "constructor")
|
|
64553
64977
|
return;
|
|
64554
64978
|
if (index === arr.length - 1) {
|
|
@@ -64559,8 +64983,8 @@ var _2 = {
|
|
|
64559
64983
|
pointer = pointer[key];
|
|
64560
64984
|
});
|
|
64561
64985
|
},
|
|
64562
|
-
get: (obj,
|
|
64563
|
-
const travel = (regexp) => String.prototype.split.call(
|
|
64986
|
+
get: (obj, path54 = "", defaultValue) => {
|
|
64987
|
+
const travel = (regexp) => String.prototype.split.call(path54, regexp).filter(Boolean).reduce(
|
|
64564
64988
|
// @ts-expect-error implicit any on res[key]
|
|
64565
64989
|
(res, key) => res !== null && res !== void 0 ? res[key] : res,
|
|
64566
64990
|
obj
|
|
@@ -64674,7 +65098,7 @@ var PromptsRunner = class {
|
|
|
64674
65098
|
throw new Error(`Prompt for type ${question.type} not found`);
|
|
64675
65099
|
}
|
|
64676
65100
|
let cleanupSignal;
|
|
64677
|
-
const promptFn = isPromptConstructor(prompt2) ? (q2, { signal: signal2 } = {}) => new Promise((
|
|
65101
|
+
const promptFn = isPromptConstructor(prompt2) ? (q2, { signal: signal2 } = {}) => new Promise((resolve38, reject) => {
|
|
64678
65102
|
const rl = import_node_readline.default.createInterface(setupReadlineOptions(this.opt));
|
|
64679
65103
|
rl.resume();
|
|
64680
65104
|
const onClose = () => {
|
|
@@ -64710,7 +65134,7 @@ var PromptsRunner = class {
|
|
|
64710
65134
|
cleanupSignal = void 0;
|
|
64711
65135
|
};
|
|
64712
65136
|
}
|
|
64713
|
-
activePrompt.run().then(
|
|
65137
|
+
activePrompt.run().then(resolve38, reject).finally(cleanup);
|
|
64714
65138
|
}) : prompt2;
|
|
64715
65139
|
const { signal: moduleSignal } = this.opt;
|
|
64716
65140
|
if (moduleSignal?.aborted) {
|
|
@@ -64924,7 +65348,7 @@ var preferencesCommand = {
|
|
|
64924
65348
|
};
|
|
64925
65349
|
|
|
64926
65350
|
// src/cli/commands/telemetry.ts
|
|
64927
|
-
var
|
|
65351
|
+
var path53 = __toESM(require("path"));
|
|
64928
65352
|
init_control_config();
|
|
64929
65353
|
init_otel_hooks();
|
|
64930
65354
|
init_telemetry_config();
|
|
@@ -65009,7 +65433,7 @@ async function handleOff() {
|
|
|
65009
65433
|
info("Mission Control will not auto-start. Existing usage rows are kept.");
|
|
65010
65434
|
}
|
|
65011
65435
|
async function handleWriteEnv(argv) {
|
|
65012
|
-
const repoPath =
|
|
65436
|
+
const repoPath = path53.resolve(argv.repo);
|
|
65013
65437
|
const harnessRoot = resolveHarnessRoot(repoPath);
|
|
65014
65438
|
const session = readSlotRegistry(harnessRoot, argv.agentId);
|
|
65015
65439
|
const workDir = argv.workDir ?? session?.workDir ?? repoPath;
|
|
@@ -65021,7 +65445,7 @@ async function handleWriteEnv(argv) {
|
|
|
65021
65445
|
suffix,
|
|
65022
65446
|
createdAt: session?.createdAt
|
|
65023
65447
|
});
|
|
65024
|
-
const envFile = argv.envFile ??
|
|
65448
|
+
const envFile = argv.envFile ?? path53.join(workDir, `.env.agent.${argv.agentId}`);
|
|
65025
65449
|
const attrs = {
|
|
65026
65450
|
sessionKey,
|
|
65027
65451
|
agentId: argv.agentId,
|
|
@@ -65040,7 +65464,7 @@ async function handleWriteEnv(argv) {
|
|
|
65040
65464
|
success(`Wrote session attribution to ${envFile}`);
|
|
65041
65465
|
}
|
|
65042
65466
|
function handlePrintEnv(argv) {
|
|
65043
|
-
const repoPath =
|
|
65467
|
+
const repoPath = path53.resolve(argv.repo);
|
|
65044
65468
|
const workDir = argv.workDir ?? repoPath;
|
|
65045
65469
|
const sessionKey = buildSessionKey({
|
|
65046
65470
|
branch: argv.branch,
|