@osfactory/har 0.20.0 → 0.22.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 +14 -0
- package/dist/index.js +1140 -529
- package/dist/templates/agent-skills/har-wt.md +11 -0
- package/dist/templates/har-boilerplate/agent-slot.sh +3 -1
- package/dist/templates/har-boilerplate/gitignore.template +3 -0
- package/dist/templates/har-boilerplate/launch.sh +10 -0
- package/dist/templates/har-boilerplate-cli/agent-slot.sh +3 -1
- package/dist/templates/har-boilerplate-cli/gitignore.template +3 -0
- package/dist/templates/har-boilerplate-cli/launch.sh +10 -0
- package/dist/templates/har-boilerplate-ios/agent-slot.sh +3 -1
- package/dist/templates/har-boilerplate-ios/gitignore.template +3 -0
- package/dist/templates/har-boilerplate-ios/launch.sh +10 -0
- 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(path52, { 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,44 @@ 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
|
+
createdAt: parsed.createdAt ?? ""
|
|
6453
|
+
};
|
|
6454
|
+
} catch {
|
|
6455
|
+
return null;
|
|
6456
|
+
}
|
|
6457
|
+
}
|
|
6458
|
+
function writePortalCredentials(creds) {
|
|
6459
|
+
const file = portalCredentialsPath();
|
|
6460
|
+
fs26.mkdirSync(path25.dirname(file), { recursive: true });
|
|
6461
|
+
fs26.writeFileSync(file, JSON.stringify(creds, null, 2), { mode: 384 });
|
|
6462
|
+
fs26.chmodSync(file, 384);
|
|
6463
|
+
}
|
|
6464
|
+
var fs26, os4, path25;
|
|
6465
|
+
var init_portal_credentials = __esm({
|
|
6466
|
+
"src/core/portal-credentials.ts"() {
|
|
6467
|
+
"use strict";
|
|
6468
|
+
fs26 = __toESM(require("fs"));
|
|
6469
|
+
os4 = __toESM(require("os"));
|
|
6470
|
+
path25 = __toESM(require("path"));
|
|
6471
|
+
}
|
|
6472
|
+
});
|
|
6473
|
+
|
|
6436
6474
|
// src/core/control-config.ts
|
|
6437
6475
|
function getControlApiUrl() {
|
|
6438
6476
|
return process.env.HAR_CONTROL_API_URL ?? DEFAULT_CONTROL_API_URL;
|
|
@@ -6440,10 +6478,33 @@ function getControlApiUrl() {
|
|
|
6440
6478
|
function isControlEnabled() {
|
|
6441
6479
|
return process.env.HAR_CONTROL_DISABLED !== "true";
|
|
6442
6480
|
}
|
|
6481
|
+
function normalizeUrl(url) {
|
|
6482
|
+
return url.replace(/\/+$/, "");
|
|
6483
|
+
}
|
|
6484
|
+
function getPortalTarget() {
|
|
6485
|
+
if (process.env.HAR_PORTAL_URL && process.env.HAR_PORTAL_TOKEN) {
|
|
6486
|
+
return {
|
|
6487
|
+
url: normalizeUrl(process.env.HAR_PORTAL_URL),
|
|
6488
|
+
token: process.env.HAR_PORTAL_TOKEN
|
|
6489
|
+
};
|
|
6490
|
+
}
|
|
6491
|
+
const stored = readPortalCredentials();
|
|
6492
|
+
if (stored) {
|
|
6493
|
+
return { url: normalizeUrl(stored.portalUrl), token: stored.token };
|
|
6494
|
+
}
|
|
6495
|
+
if (process.env.HAR_CLOUD_API_URL && process.env.HAR_CLOUD_API_KEY) {
|
|
6496
|
+
return {
|
|
6497
|
+
url: normalizeUrl(process.env.HAR_CLOUD_API_URL),
|
|
6498
|
+
token: process.env.HAR_CLOUD_API_KEY
|
|
6499
|
+
};
|
|
6500
|
+
}
|
|
6501
|
+
return null;
|
|
6502
|
+
}
|
|
6443
6503
|
var DEFAULT_CONTROL_API_URL;
|
|
6444
6504
|
var init_control_config = __esm({
|
|
6445
6505
|
"src/core/control-config.ts"() {
|
|
6446
6506
|
"use strict";
|
|
6507
|
+
init_portal_credentials();
|
|
6447
6508
|
DEFAULT_CONTROL_API_URL = "http://localhost:3847";
|
|
6448
6509
|
}
|
|
6449
6510
|
});
|
|
@@ -6451,9 +6512,9 @@ var init_control_config = __esm({
|
|
|
6451
6512
|
// src/core/telemetry-config.ts
|
|
6452
6513
|
function getPreferencePath() {
|
|
6453
6514
|
if (process.env.HAR_TELEMETRY_CONFIG_PATH) {
|
|
6454
|
-
return
|
|
6515
|
+
return path37.resolve(process.env.HAR_TELEMETRY_CONFIG_PATH);
|
|
6455
6516
|
}
|
|
6456
|
-
return
|
|
6517
|
+
return path37.join(os10.homedir(), ".har", "telemetry.json");
|
|
6457
6518
|
}
|
|
6458
6519
|
function parseEnvOverride(raw) {
|
|
6459
6520
|
if (raw === void 0 || raw === "") return void 0;
|
|
@@ -6474,10 +6535,10 @@ function normalizeSignals(enabled, raw) {
|
|
|
6474
6535
|
function readTelemetryPreference() {
|
|
6475
6536
|
const preferencePath = getPreferencePath();
|
|
6476
6537
|
try {
|
|
6477
|
-
if (!
|
|
6538
|
+
if (!fs37.existsSync(preferencePath)) {
|
|
6478
6539
|
return { enabled: true, signals: { ...DEFAULT_SIGNALS_ON } };
|
|
6479
6540
|
}
|
|
6480
|
-
const parsed = JSON.parse(
|
|
6541
|
+
const parsed = JSON.parse(fs37.readFileSync(preferencePath, "utf8"));
|
|
6481
6542
|
const enabled = parsed.enabled !== false;
|
|
6482
6543
|
return {
|
|
6483
6544
|
enabled,
|
|
@@ -6500,8 +6561,8 @@ function writeTelemetryPreference(enabled, signals2) {
|
|
|
6500
6561
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
6501
6562
|
};
|
|
6502
6563
|
const preferencePath = getPreferencePath();
|
|
6503
|
-
|
|
6504
|
-
|
|
6564
|
+
fs37.mkdirSync(path37.dirname(preferencePath), { recursive: true });
|
|
6565
|
+
fs37.writeFileSync(preferencePath, JSON.stringify(preference, null, 2) + "\n");
|
|
6505
6566
|
return preference;
|
|
6506
6567
|
}
|
|
6507
6568
|
function isTelemetryEnabled() {
|
|
@@ -6516,13 +6577,13 @@ function getTelemetrySignals() {
|
|
|
6516
6577
|
function getTelemetryPreferencePath() {
|
|
6517
6578
|
return getPreferencePath();
|
|
6518
6579
|
}
|
|
6519
|
-
var
|
|
6580
|
+
var fs37, os10, path37, DEFAULT_SIGNALS_ON, DEFAULT_SIGNALS_OFF, TELEMETRY_SIGNALS;
|
|
6520
6581
|
var init_telemetry_config = __esm({
|
|
6521
6582
|
"src/core/telemetry-config.ts"() {
|
|
6522
6583
|
"use strict";
|
|
6523
|
-
|
|
6524
|
-
|
|
6525
|
-
|
|
6584
|
+
fs37 = __toESM(require("fs"));
|
|
6585
|
+
os10 = __toESM(require("os"));
|
|
6586
|
+
path37 = __toESM(require("path"));
|
|
6526
6587
|
DEFAULT_SIGNALS_ON = {
|
|
6527
6588
|
metrics: true,
|
|
6528
6589
|
logs: true,
|
|
@@ -6563,15 +6624,15 @@ __export(otel_hooks_exports, {
|
|
|
6563
6624
|
});
|
|
6564
6625
|
function getOtelHooksHome() {
|
|
6565
6626
|
if (process.env.HAR_OTEL_HOOKS_HOME) {
|
|
6566
|
-
return
|
|
6627
|
+
return path43.resolve(process.env.HAR_OTEL_HOOKS_HOME);
|
|
6567
6628
|
}
|
|
6568
|
-
return
|
|
6629
|
+
return path43.join(os13.homedir(), ".har", "otel-hooks");
|
|
6569
6630
|
}
|
|
6570
6631
|
function getOtelHooksConfigPath(hooksHome = getOtelHooksHome()) {
|
|
6571
|
-
return
|
|
6632
|
+
return path43.join(hooksHome, "otel_config.json");
|
|
6572
6633
|
}
|
|
6573
6634
|
function getOtelHooksWrapperPath(hooksHome = getOtelHooksHome()) {
|
|
6574
|
-
return
|
|
6635
|
+
return path43.join(hooksHome, "run-otel-hook.sh");
|
|
6575
6636
|
}
|
|
6576
6637
|
function buildOtelHooksConfig(options) {
|
|
6577
6638
|
const enabled = options?.enabled ?? isTelemetryEnabled();
|
|
@@ -6590,18 +6651,18 @@ function buildOtelHooksConfig(options) {
|
|
|
6590
6651
|
};
|
|
6591
6652
|
}
|
|
6592
6653
|
function writeOtelHooksConfig(config2, hooksHome = getOtelHooksHome()) {
|
|
6593
|
-
|
|
6654
|
+
fs41.mkdirSync(hooksHome, { recursive: true });
|
|
6594
6655
|
const configPath = getOtelHooksConfigPath(hooksHome);
|
|
6595
6656
|
const payload = {
|
|
6596
6657
|
_comment: "Managed by har telemetry \u2014 do not edit by hand; use: har telemetry on|off",
|
|
6597
6658
|
...config2
|
|
6598
6659
|
};
|
|
6599
|
-
|
|
6660
|
+
fs41.writeFileSync(configPath, `${JSON.stringify(payload, null, 2)}
|
|
6600
6661
|
`);
|
|
6601
6662
|
return configPath;
|
|
6602
6663
|
}
|
|
6603
6664
|
function writeOtelHooksWrapper(otelHookCommand, hooksHome = getOtelHooksHome()) {
|
|
6604
|
-
|
|
6665
|
+
fs41.mkdirSync(hooksHome, { recursive: true });
|
|
6605
6666
|
const wrapperPath = getOtelHooksWrapperPath(hooksHome);
|
|
6606
6667
|
const script = `#!/usr/bin/env bash
|
|
6607
6668
|
# Managed by har telemetry \u2014 invokes opentelemetry-hooks with HAR config home.
|
|
@@ -6609,9 +6670,9 @@ set -euo pipefail
|
|
|
6609
6670
|
export IDE_OTEL_HOOK_HOME="${hooksHome}"
|
|
6610
6671
|
exec "${otelHookCommand}" "$@"
|
|
6611
6672
|
`;
|
|
6612
|
-
|
|
6673
|
+
fs41.writeFileSync(wrapperPath, script, { mode: 493 });
|
|
6613
6674
|
try {
|
|
6614
|
-
|
|
6675
|
+
fs41.chmodSync(wrapperPath, 493);
|
|
6615
6676
|
} catch {
|
|
6616
6677
|
}
|
|
6617
6678
|
return wrapperPath;
|
|
@@ -6691,10 +6752,10 @@ function runSetupAgent(agent, otelHookCommand, hooksHome) {
|
|
|
6691
6752
|
};
|
|
6692
6753
|
}
|
|
6693
6754
|
function rewriteHookCommandsToWrapper(filePath, wrapperPath) {
|
|
6694
|
-
if (!
|
|
6755
|
+
if (!fs41.existsSync(filePath)) return false;
|
|
6695
6756
|
let raw;
|
|
6696
6757
|
try {
|
|
6697
|
-
raw =
|
|
6758
|
+
raw = fs41.readFileSync(filePath, "utf8");
|
|
6698
6759
|
} catch {
|
|
6699
6760
|
return false;
|
|
6700
6761
|
}
|
|
@@ -6733,16 +6794,16 @@ function rewriteHookCommandsToWrapper(filePath, wrapperPath) {
|
|
|
6733
6794
|
return changed;
|
|
6734
6795
|
};
|
|
6735
6796
|
if (!walk(parsed)) return false;
|
|
6736
|
-
|
|
6797
|
+
fs41.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
|
|
6737
6798
|
`);
|
|
6738
6799
|
return true;
|
|
6739
6800
|
}
|
|
6740
6801
|
function rewriteKnownHookRegistrations(wrapperPath) {
|
|
6741
|
-
const home =
|
|
6802
|
+
const home = os13.homedir();
|
|
6742
6803
|
const candidates = [
|
|
6743
|
-
|
|
6744
|
-
|
|
6745
|
-
|
|
6804
|
+
path43.join(home, ".cursor", "hooks.json"),
|
|
6805
|
+
path43.join(home, ".claude", "settings.json"),
|
|
6806
|
+
path43.join(home, ".codex", "hooks.json")
|
|
6746
6807
|
];
|
|
6747
6808
|
for (const filePath of candidates) {
|
|
6748
6809
|
try {
|
|
@@ -6755,7 +6816,7 @@ function ensureOtelHooks(options) {
|
|
|
6755
6816
|
const hooksHome = getOtelHooksHome();
|
|
6756
6817
|
const errors = [];
|
|
6757
6818
|
const agentsSetup = [];
|
|
6758
|
-
|
|
6819
|
+
fs41.mkdirSync(hooksHome, { recursive: true });
|
|
6759
6820
|
let otelHookCommand = resolveOtelHookCommand();
|
|
6760
6821
|
if (!otelHookCommand) {
|
|
6761
6822
|
const installed = tryInstallPackage();
|
|
@@ -6824,14 +6885,14 @@ function ensureOtelHooks(options) {
|
|
|
6824
6885
|
function disableOtelHooksExport() {
|
|
6825
6886
|
return writeOtelHooksConfig(buildOtelHooksConfig({ enabled: false }));
|
|
6826
6887
|
}
|
|
6827
|
-
var import_child_process9,
|
|
6888
|
+
var import_child_process9, fs41, os13, path43, OTEL_HOOKS_PACKAGE, OTEL_HOOKS_AGENTS;
|
|
6828
6889
|
var init_otel_hooks = __esm({
|
|
6829
6890
|
"src/core/otel-hooks.ts"() {
|
|
6830
6891
|
"use strict";
|
|
6831
6892
|
import_child_process9 = require("child_process");
|
|
6832
|
-
|
|
6833
|
-
|
|
6834
|
-
|
|
6893
|
+
fs41 = __toESM(require("fs"));
|
|
6894
|
+
os13 = __toESM(require("os"));
|
|
6895
|
+
path43 = __toESM(require("path"));
|
|
6835
6896
|
init_control_config();
|
|
6836
6897
|
init_telemetry_config();
|
|
6837
6898
|
OTEL_HOOKS_PACKAGE = "opentelemetry-hooks==0.14.0";
|
|
@@ -9790,7 +9851,7 @@ var require_compile = __commonJS({
|
|
|
9790
9851
|
const schOrFunc = root.refs[ref];
|
|
9791
9852
|
if (schOrFunc)
|
|
9792
9853
|
return schOrFunc;
|
|
9793
|
-
let _sch =
|
|
9854
|
+
let _sch = resolve38.call(this, root, ref);
|
|
9794
9855
|
if (_sch === void 0) {
|
|
9795
9856
|
const schema = (_a3 = root.localRefs) === null || _a3 === void 0 ? void 0 : _a3[ref];
|
|
9796
9857
|
const { schemaId } = this.opts;
|
|
@@ -9817,7 +9878,7 @@ var require_compile = __commonJS({
|
|
|
9817
9878
|
function sameSchemaEnv(s1, s2) {
|
|
9818
9879
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
9819
9880
|
}
|
|
9820
|
-
function
|
|
9881
|
+
function resolve38(root, ref) {
|
|
9821
9882
|
let sch;
|
|
9822
9883
|
while (typeof (sch = this.refs[ref]) == "string")
|
|
9823
9884
|
ref = sch;
|
|
@@ -10035,8 +10096,8 @@ var require_utils2 = __commonJS({
|
|
|
10035
10096
|
}
|
|
10036
10097
|
return ind;
|
|
10037
10098
|
}
|
|
10038
|
-
function removeDotSegments(
|
|
10039
|
-
let input =
|
|
10099
|
+
function removeDotSegments(path54) {
|
|
10100
|
+
let input = path54;
|
|
10040
10101
|
const output = [];
|
|
10041
10102
|
let nextSlash = -1;
|
|
10042
10103
|
let len = 0;
|
|
@@ -10288,8 +10349,8 @@ var require_schemes = __commonJS({
|
|
|
10288
10349
|
wsComponent.secure = void 0;
|
|
10289
10350
|
}
|
|
10290
10351
|
if (wsComponent.resourceName) {
|
|
10291
|
-
const [
|
|
10292
|
-
wsComponent.path =
|
|
10352
|
+
const [path54, query] = wsComponent.resourceName.split("?");
|
|
10353
|
+
wsComponent.path = path54 && path54 !== "/" ? path54 : void 0;
|
|
10293
10354
|
wsComponent.query = query;
|
|
10294
10355
|
wsComponent.resourceName = void 0;
|
|
10295
10356
|
}
|
|
@@ -10348,7 +10409,7 @@ var require_schemes = __commonJS({
|
|
|
10348
10409
|
urnComponent.nss = (uuidComponent.uuid || "").toLowerCase();
|
|
10349
10410
|
return urnComponent;
|
|
10350
10411
|
}
|
|
10351
|
-
var
|
|
10412
|
+
var http2 = (
|
|
10352
10413
|
/** @type {SchemeHandler} */
|
|
10353
10414
|
{
|
|
10354
10415
|
scheme: "http",
|
|
@@ -10361,7 +10422,7 @@ var require_schemes = __commonJS({
|
|
|
10361
10422
|
/** @type {SchemeHandler} */
|
|
10362
10423
|
{
|
|
10363
10424
|
scheme: "https",
|
|
10364
|
-
domainHost:
|
|
10425
|
+
domainHost: http2.domainHost,
|
|
10365
10426
|
parse: httpParse,
|
|
10366
10427
|
serialize: httpSerialize
|
|
10367
10428
|
}
|
|
@@ -10405,7 +10466,7 @@ var require_schemes = __commonJS({
|
|
|
10405
10466
|
var SCHEMES = (
|
|
10406
10467
|
/** @type {Record<SchemeName, SchemeHandler>} */
|
|
10407
10468
|
{
|
|
10408
|
-
http,
|
|
10469
|
+
http: http2,
|
|
10409
10470
|
https,
|
|
10410
10471
|
ws,
|
|
10411
10472
|
wss,
|
|
@@ -10448,7 +10509,7 @@ var require_fast_uri = __commonJS({
|
|
|
10448
10509
|
}
|
|
10449
10510
|
return uri;
|
|
10450
10511
|
}
|
|
10451
|
-
function
|
|
10512
|
+
function resolve38(baseURI, relativeURI, options) {
|
|
10452
10513
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
10453
10514
|
const resolved = resolveComponent(parse4(baseURI, schemelessOptions), parse4(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
10454
10515
|
schemelessOptions.skipEscape = true;
|
|
@@ -10706,7 +10767,7 @@ var require_fast_uri = __commonJS({
|
|
|
10706
10767
|
var fastUri = {
|
|
10707
10768
|
SCHEMES,
|
|
10708
10769
|
normalize: normalize3,
|
|
10709
|
-
resolve:
|
|
10770
|
+
resolve: resolve38,
|
|
10710
10771
|
resolveComponent,
|
|
10711
10772
|
equal,
|
|
10712
10773
|
serialize,
|
|
@@ -13682,12 +13743,12 @@ var require_dist = __commonJS({
|
|
|
13682
13743
|
throw new Error(`Unknown format "${name}"`);
|
|
13683
13744
|
return f2;
|
|
13684
13745
|
};
|
|
13685
|
-
function addFormats(ajv, list,
|
|
13746
|
+
function addFormats(ajv, list, fs46, exportName) {
|
|
13686
13747
|
var _a3;
|
|
13687
13748
|
var _b2;
|
|
13688
13749
|
(_a3 = (_b2 = ajv.opts.code).formats) !== null && _a3 !== void 0 ? _a3 : _b2.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
|
|
13689
13750
|
for (const f2 of list)
|
|
13690
|
-
ajv.addFormat(f2,
|
|
13751
|
+
ajv.addFormat(f2, fs46[f2]);
|
|
13691
13752
|
}
|
|
13692
13753
|
module2.exports = exports2 = formatsPlugin;
|
|
13693
13754
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -14787,15 +14848,15 @@ var require_route = __commonJS({
|
|
|
14787
14848
|
};
|
|
14788
14849
|
}
|
|
14789
14850
|
function wrapConversion(toModel, graph) {
|
|
14790
|
-
const
|
|
14851
|
+
const path54 = [graph[toModel].parent, toModel];
|
|
14791
14852
|
let fn = conversions[graph[toModel].parent][toModel];
|
|
14792
14853
|
let cur = graph[toModel].parent;
|
|
14793
14854
|
while (graph[cur].parent) {
|
|
14794
|
-
|
|
14855
|
+
path54.unshift(graph[cur].parent);
|
|
14795
14856
|
fn = link(conversions[graph[cur].parent][cur], fn);
|
|
14796
14857
|
cur = graph[cur].parent;
|
|
14797
14858
|
}
|
|
14798
|
-
fn.conversion =
|
|
14859
|
+
fn.conversion = path54;
|
|
14799
14860
|
return fn;
|
|
14800
14861
|
}
|
|
14801
14862
|
module2.exports = function(fromModel) {
|
|
@@ -20725,7 +20786,7 @@ var require_iso2022 = __commonJS({
|
|
|
20725
20786
|
// node_modules/chardet/index.js
|
|
20726
20787
|
var require_chardet = __commonJS({
|
|
20727
20788
|
"node_modules/chardet/index.js"(exports2, module2) {
|
|
20728
|
-
var
|
|
20789
|
+
var fs46 = require("fs");
|
|
20729
20790
|
var utf8 = require_utf8();
|
|
20730
20791
|
var unicode = require_unicode();
|
|
20731
20792
|
var mbcs = require_mbcs();
|
|
@@ -20799,28 +20860,28 @@ var require_chardet = __commonJS({
|
|
|
20799
20860
|
var fd;
|
|
20800
20861
|
var handler = function(err, buffer) {
|
|
20801
20862
|
if (fd) {
|
|
20802
|
-
|
|
20863
|
+
fs46.closeSync(fd);
|
|
20803
20864
|
}
|
|
20804
20865
|
if (err) return cb(err, null);
|
|
20805
20866
|
cb(null, self.detect(buffer, opts));
|
|
20806
20867
|
};
|
|
20807
20868
|
if (opts && opts.sampleSize) {
|
|
20808
|
-
fd =
|
|
20809
|
-
|
|
20869
|
+
fd = fs46.openSync(filepath, "r"), sample = Buffer.allocUnsafe(opts.sampleSize);
|
|
20870
|
+
fs46.read(fd, sample, 0, opts.sampleSize, null, function(err) {
|
|
20810
20871
|
handler(err, sample);
|
|
20811
20872
|
});
|
|
20812
20873
|
return;
|
|
20813
20874
|
}
|
|
20814
|
-
|
|
20875
|
+
fs46.readFile(filepath, handler);
|
|
20815
20876
|
};
|
|
20816
20877
|
module2.exports.detectFileSync = function(filepath, opts) {
|
|
20817
20878
|
if (opts && opts.sampleSize) {
|
|
20818
|
-
var fd =
|
|
20819
|
-
|
|
20820
|
-
|
|
20879
|
+
var fd = fs46.openSync(filepath, "r"), sample2 = Buffer.allocUnsafe(opts.sampleSize);
|
|
20880
|
+
fs46.readSync(fd, sample2, 0, opts.sampleSize);
|
|
20881
|
+
fs46.closeSync(fd);
|
|
20821
20882
|
return self.detect(sample2, opts);
|
|
20822
20883
|
}
|
|
20823
|
-
return self.detect(
|
|
20884
|
+
return self.detect(fs46.readFileSync(filepath), opts);
|
|
20824
20885
|
};
|
|
20825
20886
|
module2.exports.detectAll = function(buffer, opts) {
|
|
20826
20887
|
if (typeof opts !== "object") {
|
|
@@ -24285,16 +24346,16 @@ var require_os_tmpdir = __commonJS({
|
|
|
24285
24346
|
var isWindows = process.platform === "win32";
|
|
24286
24347
|
var trailingSlashRe = isWindows ? /[^:]\\$/ : /.\/$/;
|
|
24287
24348
|
module2.exports = function() {
|
|
24288
|
-
var
|
|
24349
|
+
var path54;
|
|
24289
24350
|
if (isWindows) {
|
|
24290
|
-
|
|
24351
|
+
path54 = process.env.TEMP || process.env.TMP || (process.env.SystemRoot || process.env.windir) + "\\temp";
|
|
24291
24352
|
} else {
|
|
24292
|
-
|
|
24353
|
+
path54 = process.env.TMPDIR || process.env.TMP || process.env.TEMP || "/tmp";
|
|
24293
24354
|
}
|
|
24294
|
-
if (trailingSlashRe.test(
|
|
24295
|
-
|
|
24355
|
+
if (trailingSlashRe.test(path54)) {
|
|
24356
|
+
path54 = path54.slice(0, -1);
|
|
24296
24357
|
}
|
|
24297
|
-
return
|
|
24358
|
+
return path54;
|
|
24298
24359
|
};
|
|
24299
24360
|
}
|
|
24300
24361
|
});
|
|
@@ -24302,9 +24363,9 @@ var require_os_tmpdir = __commonJS({
|
|
|
24302
24363
|
// node_modules/tmp/lib/tmp.js
|
|
24303
24364
|
var require_tmp = __commonJS({
|
|
24304
24365
|
"node_modules/tmp/lib/tmp.js"(exports2, module2) {
|
|
24305
|
-
var
|
|
24306
|
-
var
|
|
24307
|
-
var
|
|
24366
|
+
var fs46 = require("fs");
|
|
24367
|
+
var path54 = require("path");
|
|
24368
|
+
var crypto6 = require("crypto");
|
|
24308
24369
|
var osTmpDir = require_os_tmpdir();
|
|
24309
24370
|
var _c2 = process.binding("constants");
|
|
24310
24371
|
var tmpDir = osTmpDir();
|
|
@@ -24322,9 +24383,9 @@ var require_tmp = __commonJS({
|
|
|
24322
24383
|
function _randomChars(howMany) {
|
|
24323
24384
|
var value = [], rnd = null;
|
|
24324
24385
|
try {
|
|
24325
|
-
rnd =
|
|
24386
|
+
rnd = crypto6.randomBytes(howMany);
|
|
24326
24387
|
} catch (e2) {
|
|
24327
|
-
rnd =
|
|
24388
|
+
rnd = crypto6.pseudoRandomBytes(howMany);
|
|
24328
24389
|
}
|
|
24329
24390
|
for (var i2 = 0; i2 < howMany; i2++) {
|
|
24330
24391
|
value.push(RANDOM_CHARS[rnd[i2] % RANDOM_CHARS.length]);
|
|
@@ -24345,7 +24406,7 @@ var require_tmp = __commonJS({
|
|
|
24345
24406
|
}
|
|
24346
24407
|
function _generateTmpName(opts) {
|
|
24347
24408
|
if (opts.name) {
|
|
24348
|
-
return
|
|
24409
|
+
return path54.join(opts.dir || tmpDir, opts.name);
|
|
24349
24410
|
}
|
|
24350
24411
|
if (opts.template) {
|
|
24351
24412
|
return opts.template.replace(TEMPLATE_PATTERN, _randomChars(6));
|
|
@@ -24356,7 +24417,7 @@ var require_tmp = __commonJS({
|
|
|
24356
24417
|
_randomChars(12),
|
|
24357
24418
|
opts.postfix || ""
|
|
24358
24419
|
].join("");
|
|
24359
|
-
return
|
|
24420
|
+
return path54.join(opts.dir || tmpDir, name);
|
|
24360
24421
|
}
|
|
24361
24422
|
function tmpName(options, callback) {
|
|
24362
24423
|
var args = _parseArguments(options, callback), opts = args[0], cb = args[1], tries = opts.name ? 1 : opts.tries || DEFAULT_TRIES;
|
|
@@ -24366,7 +24427,7 @@ var require_tmp = __commonJS({
|
|
|
24366
24427
|
return cb(new Error("Invalid template provided"));
|
|
24367
24428
|
(function _getUniqueName() {
|
|
24368
24429
|
const name = _generateTmpName(opts);
|
|
24369
|
-
|
|
24430
|
+
fs46.stat(name, function(err) {
|
|
24370
24431
|
if (!err) {
|
|
24371
24432
|
if (tries-- > 0) return _getUniqueName();
|
|
24372
24433
|
return cb(new Error("Could not get a unique tmp filename, max tries reached " + name));
|
|
@@ -24384,7 +24445,7 @@ var require_tmp = __commonJS({
|
|
|
24384
24445
|
do {
|
|
24385
24446
|
const name = _generateTmpName(opts);
|
|
24386
24447
|
try {
|
|
24387
|
-
|
|
24448
|
+
fs46.statSync(name);
|
|
24388
24449
|
} catch (e2) {
|
|
24389
24450
|
return name;
|
|
24390
24451
|
}
|
|
@@ -24396,13 +24457,13 @@ var require_tmp = __commonJS({
|
|
|
24396
24457
|
opts.postfix = _isUndefined(opts.postfix) ? ".tmp" : opts.postfix;
|
|
24397
24458
|
tmpName(opts, function _tmpNameCreated(err, name) {
|
|
24398
24459
|
if (err) return cb(err);
|
|
24399
|
-
|
|
24460
|
+
fs46.open(name, CREATE_FLAGS, opts.mode || FILE_MODE, function _fileCreated(err2, fd) {
|
|
24400
24461
|
if (err2) return cb(err2);
|
|
24401
24462
|
if (opts.discardDescriptor) {
|
|
24402
|
-
return
|
|
24463
|
+
return fs46.close(fd, function _discardCallback(err3) {
|
|
24403
24464
|
if (err3) {
|
|
24404
24465
|
try {
|
|
24405
|
-
|
|
24466
|
+
fs46.unlinkSync(name);
|
|
24406
24467
|
} catch (e2) {
|
|
24407
24468
|
if (!isENOENT(e2)) {
|
|
24408
24469
|
err3 = e2;
|
|
@@ -24425,9 +24486,9 @@ var require_tmp = __commonJS({
|
|
|
24425
24486
|
opts.postfix = opts.postfix || ".tmp";
|
|
24426
24487
|
const discardOrDetachDescriptor = opts.discardDescriptor || opts.detachDescriptor;
|
|
24427
24488
|
const name = tmpNameSync(opts);
|
|
24428
|
-
var fd =
|
|
24489
|
+
var fd = fs46.openSync(name, CREATE_FLAGS, opts.mode || FILE_MODE);
|
|
24429
24490
|
if (opts.discardDescriptor) {
|
|
24430
|
-
|
|
24491
|
+
fs46.closeSync(fd);
|
|
24431
24492
|
fd = void 0;
|
|
24432
24493
|
}
|
|
24433
24494
|
return {
|
|
@@ -24439,9 +24500,9 @@ var require_tmp = __commonJS({
|
|
|
24439
24500
|
function _rmdirRecursiveSync(root) {
|
|
24440
24501
|
const dirs = [root];
|
|
24441
24502
|
do {
|
|
24442
|
-
var dir2 = dirs.pop(), deferred = false, files =
|
|
24503
|
+
var dir2 = dirs.pop(), deferred = false, files = fs46.readdirSync(dir2);
|
|
24443
24504
|
for (var i2 = 0, length = files.length; i2 < length; i2++) {
|
|
24444
|
-
var file2 =
|
|
24505
|
+
var file2 = path54.join(dir2, files[i2]), stat = fs46.lstatSync(file2);
|
|
24445
24506
|
if (stat.isDirectory()) {
|
|
24446
24507
|
if (!deferred) {
|
|
24447
24508
|
deferred = true;
|
|
@@ -24449,11 +24510,11 @@ var require_tmp = __commonJS({
|
|
|
24449
24510
|
}
|
|
24450
24511
|
dirs.push(file2);
|
|
24451
24512
|
} else {
|
|
24452
|
-
|
|
24513
|
+
fs46.unlinkSync(file2);
|
|
24453
24514
|
}
|
|
24454
24515
|
}
|
|
24455
24516
|
if (!deferred) {
|
|
24456
|
-
|
|
24517
|
+
fs46.rmdirSync(dir2);
|
|
24457
24518
|
}
|
|
24458
24519
|
} while (dirs.length !== 0);
|
|
24459
24520
|
}
|
|
@@ -24461,7 +24522,7 @@ var require_tmp = __commonJS({
|
|
|
24461
24522
|
var args = _parseArguments(options, callback), opts = args[0], cb = args[1];
|
|
24462
24523
|
tmpName(opts, function _tmpNameCreated(err, name) {
|
|
24463
24524
|
if (err) return cb(err);
|
|
24464
|
-
|
|
24525
|
+
fs46.mkdir(name, opts.mode || DIR_MODE, function _dirCreated(err2) {
|
|
24465
24526
|
if (err2) return cb(err2);
|
|
24466
24527
|
cb(null, name, _prepareTmpDirRemoveCallback(name, opts));
|
|
24467
24528
|
});
|
|
@@ -24470,7 +24531,7 @@ var require_tmp = __commonJS({
|
|
|
24470
24531
|
function dirSync(options) {
|
|
24471
24532
|
var args = _parseArguments(options), opts = args[0];
|
|
24472
24533
|
const name = tmpNameSync(opts);
|
|
24473
|
-
|
|
24534
|
+
fs46.mkdirSync(name, opts.mode || DIR_MODE);
|
|
24474
24535
|
return {
|
|
24475
24536
|
name,
|
|
24476
24537
|
removeCallback: _prepareTmpDirRemoveCallback(name, opts)
|
|
@@ -24480,7 +24541,7 @@ var require_tmp = __commonJS({
|
|
|
24480
24541
|
const removeCallback = _prepareRemoveCallback(function _removeCallback(fdPath) {
|
|
24481
24542
|
try {
|
|
24482
24543
|
if (0 <= fdPath[0]) {
|
|
24483
|
-
|
|
24544
|
+
fs46.closeSync(fdPath[0]);
|
|
24484
24545
|
}
|
|
24485
24546
|
} catch (e2) {
|
|
24486
24547
|
if (!isEBADF(e2) && !isENOENT(e2)) {
|
|
@@ -24488,7 +24549,7 @@ var require_tmp = __commonJS({
|
|
|
24488
24549
|
}
|
|
24489
24550
|
}
|
|
24490
24551
|
try {
|
|
24491
|
-
|
|
24552
|
+
fs46.unlinkSync(fdPath[1]);
|
|
24492
24553
|
} catch (e2) {
|
|
24493
24554
|
if (!isENOENT(e2)) {
|
|
24494
24555
|
throw e2;
|
|
@@ -24501,7 +24562,7 @@ var require_tmp = __commonJS({
|
|
|
24501
24562
|
return removeCallback;
|
|
24502
24563
|
}
|
|
24503
24564
|
function _prepareTmpDirRemoveCallback(name, opts) {
|
|
24504
|
-
const removeFunction = opts.unsafeCleanup ? _rmdirRecursiveSync :
|
|
24565
|
+
const removeFunction = opts.unsafeCleanup ? _rmdirRecursiveSync : fs46.rmdirSync.bind(fs46);
|
|
24505
24566
|
const removeCallback = _prepareRemoveCallback(removeFunction, name);
|
|
24506
24567
|
if (!opts.keep) {
|
|
24507
24568
|
_removeObjects.unshift(removeCallback);
|
|
@@ -25652,7 +25713,7 @@ var require_Observable = __commonJS({
|
|
|
25652
25713
|
Observable2.prototype.forEach = function(next, promiseCtor) {
|
|
25653
25714
|
var _this = this;
|
|
25654
25715
|
promiseCtor = getPromiseCtor(promiseCtor);
|
|
25655
|
-
return new promiseCtor(function(
|
|
25716
|
+
return new promiseCtor(function(resolve38, reject) {
|
|
25656
25717
|
var subscriber = new Subscriber_1.SafeSubscriber({
|
|
25657
25718
|
next: function(value) {
|
|
25658
25719
|
try {
|
|
@@ -25663,7 +25724,7 @@ var require_Observable = __commonJS({
|
|
|
25663
25724
|
}
|
|
25664
25725
|
},
|
|
25665
25726
|
error: reject,
|
|
25666
|
-
complete:
|
|
25727
|
+
complete: resolve38
|
|
25667
25728
|
});
|
|
25668
25729
|
_this.subscribe(subscriber);
|
|
25669
25730
|
});
|
|
@@ -25685,14 +25746,14 @@ var require_Observable = __commonJS({
|
|
|
25685
25746
|
Observable2.prototype.toPromise = function(promiseCtor) {
|
|
25686
25747
|
var _this = this;
|
|
25687
25748
|
promiseCtor = getPromiseCtor(promiseCtor);
|
|
25688
|
-
return new promiseCtor(function(
|
|
25749
|
+
return new promiseCtor(function(resolve38, reject) {
|
|
25689
25750
|
var value;
|
|
25690
25751
|
_this.subscribe(function(x2) {
|
|
25691
25752
|
return value = x2;
|
|
25692
25753
|
}, function(err) {
|
|
25693
25754
|
return reject(err);
|
|
25694
25755
|
}, function() {
|
|
25695
|
-
return
|
|
25756
|
+
return resolve38(value);
|
|
25696
25757
|
});
|
|
25697
25758
|
});
|
|
25698
25759
|
};
|
|
@@ -27788,11 +27849,11 @@ var require_innerFrom = __commonJS({
|
|
|
27788
27849
|
"use strict";
|
|
27789
27850
|
var __awaiter = exports2 && exports2.__awaiter || function(thisArg, _arguments, P2, generator) {
|
|
27790
27851
|
function adopt(value) {
|
|
27791
|
-
return value instanceof P2 ? value : new P2(function(
|
|
27792
|
-
|
|
27852
|
+
return value instanceof P2 ? value : new P2(function(resolve38) {
|
|
27853
|
+
resolve38(value);
|
|
27793
27854
|
});
|
|
27794
27855
|
}
|
|
27795
|
-
return new (P2 || (P2 = Promise))(function(
|
|
27856
|
+
return new (P2 || (P2 = Promise))(function(resolve38, reject) {
|
|
27796
27857
|
function fulfilled(value) {
|
|
27797
27858
|
try {
|
|
27798
27859
|
step(generator.next(value));
|
|
@@ -27808,7 +27869,7 @@ var require_innerFrom = __commonJS({
|
|
|
27808
27869
|
}
|
|
27809
27870
|
}
|
|
27810
27871
|
function step(result) {
|
|
27811
|
-
result.done ?
|
|
27872
|
+
result.done ? resolve38(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
27812
27873
|
}
|
|
27813
27874
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
27814
27875
|
});
|
|
@@ -27890,14 +27951,14 @@ var require_innerFrom = __commonJS({
|
|
|
27890
27951
|
}, i2);
|
|
27891
27952
|
function verb(n2) {
|
|
27892
27953
|
i2[n2] = o2[n2] && function(v2) {
|
|
27893
|
-
return new Promise(function(
|
|
27894
|
-
v2 = o2[n2](v2), settle(
|
|
27954
|
+
return new Promise(function(resolve38, reject) {
|
|
27955
|
+
v2 = o2[n2](v2), settle(resolve38, reject, v2.done, v2.value);
|
|
27895
27956
|
});
|
|
27896
27957
|
};
|
|
27897
27958
|
}
|
|
27898
|
-
function settle(
|
|
27959
|
+
function settle(resolve38, reject, d2, v2) {
|
|
27899
27960
|
Promise.resolve(v2).then(function(v3) {
|
|
27900
|
-
|
|
27961
|
+
resolve38({ value: v3, done: d2 });
|
|
27901
27962
|
}, reject);
|
|
27902
27963
|
}
|
|
27903
27964
|
};
|
|
@@ -28516,7 +28577,7 @@ var require_lastValueFrom = __commonJS({
|
|
|
28516
28577
|
var EmptyError_1 = require_EmptyError();
|
|
28517
28578
|
function lastValueFrom2(source, config2) {
|
|
28518
28579
|
var hasConfig = typeof config2 === "object";
|
|
28519
|
-
return new Promise(function(
|
|
28580
|
+
return new Promise(function(resolve38, reject) {
|
|
28520
28581
|
var _hasValue = false;
|
|
28521
28582
|
var _value;
|
|
28522
28583
|
source.subscribe({
|
|
@@ -28527,9 +28588,9 @@ var require_lastValueFrom = __commonJS({
|
|
|
28527
28588
|
error: reject,
|
|
28528
28589
|
complete: function() {
|
|
28529
28590
|
if (_hasValue) {
|
|
28530
|
-
|
|
28591
|
+
resolve38(_value);
|
|
28531
28592
|
} else if (hasConfig) {
|
|
28532
|
-
|
|
28593
|
+
resolve38(config2.defaultValue);
|
|
28533
28594
|
} else {
|
|
28534
28595
|
reject(new EmptyError_1.EmptyError());
|
|
28535
28596
|
}
|
|
@@ -28551,16 +28612,16 @@ var require_firstValueFrom = __commonJS({
|
|
|
28551
28612
|
var Subscriber_1 = require_Subscriber();
|
|
28552
28613
|
function firstValueFrom(source, config2) {
|
|
28553
28614
|
var hasConfig = typeof config2 === "object";
|
|
28554
|
-
return new Promise(function(
|
|
28615
|
+
return new Promise(function(resolve38, reject) {
|
|
28555
28616
|
var subscriber = new Subscriber_1.SafeSubscriber({
|
|
28556
28617
|
next: function(value) {
|
|
28557
|
-
|
|
28618
|
+
resolve38(value);
|
|
28558
28619
|
subscriber.unsubscribe();
|
|
28559
28620
|
},
|
|
28560
28621
|
error: reject,
|
|
28561
28622
|
complete: function() {
|
|
28562
28623
|
if (hasConfig) {
|
|
28563
|
-
|
|
28624
|
+
resolve38(config2.defaultValue);
|
|
28564
28625
|
} else {
|
|
28565
28626
|
reject(new EmptyError_1.EmptyError());
|
|
28566
28627
|
}
|
|
@@ -34353,14 +34414,14 @@ var require_run_async = __commonJS({
|
|
|
34353
34414
|
return function() {
|
|
34354
34415
|
var args = arguments;
|
|
34355
34416
|
var originalThis = this;
|
|
34356
|
-
var promise = new Promise(function(
|
|
34417
|
+
var promise = new Promise(function(resolve38, reject) {
|
|
34357
34418
|
var resolved = false;
|
|
34358
34419
|
const wrappedResolve = function(value) {
|
|
34359
34420
|
if (resolved) {
|
|
34360
34421
|
console.warn("Run-async promise already resolved.");
|
|
34361
34422
|
}
|
|
34362
34423
|
resolved = true;
|
|
34363
|
-
|
|
34424
|
+
resolve38(value);
|
|
34364
34425
|
};
|
|
34365
34426
|
var rejected = false;
|
|
34366
34427
|
const wrappedReject = function(value) {
|
|
@@ -35714,11 +35775,11 @@ var parser = new YargsParser({
|
|
|
35714
35775
|
resolve: import_path2.resolve,
|
|
35715
35776
|
// TODO: figure out a way to combine ESM and CJS coverage, such that
|
|
35716
35777
|
// we can exercise all the lines below:
|
|
35717
|
-
require: (
|
|
35778
|
+
require: (path54) => {
|
|
35718
35779
|
if (typeof require !== "undefined") {
|
|
35719
|
-
return require(
|
|
35720
|
-
} else if (
|
|
35721
|
-
return JSON.parse((0, import_fs2.readFileSync)(
|
|
35780
|
+
return require(path54);
|
|
35781
|
+
} else if (path54.match(/\.json$/)) {
|
|
35782
|
+
return JSON.parse((0, import_fs2.readFileSync)(path54, "utf8"));
|
|
35722
35783
|
} else {
|
|
35723
35784
|
throw Error("only .json config files are supported in ESM");
|
|
35724
35785
|
}
|
|
@@ -38244,12 +38305,12 @@ var YargsInstance = class {
|
|
|
38244
38305
|
async getCompletion(args, done) {
|
|
38245
38306
|
argsert("<array> [function]", [args, done], arguments.length);
|
|
38246
38307
|
if (!done) {
|
|
38247
|
-
return new Promise((
|
|
38308
|
+
return new Promise((resolve38, reject) => {
|
|
38248
38309
|
__classPrivateFieldGet(this, _YargsInstance_completion, "f").getCompletion(args, (err, completions) => {
|
|
38249
38310
|
if (err)
|
|
38250
38311
|
reject(err);
|
|
38251
38312
|
else
|
|
38252
|
-
|
|
38313
|
+
resolve38(completions);
|
|
38253
38314
|
});
|
|
38254
38315
|
});
|
|
38255
38316
|
} else {
|
|
@@ -40399,8 +40460,8 @@ function getErrorMap() {
|
|
|
40399
40460
|
|
|
40400
40461
|
// node_modules/zod/v3/helpers/parseUtil.js
|
|
40401
40462
|
var makeIssue = (params) => {
|
|
40402
|
-
const { data, path:
|
|
40403
|
-
const fullPath = [...
|
|
40463
|
+
const { data, path: path54, errorMaps, issueData } = params;
|
|
40464
|
+
const fullPath = [...path54, ...issueData.path || []];
|
|
40404
40465
|
const fullIssue = {
|
|
40405
40466
|
...issueData,
|
|
40406
40467
|
path: fullPath
|
|
@@ -40516,11 +40577,11 @@ var errorUtil;
|
|
|
40516
40577
|
|
|
40517
40578
|
// node_modules/zod/v3/types.js
|
|
40518
40579
|
var ParseInputLazyPath = class {
|
|
40519
|
-
constructor(parent, value,
|
|
40580
|
+
constructor(parent, value, path54, key) {
|
|
40520
40581
|
this._cachedPath = [];
|
|
40521
40582
|
this.parent = parent;
|
|
40522
40583
|
this.data = value;
|
|
40523
|
-
this._path =
|
|
40584
|
+
this._path = path54;
|
|
40524
40585
|
this._key = key;
|
|
40525
40586
|
}
|
|
40526
40587
|
get path() {
|
|
@@ -44117,6 +44178,51 @@ var StageKindSchema = HarnessStageKindSchema;
|
|
|
44117
44178
|
var VerificationResultSchema = HarnessVerificationResultSchema;
|
|
44118
44179
|
var StageResultSchema = HarnessStageRunResultSchema;
|
|
44119
44180
|
var RunRecordTriggerSchema = external_exports.enum(["cli", "mcp", "script"]);
|
|
44181
|
+
var WorkUnitIdSchema = external_exports.string().min(1).max(128).regex(
|
|
44182
|
+
/^[A-Za-z0-9][A-Za-z0-9._:/#@-]*$/,
|
|
44183
|
+
"work unit id must start with an alphanumeric character and contain only stable identifier characters"
|
|
44184
|
+
);
|
|
44185
|
+
var WorkAttemptIdSchema = external_exports.string().uuid();
|
|
44186
|
+
var WorkUnitMetadataSchema = external_exports.object({
|
|
44187
|
+
workUnitId: WorkUnitIdSchema,
|
|
44188
|
+
source: external_exports.string().min(1).max(64).optional(),
|
|
44189
|
+
sourceUrl: external_exports.string().url().optional(),
|
|
44190
|
+
title: external_exports.string().min(1).max(256).optional(),
|
|
44191
|
+
parentWorkUnitId: WorkUnitIdSchema.optional()
|
|
44192
|
+
});
|
|
44193
|
+
var WorkUnitOutcomeSchema = external_exports.object({
|
|
44194
|
+
decision: external_exports.enum(["completed", "abandoned"]),
|
|
44195
|
+
decidedAt: external_exports.string(),
|
|
44196
|
+
attemptId: WorkAttemptIdSchema.optional(),
|
|
44197
|
+
validationId: external_exports.string().uuid().optional(),
|
|
44198
|
+
treeHash: external_exports.string().regex(/^[0-9a-f]{40,64}$/).optional(),
|
|
44199
|
+
reason: external_exports.string().max(2e3).optional()
|
|
44200
|
+
}).superRefine((outcome, ctx) => {
|
|
44201
|
+
if (outcome.decision === "completed" && (!outcome.attemptId || !outcome.validationId || !outcome.treeHash)) {
|
|
44202
|
+
ctx.addIssue({
|
|
44203
|
+
code: external_exports.ZodIssueCode.custom,
|
|
44204
|
+
message: "completed work must reference an attempt and exact-tree validation"
|
|
44205
|
+
});
|
|
44206
|
+
}
|
|
44207
|
+
});
|
|
44208
|
+
var WorkUnitRecordSchema = WorkUnitMetadataSchema.extend({
|
|
44209
|
+
version: external_exports.number().int().default(1),
|
|
44210
|
+
createdAt: external_exports.string(),
|
|
44211
|
+
updatedAt: external_exports.string(),
|
|
44212
|
+
outcome: WorkUnitOutcomeSchema.optional()
|
|
44213
|
+
}).passthrough();
|
|
44214
|
+
var WorkAttemptRecordSchema = external_exports.object({
|
|
44215
|
+
version: external_exports.number().int().default(1),
|
|
44216
|
+
attemptId: WorkAttemptIdSchema,
|
|
44217
|
+
workUnitId: WorkUnitIdSchema,
|
|
44218
|
+
agentId: external_exports.number().int().min(HAR_AGENT_SLOT_MIN),
|
|
44219
|
+
sessionKey: external_exports.string().min(1).optional(),
|
|
44220
|
+
workDir: external_exports.string().optional(),
|
|
44221
|
+
worktreePath: external_exports.string().optional(),
|
|
44222
|
+
branch: external_exports.string().optional(),
|
|
44223
|
+
baseCommit: external_exports.string().optional(),
|
|
44224
|
+
createdAt: external_exports.string()
|
|
44225
|
+
}).passthrough();
|
|
44120
44226
|
var RunRecordSchema = external_exports.object({
|
|
44121
44227
|
runId: external_exports.string().uuid(),
|
|
44122
44228
|
repoPath: external_exports.string(),
|
|
@@ -44132,7 +44238,9 @@ var RunRecordSchema = external_exports.object({
|
|
|
44132
44238
|
relativePath: external_exports.string().optional(),
|
|
44133
44239
|
command: external_exports.string().optional(),
|
|
44134
44240
|
workDir: external_exports.string().optional(),
|
|
44135
|
-
harnessRoot: external_exports.string().optional()
|
|
44241
|
+
harnessRoot: external_exports.string().optional(),
|
|
44242
|
+
workUnitId: WorkUnitIdSchema.optional(),
|
|
44243
|
+
attemptId: WorkAttemptIdSchema.optional()
|
|
44136
44244
|
}).passthrough();
|
|
44137
44245
|
var SlotRegistryEntrySchema = external_exports.object({
|
|
44138
44246
|
version: external_exports.number().int().default(1),
|
|
@@ -44154,6 +44262,8 @@ var SlotRegistryEntrySchema = external_exports.object({
|
|
|
44154
44262
|
createdAt: external_exports.string(),
|
|
44155
44263
|
ports: external_exports.record(external_exports.number()).optional(),
|
|
44156
44264
|
previewUrls: external_exports.record(external_exports.string()).optional(),
|
|
44265
|
+
workUnitId: WorkUnitIdSchema.optional(),
|
|
44266
|
+
attemptId: WorkAttemptIdSchema.optional(),
|
|
44157
44267
|
status: external_exports.enum(["starting", "active", "failed", "completed"]).default("active"),
|
|
44158
44268
|
lastError: external_exports.string().optional()
|
|
44159
44269
|
}).passthrough();
|
|
@@ -44199,6 +44309,8 @@ var AgentSlotStatusSchema = external_exports.object({
|
|
|
44199
44309
|
sessionCreatedAt: external_exports.string().optional(),
|
|
44200
44310
|
/** Derived from first captured user prompt (OTEL hooks); not set at launch. */
|
|
44201
44311
|
purpose: external_exports.string().optional(),
|
|
44312
|
+
workUnitId: WorkUnitIdSchema.optional(),
|
|
44313
|
+
attemptId: WorkAttemptIdSchema.optional(),
|
|
44202
44314
|
sessionStatus: external_exports.enum(["starting", "active", "failed", "completed"]).optional(),
|
|
44203
44315
|
lastError: external_exports.string().optional(),
|
|
44204
44316
|
/** Set when a failed/starting session can be resumed without --replace. */
|
|
@@ -44259,6 +44371,10 @@ var SyncSlotsInputSchema = external_exports.object({
|
|
|
44259
44371
|
slots: external_exports.array(AgentSlotStatusSchema),
|
|
44260
44372
|
generatedAt: external_exports.string()
|
|
44261
44373
|
});
|
|
44374
|
+
var SyncWorkUnitsInputSchema = external_exports.object({
|
|
44375
|
+
workUnits: external_exports.array(WorkUnitRecordSchema),
|
|
44376
|
+
attempts: external_exports.array(WorkAttemptRecordSchema)
|
|
44377
|
+
});
|
|
44262
44378
|
var ChangedFileStatusSchema = external_exports.enum(["A", "M", "D", "R", "C", "T", "U"]);
|
|
44263
44379
|
var ChangedFileSchema = external_exports.object({
|
|
44264
44380
|
path: external_exports.string(),
|
|
@@ -44285,6 +44401,17 @@ var ValidationRecordSchema = external_exports.object({
|
|
|
44285
44401
|
var SyncValidationsInputSchema = external_exports.object({
|
|
44286
44402
|
validations: external_exports.array(ValidationRecordSchema)
|
|
44287
44403
|
});
|
|
44404
|
+
var ValidationBindingRecordSchema = external_exports.object({
|
|
44405
|
+
bindingId: external_exports.string().uuid(),
|
|
44406
|
+
workUnitId: WorkUnitIdSchema,
|
|
44407
|
+
attemptId: WorkAttemptIdSchema,
|
|
44408
|
+
validationId: external_exports.string().uuid(),
|
|
44409
|
+
treeHash: external_exports.string().regex(/^[0-9a-f]{40,64}$/),
|
|
44410
|
+
createdAt: external_exports.string()
|
|
44411
|
+
});
|
|
44412
|
+
var SyncValidationBindingsInputSchema = external_exports.object({
|
|
44413
|
+
bindings: external_exports.array(ValidationBindingRecordSchema)
|
|
44414
|
+
});
|
|
44288
44415
|
var AgentToolSchema = external_exports.enum(["claude_code", "codex", "cursor"]);
|
|
44289
44416
|
var UsageSourceSchema = external_exports.enum(["otel", "harvest"]);
|
|
44290
44417
|
var AgentSessionUsageSchema = external_exports.object({
|
|
@@ -44294,6 +44421,8 @@ var AgentSessionUsageSchema = external_exports.object({
|
|
|
44294
44421
|
workDir: external_exports.string().optional(),
|
|
44295
44422
|
branch: external_exports.string().optional(),
|
|
44296
44423
|
suffix: external_exports.string().optional(),
|
|
44424
|
+
workUnitId: WorkUnitIdSchema.optional(),
|
|
44425
|
+
attemptId: WorkAttemptIdSchema.optional(),
|
|
44297
44426
|
tokensInput: external_exports.number().nonnegative().default(0),
|
|
44298
44427
|
tokensOutput: external_exports.number().nonnegative().default(0),
|
|
44299
44428
|
tokensCacheRead: external_exports.number().nonnegative().default(0),
|
|
@@ -44315,6 +44444,8 @@ var AgentSessionEventSchema = external_exports.object({
|
|
|
44315
44444
|
eventName: external_exports.string().min(1),
|
|
44316
44445
|
sequence: external_exports.number().int().nonnegative().default(0),
|
|
44317
44446
|
timestamp: external_exports.string(),
|
|
44447
|
+
workUnitId: WorkUnitIdSchema.optional(),
|
|
44448
|
+
attemptId: WorkAttemptIdSchema.optional(),
|
|
44318
44449
|
attributes: external_exports.record(external_exports.unknown()).optional(),
|
|
44319
44450
|
promptText: external_exports.string().nullable().optional(),
|
|
44320
44451
|
responseText: external_exports.string().nullable().optional(),
|
|
@@ -44589,16 +44720,16 @@ async function handleAgentSkills(options) {
|
|
|
44589
44720
|
}
|
|
44590
44721
|
async function askYesNo(question) {
|
|
44591
44722
|
const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
|
|
44592
|
-
return new Promise((
|
|
44723
|
+
return new Promise((resolve38) => {
|
|
44593
44724
|
process.stderr.write(`${question} `);
|
|
44594
44725
|
rl.once("line", (answer) => {
|
|
44595
44726
|
rl.close();
|
|
44596
44727
|
const trimmed = answer.trim();
|
|
44597
44728
|
if (trimmed === "") {
|
|
44598
|
-
|
|
44729
|
+
resolve38(true);
|
|
44599
44730
|
return;
|
|
44600
44731
|
}
|
|
44601
|
-
|
|
44732
|
+
resolve38(/^y(es)?$/i.test(trimmed));
|
|
44602
44733
|
});
|
|
44603
44734
|
});
|
|
44604
44735
|
}
|
|
@@ -44677,7 +44808,7 @@ function handleRemove(argv) {
|
|
|
44677
44808
|
}
|
|
44678
44809
|
|
|
44679
44810
|
// src/cli/commands/env.ts
|
|
44680
|
-
var
|
|
44811
|
+
var path47 = __toESM(require("path"));
|
|
44681
44812
|
|
|
44682
44813
|
// src/core/harness.ts
|
|
44683
44814
|
var fs20 = __toESM(require("fs"));
|
|
@@ -45456,13 +45587,13 @@ var MultipartBody = class {
|
|
|
45456
45587
|
// node_modules/@anthropic-ai/sdk/_shims/node-runtime.mjs
|
|
45457
45588
|
var import_web = require("node:stream/web");
|
|
45458
45589
|
var fileFromPathWarned = false;
|
|
45459
|
-
async function fileFromPath3(
|
|
45590
|
+
async function fileFromPath3(path54, ...args) {
|
|
45460
45591
|
const { fileFromPath: _fileFromPath } = await Promise.resolve().then(() => (init_fileFromPath(), fileFromPath_exports));
|
|
45461
45592
|
if (!fileFromPathWarned) {
|
|
45462
|
-
console.warn(`fileFromPath is deprecated; use fs.createReadStream(${JSON.stringify(
|
|
45593
|
+
console.warn(`fileFromPath is deprecated; use fs.createReadStream(${JSON.stringify(path54)}) instead`);
|
|
45463
45594
|
fileFromPathWarned = true;
|
|
45464
45595
|
}
|
|
45465
|
-
return await _fileFromPath(
|
|
45596
|
+
return await _fileFromPath(path54, ...args);
|
|
45466
45597
|
}
|
|
45467
45598
|
var defaultHttpAgent = new import_agentkeepalive.default({ keepAlive: true, timeout: 5 * 60 * 1e3 });
|
|
45468
45599
|
var defaultHttpsAgent = new import_agentkeepalive.default.HttpsAgent({ keepAlive: true, timeout: 5 * 60 * 1e3 });
|
|
@@ -45958,8 +46089,8 @@ async function defaultParseResponse(props) {
|
|
|
45958
46089
|
}
|
|
45959
46090
|
var APIPromise = class _APIPromise extends Promise {
|
|
45960
46091
|
constructor(responsePromise, parseResponse = defaultParseResponse) {
|
|
45961
|
-
super((
|
|
45962
|
-
|
|
46092
|
+
super((resolve38) => {
|
|
46093
|
+
resolve38(null);
|
|
45963
46094
|
});
|
|
45964
46095
|
this.responsePromise = responsePromise;
|
|
45965
46096
|
this.parseResponse = parseResponse;
|
|
@@ -46059,29 +46190,29 @@ var APIClient = class {
|
|
|
46059
46190
|
defaultIdempotencyKey() {
|
|
46060
46191
|
return `stainless-node-retry-${uuid4()}`;
|
|
46061
46192
|
}
|
|
46062
|
-
get(
|
|
46063
|
-
return this.methodRequest("get",
|
|
46193
|
+
get(path54, opts) {
|
|
46194
|
+
return this.methodRequest("get", path54, opts);
|
|
46064
46195
|
}
|
|
46065
|
-
post(
|
|
46066
|
-
return this.methodRequest("post",
|
|
46196
|
+
post(path54, opts) {
|
|
46197
|
+
return this.methodRequest("post", path54, opts);
|
|
46067
46198
|
}
|
|
46068
|
-
patch(
|
|
46069
|
-
return this.methodRequest("patch",
|
|
46199
|
+
patch(path54, opts) {
|
|
46200
|
+
return this.methodRequest("patch", path54, opts);
|
|
46070
46201
|
}
|
|
46071
|
-
put(
|
|
46072
|
-
return this.methodRequest("put",
|
|
46202
|
+
put(path54, opts) {
|
|
46203
|
+
return this.methodRequest("put", path54, opts);
|
|
46073
46204
|
}
|
|
46074
|
-
delete(
|
|
46075
|
-
return this.methodRequest("delete",
|
|
46205
|
+
delete(path54, opts) {
|
|
46206
|
+
return this.methodRequest("delete", path54, opts);
|
|
46076
46207
|
}
|
|
46077
|
-
methodRequest(method,
|
|
46208
|
+
methodRequest(method, path54, opts) {
|
|
46078
46209
|
return this.request(Promise.resolve(opts).then(async (opts2) => {
|
|
46079
46210
|
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;
|
|
46080
|
-
return { method, path:
|
|
46211
|
+
return { method, path: path54, ...opts2, body };
|
|
46081
46212
|
}));
|
|
46082
46213
|
}
|
|
46083
|
-
getAPIList(
|
|
46084
|
-
return this.requestAPIList(Page, { method: "get", path:
|
|
46214
|
+
getAPIList(path54, Page, opts) {
|
|
46215
|
+
return this.requestAPIList(Page, { method: "get", path: path54, ...opts });
|
|
46085
46216
|
}
|
|
46086
46217
|
calculateContentLength(body) {
|
|
46087
46218
|
if (typeof body === "string") {
|
|
@@ -46099,10 +46230,10 @@ var APIClient = class {
|
|
|
46099
46230
|
return null;
|
|
46100
46231
|
}
|
|
46101
46232
|
buildRequest(options) {
|
|
46102
|
-
const { method, path:
|
|
46233
|
+
const { method, path: path54, query, headers = {} } = options;
|
|
46103
46234
|
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;
|
|
46104
46235
|
const contentLength = this.calculateContentLength(body);
|
|
46105
|
-
const url = this.buildURL(
|
|
46236
|
+
const url = this.buildURL(path54, query);
|
|
46106
46237
|
if ("timeout" in options)
|
|
46107
46238
|
validatePositiveInteger("timeout", options.timeout);
|
|
46108
46239
|
const timeout = options.timeout ?? this.timeout;
|
|
@@ -46211,8 +46342,8 @@ var APIClient = class {
|
|
|
46211
46342
|
const request = this.makeRequest(options, null);
|
|
46212
46343
|
return new PagePromise(this, request, Page);
|
|
46213
46344
|
}
|
|
46214
|
-
buildURL(
|
|
46215
|
-
const url = isAbsoluteURL(
|
|
46345
|
+
buildURL(path54, query) {
|
|
46346
|
+
const url = isAbsoluteURL(path54) ? new URL(path54) : new URL(this.baseURL + (this.baseURL.endsWith("/") && path54.startsWith("/") ? path54.slice(1) : path54));
|
|
46216
46347
|
const defaultQuery = this.defaultQuery();
|
|
46217
46348
|
if (!isEmptyObj(defaultQuery)) {
|
|
46218
46349
|
query = { ...defaultQuery, ...query };
|
|
@@ -46497,7 +46628,7 @@ var startsWithSchemeRegexp = new RegExp("^(?:[a-z]+:)?//", "i");
|
|
|
46497
46628
|
var isAbsoluteURL = (url) => {
|
|
46498
46629
|
return startsWithSchemeRegexp.test(url);
|
|
46499
46630
|
};
|
|
46500
|
-
var sleep = (ms) => new Promise((
|
|
46631
|
+
var sleep = (ms) => new Promise((resolve38) => setTimeout(resolve38, ms));
|
|
46501
46632
|
var validatePositiveInteger = (name, n2) => {
|
|
46502
46633
|
if (typeof n2 !== "number" || !Number.isInteger(n2)) {
|
|
46503
46634
|
throw new AnthropicError(`${name} must be an integer`);
|
|
@@ -46988,12 +47119,12 @@ var PromptCachingBetaMessageStream = class _PromptCachingBetaMessageStream {
|
|
|
46988
47119
|
}
|
|
46989
47120
|
return this._emit("error", new AnthropicError(String(error3)));
|
|
46990
47121
|
});
|
|
46991
|
-
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_connectedPromise, new Promise((
|
|
46992
|
-
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_resolveConnectedPromise,
|
|
47122
|
+
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_connectedPromise, new Promise((resolve38, reject) => {
|
|
47123
|
+
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_resolveConnectedPromise, resolve38, "f");
|
|
46993
47124
|
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_rejectConnectedPromise, reject, "f");
|
|
46994
47125
|
}), "f");
|
|
46995
|
-
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_endPromise, new Promise((
|
|
46996
|
-
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_resolveEndPromise,
|
|
47126
|
+
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_endPromise, new Promise((resolve38, reject) => {
|
|
47127
|
+
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_resolveEndPromise, resolve38, "f");
|
|
46997
47128
|
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_rejectEndPromise, reject, "f");
|
|
46998
47129
|
}), "f");
|
|
46999
47130
|
__classPrivateFieldGet8(this, _PromptCachingBetaMessageStream_connectedPromise, "f").catch(() => {
|
|
@@ -47122,11 +47253,11 @@ var PromptCachingBetaMessageStream = class _PromptCachingBetaMessageStream {
|
|
|
47122
47253
|
* const message = await stream.emitted('message') // rejects if the stream errors
|
|
47123
47254
|
*/
|
|
47124
47255
|
emitted(event) {
|
|
47125
|
-
return new Promise((
|
|
47256
|
+
return new Promise((resolve38, reject) => {
|
|
47126
47257
|
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_catchingPromiseCreated, true, "f");
|
|
47127
47258
|
if (event !== "error")
|
|
47128
47259
|
this.once("error", reject);
|
|
47129
|
-
this.once(event,
|
|
47260
|
+
this.once(event, resolve38);
|
|
47130
47261
|
});
|
|
47131
47262
|
}
|
|
47132
47263
|
async done() {
|
|
@@ -47353,7 +47484,7 @@ var PromptCachingBetaMessageStream = class _PromptCachingBetaMessageStream {
|
|
|
47353
47484
|
if (done) {
|
|
47354
47485
|
return { value: void 0, done: true };
|
|
47355
47486
|
}
|
|
47356
|
-
return new Promise((
|
|
47487
|
+
return new Promise((resolve38, reject) => readQueue.push({ resolve: resolve38, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
|
|
47357
47488
|
}
|
|
47358
47489
|
const chunk = pushQueue.shift();
|
|
47359
47490
|
return { value: chunk, done: false };
|
|
@@ -47501,12 +47632,12 @@ var MessageStream = class _MessageStream {
|
|
|
47501
47632
|
}
|
|
47502
47633
|
return this._emit("error", new AnthropicError(String(error3)));
|
|
47503
47634
|
});
|
|
47504
|
-
__classPrivateFieldSet8(this, _MessageStream_connectedPromise, new Promise((
|
|
47505
|
-
__classPrivateFieldSet8(this, _MessageStream_resolveConnectedPromise,
|
|
47635
|
+
__classPrivateFieldSet8(this, _MessageStream_connectedPromise, new Promise((resolve38, reject) => {
|
|
47636
|
+
__classPrivateFieldSet8(this, _MessageStream_resolveConnectedPromise, resolve38, "f");
|
|
47506
47637
|
__classPrivateFieldSet8(this, _MessageStream_rejectConnectedPromise, reject, "f");
|
|
47507
47638
|
}), "f");
|
|
47508
|
-
__classPrivateFieldSet8(this, _MessageStream_endPromise, new Promise((
|
|
47509
|
-
__classPrivateFieldSet8(this, _MessageStream_resolveEndPromise,
|
|
47639
|
+
__classPrivateFieldSet8(this, _MessageStream_endPromise, new Promise((resolve38, reject) => {
|
|
47640
|
+
__classPrivateFieldSet8(this, _MessageStream_resolveEndPromise, resolve38, "f");
|
|
47510
47641
|
__classPrivateFieldSet8(this, _MessageStream_rejectEndPromise, reject, "f");
|
|
47511
47642
|
}), "f");
|
|
47512
47643
|
__classPrivateFieldGet9(this, _MessageStream_connectedPromise, "f").catch(() => {
|
|
@@ -47635,11 +47766,11 @@ var MessageStream = class _MessageStream {
|
|
|
47635
47766
|
* const message = await stream.emitted('message') // rejects if the stream errors
|
|
47636
47767
|
*/
|
|
47637
47768
|
emitted(event) {
|
|
47638
|
-
return new Promise((
|
|
47769
|
+
return new Promise((resolve38, reject) => {
|
|
47639
47770
|
__classPrivateFieldSet8(this, _MessageStream_catchingPromiseCreated, true, "f");
|
|
47640
47771
|
if (event !== "error")
|
|
47641
47772
|
this.once("error", reject);
|
|
47642
|
-
this.once(event,
|
|
47773
|
+
this.once(event, resolve38);
|
|
47643
47774
|
});
|
|
47644
47775
|
}
|
|
47645
47776
|
async done() {
|
|
@@ -47866,7 +47997,7 @@ var MessageStream = class _MessageStream {
|
|
|
47866
47997
|
if (done) {
|
|
47867
47998
|
return { value: void 0, done: true };
|
|
47868
47999
|
}
|
|
47869
|
-
return new Promise((
|
|
48000
|
+
return new Promise((resolve38, reject) => readQueue.push({ resolve: resolve38, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
|
|
47870
48001
|
}
|
|
47871
48002
|
const chunk = pushQueue.shift();
|
|
47872
48003
|
return { value: chunk, done: false };
|
|
@@ -48126,11 +48257,11 @@ async function promptApplyAgentMdProposal(repoPath) {
|
|
|
48126
48257
|
}
|
|
48127
48258
|
async function askYesNo2(question) {
|
|
48128
48259
|
const rl = readline2.createInterface({ input: process.stdin, output: process.stderr });
|
|
48129
|
-
return new Promise((
|
|
48260
|
+
return new Promise((resolve38) => {
|
|
48130
48261
|
process.stderr.write(`${question} `);
|
|
48131
48262
|
rl.once("line", (answer) => {
|
|
48132
48263
|
rl.close();
|
|
48133
|
-
|
|
48264
|
+
resolve38(/^y(es)?$/i.test(answer.trim()));
|
|
48134
48265
|
});
|
|
48135
48266
|
});
|
|
48136
48267
|
}
|
|
@@ -48360,7 +48491,7 @@ async function executeAuthoringToolCall(toolName, input, repoPath, harnessDir, c
|
|
|
48360
48491
|
}
|
|
48361
48492
|
async function askUser(question, options) {
|
|
48362
48493
|
const rl = readline3.createInterface({ input: process.stdin, output: process.stderr });
|
|
48363
|
-
return new Promise((
|
|
48494
|
+
return new Promise((resolve38) => {
|
|
48364
48495
|
process.stderr.write("\n");
|
|
48365
48496
|
process.stderr.write(`\u2753 ${question}
|
|
48366
48497
|
`);
|
|
@@ -48371,7 +48502,7 @@ async function askUser(question, options) {
|
|
|
48371
48502
|
process.stderr.write("> ");
|
|
48372
48503
|
rl.once("line", (answer) => {
|
|
48373
48504
|
rl.close();
|
|
48374
|
-
|
|
48505
|
+
resolve38(answer.trim());
|
|
48375
48506
|
});
|
|
48376
48507
|
});
|
|
48377
48508
|
}
|
|
@@ -48515,7 +48646,7 @@ function runScript(scriptPath, args = [], options = {}) {
|
|
|
48515
48646
|
function runScriptCapture(scriptPath, args = [], options = {}) {
|
|
48516
48647
|
const stream = options.stream ?? false;
|
|
48517
48648
|
const { stream: _stream, ...spawnOptions } = options;
|
|
48518
|
-
return new Promise((
|
|
48649
|
+
return new Promise((resolve38) => {
|
|
48519
48650
|
const proc = (0, import_child_process.spawn)("bash", [scriptPath, ...args], {
|
|
48520
48651
|
...spawnOptions,
|
|
48521
48652
|
stdio: ["inherit", "pipe", "pipe"]
|
|
@@ -48530,13 +48661,13 @@ function runScriptCapture(scriptPath, args = [], options = {}) {
|
|
|
48530
48661
|
stderr += d2;
|
|
48531
48662
|
if (stream) process.stderr.write(d2);
|
|
48532
48663
|
});
|
|
48533
|
-
proc.on("close", (code) =>
|
|
48664
|
+
proc.on("close", (code) => resolve38({ stdout, stderr, code: code ?? 0 }));
|
|
48534
48665
|
});
|
|
48535
48666
|
}
|
|
48536
48667
|
function runShellCommand(command2, options = {}) {
|
|
48537
48668
|
const stream = options.stream ?? false;
|
|
48538
48669
|
const { stream: _stream, ...spawnOptions } = options;
|
|
48539
|
-
return new Promise((
|
|
48670
|
+
return new Promise((resolve38) => {
|
|
48540
48671
|
const proc = (0, import_child_process.spawn)("bash", ["-lc", command2], {
|
|
48541
48672
|
...spawnOptions,
|
|
48542
48673
|
stdio: ["inherit", "pipe", "pipe"]
|
|
@@ -48551,7 +48682,7 @@ function runShellCommand(command2, options = {}) {
|
|
|
48551
48682
|
stderr += d2;
|
|
48552
48683
|
if (stream) process.stderr.write(d2);
|
|
48553
48684
|
});
|
|
48554
|
-
proc.on("close", (code) =>
|
|
48685
|
+
proc.on("close", (code) => resolve38({ stdout, stderr, code: code ?? 0 }));
|
|
48555
48686
|
});
|
|
48556
48687
|
}
|
|
48557
48688
|
|
|
@@ -49715,16 +49846,16 @@ async function promptScaffoldCursorRule(exists) {
|
|
|
49715
49846
|
}
|
|
49716
49847
|
async function askYesNo3(question) {
|
|
49717
49848
|
const rl = readline4.createInterface({ input: process.stdin, output: process.stderr });
|
|
49718
|
-
return new Promise((
|
|
49849
|
+
return new Promise((resolve38) => {
|
|
49719
49850
|
process.stderr.write(`${question} `);
|
|
49720
49851
|
rl.once("line", (answer) => {
|
|
49721
49852
|
rl.close();
|
|
49722
49853
|
const trimmed = answer.trim();
|
|
49723
49854
|
if (trimmed === "") {
|
|
49724
|
-
|
|
49855
|
+
resolve38(true);
|
|
49725
49856
|
return;
|
|
49726
49857
|
}
|
|
49727
|
-
|
|
49858
|
+
resolve38(/^y(es)?$/i.test(trimmed));
|
|
49728
49859
|
});
|
|
49729
49860
|
});
|
|
49730
49861
|
}
|
|
@@ -49802,6 +49933,9 @@ function buildStageResult(input) {
|
|
|
49802
49933
|
});
|
|
49803
49934
|
}
|
|
49804
49935
|
|
|
49936
|
+
// src/core/run-service.ts
|
|
49937
|
+
var crypto5 = __toESM(require("crypto"));
|
|
49938
|
+
|
|
49805
49939
|
// src/core/local-executor.ts
|
|
49806
49940
|
var fs25 = __toESM(require("fs"));
|
|
49807
49941
|
var path24 = __toESM(require("path"));
|
|
@@ -49854,6 +49988,8 @@ function buildLaunchFlagArgs(flags) {
|
|
|
49854
49988
|
if (flags.confirmReplace) args.push("--replace");
|
|
49855
49989
|
if (flags.force) args.push("--force");
|
|
49856
49990
|
if (flags.resume) args.push("--resume");
|
|
49991
|
+
if (flags.workUnitId) args.push(`--work-id=${flags.workUnitId}`);
|
|
49992
|
+
if (flags.attemptId) args.push(`--attempt-id=${flags.attemptId}`);
|
|
49857
49993
|
return args;
|
|
49858
49994
|
}
|
|
49859
49995
|
function resolveRepoPath(repoPath) {
|
|
@@ -50029,19 +50165,19 @@ var LocalScriptExecutor = class {
|
|
|
50029
50165
|
var localScriptExecutor = new LocalScriptExecutor();
|
|
50030
50166
|
|
|
50031
50167
|
// src/core/control-sync.ts
|
|
50032
|
-
var
|
|
50168
|
+
var path41 = __toESM(require("path"));
|
|
50033
50169
|
init_control_config();
|
|
50034
50170
|
|
|
50035
50171
|
// src/core/control-registry.ts
|
|
50036
|
-
var
|
|
50037
|
-
var
|
|
50038
|
-
var
|
|
50172
|
+
var fs28 = __toESM(require("fs"));
|
|
50173
|
+
var os5 = __toESM(require("os"));
|
|
50174
|
+
var path27 = __toESM(require("path"));
|
|
50039
50175
|
|
|
50040
50176
|
// src/core/control-repo-path.ts
|
|
50041
|
-
var
|
|
50042
|
-
var
|
|
50177
|
+
var fs27 = __toESM(require("fs"));
|
|
50178
|
+
var path26 = __toESM(require("path"));
|
|
50043
50179
|
function tryGit(cwd, args) {
|
|
50044
|
-
if (!
|
|
50180
|
+
if (!fs27.existsSync(cwd)) return void 0;
|
|
50045
50181
|
const result = run(`git ${args}`, { cwd });
|
|
50046
50182
|
return result.code === 0 ? result.stdout.trim() : void 0;
|
|
50047
50183
|
}
|
|
@@ -50049,58 +50185,58 @@ function resolveMainWorkingTree(cwd) {
|
|
|
50049
50185
|
const toplevel = tryGit(cwd, "rev-parse --show-toplevel");
|
|
50050
50186
|
if (!toplevel) return void 0;
|
|
50051
50187
|
const commonDirRaw = tryGit(cwd, "rev-parse --git-common-dir");
|
|
50052
|
-
const commonDir = commonDirRaw ?
|
|
50053
|
-
if (!commonDir) return
|
|
50054
|
-
if (
|
|
50055
|
-
return
|
|
50188
|
+
const commonDir = commonDirRaw ? path26.resolve(cwd, commonDirRaw) : void 0;
|
|
50189
|
+
if (!commonDir) return path26.resolve(toplevel);
|
|
50190
|
+
if (path26.basename(commonDir) === ".git") {
|
|
50191
|
+
return path26.dirname(commonDir);
|
|
50056
50192
|
}
|
|
50057
50193
|
const porcelain = tryGit(cwd, "worktree list --porcelain");
|
|
50058
50194
|
if (porcelain) {
|
|
50059
50195
|
for (const line of porcelain.split("\n")) {
|
|
50060
50196
|
if (line.startsWith("worktree ")) {
|
|
50061
|
-
return
|
|
50197
|
+
return path26.resolve(line.slice("worktree ".length));
|
|
50062
50198
|
}
|
|
50063
50199
|
}
|
|
50064
50200
|
}
|
|
50065
|
-
return
|
|
50201
|
+
return path26.resolve(toplevel);
|
|
50066
50202
|
}
|
|
50067
50203
|
function canonicalizeControlRepoPath(repoPath) {
|
|
50068
|
-
const resolved =
|
|
50204
|
+
const resolved = path26.resolve(repoPath);
|
|
50069
50205
|
const toplevel = tryGit(resolved, "rev-parse --show-toplevel");
|
|
50070
50206
|
if (!toplevel) return resolved;
|
|
50071
50207
|
const mainRoot = resolveMainWorkingTree(resolved);
|
|
50072
50208
|
if (!mainRoot) return resolved;
|
|
50073
|
-
const top2 =
|
|
50074
|
-
const main =
|
|
50209
|
+
const top2 = path26.resolve(toplevel);
|
|
50210
|
+
const main = path26.resolve(mainRoot);
|
|
50075
50211
|
if (top2 === main) return resolved;
|
|
50076
|
-
const rel =
|
|
50212
|
+
const rel = path26.relative(top2, resolved);
|
|
50077
50213
|
if (!rel || rel === ".") return main;
|
|
50078
|
-
if (rel.startsWith(`..${
|
|
50214
|
+
if (rel.startsWith(`..${path26.sep}`) || rel === ".." || path26.isAbsolute(rel)) {
|
|
50079
50215
|
return resolved;
|
|
50080
50216
|
}
|
|
50081
|
-
return
|
|
50217
|
+
return path26.resolve(main, rel);
|
|
50082
50218
|
}
|
|
50083
50219
|
|
|
50084
50220
|
// src/core/control-registry.ts
|
|
50085
50221
|
function getRegistryPath() {
|
|
50086
50222
|
if (process.env.HAR_CONTROL_REGISTRY_PATH) {
|
|
50087
|
-
return
|
|
50223
|
+
return path27.resolve(process.env.HAR_CONTROL_REGISTRY_PATH);
|
|
50088
50224
|
}
|
|
50089
|
-
return
|
|
50225
|
+
return path27.join(os5.homedir(), ".har", "repos.json");
|
|
50090
50226
|
}
|
|
50091
50227
|
function readRegistry() {
|
|
50092
50228
|
const registryPath = getRegistryPath();
|
|
50093
50229
|
try {
|
|
50094
|
-
if (!
|
|
50095
|
-
return JSON.parse(
|
|
50230
|
+
if (!fs28.existsSync(registryPath)) return { repos: [] };
|
|
50231
|
+
return JSON.parse(fs28.readFileSync(registryPath, "utf8"));
|
|
50096
50232
|
} catch {
|
|
50097
50233
|
return { repos: [] };
|
|
50098
50234
|
}
|
|
50099
50235
|
}
|
|
50100
50236
|
function writeRegistry(registry2) {
|
|
50101
50237
|
const registryPath = getRegistryPath();
|
|
50102
|
-
|
|
50103
|
-
|
|
50238
|
+
fs28.mkdirSync(path27.dirname(registryPath), { recursive: true });
|
|
50239
|
+
fs28.writeFileSync(registryPath, JSON.stringify(registry2, null, 2) + "\n");
|
|
50104
50240
|
}
|
|
50105
50241
|
function registryChanged(before, after) {
|
|
50106
50242
|
if (before.length !== after.length) return true;
|
|
@@ -50122,7 +50258,7 @@ function removeRegisteredRepo(repoPath) {
|
|
|
50122
50258
|
try {
|
|
50123
50259
|
return canonicalizeControlRepoPath(entry) !== resolved;
|
|
50124
50260
|
} catch {
|
|
50125
|
-
return
|
|
50261
|
+
return path27.resolve(entry) !== resolved;
|
|
50126
50262
|
}
|
|
50127
50263
|
});
|
|
50128
50264
|
if (next.length === registry2.repos.length) return false;
|
|
@@ -50134,9 +50270,9 @@ function listRegisteredRepos() {
|
|
|
50134
50270
|
const kept = [];
|
|
50135
50271
|
const seen = /* @__PURE__ */ new Set();
|
|
50136
50272
|
for (const repoPath of registry2.repos) {
|
|
50137
|
-
if (!
|
|
50273
|
+
if (!fs28.existsSync(repoPath)) continue;
|
|
50138
50274
|
const canonical = canonicalizeControlRepoPath(repoPath);
|
|
50139
|
-
if (!
|
|
50275
|
+
if (!fs28.existsSync(canonical) || !readManifest(canonical)) continue;
|
|
50140
50276
|
if (seen.has(canonical)) continue;
|
|
50141
50277
|
seen.add(canonical);
|
|
50142
50278
|
kept.push(canonical);
|
|
@@ -50148,17 +50284,17 @@ function listRegisteredRepos() {
|
|
|
50148
50284
|
}
|
|
50149
50285
|
|
|
50150
50286
|
// src/core/slot-status.ts
|
|
50151
|
-
var
|
|
50152
|
-
var
|
|
50153
|
-
var
|
|
50287
|
+
var fs33 = __toESM(require("fs"));
|
|
50288
|
+
var os8 = __toESM(require("os"));
|
|
50289
|
+
var path33 = __toESM(require("path"));
|
|
50154
50290
|
var import_child_process7 = require("child_process");
|
|
50155
50291
|
|
|
50156
50292
|
// src/core/runs.ts
|
|
50157
50293
|
var crypto2 = __toESM(require("crypto"));
|
|
50158
50294
|
var import_child_process2 = require("child_process");
|
|
50159
|
-
var
|
|
50160
|
-
var
|
|
50161
|
-
var
|
|
50295
|
+
var fs29 = __toESM(require("fs"));
|
|
50296
|
+
var os6 = __toESM(require("os"));
|
|
50297
|
+
var path28 = __toESM(require("path"));
|
|
50162
50298
|
var RUNS_DIR = "runs";
|
|
50163
50299
|
function gitCommonDir(cwd) {
|
|
50164
50300
|
try {
|
|
@@ -50167,7 +50303,7 @@ function gitCommonDir(cwd) {
|
|
|
50167
50303
|
encoding: "utf8",
|
|
50168
50304
|
stdio: ["pipe", "pipe", "ignore"]
|
|
50169
50305
|
}).trim();
|
|
50170
|
-
return out ?
|
|
50306
|
+
return out ? path28.resolve(cwd, out) : void 0;
|
|
50171
50307
|
} catch {
|
|
50172
50308
|
return void 0;
|
|
50173
50309
|
}
|
|
@@ -50189,7 +50325,7 @@ function gitPrefix(cwd) {
|
|
|
50189
50325
|
}
|
|
50190
50326
|
}
|
|
50191
50327
|
function getRunsDir(harnessRoot) {
|
|
50192
|
-
return
|
|
50328
|
+
return path28.join(getHarnessDir(harnessRoot), RUNS_DIR);
|
|
50193
50329
|
}
|
|
50194
50330
|
function formatLocalDate(d2) {
|
|
50195
50331
|
const y2 = d2.getFullYear();
|
|
@@ -50209,24 +50345,24 @@ function buildRunRelativePath(stageId, agentId, startedAt, runId, runsDir) {
|
|
|
50209
50345
|
const timePart = formatLocalTime(started);
|
|
50210
50346
|
const agentPart = agentId !== void 0 ? `_agent-${agentId}` : "";
|
|
50211
50347
|
let filename = `${timePart}_${stageId}${agentPart}.json`;
|
|
50212
|
-
const fullPath =
|
|
50213
|
-
if (
|
|
50348
|
+
const fullPath = path28.join(runsDir, dateFolder, filename);
|
|
50349
|
+
if (fs29.existsSync(fullPath)) {
|
|
50214
50350
|
filename = `${timePart}_${stageId}${agentPart}-${runId.slice(0, 8)}.json`;
|
|
50215
50351
|
}
|
|
50216
|
-
return
|
|
50352
|
+
return path28.join(dateFolder, filename);
|
|
50217
50353
|
}
|
|
50218
50354
|
function resolveRunFilePath(harnessRoot, run2) {
|
|
50219
50355
|
if (run2.relativePath) {
|
|
50220
|
-
return
|
|
50356
|
+
return path28.join(getRunsDir(harnessRoot), run2.relativePath);
|
|
50221
50357
|
}
|
|
50222
|
-
return
|
|
50358
|
+
return path28.join(getRunsDir(harnessRoot), `${run2.runId}.json`);
|
|
50223
50359
|
}
|
|
50224
50360
|
function collectRunFiles(runsDir) {
|
|
50225
|
-
if (!
|
|
50361
|
+
if (!fs29.existsSync(runsDir)) return [];
|
|
50226
50362
|
const files = [];
|
|
50227
50363
|
const walk = (dir) => {
|
|
50228
|
-
for (const entry of
|
|
50229
|
-
const full =
|
|
50364
|
+
for (const entry of fs29.readdirSync(dir, { withFileTypes: true })) {
|
|
50365
|
+
const full = path28.join(dir, entry.name);
|
|
50230
50366
|
if (entry.isDirectory()) {
|
|
50231
50367
|
walk(full);
|
|
50232
50368
|
} else if (entry.name.endsWith(".json")) {
|
|
@@ -50240,30 +50376,30 @@ function collectRunFiles(runsDir) {
|
|
|
50240
50376
|
function resolveAgentWorkDir(harnessRoot, agentId) {
|
|
50241
50377
|
if (agentId === void 0) return void 0;
|
|
50242
50378
|
const entry = readSlotRegistry(harnessRoot, agentId);
|
|
50243
|
-
if (entry?.workDir &&
|
|
50379
|
+
if (entry?.workDir && fs29.existsSync(entry.workDir)) return entry.workDir;
|
|
50244
50380
|
const env3 = readHarnessEnv(harnessRoot);
|
|
50245
|
-
const projectName = env3.HARNESS_PROJECT_NAME ??
|
|
50246
|
-
const worktreeDir =
|
|
50381
|
+
const projectName = env3.HARNESS_PROJECT_NAME ?? path28.basename(harnessRoot);
|
|
50382
|
+
const worktreeDir = path28.join(os6.homedir(), "worktrees", `${projectName}-agent-${agentId}`);
|
|
50247
50383
|
const relPrefix = gitPrefix(harnessRoot);
|
|
50248
50384
|
const sessionEnvFiles = [];
|
|
50249
|
-
const worktreesRoot =
|
|
50250
|
-
if (
|
|
50385
|
+
const worktreesRoot = path28.join(os6.homedir(), "worktrees");
|
|
50386
|
+
if (fs29.existsSync(worktreesRoot)) {
|
|
50251
50387
|
const suffix = `-har-agent-${agentId}-`;
|
|
50252
|
-
for (const entry2 of
|
|
50388
|
+
for (const entry2 of fs29.readdirSync(worktreesRoot, { withFileTypes: true })) {
|
|
50253
50389
|
if (!entry2.isDirectory() || !entry2.name.includes(suffix)) continue;
|
|
50254
|
-
const sessionDir =
|
|
50390
|
+
const sessionDir = path28.join(worktreesRoot, entry2.name);
|
|
50255
50391
|
if (!sameGitCheckout(harnessRoot, sessionDir)) continue;
|
|
50256
|
-
sessionEnvFiles.push(
|
|
50392
|
+
sessionEnvFiles.push(path28.join(sessionDir, relPrefix, `.env.agent.${agentId}`));
|
|
50257
50393
|
}
|
|
50258
50394
|
}
|
|
50259
50395
|
const candidates = [
|
|
50260
|
-
|
|
50261
|
-
|
|
50396
|
+
path28.join(worktreeDir, `.env.agent.${agentId}`),
|
|
50397
|
+
path28.join(harnessRoot, `.env.agent.${agentId}`),
|
|
50262
50398
|
...sessionEnvFiles.sort()
|
|
50263
50399
|
];
|
|
50264
50400
|
for (const envFile of candidates) {
|
|
50265
|
-
if (!
|
|
50266
|
-
const content =
|
|
50401
|
+
if (!fs29.existsSync(envFile)) continue;
|
|
50402
|
+
const content = fs29.readFileSync(envFile, "utf8");
|
|
50267
50403
|
const match = content.match(/^REPO_ROOT=(.+)$/m);
|
|
50268
50404
|
if (match) return match[1].trim();
|
|
50269
50405
|
}
|
|
@@ -50275,11 +50411,11 @@ function createRun(ctx, meta) {
|
|
|
50275
50411
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
50276
50412
|
const runId = crypto2.randomUUID();
|
|
50277
50413
|
const relativePath = buildRunRelativePath(meta.stageId, meta.agentId, startedAt, runId, runsDir);
|
|
50278
|
-
const runFilePath =
|
|
50279
|
-
|
|
50414
|
+
const runFilePath = path28.join(runsDir, relativePath);
|
|
50415
|
+
fs29.mkdirSync(path28.dirname(runFilePath), { recursive: true });
|
|
50280
50416
|
const run2 = RunRecordSchema.parse({
|
|
50281
50417
|
runId,
|
|
50282
|
-
repoPath:
|
|
50418
|
+
repoPath: path28.resolve(ctx.repoPath),
|
|
50283
50419
|
harnessRoot,
|
|
50284
50420
|
stageId: meta.stageId,
|
|
50285
50421
|
kind: meta.kind,
|
|
@@ -50288,9 +50424,11 @@ function createRun(ctx, meta) {
|
|
|
50288
50424
|
status: "unknown",
|
|
50289
50425
|
startedAt,
|
|
50290
50426
|
relativePath,
|
|
50291
|
-
trigger: ctx.trigger ?? "cli"
|
|
50427
|
+
trigger: ctx.trigger ?? "cli",
|
|
50428
|
+
workUnitId: ctx.workUnitId,
|
|
50429
|
+
attemptId: ctx.attemptId
|
|
50292
50430
|
});
|
|
50293
|
-
|
|
50431
|
+
fs29.writeFileSync(runFilePath, JSON.stringify(run2, null, 2) + "\n");
|
|
50294
50432
|
return run2;
|
|
50295
50433
|
}
|
|
50296
50434
|
function finishRun(repoPath, runId, update) {
|
|
@@ -50309,13 +50447,13 @@ function finishRun(repoPath, runId, update) {
|
|
|
50309
50447
|
finishedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
50310
50448
|
});
|
|
50311
50449
|
const runPath = resolveRunFilePath(harnessRoot, finished);
|
|
50312
|
-
|
|
50450
|
+
fs29.writeFileSync(runPath, JSON.stringify(finished, null, 2) + "\n");
|
|
50313
50451
|
return finished;
|
|
50314
50452
|
}
|
|
50315
50453
|
function findRunRecord(harnessRoot, runId) {
|
|
50316
50454
|
const runsDir = getRunsDir(harnessRoot);
|
|
50317
50455
|
for (const filePath of collectRunFiles(runsDir)) {
|
|
50318
|
-
const parsed = RunRecordSchema.safeParse(JSON.parse(
|
|
50456
|
+
const parsed = RunRecordSchema.safeParse(JSON.parse(fs29.readFileSync(filePath, "utf8")));
|
|
50319
50457
|
if (parsed.success && parsed.data.runId === runId) {
|
|
50320
50458
|
return parsed.data;
|
|
50321
50459
|
}
|
|
@@ -50327,10 +50465,10 @@ function getRun(repoPath, runId) {
|
|
|
50327
50465
|
}
|
|
50328
50466
|
function listRuns(repoPath, filter2 = {}) {
|
|
50329
50467
|
const runsDir = getRunsDir(resolveHarnessRoot(repoPath));
|
|
50330
|
-
if (!
|
|
50468
|
+
if (!fs29.existsSync(runsDir)) return [];
|
|
50331
50469
|
const runs = [];
|
|
50332
50470
|
for (const filePath of collectRunFiles(runsDir)) {
|
|
50333
|
-
const parsed = RunRecordSchema.safeParse(JSON.parse(
|
|
50471
|
+
const parsed = RunRecordSchema.safeParse(JSON.parse(fs29.readFileSync(filePath, "utf8")));
|
|
50334
50472
|
if (!parsed.success) continue;
|
|
50335
50473
|
if (filter2.stageId && parsed.data.stageId !== filter2.stageId) continue;
|
|
50336
50474
|
runs.push(parsed.data);
|
|
@@ -50343,18 +50481,18 @@ function listRuns(repoPath, filter2 = {}) {
|
|
|
50343
50481
|
}
|
|
50344
50482
|
|
|
50345
50483
|
// src/core/slot-preflight.ts
|
|
50346
|
-
var
|
|
50484
|
+
var path32 = __toESM(require("path"));
|
|
50347
50485
|
|
|
50348
50486
|
// src/core/control-port.ts
|
|
50349
50487
|
var import_child_process4 = require("child_process");
|
|
50350
|
-
var
|
|
50351
|
-
var
|
|
50488
|
+
var fs31 = __toESM(require("fs"));
|
|
50489
|
+
var path30 = __toESM(require("path"));
|
|
50352
50490
|
init_control_config();
|
|
50353
50491
|
|
|
50354
50492
|
// src/core/slot-ports.ts
|
|
50355
50493
|
var import_child_process3 = require("child_process");
|
|
50356
|
-
var
|
|
50357
|
-
var
|
|
50494
|
+
var fs30 = __toESM(require("fs"));
|
|
50495
|
+
var path29 = __toESM(require("path"));
|
|
50358
50496
|
function portStep(env3) {
|
|
50359
50497
|
return Number(env3.HARNESS_PORT_STEP ?? 10);
|
|
50360
50498
|
}
|
|
@@ -50410,7 +50548,7 @@ function allocateAppPorts(repoPath, agentId) {
|
|
|
50410
50548
|
}
|
|
50411
50549
|
function harnessUsesPm2(repoPath) {
|
|
50412
50550
|
const harnessRoot = resolveHarnessRoot(repoPath);
|
|
50413
|
-
return
|
|
50551
|
+
return fs30.existsSync(path29.join(harnessRoot, ".har", "ecosystem.agent.template.cjs"));
|
|
50414
50552
|
}
|
|
50415
50553
|
|
|
50416
50554
|
// src/core/control-port.ts
|
|
@@ -50465,13 +50603,13 @@ function controlDefaultPortWarnings(containers, defaultFrontendPort, allocatedFr
|
|
|
50465
50603
|
return [formatControlDefaultPortWarning(control.name, defaultFrontendPort, allocatedFrontend)];
|
|
50466
50604
|
}
|
|
50467
50605
|
function inspectControlUpReadiness(repoPath) {
|
|
50468
|
-
const resolved =
|
|
50606
|
+
const resolved = path30.resolve(repoPath);
|
|
50469
50607
|
const port = parseControlHostPort();
|
|
50470
50608
|
const containers = listDockerContainers();
|
|
50471
50609
|
const control = controlContainerOnPort(containers, port);
|
|
50472
50610
|
const warnings = [];
|
|
50473
|
-
const controlHarnessDir =
|
|
50474
|
-
const harnessSlot1Active =
|
|
50611
|
+
const controlHarnessDir = path30.join(resolved, "control", ".har");
|
|
50612
|
+
const harnessSlot1Active = fs31.existsSync(controlHarnessDir) && readSlotRegistry(path30.join(resolved, "control"), 1)?.status === "active";
|
|
50475
50613
|
if (control) {
|
|
50476
50614
|
return {
|
|
50477
50615
|
warnings,
|
|
@@ -50502,9 +50640,9 @@ function inspectControlUpReadiness(repoPath) {
|
|
|
50502
50640
|
}
|
|
50503
50641
|
|
|
50504
50642
|
// src/core/slot-launch-guard-occupied.ts
|
|
50505
|
-
var
|
|
50506
|
-
var
|
|
50507
|
-
var
|
|
50643
|
+
var fs32 = __toESM(require("fs"));
|
|
50644
|
+
var os7 = __toESM(require("os"));
|
|
50645
|
+
var path31 = __toESM(require("path"));
|
|
50508
50646
|
var import_child_process5 = require("child_process");
|
|
50509
50647
|
function runGit(cwd, args) {
|
|
50510
50648
|
try {
|
|
@@ -50523,7 +50661,7 @@ function worktreeDirty(worktreePath) {
|
|
|
50523
50661
|
}
|
|
50524
50662
|
function gitCommonDir2(cwd) {
|
|
50525
50663
|
const out = runGit(cwd, "rev-parse --git-common-dir");
|
|
50526
|
-
return out ?
|
|
50664
|
+
return out ? path31.resolve(cwd, out) : void 0;
|
|
50527
50665
|
}
|
|
50528
50666
|
function sameGitCheckout2(a2, b2) {
|
|
50529
50667
|
const left2 = gitCommonDir2(a2);
|
|
@@ -50532,20 +50670,20 @@ function sameGitCheckout2(a2, b2) {
|
|
|
50532
50670
|
}
|
|
50533
50671
|
function discoverWorktree(harnessRoot, agentId, projectName) {
|
|
50534
50672
|
const session = readSlotRegistry(harnessRoot, agentId);
|
|
50535
|
-
if (session?.worktreePath &&
|
|
50673
|
+
if (session?.worktreePath && fs32.existsSync(session.worktreePath)) {
|
|
50536
50674
|
return session.worktreePath;
|
|
50537
50675
|
}
|
|
50538
|
-
const legacy =
|
|
50539
|
-
if (
|
|
50540
|
-
const worktreesRoot =
|
|
50541
|
-
if (!
|
|
50676
|
+
const legacy = path31.join(os7.homedir(), "worktrees", `${projectName}-agent-${agentId}`);
|
|
50677
|
+
if (fs32.existsSync(legacy) && sameGitCheckout2(harnessRoot, legacy)) return legacy;
|
|
50678
|
+
const worktreesRoot = path31.join(os7.homedir(), "worktrees");
|
|
50679
|
+
if (!fs32.existsSync(worktreesRoot)) return void 0;
|
|
50542
50680
|
const suffix = `-har-agent-${agentId}-`;
|
|
50543
50681
|
const relPrefix = runGit(harnessRoot, "rev-parse --show-prefix") ?? "";
|
|
50544
|
-
for (const name of
|
|
50682
|
+
for (const name of fs32.readdirSync(worktreesRoot)) {
|
|
50545
50683
|
if (!name.includes(suffix)) continue;
|
|
50546
|
-
const candidate =
|
|
50684
|
+
const candidate = path31.join(worktreesRoot, name);
|
|
50547
50685
|
if (!sameGitCheckout2(harnessRoot, candidate)) continue;
|
|
50548
|
-
if (!
|
|
50686
|
+
if (!fs32.existsSync(path31.join(candidate, relPrefix, `.env.agent.${agentId}`))) continue;
|
|
50549
50687
|
return candidate;
|
|
50550
50688
|
}
|
|
50551
50689
|
return void 0;
|
|
@@ -50553,13 +50691,13 @@ function discoverWorktree(harnessRoot, agentId, projectName) {
|
|
|
50553
50691
|
function collectOccupiedSlot(repoPath, agentId) {
|
|
50554
50692
|
const harnessRoot = resolveHarnessRoot(repoPath);
|
|
50555
50693
|
const env3 = readHarnessEnv(harnessRoot);
|
|
50556
|
-
const projectName = env3.HARNESS_PROJECT_NAME ??
|
|
50694
|
+
const projectName = env3.HARNESS_PROJECT_NAME ?? path31.basename(harnessRoot);
|
|
50557
50695
|
const session = readSlotRegistry(harnessRoot, agentId);
|
|
50558
50696
|
const worktreePath = discoverWorktree(harnessRoot, agentId, projectName);
|
|
50559
50697
|
const workDir = session?.workDir;
|
|
50560
|
-
const envInWorkDir = workDir ?
|
|
50561
|
-
const envInRoot =
|
|
50562
|
-
const envInWorktree = worktreePath ?
|
|
50698
|
+
const envInWorkDir = workDir ? fs32.existsSync(path31.join(workDir, `.env.agent.${agentId}`)) : false;
|
|
50699
|
+
const envInRoot = fs32.existsSync(path31.join(harnessRoot, `.env.agent.${agentId}`));
|
|
50700
|
+
const envInWorktree = worktreePath ? fs32.existsSync(path31.join(worktreePath, `.env.agent.${agentId}`)) : false;
|
|
50563
50701
|
const active = session !== void 0 && session.status !== "completed" || envInWorkDir || envInRoot || envInWorktree;
|
|
50564
50702
|
if (!active) return void 0;
|
|
50565
50703
|
const dirty = worktreePath ? worktreeDirty(worktreePath) : void 0;
|
|
@@ -50725,7 +50863,7 @@ function checkInfraPort(env3, varName, defaultPort, scanStart, scanEnd) {
|
|
|
50725
50863
|
function inspectSlotReadiness(repoPath, agentId, options = {}) {
|
|
50726
50864
|
const harnessRoot = resolveHarnessRoot(repoPath);
|
|
50727
50865
|
const env3 = readHarnessEnv(harnessRoot);
|
|
50728
|
-
const projectName = env3.HARNESS_PROJECT_NAME ??
|
|
50866
|
+
const projectName = env3.HARNESS_PROJECT_NAME ?? path32.basename(harnessRoot);
|
|
50729
50867
|
const usesPm2 = harnessUsesPm2(repoPath);
|
|
50730
50868
|
const blockers = [];
|
|
50731
50869
|
const remediations = [];
|
|
@@ -50927,7 +51065,7 @@ function readWorktreeBranch(worktreePath) {
|
|
|
50927
51065
|
}
|
|
50928
51066
|
function gitCommonDir3(cwd) {
|
|
50929
51067
|
const out = runGit2(cwd, "rev-parse --git-common-dir");
|
|
50930
|
-
return out ?
|
|
51068
|
+
return out ? path33.resolve(cwd, out) : void 0;
|
|
50931
51069
|
}
|
|
50932
51070
|
function sameGitCheckout3(a2, b2) {
|
|
50933
51071
|
const left2 = gitCommonDir3(a2);
|
|
@@ -50939,12 +51077,12 @@ function gitPrefix2(cwd) {
|
|
|
50939
51077
|
return out ?? "";
|
|
50940
51078
|
}
|
|
50941
51079
|
function discoverSessionWorktreePath(harnessRoot, agentId) {
|
|
50942
|
-
const worktreesRoot =
|
|
50943
|
-
if (!
|
|
51080
|
+
const worktreesRoot = path33.join(os8.homedir(), "worktrees");
|
|
51081
|
+
if (!fs33.existsSync(worktreesRoot)) return void 0;
|
|
50944
51082
|
const suffix = `-har-agent-${agentId}-`;
|
|
50945
51083
|
const relPrefix = gitPrefix2(harnessRoot);
|
|
50946
|
-
const matches =
|
|
50947
|
-
(candidate) => sameGitCheckout3(harnessRoot, candidate) &&
|
|
51084
|
+
const matches = fs33.readdirSync(worktreesRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory() && entry.name.includes(suffix)).map((entry) => path33.join(worktreesRoot, entry.name)).filter(
|
|
51085
|
+
(candidate) => sameGitCheckout3(harnessRoot, candidate) && fs33.existsSync(path33.join(candidate, relPrefix, `.env.agent.${agentId}`))
|
|
50948
51086
|
);
|
|
50949
51087
|
return matches.sort()[0];
|
|
50950
51088
|
}
|
|
@@ -51019,18 +51157,18 @@ function detectPm2Issue(projectName, agentId, session, procs) {
|
|
|
51019
51157
|
}
|
|
51020
51158
|
function collectSlotStatus(harnessRoot, agentId, runs, pm2Procs) {
|
|
51021
51159
|
const env3 = readHarnessEnv(harnessRoot);
|
|
51022
|
-
const projectName = env3.HARNESS_PROJECT_NAME ??
|
|
51160
|
+
const projectName = env3.HARNESS_PROJECT_NAME ?? path33.basename(harnessRoot);
|
|
51023
51161
|
const session = readSlotRegistry(harnessRoot, agentId);
|
|
51024
|
-
const legacyWorktreePath =
|
|
51025
|
-
|
|
51162
|
+
const legacyWorktreePath = path33.join(
|
|
51163
|
+
os8.homedir(),
|
|
51026
51164
|
"worktrees",
|
|
51027
51165
|
`${projectName}-agent-${agentId}`
|
|
51028
51166
|
);
|
|
51029
|
-
const worktreePath = session?.worktreePath &&
|
|
51167
|
+
const worktreePath = session?.worktreePath && fs33.existsSync(session.worktreePath) ? session.worktreePath : fs33.existsSync(legacyWorktreePath) ? legacyWorktreePath : discoverSessionWorktreePath(harnessRoot, agentId);
|
|
51030
51168
|
const workDir = resolveAgentWorkDir(harnessRoot, agentId);
|
|
51031
|
-
const envInWorkDir = workDir ?
|
|
51032
|
-
const envInRoot =
|
|
51033
|
-
const envInWorktree = worktreePath ?
|
|
51169
|
+
const envInWorkDir = workDir ? fs33.existsSync(path33.join(workDir, `.env.agent.${agentId}`)) : false;
|
|
51170
|
+
const envInRoot = fs33.existsSync(path33.join(harnessRoot, `.env.agent.${agentId}`));
|
|
51171
|
+
const envInWorktree = worktreePath ? fs33.existsSync(path33.join(worktreePath, `.env.agent.${agentId}`)) : false;
|
|
51034
51172
|
const active = session !== void 0 && session.status !== "completed" || envInWorkDir || envInRoot || envInWorktree;
|
|
51035
51173
|
const latest = latestRunForAgent(runs, agentId);
|
|
51036
51174
|
const verifyRun = runs.find((r2) => r2.agentId === agentId && r2.stageId === "verify");
|
|
@@ -51069,6 +51207,8 @@ function collectSlotStatus(harnessRoot, agentId, runs, pm2Procs) {
|
|
|
51069
51207
|
baseBranch: session?.baseBranch,
|
|
51070
51208
|
baseCommit: session?.baseCommit,
|
|
51071
51209
|
sessionCreatedAt: session?.createdAt,
|
|
51210
|
+
workUnitId: session?.workUnitId,
|
|
51211
|
+
attemptId: session?.attemptId,
|
|
51072
51212
|
sessionStatus: session?.status,
|
|
51073
51213
|
lastError: session?.lastError,
|
|
51074
51214
|
resumeHint,
|
|
@@ -51082,7 +51222,7 @@ function collectEnvironmentStatus(repoPath) {
|
|
|
51082
51222
|
const slotIds = getAgentSlotIds(harnessRoot);
|
|
51083
51223
|
const pm2Procs = listPm2Processes2();
|
|
51084
51224
|
return {
|
|
51085
|
-
repoPath:
|
|
51225
|
+
repoPath: path33.resolve(repoPath),
|
|
51086
51226
|
harnessRoot,
|
|
51087
51227
|
gitRemote: readGitRemote(harnessRoot),
|
|
51088
51228
|
profile: manifest?.profile,
|
|
@@ -51093,13 +51233,13 @@ function collectEnvironmentStatus(repoPath) {
|
|
|
51093
51233
|
|
|
51094
51234
|
// src/core/validations.ts
|
|
51095
51235
|
var crypto3 = __toESM(require("crypto"));
|
|
51096
|
-
var
|
|
51097
|
-
var
|
|
51236
|
+
var fs35 = __toESM(require("fs"));
|
|
51237
|
+
var path35 = __toESM(require("path"));
|
|
51098
51238
|
|
|
51099
51239
|
// src/core/change-batch.ts
|
|
51100
|
-
var
|
|
51101
|
-
var
|
|
51102
|
-
var
|
|
51240
|
+
var fs34 = __toESM(require("fs"));
|
|
51241
|
+
var os9 = __toESM(require("os"));
|
|
51242
|
+
var path34 = __toESM(require("path"));
|
|
51103
51243
|
function git(checkoutDir, args, env3) {
|
|
51104
51244
|
const result = run(`git ${args}`, { cwd: checkoutDir, env: env3 });
|
|
51105
51245
|
if (result.code !== 0) {
|
|
@@ -51115,7 +51255,7 @@ function isCheckoutRoot(checkoutDir) {
|
|
|
51115
51255
|
const toplevel = tryGit2(checkoutDir, "rev-parse --show-toplevel");
|
|
51116
51256
|
if (!toplevel) return false;
|
|
51117
51257
|
try {
|
|
51118
|
-
return
|
|
51258
|
+
return fs34.realpathSync(toplevel) === fs34.realpathSync(checkoutDir);
|
|
51119
51259
|
} catch {
|
|
51120
51260
|
return false;
|
|
51121
51261
|
}
|
|
@@ -51137,7 +51277,7 @@ function isMergeOrRebaseInProgress(checkoutDir) {
|
|
|
51137
51277
|
if (tryGit2(checkoutDir, "rev-parse -q --verify MERGE_HEAD") !== void 0) return true;
|
|
51138
51278
|
for (const dir of ["rebase-merge", "rebase-apply"]) {
|
|
51139
51279
|
const gitPath = tryGit2(checkoutDir, `rev-parse --git-path ${dir}`);
|
|
51140
|
-
if (gitPath &&
|
|
51280
|
+
if (gitPath && fs34.existsSync(path34.resolve(checkoutDir, gitPath))) return true;
|
|
51141
51281
|
}
|
|
51142
51282
|
return false;
|
|
51143
51283
|
}
|
|
@@ -51160,8 +51300,8 @@ function parseNameStatus(output) {
|
|
|
51160
51300
|
return files;
|
|
51161
51301
|
}
|
|
51162
51302
|
function computeWorktreeSnapshot(checkoutDir) {
|
|
51163
|
-
const tmpDir =
|
|
51164
|
-
const tmpIndex =
|
|
51303
|
+
const tmpDir = fs34.mkdtempSync(path34.join(os9.tmpdir(), "har-idx-"));
|
|
51304
|
+
const tmpIndex = path34.join(tmpDir, "index");
|
|
51165
51305
|
const env3 = { GIT_INDEX_FILE: tmpIndex };
|
|
51166
51306
|
try {
|
|
51167
51307
|
const headTree = getHeadTree(checkoutDir);
|
|
@@ -51184,35 +51324,35 @@ function computeWorktreeSnapshot(checkoutDir) {
|
|
|
51184
51324
|
changedFiles: parseNameStatus(diffOutput)
|
|
51185
51325
|
};
|
|
51186
51326
|
} finally {
|
|
51187
|
-
|
|
51327
|
+
fs34.rmSync(tmpDir, { recursive: true, force: true });
|
|
51188
51328
|
}
|
|
51189
51329
|
}
|
|
51190
51330
|
|
|
51191
51331
|
// src/core/validations.ts
|
|
51192
51332
|
var VALIDATIONS_DIR = "validations";
|
|
51193
51333
|
function getValidationsDir(checkoutDir) {
|
|
51194
|
-
return
|
|
51334
|
+
return path35.join(checkoutDir, ".har", VALIDATIONS_DIR);
|
|
51195
51335
|
}
|
|
51196
51336
|
function validationPath(checkoutDir, treeHash) {
|
|
51197
|
-
return
|
|
51337
|
+
return path35.join(getValidationsDir(checkoutDir), `${treeHash}.json`);
|
|
51198
51338
|
}
|
|
51199
51339
|
function writeRecord(checkoutDir, record2) {
|
|
51200
51340
|
const dir = getValidationsDir(checkoutDir);
|
|
51201
|
-
|
|
51202
|
-
|
|
51341
|
+
fs35.mkdirSync(dir, { recursive: true });
|
|
51342
|
+
fs35.writeFileSync(
|
|
51203
51343
|
validationPath(checkoutDir, record2.treeHash),
|
|
51204
51344
|
`${JSON.stringify(record2, null, 2)}
|
|
51205
51345
|
`
|
|
51206
51346
|
);
|
|
51207
51347
|
}
|
|
51208
51348
|
function ensureValidationsIgnored(checkoutDir) {
|
|
51209
|
-
const harDir =
|
|
51210
|
-
if (!
|
|
51211
|
-
const gitignorePath =
|
|
51212
|
-
const content =
|
|
51349
|
+
const harDir = path35.join(checkoutDir, ".har");
|
|
51350
|
+
if (!fs35.existsSync(harDir)) return;
|
|
51351
|
+
const gitignorePath = path35.join(harDir, ".gitignore");
|
|
51352
|
+
const content = fs35.existsSync(gitignorePath) ? fs35.readFileSync(gitignorePath, "utf8") : "";
|
|
51213
51353
|
if (content.split("\n").some((line) => line.trim() === `${VALIDATIONS_DIR}/`)) return;
|
|
51214
51354
|
const suffix = content.length === 0 || content.endsWith("\n") ? "" : "\n";
|
|
51215
|
-
|
|
51355
|
+
fs35.writeFileSync(gitignorePath, `${content}${suffix}${VALIDATIONS_DIR}/
|
|
51216
51356
|
`);
|
|
51217
51357
|
}
|
|
51218
51358
|
function recordValidation(input) {
|
|
@@ -51229,8 +51369,8 @@ function recordValidation(input) {
|
|
|
51229
51369
|
treeHash: snapshot.treeHash,
|
|
51230
51370
|
headSha: snapshot.headSha,
|
|
51231
51371
|
branch: snapshot.branch,
|
|
51232
|
-
workDir:
|
|
51233
|
-
harnessRoot:
|
|
51372
|
+
workDir: path35.resolve(input.checkoutDir),
|
|
51373
|
+
harnessRoot: path35.resolve(input.harnessRoot),
|
|
51234
51374
|
agentId: input.agentId,
|
|
51235
51375
|
status: input.status,
|
|
51236
51376
|
full: input.full,
|
|
@@ -51242,16 +51382,16 @@ function recordValidation(input) {
|
|
|
51242
51382
|
committedAt: existing?.committedAt
|
|
51243
51383
|
});
|
|
51244
51384
|
writeRecord(input.checkoutDir, record2);
|
|
51245
|
-
if (
|
|
51385
|
+
if (path35.resolve(input.harnessRoot) !== path35.resolve(input.checkoutDir)) {
|
|
51246
51386
|
writeRecord(input.harnessRoot, record2);
|
|
51247
51387
|
}
|
|
51248
51388
|
return record2;
|
|
51249
51389
|
}
|
|
51250
51390
|
function findValidation(checkoutDir, treeHash) {
|
|
51251
51391
|
const file = validationPath(checkoutDir, treeHash);
|
|
51252
|
-
if (!
|
|
51392
|
+
if (!fs35.existsSync(file)) return void 0;
|
|
51253
51393
|
try {
|
|
51254
|
-
return ValidationRecordSchema.parse(JSON.parse(
|
|
51394
|
+
return ValidationRecordSchema.parse(JSON.parse(fs35.readFileSync(file, "utf8")));
|
|
51255
51395
|
} catch {
|
|
51256
51396
|
return void 0;
|
|
51257
51397
|
}
|
|
@@ -51266,25 +51406,192 @@ function attachCommit(checkoutDir, treeHash, commitSha) {
|
|
|
51266
51406
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
51267
51407
|
};
|
|
51268
51408
|
writeRecord(checkoutDir, updated);
|
|
51269
|
-
if (record2.harnessRoot &&
|
|
51409
|
+
if (record2.harnessRoot && path35.resolve(record2.harnessRoot) !== path35.resolve(checkoutDir) && fs35.existsSync(path35.join(record2.harnessRoot, ".har"))) {
|
|
51270
51410
|
writeRecord(record2.harnessRoot, updated);
|
|
51271
51411
|
}
|
|
51272
51412
|
return updated;
|
|
51273
51413
|
}
|
|
51274
51414
|
function listValidations(harnessRoot) {
|
|
51275
51415
|
const dir = getValidationsDir(harnessRoot);
|
|
51276
|
-
if (!
|
|
51416
|
+
if (!fs35.existsSync(dir)) return [];
|
|
51277
51417
|
const records = [];
|
|
51278
|
-
for (const entry of
|
|
51418
|
+
for (const entry of fs35.readdirSync(dir)) {
|
|
51279
51419
|
if (!entry.endsWith(".json")) continue;
|
|
51280
51420
|
try {
|
|
51281
|
-
records.push(ValidationRecordSchema.parse(JSON.parse(
|
|
51421
|
+
records.push(ValidationRecordSchema.parse(JSON.parse(fs35.readFileSync(path35.join(dir, entry), "utf8"))));
|
|
51282
51422
|
} catch {
|
|
51283
51423
|
}
|
|
51284
51424
|
}
|
|
51285
51425
|
return records.sort((a2, b2) => b2.updatedAt.localeCompare(a2.updatedAt));
|
|
51286
51426
|
}
|
|
51287
51427
|
|
|
51428
|
+
// src/core/work-units.ts
|
|
51429
|
+
var crypto4 = __toESM(require("crypto"));
|
|
51430
|
+
var fs36 = __toESM(require("fs"));
|
|
51431
|
+
var path36 = __toESM(require("path"));
|
|
51432
|
+
var WORK_UNITS_DIR = "work-units";
|
|
51433
|
+
var WORK_ATTEMPTS_DIR = "work-attempts";
|
|
51434
|
+
var VALIDATION_BINDINGS_DIR = "validation-bindings";
|
|
51435
|
+
var EVIDENCE_DIRS = [WORK_UNITS_DIR, WORK_ATTEMPTS_DIR, VALIDATION_BINDINGS_DIR];
|
|
51436
|
+
function harEvidenceDir(harnessRoot, name) {
|
|
51437
|
+
return path36.join(harnessRoot, ".har", name);
|
|
51438
|
+
}
|
|
51439
|
+
function hashedRecordPath(harnessRoot, dir, id) {
|
|
51440
|
+
const digest = crypto4.createHash("sha256").update(id).digest("hex");
|
|
51441
|
+
return path36.join(harEvidenceDir(harnessRoot, dir), `${digest}.json`);
|
|
51442
|
+
}
|
|
51443
|
+
function writeRecord2(file, value) {
|
|
51444
|
+
fs36.mkdirSync(path36.dirname(file), { recursive: true });
|
|
51445
|
+
const temp = `${file}.${process.pid}.tmp`;
|
|
51446
|
+
fs36.writeFileSync(temp, `${JSON.stringify(value, null, 2)}
|
|
51447
|
+
`);
|
|
51448
|
+
fs36.renameSync(temp, file);
|
|
51449
|
+
}
|
|
51450
|
+
function ensureWorkEvidenceIgnored(harnessRoot) {
|
|
51451
|
+
const harDir = path36.join(harnessRoot, ".har");
|
|
51452
|
+
if (!fs36.existsSync(harDir)) return;
|
|
51453
|
+
const gitignorePath = path36.join(harDir, ".gitignore");
|
|
51454
|
+
const content = fs36.existsSync(gitignorePath) ? fs36.readFileSync(gitignorePath, "utf8") : "";
|
|
51455
|
+
const lines2 = new Set(content.split("\n").map((line) => line.trim()));
|
|
51456
|
+
const missing = EVIDENCE_DIRS.map((dir) => `${dir}/`).filter((dir) => !lines2.has(dir));
|
|
51457
|
+
if (missing.length === 0) return;
|
|
51458
|
+
const separator = content.length === 0 || content.endsWith("\n") ? "" : "\n";
|
|
51459
|
+
fs36.writeFileSync(gitignorePath, `${content}${separator}${missing.join("\n")}
|
|
51460
|
+
`);
|
|
51461
|
+
}
|
|
51462
|
+
function listRecords(harnessRoot, dir, parse4) {
|
|
51463
|
+
const recordDir = harEvidenceDir(harnessRoot, dir);
|
|
51464
|
+
if (!fs36.existsSync(recordDir)) return [];
|
|
51465
|
+
const records = [];
|
|
51466
|
+
for (const name of fs36.readdirSync(recordDir)) {
|
|
51467
|
+
if (!name.endsWith(".json")) continue;
|
|
51468
|
+
try {
|
|
51469
|
+
records.push(parse4(JSON.parse(fs36.readFileSync(path36.join(recordDir, name), "utf8"))));
|
|
51470
|
+
} catch {
|
|
51471
|
+
}
|
|
51472
|
+
}
|
|
51473
|
+
return records;
|
|
51474
|
+
}
|
|
51475
|
+
function findWorkUnit(harnessRoot, workUnitId) {
|
|
51476
|
+
const metadata = WorkUnitMetadataSchema.parse({ workUnitId });
|
|
51477
|
+
const file = hashedRecordPath(harnessRoot, WORK_UNITS_DIR, metadata.workUnitId);
|
|
51478
|
+
if (!fs36.existsSync(file)) return void 0;
|
|
51479
|
+
try {
|
|
51480
|
+
return WorkUnitRecordSchema.parse(JSON.parse(fs36.readFileSync(file, "utf8")));
|
|
51481
|
+
} catch {
|
|
51482
|
+
return void 0;
|
|
51483
|
+
}
|
|
51484
|
+
}
|
|
51485
|
+
function upsertWorkUnit(harnessRoot, input) {
|
|
51486
|
+
const metadata = WorkUnitMetadataSchema.parse(input);
|
|
51487
|
+
ensureWorkEvidenceIgnored(harnessRoot);
|
|
51488
|
+
const existing = findWorkUnit(harnessRoot, metadata.workUnitId);
|
|
51489
|
+
if (existing) {
|
|
51490
|
+
if (existing.outcome) {
|
|
51491
|
+
throw new Error(
|
|
51492
|
+
`Work unit ${metadata.workUnitId} is already ${existing.outcome.decision}; reopening is not supported`
|
|
51493
|
+
);
|
|
51494
|
+
}
|
|
51495
|
+
for (const field of ["source", "sourceUrl", "title", "parentWorkUnitId"]) {
|
|
51496
|
+
if (metadata[field] !== void 0 && existing[field] !== void 0 && metadata[field] !== existing[field]) {
|
|
51497
|
+
throw new Error(
|
|
51498
|
+
`Work unit ${metadata.workUnitId} has immutable ${field}=${existing[field]}`
|
|
51499
|
+
);
|
|
51500
|
+
}
|
|
51501
|
+
}
|
|
51502
|
+
}
|
|
51503
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
51504
|
+
const record2 = WorkUnitRecordSchema.parse({
|
|
51505
|
+
...existing,
|
|
51506
|
+
workUnitId: metadata.workUnitId,
|
|
51507
|
+
source: existing?.source ?? metadata.source,
|
|
51508
|
+
sourceUrl: existing?.sourceUrl ?? metadata.sourceUrl,
|
|
51509
|
+
title: existing?.title ?? metadata.title,
|
|
51510
|
+
parentWorkUnitId: existing?.parentWorkUnitId ?? metadata.parentWorkUnitId,
|
|
51511
|
+
version: 1,
|
|
51512
|
+
createdAt: existing?.createdAt ?? now,
|
|
51513
|
+
updatedAt: now,
|
|
51514
|
+
outcome: existing?.outcome
|
|
51515
|
+
});
|
|
51516
|
+
writeRecord2(
|
|
51517
|
+
hashedRecordPath(harnessRoot, WORK_UNITS_DIR, metadata.workUnitId),
|
|
51518
|
+
record2
|
|
51519
|
+
);
|
|
51520
|
+
return record2;
|
|
51521
|
+
}
|
|
51522
|
+
function listWorkUnits(harnessRoot) {
|
|
51523
|
+
return listRecords(
|
|
51524
|
+
harnessRoot,
|
|
51525
|
+
WORK_UNITS_DIR,
|
|
51526
|
+
(value) => WorkUnitRecordSchema.parse(value)
|
|
51527
|
+
).sort((a2, b2) => b2.updatedAt.localeCompare(a2.updatedAt));
|
|
51528
|
+
}
|
|
51529
|
+
function createWorkAttempt(harnessRoot, input) {
|
|
51530
|
+
const attempt = WorkAttemptRecordSchema.parse({
|
|
51531
|
+
...input,
|
|
51532
|
+
version: 1,
|
|
51533
|
+
createdAt: input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
51534
|
+
});
|
|
51535
|
+
ensureWorkEvidenceIgnored(harnessRoot);
|
|
51536
|
+
writeRecord2(
|
|
51537
|
+
hashedRecordPath(harnessRoot, WORK_ATTEMPTS_DIR, attempt.attemptId),
|
|
51538
|
+
attempt
|
|
51539
|
+
);
|
|
51540
|
+
return attempt;
|
|
51541
|
+
}
|
|
51542
|
+
function listWorkAttempts(harnessRoot) {
|
|
51543
|
+
return listRecords(
|
|
51544
|
+
harnessRoot,
|
|
51545
|
+
WORK_ATTEMPTS_DIR,
|
|
51546
|
+
(value) => WorkAttemptRecordSchema.parse(value)
|
|
51547
|
+
).sort((a2, b2) => b2.createdAt.localeCompare(a2.createdAt));
|
|
51548
|
+
}
|
|
51549
|
+
function bindValidationToAttempt(harnessRoot, input) {
|
|
51550
|
+
const stableKey = `${input.attemptId}:${input.validation.validationId}`;
|
|
51551
|
+
ensureWorkEvidenceIgnored(harnessRoot);
|
|
51552
|
+
const existingFile = hashedRecordPath(
|
|
51553
|
+
harnessRoot,
|
|
51554
|
+
VALIDATION_BINDINGS_DIR,
|
|
51555
|
+
stableKey
|
|
51556
|
+
);
|
|
51557
|
+
if (fs36.existsSync(existingFile)) {
|
|
51558
|
+
try {
|
|
51559
|
+
return ValidationBindingRecordSchema.parse(
|
|
51560
|
+
JSON.parse(fs36.readFileSync(existingFile, "utf8"))
|
|
51561
|
+
);
|
|
51562
|
+
} catch {
|
|
51563
|
+
}
|
|
51564
|
+
}
|
|
51565
|
+
const binding = ValidationBindingRecordSchema.parse({
|
|
51566
|
+
bindingId: crypto4.randomUUID(),
|
|
51567
|
+
workUnitId: input.workUnitId,
|
|
51568
|
+
attemptId: input.attemptId,
|
|
51569
|
+
validationId: input.validation.validationId,
|
|
51570
|
+
treeHash: input.validation.treeHash,
|
|
51571
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
51572
|
+
});
|
|
51573
|
+
writeRecord2(existingFile, binding);
|
|
51574
|
+
return binding;
|
|
51575
|
+
}
|
|
51576
|
+
function listValidationBindings(harnessRoot) {
|
|
51577
|
+
return listRecords(
|
|
51578
|
+
harnessRoot,
|
|
51579
|
+
VALIDATION_BINDINGS_DIR,
|
|
51580
|
+
(value) => ValidationBindingRecordSchema.parse(value)
|
|
51581
|
+
).sort((a2, b2) => b2.createdAt.localeCompare(a2.createdAt));
|
|
51582
|
+
}
|
|
51583
|
+
function decideWorkUnitOutcome(harnessRoot, workUnitId, outcome) {
|
|
51584
|
+
const existing = findWorkUnit(harnessRoot, workUnitId);
|
|
51585
|
+
if (!existing) throw new Error(`Unknown work unit: ${workUnitId}`);
|
|
51586
|
+
const record2 = WorkUnitRecordSchema.parse({
|
|
51587
|
+
...existing,
|
|
51588
|
+
outcome,
|
|
51589
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
51590
|
+
});
|
|
51591
|
+
writeRecord2(hashedRecordPath(harnessRoot, WORK_UNITS_DIR, workUnitId), record2);
|
|
51592
|
+
return record2;
|
|
51593
|
+
}
|
|
51594
|
+
|
|
51288
51595
|
// src/core/cloud-executor.ts
|
|
51289
51596
|
var RemoteExecutor = class {
|
|
51290
51597
|
constructor(apiUrl, apiKey) {
|
|
@@ -51311,14 +51618,14 @@ function createRemoteExecutor(apiUrl, apiKey) {
|
|
|
51311
51618
|
init_telemetry_config();
|
|
51312
51619
|
|
|
51313
51620
|
// src/core/usage-harvest/claude.ts
|
|
51314
|
-
var
|
|
51315
|
-
var
|
|
51316
|
-
var
|
|
51621
|
+
var fs39 = __toESM(require("fs"));
|
|
51622
|
+
var os11 = __toESM(require("os"));
|
|
51623
|
+
var path39 = __toESM(require("path"));
|
|
51317
51624
|
init_telemetry_config();
|
|
51318
51625
|
|
|
51319
51626
|
// src/core/telemetry-env.ts
|
|
51320
|
-
var
|
|
51321
|
-
var
|
|
51627
|
+
var fs38 = __toESM(require("fs"));
|
|
51628
|
+
var path38 = __toESM(require("path"));
|
|
51322
51629
|
init_control_config();
|
|
51323
51630
|
function escapeAttrValue(value) {
|
|
51324
51631
|
return value.replace(/[,=]/g, "_");
|
|
@@ -51332,6 +51639,10 @@ function buildOtelResourceAttributes(attrs) {
|
|
|
51332
51639
|
];
|
|
51333
51640
|
if (attrs.branch) parts.push(`har.branch=${escapeAttrValue(attrs.branch)}`);
|
|
51334
51641
|
if (attrs.suffix) parts.push(`har.suffix=${escapeAttrValue(attrs.suffix)}`);
|
|
51642
|
+
if (attrs.workUnitId) {
|
|
51643
|
+
parts.push(`har.work_unit_id=${escapeAttrValue(attrs.workUnitId)}`);
|
|
51644
|
+
}
|
|
51645
|
+
if (attrs.attemptId) parts.push(`har.attempt_id=${attrs.attemptId}`);
|
|
51335
51646
|
return parts.join(",");
|
|
51336
51647
|
}
|
|
51337
51648
|
function buildSessionKey(input) {
|
|
@@ -51345,6 +51656,8 @@ function buildTelemetryEnvBlock(attrs) {
|
|
|
51345
51656
|
"",
|
|
51346
51657
|
"# HAR session attribution (generated)",
|
|
51347
51658
|
`HAR_SESSION_KEY=${attrs.sessionKey}`,
|
|
51659
|
+
...attrs.workUnitId ? [`HAR_WORK_UNIT_ID=${attrs.workUnitId}`] : [],
|
|
51660
|
+
...attrs.attemptId ? [`HAR_ATTEMPT_ID=${attrs.attemptId}`] : [],
|
|
51348
51661
|
`HAR_CONTROL_API_URL=${apiUrl}`,
|
|
51349
51662
|
`OTEL_RESOURCE_ATTRIBUTES=${buildOtelResourceAttributes(attrs)}`,
|
|
51350
51663
|
"# Agent telemetry: opentelemetry-hooks \u2192 Mission Control (har telemetry on|off)"
|
|
@@ -51358,8 +51671,8 @@ function appendTelemetryEnvToFile(envFilePath, attrs) {
|
|
|
51358
51671
|
${TELEMETRY_MARKER_END}
|
|
51359
51672
|
`;
|
|
51360
51673
|
let existing = "";
|
|
51361
|
-
if (
|
|
51362
|
-
existing =
|
|
51674
|
+
if (fs38.existsSync(envFilePath)) {
|
|
51675
|
+
existing = fs38.readFileSync(envFilePath, "utf8");
|
|
51363
51676
|
const start = existing.indexOf(TELEMETRY_MARKER_START);
|
|
51364
51677
|
if (start >= 0) {
|
|
51365
51678
|
const end = existing.indexOf(TELEMETRY_MARKER_END, start);
|
|
@@ -51370,28 +51683,28 @@ ${TELEMETRY_MARKER_END}
|
|
|
51370
51683
|
}
|
|
51371
51684
|
}
|
|
51372
51685
|
}
|
|
51373
|
-
|
|
51686
|
+
fs38.mkdirSync(path38.dirname(envFilePath), { recursive: true });
|
|
51374
51687
|
const combined = (existing.replace(/\n+$/, "\n") + block).replace(/^\n+/, "");
|
|
51375
|
-
|
|
51688
|
+
fs38.writeFileSync(envFilePath, combined.endsWith("\n") ? combined : combined + "\n");
|
|
51376
51689
|
}
|
|
51377
51690
|
|
|
51378
51691
|
// src/core/usage-harvest/claude.ts
|
|
51379
51692
|
function pathsMatch(candidate, targets) {
|
|
51380
|
-
const norm =
|
|
51693
|
+
const norm = path39.resolve(candidate);
|
|
51381
51694
|
return targets.some((t2) => {
|
|
51382
|
-
const target =
|
|
51383
|
-
return norm === target || norm.startsWith(target +
|
|
51695
|
+
const target = path39.resolve(t2);
|
|
51696
|
+
return norm === target || norm.startsWith(target + path39.sep) || target.startsWith(norm + path39.sep);
|
|
51384
51697
|
});
|
|
51385
51698
|
}
|
|
51386
51699
|
function claudeProjectsRoot() {
|
|
51387
|
-
return process.env.HAR_CLAUDE_PROJECTS_DIR ?
|
|
51700
|
+
return process.env.HAR_CLAUDE_PROJECTS_DIR ? path39.resolve(process.env.HAR_CLAUDE_PROJECTS_DIR) : path39.join(os11.homedir(), ".claude", "projects");
|
|
51388
51701
|
}
|
|
51389
51702
|
function encodeClaudeProjectDir(cwd) {
|
|
51390
51703
|
return cwd.replace(/[^a-zA-Z0-9]/g, "-");
|
|
51391
51704
|
}
|
|
51392
51705
|
function readJsonlRecords(filePath) {
|
|
51393
|
-
if (!
|
|
51394
|
-
const lines2 =
|
|
51706
|
+
if (!fs39.existsSync(filePath)) return [];
|
|
51707
|
+
const lines2 = fs39.readFileSync(filePath, "utf8").split(/\r?\n/);
|
|
51395
51708
|
const out = [];
|
|
51396
51709
|
for (const line of lines2) {
|
|
51397
51710
|
const trimmed = line.trim();
|
|
@@ -51434,16 +51747,16 @@ function findMatchingClaudeTranscripts(slot) {
|
|
|
51434
51747
|
const targets = [slot.workDir, slot.worktreePath].filter(Boolean);
|
|
51435
51748
|
if (targets.length === 0) return [];
|
|
51436
51749
|
const root = claudeProjectsRoot();
|
|
51437
|
-
if (!
|
|
51750
|
+
if (!fs39.existsSync(root)) return [];
|
|
51438
51751
|
const matches = [];
|
|
51439
|
-
for (const entry of
|
|
51752
|
+
for (const entry of fs39.readdirSync(root, { withFileTypes: true })) {
|
|
51440
51753
|
if (!entry.isDirectory()) continue;
|
|
51441
|
-
const projectDir =
|
|
51754
|
+
const projectDir = path39.join(root, entry.name);
|
|
51442
51755
|
const encodedHit = targets.some((t2) => entry.name.includes(encodeClaudeProjectDir(t2).slice(0, 40)));
|
|
51443
|
-
for (const file of
|
|
51756
|
+
for (const file of fs39.readdirSync(projectDir)) {
|
|
51444
51757
|
if (!file.endsWith(".jsonl")) continue;
|
|
51445
|
-
const filePath =
|
|
51446
|
-
const stat =
|
|
51758
|
+
const filePath = path39.join(projectDir, file);
|
|
51759
|
+
const stat = fs39.statSync(filePath);
|
|
51447
51760
|
const records = readJsonlRecords(filePath);
|
|
51448
51761
|
let cwdHit = encodedHit;
|
|
51449
51762
|
for (const record2 of records) {
|
|
@@ -51554,30 +51867,30 @@ function harvestClaudeEvents(slot) {
|
|
|
51554
51867
|
}
|
|
51555
51868
|
|
|
51556
51869
|
// src/core/usage-harvest/codex.ts
|
|
51557
|
-
var
|
|
51558
|
-
var
|
|
51559
|
-
var
|
|
51870
|
+
var fs40 = __toESM(require("fs"));
|
|
51871
|
+
var os12 = __toESM(require("os"));
|
|
51872
|
+
var path40 = __toESM(require("path"));
|
|
51560
51873
|
function pathsMatch2(candidate, targets) {
|
|
51561
|
-
const norm =
|
|
51874
|
+
const norm = path40.resolve(candidate);
|
|
51562
51875
|
return targets.some((t2) => {
|
|
51563
|
-
const target =
|
|
51564
|
-
return norm === target || norm.startsWith(target +
|
|
51876
|
+
const target = path40.resolve(t2);
|
|
51877
|
+
return norm === target || norm.startsWith(target + path40.sep) || target.startsWith(norm + path40.sep);
|
|
51565
51878
|
});
|
|
51566
51879
|
}
|
|
51567
51880
|
function codexSessionsRoot() {
|
|
51568
|
-
return process.env.HAR_CODEX_SESSIONS_DIR ?
|
|
51881
|
+
return process.env.HAR_CODEX_SESSIONS_DIR ? path40.resolve(process.env.HAR_CODEX_SESSIONS_DIR) : path40.join(os12.homedir(), ".codex", "sessions");
|
|
51569
51882
|
}
|
|
51570
51883
|
function walkJsonlFiles(dir, out = []) {
|
|
51571
|
-
if (!
|
|
51572
|
-
for (const entry of
|
|
51573
|
-
const full =
|
|
51884
|
+
if (!fs40.existsSync(dir)) return out;
|
|
51885
|
+
for (const entry of fs40.readdirSync(dir, { withFileTypes: true })) {
|
|
51886
|
+
const full = path40.join(dir, entry.name);
|
|
51574
51887
|
if (entry.isDirectory()) walkJsonlFiles(full, out);
|
|
51575
51888
|
else if (entry.isFile() && entry.name.endsWith(".jsonl")) out.push(full);
|
|
51576
51889
|
}
|
|
51577
51890
|
return out;
|
|
51578
51891
|
}
|
|
51579
51892
|
function readJsonl(filePath) {
|
|
51580
|
-
const lines2 =
|
|
51893
|
+
const lines2 = fs40.readFileSync(filePath, "utf8").split(/\r?\n/);
|
|
51581
51894
|
const out = [];
|
|
51582
51895
|
for (const line of lines2) {
|
|
51583
51896
|
const trimmed = line.trim();
|
|
@@ -51641,7 +51954,7 @@ function harvestCodexUsage(slot) {
|
|
|
51641
51954
|
const extracted = extractCodexTokens(records);
|
|
51642
51955
|
if (!extracted.cwd || !pathsMatch2(extracted.cwd, targets)) continue;
|
|
51643
51956
|
if (extracted.tokensInput + extracted.tokensOutput + extracted.tokensCacheRead === 0) continue;
|
|
51644
|
-
const mtime =
|
|
51957
|
+
const mtime = fs40.statSync(file).mtimeMs;
|
|
51645
51958
|
if (mtime >= bestMtime) {
|
|
51646
51959
|
bestMtime = mtime;
|
|
51647
51960
|
best = extracted;
|
|
@@ -51696,6 +52009,42 @@ async function postJson(url, body, dryRun) {
|
|
|
51696
52009
|
}
|
|
51697
52010
|
return await response.json();
|
|
51698
52011
|
}
|
|
52012
|
+
async function postPortalSync(target, body, dryRun) {
|
|
52013
|
+
if (dryRun) return;
|
|
52014
|
+
const response = await fetch(`${target.url}/api/sync`, {
|
|
52015
|
+
method: "POST",
|
|
52016
|
+
headers: {
|
|
52017
|
+
"Content-Type": "application/json",
|
|
52018
|
+
Authorization: `Bearer ${target.token}`
|
|
52019
|
+
},
|
|
52020
|
+
body: JSON.stringify(body)
|
|
52021
|
+
});
|
|
52022
|
+
if (!response.ok) {
|
|
52023
|
+
if (response.status === 401 || response.status === 403) {
|
|
52024
|
+
throw new Error(
|
|
52025
|
+
`har-portal rejected the ingest token (HTTP ${response.status}) \u2014 check HAR_PORTAL_TOKEN.`
|
|
52026
|
+
);
|
|
52027
|
+
}
|
|
52028
|
+
const text = await response.text().catch(() => "");
|
|
52029
|
+
throw new Error(`har-portal sync failed: HTTP ${response.status}${text ? ` \u2014 ${text}` : ""}`);
|
|
52030
|
+
}
|
|
52031
|
+
}
|
|
52032
|
+
function buildPortalSyncBody(repoPath) {
|
|
52033
|
+
const runs = listRuns(repoPath);
|
|
52034
|
+
const status = collectEnvironmentStatus(repoPath);
|
|
52035
|
+
const manifest = readManifest(repoPath);
|
|
52036
|
+
const stagesRegistry = readStageRegistry(repoPath);
|
|
52037
|
+
const validations = listValidations(resolveHarnessRoot(repoPath));
|
|
52038
|
+
return {
|
|
52039
|
+
path: repoPath,
|
|
52040
|
+
...manifest ? { manifest } : {},
|
|
52041
|
+
...stagesRegistry ? { stagesRegistry } : {},
|
|
52042
|
+
runs,
|
|
52043
|
+
slots: status.slots,
|
|
52044
|
+
generatedAt: status.generatedAt,
|
|
52045
|
+
...validations.length > 0 ? { validations } : {}
|
|
52046
|
+
};
|
|
52047
|
+
}
|
|
51699
52048
|
async function isControlApiReachable(apiUrl = getControlApiUrl()) {
|
|
51700
52049
|
try {
|
|
51701
52050
|
const response = await fetch(`${apiUrl}/api/health`, {
|
|
@@ -51711,14 +52060,15 @@ async function waitForControlApi(apiUrl = getControlApiUrl(), timeoutMs = 6e4, i
|
|
|
51711
52060
|
const deadline = Date.now() + timeoutMs;
|
|
51712
52061
|
while (Date.now() < deadline) {
|
|
51713
52062
|
if (await isControlApiReachable(apiUrl)) return true;
|
|
51714
|
-
await new Promise((
|
|
52063
|
+
await new Promise((resolve38) => setTimeout(resolve38, intervalMs));
|
|
51715
52064
|
}
|
|
51716
52065
|
return false;
|
|
51717
52066
|
}
|
|
51718
52067
|
async function syncAllKnownReposWithControl(options) {
|
|
51719
52068
|
if (!isControlEnabled()) return { synced: 0, failed: 0 };
|
|
51720
52069
|
const apiUrl = options?.apiUrl ?? getControlApiUrl();
|
|
51721
|
-
|
|
52070
|
+
const portal = getPortalTarget();
|
|
52071
|
+
if (!await isControlApiReachable(portal ? portal.url : apiUrl)) {
|
|
51722
52072
|
return { synced: 0, failed: 0 };
|
|
51723
52073
|
}
|
|
51724
52074
|
const repoPaths = new Set(listRegisteredRepos());
|
|
@@ -51787,26 +52137,40 @@ async function syncRepoWithControl(options) {
|
|
|
51787
52137
|
}
|
|
51788
52138
|
const runs = listRuns(repoPath);
|
|
51789
52139
|
const status = collectEnvironmentStatus(repoPath);
|
|
52140
|
+
const harnessRoot = resolveHarnessRoot(repoPath);
|
|
51790
52141
|
const response = await fetch(`${process.env.HAR_CLOUD_API_URL}/api/sync`, {
|
|
51791
52142
|
method: "POST",
|
|
51792
52143
|
headers: {
|
|
51793
52144
|
"Content-Type": "application/json",
|
|
51794
52145
|
Authorization: `Bearer ${process.env.HAR_CLOUD_API_KEY}`
|
|
51795
52146
|
},
|
|
51796
|
-
body: JSON.stringify({
|
|
52147
|
+
body: JSON.stringify({
|
|
52148
|
+
path: repoPath,
|
|
52149
|
+
runs,
|
|
52150
|
+
slots: status.slots,
|
|
52151
|
+
workUnits: listWorkUnits(harnessRoot),
|
|
52152
|
+
attempts: listWorkAttempts(harnessRoot),
|
|
52153
|
+
validations: listValidations(harnessRoot),
|
|
52154
|
+
validationBindings: listValidationBindings(harnessRoot)
|
|
52155
|
+
})
|
|
51797
52156
|
});
|
|
51798
52157
|
if (!response.ok) {
|
|
51799
52158
|
throw new Error(`Cloud sync failed: ${response.status}`);
|
|
51800
52159
|
}
|
|
51801
52160
|
return;
|
|
51802
52161
|
}
|
|
52162
|
+
const portal = getPortalTarget();
|
|
52163
|
+
if (portal) {
|
|
52164
|
+
await postPortalSync(portal, buildPortalSyncBody(repoPath), options.dryRun);
|
|
52165
|
+
return;
|
|
52166
|
+
}
|
|
51803
52167
|
const registerResult = await registerRepoWithControl({ ...options, repoPath });
|
|
51804
52168
|
const repoId = registerResult?.id;
|
|
51805
52169
|
if (!repoId && !options.dryRun) {
|
|
51806
52170
|
const listResponse = await fetch(`${apiUrl}/api/repos`);
|
|
51807
52171
|
if (!listResponse.ok) throw new Error("Failed to list repos from Control API");
|
|
51808
52172
|
const repos = await listResponse.json();
|
|
51809
|
-
const existing = repos.find((r2) =>
|
|
52173
|
+
const existing = repos.find((r2) => path41.resolve(r2.path) === repoPath);
|
|
51810
52174
|
if (!existing) {
|
|
51811
52175
|
return;
|
|
51812
52176
|
}
|
|
@@ -51827,6 +52191,13 @@ async function syncRepoRunsAndSlots(apiUrl, repoId, repoPath, dryRun) {
|
|
|
51827
52191
|
generatedAt: status.generatedAt
|
|
51828
52192
|
});
|
|
51829
52193
|
await postJson(`${apiUrl}/api/repos/${repoId}/slots`, slotsBody, dryRun);
|
|
52194
|
+
const workUnitsBody = SyncWorkUnitsInputSchema.parse({
|
|
52195
|
+
workUnits: listWorkUnits(resolveHarnessRoot(repoPath)),
|
|
52196
|
+
attempts: listWorkAttempts(resolveHarnessRoot(repoPath))
|
|
52197
|
+
});
|
|
52198
|
+
if (workUnitsBody.workUnits.length > 0 || workUnitsBody.attempts.length > 0) {
|
|
52199
|
+
await postJson(`${apiUrl}/api/repos/${repoId}/work-units`, workUnitsBody, dryRun);
|
|
52200
|
+
}
|
|
51830
52201
|
if (isTelemetryEnabled() && process.env.NODE_ENV !== "test") {
|
|
51831
52202
|
try {
|
|
51832
52203
|
const usage2 = status.slots.flatMap(
|
|
@@ -51840,6 +52211,8 @@ async function syncRepoRunsAndSlots(apiUrl, repoId, repoPath, dryRun) {
|
|
|
51840
52211
|
repoPath
|
|
51841
52212
|
}).map((row) => ({
|
|
51842
52213
|
...row,
|
|
52214
|
+
workUnitId: slot.workUnitId,
|
|
52215
|
+
attemptId: slot.attemptId,
|
|
51843
52216
|
sessionKey: row.sessionKey || buildSessionKey({
|
|
51844
52217
|
branch: slot.branch,
|
|
51845
52218
|
agentId: slot.agentId,
|
|
@@ -51861,7 +52234,11 @@ async function syncRepoRunsAndSlots(apiUrl, repoId, repoPath, dryRun) {
|
|
|
51861
52234
|
suffix: slot.suffix,
|
|
51862
52235
|
sessionCreatedAt: slot.sessionCreatedAt,
|
|
51863
52236
|
repoPath
|
|
51864
|
-
})
|
|
52237
|
+
}).map((event) => ({
|
|
52238
|
+
...event,
|
|
52239
|
+
workUnitId: slot.workUnitId,
|
|
52240
|
+
attemptId: slot.attemptId
|
|
52241
|
+
}))
|
|
51865
52242
|
);
|
|
51866
52243
|
if (events.length > 0) {
|
|
51867
52244
|
const eventsBody = SyncSessionEventsInputSchema.parse({ events });
|
|
@@ -51878,6 +52255,16 @@ async function syncRepoRunsAndSlots(apiUrl, repoId, repoPath, dryRun) {
|
|
|
51878
52255
|
const validationsBody = SyncValidationsInputSchema.parse({ validations });
|
|
51879
52256
|
await postJson(`${apiUrl}/api/repos/${repoId}/validations`, validationsBody, dryRun);
|
|
51880
52257
|
}
|
|
52258
|
+
const bindingsBody = SyncValidationBindingsInputSchema.parse({
|
|
52259
|
+
bindings: listValidationBindings(resolveHarnessRoot(repoPath))
|
|
52260
|
+
});
|
|
52261
|
+
if (bindingsBody.bindings.length > 0) {
|
|
52262
|
+
await postJson(
|
|
52263
|
+
`${apiUrl}/api/repos/${repoId}/validation-bindings`,
|
|
52264
|
+
bindingsBody,
|
|
52265
|
+
dryRun
|
|
52266
|
+
);
|
|
52267
|
+
}
|
|
51881
52268
|
}
|
|
51882
52269
|
var SYNC_TIMEOUT_MS = 15e3;
|
|
51883
52270
|
function withTimeout(promise, ms, label) {
|
|
@@ -51891,17 +52278,18 @@ async function syncRepoWithControlAsync(repoPath) {
|
|
|
51891
52278
|
if (process.env.HAR_CONTROL_DISABLED === "true" || process.env.NODE_ENV === "test") return;
|
|
51892
52279
|
const verbose = process.env.HAR_CONTROL_VERBOSE === "true";
|
|
51893
52280
|
try {
|
|
51894
|
-
const
|
|
51895
|
-
|
|
52281
|
+
const portal = getPortalTarget();
|
|
52282
|
+
const healthUrl = portal ? portal.url : getControlApiUrl();
|
|
52283
|
+
if (!await isControlApiReachable(healthUrl)) {
|
|
51896
52284
|
if (verbose) {
|
|
51897
|
-
process.stderr.write(`[har control] sync skipped:
|
|
52285
|
+
process.stderr.write(`[har control] sync skipped: not reachable at ${healthUrl}
|
|
51898
52286
|
`);
|
|
51899
52287
|
}
|
|
51900
52288
|
return;
|
|
51901
52289
|
}
|
|
51902
52290
|
const canonical = canonicalizeControlRepoPath(repoPath);
|
|
51903
52291
|
await withTimeout(
|
|
51904
|
-
syncRepoWithControl({ repoPath: canonical
|
|
52292
|
+
syncRepoWithControl({ repoPath: canonical }),
|
|
51905
52293
|
SYNC_TIMEOUT_MS,
|
|
51906
52294
|
"control sync"
|
|
51907
52295
|
);
|
|
@@ -51935,7 +52323,7 @@ init_control_config();
|
|
|
51935
52323
|
|
|
51936
52324
|
// src/core/control-lifecycle.ts
|
|
51937
52325
|
var import_child_process8 = require("child_process");
|
|
51938
|
-
var
|
|
52326
|
+
var path42 = __toESM(require("path"));
|
|
51939
52327
|
|
|
51940
52328
|
// src/core/control-image.ts
|
|
51941
52329
|
var DEFAULT_CONTROL_IMAGE = "theosfactory/har-control";
|
|
@@ -51959,10 +52347,10 @@ var CONTROL_DATA_VOLUME = "har_control_data";
|
|
|
51959
52347
|
var CONTROL_CONTAINER_PORT = 3847;
|
|
51960
52348
|
var CONTROL_DATA_DB_URL = "file:/data/har_control.db";
|
|
51961
52349
|
function resolveControlDir() {
|
|
51962
|
-
return
|
|
52350
|
+
return path42.resolve(__dirname, "..", "control");
|
|
51963
52351
|
}
|
|
51964
52352
|
function resolveControlBuildContext() {
|
|
51965
|
-
return
|
|
52353
|
+
return path42.resolve(resolveControlDir(), "..");
|
|
51966
52354
|
}
|
|
51967
52355
|
function buildDockerRunArgs(options) {
|
|
51968
52356
|
const name = options.containerName ?? CONTROL_CONTAINER_NAME;
|
|
@@ -52018,7 +52406,7 @@ async function startMissionControl(options) {
|
|
|
52018
52406
|
"-t",
|
|
52019
52407
|
imageRef,
|
|
52020
52408
|
"-f",
|
|
52021
|
-
|
|
52409
|
+
path42.join(resolveControlDir(), "Dockerfile"),
|
|
52022
52410
|
resolveControlBuildContext()
|
|
52023
52411
|
]);
|
|
52024
52412
|
if (buildCode !== 0) {
|
|
@@ -52162,7 +52550,7 @@ async function ensureTelemetryInfrastructure(options) {
|
|
|
52162
52550
|
|
|
52163
52551
|
// src/core/run-service.ts
|
|
52164
52552
|
init_telemetry_config();
|
|
52165
|
-
var
|
|
52553
|
+
var path44 = __toESM(require("path"));
|
|
52166
52554
|
function extractShellOutput(result) {
|
|
52167
52555
|
const stdout = result.logs?.find((log) => log.stream === "stdout")?.content ?? result.logs?.find((log) => !log.stream)?.content ?? "";
|
|
52168
52556
|
const stderr = result.logs?.find((log) => log.stream === "stderr")?.content ?? "";
|
|
@@ -52200,11 +52588,14 @@ var RunService = class {
|
|
|
52200
52588
|
this.executor = executor;
|
|
52201
52589
|
}
|
|
52202
52590
|
async runStage(options) {
|
|
52591
|
+
const activeSession = options.agentId !== void 0 && options.kind !== "launch" ? readSlotRegistry(resolveHarnessRoot(options.repoPath), options.agentId) : void 0;
|
|
52203
52592
|
const ctx = {
|
|
52204
52593
|
repoPath: options.repoPath,
|
|
52205
52594
|
capture: options.capture,
|
|
52206
52595
|
agentId: options.agentId,
|
|
52207
|
-
trigger: options.trigger
|
|
52596
|
+
trigger: options.trigger,
|
|
52597
|
+
workUnitId: options.workUnitId ?? activeSession?.workUnitId,
|
|
52598
|
+
attemptId: options.attemptId ?? activeSession?.attemptId
|
|
52208
52599
|
};
|
|
52209
52600
|
const stageLookup = options.stageId ? { id: options.stageId } : options.kind ? { kind: options.kind } : null;
|
|
52210
52601
|
if (!stageLookup) {
|
|
@@ -52306,47 +52697,96 @@ Usage from Cursor / Claude / Codex (opentelemetry-hooks) will appear under Workt
|
|
|
52306
52697
|
`;
|
|
52307
52698
|
}
|
|
52308
52699
|
}
|
|
52700
|
+
const harnessRoot = resolveHarnessRoot(options.repoPath);
|
|
52701
|
+
const resumableSession = options.resume ? readSlotRegistry(harnessRoot, options.agentId) : void 0;
|
|
52702
|
+
const workUnitId = options.workUnitId ?? resumableSession?.workUnitId;
|
|
52703
|
+
const attemptId = workUnitId ? resumableSession?.attemptId ?? crypto5.randomUUID() : void 0;
|
|
52704
|
+
if (workUnitId && attemptId) {
|
|
52705
|
+
const conflictingSession = listSlotRegistryEntries(harnessRoot).find(
|
|
52706
|
+
(entry) => entry.workUnitId === workUnitId && !(entry.agentId === options.agentId && (options.resume || options.confirmReplace))
|
|
52707
|
+
);
|
|
52708
|
+
if (conflictingSession) {
|
|
52709
|
+
return {
|
|
52710
|
+
code: 2,
|
|
52711
|
+
stdout: "",
|
|
52712
|
+
stderr: `Work unit ${workUnitId} is already bound to slot ${conflictingSession.agentId} (attempt ${conflictingSession.attemptId ?? "unknown"}).`,
|
|
52713
|
+
blocked: true
|
|
52714
|
+
};
|
|
52715
|
+
}
|
|
52716
|
+
upsertWorkUnit(harnessRoot, {
|
|
52717
|
+
workUnitId,
|
|
52718
|
+
source: options.source,
|
|
52719
|
+
sourceUrl: options.sourceUrl,
|
|
52720
|
+
title: options.title,
|
|
52721
|
+
parentWorkUnitId: options.parentWorkUnitId
|
|
52722
|
+
});
|
|
52723
|
+
createWorkAttempt(harnessRoot, {
|
|
52724
|
+
attemptId,
|
|
52725
|
+
workUnitId,
|
|
52726
|
+
agentId: options.agentId
|
|
52727
|
+
});
|
|
52728
|
+
}
|
|
52309
52729
|
const result = await this.runStage({
|
|
52310
52730
|
repoPath: options.repoPath,
|
|
52311
52731
|
kind: "launch",
|
|
52312
52732
|
agentId: options.agentId,
|
|
52733
|
+
workUnitId,
|
|
52734
|
+
attemptId,
|
|
52313
52735
|
capture: options.capture ?? false,
|
|
52314
52736
|
launchFlags: {
|
|
52315
52737
|
worktree: options.worktree,
|
|
52316
52738
|
claude: options.claude,
|
|
52317
52739
|
confirmReplace: options.confirmReplace,
|
|
52318
52740
|
force: options.force,
|
|
52319
|
-
resume: options.resume
|
|
52741
|
+
resume: options.resume,
|
|
52742
|
+
workUnitId,
|
|
52743
|
+
attemptId
|
|
52320
52744
|
},
|
|
52321
52745
|
trigger: "cli"
|
|
52322
52746
|
});
|
|
52323
52747
|
const envResult = toEnvironmentRunResult(result);
|
|
52324
52748
|
if (envResult.code === 0) {
|
|
52325
|
-
const harnessRoot = resolveHarnessRoot(options.repoPath);
|
|
52326
52749
|
const session = readSlotRegistry(harnessRoot, options.agentId);
|
|
52327
52750
|
if (session) {
|
|
52328
52751
|
envResult.workDir = session.workDir;
|
|
52329
52752
|
envResult.worktreePath = session.worktreePath;
|
|
52330
52753
|
envResult.branch = session.branch;
|
|
52331
52754
|
envResult.previewUrls = envResult.previewUrls ?? session.previewUrls;
|
|
52755
|
+
envResult.workUnitId = session.workUnitId;
|
|
52756
|
+
envResult.attemptId = session.attemptId;
|
|
52332
52757
|
const sessionKey = buildSessionKey({
|
|
52333
52758
|
branch: session.branch,
|
|
52334
52759
|
agentId: options.agentId,
|
|
52335
52760
|
suffix: session.suffix,
|
|
52336
52761
|
createdAt: session.createdAt
|
|
52337
52762
|
});
|
|
52338
|
-
const envFile =
|
|
52763
|
+
const envFile = path44.join(session.workDir, `.env.agent.${options.agentId}`);
|
|
52339
52764
|
try {
|
|
52340
52765
|
appendTelemetryEnvToFile(envFile, {
|
|
52341
52766
|
sessionKey,
|
|
52342
52767
|
agentId: options.agentId,
|
|
52343
|
-
repoPath:
|
|
52768
|
+
repoPath: path44.resolve(options.repoPath),
|
|
52344
52769
|
workDir: session.workDir,
|
|
52345
52770
|
branch: session.branch,
|
|
52346
|
-
suffix: session.suffix
|
|
52771
|
+
suffix: session.suffix,
|
|
52772
|
+
workUnitId: session.workUnitId,
|
|
52773
|
+
attemptId: session.attemptId
|
|
52347
52774
|
});
|
|
52348
52775
|
} catch {
|
|
52349
52776
|
}
|
|
52777
|
+
if (session.workUnitId && session.attemptId) {
|
|
52778
|
+
createWorkAttempt(harnessRoot, {
|
|
52779
|
+
attemptId: session.attemptId,
|
|
52780
|
+
workUnitId: session.workUnitId,
|
|
52781
|
+
agentId: options.agentId,
|
|
52782
|
+
sessionKey,
|
|
52783
|
+
workDir: session.workDir,
|
|
52784
|
+
worktreePath: session.worktreePath,
|
|
52785
|
+
branch: session.branch,
|
|
52786
|
+
baseCommit: session.baseCommit,
|
|
52787
|
+
createdAt: session.createdAt
|
|
52788
|
+
});
|
|
52789
|
+
}
|
|
52350
52790
|
}
|
|
52351
52791
|
if (telemetryBanner) {
|
|
52352
52792
|
envResult.stderr = `${telemetryBanner}${envResult.stderr ?? ""}`;
|
|
@@ -52377,7 +52817,7 @@ Usage from Cursor / Claude / Codex (opentelemetry-hooks) will appear under Workt
|
|
|
52377
52817
|
const harnessRoot = resolveHarnessRoot(options.repoPath);
|
|
52378
52818
|
const checkoutDir = resolveAgentWorkDir(harnessRoot, options.agentId) ?? harnessRoot;
|
|
52379
52819
|
const runId = typeof result.data === "object" && result.data !== null && !Array.isArray(result.data) ? result.data.runId : void 0;
|
|
52380
|
-
recordValidation({
|
|
52820
|
+
const validation2 = recordValidation({
|
|
52381
52821
|
checkoutDir,
|
|
52382
52822
|
harnessRoot,
|
|
52383
52823
|
status: verification.status,
|
|
@@ -52385,7 +52825,22 @@ Usage from Cursor / Claude / Codex (opentelemetry-hooks) will appear under Workt
|
|
|
52385
52825
|
runId,
|
|
52386
52826
|
agentId: options.agentId
|
|
52387
52827
|
});
|
|
52828
|
+
const session = readSlotRegistry(harnessRoot, options.agentId);
|
|
52829
|
+
if (session?.workUnitId && session.attemptId) {
|
|
52830
|
+
bindValidationToAttempt(harnessRoot, {
|
|
52831
|
+
workUnitId: session.workUnitId,
|
|
52832
|
+
attemptId: session.attemptId,
|
|
52833
|
+
validation: validation2
|
|
52834
|
+
});
|
|
52835
|
+
}
|
|
52388
52836
|
await syncRepoWithControlAsync(options.repoPath);
|
|
52837
|
+
return {
|
|
52838
|
+
code: shell.code,
|
|
52839
|
+
stdout: shell.stdout,
|
|
52840
|
+
stderr: shell.stderr,
|
|
52841
|
+
verification,
|
|
52842
|
+
validation: validation2
|
|
52843
|
+
};
|
|
52389
52844
|
} catch {
|
|
52390
52845
|
}
|
|
52391
52846
|
}
|
|
@@ -52423,6 +52878,7 @@ Usage from Cursor / Claude / Codex (opentelemetry-hooks) will appear under Workt
|
|
|
52423
52878
|
};
|
|
52424
52879
|
}
|
|
52425
52880
|
let verification;
|
|
52881
|
+
let validation2;
|
|
52426
52882
|
if (!options.skipVerify) {
|
|
52427
52883
|
const verify = await this.runVerification({
|
|
52428
52884
|
repoPath: options.repoPath,
|
|
@@ -52432,6 +52888,7 @@ Usage from Cursor / Claude / Codex (opentelemetry-hooks) will appear under Workt
|
|
|
52432
52888
|
trigger: options.trigger
|
|
52433
52889
|
});
|
|
52434
52890
|
verification = verify.verification;
|
|
52891
|
+
validation2 = verify.validation;
|
|
52435
52892
|
if (verify.code !== 0 || verification?.status !== "pass") {
|
|
52436
52893
|
return {
|
|
52437
52894
|
...verify,
|
|
@@ -52439,6 +52896,24 @@ Usage from Cursor / Claude / Codex (opentelemetry-hooks) will appear under Workt
|
|
|
52439
52896
|
};
|
|
52440
52897
|
}
|
|
52441
52898
|
}
|
|
52899
|
+
if (session.workUnitId && session.attemptId && !options.skipVerify && !validation2) {
|
|
52900
|
+
return {
|
|
52901
|
+
code: 1,
|
|
52902
|
+
stdout: "",
|
|
52903
|
+
stderr: "Full verification passed, but HAR could not record exact-tree validation proof. Session NOT completed.",
|
|
52904
|
+
verification
|
|
52905
|
+
};
|
|
52906
|
+
}
|
|
52907
|
+
if (session.workUnitId && session.attemptId && validation2) {
|
|
52908
|
+
decideWorkUnitOutcome(harnessRoot, session.workUnitId, {
|
|
52909
|
+
decision: "completed",
|
|
52910
|
+
decidedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
52911
|
+
attemptId: session.attemptId,
|
|
52912
|
+
validationId: validation2.validationId,
|
|
52913
|
+
treeHash: validation2.treeHash
|
|
52914
|
+
});
|
|
52915
|
+
await syncRepoWithControlAsync(options.repoPath);
|
|
52916
|
+
}
|
|
52442
52917
|
const teardown = await this.teardownEnvironment({
|
|
52443
52918
|
repoPath: options.repoPath,
|
|
52444
52919
|
agentId: options.agentId,
|
|
@@ -52522,9 +52997,9 @@ var getEnvironmentLogs = defaultRunService.getEnvironmentLogs.bind(defaultRunSer
|
|
|
52522
52997
|
var readline5 = __toESM(require("readline"));
|
|
52523
52998
|
|
|
52524
52999
|
// src/core/hooks.ts
|
|
52525
|
-
var
|
|
52526
|
-
var
|
|
52527
|
-
var
|
|
53000
|
+
var fs42 = __toESM(require("fs"));
|
|
53001
|
+
var os14 = __toESM(require("os"));
|
|
53002
|
+
var path45 = __toESM(require("path"));
|
|
52528
53003
|
var MARKER_START = "# >>> har commit gate (managed by `har hooks`) >>>";
|
|
52529
53004
|
var MARKER_END = "# <<< har commit gate <<<";
|
|
52530
53005
|
var PRE_COMMIT_BLOCK = [
|
|
@@ -52549,7 +53024,7 @@ function resolveCheckoutRoot(cwd) {
|
|
|
52549
53024
|
function resolveHooksDir(checkoutDir) {
|
|
52550
53025
|
const hooksPath = tryGit3(checkoutDir, "rev-parse --git-path hooks");
|
|
52551
53026
|
if (!hooksPath) throw new Error(`Not a git checkout: ${checkoutDir}`);
|
|
52552
|
-
return
|
|
53027
|
+
return path45.resolve(checkoutDir, hooksPath);
|
|
52553
53028
|
}
|
|
52554
53029
|
function getConfiguredHooksPath(checkoutDir) {
|
|
52555
53030
|
return tryGit3(checkoutDir, "config core.hooksPath") || void 0;
|
|
@@ -52557,9 +53032,9 @@ function getConfiguredHooksPath(checkoutDir) {
|
|
|
52557
53032
|
function defaultHarInvocation() {
|
|
52558
53033
|
const entry = process.argv[1];
|
|
52559
53034
|
if (entry && entry.endsWith(".js")) {
|
|
52560
|
-
return `"${process.execPath}" "${
|
|
53035
|
+
return `"${process.execPath}" "${path45.resolve(entry)}"`;
|
|
52561
53036
|
}
|
|
52562
|
-
if (entry) return `"${
|
|
53037
|
+
if (entry) return `"${path45.resolve(entry)}"`;
|
|
52563
53038
|
return "har";
|
|
52564
53039
|
}
|
|
52565
53040
|
function buildHookScript(harInvocation, subcommand, failOpenNotice) {
|
|
@@ -52580,40 +53055,40 @@ exit 0
|
|
|
52580
53055
|
`;
|
|
52581
53056
|
}
|
|
52582
53057
|
function upsertMarkedBlock(filePath, block) {
|
|
52583
|
-
if (!
|
|
52584
|
-
|
|
53058
|
+
if (!fs42.existsSync(filePath)) {
|
|
53059
|
+
fs42.writeFileSync(filePath, `#!/bin/sh
|
|
52585
53060
|
${block}
|
|
52586
53061
|
`, { mode: 493 });
|
|
52587
53062
|
return "created";
|
|
52588
53063
|
}
|
|
52589
|
-
const content =
|
|
53064
|
+
const content = fs42.readFileSync(filePath, "utf8");
|
|
52590
53065
|
if (content.includes(MARKER_START)) {
|
|
52591
53066
|
const pattern = new RegExp(
|
|
52592
53067
|
`${escapeRegExp(MARKER_START)}[\\s\\S]*?${escapeRegExp(MARKER_END)}`
|
|
52593
53068
|
);
|
|
52594
|
-
|
|
52595
|
-
|
|
53069
|
+
fs42.writeFileSync(filePath, content.replace(pattern, block));
|
|
53070
|
+
fs42.chmodSync(filePath, 493);
|
|
52596
53071
|
return "updated";
|
|
52597
53072
|
}
|
|
52598
53073
|
const suffix = content.endsWith("\n") ? "" : "\n";
|
|
52599
|
-
|
|
53074
|
+
fs42.writeFileSync(filePath, `${content}${suffix}
|
|
52600
53075
|
${block}
|
|
52601
53076
|
`);
|
|
52602
|
-
|
|
53077
|
+
fs42.chmodSync(filePath, 493);
|
|
52603
53078
|
return "appended";
|
|
52604
53079
|
}
|
|
52605
53080
|
function removeMarkedBlock(filePath) {
|
|
52606
|
-
if (!
|
|
52607
|
-
const content =
|
|
53081
|
+
if (!fs42.existsSync(filePath)) return false;
|
|
53082
|
+
const content = fs42.readFileSync(filePath, "utf8");
|
|
52608
53083
|
if (!content.includes(MARKER_START)) return false;
|
|
52609
53084
|
const pattern = new RegExp(
|
|
52610
53085
|
`\\n?${escapeRegExp(MARKER_START)}[\\s\\S]*?${escapeRegExp(MARKER_END)}\\n?`
|
|
52611
53086
|
);
|
|
52612
53087
|
const stripped = content.replace(pattern, "\n");
|
|
52613
53088
|
if (stripped.replace(/^#!\/bin\/sh\n?/, "").trim() === "") {
|
|
52614
|
-
|
|
53089
|
+
fs42.rmSync(filePath);
|
|
52615
53090
|
} else {
|
|
52616
|
-
|
|
53091
|
+
fs42.writeFileSync(filePath, stripped);
|
|
52617
53092
|
}
|
|
52618
53093
|
return true;
|
|
52619
53094
|
}
|
|
@@ -52635,20 +53110,20 @@ Or re-run with --force to write into that directory anyway.`
|
|
|
52635
53110
|
);
|
|
52636
53111
|
}
|
|
52637
53112
|
const hooksDir = resolveHooksDir(checkout);
|
|
52638
|
-
|
|
53113
|
+
fs42.mkdirSync(hooksDir, { recursive: true });
|
|
52639
53114
|
const invocation = options.harInvocation ?? defaultHarInvocation();
|
|
52640
|
-
|
|
52641
|
-
|
|
53115
|
+
fs42.writeFileSync(
|
|
53116
|
+
path45.join(hooksDir, "har-pre-commit"),
|
|
52642
53117
|
buildHookScript(invocation, "check", "har: binary not found; skipping commit gate (reinstall with har hooks install)"),
|
|
52643
53118
|
{ mode: 493 }
|
|
52644
53119
|
);
|
|
52645
|
-
|
|
52646
|
-
|
|
53120
|
+
fs42.writeFileSync(
|
|
53121
|
+
path45.join(hooksDir, "har-post-commit"),
|
|
52647
53122
|
buildHookScript(invocation, "record-commit", "har: binary not found; skipping commit association"),
|
|
52648
53123
|
{ mode: 493 }
|
|
52649
53124
|
);
|
|
52650
|
-
const preCommit = upsertMarkedBlock(
|
|
52651
|
-
const postCommit = upsertMarkedBlock(
|
|
53125
|
+
const preCommit = upsertMarkedBlock(path45.join(hooksDir, "pre-commit"), PRE_COMMIT_BLOCK);
|
|
53126
|
+
const postCommit = upsertMarkedBlock(path45.join(hooksDir, "post-commit"), POST_COMMIT_BLOCK);
|
|
52652
53127
|
ensureValidationsIgnored(checkout);
|
|
52653
53128
|
return { hooksDir, preCommit, postCommit };
|
|
52654
53129
|
}
|
|
@@ -52657,12 +53132,12 @@ function uninstallHooks(repoPath) {
|
|
|
52657
53132
|
if (!checkout) throw new Error(`Not a git repository: ${repoPath}`);
|
|
52658
53133
|
const hooksDir = resolveHooksDir(checkout);
|
|
52659
53134
|
let removed = false;
|
|
52660
|
-
removed = removeMarkedBlock(
|
|
52661
|
-
removed = removeMarkedBlock(
|
|
53135
|
+
removed = removeMarkedBlock(path45.join(hooksDir, "pre-commit")) || removed;
|
|
53136
|
+
removed = removeMarkedBlock(path45.join(hooksDir, "post-commit")) || removed;
|
|
52662
53137
|
for (const file of ["har-pre-commit", "har-post-commit"]) {
|
|
52663
|
-
const full =
|
|
52664
|
-
if (
|
|
52665
|
-
|
|
53138
|
+
const full = path45.join(hooksDir, file);
|
|
53139
|
+
if (fs42.existsSync(full)) {
|
|
53140
|
+
fs42.rmSync(full);
|
|
52666
53141
|
removed = true;
|
|
52667
53142
|
}
|
|
52668
53143
|
}
|
|
@@ -52681,10 +53156,10 @@ function isAgentWorktree(checkoutDir) {
|
|
|
52681
53156
|
if (branch && (/^har-agent-\d+$/.test(branch) || /-har-agent-\d+-[a-z0-9]+$/.test(branch))) {
|
|
52682
53157
|
return true;
|
|
52683
53158
|
}
|
|
52684
|
-
const worktreesRoot =
|
|
52685
|
-
const resolved =
|
|
52686
|
-
const name =
|
|
52687
|
-
return resolved.startsWith(`${worktreesRoot}${
|
|
53159
|
+
const worktreesRoot = path45.join(os14.homedir(), "worktrees");
|
|
53160
|
+
const resolved = path45.resolve(checkoutDir);
|
|
53161
|
+
const name = path45.basename(resolved);
|
|
53162
|
+
return resolved.startsWith(`${worktreesRoot}${path45.sep}`) && (/-agent-\d+$/.test(name) || /-har-agent-\d+-[a-z0-9]+$/.test(name));
|
|
52688
53163
|
}
|
|
52689
53164
|
function resolveEffectiveMode(checkoutDir, gate) {
|
|
52690
53165
|
if (!gate.enabled) return "off";
|
|
@@ -52697,15 +53172,15 @@ function getHooksStatus(repoPath) {
|
|
|
52697
53172
|
const hooksDir = resolveHooksDir(checkout);
|
|
52698
53173
|
const gate = getCommitGateConfig(checkout);
|
|
52699
53174
|
const hasBlock = (name) => {
|
|
52700
|
-
const file =
|
|
52701
|
-
return
|
|
53175
|
+
const file = path45.join(hooksDir, name);
|
|
53176
|
+
return fs42.existsSync(file) && fs42.readFileSync(file, "utf8").includes(MARKER_START);
|
|
52702
53177
|
};
|
|
52703
53178
|
return {
|
|
52704
53179
|
checkout,
|
|
52705
53180
|
hooksDir,
|
|
52706
53181
|
configuredHooksPath: getConfiguredHooksPath(checkout),
|
|
52707
|
-
preCommitInstalled: hasBlock("pre-commit") &&
|
|
52708
|
-
postCommitInstalled: hasBlock("post-commit") &&
|
|
53182
|
+
preCommitInstalled: hasBlock("pre-commit") && fs42.existsSync(path45.join(hooksDir, "har-pre-commit")),
|
|
53183
|
+
postCommitInstalled: hasBlock("post-commit") && fs42.existsSync(path45.join(hooksDir, "har-post-commit")),
|
|
52709
53184
|
gate,
|
|
52710
53185
|
effectiveMode: resolveEffectiveMode(checkout, gate)
|
|
52711
53186
|
};
|
|
@@ -52716,7 +53191,7 @@ function checkCommitGate(cwd) {
|
|
|
52716
53191
|
}
|
|
52717
53192
|
const checkout = resolveCheckoutRoot(cwd);
|
|
52718
53193
|
if (!checkout) return { exitCode: 0, messages: [] };
|
|
52719
|
-
if (!
|
|
53194
|
+
if (!fs42.existsSync(path45.join(checkout, ".har", "stages.json"))) {
|
|
52720
53195
|
return { exitCode: 0, messages: [] };
|
|
52721
53196
|
}
|
|
52722
53197
|
const gate = getCommitGateConfig(checkout);
|
|
@@ -52789,12 +53264,12 @@ async function recordCommitAssociation(cwd) {
|
|
|
52789
53264
|
// src/core/commit-gate-onboarding.ts
|
|
52790
53265
|
function askYesNo4(question) {
|
|
52791
53266
|
const rl = readline5.createInterface({ input: process.stdin, output: process.stderr });
|
|
52792
|
-
return new Promise((
|
|
53267
|
+
return new Promise((resolve38) => {
|
|
52793
53268
|
process.stderr.write(`${question} `);
|
|
52794
53269
|
rl.once("line", (answer) => {
|
|
52795
53270
|
rl.close();
|
|
52796
53271
|
const trimmed = answer.trim();
|
|
52797
|
-
|
|
53272
|
+
resolve38(trimmed === "" || /^y(es)?$/i.test(trimmed));
|
|
52798
53273
|
});
|
|
52799
53274
|
});
|
|
52800
53275
|
}
|
|
@@ -52836,20 +53311,20 @@ async function handleCommitGateOnboarding(options) {
|
|
|
52836
53311
|
}
|
|
52837
53312
|
|
|
52838
53313
|
// src/core/onboarding-preferences.ts
|
|
52839
|
-
var
|
|
52840
|
-
var
|
|
52841
|
-
var
|
|
53314
|
+
var fs43 = __toESM(require("fs"));
|
|
53315
|
+
var os15 = __toESM(require("os"));
|
|
53316
|
+
var path46 = __toESM(require("path"));
|
|
52842
53317
|
function getOnboardingPreferencesPath() {
|
|
52843
53318
|
if (process.env.HAR_PREFERENCES_PATH) {
|
|
52844
|
-
return
|
|
53319
|
+
return path46.resolve(process.env.HAR_PREFERENCES_PATH);
|
|
52845
53320
|
}
|
|
52846
|
-
return
|
|
53321
|
+
return path46.join(os15.homedir(), ".har", "preferences.json");
|
|
52847
53322
|
}
|
|
52848
53323
|
function readOnboardingPreferences() {
|
|
52849
53324
|
const preferencePath = getOnboardingPreferencesPath();
|
|
52850
53325
|
try {
|
|
52851
|
-
if (!
|
|
52852
|
-
return OnboardingPreferencesSchema.parse(JSON.parse(
|
|
53326
|
+
if (!fs43.existsSync(preferencePath)) return OnboardingPreferencesSchema.parse({});
|
|
53327
|
+
return OnboardingPreferencesSchema.parse(JSON.parse(fs43.readFileSync(preferencePath, "utf8")));
|
|
52853
53328
|
} catch {
|
|
52854
53329
|
return OnboardingPreferencesSchema.parse({});
|
|
52855
53330
|
}
|
|
@@ -52874,8 +53349,8 @@ function writeOnboardingPreferences(overrides) {
|
|
|
52874
53349
|
};
|
|
52875
53350
|
const parsed = OnboardingPreferencesSchema.parse(preference);
|
|
52876
53351
|
const preferencePath = getOnboardingPreferencesPath();
|
|
52877
|
-
|
|
52878
|
-
|
|
53352
|
+
fs43.mkdirSync(path46.dirname(preferencePath), { recursive: true });
|
|
53353
|
+
fs43.writeFileSync(preferencePath, `${JSON.stringify(parsed, null, 2)}
|
|
52879
53354
|
`);
|
|
52880
53355
|
return parsed;
|
|
52881
53356
|
}
|
|
@@ -53070,6 +53545,15 @@ var envCommand = {
|
|
|
53070
53545
|
type: "boolean",
|
|
53071
53546
|
default: false,
|
|
53072
53547
|
describe: LAUNCH_RESUME_DESCRIBE
|
|
53548
|
+
}).option("work-id", {
|
|
53549
|
+
type: "string",
|
|
53550
|
+
describe: "Bind this session to a durable external work identifier"
|
|
53551
|
+
}).option("work-source", {
|
|
53552
|
+
type: "string",
|
|
53553
|
+
describe: "Optional provider/source name (for example github or linear)"
|
|
53554
|
+
}).option("work-url", { type: "string", describe: "Optional source URL for the work" }).option("work-title", { type: "string", describe: "Optional human-readable title" }).option("parent-work-id", {
|
|
53555
|
+
type: "string",
|
|
53556
|
+
describe: "Optional parent work unit identifier"
|
|
53073
53557
|
}).epilog(LAUNCH_EPILOG),
|
|
53074
53558
|
handleLaunch
|
|
53075
53559
|
).command(
|
|
@@ -53146,7 +53630,7 @@ var envCommand = {
|
|
|
53146
53630
|
}
|
|
53147
53631
|
};
|
|
53148
53632
|
async function handleInit(argv) {
|
|
53149
|
-
const repoPath =
|
|
53633
|
+
const repoPath = path47.resolve(argv.repo);
|
|
53150
53634
|
const onboarding = resolveOnboardingOptions(argv);
|
|
53151
53635
|
header("har env init");
|
|
53152
53636
|
info(`Repository: ${repoPath}`);
|
|
@@ -53210,7 +53694,7 @@ async function handleInit(argv) {
|
|
|
53210
53694
|
}
|
|
53211
53695
|
}
|
|
53212
53696
|
async function handleMaintain(argv) {
|
|
53213
|
-
const repoPath =
|
|
53697
|
+
const repoPath = path47.resolve(argv.repo);
|
|
53214
53698
|
const onboarding = resolveOnboardingOptions(argv);
|
|
53215
53699
|
header("har env maintain");
|
|
53216
53700
|
info(`Repository: ${repoPath}`);
|
|
@@ -53325,7 +53809,7 @@ async function handleAgentMdProposal(repoPath, autoYes) {
|
|
|
53325
53809
|
if (autoYes) {
|
|
53326
53810
|
const proposal = readAgentMdProposal(repoPath);
|
|
53327
53811
|
if (proposal) {
|
|
53328
|
-
writeFileSafe(
|
|
53812
|
+
writeFileSafe(path47.join(repoPath, "AGENT.md"), proposal.content);
|
|
53329
53813
|
clearAgentMdProposal(repoPath);
|
|
53330
53814
|
info("Applied AGENT.md proposal (--yes)");
|
|
53331
53815
|
}
|
|
@@ -53334,7 +53818,7 @@ async function handleAgentMdProposal(repoPath, autoYes) {
|
|
|
53334
53818
|
await promptApplyAgentMdProposal(repoPath);
|
|
53335
53819
|
}
|
|
53336
53820
|
async function handleAddStage(argv) {
|
|
53337
|
-
const repoPath =
|
|
53821
|
+
const repoPath = path47.resolve(argv.repo);
|
|
53338
53822
|
const available = listStageTemplateIds();
|
|
53339
53823
|
if (argv.list) {
|
|
53340
53824
|
for (const id of available) {
|
|
@@ -53411,7 +53895,7 @@ async function handleAddStage(argv) {
|
|
|
53411
53895
|
}
|
|
53412
53896
|
}
|
|
53413
53897
|
async function handlePreflight(argv) {
|
|
53414
|
-
const repo =
|
|
53898
|
+
const repo = path47.resolve(argv.repo);
|
|
53415
53899
|
const agentId = validateAgentId(argv.id, repo);
|
|
53416
53900
|
const result = await preflightEnvironment({
|
|
53417
53901
|
repoPath: repo,
|
|
@@ -53429,7 +53913,7 @@ async function handlePreflight(argv) {
|
|
|
53429
53913
|
process.exit(result.code);
|
|
53430
53914
|
}
|
|
53431
53915
|
async function handleLaunch(argv) {
|
|
53432
|
-
const repo =
|
|
53916
|
+
const repo = path47.resolve(argv.repo);
|
|
53433
53917
|
const agentId = validateAgentId(argv.id, repo);
|
|
53434
53918
|
let confirmReplace = argv.replace;
|
|
53435
53919
|
let force = argv.force;
|
|
@@ -53441,8 +53925,8 @@ async function handleLaunch(argv) {
|
|
|
53441
53925
|
console.error(guard.reason ?? "");
|
|
53442
53926
|
const readline9 = await import("readline");
|
|
53443
53927
|
const rl = readline9.createInterface({ input: process.stdin, output: process.stderr });
|
|
53444
|
-
const answer = await new Promise((
|
|
53445
|
-
rl.question("Replace this slot? [y/N] ",
|
|
53928
|
+
const answer = await new Promise((resolve38) => {
|
|
53929
|
+
rl.question("Replace this slot? [y/N] ", resolve38);
|
|
53446
53930
|
});
|
|
53447
53931
|
rl.close();
|
|
53448
53932
|
if (!/^[Yy]$/.test(answer.trim())) {
|
|
@@ -53458,8 +53942,8 @@ async function handleLaunch(argv) {
|
|
|
53458
53942
|
warn("Worktree has uncommitted changes.");
|
|
53459
53943
|
const readline9 = await import("readline");
|
|
53460
53944
|
const rl = readline9.createInterface({ input: process.stdin, output: process.stderr });
|
|
53461
|
-
const answer = await new Promise((
|
|
53462
|
-
rl.question("Discard uncommitted changes? [y/N] ",
|
|
53945
|
+
const answer = await new Promise((resolve38) => {
|
|
53946
|
+
rl.question("Discard uncommitted changes? [y/N] ", resolve38);
|
|
53463
53947
|
});
|
|
53464
53948
|
rl.close();
|
|
53465
53949
|
if (!/^[Yy]$/.test(answer.trim())) {
|
|
@@ -53481,6 +53965,11 @@ async function handleLaunch(argv) {
|
|
|
53481
53965
|
confirmReplace,
|
|
53482
53966
|
force,
|
|
53483
53967
|
resume: argv.resume,
|
|
53968
|
+
workUnitId: argv.workId,
|
|
53969
|
+
source: argv.workSource,
|
|
53970
|
+
sourceUrl: argv.workUrl,
|
|
53971
|
+
title: argv.workTitle,
|
|
53972
|
+
parentWorkUnitId: argv.parentWorkId,
|
|
53484
53973
|
capture: false
|
|
53485
53974
|
});
|
|
53486
53975
|
if (result.blocked) {
|
|
@@ -53509,11 +53998,16 @@ async function handleRecover(argv) {
|
|
|
53509
53998
|
claude: false,
|
|
53510
53999
|
replace: false,
|
|
53511
54000
|
force: false,
|
|
53512
|
-
resume: true
|
|
54001
|
+
resume: true,
|
|
54002
|
+
workId: void 0,
|
|
54003
|
+
workSource: void 0,
|
|
54004
|
+
workUrl: void 0,
|
|
54005
|
+
workTitle: void 0,
|
|
54006
|
+
parentWorkId: void 0
|
|
53513
54007
|
});
|
|
53514
54008
|
}
|
|
53515
54009
|
async function handleVerify(argv) {
|
|
53516
|
-
const repo =
|
|
54010
|
+
const repo = path47.resolve(argv.repo);
|
|
53517
54011
|
const agentId = validateAgentId(argv.id, repo);
|
|
53518
54012
|
const result = await runVerification({
|
|
53519
54013
|
repoPath: repo,
|
|
@@ -53525,7 +54019,7 @@ async function handleVerify(argv) {
|
|
|
53525
54019
|
process.exit(result.code);
|
|
53526
54020
|
}
|
|
53527
54021
|
async function handleTeardown(argv) {
|
|
53528
|
-
const repo =
|
|
54022
|
+
const repo = path47.resolve(argv.repo);
|
|
53529
54023
|
const agentId = validateAgentId(argv.id, repo);
|
|
53530
54024
|
const result = await teardownEnvironment({
|
|
53531
54025
|
repoPath: repo,
|
|
@@ -53536,7 +54030,7 @@ async function handleTeardown(argv) {
|
|
|
53536
54030
|
process.exit(result.code);
|
|
53537
54031
|
}
|
|
53538
54032
|
async function handleComplete(argv) {
|
|
53539
|
-
const repo =
|
|
54033
|
+
const repo = path47.resolve(argv.repo);
|
|
53540
54034
|
const agentId = validateAgentId(argv.id, repo);
|
|
53541
54035
|
const result = await completeEnvironment({
|
|
53542
54036
|
repoPath: repo,
|
|
@@ -53557,7 +54051,7 @@ async function handleComplete(argv) {
|
|
|
53557
54051
|
process.exit(result.code);
|
|
53558
54052
|
}
|
|
53559
54053
|
async function handleStatus(argv) {
|
|
53560
|
-
const repoPath =
|
|
54054
|
+
const repoPath = path47.resolve(argv.repo);
|
|
53561
54055
|
if (argv.json) {
|
|
53562
54056
|
const status = collectEnvironmentStatus(repoPath);
|
|
53563
54057
|
const output = EnvironmentStatusSchema.parse(status);
|
|
@@ -53570,7 +54064,7 @@ async function handleStatus(argv) {
|
|
|
53570
54064
|
});
|
|
53571
54065
|
}
|
|
53572
54066
|
async function handleRunsList(argv) {
|
|
53573
|
-
const repoPath =
|
|
54067
|
+
const repoPath = path47.resolve(argv.repo);
|
|
53574
54068
|
const runs = listRuns(repoPath, { stageId: argv.stage, limit: argv.limit });
|
|
53575
54069
|
if (argv.json) {
|
|
53576
54070
|
process.stdout.write(JSON.stringify({ runs }, null, 2) + "\n");
|
|
@@ -53587,7 +54081,7 @@ async function handleRunsList(argv) {
|
|
|
53587
54081
|
}
|
|
53588
54082
|
}
|
|
53589
54083
|
async function handleRunsGet(argv) {
|
|
53590
|
-
const run2 = getRun(
|
|
54084
|
+
const run2 = getRun(path47.resolve(argv.repo), argv.runId);
|
|
53591
54085
|
if (!run2) {
|
|
53592
54086
|
error(`Run not found: ${argv.runId}`);
|
|
53593
54087
|
process.exit(1);
|
|
@@ -53666,20 +54160,87 @@ function printNextSteps(auto2) {
|
|
|
53666
54160
|
}
|
|
53667
54161
|
|
|
53668
54162
|
// src/cli/commands/control.ts
|
|
53669
|
-
var
|
|
54163
|
+
var path49 = __toESM(require("path"));
|
|
53670
54164
|
init_control_config();
|
|
54165
|
+
init_portal_credentials();
|
|
54166
|
+
|
|
54167
|
+
// src/core/portal-login.ts
|
|
54168
|
+
var http = __toESM(require("http"));
|
|
54169
|
+
var import_crypto = require("crypto");
|
|
54170
|
+
var import_child_process10 = require("child_process");
|
|
54171
|
+
var CALLBACK_PATH = "/callback";
|
|
54172
|
+
var LOGIN_TIMEOUT_MS = 3 * 6e4;
|
|
54173
|
+
function openBrowser(url) {
|
|
54174
|
+
const [cmd, args] = process.platform === "darwin" ? ["open", [url]] : process.platform === "win32" ? ["cmd", ["/c", "start", "", url]] : ["xdg-open", [url]];
|
|
54175
|
+
try {
|
|
54176
|
+
const child = (0, import_child_process10.spawn)(cmd, args, { stdio: "ignore", detached: true });
|
|
54177
|
+
child.on("error", () => {
|
|
54178
|
+
});
|
|
54179
|
+
child.unref();
|
|
54180
|
+
} catch {
|
|
54181
|
+
}
|
|
54182
|
+
}
|
|
54183
|
+
async function loginViaBrowser(portalUrl, openUrl = openBrowser) {
|
|
54184
|
+
const state = (0, import_crypto.randomUUID)();
|
|
54185
|
+
return new Promise((resolve38, reject) => {
|
|
54186
|
+
let timer;
|
|
54187
|
+
const server = http.createServer((req, res) => {
|
|
54188
|
+
const requestUrl = new URL(req.url ?? "", "http://127.0.0.1");
|
|
54189
|
+
if (requestUrl.pathname !== CALLBACK_PATH) {
|
|
54190
|
+
res.writeHead(404);
|
|
54191
|
+
res.end("Not found");
|
|
54192
|
+
return;
|
|
54193
|
+
}
|
|
54194
|
+
const token = requestUrl.searchParams.get("token");
|
|
54195
|
+
const returnedState = requestUrl.searchParams.get("state");
|
|
54196
|
+
const workspace = requestUrl.searchParams.get("workspace") ?? void 0;
|
|
54197
|
+
if (returnedState !== state || !token) {
|
|
54198
|
+
res.writeHead(400, { "Content-Type": "text/html" });
|
|
54199
|
+
res.end("<h1>Login failed</h1><p>You can close this tab and try again.</p>");
|
|
54200
|
+
cleanup();
|
|
54201
|
+
reject(new Error("state mismatch or missing token"));
|
|
54202
|
+
return;
|
|
54203
|
+
}
|
|
54204
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
54205
|
+
res.end("<h1>Logged in</h1><p>You can close this tab and return to the terminal.</p>");
|
|
54206
|
+
cleanup();
|
|
54207
|
+
resolve38({ portalUrl, token, workspace, createdAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
54208
|
+
});
|
|
54209
|
+
const cleanup = () => {
|
|
54210
|
+
clearTimeout(timer);
|
|
54211
|
+
server.close();
|
|
54212
|
+
};
|
|
54213
|
+
server.on("error", (err) => {
|
|
54214
|
+
cleanup();
|
|
54215
|
+
reject(err);
|
|
54216
|
+
});
|
|
54217
|
+
server.listen(0, "127.0.0.1", () => {
|
|
54218
|
+
const { port } = server.address();
|
|
54219
|
+
const callback = `http://127.0.0.1:${port}${CALLBACK_PATH}`;
|
|
54220
|
+
const loginUrl = `${portalUrl}/cli/login?callback=${encodeURIComponent(callback)}&state=${state}`;
|
|
54221
|
+
openUrl(loginUrl);
|
|
54222
|
+
process.stderr.write(`Opening ${loginUrl}
|
|
54223
|
+
If your browser did not open, paste that URL.
|
|
54224
|
+
`);
|
|
54225
|
+
timer = setTimeout(() => {
|
|
54226
|
+
cleanup();
|
|
54227
|
+
reject(new Error("timed out"));
|
|
54228
|
+
}, LOGIN_TIMEOUT_MS);
|
|
54229
|
+
});
|
|
54230
|
+
});
|
|
54231
|
+
}
|
|
53671
54232
|
|
|
53672
54233
|
// src/core/control-unregister.ts
|
|
53673
|
-
var
|
|
53674
|
-
var
|
|
54234
|
+
var fs44 = __toESM(require("fs"));
|
|
54235
|
+
var path48 = __toESM(require("path"));
|
|
53675
54236
|
init_control_config();
|
|
53676
54237
|
function listUnregisterWorktreeCandidates(repoPath) {
|
|
53677
54238
|
const harnessRoot = canonicalizeControlRepoPath(repoPath);
|
|
53678
54239
|
const byPath = /* @__PURE__ */ new Map();
|
|
53679
54240
|
const add = (partial2) => {
|
|
53680
|
-
const resolved =
|
|
54241
|
+
const resolved = path48.resolve(partial2.worktreePath);
|
|
53681
54242
|
if (!resolved || resolved === harnessRoot) return;
|
|
53682
|
-
const exists = partial2.exists ??
|
|
54243
|
+
const exists = partial2.exists ?? fs44.existsSync(resolved);
|
|
53683
54244
|
const prev = byPath.get(resolved);
|
|
53684
54245
|
if (prev) {
|
|
53685
54246
|
byPath.set(resolved, {
|
|
@@ -53730,8 +54291,8 @@ async function askYesNo5(question) {
|
|
|
53730
54291
|
if (!process.stdin.isTTY || !process.stdout.isTTY) return false;
|
|
53731
54292
|
const readline9 = await import("readline");
|
|
53732
54293
|
const rl = readline9.createInterface({ input: process.stdin, output: process.stderr });
|
|
53733
|
-
const answer = await new Promise((
|
|
53734
|
-
rl.question(question,
|
|
54294
|
+
const answer = await new Promise((resolve38) => {
|
|
54295
|
+
rl.question(question, resolve38);
|
|
53735
54296
|
});
|
|
53736
54297
|
rl.close();
|
|
53737
54298
|
return /^[Yy]$/.test(answer.trim());
|
|
@@ -53793,28 +54354,28 @@ async function teardownWorktrees(repoPath, candidates, dryRun) {
|
|
|
53793
54354
|
trigger: "cli"
|
|
53794
54355
|
});
|
|
53795
54356
|
if (result.code !== 0) {
|
|
53796
|
-
if (
|
|
53797
|
-
|
|
54357
|
+
if (fs44.existsSync(candidate.worktreePath)) {
|
|
54358
|
+
fs44.rmSync(candidate.worktreePath, { recursive: true, force: true });
|
|
53798
54359
|
}
|
|
53799
54360
|
}
|
|
53800
54361
|
outcomes.push({
|
|
53801
54362
|
path: candidate.worktreePath,
|
|
53802
54363
|
agentId: candidate.agentId,
|
|
53803
|
-
deleted: !
|
|
53804
|
-
error: result.code !== 0 &&
|
|
54364
|
+
deleted: !fs44.existsSync(candidate.worktreePath),
|
|
54365
|
+
error: result.code !== 0 && fs44.existsSync(candidate.worktreePath) ? result.stderr : void 0
|
|
53805
54366
|
});
|
|
53806
54367
|
} catch (err) {
|
|
53807
54368
|
const message = err instanceof Error ? err.message : String(err);
|
|
53808
54369
|
try {
|
|
53809
|
-
if (
|
|
53810
|
-
|
|
54370
|
+
if (fs44.existsSync(candidate.worktreePath)) {
|
|
54371
|
+
fs44.rmSync(candidate.worktreePath, { recursive: true, force: true });
|
|
53811
54372
|
}
|
|
53812
54373
|
} catch {
|
|
53813
54374
|
}
|
|
53814
54375
|
outcomes.push({
|
|
53815
54376
|
path: candidate.worktreePath,
|
|
53816
54377
|
agentId: candidate.agentId,
|
|
53817
|
-
deleted: !
|
|
54378
|
+
deleted: !fs44.existsSync(candidate.worktreePath),
|
|
53818
54379
|
error: message
|
|
53819
54380
|
});
|
|
53820
54381
|
}
|
|
@@ -53930,8 +54491,11 @@ var controlCommand = {
|
|
|
53930
54491
|
handleWatch
|
|
53931
54492
|
).command(
|
|
53932
54493
|
"login",
|
|
53933
|
-
"
|
|
53934
|
-
(y2) => y2.option("
|
|
54494
|
+
"Log in to a har-portal (browser SSO) and store an ingest token",
|
|
54495
|
+
(y2) => y2.option("portal", { type: "string", describe: "Portal base URL (or set HAR_PORTAL_URL)" }).option("api-key", {
|
|
54496
|
+
type: "string",
|
|
54497
|
+
describe: "Store this ingest token directly instead of browser login"
|
|
54498
|
+
}),
|
|
53935
54499
|
handleLogin
|
|
53936
54500
|
).demandCommand(
|
|
53937
54501
|
1,
|
|
@@ -53996,7 +54560,7 @@ async function handleDown() {
|
|
|
53996
54560
|
process.exit(code);
|
|
53997
54561
|
}
|
|
53998
54562
|
async function handleRegister(argv) {
|
|
53999
|
-
const repoPath =
|
|
54563
|
+
const repoPath = path49.resolve(argv.repo);
|
|
54000
54564
|
header("har control register");
|
|
54001
54565
|
info(`Repository: ${repoPath}`);
|
|
54002
54566
|
try {
|
|
@@ -54020,7 +54584,7 @@ async function handleRegister(argv) {
|
|
|
54020
54584
|
}
|
|
54021
54585
|
}
|
|
54022
54586
|
async function handleUnregister(argv) {
|
|
54023
|
-
const repoPath =
|
|
54587
|
+
const repoPath = path49.resolve(argv.repo);
|
|
54024
54588
|
const worktrees = listUnregisterWorktreeCandidates(repoPath);
|
|
54025
54589
|
try {
|
|
54026
54590
|
let deleteWorktrees = argv.deleteWorktrees;
|
|
@@ -54089,7 +54653,7 @@ async function handleUnregister(argv) {
|
|
|
54089
54653
|
}
|
|
54090
54654
|
}
|
|
54091
54655
|
async function handleSync(argv) {
|
|
54092
|
-
const repoPath =
|
|
54656
|
+
const repoPath = path49.resolve(argv.repo);
|
|
54093
54657
|
try {
|
|
54094
54658
|
await syncRepoWithControl({
|
|
54095
54659
|
repoPath,
|
|
@@ -54128,7 +54692,7 @@ async function handleWatch(argv) {
|
|
|
54128
54692
|
};
|
|
54129
54693
|
const tick = async () => {
|
|
54130
54694
|
if (argv.repo) {
|
|
54131
|
-
await syncOne(
|
|
54695
|
+
await syncOne(path49.resolve(argv.repo));
|
|
54132
54696
|
return;
|
|
54133
54697
|
}
|
|
54134
54698
|
try {
|
|
@@ -54149,21 +54713,40 @@ async function handleWatch(argv) {
|
|
|
54149
54713
|
}
|
|
54150
54714
|
async function handleLogin(argv) {
|
|
54151
54715
|
header("har control login");
|
|
54152
|
-
|
|
54153
|
-
|
|
54716
|
+
const portalUrl = (argv.portal ?? process.env.HAR_PORTAL_URL ?? "").replace(/\/+$/, "");
|
|
54717
|
+
if (!portalUrl) {
|
|
54718
|
+
error("Provide --portal <url> (or set HAR_PORTAL_URL)");
|
|
54719
|
+
process.exit(1);
|
|
54720
|
+
}
|
|
54721
|
+
if (argv.apiKey) {
|
|
54722
|
+
writePortalCredentials({
|
|
54723
|
+
portalUrl,
|
|
54724
|
+
token: argv.apiKey,
|
|
54725
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
54726
|
+
});
|
|
54727
|
+
success(`Saved ingest token for ${portalUrl}`);
|
|
54728
|
+
info("Sync: har control sync");
|
|
54729
|
+
return;
|
|
54730
|
+
}
|
|
54731
|
+
try {
|
|
54732
|
+
const creds = await loginViaBrowser(portalUrl);
|
|
54733
|
+
writePortalCredentials(creds);
|
|
54734
|
+
success(
|
|
54735
|
+
`Logged in to ${portalUrl}${creds.workspace ? ` (workspace: ${creds.workspace})` : ""}`
|
|
54736
|
+
);
|
|
54737
|
+
info("Sync: har control sync");
|
|
54738
|
+
} catch (err) {
|
|
54739
|
+
error(`Login failed: ${err.message}`);
|
|
54154
54740
|
process.exit(1);
|
|
54155
54741
|
}
|
|
54156
|
-
process.env.HAR_CLOUD_API_KEY = argv.apiKey;
|
|
54157
|
-
success("HAR_CLOUD_API_KEY set for this process. Export it in your shell for persistence.");
|
|
54158
|
-
info("Sync to cloud: har control sync --cloud");
|
|
54159
54742
|
}
|
|
54160
54743
|
|
|
54161
54744
|
// src/cli/commands/hooks.ts
|
|
54162
|
-
var
|
|
54745
|
+
var path51 = __toESM(require("path"));
|
|
54163
54746
|
|
|
54164
54747
|
// src/core/claude-hooks.ts
|
|
54165
|
-
var
|
|
54166
|
-
var
|
|
54748
|
+
var fs45 = __toESM(require("fs"));
|
|
54749
|
+
var path50 = __toESM(require("path"));
|
|
54167
54750
|
var CLAUDE_GUARD_RELATIVE_PATH = ".har/hooks/claude-worktree-guard.sh";
|
|
54168
54751
|
var CLAUDE_SETTINGS_RELATIVE_PATH = ".claude/settings.json";
|
|
54169
54752
|
var GUARD_MATCHER = "Edit|Write|MultiEdit|NotebookEdit";
|
|
@@ -54174,8 +54757,8 @@ function isHarGuardEntry(entry) {
|
|
|
54174
54757
|
);
|
|
54175
54758
|
}
|
|
54176
54759
|
function readSettings(settingsPath) {
|
|
54177
|
-
if (!
|
|
54178
|
-
const raw =
|
|
54760
|
+
if (!fs45.existsSync(settingsPath)) return {};
|
|
54761
|
+
const raw = fs45.readFileSync(settingsPath, "utf8").trim();
|
|
54179
54762
|
if (raw === "") return {};
|
|
54180
54763
|
const parsed = JSON.parse(raw);
|
|
54181
54764
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
@@ -54184,19 +54767,19 @@ function readSettings(settingsPath) {
|
|
|
54184
54767
|
return parsed;
|
|
54185
54768
|
}
|
|
54186
54769
|
function writeSettings(settingsPath, settings) {
|
|
54187
|
-
|
|
54188
|
-
|
|
54770
|
+
fs45.mkdirSync(path50.dirname(settingsPath), { recursive: true });
|
|
54771
|
+
fs45.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
54189
54772
|
}
|
|
54190
54773
|
function installClaudeGuard(repoPath) {
|
|
54191
54774
|
const templatePath = resolveTemplateFile("claude-worktree-guard.sh.template");
|
|
54192
54775
|
if (!templatePath) {
|
|
54193
54776
|
throw new Error("Guard template not found (claude-worktree-guard.sh.template). Run npm run build.");
|
|
54194
54777
|
}
|
|
54195
|
-
const guardScript =
|
|
54196
|
-
|
|
54197
|
-
|
|
54198
|
-
|
|
54199
|
-
const settingsPath =
|
|
54778
|
+
const guardScript = path50.join(repoPath, CLAUDE_GUARD_RELATIVE_PATH);
|
|
54779
|
+
fs45.mkdirSync(path50.dirname(guardScript), { recursive: true });
|
|
54780
|
+
fs45.copyFileSync(templatePath, guardScript);
|
|
54781
|
+
fs45.chmodSync(guardScript, 493);
|
|
54782
|
+
const settingsPath = path50.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
|
|
54200
54783
|
const settings = readSettings(settingsPath);
|
|
54201
54784
|
const hooks = settings.hooks ?? {};
|
|
54202
54785
|
const preToolUse = (hooks.PreToolUse ?? []).filter((entry) => !isHarGuardEntry(entry));
|
|
@@ -54210,15 +54793,15 @@ function installClaudeGuard(repoPath) {
|
|
|
54210
54793
|
}
|
|
54211
54794
|
function uninstallClaudeGuard(repoPath) {
|
|
54212
54795
|
let removed = false;
|
|
54213
|
-
const guardScript =
|
|
54214
|
-
if (
|
|
54215
|
-
|
|
54796
|
+
const guardScript = path50.join(repoPath, CLAUDE_GUARD_RELATIVE_PATH);
|
|
54797
|
+
if (fs45.existsSync(guardScript)) {
|
|
54798
|
+
fs45.rmSync(guardScript);
|
|
54216
54799
|
removed = true;
|
|
54217
|
-
const parent =
|
|
54218
|
-
if (
|
|
54800
|
+
const parent = path50.dirname(guardScript);
|
|
54801
|
+
if (fs45.existsSync(parent) && fs45.readdirSync(parent).length === 0) fs45.rmdirSync(parent);
|
|
54219
54802
|
}
|
|
54220
|
-
const settingsPath =
|
|
54221
|
-
if (
|
|
54803
|
+
const settingsPath = path50.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
|
|
54804
|
+
if (fs45.existsSync(settingsPath)) {
|
|
54222
54805
|
const settings = readSettings(settingsPath);
|
|
54223
54806
|
const preToolUse = settings.hooks?.PreToolUse;
|
|
54224
54807
|
if (preToolUse) {
|
|
@@ -54243,8 +54826,8 @@ function uninstallClaudeGuard(repoPath) {
|
|
|
54243
54826
|
return { removed };
|
|
54244
54827
|
}
|
|
54245
54828
|
function claudeGuardInstalled(repoPath) {
|
|
54246
|
-
const settingsPath =
|
|
54247
|
-
if (!
|
|
54829
|
+
const settingsPath = path50.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
|
|
54830
|
+
if (!fs45.existsSync(settingsPath)) return false;
|
|
54248
54831
|
try {
|
|
54249
54832
|
const settings = readSettings(settingsPath);
|
|
54250
54833
|
return (settings.hooks?.PreToolUse ?? []).some(isHarGuardEntry);
|
|
@@ -54260,7 +54843,7 @@ function repoOption(y2) {
|
|
|
54260
54843
|
function handleInstall2(argv) {
|
|
54261
54844
|
try {
|
|
54262
54845
|
if (argv.claude) {
|
|
54263
|
-
const result2 = installClaudeGuard(
|
|
54846
|
+
const result2 = installClaudeGuard(path51.resolve(argv.repo));
|
|
54264
54847
|
success("Claude Code worktree guard installed.");
|
|
54265
54848
|
info(`Guard script: ${result2.guardScript}`);
|
|
54266
54849
|
info(`Settings: ${result2.settingsPath} (PreToolUse: Edit|Write|MultiEdit|NotebookEdit)`);
|
|
@@ -54268,7 +54851,7 @@ function handleInstall2(argv) {
|
|
|
54268
54851
|
info("Commit both files so the guard travels with the repo.");
|
|
54269
54852
|
return;
|
|
54270
54853
|
}
|
|
54271
|
-
const result = installHooks({ repoPath:
|
|
54854
|
+
const result = installHooks({ repoPath: path51.resolve(argv.repo), force: argv.force });
|
|
54272
54855
|
success(`Commit gate installed in ${result.hooksDir}`);
|
|
54273
54856
|
info(`pre-commit: ${result.preCommit}, post-commit: ${result.postCommit}`);
|
|
54274
54857
|
info("Commits of unverified change batches will be blocked in agent worktrees.");
|
|
@@ -54281,7 +54864,7 @@ function handleInstall2(argv) {
|
|
|
54281
54864
|
function handleUninstall(argv) {
|
|
54282
54865
|
try {
|
|
54283
54866
|
if (argv.claude) {
|
|
54284
|
-
const result2 = uninstallClaudeGuard(
|
|
54867
|
+
const result2 = uninstallClaudeGuard(path51.resolve(argv.repo));
|
|
54285
54868
|
if (result2.removed) {
|
|
54286
54869
|
success("Claude Code worktree guard removed.");
|
|
54287
54870
|
} else {
|
|
@@ -54289,7 +54872,7 @@ function handleUninstall(argv) {
|
|
|
54289
54872
|
}
|
|
54290
54873
|
return;
|
|
54291
54874
|
}
|
|
54292
|
-
const result = uninstallHooks(
|
|
54875
|
+
const result = uninstallHooks(path51.resolve(argv.repo));
|
|
54293
54876
|
if (result.removed) {
|
|
54294
54877
|
success(`Commit gate removed from ${result.hooksDir}`);
|
|
54295
54878
|
} else {
|
|
@@ -54302,7 +54885,7 @@ function handleUninstall(argv) {
|
|
|
54302
54885
|
}
|
|
54303
54886
|
function handleStatus2(argv) {
|
|
54304
54887
|
try {
|
|
54305
|
-
const status = getHooksStatus(
|
|
54888
|
+
const status = getHooksStatus(path51.resolve(argv.repo));
|
|
54306
54889
|
if (argv.json) {
|
|
54307
54890
|
process.stdout.write(`${JSON.stringify(status, null, 2)}
|
|
54308
54891
|
`);
|
|
@@ -54320,7 +54903,7 @@ function handleStatus2(argv) {
|
|
|
54320
54903
|
);
|
|
54321
54904
|
info(`Effective: ${status.effectiveMode} (in this checkout)`);
|
|
54322
54905
|
info(
|
|
54323
|
-
`Claude guard: ${claudeGuardInstalled(
|
|
54906
|
+
`Claude guard: ${claudeGuardInstalled(path51.resolve(argv.repo)) ? `installed (${CLAUDE_GUARD_RELATIVE_PATH})` : "not installed"}`
|
|
54324
54907
|
);
|
|
54325
54908
|
} catch (err) {
|
|
54326
54909
|
error(err instanceof Error ? err.message : String(err));
|
|
@@ -54581,10 +55164,10 @@ function assignProp(target, prop, value) {
|
|
|
54581
55164
|
configurable: true
|
|
54582
55165
|
});
|
|
54583
55166
|
}
|
|
54584
|
-
function getElementAtPath(obj,
|
|
54585
|
-
if (!
|
|
55167
|
+
function getElementAtPath(obj, path54) {
|
|
55168
|
+
if (!path54)
|
|
54586
55169
|
return obj;
|
|
54587
|
-
return
|
|
55170
|
+
return path54.reduce((acc, key) => acc?.[key], obj);
|
|
54588
55171
|
}
|
|
54589
55172
|
function promiseAllObject(promisesObj) {
|
|
54590
55173
|
const keys = Object.keys(promisesObj);
|
|
@@ -54904,11 +55487,11 @@ function aborted(x2, startIndex = 0) {
|
|
|
54904
55487
|
}
|
|
54905
55488
|
return false;
|
|
54906
55489
|
}
|
|
54907
|
-
function prefixIssues(
|
|
55490
|
+
function prefixIssues(path54, issues) {
|
|
54908
55491
|
return issues.map((iss) => {
|
|
54909
55492
|
var _a3;
|
|
54910
55493
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
54911
|
-
iss.path.unshift(
|
|
55494
|
+
iss.path.unshift(path54);
|
|
54912
55495
|
return iss;
|
|
54913
55496
|
});
|
|
54914
55497
|
}
|
|
@@ -60231,7 +60814,7 @@ var Protocol = class {
|
|
|
60231
60814
|
return;
|
|
60232
60815
|
}
|
|
60233
60816
|
const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
|
|
60234
|
-
await new Promise((
|
|
60817
|
+
await new Promise((resolve38) => setTimeout(resolve38, pollInterval));
|
|
60235
60818
|
options?.signal?.throwIfAborted();
|
|
60236
60819
|
}
|
|
60237
60820
|
} catch (error3) {
|
|
@@ -60248,7 +60831,7 @@ var Protocol = class {
|
|
|
60248
60831
|
*/
|
|
60249
60832
|
request(request, resultSchema, options) {
|
|
60250
60833
|
const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
|
|
60251
|
-
return new Promise((
|
|
60834
|
+
return new Promise((resolve38, reject) => {
|
|
60252
60835
|
const earlyReject = (error3) => {
|
|
60253
60836
|
reject(error3);
|
|
60254
60837
|
};
|
|
@@ -60326,7 +60909,7 @@ var Protocol = class {
|
|
|
60326
60909
|
if (!parseResult.success) {
|
|
60327
60910
|
reject(parseResult.error);
|
|
60328
60911
|
} else {
|
|
60329
|
-
|
|
60912
|
+
resolve38(parseResult.data);
|
|
60330
60913
|
}
|
|
60331
60914
|
} catch (error3) {
|
|
60332
60915
|
reject(error3);
|
|
@@ -60587,12 +61170,12 @@ var Protocol = class {
|
|
|
60587
61170
|
}
|
|
60588
61171
|
} catch {
|
|
60589
61172
|
}
|
|
60590
|
-
return new Promise((
|
|
61173
|
+
return new Promise((resolve38, reject) => {
|
|
60591
61174
|
if (signal.aborted) {
|
|
60592
61175
|
reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
60593
61176
|
return;
|
|
60594
61177
|
}
|
|
60595
|
-
const timeoutId = setTimeout(
|
|
61178
|
+
const timeoutId = setTimeout(resolve38, interval);
|
|
60596
61179
|
signal.addEventListener("abort", () => {
|
|
60597
61180
|
clearTimeout(timeoutId);
|
|
60598
61181
|
reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
@@ -61382,7 +61965,7 @@ var Server = class extends Protocol {
|
|
|
61382
61965
|
};
|
|
61383
61966
|
|
|
61384
61967
|
// src/mcp/server.ts
|
|
61385
|
-
var
|
|
61968
|
+
var path52 = __toESM(require("path"));
|
|
61386
61969
|
|
|
61387
61970
|
// node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
|
|
61388
61971
|
var import_node_process2 = __toESM(require("node:process"), 1);
|
|
@@ -61465,12 +62048,12 @@ var StdioServerTransport = class {
|
|
|
61465
62048
|
this.onclose?.();
|
|
61466
62049
|
}
|
|
61467
62050
|
send(message) {
|
|
61468
|
-
return new Promise((
|
|
62051
|
+
return new Promise((resolve38) => {
|
|
61469
62052
|
const json = serializeMessage(message);
|
|
61470
62053
|
if (this._stdout.write(json)) {
|
|
61471
|
-
|
|
62054
|
+
resolve38();
|
|
61472
62055
|
} else {
|
|
61473
|
-
this._stdout.once("drain",
|
|
62056
|
+
this._stdout.once("drain", resolve38);
|
|
61474
62057
|
}
|
|
61475
62058
|
});
|
|
61476
62059
|
}
|
|
@@ -61553,13 +62136,20 @@ var LaunchEnvironmentInputSchema = external_exports.object({
|
|
|
61553
62136
|
force: external_exports.boolean().default(false).describe(
|
|
61554
62137
|
"Discard uncommitted changes in a dirty occupied worktree. Requires confirmReplace=true and explicit user approval \u2014 never set autonomously."
|
|
61555
62138
|
),
|
|
61556
|
-
resume: external_exports.boolean().default(false).describe("Resume a failed or partial launch without creating a new worktree.")
|
|
62139
|
+
resume: external_exports.boolean().default(false).describe("Resume a failed or partial launch without creating a new worktree."),
|
|
62140
|
+
workUnitId: external_exports.string().min(1).max(128).optional(),
|
|
62141
|
+
source: external_exports.string().min(1).max(64).optional(),
|
|
62142
|
+
sourceUrl: external_exports.string().url().optional(),
|
|
62143
|
+
title: external_exports.string().min(1).max(256).optional(),
|
|
62144
|
+
parentWorkUnitId: external_exports.string().min(1).max(128).optional()
|
|
61557
62145
|
});
|
|
61558
62146
|
var LaunchEnvironmentOutputSchema = ShellRunOutputSchema.extend({
|
|
61559
62147
|
previewUrls: external_exports.record(external_exports.string()).optional(),
|
|
61560
62148
|
workDir: external_exports.string().optional().describe("Where the session code lives \u2014 ALL file edits must go under this path"),
|
|
61561
62149
|
worktreePath: external_exports.string().optional(),
|
|
61562
62150
|
branch: external_exports.string().optional(),
|
|
62151
|
+
workUnitId: external_exports.string().optional(),
|
|
62152
|
+
attemptId: external_exports.string().uuid().optional(),
|
|
61563
62153
|
blocked: external_exports.boolean().optional(),
|
|
61564
62154
|
occupiedSlot: external_exports.object({
|
|
61565
62155
|
agentId: external_exports.number().int(),
|
|
@@ -61692,6 +62282,17 @@ var HAR_MCP_TOOLS = [
|
|
|
61692
62282
|
resume: {
|
|
61693
62283
|
type: "boolean",
|
|
61694
62284
|
description: "Resume a failed or partial launch (status failed/starting) without confirmReplace. Preserves worktree and env."
|
|
62285
|
+
},
|
|
62286
|
+
workUnitId: {
|
|
62287
|
+
type: "string",
|
|
62288
|
+
description: "Durable external work identifier to bind to this session."
|
|
62289
|
+
},
|
|
62290
|
+
source: { type: "string", description: "Optional provider/source name." },
|
|
62291
|
+
sourceUrl: { type: "string", description: "Optional source URL." },
|
|
62292
|
+
title: { type: "string", description: "Optional human-readable work title." },
|
|
62293
|
+
parentWorkUnitId: {
|
|
62294
|
+
type: "string",
|
|
62295
|
+
description: "Optional parent work unit identifier."
|
|
61695
62296
|
}
|
|
61696
62297
|
},
|
|
61697
62298
|
["agentId"]
|
|
@@ -61875,6 +62476,11 @@ async function handleMcpToolCall(toolName, args, defaultRepo = ".") {
|
|
|
61875
62476
|
confirmReplace: input.confirmReplace,
|
|
61876
62477
|
force: input.force,
|
|
61877
62478
|
resume: input.resume,
|
|
62479
|
+
workUnitId: input.workUnitId,
|
|
62480
|
+
source: input.source,
|
|
62481
|
+
sourceUrl: input.sourceUrl,
|
|
62482
|
+
title: input.title,
|
|
62483
|
+
parentWorkUnitId: input.parentWorkUnitId,
|
|
61878
62484
|
capture: true
|
|
61879
62485
|
});
|
|
61880
62486
|
const parsed = LaunchEnvironmentOutputSchema.parse(result);
|
|
@@ -61894,6 +62500,11 @@ async function handleMcpToolCall(toolName, args, defaultRepo = ".") {
|
|
|
61894
62500
|
confirmReplace: false,
|
|
61895
62501
|
force: false,
|
|
61896
62502
|
resume: true,
|
|
62503
|
+
workUnitId: input.workUnitId,
|
|
62504
|
+
source: input.source,
|
|
62505
|
+
sourceUrl: input.sourceUrl,
|
|
62506
|
+
title: input.title,
|
|
62507
|
+
parentWorkUnitId: input.parentWorkUnitId,
|
|
61897
62508
|
capture: true
|
|
61898
62509
|
});
|
|
61899
62510
|
const parsed = LaunchEnvironmentOutputSchema.parse(result);
|
|
@@ -62014,7 +62625,7 @@ async function handleMcpToolCall(toolName, args, defaultRepo = ".") {
|
|
|
62014
62625
|
const input = ControlUpInputSchema.parse({ ...args, repo });
|
|
62015
62626
|
const result = await startControlAndSync({
|
|
62016
62627
|
detach: input.detach,
|
|
62017
|
-
cwd:
|
|
62628
|
+
cwd: path52.resolve(input.repo)
|
|
62018
62629
|
});
|
|
62019
62630
|
if (result.code !== 0) {
|
|
62020
62631
|
return {
|
|
@@ -63094,13 +63705,13 @@ var PromisePolyfill = class extends Promise {
|
|
|
63094
63705
|
// Available starting from Node 22
|
|
63095
63706
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers
|
|
63096
63707
|
static withResolver() {
|
|
63097
|
-
let
|
|
63708
|
+
let resolve38;
|
|
63098
63709
|
let reject;
|
|
63099
63710
|
const promise = new Promise((res, rej) => {
|
|
63100
|
-
|
|
63711
|
+
resolve38 = res;
|
|
63101
63712
|
reject = rej;
|
|
63102
63713
|
});
|
|
63103
|
-
return { promise, resolve:
|
|
63714
|
+
return { promise, resolve: resolve38, reject };
|
|
63104
63715
|
}
|
|
63105
63716
|
};
|
|
63106
63717
|
|
|
@@ -63117,7 +63728,7 @@ function createPrompt(view) {
|
|
|
63117
63728
|
output
|
|
63118
63729
|
});
|
|
63119
63730
|
const screen = new ScreenManager(rl);
|
|
63120
|
-
const { promise, resolve:
|
|
63731
|
+
const { promise, resolve: resolve38, reject } = PromisePolyfill.withResolver();
|
|
63121
63732
|
const cancel = () => reject(new CancelPromptError());
|
|
63122
63733
|
if (signal) {
|
|
63123
63734
|
const abort = () => reject(new AbortPromptError({ cause: signal.reason }));
|
|
@@ -63141,7 +63752,7 @@ function createPrompt(view) {
|
|
|
63141
63752
|
cycle(() => {
|
|
63142
63753
|
try {
|
|
63143
63754
|
const nextView = view(config2, (value) => {
|
|
63144
|
-
setImmediate(() =>
|
|
63755
|
+
setImmediate(() => resolve38(value));
|
|
63145
63756
|
});
|
|
63146
63757
|
const [content, bottomContent] = typeof nextView === "string" ? [nextView] : nextView;
|
|
63147
63758
|
screen.render(content, bottomContent);
|
|
@@ -64128,9 +64739,9 @@ var import_run_async = __toESM(require_run_async(), 1);
|
|
|
64128
64739
|
var import_mute_stream2 = __toESM(require_lib3(), 1);
|
|
64129
64740
|
var import_ansi_escapes5 = __toESM(require_ansi_escapes(), 1);
|
|
64130
64741
|
var _2 = {
|
|
64131
|
-
set: (obj,
|
|
64742
|
+
set: (obj, path54 = "", value) => {
|
|
64132
64743
|
let pointer = obj;
|
|
64133
|
-
|
|
64744
|
+
path54.split(".").forEach((key, index, arr) => {
|
|
64134
64745
|
if (key === "__proto__" || key === "constructor")
|
|
64135
64746
|
return;
|
|
64136
64747
|
if (index === arr.length - 1) {
|
|
@@ -64141,8 +64752,8 @@ var _2 = {
|
|
|
64141
64752
|
pointer = pointer[key];
|
|
64142
64753
|
});
|
|
64143
64754
|
},
|
|
64144
|
-
get: (obj,
|
|
64145
|
-
const travel = (regexp) => String.prototype.split.call(
|
|
64755
|
+
get: (obj, path54 = "", defaultValue) => {
|
|
64756
|
+
const travel = (regexp) => String.prototype.split.call(path54, regexp).filter(Boolean).reduce(
|
|
64146
64757
|
// @ts-expect-error implicit any on res[key]
|
|
64147
64758
|
(res, key) => res !== null && res !== void 0 ? res[key] : res,
|
|
64148
64759
|
obj
|
|
@@ -64256,7 +64867,7 @@ var PromptsRunner = class {
|
|
|
64256
64867
|
throw new Error(`Prompt for type ${question.type} not found`);
|
|
64257
64868
|
}
|
|
64258
64869
|
let cleanupSignal;
|
|
64259
|
-
const promptFn = isPromptConstructor(prompt2) ? (q2, { signal: signal2 } = {}) => new Promise((
|
|
64870
|
+
const promptFn = isPromptConstructor(prompt2) ? (q2, { signal: signal2 } = {}) => new Promise((resolve38, reject) => {
|
|
64260
64871
|
const rl = import_node_readline.default.createInterface(setupReadlineOptions(this.opt));
|
|
64261
64872
|
rl.resume();
|
|
64262
64873
|
const onClose = () => {
|
|
@@ -64292,7 +64903,7 @@ var PromptsRunner = class {
|
|
|
64292
64903
|
cleanupSignal = void 0;
|
|
64293
64904
|
};
|
|
64294
64905
|
}
|
|
64295
|
-
activePrompt.run().then(
|
|
64906
|
+
activePrompt.run().then(resolve38, reject).finally(cleanup);
|
|
64296
64907
|
}) : prompt2;
|
|
64297
64908
|
const { signal: moduleSignal } = this.opt;
|
|
64298
64909
|
if (moduleSignal?.aborted) {
|
|
@@ -64506,7 +65117,7 @@ var preferencesCommand = {
|
|
|
64506
65117
|
};
|
|
64507
65118
|
|
|
64508
65119
|
// src/cli/commands/telemetry.ts
|
|
64509
|
-
var
|
|
65120
|
+
var path53 = __toESM(require("path"));
|
|
64510
65121
|
init_control_config();
|
|
64511
65122
|
init_otel_hooks();
|
|
64512
65123
|
init_telemetry_config();
|
|
@@ -64591,7 +65202,7 @@ async function handleOff() {
|
|
|
64591
65202
|
info("Mission Control will not auto-start. Existing usage rows are kept.");
|
|
64592
65203
|
}
|
|
64593
65204
|
async function handleWriteEnv(argv) {
|
|
64594
|
-
const repoPath =
|
|
65205
|
+
const repoPath = path53.resolve(argv.repo);
|
|
64595
65206
|
const harnessRoot = resolveHarnessRoot(repoPath);
|
|
64596
65207
|
const session = readSlotRegistry(harnessRoot, argv.agentId);
|
|
64597
65208
|
const workDir = argv.workDir ?? session?.workDir ?? repoPath;
|
|
@@ -64603,7 +65214,7 @@ async function handleWriteEnv(argv) {
|
|
|
64603
65214
|
suffix,
|
|
64604
65215
|
createdAt: session?.createdAt
|
|
64605
65216
|
});
|
|
64606
|
-
const envFile = argv.envFile ??
|
|
65217
|
+
const envFile = argv.envFile ?? path53.join(workDir, `.env.agent.${argv.agentId}`);
|
|
64607
65218
|
const attrs = {
|
|
64608
65219
|
sessionKey,
|
|
64609
65220
|
agentId: argv.agentId,
|
|
@@ -64622,7 +65233,7 @@ async function handleWriteEnv(argv) {
|
|
|
64622
65233
|
success(`Wrote session attribution to ${envFile}`);
|
|
64623
65234
|
}
|
|
64624
65235
|
function handlePrintEnv(argv) {
|
|
64625
|
-
const repoPath =
|
|
65236
|
+
const repoPath = path53.resolve(argv.repo);
|
|
64626
65237
|
const workDir = argv.workDir ?? repoPath;
|
|
64627
65238
|
const sessionKey = buildSessionKey({
|
|
64628
65239
|
branch: argv.branch,
|