@osfactory/har 0.34.0 → 0.36.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/dist/index.js +1136 -865
- package/dist/templates/AGENT.md.template +6 -1
- package/dist/templates/cursor-rule.mdc.template +47 -2
- package/dist/templates/har-boilerplate/CLAUDE.agent.md +11 -1
- package/dist/templates/har-boilerplate-cli/CLAUDE.agent.md +11 -1
- package/dist/templates/har-boilerplate-ios/CLAUDE.agent.md +11 -1
- package/dist/templates/plugins/playwright/.har/stages/PLAYWRIGHT.md +22 -1
- package/dist/templates/plugins/playwright/playwright.config.js +56 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -873,14 +873,14 @@ var require_url_state_machine = __commonJS({
|
|
|
873
873
|
return url.replace(/\u0009|\u000A|\u000D/g, "");
|
|
874
874
|
}
|
|
875
875
|
function shortenPath(url) {
|
|
876
|
-
const
|
|
877
|
-
if (
|
|
876
|
+
const path61 = url.path;
|
|
877
|
+
if (path61.length === 0) {
|
|
878
878
|
return;
|
|
879
879
|
}
|
|
880
|
-
if (url.scheme === "file" &&
|
|
880
|
+
if (url.scheme === "file" && path61.length === 1 && isNormalizedWindowsDriveLetter(path61[0])) {
|
|
881
881
|
return;
|
|
882
882
|
}
|
|
883
|
-
|
|
883
|
+
path61.pop();
|
|
884
884
|
}
|
|
885
885
|
function includesCredentials(url) {
|
|
886
886
|
return url.username !== "" || url.password !== "";
|
|
@@ -2200,7 +2200,7 @@ var require_lib2 = __commonJS({
|
|
|
2200
2200
|
let accum = [];
|
|
2201
2201
|
let accumBytes = 0;
|
|
2202
2202
|
let abort = false;
|
|
2203
|
-
return new Body.Promise(function(
|
|
2203
|
+
return new Body.Promise(function(resolve45, reject) {
|
|
2204
2204
|
let resTimeout;
|
|
2205
2205
|
if (_this4.timeout) {
|
|
2206
2206
|
resTimeout = setTimeout(function() {
|
|
@@ -2234,7 +2234,7 @@ var require_lib2 = __commonJS({
|
|
|
2234
2234
|
}
|
|
2235
2235
|
clearTimeout(resTimeout);
|
|
2236
2236
|
try {
|
|
2237
|
-
|
|
2237
|
+
resolve45(Buffer.concat(accum, accumBytes));
|
|
2238
2238
|
} catch (err) {
|
|
2239
2239
|
reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, "system", err));
|
|
2240
2240
|
}
|
|
@@ -2909,7 +2909,7 @@ var require_lib2 = __commonJS({
|
|
|
2909
2909
|
throw new Error("native promise missing, set fetch.Promise to your favorite alternative");
|
|
2910
2910
|
}
|
|
2911
2911
|
Body.Promise = fetch3.Promise;
|
|
2912
|
-
return new fetch3.Promise(function(
|
|
2912
|
+
return new fetch3.Promise(function(resolve45, reject) {
|
|
2913
2913
|
const request = new Request3(url, opts);
|
|
2914
2914
|
const options = getNodeRequestOptions(request);
|
|
2915
2915
|
const send = (options.protocol === "https:" ? https : http2).request;
|
|
@@ -3042,7 +3042,7 @@ var require_lib2 = __commonJS({
|
|
|
3042
3042
|
requestOpts.body = void 0;
|
|
3043
3043
|
requestOpts.headers.delete("content-length");
|
|
3044
3044
|
}
|
|
3045
|
-
|
|
3045
|
+
resolve45(fetch3(new Request3(locationURL, requestOpts)));
|
|
3046
3046
|
finalize();
|
|
3047
3047
|
return;
|
|
3048
3048
|
}
|
|
@@ -3063,7 +3063,7 @@ var require_lib2 = __commonJS({
|
|
|
3063
3063
|
const codings = headers.get("Content-Encoding");
|
|
3064
3064
|
if (!request.compress || request.method === "HEAD" || codings === null || res.statusCode === 204 || res.statusCode === 304) {
|
|
3065
3065
|
response = new Response3(body, response_options);
|
|
3066
|
-
|
|
3066
|
+
resolve45(response);
|
|
3067
3067
|
return;
|
|
3068
3068
|
}
|
|
3069
3069
|
const zlibOptions = {
|
|
@@ -3073,7 +3073,7 @@ var require_lib2 = __commonJS({
|
|
|
3073
3073
|
if (codings == "gzip" || codings == "x-gzip") {
|
|
3074
3074
|
body = body.pipe(zlib.createGunzip(zlibOptions));
|
|
3075
3075
|
response = new Response3(body, response_options);
|
|
3076
|
-
|
|
3076
|
+
resolve45(response);
|
|
3077
3077
|
return;
|
|
3078
3078
|
}
|
|
3079
3079
|
if (codings == "deflate" || codings == "x-deflate") {
|
|
@@ -3085,12 +3085,12 @@ var require_lib2 = __commonJS({
|
|
|
3085
3085
|
body = body.pipe(zlib.createInflateRaw());
|
|
3086
3086
|
}
|
|
3087
3087
|
response = new Response3(body, response_options);
|
|
3088
|
-
|
|
3088
|
+
resolve45(response);
|
|
3089
3089
|
});
|
|
3090
3090
|
raw.on("end", function() {
|
|
3091
3091
|
if (!response) {
|
|
3092
3092
|
response = new Response3(body, response_options);
|
|
3093
|
-
|
|
3093
|
+
resolve45(response);
|
|
3094
3094
|
}
|
|
3095
3095
|
});
|
|
3096
3096
|
return;
|
|
@@ -3098,11 +3098,11 @@ var require_lib2 = __commonJS({
|
|
|
3098
3098
|
if (codings == "br" && typeof zlib.createBrotliDecompress === "function") {
|
|
3099
3099
|
body = body.pipe(zlib.createBrotliDecompress());
|
|
3100
3100
|
response = new Response3(body, response_options);
|
|
3101
|
-
|
|
3101
|
+
resolve45(response);
|
|
3102
3102
|
return;
|
|
3103
3103
|
}
|
|
3104
3104
|
response = new Response3(body, response_options);
|
|
3105
|
-
|
|
3105
|
+
resolve45(response);
|
|
3106
3106
|
});
|
|
3107
3107
|
writeToStream(req, request);
|
|
3108
3108
|
});
|
|
@@ -6459,14 +6459,14 @@ __export(fileFromPath_exports, {
|
|
|
6459
6459
|
fileFromPathSync: () => fileFromPathSync,
|
|
6460
6460
|
isFile: () => isFile
|
|
6461
6461
|
});
|
|
6462
|
-
function createFileFromPath(
|
|
6462
|
+
function createFileFromPath(path61, { mtimeMs, size }, filenameOrOptions, options = {}) {
|
|
6463
6463
|
let filename;
|
|
6464
6464
|
if (isPlainObject_default2(filenameOrOptions)) {
|
|
6465
6465
|
[options, filename] = [filenameOrOptions, void 0];
|
|
6466
6466
|
} else {
|
|
6467
6467
|
filename = filenameOrOptions;
|
|
6468
6468
|
}
|
|
6469
|
-
const file = new FileFromPath({ path:
|
|
6469
|
+
const file = new FileFromPath({ path: path61, size, lastModified: mtimeMs });
|
|
6470
6470
|
if (!filename) {
|
|
6471
6471
|
filename = file.name;
|
|
6472
6472
|
}
|
|
@@ -6475,13 +6475,13 @@ function createFileFromPath(path60, { mtimeMs, size }, filenameOrOptions, option
|
|
|
6475
6475
|
lastModified: file.lastModified
|
|
6476
6476
|
});
|
|
6477
6477
|
}
|
|
6478
|
-
function fileFromPathSync(
|
|
6479
|
-
const stats = (0, import_fs5.statSync)(
|
|
6480
|
-
return createFileFromPath(
|
|
6478
|
+
function fileFromPathSync(path61, filenameOrOptions, options = {}) {
|
|
6479
|
+
const stats = (0, import_fs5.statSync)(path61);
|
|
6480
|
+
return createFileFromPath(path61, stats, filenameOrOptions, options);
|
|
6481
6481
|
}
|
|
6482
|
-
async function fileFromPath2(
|
|
6483
|
-
const stats = await import_fs5.promises.stat(
|
|
6484
|
-
return createFileFromPath(
|
|
6482
|
+
async function fileFromPath2(path61, filenameOrOptions, options) {
|
|
6483
|
+
const stats = await import_fs5.promises.stat(path61);
|
|
6484
|
+
return createFileFromPath(path61, stats, filenameOrOptions, options);
|
|
6485
6485
|
}
|
|
6486
6486
|
var import_fs5, import_path5, import_node_domexception, __classPrivateFieldSet5, __classPrivateFieldGet6, _FileFromPath_path, _FileFromPath_start, MESSAGE, FileFromPath;
|
|
6487
6487
|
var init_fileFromPath = __esm({
|
|
@@ -6544,13 +6544,13 @@ var init_fileFromPath = __esm({
|
|
|
6544
6544
|
// src/core/portal-credentials.ts
|
|
6545
6545
|
function portalCredentialsPath() {
|
|
6546
6546
|
if (process.env.HAR_CREDENTIALS_PATH) {
|
|
6547
|
-
return
|
|
6547
|
+
return path27.resolve(process.env.HAR_CREDENTIALS_PATH);
|
|
6548
6548
|
}
|
|
6549
|
-
return
|
|
6549
|
+
return path27.join(os5.homedir(), ".har", "credentials.json");
|
|
6550
6550
|
}
|
|
6551
6551
|
function readPortalCredentials() {
|
|
6552
6552
|
try {
|
|
6553
|
-
const raw =
|
|
6553
|
+
const raw = fs28.readFileSync(portalCredentialsPath(), "utf8");
|
|
6554
6554
|
const parsed = JSON.parse(raw);
|
|
6555
6555
|
if (!parsed.portalUrl || !parsed.token) return null;
|
|
6556
6556
|
return {
|
|
@@ -6566,17 +6566,17 @@ function readPortalCredentials() {
|
|
|
6566
6566
|
}
|
|
6567
6567
|
function writePortalCredentials(creds) {
|
|
6568
6568
|
const file = portalCredentialsPath();
|
|
6569
|
-
|
|
6570
|
-
|
|
6571
|
-
|
|
6569
|
+
fs28.mkdirSync(path27.dirname(file), { recursive: true });
|
|
6570
|
+
fs28.writeFileSync(file, JSON.stringify(creds, null, 2), { mode: 384 });
|
|
6571
|
+
fs28.chmodSync(file, 384);
|
|
6572
6572
|
}
|
|
6573
|
-
var
|
|
6573
|
+
var fs28, os5, path27;
|
|
6574
6574
|
var init_portal_credentials = __esm({
|
|
6575
6575
|
"src/core/portal-credentials.ts"() {
|
|
6576
6576
|
"use strict";
|
|
6577
|
-
|
|
6577
|
+
fs28 = __toESM(require("fs"));
|
|
6578
6578
|
os5 = __toESM(require("os"));
|
|
6579
|
-
|
|
6579
|
+
path27 = __toESM(require("path"));
|
|
6580
6580
|
}
|
|
6581
6581
|
});
|
|
6582
6582
|
|
|
@@ -6640,32 +6640,32 @@ __export(otel_hooks_exports, {
|
|
|
6640
6640
|
});
|
|
6641
6641
|
function getOtelHooksHome() {
|
|
6642
6642
|
if (process.env.HAR_OTEL_HOOKS_HOME) {
|
|
6643
|
-
return
|
|
6643
|
+
return path46.resolve(process.env.HAR_OTEL_HOOKS_HOME);
|
|
6644
6644
|
}
|
|
6645
|
-
return
|
|
6645
|
+
return path46.join(os14.homedir(), ".har", "otel-hooks");
|
|
6646
6646
|
}
|
|
6647
6647
|
function getOtelHooksConfigPath(hooksHome = getOtelHooksHome()) {
|
|
6648
|
-
return
|
|
6648
|
+
return path46.join(hooksHome, "otel_config.json");
|
|
6649
6649
|
}
|
|
6650
6650
|
function getOtelHooksWrapperPath(hooksHome = getOtelHooksHome()) {
|
|
6651
|
-
return
|
|
6651
|
+
return path46.join(hooksHome, "run-otel-hook.sh");
|
|
6652
6652
|
}
|
|
6653
6653
|
function getOtelHooksStateDir(hooksHome = getOtelHooksHome()) {
|
|
6654
|
-
return
|
|
6654
|
+
return path46.join(hooksHome, "state");
|
|
6655
6655
|
}
|
|
6656
6656
|
function localOtelHookBin(hooksHome) {
|
|
6657
|
-
return
|
|
6657
|
+
return path46.join(hooksHome, "node_modules", ".bin", "otel-hook");
|
|
6658
6658
|
}
|
|
6659
6659
|
function installedPackageVersion(hooksHome) {
|
|
6660
6660
|
try {
|
|
6661
|
-
const pkgPath =
|
|
6661
|
+
const pkgPath = path46.join(
|
|
6662
6662
|
hooksHome,
|
|
6663
6663
|
"node_modules",
|
|
6664
6664
|
"@osfactory",
|
|
6665
6665
|
"otel-hook",
|
|
6666
6666
|
"package.json"
|
|
6667
6667
|
);
|
|
6668
|
-
const pkg = JSON.parse(
|
|
6668
|
+
const pkg = JSON.parse(fs43.readFileSync(pkgPath, "utf8"));
|
|
6669
6669
|
return typeof pkg.version === "string" ? pkg.version : null;
|
|
6670
6670
|
} catch {
|
|
6671
6671
|
return null;
|
|
@@ -6716,15 +6716,15 @@ function buildOtelHooksConfig(options) {
|
|
|
6716
6716
|
};
|
|
6717
6717
|
}
|
|
6718
6718
|
function writeOtelHooksConfig(config2, hooksHome = getOtelHooksHome()) {
|
|
6719
|
-
|
|
6719
|
+
fs43.mkdirSync(hooksHome, { recursive: true });
|
|
6720
6720
|
const configPath = getOtelHooksConfigPath(hooksHome);
|
|
6721
|
-
|
|
6721
|
+
fs43.writeFileSync(configPath, `${JSON.stringify(config2, null, 2)}
|
|
6722
6722
|
`);
|
|
6723
6723
|
return configPath;
|
|
6724
6724
|
}
|
|
6725
6725
|
function writeOtelHooksWrapper(otelHookCommand, hooksHome = getOtelHooksHome()) {
|
|
6726
|
-
|
|
6727
|
-
|
|
6726
|
+
fs43.mkdirSync(hooksHome, { recursive: true });
|
|
6727
|
+
fs43.mkdirSync(getOtelHooksStateDir(hooksHome), { recursive: true });
|
|
6728
6728
|
const wrapperPath = getOtelHooksWrapperPath(hooksHome);
|
|
6729
6729
|
const configPath = getOtelHooksConfigPath(hooksHome);
|
|
6730
6730
|
const stateDir = getOtelHooksStateDir(hooksHome);
|
|
@@ -6736,9 +6736,9 @@ exec "${otelHookCommand}" run \\
|
|
|
6736
6736
|
--state-dir "${stateDir}" \\
|
|
6737
6737
|
"$@"
|
|
6738
6738
|
`;
|
|
6739
|
-
|
|
6739
|
+
fs43.writeFileSync(wrapperPath, script, { mode: 493 });
|
|
6740
6740
|
try {
|
|
6741
|
-
|
|
6741
|
+
fs43.chmodSync(wrapperPath, 493);
|
|
6742
6742
|
} catch {
|
|
6743
6743
|
}
|
|
6744
6744
|
return wrapperPath;
|
|
@@ -6751,11 +6751,11 @@ function commandExists2(command2) {
|
|
|
6751
6751
|
}
|
|
6752
6752
|
function resolveOtelHookCommand(hooksHome) {
|
|
6753
6753
|
const local = localOtelHookBin(hooksHome);
|
|
6754
|
-
if (
|
|
6754
|
+
if (fs43.existsSync(local)) return local;
|
|
6755
6755
|
return null;
|
|
6756
6756
|
}
|
|
6757
6757
|
function tryInstallPackage(hooksHome) {
|
|
6758
|
-
|
|
6758
|
+
fs43.mkdirSync(hooksHome, { recursive: true });
|
|
6759
6759
|
if (!commandExists2("npm")) {
|
|
6760
6760
|
return {
|
|
6761
6761
|
ok: false,
|
|
@@ -6767,7 +6767,7 @@ function tryInstallPackage(hooksHome) {
|
|
|
6767
6767
|
["install", "--prefix", hooksHome, "--no-fund", "--no-audit", OTEL_HOOKS_PACKAGE],
|
|
6768
6768
|
{ encoding: "utf8", timeout: 18e4 }
|
|
6769
6769
|
);
|
|
6770
|
-
if (result.status === 0 &&
|
|
6770
|
+
if (result.status === 0 && fs43.existsSync(localOtelHookBin(hooksHome))) {
|
|
6771
6771
|
return { ok: true, detail: `npm install --prefix ${hooksHome} ${OTEL_HOOKS_PACKAGE}` };
|
|
6772
6772
|
}
|
|
6773
6773
|
return {
|
|
@@ -6793,14 +6793,14 @@ function uninstallLegacyPythonHooks(hooksHome) {
|
|
|
6793
6793
|
}
|
|
6794
6794
|
function removeLegacyPythonArtifacts(hooksHome) {
|
|
6795
6795
|
const legacyPaths = [
|
|
6796
|
-
|
|
6797
|
-
|
|
6798
|
-
|
|
6796
|
+
path46.join(hooksHome, ".venv"),
|
|
6797
|
+
path46.join(hooksHome, "otel_config.yaml"),
|
|
6798
|
+
path46.join(hooksHome, "venv")
|
|
6799
6799
|
];
|
|
6800
6800
|
for (const target of legacyPaths) {
|
|
6801
6801
|
try {
|
|
6802
|
-
if (
|
|
6803
|
-
|
|
6802
|
+
if (fs43.existsSync(target)) {
|
|
6803
|
+
fs43.rmSync(target, { recursive: true, force: true });
|
|
6804
6804
|
}
|
|
6805
6805
|
} catch {
|
|
6806
6806
|
}
|
|
@@ -6841,10 +6841,10 @@ function runSetupProvider(providerId, otelHookCommand, wrapperPath) {
|
|
|
6841
6841
|
};
|
|
6842
6842
|
}
|
|
6843
6843
|
function rewriteHookCommandsToWrapper(filePath, wrapperPath) {
|
|
6844
|
-
if (!
|
|
6844
|
+
if (!fs43.existsSync(filePath)) return false;
|
|
6845
6845
|
let raw;
|
|
6846
6846
|
try {
|
|
6847
|
-
raw =
|
|
6847
|
+
raw = fs43.readFileSync(filePath, "utf8");
|
|
6848
6848
|
} catch {
|
|
6849
6849
|
return false;
|
|
6850
6850
|
}
|
|
@@ -6891,15 +6891,15 @@ function rewriteHookCommandsToWrapper(filePath, wrapperPath) {
|
|
|
6891
6891
|
return changed;
|
|
6892
6892
|
};
|
|
6893
6893
|
if (!walk(parsed)) return false;
|
|
6894
|
-
|
|
6894
|
+
fs43.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
|
|
6895
6895
|
`);
|
|
6896
6896
|
return true;
|
|
6897
6897
|
}
|
|
6898
6898
|
function pruneLegacyCursorHookEvents(filePath, wrapperPath) {
|
|
6899
|
-
if (!
|
|
6899
|
+
if (!fs43.existsSync(filePath)) return false;
|
|
6900
6900
|
let raw;
|
|
6901
6901
|
try {
|
|
6902
|
-
raw =
|
|
6902
|
+
raw = fs43.readFileSync(filePath, "utf8");
|
|
6903
6903
|
} catch {
|
|
6904
6904
|
return false;
|
|
6905
6905
|
}
|
|
@@ -6934,21 +6934,21 @@ function pruneLegacyCursorHookEvents(filePath, wrapperPath) {
|
|
|
6934
6934
|
}
|
|
6935
6935
|
}
|
|
6936
6936
|
if (!changed) return false;
|
|
6937
|
-
|
|
6937
|
+
fs43.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
|
|
6938
6938
|
`);
|
|
6939
6939
|
return true;
|
|
6940
6940
|
}
|
|
6941
6941
|
function rewriteKnownHookRegistrations(wrapperPath) {
|
|
6942
6942
|
const home = os14.homedir();
|
|
6943
6943
|
const candidates = [
|
|
6944
|
-
|
|
6945
|
-
|
|
6946
|
-
|
|
6944
|
+
path46.join(home, ".cursor", "hooks.json"),
|
|
6945
|
+
path46.join(home, ".claude", "settings.json"),
|
|
6946
|
+
path46.join(home, ".codex", "hooks.json")
|
|
6947
6947
|
];
|
|
6948
6948
|
for (const filePath of candidates) {
|
|
6949
6949
|
try {
|
|
6950
6950
|
rewriteHookCommandsToWrapper(filePath, wrapperPath);
|
|
6951
|
-
if (filePath.endsWith(`${
|
|
6951
|
+
if (filePath.endsWith(`${path46.sep}.cursor${path46.sep}hooks.json`)) {
|
|
6952
6952
|
pruneLegacyCursorHookEvents(filePath, wrapperPath);
|
|
6953
6953
|
}
|
|
6954
6954
|
} catch {
|
|
@@ -6964,7 +6964,7 @@ function ensureOtelHooks(options) {
|
|
|
6964
6964
|
const hooksHome = getOtelHooksHome();
|
|
6965
6965
|
const errors = [];
|
|
6966
6966
|
const providersSetup = [];
|
|
6967
|
-
|
|
6967
|
+
fs43.mkdirSync(hooksHome, { recursive: true });
|
|
6968
6968
|
let otelHookCommand = resolveOtelHookCommand(hooksHome);
|
|
6969
6969
|
const needsInstall = !otelHookCommand || installedPackageVersion(hooksHome) !== pinnedVersion();
|
|
6970
6970
|
if (needsInstall) {
|
|
@@ -7058,14 +7058,14 @@ function ensureOtelHooks(options) {
|
|
|
7058
7058
|
function disableOtelHooksExport() {
|
|
7059
7059
|
return writeOtelHooksConfig(buildOtelHooksConfig({ enabled: false }));
|
|
7060
7060
|
}
|
|
7061
|
-
var import_child_process10,
|
|
7061
|
+
var import_child_process10, fs43, os14, path46, OTEL_HOOKS_PACKAGE, OTEL_HOOKS_PROVIDERS, OTEL_HOOKS_AGENTS, LEGACY_CURSOR_ONLY_HOOK_EVENTS;
|
|
7062
7062
|
var init_otel_hooks = __esm({
|
|
7063
7063
|
"src/core/otel-hooks.ts"() {
|
|
7064
7064
|
"use strict";
|
|
7065
7065
|
import_child_process10 = require("child_process");
|
|
7066
|
-
|
|
7066
|
+
fs43 = __toESM(require("fs"));
|
|
7067
7067
|
os14 = __toESM(require("os"));
|
|
7068
|
-
|
|
7068
|
+
path46 = __toESM(require("path"));
|
|
7069
7069
|
init_control_config();
|
|
7070
7070
|
init_telemetry_config();
|
|
7071
7071
|
OTEL_HOOKS_PACKAGE = "@osfactory/otel-hook@0.1.1";
|
|
@@ -8181,15 +8181,15 @@ var require_route = __commonJS({
|
|
|
8181
8181
|
};
|
|
8182
8182
|
}
|
|
8183
8183
|
function wrapConversion(toModel, graph) {
|
|
8184
|
-
const
|
|
8184
|
+
const path61 = [graph[toModel].parent, toModel];
|
|
8185
8185
|
let fn = conversions[graph[toModel].parent][toModel];
|
|
8186
8186
|
let cur = graph[toModel].parent;
|
|
8187
8187
|
while (graph[cur].parent) {
|
|
8188
|
-
|
|
8188
|
+
path61.unshift(graph[cur].parent);
|
|
8189
8189
|
fn = link(conversions[graph[cur].parent][cur], fn);
|
|
8190
8190
|
cur = graph[cur].parent;
|
|
8191
8191
|
}
|
|
8192
|
-
fn.conversion =
|
|
8192
|
+
fn.conversion = path61;
|
|
8193
8193
|
return fn;
|
|
8194
8194
|
}
|
|
8195
8195
|
module2.exports = function(fromModel) {
|
|
@@ -14119,7 +14119,7 @@ var require_iso2022 = __commonJS({
|
|
|
14119
14119
|
// node_modules/chardet/index.js
|
|
14120
14120
|
var require_chardet = __commonJS({
|
|
14121
14121
|
"node_modules/chardet/index.js"(exports2, module2) {
|
|
14122
|
-
var
|
|
14122
|
+
var fs50 = require("fs");
|
|
14123
14123
|
var utf8 = require_utf8();
|
|
14124
14124
|
var unicode = require_unicode();
|
|
14125
14125
|
var mbcs = require_mbcs();
|
|
@@ -14193,28 +14193,28 @@ var require_chardet = __commonJS({
|
|
|
14193
14193
|
var fd;
|
|
14194
14194
|
var handler = function(err, buffer) {
|
|
14195
14195
|
if (fd) {
|
|
14196
|
-
|
|
14196
|
+
fs50.closeSync(fd);
|
|
14197
14197
|
}
|
|
14198
14198
|
if (err) return cb(err, null);
|
|
14199
14199
|
cb(null, self.detect(buffer, opts));
|
|
14200
14200
|
};
|
|
14201
14201
|
if (opts && opts.sampleSize) {
|
|
14202
|
-
fd =
|
|
14203
|
-
|
|
14202
|
+
fd = fs50.openSync(filepath, "r"), sample = Buffer.allocUnsafe(opts.sampleSize);
|
|
14203
|
+
fs50.read(fd, sample, 0, opts.sampleSize, null, function(err) {
|
|
14204
14204
|
handler(err, sample);
|
|
14205
14205
|
});
|
|
14206
14206
|
return;
|
|
14207
14207
|
}
|
|
14208
|
-
|
|
14208
|
+
fs50.readFile(filepath, handler);
|
|
14209
14209
|
};
|
|
14210
14210
|
module2.exports.detectFileSync = function(filepath, opts) {
|
|
14211
14211
|
if (opts && opts.sampleSize) {
|
|
14212
|
-
var fd =
|
|
14213
|
-
|
|
14214
|
-
|
|
14212
|
+
var fd = fs50.openSync(filepath, "r"), sample2 = Buffer.allocUnsafe(opts.sampleSize);
|
|
14213
|
+
fs50.readSync(fd, sample2, 0, opts.sampleSize);
|
|
14214
|
+
fs50.closeSync(fd);
|
|
14215
14215
|
return self.detect(sample2, opts);
|
|
14216
14216
|
}
|
|
14217
|
-
return self.detect(
|
|
14217
|
+
return self.detect(fs50.readFileSync(filepath), opts);
|
|
14218
14218
|
};
|
|
14219
14219
|
module2.exports.detectAll = function(buffer, opts) {
|
|
14220
14220
|
if (typeof opts !== "object") {
|
|
@@ -17679,16 +17679,16 @@ var require_os_tmpdir = __commonJS({
|
|
|
17679
17679
|
var isWindows = process.platform === "win32";
|
|
17680
17680
|
var trailingSlashRe = isWindows ? /[^:]\\$/ : /.\/$/;
|
|
17681
17681
|
module2.exports = function() {
|
|
17682
|
-
var
|
|
17682
|
+
var path61;
|
|
17683
17683
|
if (isWindows) {
|
|
17684
|
-
|
|
17684
|
+
path61 = process.env.TEMP || process.env.TMP || (process.env.SystemRoot || process.env.windir) + "\\temp";
|
|
17685
17685
|
} else {
|
|
17686
|
-
|
|
17686
|
+
path61 = process.env.TMPDIR || process.env.TMP || process.env.TEMP || "/tmp";
|
|
17687
17687
|
}
|
|
17688
|
-
if (trailingSlashRe.test(
|
|
17689
|
-
|
|
17688
|
+
if (trailingSlashRe.test(path61)) {
|
|
17689
|
+
path61 = path61.slice(0, -1);
|
|
17690
17690
|
}
|
|
17691
|
-
return
|
|
17691
|
+
return path61;
|
|
17692
17692
|
};
|
|
17693
17693
|
}
|
|
17694
17694
|
});
|
|
@@ -17696,8 +17696,8 @@ var require_os_tmpdir = __commonJS({
|
|
|
17696
17696
|
// node_modules/tmp/lib/tmp.js
|
|
17697
17697
|
var require_tmp = __commonJS({
|
|
17698
17698
|
"node_modules/tmp/lib/tmp.js"(exports2, module2) {
|
|
17699
|
-
var
|
|
17700
|
-
var
|
|
17699
|
+
var fs50 = require("fs");
|
|
17700
|
+
var path61 = require("path");
|
|
17701
17701
|
var crypto6 = require("crypto");
|
|
17702
17702
|
var osTmpDir = require_os_tmpdir();
|
|
17703
17703
|
var _c2 = process.binding("constants");
|
|
@@ -17739,7 +17739,7 @@ var require_tmp = __commonJS({
|
|
|
17739
17739
|
}
|
|
17740
17740
|
function _generateTmpName(opts) {
|
|
17741
17741
|
if (opts.name) {
|
|
17742
|
-
return
|
|
17742
|
+
return path61.join(opts.dir || tmpDir, opts.name);
|
|
17743
17743
|
}
|
|
17744
17744
|
if (opts.template) {
|
|
17745
17745
|
return opts.template.replace(TEMPLATE_PATTERN, _randomChars(6));
|
|
@@ -17750,7 +17750,7 @@ var require_tmp = __commonJS({
|
|
|
17750
17750
|
_randomChars(12),
|
|
17751
17751
|
opts.postfix || ""
|
|
17752
17752
|
].join("");
|
|
17753
|
-
return
|
|
17753
|
+
return path61.join(opts.dir || tmpDir, name);
|
|
17754
17754
|
}
|
|
17755
17755
|
function tmpName(options, callback) {
|
|
17756
17756
|
var args = _parseArguments(options, callback), opts = args[0], cb = args[1], tries = opts.name ? 1 : opts.tries || DEFAULT_TRIES;
|
|
@@ -17760,7 +17760,7 @@ var require_tmp = __commonJS({
|
|
|
17760
17760
|
return cb(new Error("Invalid template provided"));
|
|
17761
17761
|
(function _getUniqueName() {
|
|
17762
17762
|
const name = _generateTmpName(opts);
|
|
17763
|
-
|
|
17763
|
+
fs50.stat(name, function(err) {
|
|
17764
17764
|
if (!err) {
|
|
17765
17765
|
if (tries-- > 0) return _getUniqueName();
|
|
17766
17766
|
return cb(new Error("Could not get a unique tmp filename, max tries reached " + name));
|
|
@@ -17778,7 +17778,7 @@ var require_tmp = __commonJS({
|
|
|
17778
17778
|
do {
|
|
17779
17779
|
const name = _generateTmpName(opts);
|
|
17780
17780
|
try {
|
|
17781
|
-
|
|
17781
|
+
fs50.statSync(name);
|
|
17782
17782
|
} catch (e2) {
|
|
17783
17783
|
return name;
|
|
17784
17784
|
}
|
|
@@ -17790,13 +17790,13 @@ var require_tmp = __commonJS({
|
|
|
17790
17790
|
opts.postfix = _isUndefined(opts.postfix) ? ".tmp" : opts.postfix;
|
|
17791
17791
|
tmpName(opts, function _tmpNameCreated(err, name) {
|
|
17792
17792
|
if (err) return cb(err);
|
|
17793
|
-
|
|
17793
|
+
fs50.open(name, CREATE_FLAGS, opts.mode || FILE_MODE, function _fileCreated(err2, fd) {
|
|
17794
17794
|
if (err2) return cb(err2);
|
|
17795
17795
|
if (opts.discardDescriptor) {
|
|
17796
|
-
return
|
|
17796
|
+
return fs50.close(fd, function _discardCallback(err3) {
|
|
17797
17797
|
if (err3) {
|
|
17798
17798
|
try {
|
|
17799
|
-
|
|
17799
|
+
fs50.unlinkSync(name);
|
|
17800
17800
|
} catch (e2) {
|
|
17801
17801
|
if (!isENOENT(e2)) {
|
|
17802
17802
|
err3 = e2;
|
|
@@ -17819,9 +17819,9 @@ var require_tmp = __commonJS({
|
|
|
17819
17819
|
opts.postfix = opts.postfix || ".tmp";
|
|
17820
17820
|
const discardOrDetachDescriptor = opts.discardDescriptor || opts.detachDescriptor;
|
|
17821
17821
|
const name = tmpNameSync(opts);
|
|
17822
|
-
var fd =
|
|
17822
|
+
var fd = fs50.openSync(name, CREATE_FLAGS, opts.mode || FILE_MODE);
|
|
17823
17823
|
if (opts.discardDescriptor) {
|
|
17824
|
-
|
|
17824
|
+
fs50.closeSync(fd);
|
|
17825
17825
|
fd = void 0;
|
|
17826
17826
|
}
|
|
17827
17827
|
return {
|
|
@@ -17833,9 +17833,9 @@ var require_tmp = __commonJS({
|
|
|
17833
17833
|
function _rmdirRecursiveSync(root) {
|
|
17834
17834
|
const dirs = [root];
|
|
17835
17835
|
do {
|
|
17836
|
-
var dir2 = dirs.pop(), deferred = false, files =
|
|
17836
|
+
var dir2 = dirs.pop(), deferred = false, files = fs50.readdirSync(dir2);
|
|
17837
17837
|
for (var i2 = 0, length = files.length; i2 < length; i2++) {
|
|
17838
|
-
var file2 =
|
|
17838
|
+
var file2 = path61.join(dir2, files[i2]), stat = fs50.lstatSync(file2);
|
|
17839
17839
|
if (stat.isDirectory()) {
|
|
17840
17840
|
if (!deferred) {
|
|
17841
17841
|
deferred = true;
|
|
@@ -17843,11 +17843,11 @@ var require_tmp = __commonJS({
|
|
|
17843
17843
|
}
|
|
17844
17844
|
dirs.push(file2);
|
|
17845
17845
|
} else {
|
|
17846
|
-
|
|
17846
|
+
fs50.unlinkSync(file2);
|
|
17847
17847
|
}
|
|
17848
17848
|
}
|
|
17849
17849
|
if (!deferred) {
|
|
17850
|
-
|
|
17850
|
+
fs50.rmdirSync(dir2);
|
|
17851
17851
|
}
|
|
17852
17852
|
} while (dirs.length !== 0);
|
|
17853
17853
|
}
|
|
@@ -17855,7 +17855,7 @@ var require_tmp = __commonJS({
|
|
|
17855
17855
|
var args = _parseArguments(options, callback), opts = args[0], cb = args[1];
|
|
17856
17856
|
tmpName(opts, function _tmpNameCreated(err, name) {
|
|
17857
17857
|
if (err) return cb(err);
|
|
17858
|
-
|
|
17858
|
+
fs50.mkdir(name, opts.mode || DIR_MODE, function _dirCreated(err2) {
|
|
17859
17859
|
if (err2) return cb(err2);
|
|
17860
17860
|
cb(null, name, _prepareTmpDirRemoveCallback(name, opts));
|
|
17861
17861
|
});
|
|
@@ -17864,7 +17864,7 @@ var require_tmp = __commonJS({
|
|
|
17864
17864
|
function dirSync(options) {
|
|
17865
17865
|
var args = _parseArguments(options), opts = args[0];
|
|
17866
17866
|
const name = tmpNameSync(opts);
|
|
17867
|
-
|
|
17867
|
+
fs50.mkdirSync(name, opts.mode || DIR_MODE);
|
|
17868
17868
|
return {
|
|
17869
17869
|
name,
|
|
17870
17870
|
removeCallback: _prepareTmpDirRemoveCallback(name, opts)
|
|
@@ -17874,7 +17874,7 @@ var require_tmp = __commonJS({
|
|
|
17874
17874
|
const removeCallback = _prepareRemoveCallback(function _removeCallback(fdPath) {
|
|
17875
17875
|
try {
|
|
17876
17876
|
if (0 <= fdPath[0]) {
|
|
17877
|
-
|
|
17877
|
+
fs50.closeSync(fdPath[0]);
|
|
17878
17878
|
}
|
|
17879
17879
|
} catch (e2) {
|
|
17880
17880
|
if (!isEBADF(e2) && !isENOENT(e2)) {
|
|
@@ -17882,7 +17882,7 @@ var require_tmp = __commonJS({
|
|
|
17882
17882
|
}
|
|
17883
17883
|
}
|
|
17884
17884
|
try {
|
|
17885
|
-
|
|
17885
|
+
fs50.unlinkSync(fdPath[1]);
|
|
17886
17886
|
} catch (e2) {
|
|
17887
17887
|
if (!isENOENT(e2)) {
|
|
17888
17888
|
throw e2;
|
|
@@ -17895,7 +17895,7 @@ var require_tmp = __commonJS({
|
|
|
17895
17895
|
return removeCallback;
|
|
17896
17896
|
}
|
|
17897
17897
|
function _prepareTmpDirRemoveCallback(name, opts) {
|
|
17898
|
-
const removeFunction = opts.unsafeCleanup ? _rmdirRecursiveSync :
|
|
17898
|
+
const removeFunction = opts.unsafeCleanup ? _rmdirRecursiveSync : fs50.rmdirSync.bind(fs50);
|
|
17899
17899
|
const removeCallback = _prepareRemoveCallback(removeFunction, name);
|
|
17900
17900
|
if (!opts.keep) {
|
|
17901
17901
|
_removeObjects.unshift(removeCallback);
|
|
@@ -19046,7 +19046,7 @@ var require_Observable = __commonJS({
|
|
|
19046
19046
|
Observable2.prototype.forEach = function(next, promiseCtor) {
|
|
19047
19047
|
var _this = this;
|
|
19048
19048
|
promiseCtor = getPromiseCtor(promiseCtor);
|
|
19049
|
-
return new promiseCtor(function(
|
|
19049
|
+
return new promiseCtor(function(resolve45, reject) {
|
|
19050
19050
|
var subscriber = new Subscriber_1.SafeSubscriber({
|
|
19051
19051
|
next: function(value) {
|
|
19052
19052
|
try {
|
|
@@ -19057,7 +19057,7 @@ var require_Observable = __commonJS({
|
|
|
19057
19057
|
}
|
|
19058
19058
|
},
|
|
19059
19059
|
error: reject,
|
|
19060
|
-
complete:
|
|
19060
|
+
complete: resolve45
|
|
19061
19061
|
});
|
|
19062
19062
|
_this.subscribe(subscriber);
|
|
19063
19063
|
});
|
|
@@ -19079,14 +19079,14 @@ var require_Observable = __commonJS({
|
|
|
19079
19079
|
Observable2.prototype.toPromise = function(promiseCtor) {
|
|
19080
19080
|
var _this = this;
|
|
19081
19081
|
promiseCtor = getPromiseCtor(promiseCtor);
|
|
19082
|
-
return new promiseCtor(function(
|
|
19082
|
+
return new promiseCtor(function(resolve45, reject) {
|
|
19083
19083
|
var value;
|
|
19084
19084
|
_this.subscribe(function(x2) {
|
|
19085
19085
|
return value = x2;
|
|
19086
19086
|
}, function(err) {
|
|
19087
19087
|
return reject(err);
|
|
19088
19088
|
}, function() {
|
|
19089
|
-
return
|
|
19089
|
+
return resolve45(value);
|
|
19090
19090
|
});
|
|
19091
19091
|
});
|
|
19092
19092
|
};
|
|
@@ -21182,11 +21182,11 @@ var require_innerFrom = __commonJS({
|
|
|
21182
21182
|
"use strict";
|
|
21183
21183
|
var __awaiter = exports2 && exports2.__awaiter || function(thisArg, _arguments, P3, generator) {
|
|
21184
21184
|
function adopt(value) {
|
|
21185
|
-
return value instanceof P3 ? value : new P3(function(
|
|
21186
|
-
|
|
21185
|
+
return value instanceof P3 ? value : new P3(function(resolve45) {
|
|
21186
|
+
resolve45(value);
|
|
21187
21187
|
});
|
|
21188
21188
|
}
|
|
21189
|
-
return new (P3 || (P3 = Promise))(function(
|
|
21189
|
+
return new (P3 || (P3 = Promise))(function(resolve45, reject) {
|
|
21190
21190
|
function fulfilled(value) {
|
|
21191
21191
|
try {
|
|
21192
21192
|
step(generator.next(value));
|
|
@@ -21202,7 +21202,7 @@ var require_innerFrom = __commonJS({
|
|
|
21202
21202
|
}
|
|
21203
21203
|
}
|
|
21204
21204
|
function step(result) {
|
|
21205
|
-
result.done ?
|
|
21205
|
+
result.done ? resolve45(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
21206
21206
|
}
|
|
21207
21207
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
21208
21208
|
});
|
|
@@ -21284,14 +21284,14 @@ var require_innerFrom = __commonJS({
|
|
|
21284
21284
|
}, i2);
|
|
21285
21285
|
function verb(n2) {
|
|
21286
21286
|
i2[n2] = o2[n2] && function(v3) {
|
|
21287
|
-
return new Promise(function(
|
|
21288
|
-
v3 = o2[n2](v3), settle(
|
|
21287
|
+
return new Promise(function(resolve45, reject) {
|
|
21288
|
+
v3 = o2[n2](v3), settle(resolve45, reject, v3.done, v3.value);
|
|
21289
21289
|
});
|
|
21290
21290
|
};
|
|
21291
21291
|
}
|
|
21292
|
-
function settle(
|
|
21292
|
+
function settle(resolve45, reject, d2, v3) {
|
|
21293
21293
|
Promise.resolve(v3).then(function(v4) {
|
|
21294
|
-
|
|
21294
|
+
resolve45({ value: v4, done: d2 });
|
|
21295
21295
|
}, reject);
|
|
21296
21296
|
}
|
|
21297
21297
|
};
|
|
@@ -21910,7 +21910,7 @@ var require_lastValueFrom = __commonJS({
|
|
|
21910
21910
|
var EmptyError_1 = require_EmptyError();
|
|
21911
21911
|
function lastValueFrom2(source, config2) {
|
|
21912
21912
|
var hasConfig = typeof config2 === "object";
|
|
21913
|
-
return new Promise(function(
|
|
21913
|
+
return new Promise(function(resolve45, reject) {
|
|
21914
21914
|
var _hasValue = false;
|
|
21915
21915
|
var _value;
|
|
21916
21916
|
source.subscribe({
|
|
@@ -21921,9 +21921,9 @@ var require_lastValueFrom = __commonJS({
|
|
|
21921
21921
|
error: reject,
|
|
21922
21922
|
complete: function() {
|
|
21923
21923
|
if (_hasValue) {
|
|
21924
|
-
|
|
21924
|
+
resolve45(_value);
|
|
21925
21925
|
} else if (hasConfig) {
|
|
21926
|
-
|
|
21926
|
+
resolve45(config2.defaultValue);
|
|
21927
21927
|
} else {
|
|
21928
21928
|
reject(new EmptyError_1.EmptyError());
|
|
21929
21929
|
}
|
|
@@ -21945,16 +21945,16 @@ var require_firstValueFrom = __commonJS({
|
|
|
21945
21945
|
var Subscriber_1 = require_Subscriber();
|
|
21946
21946
|
function firstValueFrom(source, config2) {
|
|
21947
21947
|
var hasConfig = typeof config2 === "object";
|
|
21948
|
-
return new Promise(function(
|
|
21948
|
+
return new Promise(function(resolve45, reject) {
|
|
21949
21949
|
var subscriber = new Subscriber_1.SafeSubscriber({
|
|
21950
21950
|
next: function(value) {
|
|
21951
|
-
|
|
21951
|
+
resolve45(value);
|
|
21952
21952
|
subscriber.unsubscribe();
|
|
21953
21953
|
},
|
|
21954
21954
|
error: reject,
|
|
21955
21955
|
complete: function() {
|
|
21956
21956
|
if (hasConfig) {
|
|
21957
|
-
|
|
21957
|
+
resolve45(config2.defaultValue);
|
|
21958
21958
|
} else {
|
|
21959
21959
|
reject(new EmptyError_1.EmptyError());
|
|
21960
21960
|
}
|
|
@@ -27747,14 +27747,14 @@ var require_run_async = __commonJS({
|
|
|
27747
27747
|
return function() {
|
|
27748
27748
|
var args = arguments;
|
|
27749
27749
|
var originalThis = this;
|
|
27750
|
-
var promise = new Promise(function(
|
|
27750
|
+
var promise = new Promise(function(resolve45, reject) {
|
|
27751
27751
|
var resolved = false;
|
|
27752
27752
|
const wrappedResolve = function(value) {
|
|
27753
27753
|
if (resolved) {
|
|
27754
27754
|
console.warn("Run-async promise already resolved.");
|
|
27755
27755
|
}
|
|
27756
27756
|
resolved = true;
|
|
27757
|
-
|
|
27757
|
+
resolve45(value);
|
|
27758
27758
|
};
|
|
27759
27759
|
var rejected = false;
|
|
27760
27760
|
const wrappedReject = function(value) {
|
|
@@ -30783,7 +30783,7 @@ var require_compile = __commonJS({
|
|
|
30783
30783
|
const schOrFunc = root.refs[ref];
|
|
30784
30784
|
if (schOrFunc)
|
|
30785
30785
|
return schOrFunc;
|
|
30786
|
-
let _sch =
|
|
30786
|
+
let _sch = resolve45.call(this, root, ref);
|
|
30787
30787
|
if (_sch === void 0) {
|
|
30788
30788
|
const schema = (_a3 = root.localRefs) === null || _a3 === void 0 ? void 0 : _a3[ref];
|
|
30789
30789
|
const { schemaId } = this.opts;
|
|
@@ -30810,7 +30810,7 @@ var require_compile = __commonJS({
|
|
|
30810
30810
|
function sameSchemaEnv(s1, s2) {
|
|
30811
30811
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
30812
30812
|
}
|
|
30813
|
-
function
|
|
30813
|
+
function resolve45(root, ref) {
|
|
30814
30814
|
let sch;
|
|
30815
30815
|
while (typeof (sch = this.refs[ref]) == "string")
|
|
30816
30816
|
ref = sch;
|
|
@@ -31028,8 +31028,8 @@ var require_utils2 = __commonJS({
|
|
|
31028
31028
|
}
|
|
31029
31029
|
return ind;
|
|
31030
31030
|
}
|
|
31031
|
-
function removeDotSegments(
|
|
31032
|
-
let input =
|
|
31031
|
+
function removeDotSegments(path61) {
|
|
31032
|
+
let input = path61;
|
|
31033
31033
|
const output = [];
|
|
31034
31034
|
let nextSlash = -1;
|
|
31035
31035
|
let len = 0;
|
|
@@ -31281,8 +31281,8 @@ var require_schemes = __commonJS({
|
|
|
31281
31281
|
wsComponent.secure = void 0;
|
|
31282
31282
|
}
|
|
31283
31283
|
if (wsComponent.resourceName) {
|
|
31284
|
-
const [
|
|
31285
|
-
wsComponent.path =
|
|
31284
|
+
const [path61, query] = wsComponent.resourceName.split("?");
|
|
31285
|
+
wsComponent.path = path61 && path61 !== "/" ? path61 : void 0;
|
|
31286
31286
|
wsComponent.query = query;
|
|
31287
31287
|
wsComponent.resourceName = void 0;
|
|
31288
31288
|
}
|
|
@@ -31441,7 +31441,7 @@ var require_fast_uri = __commonJS({
|
|
|
31441
31441
|
}
|
|
31442
31442
|
return uri;
|
|
31443
31443
|
}
|
|
31444
|
-
function
|
|
31444
|
+
function resolve45(baseURI, relativeURI, options) {
|
|
31445
31445
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
31446
31446
|
const resolved = resolveComponent(parse4(baseURI, schemelessOptions), parse4(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
31447
31447
|
schemelessOptions.skipEscape = true;
|
|
@@ -31699,7 +31699,7 @@ var require_fast_uri = __commonJS({
|
|
|
31699
31699
|
var fastUri = {
|
|
31700
31700
|
SCHEMES,
|
|
31701
31701
|
normalize: normalize3,
|
|
31702
|
-
resolve:
|
|
31702
|
+
resolve: resolve45,
|
|
31703
31703
|
resolveComponent,
|
|
31704
31704
|
equal,
|
|
31705
31705
|
serialize,
|
|
@@ -34675,12 +34675,12 @@ var require_dist = __commonJS({
|
|
|
34675
34675
|
throw new Error(`Unknown format "${name}"`);
|
|
34676
34676
|
return f2;
|
|
34677
34677
|
};
|
|
34678
|
-
function addFormats(ajv, list,
|
|
34678
|
+
function addFormats(ajv, list, fs50, exportName) {
|
|
34679
34679
|
var _a3;
|
|
34680
34680
|
var _b2;
|
|
34681
34681
|
(_a3 = (_b2 = ajv.opts.code).formats) !== null && _a3 !== void 0 ? _a3 : _b2.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
|
|
34682
34682
|
for (const f2 of list)
|
|
34683
|
-
ajv.addFormat(f2,
|
|
34683
|
+
ajv.addFormat(f2, fs50[f2]);
|
|
34684
34684
|
}
|
|
34685
34685
|
module2.exports = exports2 = formatsPlugin;
|
|
34686
34686
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -35964,11 +35964,11 @@ var parser = new YargsParser({
|
|
|
35964
35964
|
resolve: import_path2.resolve,
|
|
35965
35965
|
// TODO: figure out a way to combine ESM and CJS coverage, such that
|
|
35966
35966
|
// we can exercise all the lines below:
|
|
35967
|
-
require: (
|
|
35967
|
+
require: (path61) => {
|
|
35968
35968
|
if (typeof require !== "undefined") {
|
|
35969
|
-
return require(
|
|
35970
|
-
} else if (
|
|
35971
|
-
return JSON.parse((0, import_fs2.readFileSync)(
|
|
35969
|
+
return require(path61);
|
|
35970
|
+
} else if (path61.match(/\.json$/)) {
|
|
35971
|
+
return JSON.parse((0, import_fs2.readFileSync)(path61, "utf8"));
|
|
35972
35972
|
} else {
|
|
35973
35973
|
throw Error("only .json config files are supported in ESM");
|
|
35974
35974
|
}
|
|
@@ -38494,12 +38494,12 @@ var YargsInstance = class {
|
|
|
38494
38494
|
async getCompletion(args, done) {
|
|
38495
38495
|
argsert("<array> [function]", [args, done], arguments.length);
|
|
38496
38496
|
if (!done) {
|
|
38497
|
-
return new Promise((
|
|
38497
|
+
return new Promise((resolve45, reject) => {
|
|
38498
38498
|
__classPrivateFieldGet(this, _YargsInstance_completion, "f").getCompletion(args, (err, completions) => {
|
|
38499
38499
|
if (err)
|
|
38500
38500
|
reject(err);
|
|
38501
38501
|
else
|
|
38502
|
-
|
|
38502
|
+
resolve45(completions);
|
|
38503
38503
|
});
|
|
38504
38504
|
});
|
|
38505
38505
|
} else {
|
|
@@ -40652,8 +40652,8 @@ function getErrorMap() {
|
|
|
40652
40652
|
|
|
40653
40653
|
// node_modules/zod/v3/helpers/parseUtil.js
|
|
40654
40654
|
var makeIssue = (params) => {
|
|
40655
|
-
const { data, path:
|
|
40656
|
-
const fullPath = [...
|
|
40655
|
+
const { data, path: path61, errorMaps, issueData } = params;
|
|
40656
|
+
const fullPath = [...path61, ...issueData.path || []];
|
|
40657
40657
|
const fullIssue = {
|
|
40658
40658
|
...issueData,
|
|
40659
40659
|
path: fullPath
|
|
@@ -40769,11 +40769,11 @@ var errorUtil;
|
|
|
40769
40769
|
|
|
40770
40770
|
// node_modules/zod/v3/types.js
|
|
40771
40771
|
var ParseInputLazyPath = class {
|
|
40772
|
-
constructor(parent, value,
|
|
40772
|
+
constructor(parent, value, path61, key) {
|
|
40773
40773
|
this._cachedPath = [];
|
|
40774
40774
|
this.parent = parent;
|
|
40775
40775
|
this.data = value;
|
|
40776
|
-
this._path =
|
|
40776
|
+
this._path = path61;
|
|
40777
40777
|
this._key = key;
|
|
40778
40778
|
}
|
|
40779
40779
|
get path() {
|
|
@@ -68312,16 +68312,16 @@ async function handleAgentSkills(options) {
|
|
|
68312
68312
|
}
|
|
68313
68313
|
async function askYesNo(question) {
|
|
68314
68314
|
const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
|
|
68315
|
-
return new Promise((
|
|
68315
|
+
return new Promise((resolve45) => {
|
|
68316
68316
|
process.stderr.write(`${question} `);
|
|
68317
68317
|
rl.once("line", (answer) => {
|
|
68318
68318
|
rl.close();
|
|
68319
68319
|
const trimmed = answer.trim();
|
|
68320
68320
|
if (trimmed === "") {
|
|
68321
|
-
|
|
68321
|
+
resolve45(true);
|
|
68322
68322
|
return;
|
|
68323
68323
|
}
|
|
68324
|
-
|
|
68324
|
+
resolve45(/^y(es)?$/i.test(trimmed));
|
|
68325
68325
|
});
|
|
68326
68326
|
});
|
|
68327
68327
|
}
|
|
@@ -68400,11 +68400,11 @@ function handleRemove(argv) {
|
|
|
68400
68400
|
}
|
|
68401
68401
|
|
|
68402
68402
|
// src/cli/commands/env.ts
|
|
68403
|
-
var
|
|
68403
|
+
var path50 = __toESM(require("path"));
|
|
68404
68404
|
|
|
68405
68405
|
// src/core/harness.ts
|
|
68406
|
-
var
|
|
68407
|
-
var
|
|
68406
|
+
var fs22 = __toESM(require("fs"));
|
|
68407
|
+
var path21 = __toESM(require("path"));
|
|
68408
68408
|
|
|
68409
68409
|
// src/harness/generator.ts
|
|
68410
68410
|
var fs11 = __toESM(require("fs"));
|
|
@@ -69179,13 +69179,13 @@ var MultipartBody = class {
|
|
|
69179
69179
|
// node_modules/@anthropic-ai/sdk/_shims/node-runtime.mjs
|
|
69180
69180
|
var import_web = require("node:stream/web");
|
|
69181
69181
|
var fileFromPathWarned = false;
|
|
69182
|
-
async function fileFromPath3(
|
|
69182
|
+
async function fileFromPath3(path61, ...args) {
|
|
69183
69183
|
const { fileFromPath: _fileFromPath } = await Promise.resolve().then(() => (init_fileFromPath(), fileFromPath_exports));
|
|
69184
69184
|
if (!fileFromPathWarned) {
|
|
69185
|
-
console.warn(`fileFromPath is deprecated; use fs.createReadStream(${JSON.stringify(
|
|
69185
|
+
console.warn(`fileFromPath is deprecated; use fs.createReadStream(${JSON.stringify(path61)}) instead`);
|
|
69186
69186
|
fileFromPathWarned = true;
|
|
69187
69187
|
}
|
|
69188
|
-
return await _fileFromPath(
|
|
69188
|
+
return await _fileFromPath(path61, ...args);
|
|
69189
69189
|
}
|
|
69190
69190
|
var defaultHttpAgent = new import_agentkeepalive.default({ keepAlive: true, timeout: 5 * 60 * 1e3 });
|
|
69191
69191
|
var defaultHttpsAgent = new import_agentkeepalive.default.HttpsAgent({ keepAlive: true, timeout: 5 * 60 * 1e3 });
|
|
@@ -69681,8 +69681,8 @@ async function defaultParseResponse(props) {
|
|
|
69681
69681
|
}
|
|
69682
69682
|
var APIPromise = class _APIPromise extends Promise {
|
|
69683
69683
|
constructor(responsePromise, parseResponse = defaultParseResponse) {
|
|
69684
|
-
super((
|
|
69685
|
-
|
|
69684
|
+
super((resolve45) => {
|
|
69685
|
+
resolve45(null);
|
|
69686
69686
|
});
|
|
69687
69687
|
this.responsePromise = responsePromise;
|
|
69688
69688
|
this.parseResponse = parseResponse;
|
|
@@ -69782,29 +69782,29 @@ var APIClient = class {
|
|
|
69782
69782
|
defaultIdempotencyKey() {
|
|
69783
69783
|
return `stainless-node-retry-${uuid4()}`;
|
|
69784
69784
|
}
|
|
69785
|
-
get(
|
|
69786
|
-
return this.methodRequest("get",
|
|
69785
|
+
get(path61, opts) {
|
|
69786
|
+
return this.methodRequest("get", path61, opts);
|
|
69787
69787
|
}
|
|
69788
|
-
post(
|
|
69789
|
-
return this.methodRequest("post",
|
|
69788
|
+
post(path61, opts) {
|
|
69789
|
+
return this.methodRequest("post", path61, opts);
|
|
69790
69790
|
}
|
|
69791
|
-
patch(
|
|
69792
|
-
return this.methodRequest("patch",
|
|
69791
|
+
patch(path61, opts) {
|
|
69792
|
+
return this.methodRequest("patch", path61, opts);
|
|
69793
69793
|
}
|
|
69794
|
-
put(
|
|
69795
|
-
return this.methodRequest("put",
|
|
69794
|
+
put(path61, opts) {
|
|
69795
|
+
return this.methodRequest("put", path61, opts);
|
|
69796
69796
|
}
|
|
69797
|
-
delete(
|
|
69798
|
-
return this.methodRequest("delete",
|
|
69797
|
+
delete(path61, opts) {
|
|
69798
|
+
return this.methodRequest("delete", path61, opts);
|
|
69799
69799
|
}
|
|
69800
|
-
methodRequest(method,
|
|
69800
|
+
methodRequest(method, path61, opts) {
|
|
69801
69801
|
return this.request(Promise.resolve(opts).then(async (opts2) => {
|
|
69802
69802
|
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;
|
|
69803
|
-
return { method, path:
|
|
69803
|
+
return { method, path: path61, ...opts2, body };
|
|
69804
69804
|
}));
|
|
69805
69805
|
}
|
|
69806
|
-
getAPIList(
|
|
69807
|
-
return this.requestAPIList(Page, { method: "get", path:
|
|
69806
|
+
getAPIList(path61, Page, opts) {
|
|
69807
|
+
return this.requestAPIList(Page, { method: "get", path: path61, ...opts });
|
|
69808
69808
|
}
|
|
69809
69809
|
calculateContentLength(body) {
|
|
69810
69810
|
if (typeof body === "string") {
|
|
@@ -69822,10 +69822,10 @@ var APIClient = class {
|
|
|
69822
69822
|
return null;
|
|
69823
69823
|
}
|
|
69824
69824
|
buildRequest(options) {
|
|
69825
|
-
const { method, path:
|
|
69825
|
+
const { method, path: path61, query, headers = {} } = options;
|
|
69826
69826
|
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;
|
|
69827
69827
|
const contentLength = this.calculateContentLength(body);
|
|
69828
|
-
const url = this.buildURL(
|
|
69828
|
+
const url = this.buildURL(path61, query);
|
|
69829
69829
|
if ("timeout" in options)
|
|
69830
69830
|
validatePositiveInteger("timeout", options.timeout);
|
|
69831
69831
|
const timeout = options.timeout ?? this.timeout;
|
|
@@ -69934,8 +69934,8 @@ var APIClient = class {
|
|
|
69934
69934
|
const request = this.makeRequest(options, null);
|
|
69935
69935
|
return new PagePromise(this, request, Page);
|
|
69936
69936
|
}
|
|
69937
|
-
buildURL(
|
|
69938
|
-
const url = isAbsoluteURL(
|
|
69937
|
+
buildURL(path61, query) {
|
|
69938
|
+
const url = isAbsoluteURL(path61) ? new URL(path61) : new URL(this.baseURL + (this.baseURL.endsWith("/") && path61.startsWith("/") ? path61.slice(1) : path61));
|
|
69939
69939
|
const defaultQuery = this.defaultQuery();
|
|
69940
69940
|
if (!isEmptyObj(defaultQuery)) {
|
|
69941
69941
|
query = { ...defaultQuery, ...query };
|
|
@@ -70220,7 +70220,7 @@ var startsWithSchemeRegexp = new RegExp("^(?:[a-z]+:)?//", "i");
|
|
|
70220
70220
|
var isAbsoluteURL = (url) => {
|
|
70221
70221
|
return startsWithSchemeRegexp.test(url);
|
|
70222
70222
|
};
|
|
70223
|
-
var sleep = (ms) => new Promise((
|
|
70223
|
+
var sleep = (ms) => new Promise((resolve45) => setTimeout(resolve45, ms));
|
|
70224
70224
|
var validatePositiveInteger = (name, n2) => {
|
|
70225
70225
|
if (typeof n2 !== "number" || !Number.isInteger(n2)) {
|
|
70226
70226
|
throw new AnthropicError(`${name} must be an integer`);
|
|
@@ -70711,12 +70711,12 @@ var PromptCachingBetaMessageStream = class _PromptCachingBetaMessageStream {
|
|
|
70711
70711
|
}
|
|
70712
70712
|
return this._emit("error", new AnthropicError(String(error3)));
|
|
70713
70713
|
});
|
|
70714
|
-
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_connectedPromise, new Promise((
|
|
70715
|
-
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_resolveConnectedPromise,
|
|
70714
|
+
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_connectedPromise, new Promise((resolve45, reject) => {
|
|
70715
|
+
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_resolveConnectedPromise, resolve45, "f");
|
|
70716
70716
|
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_rejectConnectedPromise, reject, "f");
|
|
70717
70717
|
}), "f");
|
|
70718
|
-
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_endPromise, new Promise((
|
|
70719
|
-
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_resolveEndPromise,
|
|
70718
|
+
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_endPromise, new Promise((resolve45, reject) => {
|
|
70719
|
+
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_resolveEndPromise, resolve45, "f");
|
|
70720
70720
|
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_rejectEndPromise, reject, "f");
|
|
70721
70721
|
}), "f");
|
|
70722
70722
|
__classPrivateFieldGet8(this, _PromptCachingBetaMessageStream_connectedPromise, "f").catch(() => {
|
|
@@ -70845,11 +70845,11 @@ var PromptCachingBetaMessageStream = class _PromptCachingBetaMessageStream {
|
|
|
70845
70845
|
* const message = await stream.emitted('message') // rejects if the stream errors
|
|
70846
70846
|
*/
|
|
70847
70847
|
emitted(event) {
|
|
70848
|
-
return new Promise((
|
|
70848
|
+
return new Promise((resolve45, reject) => {
|
|
70849
70849
|
__classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_catchingPromiseCreated, true, "f");
|
|
70850
70850
|
if (event !== "error")
|
|
70851
70851
|
this.once("error", reject);
|
|
70852
|
-
this.once(event,
|
|
70852
|
+
this.once(event, resolve45);
|
|
70853
70853
|
});
|
|
70854
70854
|
}
|
|
70855
70855
|
async done() {
|
|
@@ -71076,7 +71076,7 @@ var PromptCachingBetaMessageStream = class _PromptCachingBetaMessageStream {
|
|
|
71076
71076
|
if (done) {
|
|
71077
71077
|
return { value: void 0, done: true };
|
|
71078
71078
|
}
|
|
71079
|
-
return new Promise((
|
|
71079
|
+
return new Promise((resolve45, reject) => readQueue.push({ resolve: resolve45, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
|
|
71080
71080
|
}
|
|
71081
71081
|
const chunk = pushQueue.shift();
|
|
71082
71082
|
return { value: chunk, done: false };
|
|
@@ -71224,12 +71224,12 @@ var MessageStream = class _MessageStream {
|
|
|
71224
71224
|
}
|
|
71225
71225
|
return this._emit("error", new AnthropicError(String(error3)));
|
|
71226
71226
|
});
|
|
71227
|
-
__classPrivateFieldSet8(this, _MessageStream_connectedPromise, new Promise((
|
|
71228
|
-
__classPrivateFieldSet8(this, _MessageStream_resolveConnectedPromise,
|
|
71227
|
+
__classPrivateFieldSet8(this, _MessageStream_connectedPromise, new Promise((resolve45, reject) => {
|
|
71228
|
+
__classPrivateFieldSet8(this, _MessageStream_resolveConnectedPromise, resolve45, "f");
|
|
71229
71229
|
__classPrivateFieldSet8(this, _MessageStream_rejectConnectedPromise, reject, "f");
|
|
71230
71230
|
}), "f");
|
|
71231
|
-
__classPrivateFieldSet8(this, _MessageStream_endPromise, new Promise((
|
|
71232
|
-
__classPrivateFieldSet8(this, _MessageStream_resolveEndPromise,
|
|
71231
|
+
__classPrivateFieldSet8(this, _MessageStream_endPromise, new Promise((resolve45, reject) => {
|
|
71232
|
+
__classPrivateFieldSet8(this, _MessageStream_resolveEndPromise, resolve45, "f");
|
|
71233
71233
|
__classPrivateFieldSet8(this, _MessageStream_rejectEndPromise, reject, "f");
|
|
71234
71234
|
}), "f");
|
|
71235
71235
|
__classPrivateFieldGet9(this, _MessageStream_connectedPromise, "f").catch(() => {
|
|
@@ -71358,11 +71358,11 @@ var MessageStream = class _MessageStream {
|
|
|
71358
71358
|
* const message = await stream.emitted('message') // rejects if the stream errors
|
|
71359
71359
|
*/
|
|
71360
71360
|
emitted(event) {
|
|
71361
|
-
return new Promise((
|
|
71361
|
+
return new Promise((resolve45, reject) => {
|
|
71362
71362
|
__classPrivateFieldSet8(this, _MessageStream_catchingPromiseCreated, true, "f");
|
|
71363
71363
|
if (event !== "error")
|
|
71364
71364
|
this.once("error", reject);
|
|
71365
|
-
this.once(event,
|
|
71365
|
+
this.once(event, resolve45);
|
|
71366
71366
|
});
|
|
71367
71367
|
}
|
|
71368
71368
|
async done() {
|
|
@@ -71589,7 +71589,7 @@ var MessageStream = class _MessageStream {
|
|
|
71589
71589
|
if (done) {
|
|
71590
71590
|
return { value: void 0, done: true };
|
|
71591
71591
|
}
|
|
71592
|
-
return new Promise((
|
|
71592
|
+
return new Promise((resolve45, reject) => readQueue.push({ resolve: resolve45, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
|
|
71593
71593
|
}
|
|
71594
71594
|
const chunk = pushQueue.shift();
|
|
71595
71595
|
return { value: chunk, done: false };
|
|
@@ -71849,11 +71849,11 @@ async function promptApplyAgentMdProposal(repoPath) {
|
|
|
71849
71849
|
}
|
|
71850
71850
|
async function askYesNo2(question) {
|
|
71851
71851
|
const rl = readline2.createInterface({ input: process.stdin, output: process.stderr });
|
|
71852
|
-
return new Promise((
|
|
71852
|
+
return new Promise((resolve45) => {
|
|
71853
71853
|
process.stderr.write(`${question} `);
|
|
71854
71854
|
rl.once("line", (answer) => {
|
|
71855
71855
|
rl.close();
|
|
71856
|
-
|
|
71856
|
+
resolve45(/^y(es)?$/i.test(answer.trim()));
|
|
71857
71857
|
});
|
|
71858
71858
|
});
|
|
71859
71859
|
}
|
|
@@ -72083,7 +72083,7 @@ async function executeAuthoringToolCall(toolName, input, repoPath, harnessDir, c
|
|
|
72083
72083
|
}
|
|
72084
72084
|
async function askUser(question, options) {
|
|
72085
72085
|
const rl = readline3.createInterface({ input: process.stdin, output: process.stderr });
|
|
72086
|
-
return new Promise((
|
|
72086
|
+
return new Promise((resolve45) => {
|
|
72087
72087
|
process.stderr.write("\n");
|
|
72088
72088
|
process.stderr.write(`\u2753 ${question}
|
|
72089
72089
|
`);
|
|
@@ -72094,7 +72094,7 @@ async function askUser(question, options) {
|
|
|
72094
72094
|
process.stderr.write("> ");
|
|
72095
72095
|
rl.once("line", (answer) => {
|
|
72096
72096
|
rl.close();
|
|
72097
|
-
|
|
72097
|
+
resolve45(answer.trim());
|
|
72098
72098
|
});
|
|
72099
72099
|
});
|
|
72100
72100
|
}
|
|
@@ -72238,7 +72238,7 @@ function runScript(scriptPath, args = [], options = {}) {
|
|
|
72238
72238
|
function runScriptCapture(scriptPath, args = [], options = {}) {
|
|
72239
72239
|
const stream = options.stream ?? false;
|
|
72240
72240
|
const { stream: _stream, ...spawnOptions } = options;
|
|
72241
|
-
return new Promise((
|
|
72241
|
+
return new Promise((resolve45) => {
|
|
72242
72242
|
const proc = (0, import_child_process.spawn)("bash", [scriptPath, ...args], {
|
|
72243
72243
|
...spawnOptions,
|
|
72244
72244
|
stdio: ["inherit", "pipe", "pipe"]
|
|
@@ -72253,13 +72253,13 @@ function runScriptCapture(scriptPath, args = [], options = {}) {
|
|
|
72253
72253
|
stderr += d2;
|
|
72254
72254
|
if (stream) process.stderr.write(d2);
|
|
72255
72255
|
});
|
|
72256
|
-
proc.on("close", (code) =>
|
|
72256
|
+
proc.on("close", (code) => resolve45({ stdout, stderr, code: code ?? 0 }));
|
|
72257
72257
|
});
|
|
72258
72258
|
}
|
|
72259
72259
|
function runShellCommand(command2, options = {}) {
|
|
72260
72260
|
const stream = options.stream ?? false;
|
|
72261
72261
|
const { stream: _stream, ...spawnOptions } = options;
|
|
72262
|
-
return new Promise((
|
|
72262
|
+
return new Promise((resolve45) => {
|
|
72263
72263
|
const proc = (0, import_child_process.spawn)("bash", ["-lc", command2], {
|
|
72264
72264
|
...spawnOptions,
|
|
72265
72265
|
stdio: ["inherit", "pipe", "pipe"]
|
|
@@ -72274,7 +72274,7 @@ function runShellCommand(command2, options = {}) {
|
|
|
72274
72274
|
stderr += d2;
|
|
72275
72275
|
if (stream) process.stderr.write(d2);
|
|
72276
72276
|
});
|
|
72277
|
-
proc.on("close", (code) =>
|
|
72277
|
+
proc.on("close", (code) => resolve45({ stdout, stderr, code: code ?? 0 }));
|
|
72278
72278
|
});
|
|
72279
72279
|
}
|
|
72280
72280
|
|
|
@@ -72576,9 +72576,406 @@ function compareHarnessToTemplate(repoPath) {
|
|
|
72576
72576
|
}
|
|
72577
72577
|
|
|
72578
72578
|
// src/harness/maintain-bundle.ts
|
|
72579
|
-
var
|
|
72579
|
+
var fs21 = __toESM(require("fs"));
|
|
72580
72580
|
var os4 = __toESM(require("os"));
|
|
72581
|
+
var path20 = __toESM(require("path"));
|
|
72582
|
+
|
|
72583
|
+
// src/harness/plugin-drift.ts
|
|
72584
|
+
var fs20 = __toESM(require("fs"));
|
|
72585
|
+
var path19 = __toESM(require("path"));
|
|
72586
|
+
|
|
72587
|
+
// src/harness/plugins.ts
|
|
72588
|
+
var fs19 = __toESM(require("fs"));
|
|
72581
72589
|
var path18 = __toESM(require("path"));
|
|
72590
|
+
|
|
72591
|
+
// src/harness/parser.ts
|
|
72592
|
+
var fs18 = __toESM(require("fs"));
|
|
72593
|
+
function harnessExists(repoPath) {
|
|
72594
|
+
return fs18.existsSync(`${repoPath}/.har/setup-infra.sh`);
|
|
72595
|
+
}
|
|
72596
|
+
|
|
72597
|
+
// src/harness/plugins.ts
|
|
72598
|
+
var PLUGIN_IDS = ["playwright", "rocketsim"];
|
|
72599
|
+
var PluginManifestFileSchema = external_exports.object({
|
|
72600
|
+
src: external_exports.string().min(1),
|
|
72601
|
+
dest: external_exports.string().min(1),
|
|
72602
|
+
executable: external_exports.boolean().optional(),
|
|
72603
|
+
skipFlag: external_exports.string().optional()
|
|
72604
|
+
});
|
|
72605
|
+
var PluginManifestSchema = external_exports.object({
|
|
72606
|
+
id: external_exports.enum(PLUGIN_IDS),
|
|
72607
|
+
stageId: external_exports.string().min(1),
|
|
72608
|
+
verificationStages: external_exports.array(external_exports.string().min(1)).min(1),
|
|
72609
|
+
stage: external_exports.record(external_exports.unknown()),
|
|
72610
|
+
files: external_exports.array(PluginManifestFileSchema).min(1),
|
|
72611
|
+
optionalFiles: external_exports.array(PluginManifestFileSchema).optional(),
|
|
72612
|
+
merge: external_exports.record(external_exports.string()).optional(),
|
|
72613
|
+
nextSteps: external_exports.array(external_exports.string().min(1)).min(1),
|
|
72614
|
+
docsPath: external_exports.string().min(1)
|
|
72615
|
+
});
|
|
72616
|
+
function resolvePluginDir(pluginId) {
|
|
72617
|
+
const dir = path18.join(resolveTemplatesDir(), "plugins", pluginId);
|
|
72618
|
+
if (!fs19.existsSync(dir)) {
|
|
72619
|
+
throw new Error(`Plugin not found: ${pluginId}. Run npm run build.`);
|
|
72620
|
+
}
|
|
72621
|
+
return dir;
|
|
72622
|
+
}
|
|
72623
|
+
function readPluginManifest(pluginId) {
|
|
72624
|
+
const manifestPath = path18.join(resolvePluginDir(pluginId), "template.manifest.json");
|
|
72625
|
+
const parsed = PluginManifestSchema.safeParse(
|
|
72626
|
+
JSON.parse(fs19.readFileSync(manifestPath, "utf8"))
|
|
72627
|
+
);
|
|
72628
|
+
if (!parsed.success) {
|
|
72629
|
+
throw new Error(`Invalid plugin manifest for ${pluginId}: ${parsed.error.message}`);
|
|
72630
|
+
}
|
|
72631
|
+
if (parsed.data.id !== pluginId) {
|
|
72632
|
+
throw new Error(`Plugin manifest id mismatch: expected ${pluginId}, got ${parsed.data.id}`);
|
|
72633
|
+
}
|
|
72634
|
+
return parsed.data;
|
|
72635
|
+
}
|
|
72636
|
+
function ensureParentDir(filePath) {
|
|
72637
|
+
const parent = path18.dirname(filePath);
|
|
72638
|
+
if (!fs19.existsSync(parent)) {
|
|
72639
|
+
fs19.mkdirSync(parent, { recursive: true });
|
|
72640
|
+
}
|
|
72641
|
+
}
|
|
72642
|
+
function copyPluginFile(pluginDir, file, repoPath, force) {
|
|
72643
|
+
const srcPath = path18.join(pluginDir, file.src);
|
|
72644
|
+
const destPath = path18.join(repoPath, file.dest);
|
|
72645
|
+
if (!fs19.existsSync(srcPath)) {
|
|
72646
|
+
throw new Error(`Plugin file missing: ${file.src}`);
|
|
72647
|
+
}
|
|
72648
|
+
if (fs19.existsSync(destPath) && !force) {
|
|
72649
|
+
throw new Error(
|
|
72650
|
+
`File already exists: ${file.dest}. Use --force to overwrite or remove it first.`
|
|
72651
|
+
);
|
|
72652
|
+
}
|
|
72653
|
+
ensureParentDir(destPath);
|
|
72654
|
+
fs19.copyFileSync(srcPath, destPath);
|
|
72655
|
+
if (file.executable) {
|
|
72656
|
+
fs19.chmodSync(destPath, 493);
|
|
72657
|
+
}
|
|
72658
|
+
return { written: true, path: file.dest };
|
|
72659
|
+
}
|
|
72660
|
+
function mergePackageJson(repoPath, pluginDir, fragmentRelPath, warnings) {
|
|
72661
|
+
const packagePath = path18.join(repoPath, "package.json");
|
|
72662
|
+
if (!fs19.existsSync(packagePath)) {
|
|
72663
|
+
throw new Error("No package.json in repo root. Add one before applying this plugin.");
|
|
72664
|
+
}
|
|
72665
|
+
const fragmentPath = path18.join(pluginDir, fragmentRelPath);
|
|
72666
|
+
if (!fs19.existsSync(fragmentPath)) {
|
|
72667
|
+
throw new Error(`Package fragment missing: ${fragmentRelPath}`);
|
|
72668
|
+
}
|
|
72669
|
+
const pkg = JSON.parse(fs19.readFileSync(packagePath, "utf8"));
|
|
72670
|
+
const fragment = JSON.parse(fs19.readFileSync(fragmentPath, "utf8"));
|
|
72671
|
+
for (const section of ["scripts", "devDependencies"]) {
|
|
72672
|
+
const existing = pkg[section] ?? {};
|
|
72673
|
+
const incoming = fragment[section] ?? {};
|
|
72674
|
+
for (const [key, value] of Object.entries(incoming)) {
|
|
72675
|
+
if (existing[key] !== void 0 && existing[key] !== value) {
|
|
72676
|
+
warnings.push(`package.json ${section}.${key} already set \u2014 kept existing value`);
|
|
72677
|
+
continue;
|
|
72678
|
+
}
|
|
72679
|
+
existing[key] = value;
|
|
72680
|
+
}
|
|
72681
|
+
pkg[section] = existing;
|
|
72682
|
+
}
|
|
72683
|
+
fs19.writeFileSync(packagePath, JSON.stringify(pkg, null, 2) + "\n");
|
|
72684
|
+
}
|
|
72685
|
+
function patchStageRegistry(repoPath, manifest, force) {
|
|
72686
|
+
const registry2 = readStageRegistry(repoPath);
|
|
72687
|
+
const stage = HarnessStageSchema.parse(manifest.stage);
|
|
72688
|
+
const existing = registry2.stages.find((s2) => s2.id === stage.id);
|
|
72689
|
+
if (existing && !force) {
|
|
72690
|
+
throw new Error(
|
|
72691
|
+
`Stage "${stage.id}" already registered in .har/stages.json. Use --force to replace.`
|
|
72692
|
+
);
|
|
72693
|
+
}
|
|
72694
|
+
const stages = existing ? registry2.stages.map((s2) => s2.id === stage.id ? stage : s2) : [...registry2.stages, stage];
|
|
72695
|
+
const verificationStages = [...registry2.verificationStages ?? []];
|
|
72696
|
+
for (const id of manifest.verificationStages) {
|
|
72697
|
+
if (!verificationStages.includes(id)) {
|
|
72698
|
+
verificationStages.push(id);
|
|
72699
|
+
}
|
|
72700
|
+
}
|
|
72701
|
+
const verifyIdx = stages.findIndex((s2) => s2.id === "verify");
|
|
72702
|
+
if (verifyIdx >= 0) {
|
|
72703
|
+
stages[verifyIdx] = {
|
|
72704
|
+
...stages[verifyIdx],
|
|
72705
|
+
description: `Verification pipeline (quick smoke by default; --full runs the registry's verificationStages: ${verificationStages.join(", ")})`,
|
|
72706
|
+
acceptsArgs: ["--full"]
|
|
72707
|
+
};
|
|
72708
|
+
}
|
|
72709
|
+
const updated = {
|
|
72710
|
+
...registry2,
|
|
72711
|
+
stages,
|
|
72712
|
+
verificationStages
|
|
72713
|
+
};
|
|
72714
|
+
writeStageRegistry(repoPath, updated);
|
|
72715
|
+
}
|
|
72716
|
+
function assertHarnessPresent(repoPath) {
|
|
72717
|
+
if (!harnessExists(repoPath)) {
|
|
72718
|
+
throw new Error('No .har/ harness found. Run "har env init" first.');
|
|
72719
|
+
}
|
|
72720
|
+
}
|
|
72721
|
+
function assertStageNotPresent(repoPath, stageId, force) {
|
|
72722
|
+
if (force) return;
|
|
72723
|
+
const scriptPath = path18.join(repoPath, ".har", "stages", `${stageId}.sh`);
|
|
72724
|
+
if (fs19.existsSync(scriptPath)) {
|
|
72725
|
+
throw new Error(
|
|
72726
|
+
`Stage script already exists: .har/stages/${stageId}.sh. Use --force to overwrite.`
|
|
72727
|
+
);
|
|
72728
|
+
}
|
|
72729
|
+
const registry2 = readStageRegistry(repoPath);
|
|
72730
|
+
if (registry2.stages.some((s2) => s2.id === stageId)) {
|
|
72731
|
+
throw new Error(
|
|
72732
|
+
`Stage "${stageId}" already registered in .har/stages.json. Use --force to replace.`
|
|
72733
|
+
);
|
|
72734
|
+
}
|
|
72735
|
+
}
|
|
72736
|
+
function applyPlugin(repoPath, pluginId, options = {}) {
|
|
72737
|
+
const resolved = path18.resolve(repoPath);
|
|
72738
|
+
const force = options.force ?? false;
|
|
72739
|
+
const warnings = [];
|
|
72740
|
+
const filesWritten = [];
|
|
72741
|
+
assertHarnessPresent(resolved);
|
|
72742
|
+
const manifest = readPluginManifest(pluginId);
|
|
72743
|
+
assertStageNotPresent(resolved, manifest.stageId, force);
|
|
72744
|
+
const pluginDir = resolvePluginDir(pluginId);
|
|
72745
|
+
for (const file of manifest.files) {
|
|
72746
|
+
const result = copyPluginFile(pluginDir, file, resolved, force);
|
|
72747
|
+
if (result.written) {
|
|
72748
|
+
filesWritten.push(result.path);
|
|
72749
|
+
}
|
|
72750
|
+
}
|
|
72751
|
+
if (manifest.optionalFiles) {
|
|
72752
|
+
for (const file of manifest.optionalFiles) {
|
|
72753
|
+
if (file.skipFlag === "skipCi" && options.skipCi) {
|
|
72754
|
+
continue;
|
|
72755
|
+
}
|
|
72756
|
+
if (fs19.existsSync(path18.join(resolved, file.dest)) && !force) {
|
|
72757
|
+
warnings.push(`Skipped optional file (exists): ${file.dest}`);
|
|
72758
|
+
continue;
|
|
72759
|
+
}
|
|
72760
|
+
const result = copyPluginFile(pluginDir, file, resolved, force);
|
|
72761
|
+
if (result.written) {
|
|
72762
|
+
filesWritten.push(result.path);
|
|
72763
|
+
}
|
|
72764
|
+
}
|
|
72765
|
+
}
|
|
72766
|
+
if (manifest.merge) {
|
|
72767
|
+
for (const fragmentRel of Object.values(manifest.merge)) {
|
|
72768
|
+
mergePackageJson(resolved, pluginDir, fragmentRel, warnings);
|
|
72769
|
+
filesWritten.push("package.json");
|
|
72770
|
+
}
|
|
72771
|
+
}
|
|
72772
|
+
patchStageRegistry(resolved, manifest, force);
|
|
72773
|
+
success(`Applied plugin: ${pluginId}`);
|
|
72774
|
+
info(`Registered stage: ${manifest.stageId}`);
|
|
72775
|
+
for (const file of filesWritten) {
|
|
72776
|
+
info(` + ${file}`);
|
|
72777
|
+
}
|
|
72778
|
+
for (const warning of warnings) {
|
|
72779
|
+
warn(` \u26A0 ${warning}`);
|
|
72780
|
+
}
|
|
72781
|
+
return {
|
|
72782
|
+
pluginId,
|
|
72783
|
+
stageId: manifest.stageId,
|
|
72784
|
+
filesWritten,
|
|
72785
|
+
warnings,
|
|
72786
|
+
nextSteps: manifest.nextSteps,
|
|
72787
|
+
docsPath: manifest.docsPath
|
|
72788
|
+
};
|
|
72789
|
+
}
|
|
72790
|
+
function listPluginIds() {
|
|
72791
|
+
const root = path18.join(resolveTemplatesDir(), "plugins");
|
|
72792
|
+
if (!fs19.existsSync(root)) return [...PLUGIN_IDS];
|
|
72793
|
+
return fs19.readdirSync(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).filter((name) => PLUGIN_IDS.includes(name));
|
|
72794
|
+
}
|
|
72795
|
+
|
|
72796
|
+
// src/harness/plugin-drift.ts
|
|
72797
|
+
var PACKAGE_SECTIONS = ["scripts", "devDependencies"];
|
|
72798
|
+
function detectInstalledPlugins(repoPath) {
|
|
72799
|
+
const resolved = path19.resolve(repoPath);
|
|
72800
|
+
const registryPath = path19.join(resolved, ".har", "stages.json");
|
|
72801
|
+
if (!fs20.existsSync(registryPath)) return [];
|
|
72802
|
+
const registry2 = readStageRegistry(resolved);
|
|
72803
|
+
const stageIds = new Set(registry2.stages.map((stage) => stage.id));
|
|
72804
|
+
const installed = [];
|
|
72805
|
+
for (const pluginId of PLUGIN_IDS) {
|
|
72806
|
+
const manifest = readPluginManifest(pluginId);
|
|
72807
|
+
if (stageIds.has(manifest.stageId)) {
|
|
72808
|
+
installed.push(pluginId);
|
|
72809
|
+
}
|
|
72810
|
+
}
|
|
72811
|
+
return installed;
|
|
72812
|
+
}
|
|
72813
|
+
function pluginTemplatePath(pluginId, srcRel) {
|
|
72814
|
+
return path19.join(resolveTemplatesDir(), "plugins", pluginId, srcRel);
|
|
72815
|
+
}
|
|
72816
|
+
function readBundledPluginFile(pluginId, srcRel) {
|
|
72817
|
+
return fs20.readFileSync(pluginTemplatePath(pluginId, srcRel), "utf8");
|
|
72818
|
+
}
|
|
72819
|
+
function listPluginDestPaths(pluginId, repoPath) {
|
|
72820
|
+
const manifest = readPluginManifest(pluginId);
|
|
72821
|
+
const paths = manifest.files.map((file) => file.dest);
|
|
72822
|
+
if (manifest.optionalFiles) {
|
|
72823
|
+
for (const file of manifest.optionalFiles) {
|
|
72824
|
+
if (fs20.existsSync(path19.join(repoPath, file.dest))) {
|
|
72825
|
+
paths.push(file.dest);
|
|
72826
|
+
}
|
|
72827
|
+
}
|
|
72828
|
+
}
|
|
72829
|
+
if (manifest.merge) {
|
|
72830
|
+
for (const dest of Object.keys(manifest.merge)) {
|
|
72831
|
+
if (!paths.includes(dest)) paths.push(dest);
|
|
72832
|
+
}
|
|
72833
|
+
}
|
|
72834
|
+
return paths.sort();
|
|
72835
|
+
}
|
|
72836
|
+
function manifestEntryForDest(pluginId, dest) {
|
|
72837
|
+
const manifest = readPluginManifest(pluginId);
|
|
72838
|
+
return [...manifest.files, ...manifest.optionalFiles ?? []].find((file) => file.dest === dest);
|
|
72839
|
+
}
|
|
72840
|
+
function extractPackageFragment(pkgContent, fragmentContent) {
|
|
72841
|
+
const pkg = JSON.parse(pkgContent);
|
|
72842
|
+
const fragment = JSON.parse(fragmentContent);
|
|
72843
|
+
const extracted = {};
|
|
72844
|
+
for (const section of PACKAGE_SECTIONS) {
|
|
72845
|
+
const incoming = fragment[section] ?? {};
|
|
72846
|
+
const existing = pkg[section] ?? {};
|
|
72847
|
+
const picked = {};
|
|
72848
|
+
for (const key of Object.keys(incoming)) {
|
|
72849
|
+
if (existing[key] !== void 0) picked[key] = existing[key];
|
|
72850
|
+
}
|
|
72851
|
+
if (Object.keys(picked).length > 0) extracted[section] = picked;
|
|
72852
|
+
}
|
|
72853
|
+
return `${JSON.stringify(extracted, null, 2)}
|
|
72854
|
+
`;
|
|
72855
|
+
}
|
|
72856
|
+
function pluginKeysMatch(installedContent, fragmentContent) {
|
|
72857
|
+
const pkg = JSON.parse(installedContent);
|
|
72858
|
+
const fragment = JSON.parse(fragmentContent);
|
|
72859
|
+
for (const section of PACKAGE_SECTIONS) {
|
|
72860
|
+
const incoming = fragment[section] ?? {};
|
|
72861
|
+
const existing = pkg[section] ?? {};
|
|
72862
|
+
for (const [key, value] of Object.entries(incoming)) {
|
|
72863
|
+
if (existing[key] !== value) return false;
|
|
72864
|
+
}
|
|
72865
|
+
}
|
|
72866
|
+
return true;
|
|
72867
|
+
}
|
|
72868
|
+
function readTemplatePluginFile(pluginId, dest) {
|
|
72869
|
+
const entry = manifestEntryForDest(pluginId, dest);
|
|
72870
|
+
if (entry) {
|
|
72871
|
+
return readBundledPluginFile(pluginId, entry.src);
|
|
72872
|
+
}
|
|
72873
|
+
const manifest = readPluginManifest(pluginId);
|
|
72874
|
+
const fragmentRel = manifest.merge?.[dest];
|
|
72875
|
+
if (fragmentRel) {
|
|
72876
|
+
const fragment = JSON.parse(readBundledPluginFile(pluginId, fragmentRel));
|
|
72877
|
+
return `${JSON.stringify(fragment, null, 2)}
|
|
72878
|
+
`;
|
|
72879
|
+
}
|
|
72880
|
+
return null;
|
|
72881
|
+
}
|
|
72882
|
+
function readInstalledPluginFile(repoPath, pluginId, dest) {
|
|
72883
|
+
const installedPath = path19.join(path19.resolve(repoPath), dest);
|
|
72884
|
+
if (!fs20.existsSync(installedPath)) return null;
|
|
72885
|
+
const content = fs20.readFileSync(installedPath, "utf8");
|
|
72886
|
+
const manifest = readPluginManifest(pluginId);
|
|
72887
|
+
const fragmentRel = manifest.merge?.[dest];
|
|
72888
|
+
if (fragmentRel) {
|
|
72889
|
+
return extractPackageFragment(content, readBundledPluginFile(pluginId, fragmentRel));
|
|
72890
|
+
}
|
|
72891
|
+
return content;
|
|
72892
|
+
}
|
|
72893
|
+
function pluginActionHint(pluginId, dest, kind2) {
|
|
72894
|
+
if (kind2 === "missing") {
|
|
72895
|
+
return `Copy/adapt from maintain/plugins/${pluginId}/templates/${dest} or run: har env add-plugin ${pluginId} --force`;
|
|
72896
|
+
}
|
|
72897
|
+
if (dest === "package.json") {
|
|
72898
|
+
return `Merge plugin script/devDependency keys from maintain/plugins/${pluginId}/diffs/${dest}.diff or run: har env add-plugin ${pluginId} --force`;
|
|
72899
|
+
}
|
|
72900
|
+
return `Merge maintain/plugins/${pluginId}/diffs/${dest}.diff or run: har env add-plugin ${pluginId} --force`;
|
|
72901
|
+
}
|
|
72902
|
+
function comparePluginToTemplate(repoPath, pluginId) {
|
|
72903
|
+
const manifest = readPluginManifest(pluginId);
|
|
72904
|
+
const resolved = path19.resolve(repoPath);
|
|
72905
|
+
const destPaths = listPluginDestPaths(pluginId, resolved);
|
|
72906
|
+
const missing = [];
|
|
72907
|
+
const checksumMismatch = [];
|
|
72908
|
+
const unchanged = [];
|
|
72909
|
+
for (const dest of destPaths) {
|
|
72910
|
+
const templateContent = readTemplatePluginFile(pluginId, dest);
|
|
72911
|
+
if (templateContent === null) continue;
|
|
72912
|
+
const installedContent = readInstalledPluginFile(resolved, pluginId, dest);
|
|
72913
|
+
if (installedContent === null) {
|
|
72914
|
+
missing.push(dest);
|
|
72915
|
+
continue;
|
|
72916
|
+
}
|
|
72917
|
+
if (dest === "package.json") {
|
|
72918
|
+
const fragmentRel = manifest.merge?.[dest];
|
|
72919
|
+
const installedPath = path19.join(resolved, dest);
|
|
72920
|
+
const installedRaw = fs20.readFileSync(installedPath, "utf8");
|
|
72921
|
+
if (fragmentRel && pluginKeysMatch(installedRaw, readBundledPluginFile(pluginId, fragmentRel))) {
|
|
72922
|
+
unchanged.push(dest);
|
|
72923
|
+
} else if (computeFileChecksum(installedContent) === computeFileChecksum(templateContent)) {
|
|
72924
|
+
unchanged.push(dest);
|
|
72925
|
+
} else {
|
|
72926
|
+
checksumMismatch.push(dest);
|
|
72927
|
+
}
|
|
72928
|
+
continue;
|
|
72929
|
+
}
|
|
72930
|
+
if (computeFileChecksum(installedContent) === computeFileChecksum(templateContent)) {
|
|
72931
|
+
unchanged.push(dest);
|
|
72932
|
+
} else {
|
|
72933
|
+
checksumMismatch.push(dest);
|
|
72934
|
+
}
|
|
72935
|
+
}
|
|
72936
|
+
return {
|
|
72937
|
+
pluginId,
|
|
72938
|
+
stageId: manifest.stageId,
|
|
72939
|
+
missing,
|
|
72940
|
+
checksumMismatch,
|
|
72941
|
+
unchanged
|
|
72942
|
+
};
|
|
72943
|
+
}
|
|
72944
|
+
function compareInstalledPluginsToTemplate(repoPath) {
|
|
72945
|
+
return detectInstalledPlugins(repoPath).map(
|
|
72946
|
+
(pluginId) => comparePluginToTemplate(repoPath, pluginId)
|
|
72947
|
+
);
|
|
72948
|
+
}
|
|
72949
|
+
function buildPluginDriftActions(repoPath, pluginDrift) {
|
|
72950
|
+
const actions = [];
|
|
72951
|
+
for (const drift of pluginDrift) {
|
|
72952
|
+
for (const file of drift.missing) {
|
|
72953
|
+
actions.push({
|
|
72954
|
+
pluginId: drift.pluginId,
|
|
72955
|
+
file,
|
|
72956
|
+
kind: "missing",
|
|
72957
|
+
template: `maintain/plugins/${drift.pluginId}/templates/${file}`,
|
|
72958
|
+
hint: pluginActionHint(drift.pluginId, file, "missing")
|
|
72959
|
+
});
|
|
72960
|
+
}
|
|
72961
|
+
for (const file of drift.checksumMismatch) {
|
|
72962
|
+
actions.push({
|
|
72963
|
+
pluginId: drift.pluginId,
|
|
72964
|
+
file,
|
|
72965
|
+
kind: "drift",
|
|
72966
|
+
template: `maintain/plugins/${drift.pluginId}/templates/${file}`,
|
|
72967
|
+
installed: `maintain/plugins/${drift.pluginId}/installed/${file}`,
|
|
72968
|
+
diff: `maintain/plugins/${drift.pluginId}/diffs/${file}.diff`,
|
|
72969
|
+
hint: pluginActionHint(drift.pluginId, file, "drift")
|
|
72970
|
+
});
|
|
72971
|
+
}
|
|
72972
|
+
}
|
|
72973
|
+
return actions.sort(
|
|
72974
|
+
(a2, b3) => a2.pluginId.localeCompare(b3.pluginId) || a2.file.localeCompare(b3.file)
|
|
72975
|
+
);
|
|
72976
|
+
}
|
|
72977
|
+
|
|
72978
|
+
// src/harness/maintain-bundle.ts
|
|
72582
72979
|
var MAINTAIN_DIR = "maintain";
|
|
72583
72980
|
var PROFILE_DIRS3 = {
|
|
72584
72981
|
default: "har-boilerplate",
|
|
@@ -72589,14 +72986,14 @@ function substituteProjectName2(content, projectName) {
|
|
|
72589
72986
|
return content.replace(/__PROJECT_NAME__/g, projectName).replace(/template___PROJECT_NAME__/g, `template_${projectName}`);
|
|
72590
72987
|
}
|
|
72591
72988
|
function projectNameFromRepo(repoPath) {
|
|
72592
|
-
return
|
|
72989
|
+
return path20.basename(repoPath).toLowerCase().replace(/[^a-z0-9]/g, "_");
|
|
72593
72990
|
}
|
|
72594
72991
|
function boilerplateDirForProfile(profile) {
|
|
72595
|
-
return
|
|
72992
|
+
return path20.join(resolveTemplatesDir(), PROFILE_DIRS3[profile]);
|
|
72596
72993
|
}
|
|
72597
72994
|
function readBundledTemplateContent(repoPath, profile, file) {
|
|
72598
|
-
const templatePath =
|
|
72599
|
-
let content =
|
|
72995
|
+
const templatePath = path20.join(boilerplateDirForProfile(profile), templateFileForHarness(file));
|
|
72996
|
+
let content = fs21.readFileSync(templatePath, "utf8");
|
|
72600
72997
|
if (file === "harness.env") {
|
|
72601
72998
|
content = substituteProjectName2(content, projectNameFromRepo(repoPath));
|
|
72602
72999
|
}
|
|
@@ -72627,12 +73024,12 @@ function actionHint(file, kind2) {
|
|
|
72627
73024
|
return `Read maintain/diffs/${file}.diff and merge into .har/${file}.`;
|
|
72628
73025
|
}
|
|
72629
73026
|
function createUnifiedDiff(installedContent, templateContent, installedLabel, templateLabel) {
|
|
72630
|
-
const tmpDir =
|
|
73027
|
+
const tmpDir = fs21.mkdtempSync(path20.join(os4.tmpdir(), "har-maintain-diff-"));
|
|
72631
73028
|
try {
|
|
72632
|
-
const installedPath =
|
|
72633
|
-
const templatePath =
|
|
72634
|
-
|
|
72635
|
-
|
|
73029
|
+
const installedPath = path20.join(tmpDir, "installed");
|
|
73030
|
+
const templatePath = path20.join(tmpDir, "template");
|
|
73031
|
+
fs21.writeFileSync(installedPath, installedContent);
|
|
73032
|
+
fs21.writeFileSync(templatePath, templateContent);
|
|
72636
73033
|
const result = run(`diff -u "${installedPath}" "${templatePath}"`);
|
|
72637
73034
|
const body = result.stdout.trim();
|
|
72638
73035
|
if (!body) return "";
|
|
@@ -72641,7 +73038,7 @@ function createUnifiedDiff(installedContent, templateContent, installedLabel, te
|
|
|
72641
73038
|
${body.split("\n").slice(2).join("\n")}
|
|
72642
73039
|
`;
|
|
72643
73040
|
} finally {
|
|
72644
|
-
|
|
73041
|
+
fs21.rmSync(tmpDir, { recursive: true, force: true });
|
|
72645
73042
|
}
|
|
72646
73043
|
}
|
|
72647
73044
|
function buildActions(repoPath, profile, drift) {
|
|
@@ -72656,7 +73053,7 @@ function buildActions(repoPath, profile, drift) {
|
|
|
72656
73053
|
});
|
|
72657
73054
|
}
|
|
72658
73055
|
for (const file of drift.checksumMismatch) {
|
|
72659
|
-
const installedPath =
|
|
73056
|
+
const installedPath = path20.join(harnessDir, file);
|
|
72660
73057
|
const installedRel = `maintain/installed/${file}`;
|
|
72661
73058
|
const templateRel = `maintain/templates/${file}`;
|
|
72662
73059
|
const diffRel = `maintain/diffs/${file}.diff`;
|
|
@@ -72664,7 +73061,7 @@ function buildActions(repoPath, profile, drift) {
|
|
|
72664
73061
|
file,
|
|
72665
73062
|
kind: "drift",
|
|
72666
73063
|
template: templateRel,
|
|
72667
|
-
installed:
|
|
73064
|
+
installed: fs21.existsSync(installedPath) ? installedRel : void 0,
|
|
72668
73065
|
diff: diffRel,
|
|
72669
73066
|
hint: actionHint(file, "drift")
|
|
72670
73067
|
});
|
|
@@ -72698,7 +73095,7 @@ function buildReadme(report) {
|
|
|
72698
73095
|
}
|
|
72699
73096
|
lines2.push("", "## Drift actions", "");
|
|
72700
73097
|
if (report.actions.length === 0) {
|
|
72701
|
-
lines2.push("No missing or drifted template files.");
|
|
73098
|
+
lines2.push("No missing or drifted harness template files.");
|
|
72702
73099
|
} else {
|
|
72703
73100
|
lines2.push("| File | Status | Reference |");
|
|
72704
73101
|
lines2.push("|------|--------|-----------|");
|
|
@@ -72707,6 +73104,22 @@ function buildReadme(report) {
|
|
|
72707
73104
|
lines2.push(`| ${action.file} | ${action.kind} | ${ref} |`);
|
|
72708
73105
|
}
|
|
72709
73106
|
}
|
|
73107
|
+
lines2.push("", "## Plugin drift (installed verification plugins)", "");
|
|
73108
|
+
if (report.pluginActions.length === 0) {
|
|
73109
|
+
lines2.push("No installed plugins detected, or all plugin files match bundled templates.");
|
|
73110
|
+
} else {
|
|
73111
|
+
lines2.push("| Plugin | File | Status | Reference |");
|
|
73112
|
+
lines2.push("|--------|------|--------|-----------|");
|
|
73113
|
+
for (const action of report.pluginActions) {
|
|
73114
|
+
const ref = action.kind === "missing" ? `plugins/${action.pluginId}/templates/${action.file}` : `plugins/${action.pluginId}/diffs/${action.file}.diff`;
|
|
73115
|
+
lines2.push(`| ${action.pluginId} | ${action.file} | ${action.kind} | ${ref} |`);
|
|
73116
|
+
}
|
|
73117
|
+
lines2.push(
|
|
73118
|
+
"",
|
|
73119
|
+
"To refresh all plugin files: `har env add-plugin <id> --force` (overwrites plugin-owned paths).",
|
|
73120
|
+
""
|
|
73121
|
+
);
|
|
73122
|
+
}
|
|
72710
73123
|
if (report.missingPortVars.length > 0) {
|
|
72711
73124
|
lines2.push("", "## Missing port vars in harness.env", "");
|
|
72712
73125
|
for (const v3 of report.missingPortVars) {
|
|
@@ -72737,38 +73150,39 @@ function buildReadme(report) {
|
|
|
72737
73150
|
"",
|
|
72738
73151
|
"## Next steps",
|
|
72739
73152
|
"",
|
|
72740
|
-
"1. Resolve each drift action (merge diffs; keep repo-specific customizations).",
|
|
72741
|
-
"2.
|
|
72742
|
-
"3.
|
|
72743
|
-
|
|
73153
|
+
"1. Resolve each harness drift action (merge diffs; keep repo-specific customizations).",
|
|
73154
|
+
"2. Merge plugin drift under `maintain/plugins/` or run `har env add-plugin <id> --force`.",
|
|
73155
|
+
"3. Review stale files \u2014 delete or merge superseded scripts.",
|
|
73156
|
+
"4. Re-run `har env maintain` until validation passes and drift is clear.",
|
|
73157
|
+
'5. `har env maintain --finalize --summary "<what changed>"`',
|
|
72744
73158
|
""
|
|
72745
73159
|
);
|
|
72746
73160
|
return lines2.join("\n");
|
|
72747
73161
|
}
|
|
72748
73162
|
function writeBundleArtifacts(repoPath, profile, drift, report) {
|
|
72749
73163
|
const harnessDir = getHarnessDir(repoPath);
|
|
72750
|
-
const bundleDir =
|
|
72751
|
-
if (
|
|
72752
|
-
|
|
73164
|
+
const bundleDir = path20.join(harnessDir, MAINTAIN_DIR);
|
|
73165
|
+
if (fs21.existsSync(bundleDir)) {
|
|
73166
|
+
fs21.rmSync(bundleDir, { recursive: true, force: true });
|
|
72753
73167
|
}
|
|
72754
73168
|
const dirs = [
|
|
72755
73169
|
bundleDir,
|
|
72756
|
-
|
|
72757
|
-
|
|
72758
|
-
|
|
72759
|
-
|
|
73170
|
+
path20.join(bundleDir, "templates"),
|
|
73171
|
+
path20.join(bundleDir, "installed"),
|
|
73172
|
+
path20.join(bundleDir, "diffs"),
|
|
73173
|
+
path20.join(bundleDir, "stale")
|
|
72760
73174
|
];
|
|
72761
73175
|
for (const dir of dirs) {
|
|
72762
|
-
|
|
73176
|
+
fs21.mkdirSync(dir, { recursive: true });
|
|
72763
73177
|
}
|
|
72764
73178
|
const affectedFiles = [...drift.missing, ...drift.checksumMismatch];
|
|
72765
73179
|
for (const file of affectedFiles) {
|
|
72766
73180
|
const templateContent = readBundledTemplateContent(repoPath, profile, file);
|
|
72767
|
-
writeFileSafe(
|
|
72768
|
-
const harnessPath =
|
|
72769
|
-
if (
|
|
72770
|
-
const installedContent =
|
|
72771
|
-
writeFileSafe(
|
|
73181
|
+
writeFileSafe(path20.join(bundleDir, "templates", file), templateContent);
|
|
73182
|
+
const harnessPath = path20.join(harnessDir, file);
|
|
73183
|
+
if (fs21.existsSync(harnessPath)) {
|
|
73184
|
+
const installedContent = fs21.readFileSync(harnessPath, "utf8");
|
|
73185
|
+
writeFileSafe(path20.join(bundleDir, "installed", file), installedContent);
|
|
72772
73186
|
const diff = createUnifiedDiff(
|
|
72773
73187
|
installedContent,
|
|
72774
73188
|
templateContent,
|
|
@@ -72776,14 +73190,14 @@ function writeBundleArtifacts(repoPath, profile, drift, report) {
|
|
|
72776
73190
|
`templates/${file}`
|
|
72777
73191
|
);
|
|
72778
73192
|
if (diff) {
|
|
72779
|
-
writeFileSafe(
|
|
73193
|
+
writeFileSafe(path20.join(bundleDir, "diffs", `${file}.diff`), diff);
|
|
72780
73194
|
}
|
|
72781
73195
|
}
|
|
72782
73196
|
}
|
|
72783
|
-
writeFileSafe(
|
|
72784
|
-
writeFileSafe(
|
|
73197
|
+
writeFileSafe(path20.join(bundleDir, "README.md"), buildReadme(report));
|
|
73198
|
+
writeFileSafe(path20.join(bundleDir, "drift-report.json"), JSON.stringify(report, null, 2) + "\n");
|
|
72785
73199
|
writeFileSafe(
|
|
72786
|
-
|
|
73200
|
+
path20.join(bundleDir, "validation.json"),
|
|
72787
73201
|
JSON.stringify(report.validation, null, 2) + "\n"
|
|
72788
73202
|
);
|
|
72789
73203
|
if (report.stale.length > 0) {
|
|
@@ -72795,20 +73209,64 @@ function writeBundleArtifacts(repoPath, profile, drift, report) {
|
|
|
72795
73209
|
...report.stale.map((s2) => `- **${s2.file}** \u2014 ${s2.hint}`),
|
|
72796
73210
|
""
|
|
72797
73211
|
];
|
|
72798
|
-
writeFileSafe(
|
|
73212
|
+
writeFileSafe(path20.join(bundleDir, "stale", "MANIFEST.md"), staleLines.join("\n"));
|
|
72799
73213
|
}
|
|
72800
73214
|
return bundleDir;
|
|
72801
73215
|
}
|
|
73216
|
+
function ensureParentDir2(filePath) {
|
|
73217
|
+
const parent = path20.dirname(filePath);
|
|
73218
|
+
if (!fs21.existsSync(parent)) {
|
|
73219
|
+
fs21.mkdirSync(parent, { recursive: true });
|
|
73220
|
+
}
|
|
73221
|
+
}
|
|
73222
|
+
function writePluginBundleArtifacts(repoPath, bundleDir, report) {
|
|
73223
|
+
if (report.pluginActions.length === 0) return;
|
|
73224
|
+
for (const action of report.pluginActions) {
|
|
73225
|
+
const pluginRoot = path20.join(bundleDir, "plugins", action.pluginId);
|
|
73226
|
+
const templatesDir = path20.join(pluginRoot, "templates");
|
|
73227
|
+
const installedDir = path20.join(pluginRoot, "installed");
|
|
73228
|
+
const diffsDir = path20.join(pluginRoot, "diffs");
|
|
73229
|
+
for (const dir of [templatesDir, installedDir, diffsDir]) {
|
|
73230
|
+
fs21.mkdirSync(dir, { recursive: true });
|
|
73231
|
+
}
|
|
73232
|
+
const templateContent = readTemplatePluginFile(action.pluginId, action.file);
|
|
73233
|
+
if (templateContent === null) continue;
|
|
73234
|
+
const templatePath = path20.join(templatesDir, action.file);
|
|
73235
|
+
ensureParentDir2(templatePath);
|
|
73236
|
+
writeFileSafe(templatePath, templateContent);
|
|
73237
|
+
const installedContent = readInstalledPluginFile(repoPath, action.pluginId, action.file);
|
|
73238
|
+
if (installedContent !== null) {
|
|
73239
|
+
const installedPath = path20.join(installedDir, action.file);
|
|
73240
|
+
ensureParentDir2(installedPath);
|
|
73241
|
+
writeFileSafe(installedPath, installedContent);
|
|
73242
|
+
const diff = createUnifiedDiff(
|
|
73243
|
+
installedContent,
|
|
73244
|
+
templateContent,
|
|
73245
|
+
`installed/${action.file}`,
|
|
73246
|
+
`templates/${action.file}`
|
|
73247
|
+
);
|
|
73248
|
+
if (diff) {
|
|
73249
|
+
const diffPath = path20.join(diffsDir, `${action.file}.diff`);
|
|
73250
|
+
ensureParentDir2(diffPath);
|
|
73251
|
+
writeFileSafe(diffPath, diff);
|
|
73252
|
+
}
|
|
73253
|
+
}
|
|
73254
|
+
}
|
|
73255
|
+
}
|
|
72802
73256
|
function buildMaintainBundle(repoPath, validation2, drift) {
|
|
72803
73257
|
const manifest = readManifest(repoPath);
|
|
72804
73258
|
const profile = manifest?.profile ?? "default";
|
|
72805
73259
|
const errors = validation2.issues.filter((i2) => i2.severity === "error");
|
|
72806
73260
|
const warnings = validation2.issues.filter((i2) => i2.severity === "warning");
|
|
73261
|
+
const pluginDrift = compareInstalledPluginsToTemplate(repoPath);
|
|
73262
|
+
const pluginActions = buildPluginDriftActions(repoPath, pluginDrift);
|
|
72807
73263
|
const report = {
|
|
72808
73264
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
72809
73265
|
generatorVersion: drift.generatorVersion,
|
|
72810
73266
|
profile,
|
|
72811
73267
|
actions: buildActions(repoPath, profile, drift),
|
|
73268
|
+
pluginDrift,
|
|
73269
|
+
pluginActions,
|
|
72812
73270
|
stale: buildStale(drift),
|
|
72813
73271
|
missingPortVars: drift.missingPortVars,
|
|
72814
73272
|
agentSlotMismatch: drift.agentSlotMismatch,
|
|
@@ -72819,12 +73277,13 @@ function buildMaintainBundle(repoPath, validation2, drift) {
|
|
|
72819
73277
|
}
|
|
72820
73278
|
};
|
|
72821
73279
|
const bundleDir = writeBundleArtifacts(repoPath, profile, drift, report);
|
|
73280
|
+
writePluginBundleArtifacts(repoPath, bundleDir, report);
|
|
72822
73281
|
return { bundleDir, report };
|
|
72823
73282
|
}
|
|
72824
73283
|
function removeMaintainBundle(repoPath) {
|
|
72825
|
-
const bundleDir =
|
|
72826
|
-
if (
|
|
72827
|
-
|
|
73284
|
+
const bundleDir = path20.join(getHarnessDir(repoPath), MAINTAIN_DIR);
|
|
73285
|
+
if (fs21.existsSync(bundleDir)) {
|
|
73286
|
+
fs21.rmSync(bundleDir, { recursive: true, force: true });
|
|
72828
73287
|
}
|
|
72829
73288
|
}
|
|
72830
73289
|
function formatMaintainBundlePromptSection(report) {
|
|
@@ -72832,7 +73291,8 @@ function formatMaintainBundlePromptSection(report) {
|
|
|
72832
73291
|
"## Step 0 \u2014 Read the maintenance bundle",
|
|
72833
73292
|
"",
|
|
72834
73293
|
"Open `.har/maintain/README.md` and `.har/maintain/drift-report.json`.",
|
|
72835
|
-
"
|
|
73294
|
+
"Harness reference templates: `.har/maintain/templates/`.",
|
|
73295
|
+
"Plugin reference templates: `.har/maintain/plugins/<plugin-id>/`.",
|
|
72836
73296
|
"Do **not** read files from the globally installed har package.",
|
|
72837
73297
|
""
|
|
72838
73298
|
];
|
|
@@ -72851,6 +73311,19 @@ function formatMaintainBundlePromptSection(report) {
|
|
|
72851
73311
|
}
|
|
72852
73312
|
lines2.push("");
|
|
72853
73313
|
}
|
|
73314
|
+
if (report.pluginActions.length > 0) {
|
|
73315
|
+
lines2.push(
|
|
73316
|
+
"### Plugin drift",
|
|
73317
|
+
"",
|
|
73318
|
+
"| Plugin | File | Status | Reference |",
|
|
73319
|
+
"|--------|------|--------|-----------|"
|
|
73320
|
+
);
|
|
73321
|
+
for (const action of report.pluginActions) {
|
|
73322
|
+
const ref = action.kind === "missing" ? `maintain/plugins/${action.pluginId}/templates/${action.file}` : `maintain/plugins/${action.pluginId}/diffs/${action.file}.diff`;
|
|
73323
|
+
lines2.push(`| ${action.pluginId} | ${action.file} | ${action.kind} | ${ref} |`);
|
|
73324
|
+
}
|
|
73325
|
+
lines2.push("");
|
|
73326
|
+
}
|
|
72854
73327
|
if (report.stale.length > 0) {
|
|
72855
73328
|
lines2.push("### Stale files", "");
|
|
72856
73329
|
for (const stale of report.stale) {
|
|
@@ -72876,221 +73349,12 @@ function formatMaintainBundlePromptSection(report) {
|
|
|
72876
73349
|
""
|
|
72877
73350
|
);
|
|
72878
73351
|
}
|
|
72879
|
-
if (report.actions.length === 0 && report.stale.length === 0 && report.missingPortVars.length === 0 && !report.agentSlotMismatch && report.validation.errors.length === 0) {
|
|
73352
|
+
if (report.actions.length === 0 && report.pluginActions.length === 0 && report.stale.length === 0 && report.missingPortVars.length === 0 && !report.agentSlotMismatch && report.validation.errors.length === 0) {
|
|
72880
73353
|
lines2.push("No template drift detected. Review repo stack changes manually if needed.", "");
|
|
72881
73354
|
}
|
|
72882
73355
|
return lines2.join("\n");
|
|
72883
73356
|
}
|
|
72884
73357
|
|
|
72885
|
-
// src/harness/plugins.ts
|
|
72886
|
-
var fs20 = __toESM(require("fs"));
|
|
72887
|
-
var path19 = __toESM(require("path"));
|
|
72888
|
-
|
|
72889
|
-
// src/harness/parser.ts
|
|
72890
|
-
var fs19 = __toESM(require("fs"));
|
|
72891
|
-
function harnessExists(repoPath) {
|
|
72892
|
-
return fs19.existsSync(`${repoPath}/.har/setup-infra.sh`);
|
|
72893
|
-
}
|
|
72894
|
-
|
|
72895
|
-
// src/harness/plugins.ts
|
|
72896
|
-
var PLUGIN_IDS = ["playwright", "rocketsim"];
|
|
72897
|
-
var PluginManifestFileSchema = external_exports.object({
|
|
72898
|
-
src: external_exports.string().min(1),
|
|
72899
|
-
dest: external_exports.string().min(1),
|
|
72900
|
-
executable: external_exports.boolean().optional(),
|
|
72901
|
-
skipFlag: external_exports.string().optional()
|
|
72902
|
-
});
|
|
72903
|
-
var PluginManifestSchema = external_exports.object({
|
|
72904
|
-
id: external_exports.enum(PLUGIN_IDS),
|
|
72905
|
-
stageId: external_exports.string().min(1),
|
|
72906
|
-
verificationStages: external_exports.array(external_exports.string().min(1)).min(1),
|
|
72907
|
-
stage: external_exports.record(external_exports.unknown()),
|
|
72908
|
-
files: external_exports.array(PluginManifestFileSchema).min(1),
|
|
72909
|
-
optionalFiles: external_exports.array(PluginManifestFileSchema).optional(),
|
|
72910
|
-
merge: external_exports.record(external_exports.string()).optional(),
|
|
72911
|
-
nextSteps: external_exports.array(external_exports.string().min(1)).min(1),
|
|
72912
|
-
docsPath: external_exports.string().min(1)
|
|
72913
|
-
});
|
|
72914
|
-
function resolvePluginDir(pluginId) {
|
|
72915
|
-
const dir = path19.join(resolveTemplatesDir(), "plugins", pluginId);
|
|
72916
|
-
if (!fs20.existsSync(dir)) {
|
|
72917
|
-
throw new Error(`Plugin not found: ${pluginId}. Run npm run build.`);
|
|
72918
|
-
}
|
|
72919
|
-
return dir;
|
|
72920
|
-
}
|
|
72921
|
-
function readPluginManifest(pluginId) {
|
|
72922
|
-
const manifestPath = path19.join(resolvePluginDir(pluginId), "template.manifest.json");
|
|
72923
|
-
const parsed = PluginManifestSchema.safeParse(
|
|
72924
|
-
JSON.parse(fs20.readFileSync(manifestPath, "utf8"))
|
|
72925
|
-
);
|
|
72926
|
-
if (!parsed.success) {
|
|
72927
|
-
throw new Error(`Invalid plugin manifest for ${pluginId}: ${parsed.error.message}`);
|
|
72928
|
-
}
|
|
72929
|
-
if (parsed.data.id !== pluginId) {
|
|
72930
|
-
throw new Error(`Plugin manifest id mismatch: expected ${pluginId}, got ${parsed.data.id}`);
|
|
72931
|
-
}
|
|
72932
|
-
return parsed.data;
|
|
72933
|
-
}
|
|
72934
|
-
function ensureParentDir(filePath) {
|
|
72935
|
-
const parent = path19.dirname(filePath);
|
|
72936
|
-
if (!fs20.existsSync(parent)) {
|
|
72937
|
-
fs20.mkdirSync(parent, { recursive: true });
|
|
72938
|
-
}
|
|
72939
|
-
}
|
|
72940
|
-
function copyPluginFile(pluginDir, file, repoPath, force) {
|
|
72941
|
-
const srcPath = path19.join(pluginDir, file.src);
|
|
72942
|
-
const destPath = path19.join(repoPath, file.dest);
|
|
72943
|
-
if (!fs20.existsSync(srcPath)) {
|
|
72944
|
-
throw new Error(`Plugin file missing: ${file.src}`);
|
|
72945
|
-
}
|
|
72946
|
-
if (fs20.existsSync(destPath) && !force) {
|
|
72947
|
-
throw new Error(
|
|
72948
|
-
`File already exists: ${file.dest}. Use --force to overwrite or remove it first.`
|
|
72949
|
-
);
|
|
72950
|
-
}
|
|
72951
|
-
ensureParentDir(destPath);
|
|
72952
|
-
fs20.copyFileSync(srcPath, destPath);
|
|
72953
|
-
if (file.executable) {
|
|
72954
|
-
fs20.chmodSync(destPath, 493);
|
|
72955
|
-
}
|
|
72956
|
-
return { written: true, path: file.dest };
|
|
72957
|
-
}
|
|
72958
|
-
function mergePackageJson(repoPath, pluginDir, fragmentRelPath, warnings) {
|
|
72959
|
-
const packagePath = path19.join(repoPath, "package.json");
|
|
72960
|
-
if (!fs20.existsSync(packagePath)) {
|
|
72961
|
-
throw new Error("No package.json in repo root. Add one before applying this plugin.");
|
|
72962
|
-
}
|
|
72963
|
-
const fragmentPath = path19.join(pluginDir, fragmentRelPath);
|
|
72964
|
-
if (!fs20.existsSync(fragmentPath)) {
|
|
72965
|
-
throw new Error(`Package fragment missing: ${fragmentRelPath}`);
|
|
72966
|
-
}
|
|
72967
|
-
const pkg = JSON.parse(fs20.readFileSync(packagePath, "utf8"));
|
|
72968
|
-
const fragment = JSON.parse(fs20.readFileSync(fragmentPath, "utf8"));
|
|
72969
|
-
for (const section of ["scripts", "devDependencies"]) {
|
|
72970
|
-
const existing = pkg[section] ?? {};
|
|
72971
|
-
const incoming = fragment[section] ?? {};
|
|
72972
|
-
for (const [key, value] of Object.entries(incoming)) {
|
|
72973
|
-
if (existing[key] !== void 0 && existing[key] !== value) {
|
|
72974
|
-
warnings.push(`package.json ${section}.${key} already set \u2014 kept existing value`);
|
|
72975
|
-
continue;
|
|
72976
|
-
}
|
|
72977
|
-
existing[key] = value;
|
|
72978
|
-
}
|
|
72979
|
-
pkg[section] = existing;
|
|
72980
|
-
}
|
|
72981
|
-
fs20.writeFileSync(packagePath, JSON.stringify(pkg, null, 2) + "\n");
|
|
72982
|
-
}
|
|
72983
|
-
function patchStageRegistry(repoPath, manifest, force) {
|
|
72984
|
-
const registry2 = readStageRegistry(repoPath);
|
|
72985
|
-
const stage = HarnessStageSchema.parse(manifest.stage);
|
|
72986
|
-
const existing = registry2.stages.find((s2) => s2.id === stage.id);
|
|
72987
|
-
if (existing && !force) {
|
|
72988
|
-
throw new Error(
|
|
72989
|
-
`Stage "${stage.id}" already registered in .har/stages.json. Use --force to replace.`
|
|
72990
|
-
);
|
|
72991
|
-
}
|
|
72992
|
-
const stages = existing ? registry2.stages.map((s2) => s2.id === stage.id ? stage : s2) : [...registry2.stages, stage];
|
|
72993
|
-
const verificationStages = [...registry2.verificationStages ?? []];
|
|
72994
|
-
for (const id of manifest.verificationStages) {
|
|
72995
|
-
if (!verificationStages.includes(id)) {
|
|
72996
|
-
verificationStages.push(id);
|
|
72997
|
-
}
|
|
72998
|
-
}
|
|
72999
|
-
const verifyIdx = stages.findIndex((s2) => s2.id === "verify");
|
|
73000
|
-
if (verifyIdx >= 0) {
|
|
73001
|
-
stages[verifyIdx] = {
|
|
73002
|
-
...stages[verifyIdx],
|
|
73003
|
-
description: `Verification pipeline (quick smoke by default; --full runs the registry's verificationStages: ${verificationStages.join(", ")})`,
|
|
73004
|
-
acceptsArgs: ["--full"]
|
|
73005
|
-
};
|
|
73006
|
-
}
|
|
73007
|
-
const updated = {
|
|
73008
|
-
...registry2,
|
|
73009
|
-
stages,
|
|
73010
|
-
verificationStages
|
|
73011
|
-
};
|
|
73012
|
-
writeStageRegistry(repoPath, updated);
|
|
73013
|
-
}
|
|
73014
|
-
function assertHarnessPresent(repoPath) {
|
|
73015
|
-
if (!harnessExists(repoPath)) {
|
|
73016
|
-
throw new Error('No .har/ harness found. Run "har env init" first.');
|
|
73017
|
-
}
|
|
73018
|
-
}
|
|
73019
|
-
function assertStageNotPresent(repoPath, stageId, force) {
|
|
73020
|
-
if (force) return;
|
|
73021
|
-
const scriptPath = path19.join(repoPath, ".har", "stages", `${stageId}.sh`);
|
|
73022
|
-
if (fs20.existsSync(scriptPath)) {
|
|
73023
|
-
throw new Error(
|
|
73024
|
-
`Stage script already exists: .har/stages/${stageId}.sh. Use --force to overwrite.`
|
|
73025
|
-
);
|
|
73026
|
-
}
|
|
73027
|
-
const registry2 = readStageRegistry(repoPath);
|
|
73028
|
-
if (registry2.stages.some((s2) => s2.id === stageId)) {
|
|
73029
|
-
throw new Error(
|
|
73030
|
-
`Stage "${stageId}" already registered in .har/stages.json. Use --force to replace.`
|
|
73031
|
-
);
|
|
73032
|
-
}
|
|
73033
|
-
}
|
|
73034
|
-
function applyPlugin(repoPath, pluginId, options = {}) {
|
|
73035
|
-
const resolved = path19.resolve(repoPath);
|
|
73036
|
-
const force = options.force ?? false;
|
|
73037
|
-
const warnings = [];
|
|
73038
|
-
const filesWritten = [];
|
|
73039
|
-
assertHarnessPresent(resolved);
|
|
73040
|
-
const manifest = readPluginManifest(pluginId);
|
|
73041
|
-
assertStageNotPresent(resolved, manifest.stageId, force);
|
|
73042
|
-
const pluginDir = resolvePluginDir(pluginId);
|
|
73043
|
-
for (const file of manifest.files) {
|
|
73044
|
-
const result = copyPluginFile(pluginDir, file, resolved, force);
|
|
73045
|
-
if (result.written) {
|
|
73046
|
-
filesWritten.push(result.path);
|
|
73047
|
-
}
|
|
73048
|
-
}
|
|
73049
|
-
if (manifest.optionalFiles) {
|
|
73050
|
-
for (const file of manifest.optionalFiles) {
|
|
73051
|
-
if (file.skipFlag === "skipCi" && options.skipCi) {
|
|
73052
|
-
continue;
|
|
73053
|
-
}
|
|
73054
|
-
if (fs20.existsSync(path19.join(resolved, file.dest)) && !force) {
|
|
73055
|
-
warnings.push(`Skipped optional file (exists): ${file.dest}`);
|
|
73056
|
-
continue;
|
|
73057
|
-
}
|
|
73058
|
-
const result = copyPluginFile(pluginDir, file, resolved, force);
|
|
73059
|
-
if (result.written) {
|
|
73060
|
-
filesWritten.push(result.path);
|
|
73061
|
-
}
|
|
73062
|
-
}
|
|
73063
|
-
}
|
|
73064
|
-
if (manifest.merge) {
|
|
73065
|
-
for (const fragmentRel of Object.values(manifest.merge)) {
|
|
73066
|
-
mergePackageJson(resolved, pluginDir, fragmentRel, warnings);
|
|
73067
|
-
filesWritten.push("package.json");
|
|
73068
|
-
}
|
|
73069
|
-
}
|
|
73070
|
-
patchStageRegistry(resolved, manifest, force);
|
|
73071
|
-
success(`Applied plugin: ${pluginId}`);
|
|
73072
|
-
info(`Registered stage: ${manifest.stageId}`);
|
|
73073
|
-
for (const file of filesWritten) {
|
|
73074
|
-
info(` + ${file}`);
|
|
73075
|
-
}
|
|
73076
|
-
for (const warning of warnings) {
|
|
73077
|
-
warn(` \u26A0 ${warning}`);
|
|
73078
|
-
}
|
|
73079
|
-
return {
|
|
73080
|
-
pluginId,
|
|
73081
|
-
stageId: manifest.stageId,
|
|
73082
|
-
filesWritten,
|
|
73083
|
-
warnings,
|
|
73084
|
-
nextSteps: manifest.nextSteps,
|
|
73085
|
-
docsPath: manifest.docsPath
|
|
73086
|
-
};
|
|
73087
|
-
}
|
|
73088
|
-
function listPluginIds() {
|
|
73089
|
-
const root = path19.join(resolveTemplatesDir(), "plugins");
|
|
73090
|
-
if (!fs20.existsSync(root)) return [...PLUGIN_IDS];
|
|
73091
|
-
return fs20.readdirSync(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).filter((name) => PLUGIN_IDS.includes(name));
|
|
73092
|
-
}
|
|
73093
|
-
|
|
73094
73358
|
// src/utils/validation.ts
|
|
73095
73359
|
function requireApiKey() {
|
|
73096
73360
|
const key = process.env.ANTHROPIC_API_KEY;
|
|
@@ -73113,11 +73377,11 @@ function validateAgentId(id, repoPath) {
|
|
|
73113
73377
|
// src/core/harness.ts
|
|
73114
73378
|
function listHarnessScripts(repoPath) {
|
|
73115
73379
|
const harnessDir = getHarnessDir(repoPath);
|
|
73116
|
-
if (!
|
|
73117
|
-
return
|
|
73380
|
+
if (!fs22.existsSync(harnessDir)) return [];
|
|
73381
|
+
return fs22.readdirSync(harnessDir).filter((name) => name.endsWith(".sh")).sort();
|
|
73118
73382
|
}
|
|
73119
73383
|
function describeProject(repoPath) {
|
|
73120
|
-
const resolved =
|
|
73384
|
+
const resolved = path21.resolve(repoPath);
|
|
73121
73385
|
const manifest = readManifest(resolved);
|
|
73122
73386
|
const present = harnessExists(resolved);
|
|
73123
73387
|
return {
|
|
@@ -73137,8 +73401,8 @@ function describeProject(repoPath) {
|
|
|
73137
73401
|
};
|
|
73138
73402
|
}
|
|
73139
73403
|
async function initHarness(options) {
|
|
73140
|
-
const repoPath =
|
|
73141
|
-
if (!
|
|
73404
|
+
const repoPath = path21.resolve(options.repoPath);
|
|
73405
|
+
if (!fs22.existsSync(repoPath)) {
|
|
73142
73406
|
throw new Error(`Path not found: ${repoPath}`);
|
|
73143
73407
|
}
|
|
73144
73408
|
const scaffold = scaffoldHarnessBoilerplate(repoPath, {
|
|
@@ -73170,9 +73434,9 @@ async function initHarness(options) {
|
|
|
73170
73434
|
};
|
|
73171
73435
|
}
|
|
73172
73436
|
async function maintainHarness(options) {
|
|
73173
|
-
const repoPath =
|
|
73437
|
+
const repoPath = path21.resolve(options.repoPath);
|
|
73174
73438
|
const harnessDir = getHarnessDir(repoPath);
|
|
73175
|
-
if (!
|
|
73439
|
+
if (!fs22.existsSync(harnessDir)) {
|
|
73176
73440
|
throw new Error('No .har/ found. Run "har env init" first.');
|
|
73177
73441
|
}
|
|
73178
73442
|
if (options.auto) {
|
|
@@ -73224,11 +73488,11 @@ function addPlugin(repoPath, pluginId, options = {}) {
|
|
|
73224
73488
|
}
|
|
73225
73489
|
|
|
73226
73490
|
// src/harness/custom-stage.ts
|
|
73227
|
-
var
|
|
73228
|
-
var
|
|
73491
|
+
var fs23 = __toESM(require("fs"));
|
|
73492
|
+
var path22 = __toESM(require("path"));
|
|
73229
73493
|
var STAGE_ID_PATTERN = /^[a-z0-9][a-z0-9._-]*$/;
|
|
73230
73494
|
function addCustomStage(repoPath, options) {
|
|
73231
|
-
const resolved =
|
|
73495
|
+
const resolved = path22.resolve(repoPath);
|
|
73232
73496
|
if (!harnessExists(resolved)) {
|
|
73233
73497
|
throw new Error('No .har/ harness found. Run "har env init" first.');
|
|
73234
73498
|
}
|
|
@@ -73265,20 +73529,20 @@ function addCustomStage(repoPath, options) {
|
|
|
73265
73529
|
if (options.command) {
|
|
73266
73530
|
stage.command = options.command;
|
|
73267
73531
|
} else {
|
|
73268
|
-
const scriptRel =
|
|
73269
|
-
const scriptAbs =
|
|
73270
|
-
if (
|
|
73532
|
+
const scriptRel = path22.join("stages", `${id}.sh`);
|
|
73533
|
+
const scriptAbs = path22.join(resolved, ".har", scriptRel);
|
|
73534
|
+
if (fs23.existsSync(scriptAbs) && !options.force) {
|
|
73271
73535
|
throw new Error(`Stage script already exists: .har/${scriptRel}. Use --force to overwrite.`);
|
|
73272
73536
|
}
|
|
73273
|
-
const skeletonPath =
|
|
73537
|
+
const skeletonPath = path22.join(
|
|
73274
73538
|
resolveTemplatesDir(),
|
|
73275
73539
|
"plugins",
|
|
73276
73540
|
"custom-stage-skeleton.sh"
|
|
73277
73541
|
);
|
|
73278
|
-
const skeleton =
|
|
73279
|
-
|
|
73280
|
-
|
|
73281
|
-
|
|
73542
|
+
const skeleton = fs23.readFileSync(skeletonPath, "utf8").replace(/__STAGE_ID__/g, id).replace(/__STAGE_KIND__/g, kind2).replace(/__STAGE_DESCRIPTION__/g, stage.description);
|
|
73543
|
+
fs23.mkdirSync(path22.dirname(scriptAbs), { recursive: true });
|
|
73544
|
+
fs23.writeFileSync(scriptAbs, skeleton);
|
|
73545
|
+
fs23.chmodSync(scriptAbs, 493);
|
|
73282
73546
|
filesWritten.push(`.har/${scriptRel}`);
|
|
73283
73547
|
stage.script = scriptRel;
|
|
73284
73548
|
stage.artifacts = [
|
|
@@ -73326,8 +73590,8 @@ function addCustomStage(repoPath, options) {
|
|
|
73326
73590
|
}
|
|
73327
73591
|
|
|
73328
73592
|
// src/harness/adaptation-prompt.ts
|
|
73329
|
-
var
|
|
73330
|
-
var
|
|
73593
|
+
var fs24 = __toESM(require("fs"));
|
|
73594
|
+
var path23 = __toESM(require("path"));
|
|
73331
73595
|
var readline4 = __toESM(require("readline"));
|
|
73332
73596
|
|
|
73333
73597
|
// src/utils/clipboard.ts
|
|
@@ -73414,7 +73678,7 @@ function loadTemplate(name) {
|
|
|
73414
73678
|
if (!filePath) {
|
|
73415
73679
|
throw new Error(`Adaptation prompt template not found: ${name}. Run npm run build.`);
|
|
73416
73680
|
}
|
|
73417
|
-
return
|
|
73681
|
+
return fs24.readFileSync(filePath, "utf8");
|
|
73418
73682
|
}
|
|
73419
73683
|
function applyProfilePlaceholders(content, profile) {
|
|
73420
73684
|
return content.replace(/\{\{PROFILE\}\}/g, profile).replace(/\{\{PROFILE_HINT\}\}/g, PROFILE_HINTS[profile]);
|
|
@@ -73436,7 +73700,7 @@ function buildMaintainAdaptationPrompt(_repoPath, bundleReport) {
|
|
|
73436
73700
|
}
|
|
73437
73701
|
function writeAdaptationPrompt(repoPath, content) {
|
|
73438
73702
|
const harnessDir = getHarnessDir(repoPath);
|
|
73439
|
-
const filePath =
|
|
73703
|
+
const filePath = path23.join(harnessDir, ADAPTATION_PROMPT_FILE);
|
|
73440
73704
|
writeFileSafe(filePath, content);
|
|
73441
73705
|
return filePath;
|
|
73442
73706
|
}
|
|
@@ -73455,12 +73719,12 @@ function printAdaptationPrompt(content) {
|
|
|
73455
73719
|
}
|
|
73456
73720
|
function askYesNo3(question) {
|
|
73457
73721
|
const rl = readline4.createInterface({ input: process.stdin, output: process.stderr });
|
|
73458
|
-
return new Promise((
|
|
73722
|
+
return new Promise((resolve45) => {
|
|
73459
73723
|
process.stderr.write(`${question} `);
|
|
73460
73724
|
rl.once("line", (answer) => {
|
|
73461
73725
|
rl.close();
|
|
73462
73726
|
const trimmed = answer.trim();
|
|
73463
|
-
|
|
73727
|
+
resolve45(trimmed === "" || /^y(es)?$/i.test(trimmed));
|
|
73464
73728
|
});
|
|
73465
73729
|
});
|
|
73466
73730
|
}
|
|
@@ -73491,25 +73755,25 @@ async function offerAdaptationPromptClipboard(content, options = {}) {
|
|
|
73491
73755
|
}
|
|
73492
73756
|
|
|
73493
73757
|
// src/harness/cursor-rule.ts
|
|
73494
|
-
var
|
|
73495
|
-
var
|
|
73758
|
+
var fs25 = __toESM(require("fs"));
|
|
73759
|
+
var path24 = __toESM(require("path"));
|
|
73496
73760
|
var readline5 = __toESM(require("readline"));
|
|
73497
73761
|
var CURSOR_RULE_RELATIVE_PATH = ".cursor/rules/har-workflow.mdc";
|
|
73498
73762
|
function getCursorRulePath(repoPath) {
|
|
73499
|
-
return
|
|
73763
|
+
return path24.join(repoPath, CURSOR_RULE_RELATIVE_PATH);
|
|
73500
73764
|
}
|
|
73501
73765
|
function isCursorWorkspace(repoPath) {
|
|
73502
|
-
return
|
|
73766
|
+
return fs25.existsSync(path24.join(repoPath, ".cursor"));
|
|
73503
73767
|
}
|
|
73504
73768
|
function cursorRuleExists(repoPath) {
|
|
73505
|
-
return
|
|
73769
|
+
return fs25.existsSync(getCursorRulePath(repoPath));
|
|
73506
73770
|
}
|
|
73507
73771
|
function scaffoldCursorRule(repoPath) {
|
|
73508
73772
|
const templatePath = resolveTemplateFile("cursor-rule.mdc.template");
|
|
73509
73773
|
if (!templatePath) {
|
|
73510
73774
|
throw new Error("Cursor rule template not found (cursor-rule.mdc.template). Run npm run build.");
|
|
73511
73775
|
}
|
|
73512
|
-
const content =
|
|
73776
|
+
const content = fs25.readFileSync(templatePath, "utf8");
|
|
73513
73777
|
writeFileSafe(getCursorRulePath(repoPath), content);
|
|
73514
73778
|
}
|
|
73515
73779
|
async function handleCursorRule(options) {
|
|
@@ -73547,16 +73811,16 @@ async function promptScaffoldCursorRule(exists) {
|
|
|
73547
73811
|
}
|
|
73548
73812
|
async function askYesNo4(question) {
|
|
73549
73813
|
const rl = readline5.createInterface({ input: process.stdin, output: process.stderr });
|
|
73550
|
-
return new Promise((
|
|
73814
|
+
return new Promise((resolve45) => {
|
|
73551
73815
|
process.stderr.write(`${question} `);
|
|
73552
73816
|
rl.once("line", (answer) => {
|
|
73553
73817
|
rl.close();
|
|
73554
73818
|
const trimmed = answer.trim();
|
|
73555
73819
|
if (trimmed === "") {
|
|
73556
|
-
|
|
73820
|
+
resolve45(true);
|
|
73557
73821
|
return;
|
|
73558
73822
|
}
|
|
73559
|
-
|
|
73823
|
+
resolve45(/^y(es)?$/i.test(trimmed));
|
|
73560
73824
|
});
|
|
73561
73825
|
});
|
|
73562
73826
|
}
|
|
@@ -73638,26 +73902,26 @@ function buildStageResult(input) {
|
|
|
73638
73902
|
var crypto5 = __toESM(require("crypto"));
|
|
73639
73903
|
|
|
73640
73904
|
// src/core/local-executor.ts
|
|
73641
|
-
var
|
|
73642
|
-
var
|
|
73905
|
+
var fs27 = __toESM(require("fs"));
|
|
73906
|
+
var path26 = __toESM(require("path"));
|
|
73643
73907
|
|
|
73644
73908
|
// src/core/slot-registry.ts
|
|
73645
|
-
var
|
|
73646
|
-
var
|
|
73909
|
+
var fs26 = __toESM(require("fs"));
|
|
73910
|
+
var path25 = __toESM(require("path"));
|
|
73647
73911
|
function getSlotRegistryDir(repoPath) {
|
|
73648
|
-
return
|
|
73912
|
+
return path25.join(getHarnessDir(repoPath), "slots");
|
|
73649
73913
|
}
|
|
73650
73914
|
function getSlotRegistryPath(repoPath, agentId) {
|
|
73651
|
-
return
|
|
73915
|
+
return path25.join(getSlotRegistryDir(repoPath), `agent-${agentId}.json`);
|
|
73652
73916
|
}
|
|
73653
73917
|
function isSlotResumable(session) {
|
|
73654
73918
|
return session?.status === "failed" || session?.status === "starting";
|
|
73655
73919
|
}
|
|
73656
73920
|
function readSlotRegistry(repoPath, agentId) {
|
|
73657
73921
|
const file = getSlotRegistryPath(repoPath, agentId);
|
|
73658
|
-
if (!
|
|
73922
|
+
if (!fs26.existsSync(file)) return void 0;
|
|
73659
73923
|
try {
|
|
73660
|
-
const raw = JSON.parse(
|
|
73924
|
+
const raw = JSON.parse(fs26.readFileSync(file, "utf8"));
|
|
73661
73925
|
const result = SlotRegistryEntrySchema.safeParse(raw);
|
|
73662
73926
|
return result.success ? result.data : void 0;
|
|
73663
73927
|
} catch {
|
|
@@ -73666,9 +73930,9 @@ function readSlotRegistry(repoPath, agentId) {
|
|
|
73666
73930
|
}
|
|
73667
73931
|
function listSlotRegistryEntries(repoPath) {
|
|
73668
73932
|
const dir = getSlotRegistryDir(repoPath);
|
|
73669
|
-
if (!
|
|
73933
|
+
if (!fs26.existsSync(dir)) return [];
|
|
73670
73934
|
const entries = [];
|
|
73671
|
-
for (const name of
|
|
73935
|
+
for (const name of fs26.readdirSync(dir)) {
|
|
73672
73936
|
const match = name.match(/^agent-(\d+)\.json$/);
|
|
73673
73937
|
if (!match) continue;
|
|
73674
73938
|
const entry = readSlotRegistry(repoPath, Number(match[1]));
|
|
@@ -73694,7 +73958,7 @@ function buildLaunchFlagArgs(flags) {
|
|
|
73694
73958
|
return args;
|
|
73695
73959
|
}
|
|
73696
73960
|
function resolveRepoPath(repoPath) {
|
|
73697
|
-
return
|
|
73961
|
+
return path26.resolve(repoPath);
|
|
73698
73962
|
}
|
|
73699
73963
|
function buildPreviewUrlsFromPorts(ports, env3) {
|
|
73700
73964
|
const urls = {};
|
|
@@ -73746,14 +74010,14 @@ function substituteAgentId(value, agentId) {
|
|
|
73746
74010
|
function resolveStageScriptPath(repoPath, stage) {
|
|
73747
74011
|
const harnessDir = getHarnessDir(repoPath);
|
|
73748
74012
|
if (stage.script) {
|
|
73749
|
-
return
|
|
74013
|
+
return path26.join(harnessDir, stage.script);
|
|
73750
74014
|
}
|
|
73751
74015
|
if (stage.command) {
|
|
73752
74016
|
const scriptName = stage.command.split(/\s+/)[0].replace(/^\.\/\.har\//, "").replace(/^\.\//, "");
|
|
73753
|
-
return
|
|
74017
|
+
return path26.join(harnessDir, scriptName);
|
|
73754
74018
|
}
|
|
73755
|
-
const stageScript =
|
|
73756
|
-
if (
|
|
74019
|
+
const stageScript = path26.join(harnessDir, "stages", `${stage.id}.sh`);
|
|
74020
|
+
if (fs27.existsSync(stageScript)) {
|
|
73757
74021
|
return stageScript;
|
|
73758
74022
|
}
|
|
73759
74023
|
throw new Error(
|
|
@@ -73768,7 +74032,7 @@ function buildExecutionPlan(repoPath, stage, options) {
|
|
|
73768
74032
|
...harnessEnv,
|
|
73769
74033
|
...stage.env ?? {}
|
|
73770
74034
|
};
|
|
73771
|
-
const cwd = stage.cwd ?
|
|
74035
|
+
const cwd = stage.cwd ? path26.resolve(resolvedRepo, stage.cwd) : resolvedRepo;
|
|
73772
74036
|
const extraArgs = options.args ?? [];
|
|
73773
74037
|
const launchFlagArgs = stage.kind === "launch" && options.launchFlags ? buildLaunchFlagArgs(options.launchFlags) : [];
|
|
73774
74038
|
if (stage.command) {
|
|
@@ -73838,19 +74102,19 @@ var LocalScriptExecutor = class {
|
|
|
73838
74102
|
const repoPath = resolveRepoPath(ctx.repoPath);
|
|
73839
74103
|
const harnessDir = getHarnessDir(repoPath);
|
|
73840
74104
|
const artifactsDirName = getArtifactsDir(repoPath);
|
|
73841
|
-
const artifactsDir =
|
|
73842
|
-
if (!
|
|
74105
|
+
const artifactsDir = path26.join(harnessDir, artifactsDirName);
|
|
74106
|
+
if (!fs27.existsSync(artifactsDir)) return [];
|
|
73843
74107
|
const entries = [];
|
|
73844
74108
|
const walk = (dir, prefix) => {
|
|
73845
|
-
for (const entry of
|
|
73846
|
-
const full =
|
|
73847
|
-
const relative3 =
|
|
74109
|
+
for (const entry of fs27.readdirSync(dir, { withFileTypes: true })) {
|
|
74110
|
+
const full = path26.join(dir, entry.name);
|
|
74111
|
+
const relative3 = path26.join(prefix, entry.name);
|
|
73848
74112
|
if (entry.isDirectory()) {
|
|
73849
74113
|
walk(full, relative3);
|
|
73850
74114
|
continue;
|
|
73851
74115
|
}
|
|
73852
74116
|
if (filter2?.stageId && !relative3.includes(filter2.stageId)) continue;
|
|
73853
|
-
const stat =
|
|
74117
|
+
const stat = fs27.statSync(full);
|
|
73854
74118
|
entries.push({
|
|
73855
74119
|
path: full,
|
|
73856
74120
|
relativePath: relative3,
|
|
@@ -73866,19 +74130,19 @@ var LocalScriptExecutor = class {
|
|
|
73866
74130
|
var localScriptExecutor = new LocalScriptExecutor();
|
|
73867
74131
|
|
|
73868
74132
|
// src/core/control-sync.ts
|
|
73869
|
-
var
|
|
74133
|
+
var path44 = __toESM(require("path"));
|
|
73870
74134
|
init_control_config();
|
|
73871
74135
|
|
|
73872
74136
|
// src/core/control-registry.ts
|
|
73873
|
-
var
|
|
74137
|
+
var fs30 = __toESM(require("fs"));
|
|
73874
74138
|
var os6 = __toESM(require("os"));
|
|
73875
|
-
var
|
|
74139
|
+
var path29 = __toESM(require("path"));
|
|
73876
74140
|
|
|
73877
74141
|
// src/core/control-repo-path.ts
|
|
73878
|
-
var
|
|
73879
|
-
var
|
|
74142
|
+
var fs29 = __toESM(require("fs"));
|
|
74143
|
+
var path28 = __toESM(require("path"));
|
|
73880
74144
|
function tryGit(cwd, args) {
|
|
73881
|
-
if (!
|
|
74145
|
+
if (!fs29.existsSync(cwd)) return void 0;
|
|
73882
74146
|
const result = run(`git ${args}`, { cwd });
|
|
73883
74147
|
return result.code === 0 ? result.stdout.trim() : void 0;
|
|
73884
74148
|
}
|
|
@@ -73886,58 +74150,58 @@ function resolveMainWorkingTree(cwd) {
|
|
|
73886
74150
|
const toplevel = tryGit(cwd, "rev-parse --show-toplevel");
|
|
73887
74151
|
if (!toplevel) return void 0;
|
|
73888
74152
|
const commonDirRaw = tryGit(cwd, "rev-parse --git-common-dir");
|
|
73889
|
-
const commonDir = commonDirRaw ?
|
|
73890
|
-
if (!commonDir) return
|
|
73891
|
-
if (
|
|
73892
|
-
return
|
|
74153
|
+
const commonDir = commonDirRaw ? path28.resolve(cwd, commonDirRaw) : void 0;
|
|
74154
|
+
if (!commonDir) return path28.resolve(toplevel);
|
|
74155
|
+
if (path28.basename(commonDir) === ".git") {
|
|
74156
|
+
return path28.dirname(commonDir);
|
|
73893
74157
|
}
|
|
73894
74158
|
const porcelain = tryGit(cwd, "worktree list --porcelain");
|
|
73895
74159
|
if (porcelain) {
|
|
73896
74160
|
for (const line of porcelain.split("\n")) {
|
|
73897
74161
|
if (line.startsWith("worktree ")) {
|
|
73898
|
-
return
|
|
74162
|
+
return path28.resolve(line.slice("worktree ".length));
|
|
73899
74163
|
}
|
|
73900
74164
|
}
|
|
73901
74165
|
}
|
|
73902
|
-
return
|
|
74166
|
+
return path28.resolve(toplevel);
|
|
73903
74167
|
}
|
|
73904
74168
|
function canonicalizeControlRepoPath(repoPath) {
|
|
73905
|
-
const resolved =
|
|
74169
|
+
const resolved = path28.resolve(repoPath);
|
|
73906
74170
|
const toplevel = tryGit(resolved, "rev-parse --show-toplevel");
|
|
73907
74171
|
if (!toplevel) return resolved;
|
|
73908
74172
|
const mainRoot = resolveMainWorkingTree(resolved);
|
|
73909
74173
|
if (!mainRoot) return resolved;
|
|
73910
|
-
const top2 =
|
|
73911
|
-
const main =
|
|
74174
|
+
const top2 = path28.resolve(toplevel);
|
|
74175
|
+
const main = path28.resolve(mainRoot);
|
|
73912
74176
|
if (top2 === main) return resolved;
|
|
73913
|
-
const rel =
|
|
74177
|
+
const rel = path28.relative(top2, resolved);
|
|
73914
74178
|
if (!rel || rel === ".") return main;
|
|
73915
|
-
if (rel.startsWith(`..${
|
|
74179
|
+
if (rel.startsWith(`..${path28.sep}`) || rel === ".." || path28.isAbsolute(rel)) {
|
|
73916
74180
|
return resolved;
|
|
73917
74181
|
}
|
|
73918
|
-
return
|
|
74182
|
+
return path28.resolve(main, rel);
|
|
73919
74183
|
}
|
|
73920
74184
|
|
|
73921
74185
|
// src/core/control-registry.ts
|
|
73922
74186
|
function getRegistryPath() {
|
|
73923
74187
|
if (process.env.HAR_CONTROL_REGISTRY_PATH) {
|
|
73924
|
-
return
|
|
74188
|
+
return path29.resolve(process.env.HAR_CONTROL_REGISTRY_PATH);
|
|
73925
74189
|
}
|
|
73926
|
-
return
|
|
74190
|
+
return path29.join(os6.homedir(), ".har", "repos.json");
|
|
73927
74191
|
}
|
|
73928
74192
|
function readRegistry() {
|
|
73929
74193
|
const registryPath = getRegistryPath();
|
|
73930
74194
|
try {
|
|
73931
|
-
if (!
|
|
73932
|
-
return JSON.parse(
|
|
74195
|
+
if (!fs30.existsSync(registryPath)) return { repos: [] };
|
|
74196
|
+
return JSON.parse(fs30.readFileSync(registryPath, "utf8"));
|
|
73933
74197
|
} catch {
|
|
73934
74198
|
return { repos: [] };
|
|
73935
74199
|
}
|
|
73936
74200
|
}
|
|
73937
74201
|
function writeRegistry(registry2) {
|
|
73938
74202
|
const registryPath = getRegistryPath();
|
|
73939
|
-
|
|
73940
|
-
|
|
74203
|
+
fs30.mkdirSync(path29.dirname(registryPath), { recursive: true });
|
|
74204
|
+
fs30.writeFileSync(registryPath, JSON.stringify(registry2, null, 2) + "\n");
|
|
73941
74205
|
}
|
|
73942
74206
|
function registryChanged(before, after) {
|
|
73943
74207
|
if (before.length !== after.length) return true;
|
|
@@ -73959,7 +74223,7 @@ function removeRegisteredRepo(repoPath) {
|
|
|
73959
74223
|
try {
|
|
73960
74224
|
return canonicalizeControlRepoPath(entry) !== resolved;
|
|
73961
74225
|
} catch {
|
|
73962
|
-
return
|
|
74226
|
+
return path29.resolve(entry) !== resolved;
|
|
73963
74227
|
}
|
|
73964
74228
|
});
|
|
73965
74229
|
if (next.length === registry2.repos.length) return false;
|
|
@@ -73971,9 +74235,9 @@ function listRegisteredRepos() {
|
|
|
73971
74235
|
const kept = [];
|
|
73972
74236
|
const seen = /* @__PURE__ */ new Set();
|
|
73973
74237
|
for (const repoPath of registry2.repos) {
|
|
73974
|
-
if (!
|
|
74238
|
+
if (!fs30.existsSync(repoPath)) continue;
|
|
73975
74239
|
const canonical = canonicalizeControlRepoPath(repoPath);
|
|
73976
|
-
if (!
|
|
74240
|
+
if (!fs30.existsSync(canonical) || !readManifest(canonical)) continue;
|
|
73977
74241
|
if (seen.has(canonical)) continue;
|
|
73978
74242
|
seen.add(canonical);
|
|
73979
74243
|
kept.push(canonical);
|
|
@@ -73995,17 +74259,17 @@ function clearRegisteredRepos() {
|
|
|
73995
74259
|
init_portal_credentials();
|
|
73996
74260
|
|
|
73997
74261
|
// src/core/slot-status.ts
|
|
73998
|
-
var
|
|
74262
|
+
var fs35 = __toESM(require("fs"));
|
|
73999
74263
|
var os9 = __toESM(require("os"));
|
|
74000
|
-
var
|
|
74264
|
+
var path35 = __toESM(require("path"));
|
|
74001
74265
|
var import_child_process8 = require("child_process");
|
|
74002
74266
|
|
|
74003
74267
|
// src/core/runs.ts
|
|
74004
74268
|
var crypto2 = __toESM(require("crypto"));
|
|
74005
74269
|
var import_child_process3 = require("child_process");
|
|
74006
|
-
var
|
|
74270
|
+
var fs31 = __toESM(require("fs"));
|
|
74007
74271
|
var os7 = __toESM(require("os"));
|
|
74008
|
-
var
|
|
74272
|
+
var path30 = __toESM(require("path"));
|
|
74009
74273
|
var RUNS_DIR = "runs";
|
|
74010
74274
|
function gitCommonDir(cwd) {
|
|
74011
74275
|
try {
|
|
@@ -74014,7 +74278,7 @@ function gitCommonDir(cwd) {
|
|
|
74014
74278
|
encoding: "utf8",
|
|
74015
74279
|
stdio: ["pipe", "pipe", "ignore"]
|
|
74016
74280
|
}).trim();
|
|
74017
|
-
return out ?
|
|
74281
|
+
return out ? path30.resolve(cwd, out) : void 0;
|
|
74018
74282
|
} catch {
|
|
74019
74283
|
return void 0;
|
|
74020
74284
|
}
|
|
@@ -74036,7 +74300,7 @@ function gitPrefix(cwd) {
|
|
|
74036
74300
|
}
|
|
74037
74301
|
}
|
|
74038
74302
|
function getRunsDir(harnessRoot) {
|
|
74039
|
-
return
|
|
74303
|
+
return path30.join(getHarnessDir(harnessRoot), RUNS_DIR);
|
|
74040
74304
|
}
|
|
74041
74305
|
function formatLocalDate(d2) {
|
|
74042
74306
|
const y2 = d2.getFullYear();
|
|
@@ -74056,24 +74320,24 @@ function buildRunRelativePath(stageId, agentId, startedAt, runId, runsDir) {
|
|
|
74056
74320
|
const timePart = formatLocalTime(started);
|
|
74057
74321
|
const agentPart = agentId !== void 0 ? `_agent-${agentId}` : "";
|
|
74058
74322
|
let filename = `${timePart}_${stageId}${agentPart}.json`;
|
|
74059
|
-
const fullPath =
|
|
74060
|
-
if (
|
|
74323
|
+
const fullPath = path30.join(runsDir, dateFolder, filename);
|
|
74324
|
+
if (fs31.existsSync(fullPath)) {
|
|
74061
74325
|
filename = `${timePart}_${stageId}${agentPart}-${runId.slice(0, 8)}.json`;
|
|
74062
74326
|
}
|
|
74063
|
-
return
|
|
74327
|
+
return path30.join(dateFolder, filename);
|
|
74064
74328
|
}
|
|
74065
74329
|
function resolveRunFilePath(harnessRoot, run2) {
|
|
74066
74330
|
if (run2.relativePath) {
|
|
74067
|
-
return
|
|
74331
|
+
return path30.join(getRunsDir(harnessRoot), run2.relativePath);
|
|
74068
74332
|
}
|
|
74069
|
-
return
|
|
74333
|
+
return path30.join(getRunsDir(harnessRoot), `${run2.runId}.json`);
|
|
74070
74334
|
}
|
|
74071
74335
|
function collectRunFiles(runsDir) {
|
|
74072
|
-
if (!
|
|
74336
|
+
if (!fs31.existsSync(runsDir)) return [];
|
|
74073
74337
|
const files = [];
|
|
74074
74338
|
const walk = (dir) => {
|
|
74075
|
-
for (const entry of
|
|
74076
|
-
const full =
|
|
74339
|
+
for (const entry of fs31.readdirSync(dir, { withFileTypes: true })) {
|
|
74340
|
+
const full = path30.join(dir, entry.name);
|
|
74077
74341
|
if (entry.isDirectory()) {
|
|
74078
74342
|
walk(full);
|
|
74079
74343
|
} else if (entry.name.endsWith(".json")) {
|
|
@@ -74087,30 +74351,30 @@ function collectRunFiles(runsDir) {
|
|
|
74087
74351
|
function resolveAgentWorkDir(harnessRoot, agentId) {
|
|
74088
74352
|
if (agentId === void 0) return void 0;
|
|
74089
74353
|
const entry = readSlotRegistry(harnessRoot, agentId);
|
|
74090
|
-
if (entry?.workDir &&
|
|
74354
|
+
if (entry?.workDir && fs31.existsSync(entry.workDir)) return entry.workDir;
|
|
74091
74355
|
const env3 = readHarnessEnv(harnessRoot);
|
|
74092
|
-
const projectName = env3.HARNESS_PROJECT_NAME ??
|
|
74093
|
-
const worktreeDir =
|
|
74356
|
+
const projectName = env3.HARNESS_PROJECT_NAME ?? path30.basename(harnessRoot);
|
|
74357
|
+
const worktreeDir = path30.join(os7.homedir(), "worktrees", `${projectName}-agent-${agentId}`);
|
|
74094
74358
|
const relPrefix = gitPrefix(harnessRoot);
|
|
74095
74359
|
const sessionEnvFiles = [];
|
|
74096
|
-
const worktreesRoot =
|
|
74097
|
-
if (
|
|
74360
|
+
const worktreesRoot = path30.join(os7.homedir(), "worktrees");
|
|
74361
|
+
if (fs31.existsSync(worktreesRoot)) {
|
|
74098
74362
|
const suffix = `-har-agent-${agentId}-`;
|
|
74099
|
-
for (const entry2 of
|
|
74363
|
+
for (const entry2 of fs31.readdirSync(worktreesRoot, { withFileTypes: true })) {
|
|
74100
74364
|
if (!entry2.isDirectory() || !entry2.name.includes(suffix)) continue;
|
|
74101
|
-
const sessionDir =
|
|
74365
|
+
const sessionDir = path30.join(worktreesRoot, entry2.name);
|
|
74102
74366
|
if (!sameGitCheckout(harnessRoot, sessionDir)) continue;
|
|
74103
|
-
sessionEnvFiles.push(
|
|
74367
|
+
sessionEnvFiles.push(path30.join(sessionDir, relPrefix, `.env.agent.${agentId}`));
|
|
74104
74368
|
}
|
|
74105
74369
|
}
|
|
74106
74370
|
const candidates = [
|
|
74107
|
-
|
|
74108
|
-
|
|
74371
|
+
path30.join(worktreeDir, `.env.agent.${agentId}`),
|
|
74372
|
+
path30.join(harnessRoot, `.env.agent.${agentId}`),
|
|
74109
74373
|
...sessionEnvFiles.sort()
|
|
74110
74374
|
];
|
|
74111
74375
|
for (const envFile of candidates) {
|
|
74112
|
-
if (!
|
|
74113
|
-
const content =
|
|
74376
|
+
if (!fs31.existsSync(envFile)) continue;
|
|
74377
|
+
const content = fs31.readFileSync(envFile, "utf8");
|
|
74114
74378
|
const match = content.match(/^REPO_ROOT=(.+)$/m);
|
|
74115
74379
|
if (match) return match[1].trim();
|
|
74116
74380
|
}
|
|
@@ -74122,11 +74386,11 @@ function createRun(ctx, meta) {
|
|
|
74122
74386
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
74123
74387
|
const runId = crypto2.randomUUID();
|
|
74124
74388
|
const relativePath = buildRunRelativePath(meta.stageId, meta.agentId, startedAt, runId, runsDir);
|
|
74125
|
-
const runFilePath =
|
|
74126
|
-
|
|
74389
|
+
const runFilePath = path30.join(runsDir, relativePath);
|
|
74390
|
+
fs31.mkdirSync(path30.dirname(runFilePath), { recursive: true });
|
|
74127
74391
|
const run2 = RunRecordSchema.parse({
|
|
74128
74392
|
runId,
|
|
74129
|
-
repoPath:
|
|
74393
|
+
repoPath: path30.resolve(ctx.repoPath),
|
|
74130
74394
|
harnessRoot,
|
|
74131
74395
|
stageId: meta.stageId,
|
|
74132
74396
|
kind: meta.kind,
|
|
@@ -74139,7 +74403,7 @@ function createRun(ctx, meta) {
|
|
|
74139
74403
|
workUnitId: ctx.workUnitId,
|
|
74140
74404
|
attemptId: ctx.attemptId
|
|
74141
74405
|
});
|
|
74142
|
-
|
|
74406
|
+
fs31.writeFileSync(runFilePath, JSON.stringify(run2, null, 2) + "\n");
|
|
74143
74407
|
return run2;
|
|
74144
74408
|
}
|
|
74145
74409
|
function finishRun(repoPath, runId, update) {
|
|
@@ -74158,13 +74422,13 @@ function finishRun(repoPath, runId, update) {
|
|
|
74158
74422
|
finishedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
74159
74423
|
});
|
|
74160
74424
|
const runPath = resolveRunFilePath(harnessRoot, finished);
|
|
74161
|
-
|
|
74425
|
+
fs31.writeFileSync(runPath, JSON.stringify(finished, null, 2) + "\n");
|
|
74162
74426
|
return finished;
|
|
74163
74427
|
}
|
|
74164
74428
|
function findRunRecord(harnessRoot, runId) {
|
|
74165
74429
|
const runsDir = getRunsDir(harnessRoot);
|
|
74166
74430
|
for (const filePath of collectRunFiles(runsDir)) {
|
|
74167
|
-
const parsed = RunRecordSchema.safeParse(JSON.parse(
|
|
74431
|
+
const parsed = RunRecordSchema.safeParse(JSON.parse(fs31.readFileSync(filePath, "utf8")));
|
|
74168
74432
|
if (parsed.success && parsed.data.runId === runId) {
|
|
74169
74433
|
return parsed.data;
|
|
74170
74434
|
}
|
|
@@ -74176,10 +74440,10 @@ function getRun(repoPath, runId) {
|
|
|
74176
74440
|
}
|
|
74177
74441
|
function listRuns(repoPath, filter2 = {}) {
|
|
74178
74442
|
const runsDir = getRunsDir(resolveHarnessRoot(repoPath));
|
|
74179
|
-
if (!
|
|
74443
|
+
if (!fs31.existsSync(runsDir)) return [];
|
|
74180
74444
|
const runs = [];
|
|
74181
74445
|
for (const filePath of collectRunFiles(runsDir)) {
|
|
74182
|
-
const parsed = RunRecordSchema.safeParse(JSON.parse(
|
|
74446
|
+
const parsed = RunRecordSchema.safeParse(JSON.parse(fs31.readFileSync(filePath, "utf8")));
|
|
74183
74447
|
if (!parsed.success) continue;
|
|
74184
74448
|
if (filter2.stageId && parsed.data.stageId !== filter2.stageId) continue;
|
|
74185
74449
|
runs.push(parsed.data);
|
|
@@ -74192,18 +74456,18 @@ function listRuns(repoPath, filter2 = {}) {
|
|
|
74192
74456
|
}
|
|
74193
74457
|
|
|
74194
74458
|
// src/core/slot-preflight.ts
|
|
74195
|
-
var
|
|
74459
|
+
var path34 = __toESM(require("path"));
|
|
74196
74460
|
|
|
74197
74461
|
// src/core/control-port.ts
|
|
74198
74462
|
var import_child_process5 = require("child_process");
|
|
74199
|
-
var
|
|
74200
|
-
var
|
|
74463
|
+
var fs33 = __toESM(require("fs"));
|
|
74464
|
+
var path32 = __toESM(require("path"));
|
|
74201
74465
|
init_control_config();
|
|
74202
74466
|
|
|
74203
74467
|
// src/core/slot-ports.ts
|
|
74204
74468
|
var import_child_process4 = require("child_process");
|
|
74205
|
-
var
|
|
74206
|
-
var
|
|
74469
|
+
var fs32 = __toESM(require("fs"));
|
|
74470
|
+
var path31 = __toESM(require("path"));
|
|
74207
74471
|
function portStep(env3) {
|
|
74208
74472
|
return Number(env3.HARNESS_PORT_STEP ?? 10);
|
|
74209
74473
|
}
|
|
@@ -74259,7 +74523,7 @@ function allocateAppPorts(repoPath, agentId) {
|
|
|
74259
74523
|
}
|
|
74260
74524
|
function harnessUsesPm2(repoPath) {
|
|
74261
74525
|
const harnessRoot = resolveHarnessRoot(repoPath);
|
|
74262
|
-
return
|
|
74526
|
+
return fs32.existsSync(path31.join(harnessRoot, ".har", "ecosystem.agent.template.cjs"));
|
|
74263
74527
|
}
|
|
74264
74528
|
|
|
74265
74529
|
// src/core/control-port.ts
|
|
@@ -74314,13 +74578,13 @@ function controlDefaultPortWarnings(containers, defaultFrontendPort, allocatedFr
|
|
|
74314
74578
|
return [formatControlDefaultPortWarning(control.name, defaultFrontendPort, allocatedFrontend)];
|
|
74315
74579
|
}
|
|
74316
74580
|
function inspectControlUpReadiness(repoPath) {
|
|
74317
|
-
const resolved =
|
|
74581
|
+
const resolved = path32.resolve(repoPath);
|
|
74318
74582
|
const port = parseControlHostPort();
|
|
74319
74583
|
const containers = listDockerContainers();
|
|
74320
74584
|
const control = controlContainerOnPort(containers, port);
|
|
74321
74585
|
const warnings = [];
|
|
74322
|
-
const controlHarnessDir =
|
|
74323
|
-
const harnessSlot1Active =
|
|
74586
|
+
const controlHarnessDir = path32.join(resolved, "control", ".har");
|
|
74587
|
+
const harnessSlot1Active = fs33.existsSync(controlHarnessDir) && readSlotRegistry(path32.join(resolved, "control"), 1)?.status === "active";
|
|
74324
74588
|
if (control) {
|
|
74325
74589
|
return {
|
|
74326
74590
|
warnings,
|
|
@@ -74351,9 +74615,9 @@ function inspectControlUpReadiness(repoPath) {
|
|
|
74351
74615
|
}
|
|
74352
74616
|
|
|
74353
74617
|
// src/core/slot-launch-guard-occupied.ts
|
|
74354
|
-
var
|
|
74618
|
+
var fs34 = __toESM(require("fs"));
|
|
74355
74619
|
var os8 = __toESM(require("os"));
|
|
74356
|
-
var
|
|
74620
|
+
var path33 = __toESM(require("path"));
|
|
74357
74621
|
var import_child_process6 = require("child_process");
|
|
74358
74622
|
function runGit(cwd, args) {
|
|
74359
74623
|
try {
|
|
@@ -74372,7 +74636,7 @@ function worktreeDirty(worktreePath) {
|
|
|
74372
74636
|
}
|
|
74373
74637
|
function gitCommonDir2(cwd) {
|
|
74374
74638
|
const out = runGit(cwd, "rev-parse --git-common-dir");
|
|
74375
|
-
return out ?
|
|
74639
|
+
return out ? path33.resolve(cwd, out) : void 0;
|
|
74376
74640
|
}
|
|
74377
74641
|
function sameGitCheckout2(a2, b3) {
|
|
74378
74642
|
const left2 = gitCommonDir2(a2);
|
|
@@ -74381,20 +74645,20 @@ function sameGitCheckout2(a2, b3) {
|
|
|
74381
74645
|
}
|
|
74382
74646
|
function discoverWorktree(harnessRoot, agentId, projectName) {
|
|
74383
74647
|
const session = readSlotRegistry(harnessRoot, agentId);
|
|
74384
|
-
if (session?.worktreePath &&
|
|
74648
|
+
if (session?.worktreePath && fs34.existsSync(session.worktreePath)) {
|
|
74385
74649
|
return session.worktreePath;
|
|
74386
74650
|
}
|
|
74387
|
-
const legacy =
|
|
74388
|
-
if (
|
|
74389
|
-
const worktreesRoot =
|
|
74390
|
-
if (!
|
|
74651
|
+
const legacy = path33.join(os8.homedir(), "worktrees", `${projectName}-agent-${agentId}`);
|
|
74652
|
+
if (fs34.existsSync(legacy) && sameGitCheckout2(harnessRoot, legacy)) return legacy;
|
|
74653
|
+
const worktreesRoot = path33.join(os8.homedir(), "worktrees");
|
|
74654
|
+
if (!fs34.existsSync(worktreesRoot)) return void 0;
|
|
74391
74655
|
const suffix = `-har-agent-${agentId}-`;
|
|
74392
74656
|
const relPrefix = runGit(harnessRoot, "rev-parse --show-prefix") ?? "";
|
|
74393
|
-
for (const name of
|
|
74657
|
+
for (const name of fs34.readdirSync(worktreesRoot)) {
|
|
74394
74658
|
if (!name.includes(suffix)) continue;
|
|
74395
|
-
const candidate =
|
|
74659
|
+
const candidate = path33.join(worktreesRoot, name);
|
|
74396
74660
|
if (!sameGitCheckout2(harnessRoot, candidate)) continue;
|
|
74397
|
-
if (!
|
|
74661
|
+
if (!fs34.existsSync(path33.join(candidate, relPrefix, `.env.agent.${agentId}`))) continue;
|
|
74398
74662
|
return candidate;
|
|
74399
74663
|
}
|
|
74400
74664
|
return void 0;
|
|
@@ -74402,13 +74666,13 @@ function discoverWorktree(harnessRoot, agentId, projectName) {
|
|
|
74402
74666
|
function collectOccupiedSlot(repoPath, agentId) {
|
|
74403
74667
|
const harnessRoot = resolveHarnessRoot(repoPath);
|
|
74404
74668
|
const env3 = readHarnessEnv(harnessRoot);
|
|
74405
|
-
const projectName = env3.HARNESS_PROJECT_NAME ??
|
|
74669
|
+
const projectName = env3.HARNESS_PROJECT_NAME ?? path33.basename(harnessRoot);
|
|
74406
74670
|
const session = readSlotRegistry(harnessRoot, agentId);
|
|
74407
74671
|
const worktreePath = discoverWorktree(harnessRoot, agentId, projectName);
|
|
74408
74672
|
const workDir = session?.workDir;
|
|
74409
|
-
const envInWorkDir = workDir ?
|
|
74410
|
-
const envInRoot =
|
|
74411
|
-
const envInWorktree = worktreePath ?
|
|
74673
|
+
const envInWorkDir = workDir ? fs34.existsSync(path33.join(workDir, `.env.agent.${agentId}`)) : false;
|
|
74674
|
+
const envInRoot = fs34.existsSync(path33.join(harnessRoot, `.env.agent.${agentId}`));
|
|
74675
|
+
const envInWorktree = worktreePath ? fs34.existsSync(path33.join(worktreePath, `.env.agent.${agentId}`)) : false;
|
|
74412
74676
|
const active = session !== void 0 && session.status !== "completed" || envInWorkDir || envInRoot || envInWorktree;
|
|
74413
74677
|
if (!active) return void 0;
|
|
74414
74678
|
const dirty = worktreePath ? worktreeDirty(worktreePath) : void 0;
|
|
@@ -74574,7 +74838,7 @@ function checkInfraPort(env3, varName, defaultPort, scanStart, scanEnd) {
|
|
|
74574
74838
|
function inspectSlotReadiness(repoPath, agentId, options = {}) {
|
|
74575
74839
|
const harnessRoot = resolveHarnessRoot(repoPath);
|
|
74576
74840
|
const env3 = readHarnessEnv(harnessRoot);
|
|
74577
|
-
const projectName = env3.HARNESS_PROJECT_NAME ??
|
|
74841
|
+
const projectName = env3.HARNESS_PROJECT_NAME ?? path34.basename(harnessRoot);
|
|
74578
74842
|
const usesPm2 = harnessUsesPm2(repoPath);
|
|
74579
74843
|
const blockers = [];
|
|
74580
74844
|
const remediations = [];
|
|
@@ -74776,7 +75040,7 @@ function readWorktreeBranch(worktreePath) {
|
|
|
74776
75040
|
}
|
|
74777
75041
|
function gitCommonDir3(cwd) {
|
|
74778
75042
|
const out = runGit2(cwd, "rev-parse --git-common-dir");
|
|
74779
|
-
return out ?
|
|
75043
|
+
return out ? path35.resolve(cwd, out) : void 0;
|
|
74780
75044
|
}
|
|
74781
75045
|
function sameGitCheckout3(a2, b3) {
|
|
74782
75046
|
const left2 = gitCommonDir3(a2);
|
|
@@ -74788,12 +75052,12 @@ function gitPrefix2(cwd) {
|
|
|
74788
75052
|
return out ?? "";
|
|
74789
75053
|
}
|
|
74790
75054
|
function discoverSessionWorktreePath(harnessRoot, agentId) {
|
|
74791
|
-
const worktreesRoot =
|
|
74792
|
-
if (!
|
|
75055
|
+
const worktreesRoot = path35.join(os9.homedir(), "worktrees");
|
|
75056
|
+
if (!fs35.existsSync(worktreesRoot)) return void 0;
|
|
74793
75057
|
const suffix = `-har-agent-${agentId}-`;
|
|
74794
75058
|
const relPrefix = gitPrefix2(harnessRoot);
|
|
74795
|
-
const matches =
|
|
74796
|
-
(candidate) => sameGitCheckout3(harnessRoot, candidate) &&
|
|
75059
|
+
const matches = fs35.readdirSync(worktreesRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory() && entry.name.includes(suffix)).map((entry) => path35.join(worktreesRoot, entry.name)).filter(
|
|
75060
|
+
(candidate) => sameGitCheckout3(harnessRoot, candidate) && fs35.existsSync(path35.join(candidate, relPrefix, `.env.agent.${agentId}`))
|
|
74797
75061
|
);
|
|
74798
75062
|
return matches.sort()[0];
|
|
74799
75063
|
}
|
|
@@ -74868,18 +75132,18 @@ function detectPm2Issue(projectName, agentId, session, procs) {
|
|
|
74868
75132
|
}
|
|
74869
75133
|
function collectSlotStatus(harnessRoot, agentId, runs, pm2Procs) {
|
|
74870
75134
|
const env3 = readHarnessEnv(harnessRoot);
|
|
74871
|
-
const projectName = env3.HARNESS_PROJECT_NAME ??
|
|
75135
|
+
const projectName = env3.HARNESS_PROJECT_NAME ?? path35.basename(harnessRoot);
|
|
74872
75136
|
const session = readSlotRegistry(harnessRoot, agentId);
|
|
74873
|
-
const legacyWorktreePath =
|
|
75137
|
+
const legacyWorktreePath = path35.join(
|
|
74874
75138
|
os9.homedir(),
|
|
74875
75139
|
"worktrees",
|
|
74876
75140
|
`${projectName}-agent-${agentId}`
|
|
74877
75141
|
);
|
|
74878
|
-
const worktreePath = session?.worktreePath &&
|
|
75142
|
+
const worktreePath = session?.worktreePath && fs35.existsSync(session.worktreePath) ? session.worktreePath : fs35.existsSync(legacyWorktreePath) ? legacyWorktreePath : discoverSessionWorktreePath(harnessRoot, agentId);
|
|
74879
75143
|
const workDir = resolveAgentWorkDir(harnessRoot, agentId);
|
|
74880
|
-
const envInWorkDir = workDir ?
|
|
74881
|
-
const envInRoot =
|
|
74882
|
-
const envInWorktree = worktreePath ?
|
|
75144
|
+
const envInWorkDir = workDir ? fs35.existsSync(path35.join(workDir, `.env.agent.${agentId}`)) : false;
|
|
75145
|
+
const envInRoot = fs35.existsSync(path35.join(harnessRoot, `.env.agent.${agentId}`));
|
|
75146
|
+
const envInWorktree = worktreePath ? fs35.existsSync(path35.join(worktreePath, `.env.agent.${agentId}`)) : false;
|
|
74883
75147
|
const active = session !== void 0 && session.status !== "completed" || envInWorkDir || envInRoot || envInWorktree;
|
|
74884
75148
|
const latest = latestRunForAgent(runs, agentId);
|
|
74885
75149
|
const verifyRun = runs.find((r2) => r2.agentId === agentId && r2.stageId === "verify");
|
|
@@ -74933,7 +75197,7 @@ function collectEnvironmentStatus(repoPath) {
|
|
|
74933
75197
|
const slotIds = getAgentSlotIds(harnessRoot);
|
|
74934
75198
|
const pm2Procs = listPm2Processes2();
|
|
74935
75199
|
return {
|
|
74936
|
-
repoPath:
|
|
75200
|
+
repoPath: path35.resolve(repoPath),
|
|
74937
75201
|
harnessRoot,
|
|
74938
75202
|
gitRemote: readGitRemote(harnessRoot),
|
|
74939
75203
|
profile: manifest?.profile,
|
|
@@ -74944,13 +75208,13 @@ function collectEnvironmentStatus(repoPath) {
|
|
|
74944
75208
|
|
|
74945
75209
|
// src/core/validations.ts
|
|
74946
75210
|
var crypto3 = __toESM(require("crypto"));
|
|
74947
|
-
var
|
|
74948
|
-
var
|
|
75211
|
+
var fs37 = __toESM(require("fs"));
|
|
75212
|
+
var path37 = __toESM(require("path"));
|
|
74949
75213
|
|
|
74950
75214
|
// src/core/change-batch.ts
|
|
74951
|
-
var
|
|
75215
|
+
var fs36 = __toESM(require("fs"));
|
|
74952
75216
|
var os10 = __toESM(require("os"));
|
|
74953
|
-
var
|
|
75217
|
+
var path36 = __toESM(require("path"));
|
|
74954
75218
|
function git(checkoutDir, args, env3) {
|
|
74955
75219
|
const result = run(`git ${args}`, { cwd: checkoutDir, env: env3 });
|
|
74956
75220
|
if (result.code !== 0) {
|
|
@@ -74966,7 +75230,7 @@ function isCheckoutRoot(checkoutDir) {
|
|
|
74966
75230
|
const toplevel = tryGit2(checkoutDir, "rev-parse --show-toplevel");
|
|
74967
75231
|
if (!toplevel) return false;
|
|
74968
75232
|
try {
|
|
74969
|
-
return
|
|
75233
|
+
return fs36.realpathSync(toplevel) === fs36.realpathSync(checkoutDir);
|
|
74970
75234
|
} catch {
|
|
74971
75235
|
return false;
|
|
74972
75236
|
}
|
|
@@ -74988,7 +75252,7 @@ function isMergeOrRebaseInProgress(checkoutDir) {
|
|
|
74988
75252
|
if (tryGit2(checkoutDir, "rev-parse -q --verify MERGE_HEAD") !== void 0) return true;
|
|
74989
75253
|
for (const dir of ["rebase-merge", "rebase-apply"]) {
|
|
74990
75254
|
const gitPath = tryGit2(checkoutDir, `rev-parse --git-path ${dir}`);
|
|
74991
|
-
if (gitPath &&
|
|
75255
|
+
if (gitPath && fs36.existsSync(path36.resolve(checkoutDir, gitPath))) return true;
|
|
74992
75256
|
}
|
|
74993
75257
|
return false;
|
|
74994
75258
|
}
|
|
@@ -75011,8 +75275,8 @@ function parseNameStatus(output) {
|
|
|
75011
75275
|
return files;
|
|
75012
75276
|
}
|
|
75013
75277
|
function computeWorktreeSnapshot(checkoutDir) {
|
|
75014
|
-
const tmpDir =
|
|
75015
|
-
const tmpIndex =
|
|
75278
|
+
const tmpDir = fs36.mkdtempSync(path36.join(os10.tmpdir(), "har-idx-"));
|
|
75279
|
+
const tmpIndex = path36.join(tmpDir, "index");
|
|
75016
75280
|
const env3 = { GIT_INDEX_FILE: tmpIndex };
|
|
75017
75281
|
try {
|
|
75018
75282
|
const headTree = getHeadTree(checkoutDir);
|
|
@@ -75035,7 +75299,7 @@ function computeWorktreeSnapshot(checkoutDir) {
|
|
|
75035
75299
|
changedFiles: parseNameStatus(diffOutput)
|
|
75036
75300
|
};
|
|
75037
75301
|
} finally {
|
|
75038
|
-
|
|
75302
|
+
fs36.rmSync(tmpDir, { recursive: true, force: true });
|
|
75039
75303
|
}
|
|
75040
75304
|
}
|
|
75041
75305
|
|
|
@@ -75048,28 +75312,28 @@ function resolveValidationCheckoutDir(input) {
|
|
|
75048
75312
|
return candidates.find(isCheckoutRoot) ?? candidates[0] ?? input.harnessRoot;
|
|
75049
75313
|
}
|
|
75050
75314
|
function getValidationsDir(checkoutDir) {
|
|
75051
|
-
return
|
|
75315
|
+
return path37.join(checkoutDir, ".har", VALIDATIONS_DIR);
|
|
75052
75316
|
}
|
|
75053
75317
|
function validationPath(checkoutDir, treeHash) {
|
|
75054
|
-
return
|
|
75318
|
+
return path37.join(getValidationsDir(checkoutDir), `${treeHash}.json`);
|
|
75055
75319
|
}
|
|
75056
75320
|
function writeRecord(checkoutDir, record2) {
|
|
75057
75321
|
const dir = getValidationsDir(checkoutDir);
|
|
75058
|
-
|
|
75059
|
-
|
|
75322
|
+
fs37.mkdirSync(dir, { recursive: true });
|
|
75323
|
+
fs37.writeFileSync(
|
|
75060
75324
|
validationPath(checkoutDir, record2.treeHash),
|
|
75061
75325
|
`${JSON.stringify(record2, null, 2)}
|
|
75062
75326
|
`
|
|
75063
75327
|
);
|
|
75064
75328
|
}
|
|
75065
75329
|
function ensureValidationsIgnored(checkoutDir) {
|
|
75066
|
-
const harDir =
|
|
75067
|
-
if (!
|
|
75068
|
-
const gitignorePath =
|
|
75069
|
-
const content =
|
|
75330
|
+
const harDir = path37.join(checkoutDir, ".har");
|
|
75331
|
+
if (!fs37.existsSync(harDir)) return;
|
|
75332
|
+
const gitignorePath = path37.join(harDir, ".gitignore");
|
|
75333
|
+
const content = fs37.existsSync(gitignorePath) ? fs37.readFileSync(gitignorePath, "utf8") : "";
|
|
75070
75334
|
if (content.split("\n").some((line) => line.trim() === `${VALIDATIONS_DIR}/`)) return;
|
|
75071
75335
|
const suffix = content.length === 0 || content.endsWith("\n") ? "" : "\n";
|
|
75072
|
-
|
|
75336
|
+
fs37.writeFileSync(gitignorePath, `${content}${suffix}${VALIDATIONS_DIR}/
|
|
75073
75337
|
`);
|
|
75074
75338
|
}
|
|
75075
75339
|
function recordValidation(input) {
|
|
@@ -75086,8 +75350,8 @@ function recordValidation(input) {
|
|
|
75086
75350
|
treeHash: snapshot.treeHash,
|
|
75087
75351
|
headSha: snapshot.headSha,
|
|
75088
75352
|
branch: snapshot.branch,
|
|
75089
|
-
workDir:
|
|
75090
|
-
harnessRoot:
|
|
75353
|
+
workDir: path37.resolve(input.checkoutDir),
|
|
75354
|
+
harnessRoot: path37.resolve(input.harnessRoot),
|
|
75091
75355
|
agentId: input.agentId,
|
|
75092
75356
|
status: input.status,
|
|
75093
75357
|
full: input.full,
|
|
@@ -75099,16 +75363,16 @@ function recordValidation(input) {
|
|
|
75099
75363
|
committedAt: existing?.committedAt
|
|
75100
75364
|
});
|
|
75101
75365
|
writeRecord(input.checkoutDir, record2);
|
|
75102
|
-
if (
|
|
75366
|
+
if (path37.resolve(input.harnessRoot) !== path37.resolve(input.checkoutDir)) {
|
|
75103
75367
|
writeRecord(input.harnessRoot, record2);
|
|
75104
75368
|
}
|
|
75105
75369
|
return record2;
|
|
75106
75370
|
}
|
|
75107
75371
|
function findValidation(checkoutDir, treeHash) {
|
|
75108
75372
|
const file = validationPath(checkoutDir, treeHash);
|
|
75109
|
-
if (!
|
|
75373
|
+
if (!fs37.existsSync(file)) return void 0;
|
|
75110
75374
|
try {
|
|
75111
|
-
return ValidationRecordSchema.parse(JSON.parse(
|
|
75375
|
+
return ValidationRecordSchema.parse(JSON.parse(fs37.readFileSync(file, "utf8")));
|
|
75112
75376
|
} catch {
|
|
75113
75377
|
return void 0;
|
|
75114
75378
|
}
|
|
@@ -75123,19 +75387,19 @@ function attachCommit(checkoutDir, treeHash, commitSha) {
|
|
|
75123
75387
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
75124
75388
|
};
|
|
75125
75389
|
writeRecord(checkoutDir, updated);
|
|
75126
|
-
if (record2.harnessRoot &&
|
|
75390
|
+
if (record2.harnessRoot && path37.resolve(record2.harnessRoot) !== path37.resolve(checkoutDir) && fs37.existsSync(path37.join(record2.harnessRoot, ".har"))) {
|
|
75127
75391
|
writeRecord(record2.harnessRoot, updated);
|
|
75128
75392
|
}
|
|
75129
75393
|
return updated;
|
|
75130
75394
|
}
|
|
75131
75395
|
function listValidations(harnessRoot) {
|
|
75132
75396
|
const dir = getValidationsDir(harnessRoot);
|
|
75133
|
-
if (!
|
|
75397
|
+
if (!fs37.existsSync(dir)) return [];
|
|
75134
75398
|
const records = [];
|
|
75135
|
-
for (const entry of
|
|
75399
|
+
for (const entry of fs37.readdirSync(dir)) {
|
|
75136
75400
|
if (!entry.endsWith(".json")) continue;
|
|
75137
75401
|
try {
|
|
75138
|
-
records.push(ValidationRecordSchema.parse(JSON.parse(
|
|
75402
|
+
records.push(ValidationRecordSchema.parse(JSON.parse(fs37.readFileSync(path37.join(dir, entry), "utf8"))));
|
|
75139
75403
|
} catch {
|
|
75140
75404
|
}
|
|
75141
75405
|
}
|
|
@@ -75144,46 +75408,46 @@ function listValidations(harnessRoot) {
|
|
|
75144
75408
|
|
|
75145
75409
|
// src/core/work-units.ts
|
|
75146
75410
|
var crypto4 = __toESM(require("crypto"));
|
|
75147
|
-
var
|
|
75148
|
-
var
|
|
75411
|
+
var fs38 = __toESM(require("fs"));
|
|
75412
|
+
var path38 = __toESM(require("path"));
|
|
75149
75413
|
var WORK_UNITS_DIR = "work-units";
|
|
75150
75414
|
var WORK_ATTEMPTS_DIR = "work-attempts";
|
|
75151
75415
|
var VALIDATION_BINDINGS_DIR = "validation-bindings";
|
|
75152
75416
|
var EVIDENCE_DIRS = [WORK_UNITS_DIR, WORK_ATTEMPTS_DIR, VALIDATION_BINDINGS_DIR];
|
|
75153
75417
|
function harEvidenceDir(harnessRoot, name) {
|
|
75154
|
-
return
|
|
75418
|
+
return path38.join(harnessRoot, ".har", name);
|
|
75155
75419
|
}
|
|
75156
75420
|
function hashedRecordPath(harnessRoot, dir, id) {
|
|
75157
75421
|
const digest = crypto4.createHash("sha256").update(id).digest("hex");
|
|
75158
|
-
return
|
|
75422
|
+
return path38.join(harEvidenceDir(harnessRoot, dir), `${digest}.json`);
|
|
75159
75423
|
}
|
|
75160
75424
|
function writeRecord2(file, value) {
|
|
75161
|
-
|
|
75425
|
+
fs38.mkdirSync(path38.dirname(file), { recursive: true });
|
|
75162
75426
|
const temp = `${file}.${process.pid}.tmp`;
|
|
75163
|
-
|
|
75427
|
+
fs38.writeFileSync(temp, `${JSON.stringify(value, null, 2)}
|
|
75164
75428
|
`);
|
|
75165
|
-
|
|
75429
|
+
fs38.renameSync(temp, file);
|
|
75166
75430
|
}
|
|
75167
75431
|
function ensureWorkEvidenceIgnored(harnessRoot) {
|
|
75168
|
-
const harDir =
|
|
75169
|
-
if (!
|
|
75170
|
-
const gitignorePath =
|
|
75171
|
-
const content =
|
|
75432
|
+
const harDir = path38.join(harnessRoot, ".har");
|
|
75433
|
+
if (!fs38.existsSync(harDir)) return;
|
|
75434
|
+
const gitignorePath = path38.join(harDir, ".gitignore");
|
|
75435
|
+
const content = fs38.existsSync(gitignorePath) ? fs38.readFileSync(gitignorePath, "utf8") : "";
|
|
75172
75436
|
const lines2 = new Set(content.split("\n").map((line) => line.trim()));
|
|
75173
75437
|
const missing = EVIDENCE_DIRS.map((dir) => `${dir}/`).filter((dir) => !lines2.has(dir));
|
|
75174
75438
|
if (missing.length === 0) return;
|
|
75175
75439
|
const separator = content.length === 0 || content.endsWith("\n") ? "" : "\n";
|
|
75176
|
-
|
|
75440
|
+
fs38.writeFileSync(gitignorePath, `${content}${separator}${missing.join("\n")}
|
|
75177
75441
|
`);
|
|
75178
75442
|
}
|
|
75179
75443
|
function listRecords(harnessRoot, dir, parse4) {
|
|
75180
75444
|
const recordDir = harEvidenceDir(harnessRoot, dir);
|
|
75181
|
-
if (!
|
|
75445
|
+
if (!fs38.existsSync(recordDir)) return [];
|
|
75182
75446
|
const records = [];
|
|
75183
|
-
for (const name of
|
|
75447
|
+
for (const name of fs38.readdirSync(recordDir)) {
|
|
75184
75448
|
if (!name.endsWith(".json")) continue;
|
|
75185
75449
|
try {
|
|
75186
|
-
records.push(parse4(JSON.parse(
|
|
75450
|
+
records.push(parse4(JSON.parse(fs38.readFileSync(path38.join(recordDir, name), "utf8"))));
|
|
75187
75451
|
} catch {
|
|
75188
75452
|
}
|
|
75189
75453
|
}
|
|
@@ -75192,9 +75456,9 @@ function listRecords(harnessRoot, dir, parse4) {
|
|
|
75192
75456
|
function findWorkUnit(harnessRoot, workUnitId) {
|
|
75193
75457
|
const metadata = WorkUnitMetadataSchema.parse({ workUnitId });
|
|
75194
75458
|
const file = hashedRecordPath(harnessRoot, WORK_UNITS_DIR, metadata.workUnitId);
|
|
75195
|
-
if (!
|
|
75459
|
+
if (!fs38.existsSync(file)) return void 0;
|
|
75196
75460
|
try {
|
|
75197
|
-
return WorkUnitRecordSchema.parse(JSON.parse(
|
|
75461
|
+
return WorkUnitRecordSchema.parse(JSON.parse(fs38.readFileSync(file, "utf8")));
|
|
75198
75462
|
} catch {
|
|
75199
75463
|
return void 0;
|
|
75200
75464
|
}
|
|
@@ -75271,10 +75535,10 @@ function bindValidationToAttempt(harnessRoot, input) {
|
|
|
75271
75535
|
VALIDATION_BINDINGS_DIR,
|
|
75272
75536
|
stableKey
|
|
75273
75537
|
);
|
|
75274
|
-
if (
|
|
75538
|
+
if (fs38.existsSync(existingFile)) {
|
|
75275
75539
|
try {
|
|
75276
75540
|
return ValidationBindingRecordSchema.parse(
|
|
75277
|
-
JSON.parse(
|
|
75541
|
+
JSON.parse(fs38.readFileSync(existingFile, "utf8"))
|
|
75278
75542
|
);
|
|
75279
75543
|
} catch {
|
|
75280
75544
|
}
|
|
@@ -75335,14 +75599,14 @@ function createRemoteExecutor(apiUrl, apiKey) {
|
|
|
75335
75599
|
init_telemetry_config();
|
|
75336
75600
|
|
|
75337
75601
|
// src/core/usage-harvest/claude.ts
|
|
75338
|
-
var
|
|
75602
|
+
var fs40 = __toESM(require("fs"));
|
|
75339
75603
|
var os11 = __toESM(require("os"));
|
|
75340
|
-
var
|
|
75604
|
+
var path40 = __toESM(require("path"));
|
|
75341
75605
|
init_telemetry_config();
|
|
75342
75606
|
|
|
75343
75607
|
// src/core/telemetry-env.ts
|
|
75344
|
-
var
|
|
75345
|
-
var
|
|
75608
|
+
var fs39 = __toESM(require("fs"));
|
|
75609
|
+
var path39 = __toESM(require("path"));
|
|
75346
75610
|
init_control_config();
|
|
75347
75611
|
function escapeAttrValue(value) {
|
|
75348
75612
|
return value.replace(/[,=]/g, "_");
|
|
@@ -75388,8 +75652,8 @@ function appendTelemetryEnvToFile(envFilePath, attrs) {
|
|
|
75388
75652
|
${TELEMETRY_MARKER_END}
|
|
75389
75653
|
`;
|
|
75390
75654
|
let existing = "";
|
|
75391
|
-
if (
|
|
75392
|
-
existing =
|
|
75655
|
+
if (fs39.existsSync(envFilePath)) {
|
|
75656
|
+
existing = fs39.readFileSync(envFilePath, "utf8");
|
|
75393
75657
|
const start = existing.indexOf(TELEMETRY_MARKER_START);
|
|
75394
75658
|
if (start >= 0) {
|
|
75395
75659
|
const end = existing.indexOf(TELEMETRY_MARKER_END, start);
|
|
@@ -75400,28 +75664,28 @@ ${TELEMETRY_MARKER_END}
|
|
|
75400
75664
|
}
|
|
75401
75665
|
}
|
|
75402
75666
|
}
|
|
75403
|
-
|
|
75667
|
+
fs39.mkdirSync(path39.dirname(envFilePath), { recursive: true });
|
|
75404
75668
|
const combined = (existing.replace(/\n+$/, "\n") + block).replace(/^\n+/, "");
|
|
75405
|
-
|
|
75669
|
+
fs39.writeFileSync(envFilePath, combined.endsWith("\n") ? combined : combined + "\n");
|
|
75406
75670
|
}
|
|
75407
75671
|
|
|
75408
75672
|
// src/core/usage-harvest/claude.ts
|
|
75409
75673
|
function pathsMatch(candidate, targets) {
|
|
75410
|
-
const norm =
|
|
75674
|
+
const norm = path40.resolve(candidate);
|
|
75411
75675
|
return targets.some((t2) => {
|
|
75412
|
-
const target =
|
|
75413
|
-
return norm === target || norm.startsWith(target +
|
|
75676
|
+
const target = path40.resolve(t2);
|
|
75677
|
+
return norm === target || norm.startsWith(target + path40.sep) || target.startsWith(norm + path40.sep);
|
|
75414
75678
|
});
|
|
75415
75679
|
}
|
|
75416
75680
|
function claudeProjectsRoot() {
|
|
75417
|
-
return process.env.HAR_CLAUDE_PROJECTS_DIR ?
|
|
75681
|
+
return process.env.HAR_CLAUDE_PROJECTS_DIR ? path40.resolve(process.env.HAR_CLAUDE_PROJECTS_DIR) : path40.join(os11.homedir(), ".claude", "projects");
|
|
75418
75682
|
}
|
|
75419
75683
|
function encodeClaudeProjectDir(cwd) {
|
|
75420
75684
|
return cwd.replace(/[^a-zA-Z0-9]/g, "-");
|
|
75421
75685
|
}
|
|
75422
75686
|
function readJsonlRecords(filePath) {
|
|
75423
|
-
if (!
|
|
75424
|
-
const lines2 =
|
|
75687
|
+
if (!fs40.existsSync(filePath)) return [];
|
|
75688
|
+
const lines2 = fs40.readFileSync(filePath, "utf8").split(/\r?\n/);
|
|
75425
75689
|
const out = [];
|
|
75426
75690
|
for (const line of lines2) {
|
|
75427
75691
|
const trimmed = line.trim();
|
|
@@ -75485,16 +75749,16 @@ function findMatchingClaudeTranscripts(slot) {
|
|
|
75485
75749
|
const targets = [slot.workDir, slot.worktreePath].filter(Boolean);
|
|
75486
75750
|
if (targets.length === 0) return [];
|
|
75487
75751
|
const root = claudeProjectsRoot();
|
|
75488
|
-
if (!
|
|
75752
|
+
if (!fs40.existsSync(root)) return [];
|
|
75489
75753
|
const matches = [];
|
|
75490
|
-
for (const entry of
|
|
75754
|
+
for (const entry of fs40.readdirSync(root, { withFileTypes: true })) {
|
|
75491
75755
|
if (!entry.isDirectory()) continue;
|
|
75492
|
-
const projectDir =
|
|
75756
|
+
const projectDir = path40.join(root, entry.name);
|
|
75493
75757
|
const encodedHit = targets.some((t2) => entry.name.includes(encodeClaudeProjectDir(t2).slice(0, 40)));
|
|
75494
|
-
for (const file of
|
|
75758
|
+
for (const file of fs40.readdirSync(projectDir)) {
|
|
75495
75759
|
if (!file.endsWith(".jsonl")) continue;
|
|
75496
|
-
const filePath =
|
|
75497
|
-
const stat =
|
|
75760
|
+
const filePath = path40.join(projectDir, file);
|
|
75761
|
+
const stat = fs40.statSync(filePath);
|
|
75498
75762
|
const records = readJsonlRecords(filePath);
|
|
75499
75763
|
let cwdHit = encodedHit;
|
|
75500
75764
|
for (const record2 of records) {
|
|
@@ -75606,30 +75870,30 @@ function harvestClaudeEvents(slot) {
|
|
|
75606
75870
|
}
|
|
75607
75871
|
|
|
75608
75872
|
// src/core/usage-harvest/codex.ts
|
|
75609
|
-
var
|
|
75873
|
+
var fs41 = __toESM(require("fs"));
|
|
75610
75874
|
var os12 = __toESM(require("os"));
|
|
75611
|
-
var
|
|
75875
|
+
var path41 = __toESM(require("path"));
|
|
75612
75876
|
function pathsMatch2(candidate, targets) {
|
|
75613
|
-
const norm =
|
|
75877
|
+
const norm = path41.resolve(candidate);
|
|
75614
75878
|
return targets.some((t2) => {
|
|
75615
|
-
const target =
|
|
75616
|
-
return norm === target || norm.startsWith(target +
|
|
75879
|
+
const target = path41.resolve(t2);
|
|
75880
|
+
return norm === target || norm.startsWith(target + path41.sep) || target.startsWith(norm + path41.sep);
|
|
75617
75881
|
});
|
|
75618
75882
|
}
|
|
75619
75883
|
function codexSessionsRoot() {
|
|
75620
|
-
return process.env.HAR_CODEX_SESSIONS_DIR ?
|
|
75884
|
+
return process.env.HAR_CODEX_SESSIONS_DIR ? path41.resolve(process.env.HAR_CODEX_SESSIONS_DIR) : path41.join(os12.homedir(), ".codex", "sessions");
|
|
75621
75885
|
}
|
|
75622
75886
|
function walkJsonlFiles(dir, out = []) {
|
|
75623
|
-
if (!
|
|
75624
|
-
for (const entry of
|
|
75625
|
-
const full =
|
|
75887
|
+
if (!fs41.existsSync(dir)) return out;
|
|
75888
|
+
for (const entry of fs41.readdirSync(dir, { withFileTypes: true })) {
|
|
75889
|
+
const full = path41.join(dir, entry.name);
|
|
75626
75890
|
if (entry.isDirectory()) walkJsonlFiles(full, out);
|
|
75627
75891
|
else if (entry.isFile() && entry.name.endsWith(".jsonl")) out.push(full);
|
|
75628
75892
|
}
|
|
75629
75893
|
return out;
|
|
75630
75894
|
}
|
|
75631
75895
|
function readJsonl(filePath) {
|
|
75632
|
-
const lines2 =
|
|
75896
|
+
const lines2 = fs41.readFileSync(filePath, "utf8").split(/\r?\n/);
|
|
75633
75897
|
const out = [];
|
|
75634
75898
|
for (const line of lines2) {
|
|
75635
75899
|
const trimmed = line.trim();
|
|
@@ -75693,7 +75957,7 @@ function harvestCodexUsage(slot) {
|
|
|
75693
75957
|
const extracted = extractCodexTokens(records);
|
|
75694
75958
|
if (!extracted.cwd || !pathsMatch2(extracted.cwd, targets)) continue;
|
|
75695
75959
|
if (extracted.tokensInput + extracted.tokensOutput + extracted.tokensCacheRead === 0) continue;
|
|
75696
|
-
const mtime =
|
|
75960
|
+
const mtime = fs41.statSync(file).mtimeMs;
|
|
75697
75961
|
if (mtime >= bestMtime) {
|
|
75698
75962
|
bestMtime = mtime;
|
|
75699
75963
|
best = extracted;
|
|
@@ -75735,23 +75999,23 @@ function harvestEventsForSlot(slot) {
|
|
|
75735
75999
|
}
|
|
75736
76000
|
|
|
75737
76001
|
// src/core/control-persisted-usage.ts
|
|
75738
|
-
var
|
|
76002
|
+
var path43 = __toESM(require("path"));
|
|
75739
76003
|
|
|
75740
76004
|
// src/core/portal-watermark.ts
|
|
75741
|
-
var
|
|
76005
|
+
var fs42 = __toESM(require("fs"));
|
|
75742
76006
|
var os13 = __toESM(require("os"));
|
|
75743
|
-
var
|
|
76007
|
+
var path42 = __toESM(require("path"));
|
|
75744
76008
|
function getStatePath() {
|
|
75745
76009
|
if (process.env.HAR_PORTAL_SYNC_STATE_PATH) {
|
|
75746
|
-
return
|
|
76010
|
+
return path42.resolve(process.env.HAR_PORTAL_SYNC_STATE_PATH);
|
|
75747
76011
|
}
|
|
75748
|
-
return
|
|
76012
|
+
return path42.join(os13.homedir(), ".har", "portal-sync-state.json");
|
|
75749
76013
|
}
|
|
75750
76014
|
function readState() {
|
|
75751
76015
|
const statePath = getStatePath();
|
|
75752
76016
|
try {
|
|
75753
|
-
if (!
|
|
75754
|
-
const parsed = JSON.parse(
|
|
76017
|
+
if (!fs42.existsSync(statePath)) return { states: [] };
|
|
76018
|
+
const parsed = JSON.parse(fs42.readFileSync(statePath, "utf8"));
|
|
75755
76019
|
return Array.isArray(parsed.states) ? parsed : { states: [] };
|
|
75756
76020
|
} catch {
|
|
75757
76021
|
return { states: [] };
|
|
@@ -75759,8 +76023,8 @@ function readState() {
|
|
|
75759
76023
|
}
|
|
75760
76024
|
function writeState(state) {
|
|
75761
76025
|
const statePath = getStatePath();
|
|
75762
|
-
|
|
75763
|
-
|
|
76026
|
+
fs42.mkdirSync(path42.dirname(statePath), { recursive: true });
|
|
76027
|
+
fs42.writeFileSync(statePath, JSON.stringify(state, null, 2) + "\n");
|
|
75764
76028
|
}
|
|
75765
76029
|
function readPortalWatermark(repoPath, portalUrl) {
|
|
75766
76030
|
const canonical = canonicalizeControlRepoPath(repoPath);
|
|
@@ -75811,8 +76075,8 @@ async function getJson(url) {
|
|
|
75811
76075
|
async function resolveControlRepoId(apiUrl, repoPath) {
|
|
75812
76076
|
const repos = await getJson(`${apiUrl}/api/repos`);
|
|
75813
76077
|
if (!Array.isArray(repos)) return null;
|
|
75814
|
-
const target =
|
|
75815
|
-
return repos.find((repo) =>
|
|
76078
|
+
const target = path43.resolve(repoPath);
|
|
76079
|
+
return repos.find((repo) => path43.resolve(repo.path) === target)?.id ?? null;
|
|
75816
76080
|
}
|
|
75817
76081
|
function optionalString(value) {
|
|
75818
76082
|
return value == null ? void 0 : value;
|
|
@@ -76115,7 +76379,7 @@ async function waitForControlApi(apiUrl = getControlApiUrl(), timeoutMs = 6e4, i
|
|
|
76115
76379
|
const deadline = Date.now() + timeoutMs;
|
|
76116
76380
|
while (Date.now() < deadline) {
|
|
76117
76381
|
if (await isControlApiReachable(apiUrl)) return true;
|
|
76118
|
-
await new Promise((
|
|
76382
|
+
await new Promise((resolve45) => setTimeout(resolve45, intervalMs));
|
|
76119
76383
|
}
|
|
76120
76384
|
return false;
|
|
76121
76385
|
}
|
|
@@ -76207,7 +76471,7 @@ async function syncRepoWithLocalControl(options) {
|
|
|
76207
76471
|
const listResponse = await fetch(`${apiUrl}/api/repos`);
|
|
76208
76472
|
if (!listResponse.ok) throw new Error("Failed to list repos from Control API");
|
|
76209
76473
|
const repos = await listResponse.json();
|
|
76210
|
-
const existing = repos.find((r2) =>
|
|
76474
|
+
const existing = repos.find((r2) => path44.resolve(r2.path) === repoPath);
|
|
76211
76475
|
if (!existing) {
|
|
76212
76476
|
return;
|
|
76213
76477
|
}
|
|
@@ -76410,7 +76674,7 @@ init_control_config();
|
|
|
76410
76674
|
|
|
76411
76675
|
// src/core/control-lifecycle.ts
|
|
76412
76676
|
var import_child_process9 = require("child_process");
|
|
76413
|
-
var
|
|
76677
|
+
var path45 = __toESM(require("path"));
|
|
76414
76678
|
|
|
76415
76679
|
// src/core/control-image.ts
|
|
76416
76680
|
var DEFAULT_CONTROL_IMAGE = "theosfactory/har-control";
|
|
@@ -76434,10 +76698,10 @@ var CONTROL_DATA_VOLUME = "har_control_data";
|
|
|
76434
76698
|
var CONTROL_CONTAINER_PORT = 3847;
|
|
76435
76699
|
var CONTROL_DATA_DB_URL = "file:/data/har_control.db";
|
|
76436
76700
|
function resolveControlDir() {
|
|
76437
|
-
return
|
|
76701
|
+
return path45.resolve(__dirname, "..", "control");
|
|
76438
76702
|
}
|
|
76439
76703
|
function resolveControlBuildContext() {
|
|
76440
|
-
return
|
|
76704
|
+
return path45.resolve(resolveControlDir(), "..");
|
|
76441
76705
|
}
|
|
76442
76706
|
function buildDockerRunArgs(options) {
|
|
76443
76707
|
const name = options.containerName ?? CONTROL_CONTAINER_NAME;
|
|
@@ -76493,7 +76757,7 @@ async function startMissionControl(options) {
|
|
|
76493
76757
|
"-t",
|
|
76494
76758
|
imageRef,
|
|
76495
76759
|
"-f",
|
|
76496
|
-
|
|
76760
|
+
path45.join(resolveControlDir(), "Dockerfile"),
|
|
76497
76761
|
resolveControlBuildContext()
|
|
76498
76762
|
]);
|
|
76499
76763
|
if (buildCode !== 0) {
|
|
@@ -76638,7 +76902,7 @@ async function ensureTelemetryInfrastructure(options) {
|
|
|
76638
76902
|
|
|
76639
76903
|
// src/core/run-service.ts
|
|
76640
76904
|
init_telemetry_config();
|
|
76641
|
-
var
|
|
76905
|
+
var path47 = __toESM(require("path"));
|
|
76642
76906
|
function extractShellOutput(result) {
|
|
76643
76907
|
const stdout = result.logs?.find((log) => log.stream === "stdout")?.content ?? result.logs?.find((log) => !log.stream)?.content ?? "";
|
|
76644
76908
|
const stderr = result.logs?.find((log) => log.stream === "stderr")?.content ?? "";
|
|
@@ -76848,12 +77112,12 @@ Usage from Cursor / Claude / Codex (@osfactory/otel-hook) will appear under Work
|
|
|
76848
77112
|
suffix: session.suffix,
|
|
76849
77113
|
createdAt: session.createdAt
|
|
76850
77114
|
});
|
|
76851
|
-
const envFile =
|
|
77115
|
+
const envFile = path47.join(session.workDir, `.env.agent.${options.agentId}`);
|
|
76852
77116
|
try {
|
|
76853
77117
|
appendTelemetryEnvToFile(envFile, {
|
|
76854
77118
|
sessionKey,
|
|
76855
77119
|
agentId: options.agentId,
|
|
76856
|
-
repoPath:
|
|
77120
|
+
repoPath: path47.resolve(options.repoPath),
|
|
76857
77121
|
workDir: session.workDir,
|
|
76858
77122
|
branch: session.branch,
|
|
76859
77123
|
suffix: session.suffix,
|
|
@@ -77089,9 +77353,9 @@ var getEnvironmentLogs = defaultRunService.getEnvironmentLogs.bind(defaultRunSer
|
|
|
77089
77353
|
var readline6 = __toESM(require("readline"));
|
|
77090
77354
|
|
|
77091
77355
|
// src/core/hooks.ts
|
|
77092
|
-
var
|
|
77356
|
+
var fs44 = __toESM(require("fs"));
|
|
77093
77357
|
var os15 = __toESM(require("os"));
|
|
77094
|
-
var
|
|
77358
|
+
var path48 = __toESM(require("path"));
|
|
77095
77359
|
var MARKER_START = "# >>> har commit gate (managed by `har hooks`) >>>";
|
|
77096
77360
|
var MARKER_END = "# <<< har commit gate <<<";
|
|
77097
77361
|
var PRE_COMMIT_BLOCK = [
|
|
@@ -77116,7 +77380,7 @@ function resolveCheckoutRoot(cwd) {
|
|
|
77116
77380
|
function resolveHooksDir(checkoutDir) {
|
|
77117
77381
|
const hooksPath = tryGit3(checkoutDir, "rev-parse --git-path hooks");
|
|
77118
77382
|
if (!hooksPath) throw new Error(`Not a git checkout: ${checkoutDir}`);
|
|
77119
|
-
return
|
|
77383
|
+
return path48.resolve(checkoutDir, hooksPath);
|
|
77120
77384
|
}
|
|
77121
77385
|
function getConfiguredHooksPath(checkoutDir) {
|
|
77122
77386
|
return tryGit3(checkoutDir, "config core.hooksPath") || void 0;
|
|
@@ -77124,9 +77388,9 @@ function getConfiguredHooksPath(checkoutDir) {
|
|
|
77124
77388
|
function defaultHarInvocation() {
|
|
77125
77389
|
const entry = process.argv[1];
|
|
77126
77390
|
if (entry && entry.endsWith(".js")) {
|
|
77127
|
-
return `"${process.execPath}" "${
|
|
77391
|
+
return `"${process.execPath}" "${path48.resolve(entry)}"`;
|
|
77128
77392
|
}
|
|
77129
|
-
if (entry) return `"${
|
|
77393
|
+
if (entry) return `"${path48.resolve(entry)}"`;
|
|
77130
77394
|
return "har";
|
|
77131
77395
|
}
|
|
77132
77396
|
function buildHookScript(harInvocation, subcommand, failOpenNotice) {
|
|
@@ -77147,40 +77411,40 @@ exit 0
|
|
|
77147
77411
|
`;
|
|
77148
77412
|
}
|
|
77149
77413
|
function upsertMarkedBlock(filePath, block) {
|
|
77150
|
-
if (!
|
|
77151
|
-
|
|
77414
|
+
if (!fs44.existsSync(filePath)) {
|
|
77415
|
+
fs44.writeFileSync(filePath, `#!/bin/sh
|
|
77152
77416
|
${block}
|
|
77153
77417
|
`, { mode: 493 });
|
|
77154
77418
|
return "created";
|
|
77155
77419
|
}
|
|
77156
|
-
const content =
|
|
77420
|
+
const content = fs44.readFileSync(filePath, "utf8");
|
|
77157
77421
|
if (content.includes(MARKER_START)) {
|
|
77158
77422
|
const pattern = new RegExp(
|
|
77159
77423
|
`${escapeRegExp(MARKER_START)}[\\s\\S]*?${escapeRegExp(MARKER_END)}`
|
|
77160
77424
|
);
|
|
77161
|
-
|
|
77162
|
-
|
|
77425
|
+
fs44.writeFileSync(filePath, content.replace(pattern, block));
|
|
77426
|
+
fs44.chmodSync(filePath, 493);
|
|
77163
77427
|
return "updated";
|
|
77164
77428
|
}
|
|
77165
77429
|
const suffix = content.endsWith("\n") ? "" : "\n";
|
|
77166
|
-
|
|
77430
|
+
fs44.writeFileSync(filePath, `${content}${suffix}
|
|
77167
77431
|
${block}
|
|
77168
77432
|
`);
|
|
77169
|
-
|
|
77433
|
+
fs44.chmodSync(filePath, 493);
|
|
77170
77434
|
return "appended";
|
|
77171
77435
|
}
|
|
77172
77436
|
function removeMarkedBlock(filePath) {
|
|
77173
|
-
if (!
|
|
77174
|
-
const content =
|
|
77437
|
+
if (!fs44.existsSync(filePath)) return false;
|
|
77438
|
+
const content = fs44.readFileSync(filePath, "utf8");
|
|
77175
77439
|
if (!content.includes(MARKER_START)) return false;
|
|
77176
77440
|
const pattern = new RegExp(
|
|
77177
77441
|
`\\n?${escapeRegExp(MARKER_START)}[\\s\\S]*?${escapeRegExp(MARKER_END)}\\n?`
|
|
77178
77442
|
);
|
|
77179
77443
|
const stripped = content.replace(pattern, "\n");
|
|
77180
77444
|
if (stripped.replace(/^#!\/bin\/sh\n?/, "").trim() === "") {
|
|
77181
|
-
|
|
77445
|
+
fs44.rmSync(filePath);
|
|
77182
77446
|
} else {
|
|
77183
|
-
|
|
77447
|
+
fs44.writeFileSync(filePath, stripped);
|
|
77184
77448
|
}
|
|
77185
77449
|
return true;
|
|
77186
77450
|
}
|
|
@@ -77202,20 +77466,20 @@ Or re-run with --force to write into that directory anyway.`
|
|
|
77202
77466
|
);
|
|
77203
77467
|
}
|
|
77204
77468
|
const hooksDir = resolveHooksDir(checkout);
|
|
77205
|
-
|
|
77469
|
+
fs44.mkdirSync(hooksDir, { recursive: true });
|
|
77206
77470
|
const invocation = options.harInvocation ?? defaultHarInvocation();
|
|
77207
|
-
|
|
77208
|
-
|
|
77471
|
+
fs44.writeFileSync(
|
|
77472
|
+
path48.join(hooksDir, "har-pre-commit"),
|
|
77209
77473
|
buildHookScript(invocation, "check", "har: binary not found; skipping commit gate (reinstall with har hooks install)"),
|
|
77210
77474
|
{ mode: 493 }
|
|
77211
77475
|
);
|
|
77212
|
-
|
|
77213
|
-
|
|
77476
|
+
fs44.writeFileSync(
|
|
77477
|
+
path48.join(hooksDir, "har-post-commit"),
|
|
77214
77478
|
buildHookScript(invocation, "record-commit", "har: binary not found; skipping commit association"),
|
|
77215
77479
|
{ mode: 493 }
|
|
77216
77480
|
);
|
|
77217
|
-
const preCommit = upsertMarkedBlock(
|
|
77218
|
-
const postCommit = upsertMarkedBlock(
|
|
77481
|
+
const preCommit = upsertMarkedBlock(path48.join(hooksDir, "pre-commit"), PRE_COMMIT_BLOCK);
|
|
77482
|
+
const postCommit = upsertMarkedBlock(path48.join(hooksDir, "post-commit"), POST_COMMIT_BLOCK);
|
|
77219
77483
|
ensureValidationsIgnored(checkout);
|
|
77220
77484
|
return { hooksDir, preCommit, postCommit };
|
|
77221
77485
|
}
|
|
@@ -77224,12 +77488,12 @@ function uninstallHooks(repoPath) {
|
|
|
77224
77488
|
if (!checkout) throw new Error(`Not a git repository: ${repoPath}`);
|
|
77225
77489
|
const hooksDir = resolveHooksDir(checkout);
|
|
77226
77490
|
let removed = false;
|
|
77227
|
-
removed = removeMarkedBlock(
|
|
77228
|
-
removed = removeMarkedBlock(
|
|
77491
|
+
removed = removeMarkedBlock(path48.join(hooksDir, "pre-commit")) || removed;
|
|
77492
|
+
removed = removeMarkedBlock(path48.join(hooksDir, "post-commit")) || removed;
|
|
77229
77493
|
for (const file of ["har-pre-commit", "har-post-commit"]) {
|
|
77230
|
-
const full =
|
|
77231
|
-
if (
|
|
77232
|
-
|
|
77494
|
+
const full = path48.join(hooksDir, file);
|
|
77495
|
+
if (fs44.existsSync(full)) {
|
|
77496
|
+
fs44.rmSync(full);
|
|
77233
77497
|
removed = true;
|
|
77234
77498
|
}
|
|
77235
77499
|
}
|
|
@@ -77248,10 +77512,10 @@ function isAgentWorktree(checkoutDir) {
|
|
|
77248
77512
|
if (branch && (/^har-agent-\d+$/.test(branch) || /-har-agent-\d+-[a-z0-9]+$/.test(branch))) {
|
|
77249
77513
|
return true;
|
|
77250
77514
|
}
|
|
77251
|
-
const worktreesRoot =
|
|
77252
|
-
const resolved =
|
|
77253
|
-
const name =
|
|
77254
|
-
return resolved.startsWith(`${worktreesRoot}${
|
|
77515
|
+
const worktreesRoot = path48.join(os15.homedir(), "worktrees");
|
|
77516
|
+
const resolved = path48.resolve(checkoutDir);
|
|
77517
|
+
const name = path48.basename(resolved);
|
|
77518
|
+
return resolved.startsWith(`${worktreesRoot}${path48.sep}`) && (/-agent-\d+$/.test(name) || /-har-agent-\d+-[a-z0-9]+$/.test(name));
|
|
77255
77519
|
}
|
|
77256
77520
|
function resolveEffectiveMode(checkoutDir, gate) {
|
|
77257
77521
|
if (!gate.enabled) return "off";
|
|
@@ -77264,15 +77528,15 @@ function getHooksStatus(repoPath) {
|
|
|
77264
77528
|
const hooksDir = resolveHooksDir(checkout);
|
|
77265
77529
|
const gate = getCommitGateConfig(checkout);
|
|
77266
77530
|
const hasBlock = (name) => {
|
|
77267
|
-
const file =
|
|
77268
|
-
return
|
|
77531
|
+
const file = path48.join(hooksDir, name);
|
|
77532
|
+
return fs44.existsSync(file) && fs44.readFileSync(file, "utf8").includes(MARKER_START);
|
|
77269
77533
|
};
|
|
77270
77534
|
return {
|
|
77271
77535
|
checkout,
|
|
77272
77536
|
hooksDir,
|
|
77273
77537
|
configuredHooksPath: getConfiguredHooksPath(checkout),
|
|
77274
|
-
preCommitInstalled: hasBlock("pre-commit") &&
|
|
77275
|
-
postCommitInstalled: hasBlock("post-commit") &&
|
|
77538
|
+
preCommitInstalled: hasBlock("pre-commit") && fs44.existsSync(path48.join(hooksDir, "har-pre-commit")),
|
|
77539
|
+
postCommitInstalled: hasBlock("post-commit") && fs44.existsSync(path48.join(hooksDir, "har-post-commit")),
|
|
77276
77540
|
gate,
|
|
77277
77541
|
effectiveMode: resolveEffectiveMode(checkout, gate)
|
|
77278
77542
|
};
|
|
@@ -77283,7 +77547,7 @@ function checkCommitGate(cwd) {
|
|
|
77283
77547
|
}
|
|
77284
77548
|
const checkout = resolveCheckoutRoot(cwd);
|
|
77285
77549
|
if (!checkout) return { exitCode: 0, messages: [] };
|
|
77286
|
-
if (!
|
|
77550
|
+
if (!fs44.existsSync(path48.join(checkout, ".har", "stages.json"))) {
|
|
77287
77551
|
return { exitCode: 0, messages: [] };
|
|
77288
77552
|
}
|
|
77289
77553
|
const gate = getCommitGateConfig(checkout);
|
|
@@ -77356,12 +77620,12 @@ async function recordCommitAssociation(cwd) {
|
|
|
77356
77620
|
// src/core/commit-gate-onboarding.ts
|
|
77357
77621
|
function askYesNo5(question) {
|
|
77358
77622
|
const rl = readline6.createInterface({ input: process.stdin, output: process.stderr });
|
|
77359
|
-
return new Promise((
|
|
77623
|
+
return new Promise((resolve45) => {
|
|
77360
77624
|
process.stderr.write(`${question} `);
|
|
77361
77625
|
rl.once("line", (answer) => {
|
|
77362
77626
|
rl.close();
|
|
77363
77627
|
const trimmed = answer.trim();
|
|
77364
|
-
|
|
77628
|
+
resolve45(trimmed === "" || /^y(es)?$/i.test(trimmed));
|
|
77365
77629
|
});
|
|
77366
77630
|
});
|
|
77367
77631
|
}
|
|
@@ -77403,20 +77667,20 @@ async function handleCommitGateOnboarding(options) {
|
|
|
77403
77667
|
}
|
|
77404
77668
|
|
|
77405
77669
|
// src/core/onboarding-preferences.ts
|
|
77406
|
-
var
|
|
77670
|
+
var fs45 = __toESM(require("fs"));
|
|
77407
77671
|
var os16 = __toESM(require("os"));
|
|
77408
|
-
var
|
|
77672
|
+
var path49 = __toESM(require("path"));
|
|
77409
77673
|
function getOnboardingPreferencesPath() {
|
|
77410
77674
|
if (process.env.HAR_PREFERENCES_PATH) {
|
|
77411
|
-
return
|
|
77675
|
+
return path49.resolve(process.env.HAR_PREFERENCES_PATH);
|
|
77412
77676
|
}
|
|
77413
|
-
return
|
|
77677
|
+
return path49.join(os16.homedir(), ".har", "preferences.json");
|
|
77414
77678
|
}
|
|
77415
77679
|
function readOnboardingPreferences() {
|
|
77416
77680
|
const preferencePath = getOnboardingPreferencesPath();
|
|
77417
77681
|
try {
|
|
77418
|
-
if (!
|
|
77419
|
-
return OnboardingPreferencesSchema.parse(JSON.parse(
|
|
77682
|
+
if (!fs45.existsSync(preferencePath)) return OnboardingPreferencesSchema.parse({});
|
|
77683
|
+
return OnboardingPreferencesSchema.parse(JSON.parse(fs45.readFileSync(preferencePath, "utf8")));
|
|
77420
77684
|
} catch {
|
|
77421
77685
|
return OnboardingPreferencesSchema.parse({});
|
|
77422
77686
|
}
|
|
@@ -77441,8 +77705,8 @@ function writeOnboardingPreferences(overrides) {
|
|
|
77441
77705
|
};
|
|
77442
77706
|
const parsed = OnboardingPreferencesSchema.parse(preference);
|
|
77443
77707
|
const preferencePath = getOnboardingPreferencesPath();
|
|
77444
|
-
|
|
77445
|
-
|
|
77708
|
+
fs45.mkdirSync(path49.dirname(preferencePath), { recursive: true });
|
|
77709
|
+
fs45.writeFileSync(preferencePath, `${JSON.stringify(parsed, null, 2)}
|
|
77446
77710
|
`);
|
|
77447
77711
|
return parsed;
|
|
77448
77712
|
}
|
|
@@ -77745,7 +78009,7 @@ var envCommand = {
|
|
|
77745
78009
|
}
|
|
77746
78010
|
};
|
|
77747
78011
|
async function handleInit(argv) {
|
|
77748
|
-
const repoPath =
|
|
78012
|
+
const repoPath = path50.resolve(argv.repo);
|
|
77749
78013
|
const onboarding = resolveOnboardingOptions(argv);
|
|
77750
78014
|
header("har env init");
|
|
77751
78015
|
info(`Repository: ${repoPath}`);
|
|
@@ -77809,7 +78073,7 @@ async function handleInit(argv) {
|
|
|
77809
78073
|
}
|
|
77810
78074
|
}
|
|
77811
78075
|
async function handleMaintain(argv) {
|
|
77812
|
-
const repoPath =
|
|
78076
|
+
const repoPath = path50.resolve(argv.repo);
|
|
77813
78077
|
const onboarding = resolveOnboardingOptions(argv);
|
|
77814
78078
|
header("har env maintain");
|
|
77815
78079
|
info(`Repository: ${repoPath}`);
|
|
@@ -77931,7 +78195,7 @@ async function handleAgentMdProposal(repoPath, autoYes) {
|
|
|
77931
78195
|
if (autoYes) {
|
|
77932
78196
|
const proposal = readAgentMdProposal(repoPath);
|
|
77933
78197
|
if (proposal) {
|
|
77934
|
-
writeFileSafe(
|
|
78198
|
+
writeFileSafe(path50.join(repoPath, "AGENT.md"), proposal.content);
|
|
77935
78199
|
clearAgentMdProposal(repoPath);
|
|
77936
78200
|
info("Applied AGENT.md proposal (--yes)");
|
|
77937
78201
|
}
|
|
@@ -77940,7 +78204,7 @@ async function handleAgentMdProposal(repoPath, autoYes) {
|
|
|
77940
78204
|
await promptApplyAgentMdProposal(repoPath);
|
|
77941
78205
|
}
|
|
77942
78206
|
async function handleAddPlugin(argv) {
|
|
77943
|
-
const repoPath =
|
|
78207
|
+
const repoPath = path50.resolve(argv.repo);
|
|
77944
78208
|
const available = listPluginIds();
|
|
77945
78209
|
if (argv.list) {
|
|
77946
78210
|
for (const id of available) {
|
|
@@ -77978,7 +78242,7 @@ async function handleAddPlugin(argv) {
|
|
|
77978
78242
|
}
|
|
77979
78243
|
}
|
|
77980
78244
|
async function handleAddStage(argv) {
|
|
77981
|
-
const repoPath =
|
|
78245
|
+
const repoPath = path50.resolve(argv.repo);
|
|
77982
78246
|
const available = listPluginIds();
|
|
77983
78247
|
if (argv.list) {
|
|
77984
78248
|
warn("har env add-stage --list is deprecated; prefer: har env add-plugin --list");
|
|
@@ -78044,7 +78308,7 @@ async function handleAddStage(argv) {
|
|
|
78044
78308
|
});
|
|
78045
78309
|
}
|
|
78046
78310
|
async function handlePreflight(argv) {
|
|
78047
|
-
const repo =
|
|
78311
|
+
const repo = path50.resolve(argv.repo);
|
|
78048
78312
|
const agentId = validateAgentId(argv.id, repo);
|
|
78049
78313
|
const result = await preflightEnvironment({
|
|
78050
78314
|
repoPath: repo,
|
|
@@ -78062,7 +78326,7 @@ async function handlePreflight(argv) {
|
|
|
78062
78326
|
process.exit(result.code);
|
|
78063
78327
|
}
|
|
78064
78328
|
async function handleLaunch(argv) {
|
|
78065
|
-
const repo =
|
|
78329
|
+
const repo = path50.resolve(argv.repo);
|
|
78066
78330
|
const agentId = validateAgentId(argv.id, repo);
|
|
78067
78331
|
let confirmReplace = argv.replace;
|
|
78068
78332
|
let force = argv.force;
|
|
@@ -78074,8 +78338,8 @@ async function handleLaunch(argv) {
|
|
|
78074
78338
|
console.error(guard.reason ?? "");
|
|
78075
78339
|
const readline10 = await import("readline");
|
|
78076
78340
|
const rl = readline10.createInterface({ input: process.stdin, output: process.stderr });
|
|
78077
|
-
const answer = await new Promise((
|
|
78078
|
-
rl.question("Replace this slot? [y/N] ",
|
|
78341
|
+
const answer = await new Promise((resolve45) => {
|
|
78342
|
+
rl.question("Replace this slot? [y/N] ", resolve45);
|
|
78079
78343
|
});
|
|
78080
78344
|
rl.close();
|
|
78081
78345
|
if (!/^[Yy]$/.test(answer.trim())) {
|
|
@@ -78091,8 +78355,8 @@ async function handleLaunch(argv) {
|
|
|
78091
78355
|
warn("Worktree has uncommitted changes.");
|
|
78092
78356
|
const readline10 = await import("readline");
|
|
78093
78357
|
const rl = readline10.createInterface({ input: process.stdin, output: process.stderr });
|
|
78094
|
-
const answer = await new Promise((
|
|
78095
|
-
rl.question("Discard uncommitted changes? [y/N] ",
|
|
78358
|
+
const answer = await new Promise((resolve45) => {
|
|
78359
|
+
rl.question("Discard uncommitted changes? [y/N] ", resolve45);
|
|
78096
78360
|
});
|
|
78097
78361
|
rl.close();
|
|
78098
78362
|
if (!/^[Yy]$/.test(answer.trim())) {
|
|
@@ -78156,7 +78420,7 @@ async function handleRecover(argv) {
|
|
|
78156
78420
|
});
|
|
78157
78421
|
}
|
|
78158
78422
|
async function handleVerify(argv) {
|
|
78159
|
-
const repo =
|
|
78423
|
+
const repo = path50.resolve(argv.repo);
|
|
78160
78424
|
const agentId = validateAgentId(argv.id, repo);
|
|
78161
78425
|
const result = await runVerification({
|
|
78162
78426
|
repoPath: repo,
|
|
@@ -78168,7 +78432,7 @@ async function handleVerify(argv) {
|
|
|
78168
78432
|
process.exit(result.code);
|
|
78169
78433
|
}
|
|
78170
78434
|
async function handleTeardown(argv) {
|
|
78171
|
-
const repo =
|
|
78435
|
+
const repo = path50.resolve(argv.repo);
|
|
78172
78436
|
const agentId = validateAgentId(argv.id, repo);
|
|
78173
78437
|
const result = await teardownEnvironment({
|
|
78174
78438
|
repoPath: repo,
|
|
@@ -78179,7 +78443,7 @@ async function handleTeardown(argv) {
|
|
|
78179
78443
|
process.exit(result.code);
|
|
78180
78444
|
}
|
|
78181
78445
|
async function handleComplete(argv) {
|
|
78182
|
-
const repo =
|
|
78446
|
+
const repo = path50.resolve(argv.repo);
|
|
78183
78447
|
const agentId = validateAgentId(argv.id, repo);
|
|
78184
78448
|
const result = await completeEnvironment({
|
|
78185
78449
|
repoPath: repo,
|
|
@@ -78200,7 +78464,7 @@ async function handleComplete(argv) {
|
|
|
78200
78464
|
process.exit(result.code);
|
|
78201
78465
|
}
|
|
78202
78466
|
async function handleStatus(argv) {
|
|
78203
|
-
const repoPath =
|
|
78467
|
+
const repoPath = path50.resolve(argv.repo);
|
|
78204
78468
|
if (argv.json) {
|
|
78205
78469
|
const status = collectEnvironmentStatus(repoPath);
|
|
78206
78470
|
const output = EnvironmentStatusSchema.parse(status);
|
|
@@ -78213,7 +78477,7 @@ async function handleStatus(argv) {
|
|
|
78213
78477
|
});
|
|
78214
78478
|
}
|
|
78215
78479
|
async function handleRunsList(argv) {
|
|
78216
|
-
const repoPath =
|
|
78480
|
+
const repoPath = path50.resolve(argv.repo);
|
|
78217
78481
|
const runs = listRuns(repoPath, { stageId: argv.stage, limit: argv.limit });
|
|
78218
78482
|
if (argv.json) {
|
|
78219
78483
|
process.stdout.write(JSON.stringify({ runs }, null, 2) + "\n");
|
|
@@ -78230,7 +78494,7 @@ async function handleRunsList(argv) {
|
|
|
78230
78494
|
}
|
|
78231
78495
|
}
|
|
78232
78496
|
async function handleRunsGet(argv) {
|
|
78233
|
-
const run2 = getRun(
|
|
78497
|
+
const run2 = getRun(path50.resolve(argv.repo), argv.runId);
|
|
78234
78498
|
if (!run2) {
|
|
78235
78499
|
error(`Run not found: ${argv.runId}`);
|
|
78236
78500
|
process.exit(1);
|
|
@@ -78284,9 +78548,16 @@ function printDrift(drift) {
|
|
|
78284
78548
|
function printMaintainBundleSummary(report) {
|
|
78285
78549
|
const missing = report.actions.filter((a2) => a2.kind === "missing").length;
|
|
78286
78550
|
const drifted = report.actions.filter((a2) => a2.kind === "drift").length;
|
|
78551
|
+
const pluginMissing = report.pluginActions.filter((a2) => a2.kind === "missing").length;
|
|
78552
|
+
const pluginDrifted = report.pluginActions.filter((a2) => a2.kind === "drift").length;
|
|
78287
78553
|
const stale = report.stale.length;
|
|
78288
78554
|
info(`Maintenance bundle: .har/maintain/`);
|
|
78289
|
-
info(` ${missing} missing, ${drifted} drifted, ${stale} stale`);
|
|
78555
|
+
info(` Harness: ${missing} missing, ${drifted} drifted, ${stale} stale`);
|
|
78556
|
+
if (report.pluginDrift.length > 0) {
|
|
78557
|
+
info(
|
|
78558
|
+
` Plugins (${report.pluginDrift.map((p2) => p2.pluginId).join(", ")}): ${pluginMissing} missing, ${pluginDrifted} drifted`
|
|
78559
|
+
);
|
|
78560
|
+
}
|
|
78290
78561
|
if (!report.validation.pass) {
|
|
78291
78562
|
warn(` Validation: ${report.validation.errors.length} error(s) \u2014 blocks --finalize`);
|
|
78292
78563
|
}
|
|
@@ -78309,7 +78580,7 @@ function printNextSteps(auto2) {
|
|
|
78309
78580
|
}
|
|
78310
78581
|
|
|
78311
78582
|
// src/cli/commands/control.ts
|
|
78312
|
-
var
|
|
78583
|
+
var path54 = __toESM(require("path"));
|
|
78313
78584
|
|
|
78314
78585
|
// node_modules/@inquirer/core/dist/esm/lib/key.mjs
|
|
78315
78586
|
var isUpKey = (key) => (
|
|
@@ -79329,13 +79600,13 @@ var PromisePolyfill = class extends Promise {
|
|
|
79329
79600
|
// Available starting from Node 22
|
|
79330
79601
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers
|
|
79331
79602
|
static withResolver() {
|
|
79332
|
-
let
|
|
79603
|
+
let resolve45;
|
|
79333
79604
|
let reject;
|
|
79334
79605
|
const promise = new Promise((res, rej) => {
|
|
79335
|
-
|
|
79606
|
+
resolve45 = res;
|
|
79336
79607
|
reject = rej;
|
|
79337
79608
|
});
|
|
79338
|
-
return { promise, resolve:
|
|
79609
|
+
return { promise, resolve: resolve45, reject };
|
|
79339
79610
|
}
|
|
79340
79611
|
};
|
|
79341
79612
|
|
|
@@ -79352,7 +79623,7 @@ function createPrompt(view) {
|
|
|
79352
79623
|
output
|
|
79353
79624
|
});
|
|
79354
79625
|
const screen = new ScreenManager(rl);
|
|
79355
|
-
const { promise, resolve:
|
|
79626
|
+
const { promise, resolve: resolve45, reject } = PromisePolyfill.withResolver();
|
|
79356
79627
|
const cancel = () => reject(new CancelPromptError());
|
|
79357
79628
|
if (signal) {
|
|
79358
79629
|
const abort = () => reject(new AbortPromptError({ cause: signal.reason }));
|
|
@@ -79376,7 +79647,7 @@ function createPrompt(view) {
|
|
|
79376
79647
|
cycle(() => {
|
|
79377
79648
|
try {
|
|
79378
79649
|
const nextView = view(config2, (value) => {
|
|
79379
|
-
setImmediate(() =>
|
|
79650
|
+
setImmediate(() => resolve45(value));
|
|
79380
79651
|
});
|
|
79381
79652
|
const [content, bottomContent] = typeof nextView === "string" ? [nextView] : nextView;
|
|
79382
79653
|
screen.render(content, bottomContent);
|
|
@@ -80363,9 +80634,9 @@ var import_run_async = __toESM(require_run_async(), 1);
|
|
|
80363
80634
|
var import_mute_stream2 = __toESM(require_lib3(), 1);
|
|
80364
80635
|
var import_ansi_escapes5 = __toESM(require_ansi_escapes(), 1);
|
|
80365
80636
|
var _2 = {
|
|
80366
|
-
set: (obj,
|
|
80637
|
+
set: (obj, path61 = "", value) => {
|
|
80367
80638
|
let pointer = obj;
|
|
80368
|
-
|
|
80639
|
+
path61.split(".").forEach((key, index, arr) => {
|
|
80369
80640
|
if (key === "__proto__" || key === "constructor")
|
|
80370
80641
|
return;
|
|
80371
80642
|
if (index === arr.length - 1) {
|
|
@@ -80376,8 +80647,8 @@ var _2 = {
|
|
|
80376
80647
|
pointer = pointer[key];
|
|
80377
80648
|
});
|
|
80378
80649
|
},
|
|
80379
|
-
get: (obj,
|
|
80380
|
-
const travel = (regexp) => String.prototype.split.call(
|
|
80650
|
+
get: (obj, path61 = "", defaultValue) => {
|
|
80651
|
+
const travel = (regexp) => String.prototype.split.call(path61, regexp).filter(Boolean).reduce(
|
|
80381
80652
|
// @ts-expect-error implicit any on res[key]
|
|
80382
80653
|
(res, key) => res !== null && res !== void 0 ? res[key] : res,
|
|
80383
80654
|
obj
|
|
@@ -80491,7 +80762,7 @@ var PromptsRunner = class {
|
|
|
80491
80762
|
throw new Error(`Prompt for type ${question.type} not found`);
|
|
80492
80763
|
}
|
|
80493
80764
|
let cleanupSignal;
|
|
80494
|
-
const promptFn = isPromptConstructor(prompt2) ? (q2, { signal: signal2 } = {}) => new Promise((
|
|
80765
|
+
const promptFn = isPromptConstructor(prompt2) ? (q2, { signal: signal2 } = {}) => new Promise((resolve45, reject) => {
|
|
80495
80766
|
const rl = import_node_readline.default.createInterface(setupReadlineOptions(this.opt));
|
|
80496
80767
|
rl.resume();
|
|
80497
80768
|
const onClose = () => {
|
|
@@ -80527,7 +80798,7 @@ var PromptsRunner = class {
|
|
|
80527
80798
|
cleanupSignal = void 0;
|
|
80528
80799
|
};
|
|
80529
80800
|
}
|
|
80530
|
-
activePrompt.run().then(
|
|
80801
|
+
activePrompt.run().then(resolve45, reject).finally(cleanup);
|
|
80531
80802
|
}) : prompt2;
|
|
80532
80803
|
const { signal: moduleSignal } = this.opt;
|
|
80533
80804
|
if (moduleSignal?.aborted) {
|
|
@@ -80629,20 +80900,20 @@ var esm_default13 = inquirer;
|
|
|
80629
80900
|
init_control_config();
|
|
80630
80901
|
|
|
80631
80902
|
// src/core/control-sync-selection.ts
|
|
80632
|
-
var
|
|
80903
|
+
var fs46 = __toESM(require("fs"));
|
|
80633
80904
|
var os17 = __toESM(require("os"));
|
|
80634
|
-
var
|
|
80905
|
+
var path51 = __toESM(require("path"));
|
|
80635
80906
|
function getSelectionPath() {
|
|
80636
80907
|
if (process.env.HAR_CONTROL_SYNC_SELECTION_PATH) {
|
|
80637
|
-
return
|
|
80908
|
+
return path51.resolve(process.env.HAR_CONTROL_SYNC_SELECTION_PATH);
|
|
80638
80909
|
}
|
|
80639
|
-
return
|
|
80910
|
+
return path51.join(os17.homedir(), ".har", "sync-selection.json");
|
|
80640
80911
|
}
|
|
80641
80912
|
function readSyncSelection() {
|
|
80642
80913
|
const selectionPath = getSelectionPath();
|
|
80643
80914
|
try {
|
|
80644
|
-
if (!
|
|
80645
|
-
const parsed = JSON.parse(
|
|
80915
|
+
if (!fs46.existsSync(selectionPath)) return null;
|
|
80916
|
+
const parsed = JSON.parse(fs46.readFileSync(selectionPath, "utf8"));
|
|
80646
80917
|
if (!Array.isArray(parsed.repos)) return null;
|
|
80647
80918
|
return parsed.repos.map((repoPath) => canonicalizeControlRepoPath(repoPath));
|
|
80648
80919
|
} catch {
|
|
@@ -80652,8 +80923,8 @@ function readSyncSelection() {
|
|
|
80652
80923
|
function writeSyncSelection(repos) {
|
|
80653
80924
|
const selectionPath = getSelectionPath();
|
|
80654
80925
|
const canonical = Array.from(new Set(repos.map((repoPath) => canonicalizeControlRepoPath(repoPath))));
|
|
80655
|
-
|
|
80656
|
-
|
|
80926
|
+
fs46.mkdirSync(path51.dirname(selectionPath), { recursive: true });
|
|
80927
|
+
fs46.writeFileSync(selectionPath, JSON.stringify({ repos: canonical }, null, 2) + "\n");
|
|
80657
80928
|
}
|
|
80658
80929
|
function resolveSyncSelection(input) {
|
|
80659
80930
|
const { discovered, stored, forceSelect, isTTY } = input;
|
|
@@ -80700,7 +80971,7 @@ function openBrowser(url) {
|
|
|
80700
80971
|
}
|
|
80701
80972
|
async function loginViaBrowser(portalUrl, openUrl = openBrowser) {
|
|
80702
80973
|
const state = (0, import_crypto.randomUUID)();
|
|
80703
|
-
return new Promise((
|
|
80974
|
+
return new Promise((resolve45, reject) => {
|
|
80704
80975
|
let timer;
|
|
80705
80976
|
const server = http.createServer((req, res) => {
|
|
80706
80977
|
const requestUrl = new URL(req.url ?? "", "http://127.0.0.1");
|
|
@@ -80723,7 +80994,7 @@ async function loginViaBrowser(portalUrl, openUrl = openBrowser) {
|
|
|
80723
80994
|
res.writeHead(200, { "Content-Type": "text/html" });
|
|
80724
80995
|
res.end("<h1>Logged in</h1><p>You can close this tab and return to the terminal.</p>");
|
|
80725
80996
|
cleanup();
|
|
80726
|
-
|
|
80997
|
+
resolve45({ portalUrl, token, workspace, email: email2, createdAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
80727
80998
|
});
|
|
80728
80999
|
const cleanup = () => {
|
|
80729
81000
|
clearTimeout(timer);
|
|
@@ -80750,16 +81021,16 @@ If your browser did not open, paste that URL.
|
|
|
80750
81021
|
}
|
|
80751
81022
|
|
|
80752
81023
|
// src/core/control-unregister.ts
|
|
80753
|
-
var
|
|
80754
|
-
var
|
|
81024
|
+
var fs47 = __toESM(require("fs"));
|
|
81025
|
+
var path52 = __toESM(require("path"));
|
|
80755
81026
|
init_control_config();
|
|
80756
81027
|
function listUnregisterWorktreeCandidates(repoPath) {
|
|
80757
81028
|
const harnessRoot = canonicalizeControlRepoPath(repoPath);
|
|
80758
81029
|
const byPath = /* @__PURE__ */ new Map();
|
|
80759
81030
|
const add = (partial2) => {
|
|
80760
|
-
const resolved =
|
|
81031
|
+
const resolved = path52.resolve(partial2.worktreePath);
|
|
80761
81032
|
if (!resolved || resolved === harnessRoot) return;
|
|
80762
|
-
const exists = partial2.exists ??
|
|
81033
|
+
const exists = partial2.exists ?? fs47.existsSync(resolved);
|
|
80763
81034
|
const prev = byPath.get(resolved);
|
|
80764
81035
|
if (prev) {
|
|
80765
81036
|
byPath.set(resolved, {
|
|
@@ -80810,8 +81081,8 @@ async function askYesNo6(question) {
|
|
|
80810
81081
|
if (!process.stdin.isTTY || !process.stdout.isTTY) return false;
|
|
80811
81082
|
const readline10 = await import("readline");
|
|
80812
81083
|
const rl = readline10.createInterface({ input: process.stdin, output: process.stderr });
|
|
80813
|
-
const answer = await new Promise((
|
|
80814
|
-
rl.question(question,
|
|
81084
|
+
const answer = await new Promise((resolve45) => {
|
|
81085
|
+
rl.question(question, resolve45);
|
|
80815
81086
|
});
|
|
80816
81087
|
rl.close();
|
|
80817
81088
|
return /^[Yy]$/.test(answer.trim());
|
|
@@ -80873,28 +81144,28 @@ async function teardownWorktrees(repoPath, candidates, dryRun) {
|
|
|
80873
81144
|
trigger: "cli"
|
|
80874
81145
|
});
|
|
80875
81146
|
if (result.code !== 0) {
|
|
80876
|
-
if (
|
|
80877
|
-
|
|
81147
|
+
if (fs47.existsSync(candidate.worktreePath)) {
|
|
81148
|
+
fs47.rmSync(candidate.worktreePath, { recursive: true, force: true });
|
|
80878
81149
|
}
|
|
80879
81150
|
}
|
|
80880
81151
|
outcomes.push({
|
|
80881
81152
|
path: candidate.worktreePath,
|
|
80882
81153
|
agentId: candidate.agentId,
|
|
80883
|
-
deleted: !
|
|
80884
|
-
error: result.code !== 0 &&
|
|
81154
|
+
deleted: !fs47.existsSync(candidate.worktreePath),
|
|
81155
|
+
error: result.code !== 0 && fs47.existsSync(candidate.worktreePath) ? result.stderr : void 0
|
|
80885
81156
|
});
|
|
80886
81157
|
} catch (err) {
|
|
80887
81158
|
const message = err instanceof Error ? err.message : String(err);
|
|
80888
81159
|
try {
|
|
80889
|
-
if (
|
|
80890
|
-
|
|
81160
|
+
if (fs47.existsSync(candidate.worktreePath)) {
|
|
81161
|
+
fs47.rmSync(candidate.worktreePath, { recursive: true, force: true });
|
|
80891
81162
|
}
|
|
80892
81163
|
} catch {
|
|
80893
81164
|
}
|
|
80894
81165
|
outcomes.push({
|
|
80895
81166
|
path: candidate.worktreePath,
|
|
80896
81167
|
agentId: candidate.agentId,
|
|
80897
|
-
deleted: !
|
|
81168
|
+
deleted: !fs47.existsSync(candidate.worktreePath),
|
|
80898
81169
|
error: message
|
|
80899
81170
|
});
|
|
80900
81171
|
}
|
|
@@ -80956,16 +81227,16 @@ async function unregisterRepoWithControl(options) {
|
|
|
80956
81227
|
init_control_config();
|
|
80957
81228
|
|
|
80958
81229
|
// src/core/harness-scrub.ts
|
|
80959
|
-
var
|
|
80960
|
-
var
|
|
81230
|
+
var fs48 = __toESM(require("fs"));
|
|
81231
|
+
var path53 = __toESM(require("path"));
|
|
80961
81232
|
var HARNESS_SCRUB_DIRS = ["runs", "validations", "state", "slots"];
|
|
80962
81233
|
function scrubLocalHarnessDirs(repoPath) {
|
|
80963
81234
|
const results = [];
|
|
80964
|
-
const resolved =
|
|
80965
|
-
if (!
|
|
81235
|
+
const resolved = path53.resolve(repoPath);
|
|
81236
|
+
if (!fs48.existsSync(resolved)) {
|
|
80966
81237
|
for (const directory of HARNESS_SCRUB_DIRS) {
|
|
80967
81238
|
results.push({
|
|
80968
|
-
path:
|
|
81239
|
+
path: path53.join(resolved, ".har", directory),
|
|
80969
81240
|
directory,
|
|
80970
81241
|
deleted: false,
|
|
80971
81242
|
error: "repository path does not exist"
|
|
@@ -80974,24 +81245,24 @@ function scrubLocalHarnessDirs(repoPath) {
|
|
|
80974
81245
|
return results;
|
|
80975
81246
|
}
|
|
80976
81247
|
for (const directory of HARNESS_SCRUB_DIRS) {
|
|
80977
|
-
const target =
|
|
80978
|
-
if (!
|
|
81248
|
+
const target = path53.join(resolved, ".har", directory);
|
|
81249
|
+
if (!fs48.existsSync(target)) {
|
|
80979
81250
|
results.push({ path: target, directory, deleted: true });
|
|
80980
81251
|
continue;
|
|
80981
81252
|
}
|
|
80982
81253
|
try {
|
|
80983
|
-
|
|
81254
|
+
fs48.rmSync(target, { recursive: true, force: true });
|
|
80984
81255
|
results.push({
|
|
80985
81256
|
path: target,
|
|
80986
81257
|
directory,
|
|
80987
|
-
deleted: !
|
|
80988
|
-
error:
|
|
81258
|
+
deleted: !fs48.existsSync(target),
|
|
81259
|
+
error: fs48.existsSync(target) ? "failed to remove directory" : void 0
|
|
80989
81260
|
});
|
|
80990
81261
|
} catch (err) {
|
|
80991
81262
|
results.push({
|
|
80992
81263
|
path: target,
|
|
80993
81264
|
directory,
|
|
80994
|
-
deleted: !
|
|
81265
|
+
deleted: !fs48.existsSync(target),
|
|
80995
81266
|
error: err instanceof Error ? err.message : String(err)
|
|
80996
81267
|
});
|
|
80997
81268
|
}
|
|
@@ -81002,7 +81273,7 @@ function scrubLocalHarnessForRepos(repoPaths) {
|
|
|
81002
81273
|
const results = [];
|
|
81003
81274
|
const seen = /* @__PURE__ */ new Set();
|
|
81004
81275
|
for (const repoPath of repoPaths) {
|
|
81005
|
-
const key =
|
|
81276
|
+
const key = path53.resolve(repoPath);
|
|
81006
81277
|
if (seen.has(key)) continue;
|
|
81007
81278
|
seen.add(key);
|
|
81008
81279
|
results.push(...scrubLocalHarnessDirs(key));
|
|
@@ -81015,8 +81286,8 @@ async function askYesNo7(question) {
|
|
|
81015
81286
|
if (!process.stdin.isTTY || !process.stdout.isTTY) return false;
|
|
81016
81287
|
const readline10 = await import("readline");
|
|
81017
81288
|
const rl = readline10.createInterface({ input: process.stdin, output: process.stderr });
|
|
81018
|
-
const answer = await new Promise((
|
|
81019
|
-
rl.question(question,
|
|
81289
|
+
const answer = await new Promise((resolve45) => {
|
|
81290
|
+
rl.question(question, resolve45);
|
|
81020
81291
|
});
|
|
81021
81292
|
rl.close();
|
|
81022
81293
|
return /^[Yy]$/.test(answer.trim());
|
|
@@ -81261,7 +81532,7 @@ async function handleDown() {
|
|
|
81261
81532
|
process.exit(code);
|
|
81262
81533
|
}
|
|
81263
81534
|
async function handleRegister(argv) {
|
|
81264
|
-
const repoPath =
|
|
81535
|
+
const repoPath = path54.resolve(argv.repo);
|
|
81265
81536
|
header("har control register");
|
|
81266
81537
|
info(`Repository: ${repoPath}`);
|
|
81267
81538
|
try {
|
|
@@ -81353,7 +81624,7 @@ async function handleReset(argv) {
|
|
|
81353
81624
|
}
|
|
81354
81625
|
}
|
|
81355
81626
|
async function handleUnregister(argv) {
|
|
81356
|
-
const repoPath =
|
|
81627
|
+
const repoPath = path54.resolve(argv.repo);
|
|
81357
81628
|
const worktrees = listUnregisterWorktreeCandidates(repoPath);
|
|
81358
81629
|
try {
|
|
81359
81630
|
let deleteWorktrees = argv.deleteWorktrees;
|
|
@@ -81514,7 +81785,7 @@ async function handleWatch(argv) {
|
|
|
81514
81785
|
};
|
|
81515
81786
|
const tick = async () => {
|
|
81516
81787
|
if (argv.repo) {
|
|
81517
|
-
await syncOne(
|
|
81788
|
+
await syncOne(path54.resolve(argv.repo));
|
|
81518
81789
|
return;
|
|
81519
81790
|
}
|
|
81520
81791
|
try {
|
|
@@ -81564,11 +81835,11 @@ async function handleLogin(argv) {
|
|
|
81564
81835
|
}
|
|
81565
81836
|
|
|
81566
81837
|
// src/cli/commands/hooks.ts
|
|
81567
|
-
var
|
|
81838
|
+
var path56 = __toESM(require("path"));
|
|
81568
81839
|
|
|
81569
81840
|
// src/core/claude-hooks.ts
|
|
81570
|
-
var
|
|
81571
|
-
var
|
|
81841
|
+
var fs49 = __toESM(require("fs"));
|
|
81842
|
+
var path55 = __toESM(require("path"));
|
|
81572
81843
|
var CLAUDE_GUARD_RELATIVE_PATH = ".har/hooks/claude-worktree-guard.sh";
|
|
81573
81844
|
var CLAUDE_SETTINGS_RELATIVE_PATH = ".claude/settings.json";
|
|
81574
81845
|
var GUARD_MATCHER = "Edit|Write|MultiEdit|NotebookEdit";
|
|
@@ -81579,8 +81850,8 @@ function isHarGuardEntry(entry) {
|
|
|
81579
81850
|
);
|
|
81580
81851
|
}
|
|
81581
81852
|
function readSettings(settingsPath) {
|
|
81582
|
-
if (!
|
|
81583
|
-
const raw =
|
|
81853
|
+
if (!fs49.existsSync(settingsPath)) return {};
|
|
81854
|
+
const raw = fs49.readFileSync(settingsPath, "utf8").trim();
|
|
81584
81855
|
if (raw === "") return {};
|
|
81585
81856
|
const parsed = JSON.parse(raw);
|
|
81586
81857
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
@@ -81589,19 +81860,19 @@ function readSettings(settingsPath) {
|
|
|
81589
81860
|
return parsed;
|
|
81590
81861
|
}
|
|
81591
81862
|
function writeSettings(settingsPath, settings) {
|
|
81592
|
-
|
|
81593
|
-
|
|
81863
|
+
fs49.mkdirSync(path55.dirname(settingsPath), { recursive: true });
|
|
81864
|
+
fs49.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
81594
81865
|
}
|
|
81595
81866
|
function installClaudeGuard(repoPath) {
|
|
81596
81867
|
const templatePath = resolveTemplateFile("claude-worktree-guard.sh.template");
|
|
81597
81868
|
if (!templatePath) {
|
|
81598
81869
|
throw new Error("Guard template not found (claude-worktree-guard.sh.template). Run npm run build.");
|
|
81599
81870
|
}
|
|
81600
|
-
const guardScript =
|
|
81601
|
-
|
|
81602
|
-
|
|
81603
|
-
|
|
81604
|
-
const settingsPath =
|
|
81871
|
+
const guardScript = path55.join(repoPath, CLAUDE_GUARD_RELATIVE_PATH);
|
|
81872
|
+
fs49.mkdirSync(path55.dirname(guardScript), { recursive: true });
|
|
81873
|
+
fs49.copyFileSync(templatePath, guardScript);
|
|
81874
|
+
fs49.chmodSync(guardScript, 493);
|
|
81875
|
+
const settingsPath = path55.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
|
|
81605
81876
|
const settings = readSettings(settingsPath);
|
|
81606
81877
|
const hooks = settings.hooks ?? {};
|
|
81607
81878
|
const preToolUse = (hooks.PreToolUse ?? []).filter((entry) => !isHarGuardEntry(entry));
|
|
@@ -81615,15 +81886,15 @@ function installClaudeGuard(repoPath) {
|
|
|
81615
81886
|
}
|
|
81616
81887
|
function uninstallClaudeGuard(repoPath) {
|
|
81617
81888
|
let removed = false;
|
|
81618
|
-
const guardScript =
|
|
81619
|
-
if (
|
|
81620
|
-
|
|
81889
|
+
const guardScript = path55.join(repoPath, CLAUDE_GUARD_RELATIVE_PATH);
|
|
81890
|
+
if (fs49.existsSync(guardScript)) {
|
|
81891
|
+
fs49.rmSync(guardScript);
|
|
81621
81892
|
removed = true;
|
|
81622
|
-
const parent =
|
|
81623
|
-
if (
|
|
81893
|
+
const parent = path55.dirname(guardScript);
|
|
81894
|
+
if (fs49.existsSync(parent) && fs49.readdirSync(parent).length === 0) fs49.rmdirSync(parent);
|
|
81624
81895
|
}
|
|
81625
|
-
const settingsPath =
|
|
81626
|
-
if (
|
|
81896
|
+
const settingsPath = path55.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
|
|
81897
|
+
if (fs49.existsSync(settingsPath)) {
|
|
81627
81898
|
const settings = readSettings(settingsPath);
|
|
81628
81899
|
const preToolUse = settings.hooks?.PreToolUse;
|
|
81629
81900
|
if (preToolUse) {
|
|
@@ -81648,8 +81919,8 @@ function uninstallClaudeGuard(repoPath) {
|
|
|
81648
81919
|
return { removed };
|
|
81649
81920
|
}
|
|
81650
81921
|
function claudeGuardInstalled(repoPath) {
|
|
81651
|
-
const settingsPath =
|
|
81652
|
-
if (!
|
|
81922
|
+
const settingsPath = path55.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
|
|
81923
|
+
if (!fs49.existsSync(settingsPath)) return false;
|
|
81653
81924
|
try {
|
|
81654
81925
|
const settings = readSettings(settingsPath);
|
|
81655
81926
|
return (settings.hooks?.PreToolUse ?? []).some(isHarGuardEntry);
|
|
@@ -81665,7 +81936,7 @@ function repoOption(y2) {
|
|
|
81665
81936
|
function handleInstall2(argv) {
|
|
81666
81937
|
try {
|
|
81667
81938
|
if (argv.claude) {
|
|
81668
|
-
const result2 = installClaudeGuard(
|
|
81939
|
+
const result2 = installClaudeGuard(path56.resolve(argv.repo));
|
|
81669
81940
|
success("Claude Code worktree guard installed.");
|
|
81670
81941
|
info(`Guard script: ${result2.guardScript}`);
|
|
81671
81942
|
info(`Settings: ${result2.settingsPath} (PreToolUse: Edit|Write|MultiEdit|NotebookEdit)`);
|
|
@@ -81673,7 +81944,7 @@ function handleInstall2(argv) {
|
|
|
81673
81944
|
info("Commit both files so the guard travels with the repo.");
|
|
81674
81945
|
return;
|
|
81675
81946
|
}
|
|
81676
|
-
const result = installHooks({ repoPath:
|
|
81947
|
+
const result = installHooks({ repoPath: path56.resolve(argv.repo), force: argv.force });
|
|
81677
81948
|
success(`Commit gate installed in ${result.hooksDir}`);
|
|
81678
81949
|
info(`pre-commit: ${result.preCommit}, post-commit: ${result.postCommit}`);
|
|
81679
81950
|
info("Commits of unverified change batches will be blocked in agent worktrees.");
|
|
@@ -81686,7 +81957,7 @@ function handleInstall2(argv) {
|
|
|
81686
81957
|
function handleUninstall(argv) {
|
|
81687
81958
|
try {
|
|
81688
81959
|
if (argv.claude) {
|
|
81689
|
-
const result2 = uninstallClaudeGuard(
|
|
81960
|
+
const result2 = uninstallClaudeGuard(path56.resolve(argv.repo));
|
|
81690
81961
|
if (result2.removed) {
|
|
81691
81962
|
success("Claude Code worktree guard removed.");
|
|
81692
81963
|
} else {
|
|
@@ -81694,7 +81965,7 @@ function handleUninstall(argv) {
|
|
|
81694
81965
|
}
|
|
81695
81966
|
return;
|
|
81696
81967
|
}
|
|
81697
|
-
const result = uninstallHooks(
|
|
81968
|
+
const result = uninstallHooks(path56.resolve(argv.repo));
|
|
81698
81969
|
if (result.removed) {
|
|
81699
81970
|
success(`Commit gate removed from ${result.hooksDir}`);
|
|
81700
81971
|
} else {
|
|
@@ -81707,7 +81978,7 @@ function handleUninstall(argv) {
|
|
|
81707
81978
|
}
|
|
81708
81979
|
function handleStatus2(argv) {
|
|
81709
81980
|
try {
|
|
81710
|
-
const status = getHooksStatus(
|
|
81981
|
+
const status = getHooksStatus(path56.resolve(argv.repo));
|
|
81711
81982
|
if (argv.json) {
|
|
81712
81983
|
process.stdout.write(`${JSON.stringify(status, null, 2)}
|
|
81713
81984
|
`);
|
|
@@ -81725,7 +81996,7 @@ function handleStatus2(argv) {
|
|
|
81725
81996
|
);
|
|
81726
81997
|
info(`Effective: ${status.effectiveMode} (in this checkout)`);
|
|
81727
81998
|
info(
|
|
81728
|
-
`Claude guard: ${claudeGuardInstalled(
|
|
81999
|
+
`Claude guard: ${claudeGuardInstalled(path56.resolve(argv.repo)) ? `installed (${CLAUDE_GUARD_RELATIVE_PATH})` : "not installed"}`
|
|
81729
82000
|
);
|
|
81730
82001
|
} catch (err) {
|
|
81731
82002
|
error(err instanceof Error ? err.message : String(err));
|
|
@@ -81986,10 +82257,10 @@ function assignProp(target, prop, value) {
|
|
|
81986
82257
|
configurable: true
|
|
81987
82258
|
});
|
|
81988
82259
|
}
|
|
81989
|
-
function getElementAtPath(obj,
|
|
81990
|
-
if (!
|
|
82260
|
+
function getElementAtPath(obj, path61) {
|
|
82261
|
+
if (!path61)
|
|
81991
82262
|
return obj;
|
|
81992
|
-
return
|
|
82263
|
+
return path61.reduce((acc, key) => acc?.[key], obj);
|
|
81993
82264
|
}
|
|
81994
82265
|
function promiseAllObject(promisesObj) {
|
|
81995
82266
|
const keys = Object.keys(promisesObj);
|
|
@@ -82309,11 +82580,11 @@ function aborted(x2, startIndex = 0) {
|
|
|
82309
82580
|
}
|
|
82310
82581
|
return false;
|
|
82311
82582
|
}
|
|
82312
|
-
function prefixIssues(
|
|
82583
|
+
function prefixIssues(path61, issues) {
|
|
82313
82584
|
return issues.map((iss) => {
|
|
82314
82585
|
var _a3;
|
|
82315
82586
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
82316
|
-
iss.path.unshift(
|
|
82587
|
+
iss.path.unshift(path61);
|
|
82317
82588
|
return iss;
|
|
82318
82589
|
});
|
|
82319
82590
|
}
|
|
@@ -87636,7 +87907,7 @@ var Protocol = class {
|
|
|
87636
87907
|
return;
|
|
87637
87908
|
}
|
|
87638
87909
|
const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
|
|
87639
|
-
await new Promise((
|
|
87910
|
+
await new Promise((resolve45) => setTimeout(resolve45, pollInterval));
|
|
87640
87911
|
options?.signal?.throwIfAborted();
|
|
87641
87912
|
}
|
|
87642
87913
|
} catch (error3) {
|
|
@@ -87653,7 +87924,7 @@ var Protocol = class {
|
|
|
87653
87924
|
*/
|
|
87654
87925
|
request(request, resultSchema, options) {
|
|
87655
87926
|
const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
|
|
87656
|
-
return new Promise((
|
|
87927
|
+
return new Promise((resolve45, reject) => {
|
|
87657
87928
|
const earlyReject = (error3) => {
|
|
87658
87929
|
reject(error3);
|
|
87659
87930
|
};
|
|
@@ -87731,7 +88002,7 @@ var Protocol = class {
|
|
|
87731
88002
|
if (!parseResult.success) {
|
|
87732
88003
|
reject(parseResult.error);
|
|
87733
88004
|
} else {
|
|
87734
|
-
|
|
88005
|
+
resolve45(parseResult.data);
|
|
87735
88006
|
}
|
|
87736
88007
|
} catch (error3) {
|
|
87737
88008
|
reject(error3);
|
|
@@ -87992,12 +88263,12 @@ var Protocol = class {
|
|
|
87992
88263
|
}
|
|
87993
88264
|
} catch {
|
|
87994
88265
|
}
|
|
87995
|
-
return new Promise((
|
|
88266
|
+
return new Promise((resolve45, reject) => {
|
|
87996
88267
|
if (signal.aborted) {
|
|
87997
88268
|
reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
87998
88269
|
return;
|
|
87999
88270
|
}
|
|
88000
|
-
const timeoutId = setTimeout(
|
|
88271
|
+
const timeoutId = setTimeout(resolve45, interval);
|
|
88001
88272
|
signal.addEventListener("abort", () => {
|
|
88002
88273
|
clearTimeout(timeoutId);
|
|
88003
88274
|
reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
@@ -88787,7 +89058,7 @@ var Server = class extends Protocol {
|
|
|
88787
89058
|
};
|
|
88788
89059
|
|
|
88789
89060
|
// src/mcp/server.ts
|
|
88790
|
-
var
|
|
89061
|
+
var path57 = __toESM(require("path"));
|
|
88791
89062
|
|
|
88792
89063
|
// node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
|
|
88793
89064
|
var import_node_process3 = __toESM(require("node:process"), 1);
|
|
@@ -88870,12 +89141,12 @@ var StdioServerTransport = class {
|
|
|
88870
89141
|
this.onclose?.();
|
|
88871
89142
|
}
|
|
88872
89143
|
send(message) {
|
|
88873
|
-
return new Promise((
|
|
89144
|
+
return new Promise((resolve45) => {
|
|
88874
89145
|
const json = serializeMessage(message);
|
|
88875
89146
|
if (this._stdout.write(json)) {
|
|
88876
|
-
|
|
89147
|
+
resolve45();
|
|
88877
89148
|
} else {
|
|
88878
|
-
this._stdout.once("drain",
|
|
89149
|
+
this._stdout.once("drain", resolve45);
|
|
88879
89150
|
}
|
|
88880
89151
|
});
|
|
88881
89152
|
}
|
|
@@ -89450,7 +89721,7 @@ async function handleMcpToolCall(toolName, args, defaultRepo = ".") {
|
|
|
89450
89721
|
const input = ControlUpInputSchema.parse({ ...args, repo });
|
|
89451
89722
|
const result = await startControlAndSync({
|
|
89452
89723
|
detach: input.detach,
|
|
89453
|
-
cwd:
|
|
89724
|
+
cwd: path57.resolve(input.repo)
|
|
89454
89725
|
});
|
|
89455
89726
|
if (result.code !== 0) {
|
|
89456
89727
|
return {
|
|
@@ -89514,10 +89785,10 @@ var mcpCommand = {
|
|
|
89514
89785
|
};
|
|
89515
89786
|
|
|
89516
89787
|
// src/cli/commands/onboard.ts
|
|
89517
|
-
var
|
|
89788
|
+
var path59 = __toESM(require("path"));
|
|
89518
89789
|
|
|
89519
89790
|
// src/core/onboarding.ts
|
|
89520
|
-
var
|
|
89791
|
+
var path58 = __toESM(require("path"));
|
|
89521
89792
|
init_control_config();
|
|
89522
89793
|
init_otel_hooks();
|
|
89523
89794
|
init_telemetry_config();
|
|
@@ -89645,7 +89916,7 @@ async function defaultEnsureControl(options) {
|
|
|
89645
89916
|
return { started: true, apiUrl: result.apiUrl };
|
|
89646
89917
|
}
|
|
89647
89918
|
async function runOnboarding(options, deps = {}) {
|
|
89648
|
-
const repoPath =
|
|
89919
|
+
const repoPath = path58.resolve(options.repoPath);
|
|
89649
89920
|
const applyTelemetry = deps.applyTelemetry ?? applyOnboardingTelemetry;
|
|
89650
89921
|
const ensureControl = deps.ensureControl ?? defaultEnsureControl;
|
|
89651
89922
|
const init = deps.initHarness ?? initHarness;
|
|
@@ -89796,7 +90067,7 @@ async function promptChoices(args) {
|
|
|
89796
90067
|
};
|
|
89797
90068
|
}
|
|
89798
90069
|
const pluginChoices = listPluginChoices();
|
|
89799
|
-
const alreadyPresent = harnessExists(
|
|
90070
|
+
const alreadyPresent = harnessExists(path59.resolve(args.repo));
|
|
89800
90071
|
const needProfile = !alreadyPresent && !args.skipInit && args.profile === void 0;
|
|
89801
90072
|
const answers = await esm_default13.prompt([
|
|
89802
90073
|
{
|
|
@@ -89878,7 +90149,7 @@ function printSummary(result) {
|
|
|
89878
90149
|
console.error("");
|
|
89879
90150
|
}
|
|
89880
90151
|
async function handleOnboard(argv) {
|
|
89881
|
-
const repoPath =
|
|
90152
|
+
const repoPath = path59.resolve(argv.repo);
|
|
89882
90153
|
header("har onboard");
|
|
89883
90154
|
info(`Repository: ${repoPath}`);
|
|
89884
90155
|
try {
|
|
@@ -90109,7 +90380,7 @@ var preferencesCommand = {
|
|
|
90109
90380
|
};
|
|
90110
90381
|
|
|
90111
90382
|
// src/cli/commands/telemetry.ts
|
|
90112
|
-
var
|
|
90383
|
+
var path60 = __toESM(require("path"));
|
|
90113
90384
|
init_control_config();
|
|
90114
90385
|
init_otel_hooks();
|
|
90115
90386
|
init_telemetry_config();
|
|
@@ -90196,7 +90467,7 @@ async function handleOff() {
|
|
|
90196
90467
|
info("Mission Control will not auto-start. Existing usage rows are kept.");
|
|
90197
90468
|
}
|
|
90198
90469
|
async function handleWriteEnv(argv) {
|
|
90199
|
-
const repoPath =
|
|
90470
|
+
const repoPath = path60.resolve(argv.repo);
|
|
90200
90471
|
const harnessRoot = resolveHarnessRoot(repoPath);
|
|
90201
90472
|
const session = readSlotRegistry(harnessRoot, argv.agentId);
|
|
90202
90473
|
const workDir = argv.workDir ?? session?.workDir ?? repoPath;
|
|
@@ -90208,7 +90479,7 @@ async function handleWriteEnv(argv) {
|
|
|
90208
90479
|
suffix,
|
|
90209
90480
|
createdAt: session?.createdAt
|
|
90210
90481
|
});
|
|
90211
|
-
const envFile = argv.envFile ??
|
|
90482
|
+
const envFile = argv.envFile ?? path60.join(workDir, `.env.agent.${argv.agentId}`);
|
|
90212
90483
|
const attrs = {
|
|
90213
90484
|
sessionKey,
|
|
90214
90485
|
agentId: argv.agentId,
|
|
@@ -90224,7 +90495,7 @@ async function handleWriteEnv(argv) {
|
|
|
90224
90495
|
success(`Wrote session attribution to ${envFile}`);
|
|
90225
90496
|
}
|
|
90226
90497
|
function handlePrintEnv(argv) {
|
|
90227
|
-
const repoPath =
|
|
90498
|
+
const repoPath = path60.resolve(argv.repo);
|
|
90228
90499
|
const workDir = argv.workDir ?? repoPath;
|
|
90229
90500
|
const sessionKey = buildSessionKey({
|
|
90230
90501
|
branch: argv.branch,
|