@osfactory/har 0.56.1 → 0.57.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 +1050 -580
- package/dist/templates/profiles/cli/profile.manifest.json +8 -0
- package/dist/templates/profiles/default/profile.manifest.json +9 -0
- package/dist/templates/profiles/ios/profile.manifest.json +9 -0
- package/dist/templates/runtime-bundles/pm2-runtime/README.md +4 -0
- package/dist/templates/runtime-bundles/pm2-runtime/attach.sh +22 -0
- package/dist/templates/runtime-bundles/pm2-runtime/ecosystem.agent.template.cjs +46 -0
- package/dist/templates/runtime-bundles/pm2-runtime/env.template +40 -0
- package/dist/templates/runtime-bundles/shared-kernel/README.md +3 -0
- package/dist/templates/runtime-bundles/shared-kernel/STAGES.md +99 -0
- package/dist/templates/runtime-bundles/shared-kernel/provision-toolchain.sh +407 -0
- package/dist/templates/runtime-bundles/shared-kernel/stages/README.sh +11 -0
- package/dist/templates/runtime-bundles/xcode-sim/README.md +4 -0
- package/dist/templates/runtime-bundles/xcode-sim/simulator.sh +492 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -553,8 +553,8 @@ var init_parseUtil = __esm({
|
|
|
553
553
|
init_errors();
|
|
554
554
|
init_en();
|
|
555
555
|
makeIssue = (params) => {
|
|
556
|
-
const { data, path:
|
|
557
|
-
const fullPath = [...
|
|
556
|
+
const { data, path: path65, errorMaps, issueData } = params;
|
|
557
|
+
const fullPath = [...path65, ...issueData.path || []];
|
|
558
558
|
const fullIssue = {
|
|
559
559
|
...issueData,
|
|
560
560
|
path: fullPath
|
|
@@ -862,11 +862,11 @@ var init_types = __esm({
|
|
|
862
862
|
init_parseUtil();
|
|
863
863
|
init_util();
|
|
864
864
|
ParseInputLazyPath = class {
|
|
865
|
-
constructor(parent, value,
|
|
865
|
+
constructor(parent, value, path65, key) {
|
|
866
866
|
this._cachedPath = [];
|
|
867
867
|
this.parent = parent;
|
|
868
868
|
this.data = value;
|
|
869
|
-
this._path =
|
|
869
|
+
this._path = path65;
|
|
870
870
|
this._key = key;
|
|
871
871
|
}
|
|
872
872
|
get path() {
|
|
@@ -28353,6 +28353,7 @@ var init_manifest = __esm({
|
|
|
28353
28353
|
DEFAULT_HAR_DIR = ".har";
|
|
28354
28354
|
CHECKSUM_SKIP = /* @__PURE__ */ new Set([
|
|
28355
28355
|
"manifest.json",
|
|
28356
|
+
"plugins.json",
|
|
28356
28357
|
"AGENTS.md.proposed",
|
|
28357
28358
|
"AGENTS.md.proposed.meta.json",
|
|
28358
28359
|
"AGENT.md.proposed",
|
|
@@ -28757,7 +28758,7 @@ function runScript(scriptPath, args = [], options = {}) {
|
|
|
28757
28758
|
function runScriptCapture(scriptPath, args = [], options = {}) {
|
|
28758
28759
|
const stream = options.stream ?? false;
|
|
28759
28760
|
const { stream: _stream, ...spawnOptions } = options;
|
|
28760
|
-
return new Promise((
|
|
28761
|
+
return new Promise((resolve49) => {
|
|
28761
28762
|
const proc = (0, import_child_process.spawn)("bash", [scriptPath, ...args], {
|
|
28762
28763
|
...spawnOptions,
|
|
28763
28764
|
stdio: ["inherit", "pipe", "pipe"]
|
|
@@ -28772,13 +28773,13 @@ function runScriptCapture(scriptPath, args = [], options = {}) {
|
|
|
28772
28773
|
stderr += d;
|
|
28773
28774
|
if (stream) process.stderr.write(d);
|
|
28774
28775
|
});
|
|
28775
|
-
proc.on("close", (code) =>
|
|
28776
|
+
proc.on("close", (code) => resolve49({ stdout, stderr, code: code ?? 0 }));
|
|
28776
28777
|
});
|
|
28777
28778
|
}
|
|
28778
28779
|
function runShellCommand(command2, options = {}) {
|
|
28779
28780
|
const stream = options.stream ?? false;
|
|
28780
28781
|
const { stream: _stream, ...spawnOptions } = options;
|
|
28781
|
-
return new Promise((
|
|
28782
|
+
return new Promise((resolve49) => {
|
|
28782
28783
|
const proc = (0, import_child_process.spawn)("bash", ["-lc", command2], {
|
|
28783
28784
|
...spawnOptions,
|
|
28784
28785
|
stdio: ["inherit", "pipe", "pipe"]
|
|
@@ -28793,7 +28794,7 @@ function runShellCommand(command2, options = {}) {
|
|
|
28793
28794
|
stderr += d;
|
|
28794
28795
|
if (stream) process.stderr.write(d);
|
|
28795
28796
|
});
|
|
28796
|
-
proc.on("close", (code) =>
|
|
28797
|
+
proc.on("close", (code) => resolve49({ stdout, stderr, code: code ?? 0 }));
|
|
28797
28798
|
});
|
|
28798
28799
|
}
|
|
28799
28800
|
var import_child_process;
|
|
@@ -29495,6 +29496,22 @@ var init_runs = __esm({
|
|
|
29495
29496
|
}
|
|
29496
29497
|
});
|
|
29497
29498
|
|
|
29499
|
+
// src/harness/capabilities.ts
|
|
29500
|
+
function harnessUsesPm2(repoPath) {
|
|
29501
|
+
const harnessRoot = resolveHarnessRoot(repoPath);
|
|
29502
|
+
return fs13.existsSync(path13.join(harnessRoot, ".har", "ecosystem.agent.template.cjs"));
|
|
29503
|
+
}
|
|
29504
|
+
var fs13, path13;
|
|
29505
|
+
var init_capabilities = __esm({
|
|
29506
|
+
"src/harness/capabilities.ts"() {
|
|
29507
|
+
"use strict";
|
|
29508
|
+
fs13 = __toESM(require("fs"));
|
|
29509
|
+
path13 = __toESM(require("path"));
|
|
29510
|
+
init_manifest();
|
|
29511
|
+
init_env();
|
|
29512
|
+
}
|
|
29513
|
+
});
|
|
29514
|
+
|
|
29498
29515
|
// src/core/slot-ports.ts
|
|
29499
29516
|
function portStep(env3) {
|
|
29500
29517
|
return Number(env3.HARNESS_PORT_STEP ?? 10);
|
|
@@ -29549,19 +29566,14 @@ function allocateAppPorts(repoPath, agentId) {
|
|
|
29549
29566
|
allocated: frontend !== feDefault || api !== apiDefault || debug !== debugDefault
|
|
29550
29567
|
};
|
|
29551
29568
|
}
|
|
29552
|
-
|
|
29553
|
-
const harnessRoot = resolveHarnessRoot(repoPath);
|
|
29554
|
-
return fs13.existsSync(path13.join(harnessRoot, ".har", "ecosystem.agent.template.cjs"));
|
|
29555
|
-
}
|
|
29556
|
-
var import_child_process3, fs13, path13;
|
|
29569
|
+
var import_child_process3;
|
|
29557
29570
|
var init_slot_ports = __esm({
|
|
29558
29571
|
"src/core/slot-ports.ts"() {
|
|
29559
29572
|
"use strict";
|
|
29560
29573
|
import_child_process3 = require("child_process");
|
|
29561
|
-
fs13 = __toESM(require("fs"));
|
|
29562
|
-
path13 = __toESM(require("path"));
|
|
29563
29574
|
init_env();
|
|
29564
29575
|
init_manifest();
|
|
29576
|
+
init_capabilities();
|
|
29565
29577
|
}
|
|
29566
29578
|
});
|
|
29567
29579
|
|
|
@@ -30628,6 +30640,7 @@ var init_slot_preflight = __esm({
|
|
|
30628
30640
|
init_control_port();
|
|
30629
30641
|
init_slot_launch_guard_occupied();
|
|
30630
30642
|
init_slot_ports();
|
|
30643
|
+
init_capabilities();
|
|
30631
30644
|
init_slot_registry();
|
|
30632
30645
|
init_worktree_untracked();
|
|
30633
30646
|
import_child_process8 = require("child_process");
|
|
@@ -32418,7 +32431,7 @@ async function postForResponse(url, headers, payload) {
|
|
|
32418
32431
|
} catch (err) {
|
|
32419
32432
|
lastErr = err;
|
|
32420
32433
|
if (attempt < MAX_FETCH_ATTEMPTS) {
|
|
32421
|
-
await new Promise((
|
|
32434
|
+
await new Promise((resolve49) => setTimeout(resolve49, attempt * 100));
|
|
32422
32435
|
}
|
|
32423
32436
|
}
|
|
32424
32437
|
}
|
|
@@ -32618,7 +32631,7 @@ async function waitForControlApi(apiUrl = getControlApiUrl(), timeoutMs = 6e4, i
|
|
|
32618
32631
|
const deadline = Date.now() + timeoutMs;
|
|
32619
32632
|
while (Date.now() < deadline) {
|
|
32620
32633
|
if (await isControlApiReachable(apiUrl)) return true;
|
|
32621
|
-
await new Promise((
|
|
32634
|
+
await new Promise((resolve49) => setTimeout(resolve49, intervalMs));
|
|
32622
32635
|
}
|
|
32623
32636
|
return false;
|
|
32624
32637
|
}
|
|
@@ -34115,15 +34128,15 @@ var require_route = __commonJS({
|
|
|
34115
34128
|
};
|
|
34116
34129
|
}
|
|
34117
34130
|
function wrapConversion(toModel, graph) {
|
|
34118
|
-
const
|
|
34131
|
+
const path65 = [graph[toModel].parent, toModel];
|
|
34119
34132
|
let fn = conversions[graph[toModel].parent][toModel];
|
|
34120
34133
|
let cur = graph[toModel].parent;
|
|
34121
34134
|
while (graph[cur].parent) {
|
|
34122
|
-
|
|
34135
|
+
path65.unshift(graph[cur].parent);
|
|
34123
34136
|
fn = link(conversions[graph[cur].parent][cur], fn);
|
|
34124
34137
|
cur = graph[cur].parent;
|
|
34125
34138
|
}
|
|
34126
|
-
fn.conversion =
|
|
34139
|
+
fn.conversion = path65;
|
|
34127
34140
|
return fn;
|
|
34128
34141
|
}
|
|
34129
34142
|
module2.exports = function(fromModel) {
|
|
@@ -40053,7 +40066,7 @@ var require_iso2022 = __commonJS({
|
|
|
40053
40066
|
// node_modules/chardet/index.js
|
|
40054
40067
|
var require_chardet = __commonJS({
|
|
40055
40068
|
"node_modules/chardet/index.js"(exports2, module2) {
|
|
40056
|
-
var
|
|
40069
|
+
var fs51 = require("fs");
|
|
40057
40070
|
var utf8 = require_utf8();
|
|
40058
40071
|
var unicode = require_unicode();
|
|
40059
40072
|
var mbcs = require_mbcs();
|
|
@@ -40127,28 +40140,28 @@ var require_chardet = __commonJS({
|
|
|
40127
40140
|
var fd;
|
|
40128
40141
|
var handler = function(err, buffer) {
|
|
40129
40142
|
if (fd) {
|
|
40130
|
-
|
|
40143
|
+
fs51.closeSync(fd);
|
|
40131
40144
|
}
|
|
40132
40145
|
if (err) return cb(err, null);
|
|
40133
40146
|
cb(null, self.detect(buffer, opts));
|
|
40134
40147
|
};
|
|
40135
40148
|
if (opts && opts.sampleSize) {
|
|
40136
|
-
fd =
|
|
40137
|
-
|
|
40149
|
+
fd = fs51.openSync(filepath, "r"), sample = Buffer.allocUnsafe(opts.sampleSize);
|
|
40150
|
+
fs51.read(fd, sample, 0, opts.sampleSize, null, function(err) {
|
|
40138
40151
|
handler(err, sample);
|
|
40139
40152
|
});
|
|
40140
40153
|
return;
|
|
40141
40154
|
}
|
|
40142
|
-
|
|
40155
|
+
fs51.readFile(filepath, handler);
|
|
40143
40156
|
};
|
|
40144
40157
|
module2.exports.detectFileSync = function(filepath, opts) {
|
|
40145
40158
|
if (opts && opts.sampleSize) {
|
|
40146
|
-
var fd =
|
|
40147
|
-
|
|
40148
|
-
|
|
40159
|
+
var fd = fs51.openSync(filepath, "r"), sample2 = Buffer.allocUnsafe(opts.sampleSize);
|
|
40160
|
+
fs51.readSync(fd, sample2, 0, opts.sampleSize);
|
|
40161
|
+
fs51.closeSync(fd);
|
|
40149
40162
|
return self.detect(sample2, opts);
|
|
40150
40163
|
}
|
|
40151
|
-
return self.detect(
|
|
40164
|
+
return self.detect(fs51.readFileSync(filepath), opts);
|
|
40152
40165
|
};
|
|
40153
40166
|
module2.exports.detectAll = function(buffer, opts) {
|
|
40154
40167
|
if (typeof opts !== "object") {
|
|
@@ -43613,16 +43626,16 @@ var require_os_tmpdir = __commonJS({
|
|
|
43613
43626
|
var isWindows = process.platform === "win32";
|
|
43614
43627
|
var trailingSlashRe = isWindows ? /[^:]\\$/ : /.\/$/;
|
|
43615
43628
|
module2.exports = function() {
|
|
43616
|
-
var
|
|
43629
|
+
var path65;
|
|
43617
43630
|
if (isWindows) {
|
|
43618
|
-
|
|
43631
|
+
path65 = process.env.TEMP || process.env.TMP || (process.env.SystemRoot || process.env.windir) + "\\temp";
|
|
43619
43632
|
} else {
|
|
43620
|
-
|
|
43633
|
+
path65 = process.env.TMPDIR || process.env.TMP || process.env.TEMP || "/tmp";
|
|
43621
43634
|
}
|
|
43622
|
-
if (trailingSlashRe.test(
|
|
43623
|
-
|
|
43635
|
+
if (trailingSlashRe.test(path65)) {
|
|
43636
|
+
path65 = path65.slice(0, -1);
|
|
43624
43637
|
}
|
|
43625
|
-
return
|
|
43638
|
+
return path65;
|
|
43626
43639
|
};
|
|
43627
43640
|
}
|
|
43628
43641
|
});
|
|
@@ -43630,8 +43643,8 @@ var require_os_tmpdir = __commonJS({
|
|
|
43630
43643
|
// node_modules/tmp/lib/tmp.js
|
|
43631
43644
|
var require_tmp = __commonJS({
|
|
43632
43645
|
"node_modules/tmp/lib/tmp.js"(exports2, module2) {
|
|
43633
|
-
var
|
|
43634
|
-
var
|
|
43646
|
+
var fs51 = require("fs");
|
|
43647
|
+
var path65 = require("path");
|
|
43635
43648
|
var crypto6 = require("crypto");
|
|
43636
43649
|
var osTmpDir = require_os_tmpdir();
|
|
43637
43650
|
var _c2 = process.binding("constants");
|
|
@@ -43673,7 +43686,7 @@ var require_tmp = __commonJS({
|
|
|
43673
43686
|
}
|
|
43674
43687
|
function _generateTmpName(opts) {
|
|
43675
43688
|
if (opts.name) {
|
|
43676
|
-
return
|
|
43689
|
+
return path65.join(opts.dir || tmpDir, opts.name);
|
|
43677
43690
|
}
|
|
43678
43691
|
if (opts.template) {
|
|
43679
43692
|
return opts.template.replace(TEMPLATE_PATTERN, _randomChars(6));
|
|
@@ -43684,7 +43697,7 @@ var require_tmp = __commonJS({
|
|
|
43684
43697
|
_randomChars(12),
|
|
43685
43698
|
opts.postfix || ""
|
|
43686
43699
|
].join("");
|
|
43687
|
-
return
|
|
43700
|
+
return path65.join(opts.dir || tmpDir, name);
|
|
43688
43701
|
}
|
|
43689
43702
|
function tmpName(options, callback) {
|
|
43690
43703
|
var args = _parseArguments(options, callback), opts = args[0], cb = args[1], tries = opts.name ? 1 : opts.tries || DEFAULT_TRIES;
|
|
@@ -43694,7 +43707,7 @@ var require_tmp = __commonJS({
|
|
|
43694
43707
|
return cb(new Error("Invalid template provided"));
|
|
43695
43708
|
(function _getUniqueName() {
|
|
43696
43709
|
const name = _generateTmpName(opts);
|
|
43697
|
-
|
|
43710
|
+
fs51.stat(name, function(err) {
|
|
43698
43711
|
if (!err) {
|
|
43699
43712
|
if (tries-- > 0) return _getUniqueName();
|
|
43700
43713
|
return cb(new Error("Could not get a unique tmp filename, max tries reached " + name));
|
|
@@ -43712,7 +43725,7 @@ var require_tmp = __commonJS({
|
|
|
43712
43725
|
do {
|
|
43713
43726
|
const name = _generateTmpName(opts);
|
|
43714
43727
|
try {
|
|
43715
|
-
|
|
43728
|
+
fs51.statSync(name);
|
|
43716
43729
|
} catch (e) {
|
|
43717
43730
|
return name;
|
|
43718
43731
|
}
|
|
@@ -43724,13 +43737,13 @@ var require_tmp = __commonJS({
|
|
|
43724
43737
|
opts.postfix = _isUndefined(opts.postfix) ? ".tmp" : opts.postfix;
|
|
43725
43738
|
tmpName(opts, function _tmpNameCreated(err, name) {
|
|
43726
43739
|
if (err) return cb(err);
|
|
43727
|
-
|
|
43740
|
+
fs51.open(name, CREATE_FLAGS, opts.mode || FILE_MODE, function _fileCreated(err2, fd) {
|
|
43728
43741
|
if (err2) return cb(err2);
|
|
43729
43742
|
if (opts.discardDescriptor) {
|
|
43730
|
-
return
|
|
43743
|
+
return fs51.close(fd, function _discardCallback(err3) {
|
|
43731
43744
|
if (err3) {
|
|
43732
43745
|
try {
|
|
43733
|
-
|
|
43746
|
+
fs51.unlinkSync(name);
|
|
43734
43747
|
} catch (e) {
|
|
43735
43748
|
if (!isENOENT(e)) {
|
|
43736
43749
|
err3 = e;
|
|
@@ -43753,9 +43766,9 @@ var require_tmp = __commonJS({
|
|
|
43753
43766
|
opts.postfix = opts.postfix || ".tmp";
|
|
43754
43767
|
const discardOrDetachDescriptor = opts.discardDescriptor || opts.detachDescriptor;
|
|
43755
43768
|
const name = tmpNameSync(opts);
|
|
43756
|
-
var fd =
|
|
43769
|
+
var fd = fs51.openSync(name, CREATE_FLAGS, opts.mode || FILE_MODE);
|
|
43757
43770
|
if (opts.discardDescriptor) {
|
|
43758
|
-
|
|
43771
|
+
fs51.closeSync(fd);
|
|
43759
43772
|
fd = void 0;
|
|
43760
43773
|
}
|
|
43761
43774
|
return {
|
|
@@ -43767,9 +43780,9 @@ var require_tmp = __commonJS({
|
|
|
43767
43780
|
function _rmdirRecursiveSync(root) {
|
|
43768
43781
|
const dirs = [root];
|
|
43769
43782
|
do {
|
|
43770
|
-
var dir2 = dirs.pop(), deferred = false, files =
|
|
43783
|
+
var dir2 = dirs.pop(), deferred = false, files = fs51.readdirSync(dir2);
|
|
43771
43784
|
for (var i = 0, length = files.length; i < length; i++) {
|
|
43772
|
-
var file2 =
|
|
43785
|
+
var file2 = path65.join(dir2, files[i]), stat = fs51.lstatSync(file2);
|
|
43773
43786
|
if (stat.isDirectory()) {
|
|
43774
43787
|
if (!deferred) {
|
|
43775
43788
|
deferred = true;
|
|
@@ -43777,11 +43790,11 @@ var require_tmp = __commonJS({
|
|
|
43777
43790
|
}
|
|
43778
43791
|
dirs.push(file2);
|
|
43779
43792
|
} else {
|
|
43780
|
-
|
|
43793
|
+
fs51.unlinkSync(file2);
|
|
43781
43794
|
}
|
|
43782
43795
|
}
|
|
43783
43796
|
if (!deferred) {
|
|
43784
|
-
|
|
43797
|
+
fs51.rmdirSync(dir2);
|
|
43785
43798
|
}
|
|
43786
43799
|
} while (dirs.length !== 0);
|
|
43787
43800
|
}
|
|
@@ -43789,7 +43802,7 @@ var require_tmp = __commonJS({
|
|
|
43789
43802
|
var args = _parseArguments(options, callback), opts = args[0], cb = args[1];
|
|
43790
43803
|
tmpName(opts, function _tmpNameCreated(err, name) {
|
|
43791
43804
|
if (err) return cb(err);
|
|
43792
|
-
|
|
43805
|
+
fs51.mkdir(name, opts.mode || DIR_MODE, function _dirCreated(err2) {
|
|
43793
43806
|
if (err2) return cb(err2);
|
|
43794
43807
|
cb(null, name, _prepareTmpDirRemoveCallback(name, opts));
|
|
43795
43808
|
});
|
|
@@ -43798,7 +43811,7 @@ var require_tmp = __commonJS({
|
|
|
43798
43811
|
function dirSync(options) {
|
|
43799
43812
|
var args = _parseArguments(options), opts = args[0];
|
|
43800
43813
|
const name = tmpNameSync(opts);
|
|
43801
|
-
|
|
43814
|
+
fs51.mkdirSync(name, opts.mode || DIR_MODE);
|
|
43802
43815
|
return {
|
|
43803
43816
|
name,
|
|
43804
43817
|
removeCallback: _prepareTmpDirRemoveCallback(name, opts)
|
|
@@ -43808,7 +43821,7 @@ var require_tmp = __commonJS({
|
|
|
43808
43821
|
const removeCallback = _prepareRemoveCallback(function _removeCallback(fdPath) {
|
|
43809
43822
|
try {
|
|
43810
43823
|
if (0 <= fdPath[0]) {
|
|
43811
|
-
|
|
43824
|
+
fs51.closeSync(fdPath[0]);
|
|
43812
43825
|
}
|
|
43813
43826
|
} catch (e) {
|
|
43814
43827
|
if (!isEBADF(e) && !isENOENT(e)) {
|
|
@@ -43816,7 +43829,7 @@ var require_tmp = __commonJS({
|
|
|
43816
43829
|
}
|
|
43817
43830
|
}
|
|
43818
43831
|
try {
|
|
43819
|
-
|
|
43832
|
+
fs51.unlinkSync(fdPath[1]);
|
|
43820
43833
|
} catch (e) {
|
|
43821
43834
|
if (!isENOENT(e)) {
|
|
43822
43835
|
throw e;
|
|
@@ -43829,7 +43842,7 @@ var require_tmp = __commonJS({
|
|
|
43829
43842
|
return removeCallback;
|
|
43830
43843
|
}
|
|
43831
43844
|
function _prepareTmpDirRemoveCallback(name, opts) {
|
|
43832
|
-
const removeFunction = opts.unsafeCleanup ? _rmdirRecursiveSync :
|
|
43845
|
+
const removeFunction = opts.unsafeCleanup ? _rmdirRecursiveSync : fs51.rmdirSync.bind(fs51);
|
|
43833
43846
|
const removeCallback = _prepareRemoveCallback(removeFunction, name);
|
|
43834
43847
|
if (!opts.keep) {
|
|
43835
43848
|
_removeObjects.unshift(removeCallback);
|
|
@@ -44980,7 +44993,7 @@ var require_Observable = __commonJS({
|
|
|
44980
44993
|
Observable2.prototype.forEach = function(next, promiseCtor) {
|
|
44981
44994
|
var _this = this;
|
|
44982
44995
|
promiseCtor = getPromiseCtor(promiseCtor);
|
|
44983
|
-
return new promiseCtor(function(
|
|
44996
|
+
return new promiseCtor(function(resolve49, reject) {
|
|
44984
44997
|
var subscriber = new Subscriber_1.SafeSubscriber({
|
|
44985
44998
|
next: function(value) {
|
|
44986
44999
|
try {
|
|
@@ -44991,7 +45004,7 @@ var require_Observable = __commonJS({
|
|
|
44991
45004
|
}
|
|
44992
45005
|
},
|
|
44993
45006
|
error: reject,
|
|
44994
|
-
complete:
|
|
45007
|
+
complete: resolve49
|
|
44995
45008
|
});
|
|
44996
45009
|
_this.subscribe(subscriber);
|
|
44997
45010
|
});
|
|
@@ -45013,14 +45026,14 @@ var require_Observable = __commonJS({
|
|
|
45013
45026
|
Observable2.prototype.toPromise = function(promiseCtor) {
|
|
45014
45027
|
var _this = this;
|
|
45015
45028
|
promiseCtor = getPromiseCtor(promiseCtor);
|
|
45016
|
-
return new promiseCtor(function(
|
|
45029
|
+
return new promiseCtor(function(resolve49, reject) {
|
|
45017
45030
|
var value;
|
|
45018
45031
|
_this.subscribe(function(x) {
|
|
45019
45032
|
return value = x;
|
|
45020
45033
|
}, function(err) {
|
|
45021
45034
|
return reject(err);
|
|
45022
45035
|
}, function() {
|
|
45023
|
-
return
|
|
45036
|
+
return resolve49(value);
|
|
45024
45037
|
});
|
|
45025
45038
|
});
|
|
45026
45039
|
};
|
|
@@ -47116,11 +47129,11 @@ var require_innerFrom = __commonJS({
|
|
|
47116
47129
|
"use strict";
|
|
47117
47130
|
var __awaiter = exports2 && exports2.__awaiter || function(thisArg, _arguments, P2, generator) {
|
|
47118
47131
|
function adopt(value) {
|
|
47119
|
-
return value instanceof P2 ? value : new P2(function(
|
|
47120
|
-
|
|
47132
|
+
return value instanceof P2 ? value : new P2(function(resolve49) {
|
|
47133
|
+
resolve49(value);
|
|
47121
47134
|
});
|
|
47122
47135
|
}
|
|
47123
|
-
return new (P2 || (P2 = Promise))(function(
|
|
47136
|
+
return new (P2 || (P2 = Promise))(function(resolve49, reject) {
|
|
47124
47137
|
function fulfilled(value) {
|
|
47125
47138
|
try {
|
|
47126
47139
|
step(generator.next(value));
|
|
@@ -47136,7 +47149,7 @@ var require_innerFrom = __commonJS({
|
|
|
47136
47149
|
}
|
|
47137
47150
|
}
|
|
47138
47151
|
function step(result) {
|
|
47139
|
-
result.done ?
|
|
47152
|
+
result.done ? resolve49(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
47140
47153
|
}
|
|
47141
47154
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
47142
47155
|
});
|
|
@@ -47218,14 +47231,14 @@ var require_innerFrom = __commonJS({
|
|
|
47218
47231
|
}, i);
|
|
47219
47232
|
function verb(n) {
|
|
47220
47233
|
i[n] = o[n] && function(v2) {
|
|
47221
|
-
return new Promise(function(
|
|
47222
|
-
v2 = o[n](v2), settle(
|
|
47234
|
+
return new Promise(function(resolve49, reject) {
|
|
47235
|
+
v2 = o[n](v2), settle(resolve49, reject, v2.done, v2.value);
|
|
47223
47236
|
});
|
|
47224
47237
|
};
|
|
47225
47238
|
}
|
|
47226
|
-
function settle(
|
|
47239
|
+
function settle(resolve49, reject, d, v2) {
|
|
47227
47240
|
Promise.resolve(v2).then(function(v3) {
|
|
47228
|
-
|
|
47241
|
+
resolve49({ value: v3, done: d });
|
|
47229
47242
|
}, reject);
|
|
47230
47243
|
}
|
|
47231
47244
|
};
|
|
@@ -47844,7 +47857,7 @@ var require_lastValueFrom = __commonJS({
|
|
|
47844
47857
|
var EmptyError_1 = require_EmptyError();
|
|
47845
47858
|
function lastValueFrom2(source, config2) {
|
|
47846
47859
|
var hasConfig = typeof config2 === "object";
|
|
47847
|
-
return new Promise(function(
|
|
47860
|
+
return new Promise(function(resolve49, reject) {
|
|
47848
47861
|
var _hasValue = false;
|
|
47849
47862
|
var _value;
|
|
47850
47863
|
source.subscribe({
|
|
@@ -47855,9 +47868,9 @@ var require_lastValueFrom = __commonJS({
|
|
|
47855
47868
|
error: reject,
|
|
47856
47869
|
complete: function() {
|
|
47857
47870
|
if (_hasValue) {
|
|
47858
|
-
|
|
47871
|
+
resolve49(_value);
|
|
47859
47872
|
} else if (hasConfig) {
|
|
47860
|
-
|
|
47873
|
+
resolve49(config2.defaultValue);
|
|
47861
47874
|
} else {
|
|
47862
47875
|
reject(new EmptyError_1.EmptyError());
|
|
47863
47876
|
}
|
|
@@ -47879,16 +47892,16 @@ var require_firstValueFrom = __commonJS({
|
|
|
47879
47892
|
var Subscriber_1 = require_Subscriber();
|
|
47880
47893
|
function firstValueFrom(source, config2) {
|
|
47881
47894
|
var hasConfig = typeof config2 === "object";
|
|
47882
|
-
return new Promise(function(
|
|
47895
|
+
return new Promise(function(resolve49, reject) {
|
|
47883
47896
|
var subscriber = new Subscriber_1.SafeSubscriber({
|
|
47884
47897
|
next: function(value) {
|
|
47885
|
-
|
|
47898
|
+
resolve49(value);
|
|
47886
47899
|
subscriber.unsubscribe();
|
|
47887
47900
|
},
|
|
47888
47901
|
error: reject,
|
|
47889
47902
|
complete: function() {
|
|
47890
47903
|
if (hasConfig) {
|
|
47891
|
-
|
|
47904
|
+
resolve49(config2.defaultValue);
|
|
47892
47905
|
} else {
|
|
47893
47906
|
reject(new EmptyError_1.EmptyError());
|
|
47894
47907
|
}
|
|
@@ -53681,14 +53694,14 @@ var require_run_async = __commonJS({
|
|
|
53681
53694
|
return function() {
|
|
53682
53695
|
var args = arguments;
|
|
53683
53696
|
var originalThis = this;
|
|
53684
|
-
var promise = new Promise(function(
|
|
53697
|
+
var promise = new Promise(function(resolve49, reject) {
|
|
53685
53698
|
var resolved = false;
|
|
53686
53699
|
const wrappedResolve = function(value) {
|
|
53687
53700
|
if (resolved) {
|
|
53688
53701
|
console.warn("Run-async promise already resolved.");
|
|
53689
53702
|
}
|
|
53690
53703
|
resolved = true;
|
|
53691
|
-
|
|
53704
|
+
resolve49(value);
|
|
53692
53705
|
};
|
|
53693
53706
|
var rejected = false;
|
|
53694
53707
|
const wrappedReject = function(value) {
|
|
@@ -53788,32 +53801,32 @@ __export(otel_hooks_exports, {
|
|
|
53788
53801
|
});
|
|
53789
53802
|
function getOtelHooksHome() {
|
|
53790
53803
|
if (process.env.HAR_OTEL_HOOKS_HOME) {
|
|
53791
|
-
return
|
|
53804
|
+
return path51.resolve(process.env.HAR_OTEL_HOOKS_HOME);
|
|
53792
53805
|
}
|
|
53793
|
-
return
|
|
53806
|
+
return path51.join(os17.homedir(), ".har", "otel-hooks");
|
|
53794
53807
|
}
|
|
53795
53808
|
function getOtelHooksConfigPath(hooksHome = getOtelHooksHome()) {
|
|
53796
|
-
return
|
|
53809
|
+
return path51.join(hooksHome, "otel_config.json");
|
|
53797
53810
|
}
|
|
53798
53811
|
function getOtelHooksWrapperPath(hooksHome = getOtelHooksHome()) {
|
|
53799
|
-
return
|
|
53812
|
+
return path51.join(hooksHome, "run-otel-hook.sh");
|
|
53800
53813
|
}
|
|
53801
53814
|
function getOtelHooksStateDir(hooksHome = getOtelHooksHome()) {
|
|
53802
|
-
return
|
|
53815
|
+
return path51.join(hooksHome, "state");
|
|
53803
53816
|
}
|
|
53804
53817
|
function localOtelHookBin(hooksHome) {
|
|
53805
|
-
return
|
|
53818
|
+
return path51.join(hooksHome, "node_modules", ".bin", "otel-hook");
|
|
53806
53819
|
}
|
|
53807
53820
|
function installedPackageVersion(hooksHome) {
|
|
53808
53821
|
try {
|
|
53809
|
-
const pkgPath =
|
|
53822
|
+
const pkgPath = path51.join(
|
|
53810
53823
|
hooksHome,
|
|
53811
53824
|
"node_modules",
|
|
53812
53825
|
"@osfactory",
|
|
53813
53826
|
"otel-hook",
|
|
53814
53827
|
"package.json"
|
|
53815
53828
|
);
|
|
53816
|
-
const pkg = JSON.parse(
|
|
53829
|
+
const pkg = JSON.parse(fs45.readFileSync(pkgPath, "utf8"));
|
|
53817
53830
|
return typeof pkg.version === "string" ? pkg.version : null;
|
|
53818
53831
|
} catch {
|
|
53819
53832
|
return null;
|
|
@@ -53864,15 +53877,15 @@ function buildOtelHooksConfig(options) {
|
|
|
53864
53877
|
};
|
|
53865
53878
|
}
|
|
53866
53879
|
function writeOtelHooksConfig(config2, hooksHome = getOtelHooksHome()) {
|
|
53867
|
-
|
|
53880
|
+
fs45.mkdirSync(hooksHome, { recursive: true });
|
|
53868
53881
|
const configPath = getOtelHooksConfigPath(hooksHome);
|
|
53869
|
-
|
|
53882
|
+
fs45.writeFileSync(configPath, `${JSON.stringify(config2, null, 2)}
|
|
53870
53883
|
`);
|
|
53871
53884
|
return configPath;
|
|
53872
53885
|
}
|
|
53873
53886
|
function writeOtelHooksWrapper(otelHookCommand, hooksHome = getOtelHooksHome()) {
|
|
53874
|
-
|
|
53875
|
-
|
|
53887
|
+
fs45.mkdirSync(hooksHome, { recursive: true });
|
|
53888
|
+
fs45.mkdirSync(getOtelHooksStateDir(hooksHome), { recursive: true });
|
|
53876
53889
|
const wrapperPath = getOtelHooksWrapperPath(hooksHome);
|
|
53877
53890
|
const configPath = getOtelHooksConfigPath(hooksHome);
|
|
53878
53891
|
const stateDir = getOtelHooksStateDir(hooksHome);
|
|
@@ -53884,22 +53897,22 @@ exec "${otelHookCommand}" run \\
|
|
|
53884
53897
|
--state-dir "${stateDir}" \\
|
|
53885
53898
|
"$@"
|
|
53886
53899
|
`;
|
|
53887
|
-
|
|
53900
|
+
fs45.writeFileSync(wrapperPath, script, { mode: 493 });
|
|
53888
53901
|
try {
|
|
53889
|
-
|
|
53902
|
+
fs45.chmodSync(wrapperPath, 493);
|
|
53890
53903
|
} catch {
|
|
53891
53904
|
}
|
|
53892
53905
|
return wrapperPath;
|
|
53893
53906
|
}
|
|
53894
53907
|
function commandExists3(command2) {
|
|
53895
|
-
const result = (0,
|
|
53908
|
+
const result = (0, import_child_process13.spawnSync)("sh", ["-c", `command -v ${JSON.stringify(command2)}`], {
|
|
53896
53909
|
encoding: "utf8"
|
|
53897
53910
|
});
|
|
53898
53911
|
return result.status === 0 && Boolean(result.stdout?.trim());
|
|
53899
53912
|
}
|
|
53900
53913
|
function resolveOtelHookCommand(hooksHome) {
|
|
53901
53914
|
const local = localOtelHookBin(hooksHome);
|
|
53902
|
-
if (
|
|
53915
|
+
if (fs45.existsSync(local)) return local;
|
|
53903
53916
|
return null;
|
|
53904
53917
|
}
|
|
53905
53918
|
function resolveHooksInstaller(hooksHome) {
|
|
@@ -53914,7 +53927,7 @@ function resolveHooksInstaller(hooksHome) {
|
|
|
53914
53927
|
return candidates.find((candidate) => commandExists3(candidate.command)) ?? null;
|
|
53915
53928
|
}
|
|
53916
53929
|
function tryInstallPackage(hooksHome) {
|
|
53917
|
-
|
|
53930
|
+
fs45.mkdirSync(hooksHome, { recursive: true });
|
|
53918
53931
|
const installer = resolveHooksInstaller(hooksHome);
|
|
53919
53932
|
if (!installer) {
|
|
53920
53933
|
return {
|
|
@@ -53923,11 +53936,11 @@ function tryInstallPackage(hooksHome) {
|
|
|
53923
53936
|
};
|
|
53924
53937
|
}
|
|
53925
53938
|
const described = `${installer.command} ${installer.args.join(" ")}`;
|
|
53926
|
-
const result = (0,
|
|
53939
|
+
const result = (0, import_child_process13.spawnSync)(installer.command, installer.args, {
|
|
53927
53940
|
encoding: "utf8",
|
|
53928
53941
|
timeout: 18e4
|
|
53929
53942
|
});
|
|
53930
|
-
if (result.status === 0 &&
|
|
53943
|
+
if (result.status === 0 && fs45.existsSync(localOtelHookBin(hooksHome))) {
|
|
53931
53944
|
return { ok: true, detail: described };
|
|
53932
53945
|
}
|
|
53933
53946
|
return {
|
|
@@ -53945,7 +53958,7 @@ function uninstallLegacyPythonHooks(hooksHome) {
|
|
|
53945
53958
|
for (const [cmd, args] of attempts) {
|
|
53946
53959
|
if (!commandExists3(cmd)) continue;
|
|
53947
53960
|
try {
|
|
53948
|
-
(0,
|
|
53961
|
+
(0, import_child_process13.spawnSync)(cmd, args, { encoding: "utf8", timeout: 6e4 });
|
|
53949
53962
|
} catch {
|
|
53950
53963
|
}
|
|
53951
53964
|
}
|
|
@@ -53953,14 +53966,14 @@ function uninstallLegacyPythonHooks(hooksHome) {
|
|
|
53953
53966
|
}
|
|
53954
53967
|
function removeLegacyPythonArtifacts(hooksHome) {
|
|
53955
53968
|
const legacyPaths = [
|
|
53956
|
-
|
|
53957
|
-
|
|
53958
|
-
|
|
53969
|
+
path51.join(hooksHome, ".venv"),
|
|
53970
|
+
path51.join(hooksHome, "otel_config.yaml"),
|
|
53971
|
+
path51.join(hooksHome, "venv")
|
|
53959
53972
|
];
|
|
53960
53973
|
for (const target of legacyPaths) {
|
|
53961
53974
|
try {
|
|
53962
|
-
if (
|
|
53963
|
-
|
|
53975
|
+
if (fs45.existsSync(target)) {
|
|
53976
|
+
fs45.rmSync(target, { recursive: true, force: true });
|
|
53964
53977
|
}
|
|
53965
53978
|
} catch {
|
|
53966
53979
|
}
|
|
@@ -53977,7 +53990,7 @@ function normalizeLegacyProviderFlagsInCommand(command2) {
|
|
|
53977
53990
|
}
|
|
53978
53991
|
function runSetupProvider(providerId, otelHookCommand, wrapperPath) {
|
|
53979
53992
|
const hookCommand = `${wrapperPath} --provider ${providerId}`;
|
|
53980
|
-
const result = (0,
|
|
53993
|
+
const result = (0, import_child_process13.spawnSync)(
|
|
53981
53994
|
otelHookCommand,
|
|
53982
53995
|
[
|
|
53983
53996
|
"setup",
|
|
@@ -54001,10 +54014,10 @@ function runSetupProvider(providerId, otelHookCommand, wrapperPath) {
|
|
|
54001
54014
|
};
|
|
54002
54015
|
}
|
|
54003
54016
|
function rewriteHookCommandsToWrapper(filePath, wrapperPath) {
|
|
54004
|
-
if (!
|
|
54017
|
+
if (!fs45.existsSync(filePath)) return false;
|
|
54005
54018
|
let raw;
|
|
54006
54019
|
try {
|
|
54007
|
-
raw =
|
|
54020
|
+
raw = fs45.readFileSync(filePath, "utf8");
|
|
54008
54021
|
} catch {
|
|
54009
54022
|
return false;
|
|
54010
54023
|
}
|
|
@@ -54051,15 +54064,15 @@ function rewriteHookCommandsToWrapper(filePath, wrapperPath) {
|
|
|
54051
54064
|
return changed;
|
|
54052
54065
|
};
|
|
54053
54066
|
if (!walk(parsed)) return false;
|
|
54054
|
-
|
|
54067
|
+
fs45.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
|
|
54055
54068
|
`);
|
|
54056
54069
|
return true;
|
|
54057
54070
|
}
|
|
54058
54071
|
function pruneLegacyCursorHookEvents(filePath, wrapperPath) {
|
|
54059
|
-
if (!
|
|
54072
|
+
if (!fs45.existsSync(filePath)) return false;
|
|
54060
54073
|
let raw;
|
|
54061
54074
|
try {
|
|
54062
|
-
raw =
|
|
54075
|
+
raw = fs45.readFileSync(filePath, "utf8");
|
|
54063
54076
|
} catch {
|
|
54064
54077
|
return false;
|
|
54065
54078
|
}
|
|
@@ -54094,21 +54107,21 @@ function pruneLegacyCursorHookEvents(filePath, wrapperPath) {
|
|
|
54094
54107
|
}
|
|
54095
54108
|
}
|
|
54096
54109
|
if (!changed) return false;
|
|
54097
|
-
|
|
54110
|
+
fs45.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
|
|
54098
54111
|
`);
|
|
54099
54112
|
return true;
|
|
54100
54113
|
}
|
|
54101
54114
|
function rewriteKnownHookRegistrations(wrapperPath) {
|
|
54102
|
-
const home =
|
|
54115
|
+
const home = os17.homedir();
|
|
54103
54116
|
const candidates = [
|
|
54104
|
-
|
|
54105
|
-
|
|
54106
|
-
|
|
54117
|
+
path51.join(home, ".cursor", "hooks.json"),
|
|
54118
|
+
path51.join(home, ".claude", "settings.json"),
|
|
54119
|
+
path51.join(home, ".codex", "hooks.json")
|
|
54107
54120
|
];
|
|
54108
54121
|
for (const filePath of candidates) {
|
|
54109
54122
|
try {
|
|
54110
54123
|
rewriteHookCommandsToWrapper(filePath, wrapperPath);
|
|
54111
|
-
if (filePath.endsWith(`${
|
|
54124
|
+
if (filePath.endsWith(`${path51.sep}.cursor${path51.sep}hooks.json`)) {
|
|
54112
54125
|
pruneLegacyCursorHookEvents(filePath, wrapperPath);
|
|
54113
54126
|
}
|
|
54114
54127
|
} catch {
|
|
@@ -54124,7 +54137,7 @@ function ensureOtelHooks(options) {
|
|
|
54124
54137
|
const hooksHome = getOtelHooksHome();
|
|
54125
54138
|
const errors = [];
|
|
54126
54139
|
const providersSetup = [];
|
|
54127
|
-
|
|
54140
|
+
fs45.mkdirSync(hooksHome, { recursive: true });
|
|
54128
54141
|
let otelHookCommand = resolveOtelHookCommand(hooksHome);
|
|
54129
54142
|
const needsInstall = !otelHookCommand || installedPackageVersion(hooksHome) !== pinnedVersion();
|
|
54130
54143
|
if (needsInstall) {
|
|
@@ -54218,14 +54231,14 @@ function ensureOtelHooks(options) {
|
|
|
54218
54231
|
function disableOtelHooksExport() {
|
|
54219
54232
|
return writeOtelHooksConfig(buildOtelHooksConfig({ enabled: false }));
|
|
54220
54233
|
}
|
|
54221
|
-
var
|
|
54234
|
+
var import_child_process13, fs45, os17, path51, OTEL_HOOKS_PACKAGE, OTEL_HOOKS_PROVIDERS, OTEL_HOOKS_AGENTS, LEGACY_CURSOR_ONLY_HOOK_EVENTS;
|
|
54222
54235
|
var init_otel_hooks = __esm({
|
|
54223
54236
|
"src/core/otel-hooks.ts"() {
|
|
54224
54237
|
"use strict";
|
|
54225
|
-
|
|
54226
|
-
|
|
54227
|
-
|
|
54228
|
-
|
|
54238
|
+
import_child_process13 = require("child_process");
|
|
54239
|
+
fs45 = __toESM(require("fs"));
|
|
54240
|
+
os17 = __toESM(require("os"));
|
|
54241
|
+
path51 = __toESM(require("path"));
|
|
54229
54242
|
init_control_config();
|
|
54230
54243
|
init_telemetry_config();
|
|
54231
54244
|
OTEL_HOOKS_PACKAGE = "@osfactory/otel-hook@0.2.0";
|
|
@@ -57200,7 +57213,7 @@ var require_compile = __commonJS({
|
|
|
57200
57213
|
const schOrFunc = root.refs[ref];
|
|
57201
57214
|
if (schOrFunc)
|
|
57202
57215
|
return schOrFunc;
|
|
57203
|
-
let _sch =
|
|
57216
|
+
let _sch = resolve49.call(this, root, ref);
|
|
57204
57217
|
if (_sch === void 0) {
|
|
57205
57218
|
const schema = (_a2 = root.localRefs) === null || _a2 === void 0 ? void 0 : _a2[ref];
|
|
57206
57219
|
const { schemaId } = this.opts;
|
|
@@ -57227,7 +57240,7 @@ var require_compile = __commonJS({
|
|
|
57227
57240
|
function sameSchemaEnv(s1, s2) {
|
|
57228
57241
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
57229
57242
|
}
|
|
57230
|
-
function
|
|
57243
|
+
function resolve49(root, ref) {
|
|
57231
57244
|
let sch;
|
|
57232
57245
|
while (typeof (sch = this.refs[ref]) == "string")
|
|
57233
57246
|
ref = sch;
|
|
@@ -57445,8 +57458,8 @@ var require_utils = __commonJS({
|
|
|
57445
57458
|
}
|
|
57446
57459
|
return ind;
|
|
57447
57460
|
}
|
|
57448
|
-
function removeDotSegments(
|
|
57449
|
-
let input =
|
|
57461
|
+
function removeDotSegments(path65) {
|
|
57462
|
+
let input = path65;
|
|
57450
57463
|
const output = [];
|
|
57451
57464
|
let nextSlash = -1;
|
|
57452
57465
|
let len = 0;
|
|
@@ -57698,8 +57711,8 @@ var require_schemes = __commonJS({
|
|
|
57698
57711
|
wsComponent.secure = void 0;
|
|
57699
57712
|
}
|
|
57700
57713
|
if (wsComponent.resourceName) {
|
|
57701
|
-
const [
|
|
57702
|
-
wsComponent.path =
|
|
57714
|
+
const [path65, query] = wsComponent.resourceName.split("?");
|
|
57715
|
+
wsComponent.path = path65 && path65 !== "/" ? path65 : void 0;
|
|
57703
57716
|
wsComponent.query = query;
|
|
57704
57717
|
wsComponent.resourceName = void 0;
|
|
57705
57718
|
}
|
|
@@ -57858,7 +57871,7 @@ var require_fast_uri = __commonJS({
|
|
|
57858
57871
|
}
|
|
57859
57872
|
return uri;
|
|
57860
57873
|
}
|
|
57861
|
-
function
|
|
57874
|
+
function resolve49(baseURI, relativeURI, options) {
|
|
57862
57875
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
57863
57876
|
const resolved = resolveComponent(parse4(baseURI, schemelessOptions), parse4(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
57864
57877
|
schemelessOptions.skipEscape = true;
|
|
@@ -58116,7 +58129,7 @@ var require_fast_uri = __commonJS({
|
|
|
58116
58129
|
var fastUri = {
|
|
58117
58130
|
SCHEMES,
|
|
58118
58131
|
normalize: normalize3,
|
|
58119
|
-
resolve:
|
|
58132
|
+
resolve: resolve49,
|
|
58120
58133
|
resolveComponent,
|
|
58121
58134
|
equal,
|
|
58122
58135
|
serialize,
|
|
@@ -61092,12 +61105,12 @@ var require_dist = __commonJS({
|
|
|
61092
61105
|
throw new Error(`Unknown format "${name}"`);
|
|
61093
61106
|
return f;
|
|
61094
61107
|
};
|
|
61095
|
-
function addFormats(ajv, list,
|
|
61108
|
+
function addFormats(ajv, list, fs51, exportName) {
|
|
61096
61109
|
var _a2;
|
|
61097
61110
|
var _b2;
|
|
61098
61111
|
(_a2 = (_b2 = ajv.opts.code).formats) !== null && _a2 !== void 0 ? _a2 : _b2.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
|
|
61099
61112
|
for (const f of list)
|
|
61100
|
-
ajv.addFormat(f,
|
|
61113
|
+
ajv.addFormat(f, fs51[f]);
|
|
61101
61114
|
}
|
|
61102
61115
|
module2.exports = exports2 = formatsPlugin;
|
|
61103
61116
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -62381,11 +62394,11 @@ var parser = new YargsParser({
|
|
|
62381
62394
|
resolve: import_path2.resolve,
|
|
62382
62395
|
// TODO: figure out a way to combine ESM and CJS coverage, such that
|
|
62383
62396
|
// we can exercise all the lines below:
|
|
62384
|
-
require: (
|
|
62397
|
+
require: (path65) => {
|
|
62385
62398
|
if (typeof require !== "undefined") {
|
|
62386
|
-
return require(
|
|
62387
|
-
} else if (
|
|
62388
|
-
return JSON.parse((0, import_fs2.readFileSync)(
|
|
62399
|
+
return require(path65);
|
|
62400
|
+
} else if (path65.match(/\.json$/)) {
|
|
62401
|
+
return JSON.parse((0, import_fs2.readFileSync)(path65, "utf8"));
|
|
62389
62402
|
} else {
|
|
62390
62403
|
throw Error("only .json config files are supported in ESM");
|
|
62391
62404
|
}
|
|
@@ -64911,12 +64924,12 @@ var YargsInstance = class {
|
|
|
64911
64924
|
async getCompletion(args, done) {
|
|
64912
64925
|
argsert("<array> [function]", [args, done], arguments.length);
|
|
64913
64926
|
if (!done) {
|
|
64914
|
-
return new Promise((
|
|
64927
|
+
return new Promise((resolve49, reject) => {
|
|
64915
64928
|
__classPrivateFieldGet(this, _YargsInstance_completion, "f").getCompletion(args, (err, completions) => {
|
|
64916
64929
|
if (err)
|
|
64917
64930
|
reject(err);
|
|
64918
64931
|
else
|
|
64919
|
-
|
|
64932
|
+
resolve49(completions);
|
|
64920
64933
|
});
|
|
64921
64934
|
});
|
|
64922
64935
|
} else {
|
|
@@ -66205,16 +66218,16 @@ async function handleAgentSkills(options) {
|
|
|
66205
66218
|
}
|
|
66206
66219
|
async function askYesNo(question) {
|
|
66207
66220
|
const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
|
|
66208
|
-
return new Promise((
|
|
66221
|
+
return new Promise((resolve49) => {
|
|
66209
66222
|
process.stderr.write(`${question} `);
|
|
66210
66223
|
rl.once("line", (answer) => {
|
|
66211
66224
|
rl.close();
|
|
66212
66225
|
const trimmed = answer.trim();
|
|
66213
66226
|
if (trimmed === "") {
|
|
66214
|
-
|
|
66227
|
+
resolve49(true);
|
|
66215
66228
|
return;
|
|
66216
66229
|
}
|
|
66217
|
-
|
|
66230
|
+
resolve49(/^y(es)?$/i.test(trimmed));
|
|
66218
66231
|
});
|
|
66219
66232
|
});
|
|
66220
66233
|
}
|
|
@@ -66294,7 +66307,7 @@ function handleRemove(argv) {
|
|
|
66294
66307
|
}
|
|
66295
66308
|
|
|
66296
66309
|
// src/cli/commands/env.ts
|
|
66297
|
-
var
|
|
66310
|
+
var path54 = __toESM(require("path"));
|
|
66298
66311
|
|
|
66299
66312
|
// src/cli/finish-command.ts
|
|
66300
66313
|
init_sync_context();
|
|
@@ -66304,12 +66317,12 @@ async function finishCommand(code) {
|
|
|
66304
66317
|
}
|
|
66305
66318
|
|
|
66306
66319
|
// src/core/harness.ts
|
|
66307
|
-
var
|
|
66308
|
-
var
|
|
66320
|
+
var fs41 = __toESM(require("fs"));
|
|
66321
|
+
var path46 = __toESM(require("path"));
|
|
66309
66322
|
|
|
66310
66323
|
// src/harness/generator.ts
|
|
66311
|
-
var
|
|
66312
|
-
var
|
|
66324
|
+
var fs31 = __toESM(require("fs"));
|
|
66325
|
+
var path37 = __toESM(require("path"));
|
|
66313
66326
|
init_file_ops();
|
|
66314
66327
|
init_logging();
|
|
66315
66328
|
|
|
@@ -66363,12 +66376,163 @@ function isExpectedHarnessOnlyFile(harnessFile, templateFiles) {
|
|
|
66363
66376
|
|
|
66364
66377
|
// src/harness/generator.ts
|
|
66365
66378
|
init_manifest();
|
|
66366
|
-
|
|
66379
|
+
|
|
66380
|
+
// src/harness/plugin-ledger.ts
|
|
66381
|
+
var fs29 = __toESM(require("fs"));
|
|
66382
|
+
var path35 = __toESM(require("path"));
|
|
66383
|
+
init_zod();
|
|
66384
|
+
init_file_ops();
|
|
66385
|
+
init_manifest();
|
|
66386
|
+
var PluginLedgerEntrySchema = external_exports.object({
|
|
66387
|
+
id: external_exports.string().min(1),
|
|
66388
|
+
source: external_exports.enum(["bundled", "path", "npm", "git"]),
|
|
66389
|
+
/** Original install spec (id, path, package, or git URL). */
|
|
66390
|
+
spec: external_exports.string().min(1),
|
|
66391
|
+
/** Package/plugin version when known. */
|
|
66392
|
+
version: external_exports.string().optional(),
|
|
66393
|
+
stageIds: external_exports.array(external_exports.string().min(1)).min(1),
|
|
66394
|
+
installedAt: external_exports.string()
|
|
66395
|
+
});
|
|
66396
|
+
var PluginLedgerSchema = external_exports.object({
|
|
66397
|
+
version: external_exports.literal("1"),
|
|
66398
|
+
/** Profile used at init, when known. */
|
|
66399
|
+
profile: external_exports.enum(["default", "cli", "ios"]).optional(),
|
|
66400
|
+
/** Ordered runtime bundles that composed the harness scaffold. */
|
|
66401
|
+
bundles: external_exports.array(external_exports.string().min(1)).optional(),
|
|
66402
|
+
plugins: external_exports.array(PluginLedgerEntrySchema).default([])
|
|
66403
|
+
});
|
|
66404
|
+
function getPluginLedgerPath(repoPath) {
|
|
66405
|
+
return path35.join(path35.resolve(repoPath), DEFAULT_HAR_DIR, "plugins.json");
|
|
66406
|
+
}
|
|
66407
|
+
function readPluginLedger(repoPath) {
|
|
66408
|
+
const ledgerPath = getPluginLedgerPath(repoPath);
|
|
66409
|
+
if (!fs29.existsSync(ledgerPath)) return null;
|
|
66410
|
+
try {
|
|
66411
|
+
const raw = JSON.parse(fs29.readFileSync(ledgerPath, "utf8"));
|
|
66412
|
+
const parsed = PluginLedgerSchema.safeParse(raw);
|
|
66413
|
+
return parsed.success ? parsed.data : null;
|
|
66414
|
+
} catch {
|
|
66415
|
+
return null;
|
|
66416
|
+
}
|
|
66417
|
+
}
|
|
66418
|
+
function writePluginLedger(repoPath, ledger) {
|
|
66419
|
+
const ledgerPath = getPluginLedgerPath(repoPath);
|
|
66420
|
+
const harnessDir = path35.dirname(ledgerPath);
|
|
66421
|
+
if (!fs29.existsSync(harnessDir)) {
|
|
66422
|
+
fs29.mkdirSync(harnessDir, { recursive: true });
|
|
66423
|
+
}
|
|
66424
|
+
writeFileSafe(ledgerPath, `${JSON.stringify(ledger, null, 2)}
|
|
66425
|
+
`);
|
|
66426
|
+
}
|
|
66427
|
+
function upsertPluginLedgerEntry(repoPath, entry, extras) {
|
|
66428
|
+
const existing = readPluginLedger(repoPath) ?? {
|
|
66429
|
+
version: "1",
|
|
66430
|
+
plugins: []
|
|
66431
|
+
};
|
|
66432
|
+
const plugins = existing.plugins.filter((p) => p.id !== entry.id);
|
|
66433
|
+
plugins.push(entry);
|
|
66434
|
+
plugins.sort((a, b2) => a.id.localeCompare(b2.id));
|
|
66435
|
+
const ledger = {
|
|
66436
|
+
version: "1",
|
|
66437
|
+
profile: extras?.profile ?? existing.profile,
|
|
66438
|
+
bundles: extras?.bundles ?? existing.bundles,
|
|
66439
|
+
plugins
|
|
66440
|
+
};
|
|
66441
|
+
writePluginLedger(repoPath, ledger);
|
|
66442
|
+
return ledger;
|
|
66443
|
+
}
|
|
66444
|
+
function ensurePluginLedgerScaffold(repoPath, options) {
|
|
66445
|
+
const existing = readPluginLedger(repoPath);
|
|
66446
|
+
const ledger = {
|
|
66447
|
+
version: "1",
|
|
66448
|
+
profile: options.profile ?? existing?.profile,
|
|
66449
|
+
bundles: options.bundles ?? existing?.bundles,
|
|
66450
|
+
plugins: existing?.plugins ?? []
|
|
66451
|
+
};
|
|
66452
|
+
writePluginLedger(repoPath, ledger);
|
|
66453
|
+
return ledger;
|
|
66454
|
+
}
|
|
66455
|
+
|
|
66456
|
+
// src/harness/profiles.ts
|
|
66457
|
+
var fs30 = __toESM(require("fs"));
|
|
66458
|
+
var path36 = __toESM(require("path"));
|
|
66459
|
+
init_zod();
|
|
66460
|
+
var HARNESS_PROFILES = ["default", "cli", "ios"];
|
|
66461
|
+
var ProfileBundleRefSchema = external_exports.object({
|
|
66462
|
+
/** Stable bundle id recorded in .har/plugins.json */
|
|
66463
|
+
id: external_exports.string().min(1),
|
|
66464
|
+
/**
|
|
66465
|
+
* Directory under src/templates/ (e.g. "runtime-bundles/shared-kernel"
|
|
66466
|
+
* or "har-boilerplate").
|
|
66467
|
+
*/
|
|
66468
|
+
path: external_exports.string().min(1)
|
|
66469
|
+
});
|
|
66470
|
+
var ProfileManifestSchema = external_exports.object({
|
|
66471
|
+
id: external_exports.enum(HARNESS_PROFILES),
|
|
66472
|
+
description: external_exports.string().min(1),
|
|
66473
|
+
/** Ordered runtime bundles — later bundles overwrite earlier files on conflict. */
|
|
66474
|
+
bundles: external_exports.array(ProfileBundleRefSchema).min(1)
|
|
66475
|
+
});
|
|
66476
|
+
var PROFILE_COMPOSITIONS = {
|
|
66477
|
+
default: {
|
|
66478
|
+
id: "default",
|
|
66479
|
+
description: "Web app \u2014 shared kernel + PM2 runtime + Docker infra",
|
|
66480
|
+
bundles: [
|
|
66481
|
+
{ id: "shared-kernel", path: "runtime-bundles/shared-kernel" },
|
|
66482
|
+
{ id: "pm2-runtime", path: "runtime-bundles/pm2-runtime" },
|
|
66483
|
+
{ id: "runtime-default", path: "har-boilerplate" }
|
|
66484
|
+
]
|
|
66485
|
+
},
|
|
66486
|
+
cli: {
|
|
66487
|
+
id: "cli",
|
|
66488
|
+
description: "CLI/library \u2014 shared kernel + CLI overlay (no PM2)",
|
|
66489
|
+
bundles: [
|
|
66490
|
+
{ id: "shared-kernel", path: "runtime-bundles/shared-kernel" },
|
|
66491
|
+
{ id: "runtime-cli", path: "har-boilerplate-cli" }
|
|
66492
|
+
]
|
|
66493
|
+
},
|
|
66494
|
+
ios: {
|
|
66495
|
+
id: "ios",
|
|
66496
|
+
description: "iOS \u2014 shared kernel + Xcode/Simulator overlay",
|
|
66497
|
+
bundles: [
|
|
66498
|
+
{ id: "shared-kernel", path: "runtime-bundles/shared-kernel" },
|
|
66499
|
+
{ id: "xcode-sim", path: "runtime-bundles/xcode-sim" },
|
|
66500
|
+
{ id: "runtime-ios", path: "har-boilerplate-ios" }
|
|
66501
|
+
]
|
|
66502
|
+
}
|
|
66503
|
+
};
|
|
66367
66504
|
var PROFILE_DIRS = {
|
|
66368
66505
|
default: "har-boilerplate",
|
|
66369
66506
|
cli: "har-boilerplate-cli",
|
|
66370
66507
|
ios: "har-boilerplate-ios"
|
|
66371
66508
|
};
|
|
66509
|
+
function readProfileManifest(profile) {
|
|
66510
|
+
const templates = resolveTemplatesDir();
|
|
66511
|
+
const manifestPath = path36.join(templates, "profiles", profile, "profile.manifest.json");
|
|
66512
|
+
if (fs30.existsSync(manifestPath)) {
|
|
66513
|
+
const parsed = ProfileManifestSchema.safeParse(
|
|
66514
|
+
JSON.parse(fs30.readFileSync(manifestPath, "utf8"))
|
|
66515
|
+
);
|
|
66516
|
+
if (!parsed.success) {
|
|
66517
|
+
throw new Error(`Invalid profile manifest for ${profile}: ${parsed.error.message}`);
|
|
66518
|
+
}
|
|
66519
|
+
if (parsed.data.id !== profile) {
|
|
66520
|
+
throw new Error(`Profile manifest id mismatch: expected ${profile}, got ${parsed.data.id}`);
|
|
66521
|
+
}
|
|
66522
|
+
return parsed.data;
|
|
66523
|
+
}
|
|
66524
|
+
return PROFILE_COMPOSITIONS[profile];
|
|
66525
|
+
}
|
|
66526
|
+
function resolveProfileBundleDir(bundle) {
|
|
66527
|
+
const dir = path36.join(resolveTemplatesDir(), bundle.path);
|
|
66528
|
+
if (!fs30.existsSync(dir)) {
|
|
66529
|
+
throw new Error(`Profile bundle not found: ${bundle.id} (${bundle.path}). Run npm run build.`);
|
|
66530
|
+
}
|
|
66531
|
+
return dir;
|
|
66532
|
+
}
|
|
66533
|
+
|
|
66534
|
+
// src/harness/generator.ts
|
|
66535
|
+
init_stages();
|
|
66372
66536
|
var CLI_PRUNE_FILES = [
|
|
66373
66537
|
"ecosystem.agent.template.cjs",
|
|
66374
66538
|
"env.template",
|
|
@@ -66376,39 +66540,46 @@ var CLI_PRUNE_FILES = [
|
|
|
66376
66540
|
];
|
|
66377
66541
|
function pruneCliProfile(harnessDir) {
|
|
66378
66542
|
for (const file of CLI_PRUNE_FILES) {
|
|
66379
|
-
const filePath =
|
|
66380
|
-
if (
|
|
66381
|
-
|
|
66543
|
+
const filePath = path37.join(harnessDir, file);
|
|
66544
|
+
if (fs31.existsSync(filePath)) {
|
|
66545
|
+
fs31.unlinkSync(filePath);
|
|
66382
66546
|
}
|
|
66383
66547
|
}
|
|
66384
66548
|
}
|
|
66385
66549
|
function scaffoldHarnessBoilerplate(repoPath, options = {}) {
|
|
66386
|
-
const harnessDir =
|
|
66387
|
-
const projectName =
|
|
66550
|
+
const harnessDir = path37.join(repoPath, DEFAULT_HAR_DIR);
|
|
66551
|
+
const projectName = path37.basename(repoPath).toLowerCase().replace(/[^a-z0-9]/g, "_");
|
|
66388
66552
|
const profile = options.profile ?? "default";
|
|
66389
|
-
const
|
|
66390
|
-
|
|
66553
|
+
const profileManifest = readProfileManifest(profile);
|
|
66554
|
+
const bundleIds = profileManifest.bundles.map((b2) => b2.id);
|
|
66555
|
+
const primaryOverlay = PROFILE_DIRS[profile];
|
|
66556
|
+
const boilerplateDir = path37.join(resolveTemplatesDir(), primaryOverlay);
|
|
66557
|
+
if (fs31.existsSync(harnessDir) && !options.force) {
|
|
66391
66558
|
throw new Error(
|
|
66392
66559
|
'.har/ already exists. Use --force to overwrite or run "har env maintain" to update in place.'
|
|
66393
66560
|
);
|
|
66394
66561
|
}
|
|
66395
|
-
if (!
|
|
66562
|
+
if (!fs31.existsSync(boilerplateDir)) {
|
|
66396
66563
|
throw new Error(`Boilerplate template not found at ${boilerplateDir}`);
|
|
66397
66564
|
}
|
|
66398
|
-
if (options.force &&
|
|
66399
|
-
|
|
66565
|
+
if (options.force && fs31.existsSync(harnessDir)) {
|
|
66566
|
+
fs31.rmSync(harnessDir, { recursive: true, force: true });
|
|
66567
|
+
}
|
|
66568
|
+
fs31.mkdirSync(harnessDir, { recursive: true });
|
|
66569
|
+
for (const bundle of profileManifest.bundles) {
|
|
66570
|
+
const bundleDir = resolveProfileBundleDir(bundle);
|
|
66571
|
+
copyDirRecursive(bundleDir, harnessDir);
|
|
66400
66572
|
}
|
|
66401
|
-
copyDirRecursive(boilerplateDir, harnessDir);
|
|
66402
66573
|
writeHarnessGitignore(harnessDir, boilerplateDir);
|
|
66403
66574
|
if (profile === "cli") {
|
|
66404
66575
|
pruneCliProfile(harnessDir);
|
|
66405
66576
|
}
|
|
66406
66577
|
syncAgentSlotsToHarnessEnv(repoPath);
|
|
66407
|
-
const harnessEnvPath =
|
|
66408
|
-
if (
|
|
66409
|
-
let content =
|
|
66578
|
+
const harnessEnvPath = path37.join(harnessDir, "harness.env");
|
|
66579
|
+
if (fs31.existsSync(harnessEnvPath)) {
|
|
66580
|
+
let content = fs31.readFileSync(harnessEnvPath, "utf8");
|
|
66410
66581
|
content = content.replace(/__PROJECT_NAME__/g, projectName).replace(/template___PROJECT_NAME__/g, `template_${projectName}`);
|
|
66411
|
-
|
|
66582
|
+
fs31.writeFileSync(harnessEnvPath, content);
|
|
66412
66583
|
}
|
|
66413
66584
|
const manifest = createManifest(
|
|
66414
66585
|
repoPath,
|
|
@@ -66417,10 +66588,12 @@ function scaffoldHarnessBoilerplate(repoPath, options = {}) {
|
|
|
66417
66588
|
profile
|
|
66418
66589
|
);
|
|
66419
66590
|
writeManifest(repoPath, manifest);
|
|
66591
|
+
ensurePluginLedgerScaffold(repoPath, { profile, bundles: bundleIds });
|
|
66420
66592
|
ensureRootGitignorePatterns(repoPath);
|
|
66421
66593
|
success(`Copied harness boilerplate to .har/ (profile: ${profile})`);
|
|
66422
66594
|
info(`Project name: ${projectName}`);
|
|
66423
|
-
|
|
66595
|
+
info(`Bundles: ${bundleIds.join(" \u2192 ")}`);
|
|
66596
|
+
return { harnessDir, projectName, bundles: bundleIds };
|
|
66424
66597
|
}
|
|
66425
66598
|
function finalizeHarness(repoPath, adaptationSummary, stack) {
|
|
66426
66599
|
const existing = readManifest(repoPath);
|
|
@@ -66430,16 +66603,16 @@ function finalizeHarness(repoPath, adaptationSummary, stack) {
|
|
|
66430
66603
|
}
|
|
66431
66604
|
|
|
66432
66605
|
// src/harness/agent-md.ts
|
|
66433
|
-
var
|
|
66434
|
-
var
|
|
66606
|
+
var fs33 = __toESM(require("fs"));
|
|
66607
|
+
var path39 = __toESM(require("path"));
|
|
66435
66608
|
init_file_ops();
|
|
66436
66609
|
init_logging();
|
|
66437
66610
|
init_manifest();
|
|
66438
66611
|
|
|
66439
66612
|
// src/harness/instruction-files.ts
|
|
66440
|
-
var
|
|
66613
|
+
var fs32 = __toESM(require("fs"));
|
|
66441
66614
|
var os14 = __toESM(require("os"));
|
|
66442
|
-
var
|
|
66615
|
+
var path38 = __toESM(require("path"));
|
|
66443
66616
|
|
|
66444
66617
|
// node_modules/@inquirer/core/dist/esm/lib/key.mjs
|
|
66445
66618
|
var isUpKey = (key) => (
|
|
@@ -67459,13 +67632,13 @@ var PromisePolyfill = class extends Promise {
|
|
|
67459
67632
|
// Available starting from Node 22
|
|
67460
67633
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers
|
|
67461
67634
|
static withResolver() {
|
|
67462
|
-
let
|
|
67635
|
+
let resolve49;
|
|
67463
67636
|
let reject;
|
|
67464
67637
|
const promise = new Promise((res, rej) => {
|
|
67465
|
-
|
|
67638
|
+
resolve49 = res;
|
|
67466
67639
|
reject = rej;
|
|
67467
67640
|
});
|
|
67468
|
-
return { promise, resolve:
|
|
67641
|
+
return { promise, resolve: resolve49, reject };
|
|
67469
67642
|
}
|
|
67470
67643
|
};
|
|
67471
67644
|
|
|
@@ -67482,7 +67655,7 @@ function createPrompt(view) {
|
|
|
67482
67655
|
output
|
|
67483
67656
|
});
|
|
67484
67657
|
const screen = new ScreenManager(rl);
|
|
67485
|
-
const { promise, resolve:
|
|
67658
|
+
const { promise, resolve: resolve49, reject } = PromisePolyfill.withResolver();
|
|
67486
67659
|
const cancel = () => reject(new CancelPromptError());
|
|
67487
67660
|
if (signal) {
|
|
67488
67661
|
const abort = () => reject(new AbortPromptError({ cause: signal.reason }));
|
|
@@ -67506,7 +67679,7 @@ function createPrompt(view) {
|
|
|
67506
67679
|
cycle(() => {
|
|
67507
67680
|
try {
|
|
67508
67681
|
const nextView = view(config2, (value) => {
|
|
67509
|
-
setImmediate(() =>
|
|
67682
|
+
setImmediate(() => resolve49(value));
|
|
67510
67683
|
});
|
|
67511
67684
|
const [content, bottomContent] = typeof nextView === "string" ? [nextView] : nextView;
|
|
67512
67685
|
screen.render(content, bottomContent);
|
|
@@ -68493,9 +68666,9 @@ var import_run_async = __toESM(require_run_async(), 1);
|
|
|
68493
68666
|
var import_mute_stream2 = __toESM(require_lib(), 1);
|
|
68494
68667
|
var import_ansi_escapes5 = __toESM(require_ansi_escapes(), 1);
|
|
68495
68668
|
var _ = {
|
|
68496
|
-
set: (obj,
|
|
68669
|
+
set: (obj, path65 = "", value) => {
|
|
68497
68670
|
let pointer = obj;
|
|
68498
|
-
|
|
68671
|
+
path65.split(".").forEach((key, index, arr) => {
|
|
68499
68672
|
if (key === "__proto__" || key === "constructor")
|
|
68500
68673
|
return;
|
|
68501
68674
|
if (index === arr.length - 1) {
|
|
@@ -68506,8 +68679,8 @@ var _ = {
|
|
|
68506
68679
|
pointer = pointer[key];
|
|
68507
68680
|
});
|
|
68508
68681
|
},
|
|
68509
|
-
get: (obj,
|
|
68510
|
-
const travel = (regexp) => String.prototype.split.call(
|
|
68682
|
+
get: (obj, path65 = "", defaultValue) => {
|
|
68683
|
+
const travel = (regexp) => String.prototype.split.call(path65, regexp).filter(Boolean).reduce(
|
|
68511
68684
|
// @ts-expect-error implicit any on res[key]
|
|
68512
68685
|
(res, key) => res !== null && res !== void 0 ? res[key] : res,
|
|
68513
68686
|
obj
|
|
@@ -68621,7 +68794,7 @@ var PromptsRunner = class {
|
|
|
68621
68794
|
throw new Error(`Prompt for type ${question.type} not found`);
|
|
68622
68795
|
}
|
|
68623
68796
|
let cleanupSignal;
|
|
68624
|
-
const promptFn = isPromptConstructor(prompt2) ? (q, { signal: signal2 } = {}) => new Promise((
|
|
68797
|
+
const promptFn = isPromptConstructor(prompt2) ? (q, { signal: signal2 } = {}) => new Promise((resolve49, reject) => {
|
|
68625
68798
|
const rl = import_node_readline.default.createInterface(setupReadlineOptions(this.opt));
|
|
68626
68799
|
rl.resume();
|
|
68627
68800
|
const onClose = () => {
|
|
@@ -68657,7 +68830,7 @@ var PromptsRunner = class {
|
|
|
68657
68830
|
cleanupSignal = void 0;
|
|
68658
68831
|
};
|
|
68659
68832
|
}
|
|
68660
|
-
activePrompt.run().then(
|
|
68833
|
+
activePrompt.run().then(resolve49, reject).finally(cleanup);
|
|
68661
68834
|
}) : prompt2;
|
|
68662
68835
|
const { signal: moduleSignal } = this.opt;
|
|
68663
68836
|
if (moduleSignal?.aborted) {
|
|
@@ -68833,12 +69006,12 @@ function outsideContentShrinkMessage(beforeLines, afterLines) {
|
|
|
68833
69006
|
}
|
|
68834
69007
|
function detectInstructionFiles(repoPath) {
|
|
68835
69008
|
return {
|
|
68836
|
-
agentsMd:
|
|
68837
|
-
agentMd:
|
|
68838
|
-
claudeMd:
|
|
68839
|
-
cursorDir:
|
|
68840
|
-
claudeDir:
|
|
68841
|
-
codexHome:
|
|
69009
|
+
agentsMd: fs32.existsSync(path38.join(repoPath, AGENTS_MD)),
|
|
69010
|
+
agentMd: fs32.existsSync(path38.join(repoPath, LEGACY_AGENT_MD)),
|
|
69011
|
+
claudeMd: fs32.existsSync(path38.join(repoPath, CLAUDE_MD)),
|
|
69012
|
+
cursorDir: fs32.existsSync(path38.join(repoPath, ".cursor")),
|
|
69013
|
+
claudeDir: fs32.existsSync(path38.join(repoPath, ".claude")),
|
|
69014
|
+
codexHome: fs32.existsSync(path38.join(os14.homedir(), ".codex"))
|
|
68842
69015
|
};
|
|
68843
69016
|
}
|
|
68844
69017
|
function formatDetectionReport(detection) {
|
|
@@ -68893,7 +69066,7 @@ function loadHarAgentsSectionFromTemplate() {
|
|
|
68893
69066
|
if (!templatePath) {
|
|
68894
69067
|
throw new Error("AGENTS.md.template not found. Run npm run build.");
|
|
68895
69068
|
}
|
|
68896
|
-
const content =
|
|
69069
|
+
const content = fs32.readFileSync(templatePath, "utf8");
|
|
68897
69070
|
const start = content.indexOf(HAR_SECTION_START);
|
|
68898
69071
|
const end = content.indexOf(HAR_SECTION_END);
|
|
68899
69072
|
if (start === -1 || end === -1 || end < start) {
|
|
@@ -68906,7 +69079,7 @@ function loadAgentsMdTemplate() {
|
|
|
68906
69079
|
if (!templatePath) {
|
|
68907
69080
|
throw new Error("AGENTS.md.template not found. Run npm run build.");
|
|
68908
69081
|
}
|
|
68909
|
-
return
|
|
69082
|
+
return fs32.readFileSync(templatePath, "utf8");
|
|
68910
69083
|
}
|
|
68911
69084
|
function upsertMarkedBlock2(content, block, startMarker, endMarker) {
|
|
68912
69085
|
const existingBlock = findLastCompleteMarkedBlock(content, startMarker, endMarker);
|
|
@@ -68939,13 +69112,13 @@ function mergeAgentsMdContent(existing, incoming) {
|
|
|
68939
69112
|
return content;
|
|
68940
69113
|
}
|
|
68941
69114
|
function upsertAgentsMdHarSection(repoPath, options = {}) {
|
|
68942
|
-
const dest =
|
|
69115
|
+
const dest = path38.join(repoPath, AGENTS_MD);
|
|
68943
69116
|
const section = loadHarAgentsSectionFromTemplate();
|
|
68944
|
-
if (!
|
|
69117
|
+
if (!fs32.existsSync(dest)) {
|
|
68945
69118
|
writeFileSafe(dest, loadAgentsMdTemplate());
|
|
68946
69119
|
return "created";
|
|
68947
69120
|
}
|
|
68948
|
-
const existing =
|
|
69121
|
+
const existing = fs32.readFileSync(dest, "utf8");
|
|
68949
69122
|
const sanitized = stripClaudePointerFromAgentsMd(existing);
|
|
68950
69123
|
const { content, action } = upsertMarkedBlock2(
|
|
68951
69124
|
sanitized,
|
|
@@ -68970,15 +69143,15 @@ function upsertAgentsMdHarSection(repoPath, options = {}) {
|
|
|
68970
69143
|
return action;
|
|
68971
69144
|
}
|
|
68972
69145
|
function migrateLegacyAgentMd(repoPath) {
|
|
68973
|
-
const legacyPath =
|
|
68974
|
-
const agentsPath =
|
|
68975
|
-
if (!
|
|
68976
|
-
const legacy =
|
|
68977
|
-
if (!
|
|
69146
|
+
const legacyPath = path38.join(repoPath, LEGACY_AGENT_MD);
|
|
69147
|
+
const agentsPath = path38.join(repoPath, AGENTS_MD);
|
|
69148
|
+
if (!fs32.existsSync(legacyPath)) return false;
|
|
69149
|
+
const legacy = fs32.readFileSync(legacyPath, "utf8");
|
|
69150
|
+
if (!fs32.existsSync(agentsPath)) {
|
|
68978
69151
|
writeFileSafe(agentsPath, legacy);
|
|
68979
69152
|
upsertAgentsMdHarSection(repoPath);
|
|
68980
69153
|
} else {
|
|
68981
|
-
const agents =
|
|
69154
|
+
const agents = fs32.readFileSync(agentsPath, "utf8");
|
|
68982
69155
|
const legacyTrimmed = legacy.trim();
|
|
68983
69156
|
if (legacyTrimmed.length > 0 && !agents.includes(legacyTrimmed)) {
|
|
68984
69157
|
const suffix = agents.endsWith("\n") ? "" : "\n";
|
|
@@ -68988,7 +69161,7 @@ ${legacyTrimmed}
|
|
|
68988
69161
|
}
|
|
68989
69162
|
upsertAgentsMdHarSection(repoPath);
|
|
68990
69163
|
}
|
|
68991
|
-
|
|
69164
|
+
fs32.unlinkSync(legacyPath);
|
|
68992
69165
|
info(`Migrated ${LEGACY_AGENT_MD} \u2192 ${AGENTS_MD} (removed legacy file)`);
|
|
68993
69166
|
return true;
|
|
68994
69167
|
}
|
|
@@ -68998,7 +69171,7 @@ function loadClaudeMdTemplate(projectName) {
|
|
|
68998
69171
|
throw new Error("CLAUDE.md.template not found. Run npm run build.");
|
|
68999
69172
|
}
|
|
69000
69173
|
const displayName = projectName.replace(/_/g, " ");
|
|
69001
|
-
return
|
|
69174
|
+
return fs32.readFileSync(templatePath, "utf8").replace(/__PROJECT_DISPLAY_NAME__/g, displayName);
|
|
69002
69175
|
}
|
|
69003
69176
|
function isThinClaudePointer(content) {
|
|
69004
69177
|
const trimmed = content.trim();
|
|
@@ -69012,14 +69185,14 @@ This repository uses a \`.har/\` harness. Read [AGENTS.md](./AGENTS.md) and
|
|
|
69012
69185
|
[\`.har/README.md\`](./.har/README.md) before making changes.
|
|
69013
69186
|
${CLAUDE_HAR_SECTION_END}`;
|
|
69014
69187
|
function ensureClaudeMdPointer(repoPath, options = {}) {
|
|
69015
|
-
const dest =
|
|
69016
|
-
const projectName =
|
|
69188
|
+
const dest = path38.join(repoPath, CLAUDE_MD);
|
|
69189
|
+
const projectName = path38.basename(repoPath).toLowerCase().replace(/[^a-z0-9]/g, "_");
|
|
69017
69190
|
const thin = loadClaudeMdTemplate(projectName);
|
|
69018
|
-
if (!
|
|
69191
|
+
if (!fs32.existsSync(dest)) {
|
|
69019
69192
|
writeFileSafe(dest, thin);
|
|
69020
69193
|
return "created";
|
|
69021
69194
|
}
|
|
69022
|
-
const existing =
|
|
69195
|
+
const existing = fs32.readFileSync(dest, "utf8");
|
|
69023
69196
|
if (isThinClaudePointer(existing) || options.force) {
|
|
69024
69197
|
writeFileSafe(dest, thin);
|
|
69025
69198
|
return "updated";
|
|
@@ -69168,19 +69341,19 @@ var AGENT_MD_PROPOSAL = "AGENT.md.proposed";
|
|
|
69168
69341
|
var AGENT_MD_PROPOSAL_META = "AGENT.md.proposed.meta.json";
|
|
69169
69342
|
function readAgentMdProposal(repoPath) {
|
|
69170
69343
|
const harnessDir = getHarnessDir(repoPath);
|
|
69171
|
-
const proposalPath =
|
|
69172
|
-
const metaPath =
|
|
69173
|
-
const legacyProposalPath =
|
|
69174
|
-
const legacyMetaPath =
|
|
69175
|
-
const resolvedProposal =
|
|
69344
|
+
const proposalPath = path39.join(harnessDir, AGENTS_MD_PROPOSAL);
|
|
69345
|
+
const metaPath = path39.join(harnessDir, AGENTS_MD_PROPOSAL_META);
|
|
69346
|
+
const legacyProposalPath = path39.join(harnessDir, AGENT_MD_PROPOSAL);
|
|
69347
|
+
const legacyMetaPath = path39.join(harnessDir, AGENT_MD_PROPOSAL_META);
|
|
69348
|
+
const resolvedProposal = fs33.existsSync(proposalPath) ? proposalPath : fs33.existsSync(legacyProposalPath) ? legacyProposalPath : null;
|
|
69176
69349
|
if (!resolvedProposal) return null;
|
|
69177
69350
|
const resolvedMeta = resolvedProposal === proposalPath ? metaPath : legacyMetaPath;
|
|
69178
|
-
const content =
|
|
69351
|
+
const content = fs33.readFileSync(resolvedProposal, "utf8");
|
|
69179
69352
|
let rationale = "";
|
|
69180
69353
|
let createdAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
69181
|
-
if (
|
|
69354
|
+
if (fs33.existsSync(resolvedMeta)) {
|
|
69182
69355
|
try {
|
|
69183
|
-
const meta = JSON.parse(
|
|
69356
|
+
const meta = JSON.parse(fs33.readFileSync(resolvedMeta, "utf8"));
|
|
69184
69357
|
rationale = meta.rationale ?? "";
|
|
69185
69358
|
createdAt = meta.createdAt ?? createdAt;
|
|
69186
69359
|
} catch {
|
|
@@ -69197,8 +69370,8 @@ function clearAgentMdProposal(repoPath) {
|
|
|
69197
69370
|
AGENT_MD_PROPOSAL,
|
|
69198
69371
|
AGENT_MD_PROPOSAL_META
|
|
69199
69372
|
]) {
|
|
69200
|
-
const p =
|
|
69201
|
-
if (
|
|
69373
|
+
const p = path39.join(harnessDir, file);
|
|
69374
|
+
if (fs33.existsSync(p)) fs33.unlinkSync(p);
|
|
69202
69375
|
}
|
|
69203
69376
|
}
|
|
69204
69377
|
function wouldProposalShrinkExisting(existing, proposal) {
|
|
@@ -69211,9 +69384,9 @@ function wouldProposalShrinkExisting(existing, proposal) {
|
|
|
69211
69384
|
function applyAgentMdProposalMerge(repoPath, options = {}) {
|
|
69212
69385
|
const proposal = readAgentMdProposal(repoPath);
|
|
69213
69386
|
if (!proposal) return false;
|
|
69214
|
-
const agentsMdPath =
|
|
69215
|
-
if (
|
|
69216
|
-
const existing =
|
|
69387
|
+
const agentsMdPath = path39.join(repoPath, AGENTS_MD);
|
|
69388
|
+
if (fs33.existsSync(agentsMdPath)) {
|
|
69389
|
+
const existing = fs33.readFileSync(agentsMdPath, "utf8");
|
|
69217
69390
|
if (wouldProposalShrinkExisting(existing, proposal.content)) {
|
|
69218
69391
|
const message = `${AGENTS_MD} proposal would drop project-specific content outside har:agent-environment markers \u2014 merge custom sections from .har/${AGENTS_MD_PROPOSAL} manually, then delete the proposal.`;
|
|
69219
69392
|
if (options.rejectSignificantShrink) {
|
|
@@ -69236,8 +69409,8 @@ function finalizeAgentsMdInstructionFiles(repoPath) {
|
|
|
69236
69409
|
}
|
|
69237
69410
|
|
|
69238
69411
|
// src/harness/validator.ts
|
|
69239
|
-
var
|
|
69240
|
-
var
|
|
69412
|
+
var fs34 = __toESM(require("fs"));
|
|
69413
|
+
var path40 = __toESM(require("path"));
|
|
69241
69414
|
init_shell();
|
|
69242
69415
|
init_manifest();
|
|
69243
69416
|
init_stages();
|
|
@@ -69292,22 +69465,22 @@ var SHELL_SCRIPTS = [
|
|
|
69292
69465
|
function validateHarness(repoPath) {
|
|
69293
69466
|
const harnessDir = getHarnessDir(repoPath);
|
|
69294
69467
|
const issues = [];
|
|
69295
|
-
if (!
|
|
69468
|
+
if (!fs34.existsSync(harnessDir)) {
|
|
69296
69469
|
return {
|
|
69297
69470
|
pass: false,
|
|
69298
69471
|
issues: [{ file: ".har", message: "Harness directory not found", severity: "error" }]
|
|
69299
69472
|
};
|
|
69300
69473
|
}
|
|
69301
69474
|
for (const file of getRequiredFiles(repoPath)) {
|
|
69302
|
-
const filePath =
|
|
69303
|
-
if (!
|
|
69475
|
+
const filePath = path40.join(harnessDir, file);
|
|
69476
|
+
if (!fs34.existsSync(filePath)) {
|
|
69304
69477
|
issues.push({ file, message: "Required file missing", severity: "error" });
|
|
69305
69478
|
}
|
|
69306
69479
|
}
|
|
69307
69480
|
for (const script of SHELL_SCRIPTS) {
|
|
69308
|
-
const scriptPath =
|
|
69309
|
-
if (!
|
|
69310
|
-
const stat =
|
|
69481
|
+
const scriptPath = path40.join(harnessDir, script);
|
|
69482
|
+
if (!fs34.existsSync(scriptPath)) continue;
|
|
69483
|
+
const stat = fs34.statSync(scriptPath);
|
|
69311
69484
|
if (!(stat.mode & 73)) {
|
|
69312
69485
|
issues.push({ file: script, message: "Script is not executable", severity: "warning" });
|
|
69313
69486
|
}
|
|
@@ -69322,9 +69495,9 @@ function validateHarness(repoPath) {
|
|
|
69322
69495
|
}
|
|
69323
69496
|
const manifest = readManifest(repoPath);
|
|
69324
69497
|
const profile = manifest?.profile ?? "default";
|
|
69325
|
-
const ecosystemPath =
|
|
69326
|
-
if (profile !== "cli" &&
|
|
69327
|
-
const content =
|
|
69498
|
+
const ecosystemPath = path40.join(harnessDir, "ecosystem.agent.template.cjs");
|
|
69499
|
+
if (profile !== "cli" && fs34.existsSync(ecosystemPath)) {
|
|
69500
|
+
const content = fs34.readFileSync(ecosystemPath, "utf8");
|
|
69328
69501
|
if (!content.includes("module.exports")) {
|
|
69329
69502
|
issues.push({
|
|
69330
69503
|
file: "ecosystem.agent.template.cjs",
|
|
@@ -69333,9 +69506,9 @@ function validateHarness(repoPath) {
|
|
|
69333
69506
|
});
|
|
69334
69507
|
}
|
|
69335
69508
|
}
|
|
69336
|
-
const harnessEnvPath =
|
|
69337
|
-
if (
|
|
69338
|
-
const content =
|
|
69509
|
+
const harnessEnvPath = path40.join(harnessDir, "harness.env");
|
|
69510
|
+
if (fs34.existsSync(harnessEnvPath)) {
|
|
69511
|
+
const content = fs34.readFileSync(harnessEnvPath, "utf8");
|
|
69339
69512
|
if (content.includes("TODO: set migrate command")) {
|
|
69340
69513
|
issues.push({ file: "harness.env", message: "Migrate command still has TODO", severity: "warning" });
|
|
69341
69514
|
}
|
|
@@ -69343,17 +69516,17 @@ function validateHarness(repoPath) {
|
|
|
69343
69516
|
issues.push({ file: "harness.env", message: "Seed command still has TODO", severity: "warning" });
|
|
69344
69517
|
}
|
|
69345
69518
|
}
|
|
69346
|
-
const verifyPath =
|
|
69347
|
-
if (
|
|
69348
|
-
const content =
|
|
69519
|
+
const verifyPath = path40.join(harnessDir, "verify.sh");
|
|
69520
|
+
if (fs34.existsSync(verifyPath)) {
|
|
69521
|
+
const content = fs34.readFileSync(verifyPath, "utf8");
|
|
69349
69522
|
if (content.includes("echo 'TODO:")) {
|
|
69350
69523
|
issues.push({ file: "verify.sh", message: "Verification steps still have TODO placeholders", severity: "warning" });
|
|
69351
69524
|
}
|
|
69352
69525
|
}
|
|
69353
|
-
const stagesPath =
|
|
69354
|
-
if (
|
|
69526
|
+
const stagesPath = path40.join(harnessDir, "stages.json");
|
|
69527
|
+
if (fs34.existsSync(stagesPath)) {
|
|
69355
69528
|
try {
|
|
69356
|
-
JSON.parse(
|
|
69529
|
+
JSON.parse(fs34.readFileSync(stagesPath, "utf8"));
|
|
69357
69530
|
const registry2 = readStageRegistry(repoPath);
|
|
69358
69531
|
if (registry2.stages.length === 0) {
|
|
69359
69532
|
issues.push({ file: "stages.json", message: "No harness stages declared", severity: "warning" });
|
|
@@ -69368,9 +69541,9 @@ function validateHarness(repoPath) {
|
|
|
69368
69541
|
} else {
|
|
69369
69542
|
issues.push({ file: "stages.json", message: "Stage registry missing", severity: "warning" });
|
|
69370
69543
|
}
|
|
69371
|
-
const readmePath =
|
|
69372
|
-
if (
|
|
69373
|
-
const content =
|
|
69544
|
+
const readmePath = path40.join(harnessDir, "README.md");
|
|
69545
|
+
if (fs34.existsSync(readmePath)) {
|
|
69546
|
+
const content = fs34.readFileSync(readmePath, "utf8");
|
|
69374
69547
|
if (!content.includes(".har")) {
|
|
69375
69548
|
issues.push({ file: "README.md", message: "README should document .har/ paths", severity: "warning" });
|
|
69376
69549
|
}
|
|
@@ -69384,8 +69557,8 @@ function validateHarness(repoPath) {
|
|
|
69384
69557
|
async function smokeTestHarness(repoPath) {
|
|
69385
69558
|
const harnessDir = getHarnessDir(repoPath);
|
|
69386
69559
|
const issues = [];
|
|
69387
|
-
const setupScript =
|
|
69388
|
-
if (
|
|
69560
|
+
const setupScript = path40.join(harnessDir, "setup-infra.sh");
|
|
69561
|
+
if (fs34.existsSync(setupScript)) {
|
|
69389
69562
|
const result = run(`bash "${setupScript}"`, { cwd: repoPath });
|
|
69390
69563
|
if (result.code !== 0) {
|
|
69391
69564
|
issues.push({
|
|
@@ -69400,16 +69573,11 @@ async function smokeTestHarness(repoPath) {
|
|
|
69400
69573
|
}
|
|
69401
69574
|
|
|
69402
69575
|
// src/harness/drift.ts
|
|
69403
|
-
var
|
|
69404
|
-
var
|
|
69576
|
+
var fs35 = __toESM(require("fs"));
|
|
69577
|
+
var path41 = __toESM(require("path"));
|
|
69405
69578
|
init_env();
|
|
69406
69579
|
init_manifest();
|
|
69407
69580
|
init_stages();
|
|
69408
|
-
var PROFILE_DIRS2 = {
|
|
69409
|
-
default: "har-boilerplate",
|
|
69410
|
-
cli: "har-boilerplate-cli",
|
|
69411
|
-
ios: "har-boilerplate-ios"
|
|
69412
|
-
};
|
|
69413
69581
|
var CLI_EXPECTED_ABSENT = /* @__PURE__ */ new Set([
|
|
69414
69582
|
"ecosystem.agent.template.cjs",
|
|
69415
69583
|
"env.template",
|
|
@@ -69472,16 +69640,16 @@ function substituteProjectName(content, projectName) {
|
|
|
69472
69640
|
return content.replace(/__PROJECT_NAME__/g, projectName).replace(/template___PROJECT_NAME__/g, `template_${projectName}`);
|
|
69473
69641
|
}
|
|
69474
69642
|
function listBoilerplateFiles(boilerplateDir) {
|
|
69475
|
-
if (!
|
|
69476
|
-
return
|
|
69643
|
+
if (!fs35.existsSync(boilerplateDir)) return [];
|
|
69644
|
+
return fs35.readdirSync(boilerplateDir, { withFileTypes: true }).filter((entry) => entry.isFile()).map((entry) => entry.name).sort();
|
|
69477
69645
|
}
|
|
69478
69646
|
function compareHarnessToTemplate(repoPath) {
|
|
69479
|
-
const resolved =
|
|
69647
|
+
const resolved = path41.resolve(repoPath);
|
|
69480
69648
|
const manifest = readManifest(resolved);
|
|
69481
69649
|
const profile = manifest?.profile ?? "default";
|
|
69482
69650
|
const harnessDir = getHarnessDir(resolved);
|
|
69483
|
-
const projectName =
|
|
69484
|
-
const boilerplateDir =
|
|
69651
|
+
const projectName = path41.basename(resolved).toLowerCase().replace(/[^a-z0-9]/g, "_");
|
|
69652
|
+
const boilerplateDir = path41.join(resolveTemplatesDir(), PROFILE_DIRS[profile]);
|
|
69485
69653
|
const templateFiles = listBoilerplateFiles(boilerplateDir);
|
|
69486
69654
|
const missing = [];
|
|
69487
69655
|
const checksumMismatch = [];
|
|
@@ -69489,17 +69657,17 @@ function compareHarnessToTemplate(repoPath) {
|
|
|
69489
69657
|
const unchanged = [];
|
|
69490
69658
|
for (const file of templateFiles) {
|
|
69491
69659
|
const harnessFile = harnessFileForTemplate(file);
|
|
69492
|
-
const templatePath =
|
|
69493
|
-
const harnessPath =
|
|
69494
|
-
let templateContent =
|
|
69660
|
+
const templatePath = path41.join(boilerplateDir, file);
|
|
69661
|
+
const harnessPath = path41.join(harnessDir, harnessFile);
|
|
69662
|
+
let templateContent = fs35.readFileSync(templatePath, "utf8");
|
|
69495
69663
|
if (file === "harness.env") {
|
|
69496
69664
|
templateContent = substituteProjectName(templateContent, projectName);
|
|
69497
69665
|
}
|
|
69498
|
-
if (!
|
|
69666
|
+
if (!fs35.existsSync(harnessPath)) {
|
|
69499
69667
|
missing.push(harnessFile);
|
|
69500
69668
|
continue;
|
|
69501
69669
|
}
|
|
69502
|
-
const harnessChecksum = computeFileChecksum(
|
|
69670
|
+
const harnessChecksum = computeFileChecksum(fs35.readFileSync(harnessPath, "utf8"));
|
|
69503
69671
|
const templateChecksum = computeFileChecksum(templateContent);
|
|
69504
69672
|
if (harnessChecksum === templateChecksum) {
|
|
69505
69673
|
unchanged.push(harnessFile);
|
|
@@ -69507,11 +69675,13 @@ function compareHarnessToTemplate(repoPath) {
|
|
|
69507
69675
|
checksumMismatch.push(harnessFile);
|
|
69508
69676
|
}
|
|
69509
69677
|
}
|
|
69510
|
-
if (
|
|
69511
|
-
for (const file of
|
|
69512
|
-
const full =
|
|
69513
|
-
if (!
|
|
69514
|
-
if (file === "manifest.json" || file.startsWith("ADAPT-PROMPT"))
|
|
69678
|
+
if (fs35.existsSync(harnessDir)) {
|
|
69679
|
+
for (const file of fs35.readdirSync(harnessDir)) {
|
|
69680
|
+
const full = path41.join(harnessDir, file);
|
|
69681
|
+
if (!fs35.statSync(full).isFile()) continue;
|
|
69682
|
+
if (file === "manifest.json" || file === "plugins.json" || file.startsWith("ADAPT-PROMPT")) {
|
|
69683
|
+
continue;
|
|
69684
|
+
}
|
|
69515
69685
|
if (profile === "cli" && CLI_EXPECTED_ABSENT.has(file)) {
|
|
69516
69686
|
extra.push(file);
|
|
69517
69687
|
} else if (isExpectedHarnessOnlyFile(file, templateFiles)) {
|
|
@@ -69541,107 +69711,356 @@ function compareHarnessToTemplate(repoPath) {
|
|
|
69541
69711
|
}
|
|
69542
69712
|
|
|
69543
69713
|
// src/harness/maintain-bundle.ts
|
|
69544
|
-
var
|
|
69545
|
-
var
|
|
69546
|
-
var
|
|
69714
|
+
var fs40 = __toESM(require("fs"));
|
|
69715
|
+
var os16 = __toESM(require("os"));
|
|
69716
|
+
var path45 = __toESM(require("path"));
|
|
69547
69717
|
init_file_ops();
|
|
69548
69718
|
init_shell();
|
|
69549
69719
|
init_manifest();
|
|
69550
69720
|
|
|
69551
69721
|
// src/harness/plugin-drift.ts
|
|
69552
|
-
var
|
|
69553
|
-
var
|
|
69722
|
+
var fs39 = __toESM(require("fs"));
|
|
69723
|
+
var path44 = __toESM(require("path"));
|
|
69554
69724
|
init_manifest();
|
|
69555
69725
|
|
|
69556
69726
|
// src/harness/plugins.ts
|
|
69557
|
-
var
|
|
69558
|
-
var
|
|
69727
|
+
var fs38 = __toESM(require("fs"));
|
|
69728
|
+
var path43 = __toESM(require("path"));
|
|
69559
69729
|
init_zod();
|
|
69560
69730
|
init_logging();
|
|
69561
69731
|
|
|
69562
69732
|
// src/harness/parser.ts
|
|
69563
|
-
var
|
|
69733
|
+
var fs36 = __toESM(require("fs"));
|
|
69564
69734
|
init_manifest();
|
|
69565
69735
|
function harnessExists(repoPath) {
|
|
69566
|
-
return
|
|
69736
|
+
return fs36.existsSync(`${repoPath}/.har/setup-infra.sh`);
|
|
69737
|
+
}
|
|
69738
|
+
|
|
69739
|
+
// src/harness/plugin-resolve.ts
|
|
69740
|
+
var import_child_process10 = require("child_process");
|
|
69741
|
+
var fs37 = __toESM(require("fs"));
|
|
69742
|
+
var os15 = __toESM(require("os"));
|
|
69743
|
+
var path42 = __toESM(require("path"));
|
|
69744
|
+
function hasManifest(dir) {
|
|
69745
|
+
return fs37.existsSync(path42.join(dir, "template.manifest.json"));
|
|
69746
|
+
}
|
|
69747
|
+
function readPackageVersion(dir) {
|
|
69748
|
+
const pkgPath = path42.join(dir, "package.json");
|
|
69749
|
+
if (!fs37.existsSync(pkgPath)) return void 0;
|
|
69750
|
+
try {
|
|
69751
|
+
const pkg = JSON.parse(fs37.readFileSync(pkgPath, "utf8"));
|
|
69752
|
+
return typeof pkg.version === "string" ? pkg.version : void 0;
|
|
69753
|
+
} catch {
|
|
69754
|
+
return void 0;
|
|
69755
|
+
}
|
|
69756
|
+
}
|
|
69757
|
+
function readManifestId(dir) {
|
|
69758
|
+
const manifestPath = path42.join(dir, "template.manifest.json");
|
|
69759
|
+
if (!fs37.existsSync(manifestPath)) return void 0;
|
|
69760
|
+
try {
|
|
69761
|
+
const raw = JSON.parse(fs37.readFileSync(manifestPath, "utf8"));
|
|
69762
|
+
return typeof raw.id === "string" ? raw.id : void 0;
|
|
69763
|
+
} catch {
|
|
69764
|
+
return void 0;
|
|
69765
|
+
}
|
|
69766
|
+
}
|
|
69767
|
+
function looksLikePath(spec) {
|
|
69768
|
+
return spec.startsWith(".") || spec.startsWith("/") || spec.startsWith("~") || spec.startsWith("file:");
|
|
69769
|
+
}
|
|
69770
|
+
function looksLikeGit(spec) {
|
|
69771
|
+
return spec.startsWith("git+") || spec.startsWith("github:") || spec.startsWith("gitlab:") || spec.startsWith("bitbucket:") || /^https?:\/\/.+\.git$/i.test(spec) || /^git@/.test(spec);
|
|
69772
|
+
}
|
|
69773
|
+
function looksLikeNpm(spec) {
|
|
69774
|
+
if (looksLikePath(spec) || looksLikeGit(spec)) return false;
|
|
69775
|
+
if (spec.includes("/") && !spec.startsWith("@")) return false;
|
|
69776
|
+
return /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*(@.+)?$/i.test(spec);
|
|
69777
|
+
}
|
|
69778
|
+
function resolveBundledDir(pluginId) {
|
|
69779
|
+
const dir = path42.join(resolveTemplatesDir(), "plugins", pluginId);
|
|
69780
|
+
return hasManifest(dir) ? dir : null;
|
|
69781
|
+
}
|
|
69782
|
+
function expandHome(p) {
|
|
69783
|
+
if (p.startsWith("~/")) return path42.join(os15.homedir(), p.slice(2));
|
|
69784
|
+
if (p === "~") return os15.homedir();
|
|
69785
|
+
return p;
|
|
69786
|
+
}
|
|
69787
|
+
function resolvePathSpec(spec) {
|
|
69788
|
+
const raw = spec.startsWith("file:") ? spec.slice("file:".length) : spec;
|
|
69789
|
+
const dir = path42.resolve(expandHome(raw));
|
|
69790
|
+
if (!fs37.existsSync(dir) || !fs37.statSync(dir).isDirectory()) {
|
|
69791
|
+
throw new Error(`Plugin path not found: ${spec}`);
|
|
69792
|
+
}
|
|
69793
|
+
if (!hasManifest(dir)) {
|
|
69794
|
+
throw new Error(`No template.manifest.json in ${dir}`);
|
|
69795
|
+
}
|
|
69796
|
+
const id = readManifestId(dir) ?? path42.basename(dir);
|
|
69797
|
+
return {
|
|
69798
|
+
id,
|
|
69799
|
+
kind: "path",
|
|
69800
|
+
dir,
|
|
69801
|
+
spec,
|
|
69802
|
+
version: readPackageVersion(dir),
|
|
69803
|
+
cleanupDirs: []
|
|
69804
|
+
};
|
|
69805
|
+
}
|
|
69806
|
+
function makeTempDir(prefix) {
|
|
69807
|
+
return fs37.mkdtempSync(path42.join(os15.tmpdir(), prefix));
|
|
69808
|
+
}
|
|
69809
|
+
function resolveNpmSpec(spec) {
|
|
69810
|
+
const tmp = makeTempDir("har-plugin-npm-");
|
|
69811
|
+
const cleanupDirs = [tmp];
|
|
69812
|
+
try {
|
|
69813
|
+
(0, import_child_process10.execFileSync)("npm", ["pack", spec, "--pack-destination", tmp], {
|
|
69814
|
+
encoding: "utf8",
|
|
69815
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
69816
|
+
timeout: 12e4
|
|
69817
|
+
});
|
|
69818
|
+
const tarballs = fs37.readdirSync(tmp).filter((f) => f.endsWith(".tgz"));
|
|
69819
|
+
if (tarballs.length === 0) {
|
|
69820
|
+
throw new Error(`npm pack produced no tarball for ${spec}`);
|
|
69821
|
+
}
|
|
69822
|
+
const extractDir = path42.join(tmp, "extract");
|
|
69823
|
+
fs37.mkdirSync(extractDir);
|
|
69824
|
+
(0, import_child_process10.execFileSync)("tar", ["-xzf", path42.join(tmp, tarballs[0]), "-C", extractDir], {
|
|
69825
|
+
encoding: "utf8",
|
|
69826
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
69827
|
+
});
|
|
69828
|
+
const packageDir = path42.join(extractDir, "package");
|
|
69829
|
+
let dir = packageDir;
|
|
69830
|
+
if (!hasManifest(dir)) {
|
|
69831
|
+
const nested = fs37.readdirSync(extractDir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => path42.join(extractDir, e.name)).find((d) => hasManifest(d));
|
|
69832
|
+
if (!nested) {
|
|
69833
|
+
throw new Error(
|
|
69834
|
+
`npm package ${spec} has no template.manifest.json (not a HAR plugin bundle)`
|
|
69835
|
+
);
|
|
69836
|
+
}
|
|
69837
|
+
dir = nested;
|
|
69838
|
+
}
|
|
69839
|
+
const id = readManifestId(dir) ?? spec.replace(/^@/, "").replace(/[/:].*/g, "");
|
|
69840
|
+
return {
|
|
69841
|
+
id,
|
|
69842
|
+
kind: "npm",
|
|
69843
|
+
dir,
|
|
69844
|
+
spec,
|
|
69845
|
+
version: readPackageVersion(dir),
|
|
69846
|
+
cleanupDirs
|
|
69847
|
+
};
|
|
69848
|
+
} catch (err) {
|
|
69849
|
+
for (const d of cleanupDirs) {
|
|
69850
|
+
fs37.rmSync(d, { recursive: true, force: true });
|
|
69851
|
+
}
|
|
69852
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
69853
|
+
throw new Error(`Failed to install plugin from npm (${spec}): ${message}`);
|
|
69854
|
+
}
|
|
69855
|
+
}
|
|
69856
|
+
function resolveGitSpec(spec) {
|
|
69857
|
+
const tmp = makeTempDir("har-plugin-git-");
|
|
69858
|
+
const cleanupDirs = [tmp];
|
|
69859
|
+
const cloneDir = path42.join(tmp, "repo");
|
|
69860
|
+
try {
|
|
69861
|
+
let url = spec;
|
|
69862
|
+
if (spec.startsWith("github:")) {
|
|
69863
|
+
url = `https://github.com/${spec.slice("github:".length)}.git`;
|
|
69864
|
+
} else if (spec.startsWith("gitlab:")) {
|
|
69865
|
+
url = `https://gitlab.com/${spec.slice("gitlab:".length)}.git`;
|
|
69866
|
+
} else if (spec.startsWith("bitbucket:")) {
|
|
69867
|
+
url = `https://bitbucket.org/${spec.slice("bitbucket:".length)}.git`;
|
|
69868
|
+
} else if (spec.startsWith("git+")) {
|
|
69869
|
+
url = spec.slice("git+".length);
|
|
69870
|
+
}
|
|
69871
|
+
(0, import_child_process10.execFileSync)("git", ["clone", "--depth", "1", url, cloneDir], {
|
|
69872
|
+
encoding: "utf8",
|
|
69873
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
69874
|
+
timeout: 18e4
|
|
69875
|
+
});
|
|
69876
|
+
let dir = cloneDir;
|
|
69877
|
+
if (!hasManifest(dir)) {
|
|
69878
|
+
const pluginsRoot = path42.join(cloneDir, "plugins");
|
|
69879
|
+
if (fs37.existsSync(pluginsRoot)) {
|
|
69880
|
+
const child = fs37.readdirSync(pluginsRoot, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => path42.join(pluginsRoot, e.name)).find((d) => hasManifest(d));
|
|
69881
|
+
if (child) dir = child;
|
|
69882
|
+
}
|
|
69883
|
+
}
|
|
69884
|
+
if (!hasManifest(dir)) {
|
|
69885
|
+
throw new Error(`Git repo ${spec} has no template.manifest.json (not a HAR plugin bundle)`);
|
|
69886
|
+
}
|
|
69887
|
+
const id = readManifestId(dir) ?? path42.basename(url.replace(/\.git$/, ""));
|
|
69888
|
+
return {
|
|
69889
|
+
id,
|
|
69890
|
+
kind: "git",
|
|
69891
|
+
dir,
|
|
69892
|
+
spec,
|
|
69893
|
+
version: readPackageVersion(dir),
|
|
69894
|
+
cleanupDirs
|
|
69895
|
+
};
|
|
69896
|
+
} catch (err) {
|
|
69897
|
+
for (const d of cleanupDirs) {
|
|
69898
|
+
fs37.rmSync(d, { recursive: true, force: true });
|
|
69899
|
+
}
|
|
69900
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
69901
|
+
throw new Error(`Failed to install plugin from git (${spec}): ${message}`);
|
|
69902
|
+
}
|
|
69903
|
+
}
|
|
69904
|
+
function resolvePluginSource(spec) {
|
|
69905
|
+
const trimmed = spec.trim();
|
|
69906
|
+
if (!trimmed) {
|
|
69907
|
+
throw new Error("Plugin spec is empty");
|
|
69908
|
+
}
|
|
69909
|
+
if (looksLikePath(trimmed)) {
|
|
69910
|
+
return resolvePathSpec(trimmed);
|
|
69911
|
+
}
|
|
69912
|
+
if (looksLikeGit(trimmed)) {
|
|
69913
|
+
return resolveGitSpec(trimmed);
|
|
69914
|
+
}
|
|
69915
|
+
const bundled = resolveBundledDir(trimmed);
|
|
69916
|
+
if (bundled) {
|
|
69917
|
+
return {
|
|
69918
|
+
id: trimmed,
|
|
69919
|
+
kind: "bundled",
|
|
69920
|
+
dir: bundled,
|
|
69921
|
+
spec: trimmed,
|
|
69922
|
+
version: readPackageVersion(bundled),
|
|
69923
|
+
cleanupDirs: []
|
|
69924
|
+
};
|
|
69925
|
+
}
|
|
69926
|
+
if (looksLikeNpm(trimmed) && (trimmed.includes("@") || trimmed.includes("/"))) {
|
|
69927
|
+
return resolveNpmSpec(trimmed);
|
|
69928
|
+
}
|
|
69929
|
+
if (looksLikeNpm(trimmed)) {
|
|
69930
|
+
try {
|
|
69931
|
+
return resolveNpmSpec(trimmed);
|
|
69932
|
+
} catch (npmErr) {
|
|
69933
|
+
const available2 = listBundledPluginIds();
|
|
69934
|
+
const npmMessage = npmErr instanceof Error ? npmErr.message : String(npmErr);
|
|
69935
|
+
throw new Error(
|
|
69936
|
+
`Unknown plugin: ${trimmed}. Bundled: ${available2.join(", ") || "(none)"}. Or pass a path, npm package, or git URL. (${npmMessage})`
|
|
69937
|
+
);
|
|
69938
|
+
}
|
|
69939
|
+
}
|
|
69940
|
+
const available = listBundledPluginIds();
|
|
69941
|
+
throw new Error(
|
|
69942
|
+
`Unknown plugin: ${trimmed}. Bundled: ${available.join(", ") || "(none)"}. Or pass a path (./plugin), npm package (@org/pkg), or git URL (github:org/repo).`
|
|
69943
|
+
);
|
|
69944
|
+
}
|
|
69945
|
+
function listBundledPluginIds() {
|
|
69946
|
+
const root = path42.join(resolveTemplatesDir(), "plugins");
|
|
69947
|
+
if (!fs37.existsSync(root)) return [];
|
|
69948
|
+
return fs37.readdirSync(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).filter((name) => hasManifest(path42.join(root, name))).sort();
|
|
69949
|
+
}
|
|
69950
|
+
function cleanupResolvedPlugin(source) {
|
|
69951
|
+
for (const dir of source.cleanupDirs) {
|
|
69952
|
+
fs37.rmSync(dir, { recursive: true, force: true });
|
|
69953
|
+
}
|
|
69567
69954
|
}
|
|
69568
69955
|
|
|
69569
69956
|
// src/harness/plugins.ts
|
|
69570
69957
|
init_schema2();
|
|
69571
69958
|
init_stages();
|
|
69572
|
-
var PLUGIN_IDS = ["playwright", "rocketsim", "kerno", "gitleaks", "trivy", "semgrep"];
|
|
69573
69959
|
var PluginManifestFileSchema = external_exports.object({
|
|
69574
69960
|
src: external_exports.string().min(1),
|
|
69575
69961
|
dest: external_exports.string().min(1),
|
|
69576
69962
|
executable: external_exports.boolean().optional(),
|
|
69577
69963
|
skipFlag: external_exports.string().optional()
|
|
69578
69964
|
});
|
|
69965
|
+
var PluginIdSchema = external_exports.string().min(1).regex(/^[a-z0-9][a-z0-9._-]*$/i, "Plugin id must be a slug (letters, digits, ._-)");
|
|
69579
69966
|
var PluginManifestSchema = external_exports.object({
|
|
69580
|
-
id:
|
|
69581
|
-
|
|
69967
|
+
id: PluginIdSchema,
|
|
69968
|
+
/** @deprecated Prefer `stages` — primary stage id for single-stage plugins. */
|
|
69969
|
+
stageId: external_exports.string().min(1).optional(),
|
|
69582
69970
|
verificationStages: external_exports.array(external_exports.string().min(1)).min(1),
|
|
69583
|
-
stage
|
|
69971
|
+
/** @deprecated Prefer `stages` — single stage object. */
|
|
69972
|
+
stage: external_exports.record(external_exports.unknown()).optional(),
|
|
69973
|
+
/** One or more stages registered by this plugin. */
|
|
69974
|
+
stages: external_exports.array(external_exports.record(external_exports.unknown())).optional(),
|
|
69584
69975
|
files: external_exports.array(PluginManifestFileSchema).min(1),
|
|
69585
69976
|
optionalFiles: external_exports.array(PluginManifestFileSchema).optional(),
|
|
69586
69977
|
merge: external_exports.record(external_exports.string()).optional(),
|
|
69587
69978
|
nextSteps: external_exports.array(external_exports.string().min(1)).min(1),
|
|
69588
69979
|
docsPath: external_exports.string().min(1)
|
|
69980
|
+
}).superRefine((data, ctx) => {
|
|
69981
|
+
const hasStages = Array.isArray(data.stages) && data.stages.length > 0;
|
|
69982
|
+
const hasLegacy = data.stage !== void 0 && data.stageId !== void 0;
|
|
69983
|
+
if (!hasStages && !hasLegacy) {
|
|
69984
|
+
ctx.addIssue({
|
|
69985
|
+
code: external_exports.ZodIssueCode.custom,
|
|
69986
|
+
message: "Plugin manifest requires `stages` (preferred) or legacy `stage` + `stageId`"
|
|
69987
|
+
});
|
|
69988
|
+
}
|
|
69589
69989
|
});
|
|
69590
|
-
function
|
|
69591
|
-
|
|
69592
|
-
|
|
69990
|
+
function normalizePluginStages(manifest) {
|
|
69991
|
+
if (manifest.stages && manifest.stages.length > 0) {
|
|
69992
|
+
return manifest.stages.map((s) => HarnessStageSchema.parse(s));
|
|
69993
|
+
}
|
|
69994
|
+
if (manifest.stage) {
|
|
69995
|
+
return [HarnessStageSchema.parse(manifest.stage)];
|
|
69996
|
+
}
|
|
69997
|
+
throw new Error(`Plugin ${manifest.id} has no stages`);
|
|
69998
|
+
}
|
|
69999
|
+
function primaryStageId(manifest) {
|
|
70000
|
+
const stages = normalizePluginStages(manifest);
|
|
70001
|
+
return manifest.stageId ?? stages[0].id;
|
|
70002
|
+
}
|
|
70003
|
+
function resolveBundledPluginDir(pluginId) {
|
|
70004
|
+
const dir = path43.join(resolveTemplatesDir(), "plugins", pluginId);
|
|
70005
|
+
if (!fs38.existsSync(dir)) {
|
|
69593
70006
|
throw new Error(`Plugin not found: ${pluginId}. Run npm run build.`);
|
|
69594
70007
|
}
|
|
69595
70008
|
return dir;
|
|
69596
70009
|
}
|
|
69597
|
-
function
|
|
69598
|
-
const manifestPath =
|
|
70010
|
+
function readPluginManifestFromDir(pluginDir, expectedId) {
|
|
70011
|
+
const manifestPath = path43.join(pluginDir, "template.manifest.json");
|
|
70012
|
+
if (!fs38.existsSync(manifestPath)) {
|
|
70013
|
+
throw new Error(`No template.manifest.json in ${pluginDir}`);
|
|
70014
|
+
}
|
|
69599
70015
|
const parsed = PluginManifestSchema.safeParse(
|
|
69600
|
-
JSON.parse(
|
|
70016
|
+
JSON.parse(fs38.readFileSync(manifestPath, "utf8"))
|
|
69601
70017
|
);
|
|
69602
70018
|
if (!parsed.success) {
|
|
69603
|
-
throw new Error(`Invalid plugin manifest
|
|
70019
|
+
throw new Error(`Invalid plugin manifest: ${parsed.error.message}`);
|
|
69604
70020
|
}
|
|
69605
|
-
if (parsed.data.id !==
|
|
69606
|
-
throw new Error(`Plugin manifest id mismatch: expected ${
|
|
70021
|
+
if (expectedId && parsed.data.id !== expectedId) {
|
|
70022
|
+
throw new Error(`Plugin manifest id mismatch: expected ${expectedId}, got ${parsed.data.id}`);
|
|
69607
70023
|
}
|
|
69608
70024
|
return parsed.data;
|
|
69609
70025
|
}
|
|
70026
|
+
function readPluginManifest(pluginId) {
|
|
70027
|
+
return readPluginManifestFromDir(resolveBundledPluginDir(pluginId), pluginId);
|
|
70028
|
+
}
|
|
69610
70029
|
function ensureParentDir(filePath) {
|
|
69611
|
-
const parent =
|
|
69612
|
-
if (!
|
|
69613
|
-
|
|
70030
|
+
const parent = path43.dirname(filePath);
|
|
70031
|
+
if (!fs38.existsSync(parent)) {
|
|
70032
|
+
fs38.mkdirSync(parent, { recursive: true });
|
|
69614
70033
|
}
|
|
69615
70034
|
}
|
|
69616
70035
|
function copyPluginFile(pluginDir, file, repoPath, force) {
|
|
69617
|
-
const srcPath =
|
|
69618
|
-
const destPath =
|
|
69619
|
-
if (!
|
|
70036
|
+
const srcPath = path43.join(pluginDir, file.src);
|
|
70037
|
+
const destPath = path43.join(repoPath, file.dest);
|
|
70038
|
+
if (!fs38.existsSync(srcPath)) {
|
|
69620
70039
|
throw new Error(`Plugin file missing: ${file.src}`);
|
|
69621
70040
|
}
|
|
69622
|
-
if (
|
|
70041
|
+
if (fs38.existsSync(destPath) && !force) {
|
|
69623
70042
|
throw new Error(
|
|
69624
70043
|
`File already exists: ${file.dest}. Use --force to overwrite or remove it first.`
|
|
69625
70044
|
);
|
|
69626
70045
|
}
|
|
69627
70046
|
ensureParentDir(destPath);
|
|
69628
|
-
|
|
70047
|
+
fs38.copyFileSync(srcPath, destPath);
|
|
69629
70048
|
if (file.executable) {
|
|
69630
|
-
|
|
70049
|
+
fs38.chmodSync(destPath, 493);
|
|
69631
70050
|
}
|
|
69632
70051
|
return { written: true, path: file.dest };
|
|
69633
70052
|
}
|
|
69634
70053
|
function mergePackageJson(repoPath, pluginDir, fragmentRelPath, warnings) {
|
|
69635
|
-
const packagePath =
|
|
69636
|
-
if (!
|
|
70054
|
+
const packagePath = path43.join(repoPath, "package.json");
|
|
70055
|
+
if (!fs38.existsSync(packagePath)) {
|
|
69637
70056
|
throw new Error("No package.json in repo root. Add one before applying this plugin.");
|
|
69638
70057
|
}
|
|
69639
|
-
const fragmentPath =
|
|
69640
|
-
if (!
|
|
70058
|
+
const fragmentPath = path43.join(pluginDir, fragmentRelPath);
|
|
70059
|
+
if (!fs38.existsSync(fragmentPath)) {
|
|
69641
70060
|
throw new Error(`Package fragment missing: ${fragmentRelPath}`);
|
|
69642
70061
|
}
|
|
69643
|
-
const pkg = JSON.parse(
|
|
69644
|
-
const fragment = JSON.parse(
|
|
70062
|
+
const pkg = JSON.parse(fs38.readFileSync(packagePath, "utf8"));
|
|
70063
|
+
const fragment = JSON.parse(fs38.readFileSync(fragmentPath, "utf8"));
|
|
69645
70064
|
for (const section of ["scripts", "devDependencies"]) {
|
|
69646
70065
|
const existing = pkg[section] ?? {};
|
|
69647
70066
|
const incoming = fragment[section] ?? {};
|
|
@@ -69654,35 +70073,37 @@ function mergePackageJson(repoPath, pluginDir, fragmentRelPath, warnings) {
|
|
|
69654
70073
|
}
|
|
69655
70074
|
pkg[section] = existing;
|
|
69656
70075
|
}
|
|
69657
|
-
|
|
70076
|
+
fs38.writeFileSync(packagePath, JSON.stringify(pkg, null, 2) + "\n");
|
|
69658
70077
|
}
|
|
69659
|
-
function patchStageRegistry(repoPath,
|
|
70078
|
+
function patchStageRegistry(repoPath, stages, verificationStageIds, force) {
|
|
69660
70079
|
const registry2 = readStageRegistry(repoPath);
|
|
69661
|
-
|
|
69662
|
-
const
|
|
69663
|
-
|
|
69664
|
-
|
|
69665
|
-
|
|
69666
|
-
|
|
70080
|
+
let nextStages = [...registry2.stages];
|
|
70081
|
+
for (const stage of stages) {
|
|
70082
|
+
const existing = nextStages.find((s) => s.id === stage.id);
|
|
70083
|
+
if (existing && !force) {
|
|
70084
|
+
throw new Error(
|
|
70085
|
+
`Stage "${stage.id}" already registered in .har/stages.json. Use --force to replace.`
|
|
70086
|
+
);
|
|
70087
|
+
}
|
|
70088
|
+
nextStages = existing ? nextStages.map((s) => s.id === stage.id ? stage : s) : [...nextStages, stage];
|
|
69667
70089
|
}
|
|
69668
|
-
const stages = existing ? registry2.stages.map((s) => s.id === stage.id ? stage : s) : [...registry2.stages, stage];
|
|
69669
70090
|
const verificationStages = [...registry2.verificationStages ?? []];
|
|
69670
|
-
for (const id of
|
|
70091
|
+
for (const id of verificationStageIds) {
|
|
69671
70092
|
if (!verificationStages.includes(id)) {
|
|
69672
70093
|
verificationStages.push(id);
|
|
69673
70094
|
}
|
|
69674
70095
|
}
|
|
69675
|
-
const verifyIdx =
|
|
70096
|
+
const verifyIdx = nextStages.findIndex((s) => s.id === "verify");
|
|
69676
70097
|
if (verifyIdx >= 0) {
|
|
69677
|
-
|
|
69678
|
-
...
|
|
70098
|
+
nextStages[verifyIdx] = {
|
|
70099
|
+
...nextStages[verifyIdx],
|
|
69679
70100
|
description: `Verification pipeline (quick smoke by default; --full runs the registry's verificationStages: ${verificationStages.join(", ")})`,
|
|
69680
70101
|
acceptsArgs: ["--full"]
|
|
69681
70102
|
};
|
|
69682
70103
|
}
|
|
69683
70104
|
const updated = {
|
|
69684
70105
|
...registry2,
|
|
69685
|
-
stages,
|
|
70106
|
+
stages: nextStages,
|
|
69686
70107
|
verificationStages
|
|
69687
70108
|
};
|
|
69688
70109
|
writeStageRegistry(repoPath, updated);
|
|
@@ -69692,30 +70113,33 @@ function assertHarnessPresent(repoPath) {
|
|
|
69692
70113
|
throw new Error('No .har/ harness found. Run "har env init" first.');
|
|
69693
70114
|
}
|
|
69694
70115
|
}
|
|
69695
|
-
function
|
|
70116
|
+
function assertStagesNotPresent(repoPath, stageIds, force) {
|
|
69696
70117
|
if (force) return;
|
|
69697
|
-
const scriptPath = path40.join(repoPath, ".har", "stages", `${stageId}.sh`);
|
|
69698
|
-
if (fs35.existsSync(scriptPath)) {
|
|
69699
|
-
throw new Error(
|
|
69700
|
-
`Stage script already exists: .har/stages/${stageId}.sh. Use --force to overwrite.`
|
|
69701
|
-
);
|
|
69702
|
-
}
|
|
69703
70118
|
const registry2 = readStageRegistry(repoPath);
|
|
69704
|
-
|
|
69705
|
-
|
|
69706
|
-
|
|
69707
|
-
|
|
70119
|
+
for (const stageId of stageIds) {
|
|
70120
|
+
const scriptPath = path43.join(repoPath, ".har", "stages", `${stageId}.sh`);
|
|
70121
|
+
if (fs38.existsSync(scriptPath)) {
|
|
70122
|
+
throw new Error(
|
|
70123
|
+
`Stage script already exists: .har/stages/${stageId}.sh. Use --force to overwrite.`
|
|
70124
|
+
);
|
|
70125
|
+
}
|
|
70126
|
+
if (registry2.stages.some((s) => s.id === stageId)) {
|
|
70127
|
+
throw new Error(
|
|
70128
|
+
`Stage "${stageId}" already registered in .har/stages.json. Use --force to replace.`
|
|
70129
|
+
);
|
|
70130
|
+
}
|
|
69708
70131
|
}
|
|
69709
70132
|
}
|
|
69710
|
-
function
|
|
69711
|
-
const resolved =
|
|
70133
|
+
function applyPluginFromDir(repoPath, pluginDir, options, meta) {
|
|
70134
|
+
const resolved = path43.resolve(repoPath);
|
|
69712
70135
|
const force = options.force ?? false;
|
|
69713
70136
|
const warnings = [];
|
|
69714
70137
|
const filesWritten = [];
|
|
69715
70138
|
assertHarnessPresent(resolved);
|
|
69716
|
-
const manifest =
|
|
69717
|
-
|
|
69718
|
-
const
|
|
70139
|
+
const manifest = readPluginManifestFromDir(pluginDir);
|
|
70140
|
+
const stages = normalizePluginStages(manifest);
|
|
70141
|
+
const stageIds = stages.map((s) => s.id);
|
|
70142
|
+
assertStagesNotPresent(resolved, stageIds, force);
|
|
69719
70143
|
for (const file of manifest.files) {
|
|
69720
70144
|
const result = copyPluginFile(pluginDir, file, resolved, force);
|
|
69721
70145
|
if (result.written) {
|
|
@@ -69727,7 +70151,7 @@ function applyPlugin(repoPath, pluginId, options = {}) {
|
|
|
69727
70151
|
if (file.skipFlag === "skipCi" && options.skipCi) {
|
|
69728
70152
|
continue;
|
|
69729
70153
|
}
|
|
69730
|
-
if (
|
|
70154
|
+
if (fs38.existsSync(path43.join(resolved, file.dest)) && !force) {
|
|
69731
70155
|
warnings.push(`Skipped optional file (exists): ${file.dest}`);
|
|
69732
70156
|
continue;
|
|
69733
70157
|
}
|
|
@@ -69743,9 +70167,18 @@ function applyPlugin(repoPath, pluginId, options = {}) {
|
|
|
69743
70167
|
filesWritten.push("package.json");
|
|
69744
70168
|
}
|
|
69745
70169
|
}
|
|
69746
|
-
patchStageRegistry(resolved, manifest, force);
|
|
69747
|
-
|
|
69748
|
-
|
|
70170
|
+
patchStageRegistry(resolved, stages, manifest.verificationStages, force);
|
|
70171
|
+
upsertPluginLedgerEntry(resolved, {
|
|
70172
|
+
id: manifest.id,
|
|
70173
|
+
source: meta.source,
|
|
70174
|
+
spec: meta.spec,
|
|
70175
|
+
version: meta.version,
|
|
70176
|
+
stageIds,
|
|
70177
|
+
installedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
70178
|
+
});
|
|
70179
|
+
const primary = primaryStageId(manifest);
|
|
70180
|
+
success(`Applied plugin: ${manifest.id}`);
|
|
70181
|
+
info(`Registered stage(s): ${stageIds.join(", ")}`);
|
|
69749
70182
|
for (const file of filesWritten) {
|
|
69750
70183
|
info(` + ${file}`);
|
|
69751
70184
|
}
|
|
@@ -69753,50 +70186,88 @@ function applyPlugin(repoPath, pluginId, options = {}) {
|
|
|
69753
70186
|
warn(` \u26A0 ${warning}`);
|
|
69754
70187
|
}
|
|
69755
70188
|
return {
|
|
69756
|
-
pluginId,
|
|
69757
|
-
stageId:
|
|
70189
|
+
pluginId: manifest.id,
|
|
70190
|
+
stageId: primary,
|
|
70191
|
+
stageIds,
|
|
69758
70192
|
filesWritten,
|
|
69759
70193
|
warnings,
|
|
69760
70194
|
nextSteps: manifest.nextSteps,
|
|
69761
|
-
docsPath: manifest.docsPath
|
|
70195
|
+
docsPath: manifest.docsPath,
|
|
70196
|
+
source: meta.source
|
|
69762
70197
|
};
|
|
69763
70198
|
}
|
|
70199
|
+
function applyPlugin(repoPath, pluginSpec, options = {}) {
|
|
70200
|
+
const spec = options.spec ?? pluginSpec;
|
|
70201
|
+
const source = resolvePluginSource(spec);
|
|
70202
|
+
try {
|
|
70203
|
+
return applyPluginFromDir(repoPath, source.dir, options, {
|
|
70204
|
+
source: source.kind,
|
|
70205
|
+
spec: source.spec,
|
|
70206
|
+
version: source.version
|
|
70207
|
+
});
|
|
70208
|
+
} finally {
|
|
70209
|
+
cleanupResolvedPlugin(source);
|
|
70210
|
+
}
|
|
70211
|
+
}
|
|
69764
70212
|
function listPluginIds() {
|
|
69765
|
-
|
|
69766
|
-
if (!fs35.existsSync(root)) return [...PLUGIN_IDS];
|
|
69767
|
-
return fs35.readdirSync(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).filter((name) => PLUGIN_IDS.includes(name));
|
|
70213
|
+
return listBundledPluginIds();
|
|
69768
70214
|
}
|
|
69769
70215
|
|
|
69770
70216
|
// src/harness/plugin-drift.ts
|
|
69771
70217
|
init_stages();
|
|
69772
70218
|
var PACKAGE_SECTIONS = ["scripts", "devDependencies"];
|
|
69773
70219
|
function detectInstalledPlugins(repoPath) {
|
|
69774
|
-
const resolved =
|
|
69775
|
-
const
|
|
69776
|
-
if (
|
|
70220
|
+
const resolved = path44.resolve(repoPath);
|
|
70221
|
+
const ledger = readPluginLedger(resolved);
|
|
70222
|
+
if (ledger && ledger.plugins.length > 0) {
|
|
70223
|
+
return ledger.plugins.map((p) => p.id).sort();
|
|
70224
|
+
}
|
|
70225
|
+
const registryPath = path44.join(resolved, ".har", "stages.json");
|
|
70226
|
+
if (!fs39.existsSync(registryPath)) return [];
|
|
69777
70227
|
const registry2 = readStageRegistry(resolved);
|
|
69778
70228
|
const stageIds = new Set(registry2.stages.map((stage) => stage.id));
|
|
69779
70229
|
const installed = [];
|
|
69780
|
-
for (const pluginId of
|
|
69781
|
-
|
|
69782
|
-
|
|
69783
|
-
|
|
70230
|
+
for (const pluginId of listPluginIds()) {
|
|
70231
|
+
try {
|
|
70232
|
+
const manifest = readPluginManifest(pluginId);
|
|
70233
|
+
const primary = primaryStageId(manifest);
|
|
70234
|
+
if (stageIds.has(primary)) {
|
|
70235
|
+
installed.push(pluginId);
|
|
70236
|
+
}
|
|
70237
|
+
} catch {
|
|
69784
70238
|
}
|
|
69785
70239
|
}
|
|
69786
|
-
return installed;
|
|
70240
|
+
return installed.sort();
|
|
69787
70241
|
}
|
|
69788
70242
|
function pluginTemplatePath(pluginId, srcRel) {
|
|
69789
|
-
return
|
|
70243
|
+
return path44.join(resolveTemplatesDir(), "plugins", pluginId, srcRel);
|
|
70244
|
+
}
|
|
70245
|
+
function resolvePluginTemplateDir(repoPath, pluginId) {
|
|
70246
|
+
const ledger = readPluginLedger(repoPath);
|
|
70247
|
+
const entry = ledger?.plugins.find((p) => p.id === pluginId);
|
|
70248
|
+
if (entry && entry.source !== "bundled") {
|
|
70249
|
+
try {
|
|
70250
|
+
const source = resolvePluginSource(entry.spec);
|
|
70251
|
+
cleanupResolvedPlugin(source);
|
|
70252
|
+
} catch {
|
|
70253
|
+
}
|
|
70254
|
+
}
|
|
70255
|
+
const bundled = path44.join(resolveTemplatesDir(), "plugins", pluginId);
|
|
70256
|
+
if (fs39.existsSync(path44.join(bundled, "template.manifest.json"))) {
|
|
70257
|
+
return bundled;
|
|
70258
|
+
}
|
|
70259
|
+
return null;
|
|
69790
70260
|
}
|
|
69791
70261
|
function readBundledPluginFile(pluginId, srcRel) {
|
|
69792
|
-
return
|
|
70262
|
+
return fs39.readFileSync(pluginTemplatePath(pluginId, srcRel), "utf8");
|
|
69793
70263
|
}
|
|
69794
70264
|
function listPluginDestPaths(pluginId, repoPath) {
|
|
69795
|
-
const
|
|
70265
|
+
const templateDir = resolvePluginTemplateDir(repoPath, pluginId);
|
|
70266
|
+
const manifest = templateDir ? readPluginManifestFromDir(templateDir) : readPluginManifest(pluginId);
|
|
69796
70267
|
const paths = manifest.files.map((file) => file.dest);
|
|
69797
70268
|
if (manifest.optionalFiles) {
|
|
69798
70269
|
for (const file of manifest.optionalFiles) {
|
|
69799
|
-
if (
|
|
70270
|
+
if (fs39.existsSync(path44.join(repoPath, file.dest))) {
|
|
69800
70271
|
paths.push(file.dest);
|
|
69801
70272
|
}
|
|
69802
70273
|
}
|
|
@@ -69855,9 +70326,9 @@ function readTemplatePluginFile(pluginId, dest) {
|
|
|
69855
70326
|
return null;
|
|
69856
70327
|
}
|
|
69857
70328
|
function readInstalledPluginFile(repoPath, pluginId, dest) {
|
|
69858
|
-
const installedPath =
|
|
69859
|
-
if (!
|
|
69860
|
-
const content =
|
|
70329
|
+
const installedPath = path44.join(path44.resolve(repoPath), dest);
|
|
70330
|
+
if (!fs39.existsSync(installedPath)) return null;
|
|
70331
|
+
const content = fs39.readFileSync(installedPath, "utf8");
|
|
69861
70332
|
const manifest = readPluginManifest(pluginId);
|
|
69862
70333
|
const fragmentRel = manifest.merge?.[dest];
|
|
69863
70334
|
if (fragmentRel) {
|
|
@@ -69876,7 +70347,7 @@ function pluginActionHint(pluginId, dest, kind) {
|
|
|
69876
70347
|
}
|
|
69877
70348
|
function comparePluginToTemplate(repoPath, pluginId) {
|
|
69878
70349
|
const manifest = readPluginManifest(pluginId);
|
|
69879
|
-
const resolved =
|
|
70350
|
+
const resolved = path44.resolve(repoPath);
|
|
69880
70351
|
const destPaths = listPluginDestPaths(pluginId, resolved);
|
|
69881
70352
|
const missing = [];
|
|
69882
70353
|
const checksumMismatch = [];
|
|
@@ -69891,8 +70362,8 @@ function comparePluginToTemplate(repoPath, pluginId) {
|
|
|
69891
70362
|
}
|
|
69892
70363
|
if (dest === "package.json") {
|
|
69893
70364
|
const fragmentRel = manifest.merge?.[dest];
|
|
69894
|
-
const installedPath =
|
|
69895
|
-
const installedRaw =
|
|
70365
|
+
const installedPath = path44.join(resolved, dest);
|
|
70366
|
+
const installedRaw = fs39.readFileSync(installedPath, "utf8");
|
|
69896
70367
|
if (fragmentRel && pluginKeysMatch(installedRaw, readBundledPluginFile(pluginId, fragmentRel))) {
|
|
69897
70368
|
unchanged.push(dest);
|
|
69898
70369
|
} else if (computeFileChecksum(installedContent) === computeFileChecksum(templateContent)) {
|
|
@@ -69910,16 +70381,17 @@ function comparePluginToTemplate(repoPath, pluginId) {
|
|
|
69910
70381
|
}
|
|
69911
70382
|
return {
|
|
69912
70383
|
pluginId,
|
|
69913
|
-
stageId: manifest
|
|
70384
|
+
stageId: primaryStageId(manifest),
|
|
69914
70385
|
missing,
|
|
69915
70386
|
checksumMismatch,
|
|
69916
70387
|
unchanged
|
|
69917
70388
|
};
|
|
69918
70389
|
}
|
|
69919
70390
|
function compareInstalledPluginsToTemplate(repoPath) {
|
|
69920
|
-
return detectInstalledPlugins(repoPath).
|
|
69921
|
-
(
|
|
69922
|
-
|
|
70391
|
+
return detectInstalledPlugins(repoPath).filter((pluginId) => {
|
|
70392
|
+
const bundled = path44.join(resolveTemplatesDir(), "plugins", pluginId, "template.manifest.json");
|
|
70393
|
+
return fs39.existsSync(bundled);
|
|
70394
|
+
}).map((pluginId) => comparePluginToTemplate(repoPath, pluginId));
|
|
69923
70395
|
}
|
|
69924
70396
|
function buildPluginDriftActions(repoPath, pluginDrift) {
|
|
69925
70397
|
const actions = [];
|
|
@@ -69952,23 +70424,18 @@ function buildPluginDriftActions(repoPath, pluginDrift) {
|
|
|
69952
70424
|
|
|
69953
70425
|
// src/harness/maintain-bundle.ts
|
|
69954
70426
|
var MAINTAIN_DIR = "maintain";
|
|
69955
|
-
var PROFILE_DIRS3 = {
|
|
69956
|
-
default: "har-boilerplate",
|
|
69957
|
-
cli: "har-boilerplate-cli",
|
|
69958
|
-
ios: "har-boilerplate-ios"
|
|
69959
|
-
};
|
|
69960
70427
|
function substituteProjectName2(content, projectName) {
|
|
69961
70428
|
return content.replace(/__PROJECT_NAME__/g, projectName).replace(/template___PROJECT_NAME__/g, `template_${projectName}`);
|
|
69962
70429
|
}
|
|
69963
70430
|
function projectNameFromRepo(repoPath) {
|
|
69964
|
-
return
|
|
70431
|
+
return path45.basename(repoPath).toLowerCase().replace(/[^a-z0-9]/g, "_");
|
|
69965
70432
|
}
|
|
69966
70433
|
function boilerplateDirForProfile(profile) {
|
|
69967
|
-
return
|
|
70434
|
+
return path45.join(resolveTemplatesDir(), PROFILE_DIRS[profile]);
|
|
69968
70435
|
}
|
|
69969
70436
|
function readBundledTemplateContent(repoPath, profile, file) {
|
|
69970
|
-
const templatePath =
|
|
69971
|
-
let content =
|
|
70437
|
+
const templatePath = path45.join(boilerplateDirForProfile(profile), templateFileForHarness(file));
|
|
70438
|
+
let content = fs40.readFileSync(templatePath, "utf8");
|
|
69972
70439
|
if (file === "harness.env") {
|
|
69973
70440
|
content = substituteProjectName2(content, projectNameFromRepo(repoPath));
|
|
69974
70441
|
}
|
|
@@ -69999,12 +70466,12 @@ function actionHint(file, kind) {
|
|
|
69999
70466
|
return `Read maintain/diffs/${file}.diff and merge into .har/${file}.`;
|
|
70000
70467
|
}
|
|
70001
70468
|
function createUnifiedDiff(installedContent, templateContent, installedLabel, templateLabel) {
|
|
70002
|
-
const tmpDir =
|
|
70469
|
+
const tmpDir = fs40.mkdtempSync(path45.join(os16.tmpdir(), "har-maintain-diff-"));
|
|
70003
70470
|
try {
|
|
70004
|
-
const installedPath =
|
|
70005
|
-
const templatePath =
|
|
70006
|
-
|
|
70007
|
-
|
|
70471
|
+
const installedPath = path45.join(tmpDir, "installed");
|
|
70472
|
+
const templatePath = path45.join(tmpDir, "template");
|
|
70473
|
+
fs40.writeFileSync(installedPath, installedContent);
|
|
70474
|
+
fs40.writeFileSync(templatePath, templateContent);
|
|
70008
70475
|
const result = run(`diff -u "${installedPath}" "${templatePath}"`);
|
|
70009
70476
|
const body = result.stdout.trim();
|
|
70010
70477
|
if (!body) return "";
|
|
@@ -70013,7 +70480,7 @@ function createUnifiedDiff(installedContent, templateContent, installedLabel, te
|
|
|
70013
70480
|
${body.split("\n").slice(2).join("\n")}
|
|
70014
70481
|
`;
|
|
70015
70482
|
} finally {
|
|
70016
|
-
|
|
70483
|
+
fs40.rmSync(tmpDir, { recursive: true, force: true });
|
|
70017
70484
|
}
|
|
70018
70485
|
}
|
|
70019
70486
|
function buildActions(repoPath, profile, drift) {
|
|
@@ -70028,7 +70495,7 @@ function buildActions(repoPath, profile, drift) {
|
|
|
70028
70495
|
});
|
|
70029
70496
|
}
|
|
70030
70497
|
for (const file of drift.checksumMismatch) {
|
|
70031
|
-
const installedPath =
|
|
70498
|
+
const installedPath = path45.join(harnessDir, file);
|
|
70032
70499
|
const installedRel = `maintain/installed/${file}`;
|
|
70033
70500
|
const templateRel = `maintain/templates/${file}`;
|
|
70034
70501
|
const diffRel = `maintain/diffs/${file}.diff`;
|
|
@@ -70036,7 +70503,7 @@ function buildActions(repoPath, profile, drift) {
|
|
|
70036
70503
|
file,
|
|
70037
70504
|
kind: "drift",
|
|
70038
70505
|
template: templateRel,
|
|
70039
|
-
installed:
|
|
70506
|
+
installed: fs40.existsSync(installedPath) ? installedRel : void 0,
|
|
70040
70507
|
diff: diffRel,
|
|
70041
70508
|
hint: actionHint(file, "drift")
|
|
70042
70509
|
});
|
|
@@ -70188,28 +70655,28 @@ function buildReadme(report) {
|
|
|
70188
70655
|
}
|
|
70189
70656
|
function writeBundleArtifacts(repoPath, profile, drift, report) {
|
|
70190
70657
|
const harnessDir = getHarnessDir(repoPath);
|
|
70191
|
-
const bundleDir =
|
|
70192
|
-
if (
|
|
70193
|
-
|
|
70658
|
+
const bundleDir = path45.join(harnessDir, MAINTAIN_DIR);
|
|
70659
|
+
if (fs40.existsSync(bundleDir)) {
|
|
70660
|
+
fs40.rmSync(bundleDir, { recursive: true, force: true });
|
|
70194
70661
|
}
|
|
70195
70662
|
const dirs = [
|
|
70196
70663
|
bundleDir,
|
|
70197
|
-
|
|
70198
|
-
|
|
70199
|
-
|
|
70200
|
-
|
|
70664
|
+
path45.join(bundleDir, "templates"),
|
|
70665
|
+
path45.join(bundleDir, "installed"),
|
|
70666
|
+
path45.join(bundleDir, "diffs"),
|
|
70667
|
+
path45.join(bundleDir, "stale")
|
|
70201
70668
|
];
|
|
70202
70669
|
for (const dir of dirs) {
|
|
70203
|
-
|
|
70670
|
+
fs40.mkdirSync(dir, { recursive: true });
|
|
70204
70671
|
}
|
|
70205
70672
|
const affectedFiles = [...drift.missing, ...drift.checksumMismatch];
|
|
70206
70673
|
for (const file of affectedFiles) {
|
|
70207
70674
|
const templateContent = readBundledTemplateContent(repoPath, profile, file);
|
|
70208
|
-
writeFileSafe(
|
|
70209
|
-
const harnessPath =
|
|
70210
|
-
if (
|
|
70211
|
-
const installedContent =
|
|
70212
|
-
writeFileSafe(
|
|
70675
|
+
writeFileSafe(path45.join(bundleDir, "templates", file), templateContent);
|
|
70676
|
+
const harnessPath = path45.join(harnessDir, file);
|
|
70677
|
+
if (fs40.existsSync(harnessPath)) {
|
|
70678
|
+
const installedContent = fs40.readFileSync(harnessPath, "utf8");
|
|
70679
|
+
writeFileSafe(path45.join(bundleDir, "installed", file), installedContent);
|
|
70213
70680
|
const diff = createUnifiedDiff(
|
|
70214
70681
|
installedContent,
|
|
70215
70682
|
templateContent,
|
|
@@ -70217,14 +70684,14 @@ function writeBundleArtifacts(repoPath, profile, drift, report) {
|
|
|
70217
70684
|
`templates/${file}`
|
|
70218
70685
|
);
|
|
70219
70686
|
if (diff) {
|
|
70220
|
-
writeFileSafe(
|
|
70687
|
+
writeFileSafe(path45.join(bundleDir, "diffs", `${file}.diff`), diff);
|
|
70221
70688
|
}
|
|
70222
70689
|
}
|
|
70223
70690
|
}
|
|
70224
|
-
writeFileSafe(
|
|
70225
|
-
writeFileSafe(
|
|
70691
|
+
writeFileSafe(path45.join(bundleDir, "README.md"), buildReadme(report));
|
|
70692
|
+
writeFileSafe(path45.join(bundleDir, "drift-report.json"), JSON.stringify(report, null, 2) + "\n");
|
|
70226
70693
|
writeFileSafe(
|
|
70227
|
-
|
|
70694
|
+
path45.join(bundleDir, "validation.json"),
|
|
70228
70695
|
JSON.stringify(report.validation, null, 2) + "\n"
|
|
70229
70696
|
);
|
|
70230
70697
|
if (report.stale.length > 0) {
|
|
@@ -70236,34 +70703,34 @@ function writeBundleArtifacts(repoPath, profile, drift, report) {
|
|
|
70236
70703
|
...report.stale.map((s) => `- **${s.file}** \u2014 ${s.hint}`),
|
|
70237
70704
|
""
|
|
70238
70705
|
];
|
|
70239
|
-
writeFileSafe(
|
|
70706
|
+
writeFileSafe(path45.join(bundleDir, "stale", "MANIFEST.md"), staleLines.join("\n"));
|
|
70240
70707
|
}
|
|
70241
70708
|
return bundleDir;
|
|
70242
70709
|
}
|
|
70243
70710
|
function ensureParentDir2(filePath) {
|
|
70244
|
-
const parent =
|
|
70245
|
-
if (!
|
|
70246
|
-
|
|
70711
|
+
const parent = path45.dirname(filePath);
|
|
70712
|
+
if (!fs40.existsSync(parent)) {
|
|
70713
|
+
fs40.mkdirSync(parent, { recursive: true });
|
|
70247
70714
|
}
|
|
70248
70715
|
}
|
|
70249
70716
|
function writePluginBundleArtifacts(repoPath, bundleDir, report) {
|
|
70250
70717
|
if (report.pluginActions.length === 0) return;
|
|
70251
70718
|
for (const action of report.pluginActions) {
|
|
70252
|
-
const pluginRoot =
|
|
70253
|
-
const templatesDir =
|
|
70254
|
-
const installedDir =
|
|
70255
|
-
const diffsDir =
|
|
70719
|
+
const pluginRoot = path45.join(bundleDir, "plugins", action.pluginId);
|
|
70720
|
+
const templatesDir = path45.join(pluginRoot, "templates");
|
|
70721
|
+
const installedDir = path45.join(pluginRoot, "installed");
|
|
70722
|
+
const diffsDir = path45.join(pluginRoot, "diffs");
|
|
70256
70723
|
for (const dir of [templatesDir, installedDir, diffsDir]) {
|
|
70257
|
-
|
|
70724
|
+
fs40.mkdirSync(dir, { recursive: true });
|
|
70258
70725
|
}
|
|
70259
70726
|
const templateContent = readTemplatePluginFile(action.pluginId, action.file);
|
|
70260
70727
|
if (templateContent === null) continue;
|
|
70261
|
-
const templatePath =
|
|
70728
|
+
const templatePath = path45.join(templatesDir, action.file);
|
|
70262
70729
|
ensureParentDir2(templatePath);
|
|
70263
70730
|
writeFileSafe(templatePath, templateContent);
|
|
70264
70731
|
const installedContent = readInstalledPluginFile(repoPath, action.pluginId, action.file);
|
|
70265
70732
|
if (installedContent !== null) {
|
|
70266
|
-
const installedPath =
|
|
70733
|
+
const installedPath = path45.join(installedDir, action.file);
|
|
70267
70734
|
ensureParentDir2(installedPath);
|
|
70268
70735
|
writeFileSafe(installedPath, installedContent);
|
|
70269
70736
|
const diff = createUnifiedDiff(
|
|
@@ -70273,7 +70740,7 @@ function writePluginBundleArtifacts(repoPath, bundleDir, report) {
|
|
|
70273
70740
|
`templates/${action.file}`
|
|
70274
70741
|
);
|
|
70275
70742
|
if (diff) {
|
|
70276
|
-
const diffPath =
|
|
70743
|
+
const diffPath = path45.join(diffsDir, `${action.file}.diff`);
|
|
70277
70744
|
ensureParentDir2(diffPath);
|
|
70278
70745
|
writeFileSafe(diffPath, diff);
|
|
70279
70746
|
}
|
|
@@ -70309,9 +70776,9 @@ function buildMaintainBundle(repoPath, validation2, drift) {
|
|
|
70309
70776
|
return { bundleDir, report };
|
|
70310
70777
|
}
|
|
70311
70778
|
function removeMaintainBundle(repoPath) {
|
|
70312
|
-
const bundleDir =
|
|
70313
|
-
if (
|
|
70314
|
-
|
|
70779
|
+
const bundleDir = path45.join(getHarnessDir(repoPath), MAINTAIN_DIR);
|
|
70780
|
+
if (fs40.existsSync(bundleDir)) {
|
|
70781
|
+
fs40.rmSync(bundleDir, { recursive: true, force: true });
|
|
70315
70782
|
}
|
|
70316
70783
|
}
|
|
70317
70784
|
function formatMaintainBundlePromptSection(report) {
|
|
@@ -70400,11 +70867,11 @@ init_manifest();
|
|
|
70400
70867
|
init_stages();
|
|
70401
70868
|
function listHarnessScripts(repoPath) {
|
|
70402
70869
|
const harnessDir = getHarnessDir(repoPath);
|
|
70403
|
-
if (!
|
|
70404
|
-
return
|
|
70870
|
+
if (!fs41.existsSync(harnessDir)) return [];
|
|
70871
|
+
return fs41.readdirSync(harnessDir).filter((name) => name.endsWith(".sh")).sort();
|
|
70405
70872
|
}
|
|
70406
70873
|
function describeProject(repoPath) {
|
|
70407
|
-
const resolved =
|
|
70874
|
+
const resolved = path46.resolve(repoPath);
|
|
70408
70875
|
const manifest = readManifest(resolved);
|
|
70409
70876
|
const present = harnessExists(resolved);
|
|
70410
70877
|
return {
|
|
@@ -70424,8 +70891,8 @@ function describeProject(repoPath) {
|
|
|
70424
70891
|
};
|
|
70425
70892
|
}
|
|
70426
70893
|
async function initHarness(options) {
|
|
70427
|
-
const repoPath =
|
|
70428
|
-
if (!
|
|
70894
|
+
const repoPath = path46.resolve(options.repoPath);
|
|
70895
|
+
if (!fs41.existsSync(repoPath)) {
|
|
70429
70896
|
throw new Error(`Path not found: ${repoPath}`);
|
|
70430
70897
|
}
|
|
70431
70898
|
const scaffold = scaffoldHarnessBoilerplate(repoPath, {
|
|
@@ -70445,9 +70912,9 @@ async function initHarness(options) {
|
|
|
70445
70912
|
};
|
|
70446
70913
|
}
|
|
70447
70914
|
async function maintainHarness(options) {
|
|
70448
|
-
const repoPath =
|
|
70915
|
+
const repoPath = path46.resolve(options.repoPath);
|
|
70449
70916
|
const harnessDir = getHarnessDir(repoPath);
|
|
70450
|
-
if (!
|
|
70917
|
+
if (!fs41.existsSync(harnessDir)) {
|
|
70451
70918
|
throw new Error('No .har/ found. Run "har env init" first.');
|
|
70452
70919
|
}
|
|
70453
70920
|
const drift = compareHarnessToTemplate(repoPath);
|
|
@@ -70482,13 +70949,13 @@ function addPlugin(repoPath, pluginId, options = {}) {
|
|
|
70482
70949
|
}
|
|
70483
70950
|
|
|
70484
70951
|
// src/harness/custom-stage.ts
|
|
70485
|
-
var
|
|
70486
|
-
var
|
|
70952
|
+
var fs42 = __toESM(require("fs"));
|
|
70953
|
+
var path47 = __toESM(require("path"));
|
|
70487
70954
|
init_schema2();
|
|
70488
70955
|
init_stages();
|
|
70489
70956
|
var STAGE_ID_PATTERN = /^[a-z0-9][a-z0-9._-]*$/;
|
|
70490
70957
|
function addCustomStage(repoPath, options) {
|
|
70491
|
-
const resolved =
|
|
70958
|
+
const resolved = path47.resolve(repoPath);
|
|
70492
70959
|
if (!harnessExists(resolved)) {
|
|
70493
70960
|
throw new Error('No .har/ harness found. Run "har env init" first.');
|
|
70494
70961
|
}
|
|
@@ -70525,20 +70992,20 @@ function addCustomStage(repoPath, options) {
|
|
|
70525
70992
|
if (options.command) {
|
|
70526
70993
|
stage.command = options.command;
|
|
70527
70994
|
} else {
|
|
70528
|
-
const scriptRel =
|
|
70529
|
-
const scriptAbs =
|
|
70530
|
-
if (
|
|
70995
|
+
const scriptRel = path47.join("stages", `${id}.sh`);
|
|
70996
|
+
const scriptAbs = path47.join(resolved, ".har", scriptRel);
|
|
70997
|
+
if (fs42.existsSync(scriptAbs) && !options.force) {
|
|
70531
70998
|
throw new Error(`Stage script already exists: .har/${scriptRel}. Use --force to overwrite.`);
|
|
70532
70999
|
}
|
|
70533
|
-
const skeletonPath =
|
|
71000
|
+
const skeletonPath = path47.join(
|
|
70534
71001
|
resolveTemplatesDir(),
|
|
70535
71002
|
"plugins",
|
|
70536
71003
|
"custom-stage-skeleton.sh"
|
|
70537
71004
|
);
|
|
70538
|
-
const skeleton =
|
|
70539
|
-
|
|
70540
|
-
|
|
70541
|
-
|
|
71005
|
+
const skeleton = fs42.readFileSync(skeletonPath, "utf8").replace(/__STAGE_ID__/g, id).replace(/__STAGE_KIND__/g, kind).replace(/__STAGE_DESCRIPTION__/g, stage.description);
|
|
71006
|
+
fs42.mkdirSync(path47.dirname(scriptAbs), { recursive: true });
|
|
71007
|
+
fs42.writeFileSync(scriptAbs, skeleton);
|
|
71008
|
+
fs42.chmodSync(scriptAbs, 493);
|
|
70542
71009
|
filesWritten.push(`.har/${scriptRel}`);
|
|
70543
71010
|
stage.script = scriptRel;
|
|
70544
71011
|
stage.artifacts = [
|
|
@@ -70586,18 +71053,18 @@ function addCustomStage(repoPath, options) {
|
|
|
70586
71053
|
}
|
|
70587
71054
|
|
|
70588
71055
|
// src/harness/adaptation-prompt.ts
|
|
70589
|
-
var
|
|
70590
|
-
var
|
|
71056
|
+
var fs43 = __toESM(require("fs"));
|
|
71057
|
+
var path48 = __toESM(require("path"));
|
|
70591
71058
|
var readline5 = __toESM(require("readline"));
|
|
70592
71059
|
|
|
70593
71060
|
// src/utils/clipboard.ts
|
|
70594
|
-
var
|
|
71061
|
+
var import_child_process11 = require("child_process");
|
|
70595
71062
|
function commandExists2(command2) {
|
|
70596
|
-
const probe = process.platform === "win32" ? (0,
|
|
71063
|
+
const probe = process.platform === "win32" ? (0, import_child_process11.spawnSync)("where", [command2], { encoding: "utf8", stdio: ["ignore", "ignore", "ignore"] }) : (0, import_child_process11.spawnSync)("which", [command2], { encoding: "utf8", stdio: ["ignore", "ignore", "ignore"] });
|
|
70597
71064
|
return probe.status === 0;
|
|
70598
71065
|
}
|
|
70599
71066
|
function tryPipeCommand(command2, args, text) {
|
|
70600
|
-
const result = (0,
|
|
71067
|
+
const result = (0, import_child_process11.spawnSync)(command2, args, {
|
|
70601
71068
|
input: text,
|
|
70602
71069
|
encoding: "utf8",
|
|
70603
71070
|
stdio: ["pipe", "ignore", "ignore"]
|
|
@@ -70617,7 +71084,7 @@ function copyViaPlatformTools(text) {
|
|
|
70617
71084
|
}
|
|
70618
71085
|
if (process.platform === "win32") {
|
|
70619
71086
|
if (commandExists2("powershell")) {
|
|
70620
|
-
const result = (0,
|
|
71087
|
+
const result = (0, import_child_process11.spawnSync)(
|
|
70621
71088
|
"powershell",
|
|
70622
71089
|
[
|
|
70623
71090
|
"-NoProfile",
|
|
@@ -70677,7 +71144,7 @@ function loadTemplate(name) {
|
|
|
70677
71144
|
if (!filePath) {
|
|
70678
71145
|
throw new Error(`Adaptation prompt template not found: ${name}. Run npm run build.`);
|
|
70679
71146
|
}
|
|
70680
|
-
return
|
|
71147
|
+
return fs43.readFileSync(filePath, "utf8");
|
|
70681
71148
|
}
|
|
70682
71149
|
function applyProfilePlaceholders(content, profile) {
|
|
70683
71150
|
return content.replace(/\{\{PROFILE\}\}/g, profile).replace(/\{\{PROFILE_HINT\}\}/g, PROFILE_HINTS[profile]);
|
|
@@ -70699,7 +71166,7 @@ function buildMaintainAdaptationPrompt(_repoPath, bundleReport) {
|
|
|
70699
71166
|
}
|
|
70700
71167
|
function writeAdaptationPrompt(repoPath, content) {
|
|
70701
71168
|
const harnessDir = getHarnessDir(repoPath);
|
|
70702
|
-
const filePath =
|
|
71169
|
+
const filePath = path48.join(harnessDir, ADAPTATION_PROMPT_FILE);
|
|
70703
71170
|
writeFileSafe(filePath, content);
|
|
70704
71171
|
return filePath;
|
|
70705
71172
|
}
|
|
@@ -70718,12 +71185,12 @@ function printAdaptationPrompt(content) {
|
|
|
70718
71185
|
}
|
|
70719
71186
|
function askYesNo2(question) {
|
|
70720
71187
|
const rl = readline5.createInterface({ input: process.stdin, output: process.stderr });
|
|
70721
|
-
return new Promise((
|
|
71188
|
+
return new Promise((resolve49) => {
|
|
70722
71189
|
process.stderr.write(`${question} `);
|
|
70723
71190
|
rl.once("line", (answer) => {
|
|
70724
71191
|
rl.close();
|
|
70725
71192
|
const trimmed = answer.trim();
|
|
70726
|
-
|
|
71193
|
+
resolve49(trimmed === "" || /^y(es)?$/i.test(trimmed));
|
|
70727
71194
|
});
|
|
70728
71195
|
});
|
|
70729
71196
|
}
|
|
@@ -70754,27 +71221,27 @@ async function offerAdaptationPromptClipboard(content, options = {}) {
|
|
|
70754
71221
|
}
|
|
70755
71222
|
|
|
70756
71223
|
// src/harness/cursor-rule.ts
|
|
70757
|
-
var
|
|
70758
|
-
var
|
|
71224
|
+
var fs44 = __toESM(require("fs"));
|
|
71225
|
+
var path49 = __toESM(require("path"));
|
|
70759
71226
|
var readline6 = __toESM(require("readline"));
|
|
70760
71227
|
init_file_ops();
|
|
70761
71228
|
init_logging();
|
|
70762
71229
|
var CURSOR_RULE_RELATIVE_PATH = ".cursor/rules/har-workflow.mdc";
|
|
70763
71230
|
function getCursorRulePath(repoPath) {
|
|
70764
|
-
return
|
|
71231
|
+
return path49.join(repoPath, CURSOR_RULE_RELATIVE_PATH);
|
|
70765
71232
|
}
|
|
70766
71233
|
function isCursorWorkspace(repoPath) {
|
|
70767
|
-
return
|
|
71234
|
+
return fs44.existsSync(path49.join(repoPath, ".cursor"));
|
|
70768
71235
|
}
|
|
70769
71236
|
function cursorRuleExists(repoPath) {
|
|
70770
|
-
return
|
|
71237
|
+
return fs44.existsSync(getCursorRulePath(repoPath));
|
|
70771
71238
|
}
|
|
70772
71239
|
function scaffoldCursorRule(repoPath) {
|
|
70773
71240
|
const templatePath = resolveTemplateFile("cursor-rule.mdc.template");
|
|
70774
71241
|
if (!templatePath) {
|
|
70775
71242
|
throw new Error("Cursor rule template not found (cursor-rule.mdc.template). Run npm run build.");
|
|
70776
71243
|
}
|
|
70777
|
-
const content =
|
|
71244
|
+
const content = fs44.readFileSync(templatePath, "utf8");
|
|
70778
71245
|
writeFileSafe(getCursorRulePath(repoPath), content);
|
|
70779
71246
|
}
|
|
70780
71247
|
async function handleCursorRule(options) {
|
|
@@ -70812,16 +71279,16 @@ async function promptScaffoldCursorRule(exists) {
|
|
|
70812
71279
|
}
|
|
70813
71280
|
async function askYesNo3(question) {
|
|
70814
71281
|
const rl = readline6.createInterface({ input: process.stdin, output: process.stderr });
|
|
70815
|
-
return new Promise((
|
|
71282
|
+
return new Promise((resolve49) => {
|
|
70816
71283
|
process.stderr.write(`${question} `);
|
|
70817
71284
|
rl.once("line", (answer) => {
|
|
70818
71285
|
rl.close();
|
|
70819
71286
|
const trimmed = answer.trim();
|
|
70820
71287
|
if (trimmed === "") {
|
|
70821
|
-
|
|
71288
|
+
resolve49(true);
|
|
70822
71289
|
return;
|
|
70823
71290
|
}
|
|
70824
|
-
|
|
71291
|
+
resolve49(/^y(es)?$/i.test(trimmed));
|
|
70825
71292
|
});
|
|
70826
71293
|
});
|
|
70827
71294
|
}
|
|
@@ -70863,8 +71330,8 @@ init_validation();
|
|
|
70863
71330
|
init_control_config();
|
|
70864
71331
|
|
|
70865
71332
|
// src/core/control-lifecycle.ts
|
|
70866
|
-
var
|
|
70867
|
-
var
|
|
71333
|
+
var import_child_process12 = require("child_process");
|
|
71334
|
+
var path50 = __toESM(require("path"));
|
|
70868
71335
|
|
|
70869
71336
|
// src/core/control-image.ts
|
|
70870
71337
|
var DEFAULT_CONTROL_IMAGE = "theosfactory/har-control";
|
|
@@ -70890,10 +71357,10 @@ var CONTROL_DATA_VOLUME = "har_control_data";
|
|
|
70890
71357
|
var CONTROL_CONTAINER_PORT = 3847;
|
|
70891
71358
|
var CONTROL_DATA_DB_URL = "file:/data/har_control.db";
|
|
70892
71359
|
function resolveControlDir() {
|
|
70893
|
-
return
|
|
71360
|
+
return path50.resolve(__dirname, "..", "control");
|
|
70894
71361
|
}
|
|
70895
71362
|
function resolveControlBuildContext() {
|
|
70896
|
-
return
|
|
71363
|
+
return path50.resolve(resolveControlDir(), "..");
|
|
70897
71364
|
}
|
|
70898
71365
|
function buildDockerRunArgs(options) {
|
|
70899
71366
|
const name = options.containerName ?? CONTROL_CONTAINER_NAME;
|
|
@@ -70916,7 +71383,7 @@ function buildDockerRunArgs(options) {
|
|
|
70916
71383
|
return args;
|
|
70917
71384
|
}
|
|
70918
71385
|
function runDocker(args) {
|
|
70919
|
-
const result = (0,
|
|
71386
|
+
const result = (0, import_child_process12.spawnSync)("docker", args, {
|
|
70920
71387
|
stdio: "inherit",
|
|
70921
71388
|
env: process.env
|
|
70922
71389
|
});
|
|
@@ -70926,7 +71393,7 @@ function runDocker(args) {
|
|
|
70926
71393
|
return result.status ?? 1;
|
|
70927
71394
|
}
|
|
70928
71395
|
function controlContainerExists(name = CONTROL_CONTAINER_NAME) {
|
|
70929
|
-
const result = (0,
|
|
71396
|
+
const result = (0, import_child_process12.spawnSync)("docker", ["ps", "-aq", "-f", `name=^${name}$`], {
|
|
70930
71397
|
encoding: "utf8",
|
|
70931
71398
|
stdio: ["pipe", "pipe", "ignore"]
|
|
70932
71399
|
});
|
|
@@ -70949,7 +71416,7 @@ async function startMissionControl(options) {
|
|
|
70949
71416
|
"-t",
|
|
70950
71417
|
imageRef,
|
|
70951
71418
|
"-f",
|
|
70952
|
-
|
|
71419
|
+
path50.join(resolveControlDir(), "Dockerfile"),
|
|
70953
71420
|
resolveControlBuildContext()
|
|
70954
71421
|
]);
|
|
70955
71422
|
if (buildCode !== 0) {
|
|
@@ -71096,7 +71563,7 @@ async function ensureTelemetryInfrastructure(options) {
|
|
|
71096
71563
|
// src/core/run-service.ts
|
|
71097
71564
|
init_telemetry_config();
|
|
71098
71565
|
init_telemetry_env();
|
|
71099
|
-
var
|
|
71566
|
+
var path52 = __toESM(require("path"));
|
|
71100
71567
|
init_local_executor();
|
|
71101
71568
|
function extractShellOutput(result) {
|
|
71102
71569
|
const stdout = result.logs?.find((log) => log.stream === "stdout")?.content ?? result.logs?.find((log) => !log.stream)?.content ?? "";
|
|
@@ -71301,12 +71768,12 @@ Usage from Cursor / Claude / Codex (@osfactory/otel-hook) will appear under Work
|
|
|
71301
71768
|
suffix: session.suffix,
|
|
71302
71769
|
createdAt: session.createdAt
|
|
71303
71770
|
});
|
|
71304
|
-
const envFile =
|
|
71771
|
+
const envFile = path52.join(session.workDir, `.env.agent.${options.agentId}`);
|
|
71305
71772
|
try {
|
|
71306
71773
|
appendTelemetryEnvToFile(envFile, {
|
|
71307
71774
|
sessionKey,
|
|
71308
71775
|
agentId: options.agentId,
|
|
71309
|
-
repoPath:
|
|
71776
|
+
repoPath: path52.resolve(options.repoPath),
|
|
71310
71777
|
workDir: session.workDir,
|
|
71311
71778
|
branch: session.branch,
|
|
71312
71779
|
suffix: session.suffix,
|
|
@@ -71547,12 +72014,12 @@ init_stages();
|
|
|
71547
72014
|
init_logging();
|
|
71548
72015
|
function askYesNo4(question) {
|
|
71549
72016
|
const rl = readline7.createInterface({ input: process.stdin, output: process.stderr });
|
|
71550
|
-
return new Promise((
|
|
72017
|
+
return new Promise((resolve49) => {
|
|
71551
72018
|
process.stderr.write(`${question} `);
|
|
71552
72019
|
rl.once("line", (answer) => {
|
|
71553
72020
|
rl.close();
|
|
71554
72021
|
const trimmed = answer.trim();
|
|
71555
|
-
|
|
72022
|
+
resolve49(trimmed === "" || /^y(es)?$/i.test(trimmed));
|
|
71556
72023
|
});
|
|
71557
72024
|
});
|
|
71558
72025
|
}
|
|
@@ -71594,21 +72061,21 @@ async function handleCommitGateOnboarding(options) {
|
|
|
71594
72061
|
}
|
|
71595
72062
|
|
|
71596
72063
|
// src/core/onboarding-preferences.ts
|
|
71597
|
-
var
|
|
71598
|
-
var
|
|
71599
|
-
var
|
|
72064
|
+
var fs46 = __toESM(require("fs"));
|
|
72065
|
+
var os18 = __toESM(require("os"));
|
|
72066
|
+
var path53 = __toESM(require("path"));
|
|
71600
72067
|
init_schema2();
|
|
71601
72068
|
function getOnboardingPreferencesPath() {
|
|
71602
72069
|
if (process.env.HAR_PREFERENCES_PATH) {
|
|
71603
|
-
return
|
|
72070
|
+
return path53.resolve(process.env.HAR_PREFERENCES_PATH);
|
|
71604
72071
|
}
|
|
71605
|
-
return
|
|
72072
|
+
return path53.join(os18.homedir(), ".har", "preferences.json");
|
|
71606
72073
|
}
|
|
71607
72074
|
function readOnboardingPreferences() {
|
|
71608
72075
|
const preferencePath = getOnboardingPreferencesPath();
|
|
71609
72076
|
try {
|
|
71610
|
-
if (!
|
|
71611
|
-
return OnboardingPreferencesSchema.parse(JSON.parse(
|
|
72077
|
+
if (!fs46.existsSync(preferencePath)) return OnboardingPreferencesSchema.parse({});
|
|
72078
|
+
return OnboardingPreferencesSchema.parse(JSON.parse(fs46.readFileSync(preferencePath, "utf8")));
|
|
71612
72079
|
} catch {
|
|
71613
72080
|
return OnboardingPreferencesSchema.parse({});
|
|
71614
72081
|
}
|
|
@@ -71633,8 +72100,8 @@ function writeOnboardingPreferences(overrides) {
|
|
|
71633
72100
|
};
|
|
71634
72101
|
const parsed = OnboardingPreferencesSchema.parse(preference);
|
|
71635
72102
|
const preferencePath = getOnboardingPreferencesPath();
|
|
71636
|
-
|
|
71637
|
-
|
|
72103
|
+
fs46.mkdirSync(path53.dirname(preferencePath), { recursive: true });
|
|
72104
|
+
fs46.writeFileSync(preferencePath, `${JSON.stringify(parsed, null, 2)}
|
|
71638
72105
|
`);
|
|
71639
72106
|
return parsed;
|
|
71640
72107
|
}
|
|
@@ -71768,14 +72235,14 @@ var envCommand = {
|
|
|
71768
72235
|
handleMaintain
|
|
71769
72236
|
).command(
|
|
71770
72237
|
"add-plugin [plugin]",
|
|
71771
|
-
|
|
72238
|
+
"Install a verification plugin (bundled id, path, npm package, or git URL) that registers stages",
|
|
71772
72239
|
(y) => y.positional("plugin", {
|
|
71773
72240
|
type: "string",
|
|
71774
|
-
describe:
|
|
72241
|
+
describe: "Bundled plugin id, local path (./plugin), npm package (@org/pkg), or git URL (github:org/repo)"
|
|
71775
72242
|
}).option("list", {
|
|
71776
72243
|
type: "boolean",
|
|
71777
72244
|
default: false,
|
|
71778
|
-
describe: "List
|
|
72245
|
+
describe: "List bundled plugins and exit"
|
|
71779
72246
|
}).option("repo", { type: "string", default: ".", describe: "Path to the repository" }).option("force", {
|
|
71780
72247
|
type: "boolean",
|
|
71781
72248
|
default: false,
|
|
@@ -71791,7 +72258,7 @@ var envCommand = {
|
|
|
71791
72258
|
`Register a custom stage (--custom), or install a plugin (deprecated alias for add-plugin)`,
|
|
71792
72259
|
(y) => y.positional("template", {
|
|
71793
72260
|
type: "string",
|
|
71794
|
-
describe:
|
|
72261
|
+
describe: "Custom stage id with --custom, or a plugin id / path / npm / git spec as a deprecated alias"
|
|
71795
72262
|
}).option("list", {
|
|
71796
72263
|
type: "boolean",
|
|
71797
72264
|
default: false,
|
|
@@ -71925,7 +72392,7 @@ var envCommand = {
|
|
|
71925
72392
|
}
|
|
71926
72393
|
};
|
|
71927
72394
|
async function handleInit(argv) {
|
|
71928
|
-
const repoPath =
|
|
72395
|
+
const repoPath = path54.resolve(argv.repo);
|
|
71929
72396
|
const onboarding = resolveOnboardingOptions(argv);
|
|
71930
72397
|
header("har env init");
|
|
71931
72398
|
info(`Repository: ${repoPath}`);
|
|
@@ -71971,7 +72438,7 @@ async function handleInit(argv) {
|
|
|
71971
72438
|
}
|
|
71972
72439
|
}
|
|
71973
72440
|
async function handleMaintain(argv) {
|
|
71974
|
-
const repoPath =
|
|
72441
|
+
const repoPath = path54.resolve(argv.repo);
|
|
71975
72442
|
const onboarding = resolveOnboardingOptions(argv);
|
|
71976
72443
|
header("har env maintain");
|
|
71977
72444
|
info(`Repository: ${repoPath}`);
|
|
@@ -72102,7 +72569,7 @@ async function applyAgentIntegrations(options) {
|
|
|
72102
72569
|
}
|
|
72103
72570
|
}
|
|
72104
72571
|
async function handleAddPlugin(argv) {
|
|
72105
|
-
const repoPath =
|
|
72572
|
+
const repoPath = path54.resolve(argv.repo);
|
|
72106
72573
|
const available = listPluginIds();
|
|
72107
72574
|
if (argv.list) {
|
|
72108
72575
|
for (const id of available) {
|
|
@@ -72110,9 +72577,9 @@ async function handleAddPlugin(argv) {
|
|
|
72110
72577
|
}
|
|
72111
72578
|
return;
|
|
72112
72579
|
}
|
|
72113
|
-
if (!argv.plugin
|
|
72580
|
+
if (!argv.plugin) {
|
|
72114
72581
|
error(
|
|
72115
|
-
`
|
|
72582
|
+
`Missing plugin. Bundled: ${available.join(", ") || "(none)"}. Or pass a path, npm package, or git URL. For a project-specific stage, use: har env add-stage <id> --custom`
|
|
72116
72583
|
);
|
|
72117
72584
|
return finishCommand(1);
|
|
72118
72585
|
}
|
|
@@ -72122,10 +72589,12 @@ async function handleAddPlugin(argv) {
|
|
|
72122
72589
|
try {
|
|
72123
72590
|
const result = addPlugin(repoPath, argv.plugin, {
|
|
72124
72591
|
force: argv.force,
|
|
72125
|
-
skipCi: argv.skipCi
|
|
72592
|
+
skipCi: argv.skipCi,
|
|
72593
|
+
spec: argv.plugin
|
|
72126
72594
|
});
|
|
72127
72595
|
divider();
|
|
72128
|
-
|
|
72596
|
+
const stageLabel = result.stageIds.length > 1 ? `stages: ${result.stageIds.join(", ")}` : `stage: ${result.stageId}`;
|
|
72597
|
+
success(`Plugin applied \u2014 registered ${stageLabel} (source: ${result.source})`);
|
|
72129
72598
|
console.error("");
|
|
72130
72599
|
console.error(" Next steps:");
|
|
72131
72600
|
for (const step of result.nextSteps) {
|
|
@@ -72140,7 +72609,7 @@ async function handleAddPlugin(argv) {
|
|
|
72140
72609
|
}
|
|
72141
72610
|
}
|
|
72142
72611
|
async function handleAddStage(argv) {
|
|
72143
|
-
const repoPath =
|
|
72612
|
+
const repoPath = path54.resolve(argv.repo);
|
|
72144
72613
|
const available = listPluginIds();
|
|
72145
72614
|
if (argv.list) {
|
|
72146
72615
|
warn("har env add-stage --list is deprecated; prefer: har env add-plugin --list");
|
|
@@ -72188,9 +72657,9 @@ async function handleAddStage(argv) {
|
|
|
72188
72657
|
}
|
|
72189
72658
|
return;
|
|
72190
72659
|
}
|
|
72191
|
-
if (!argv.template
|
|
72660
|
+
if (!argv.template) {
|
|
72192
72661
|
error(
|
|
72193
|
-
`Unknown plugin:
|
|
72662
|
+
`Unknown plugin: (missing). Available: ${available.join(", ")}. Prefer: har env add-plugin <id>. For a project-specific stage, use: har env add-stage <id> --custom`
|
|
72194
72663
|
);
|
|
72195
72664
|
return finishCommand(1);
|
|
72196
72665
|
}
|
|
@@ -72206,7 +72675,7 @@ async function handleAddStage(argv) {
|
|
|
72206
72675
|
});
|
|
72207
72676
|
}
|
|
72208
72677
|
async function handlePreflight(argv) {
|
|
72209
|
-
const repo =
|
|
72678
|
+
const repo = path54.resolve(argv.repo);
|
|
72210
72679
|
const agentId = validateAgentId(argv.id, repo);
|
|
72211
72680
|
const result = await preflightEnvironment({
|
|
72212
72681
|
repoPath: repo,
|
|
@@ -72222,7 +72691,7 @@ async function handlePreflight(argv) {
|
|
|
72222
72691
|
return finishCommand(result.code);
|
|
72223
72692
|
}
|
|
72224
72693
|
async function handleLaunch(argv) {
|
|
72225
|
-
const repo =
|
|
72694
|
+
const repo = path54.resolve(argv.repo);
|
|
72226
72695
|
const agentId = validateAgentId(argv.id, repo);
|
|
72227
72696
|
if (!argv.resume) {
|
|
72228
72697
|
const guard = checkLaunchGuard2(repo, agentId, { worktree: argv.worktree });
|
|
@@ -72280,7 +72749,7 @@ async function handleRecover(argv) {
|
|
|
72280
72749
|
});
|
|
72281
72750
|
}
|
|
72282
72751
|
async function handleVerify(argv) {
|
|
72283
|
-
const repo =
|
|
72752
|
+
const repo = path54.resolve(argv.repo);
|
|
72284
72753
|
const agentId = validateAgentId(argv.id, repo);
|
|
72285
72754
|
const result = await runVerification({
|
|
72286
72755
|
repoPath: repo,
|
|
@@ -72292,7 +72761,7 @@ async function handleVerify(argv) {
|
|
|
72292
72761
|
return finishCommand(result.code);
|
|
72293
72762
|
}
|
|
72294
72763
|
async function handleTeardown(argv) {
|
|
72295
|
-
const repo =
|
|
72764
|
+
const repo = path54.resolve(argv.repo);
|
|
72296
72765
|
const agentId = validateAgentId(argv.id, repo);
|
|
72297
72766
|
const result = await teardownEnvironment({
|
|
72298
72767
|
repoPath: repo,
|
|
@@ -72303,7 +72772,7 @@ async function handleTeardown(argv) {
|
|
|
72303
72772
|
return finishCommand(result.code);
|
|
72304
72773
|
}
|
|
72305
72774
|
async function handleComplete(argv) {
|
|
72306
|
-
const repo =
|
|
72775
|
+
const repo = path54.resolve(argv.repo);
|
|
72307
72776
|
const agentId = validateAgentId(argv.id, repo);
|
|
72308
72777
|
const result = await completeEnvironment({
|
|
72309
72778
|
repoPath: repo,
|
|
@@ -72324,7 +72793,7 @@ async function handleComplete(argv) {
|
|
|
72324
72793
|
return finishCommand(result.code);
|
|
72325
72794
|
}
|
|
72326
72795
|
async function handleStatus(argv) {
|
|
72327
|
-
const repoPath =
|
|
72796
|
+
const repoPath = path54.resolve(argv.repo);
|
|
72328
72797
|
if (argv.json) {
|
|
72329
72798
|
const status = collectEnvironmentStatus(repoPath);
|
|
72330
72799
|
const output = EnvironmentStatusSchema.parse(status);
|
|
@@ -72337,7 +72806,7 @@ async function handleStatus(argv) {
|
|
|
72337
72806
|
});
|
|
72338
72807
|
}
|
|
72339
72808
|
async function handleRunsList(argv) {
|
|
72340
|
-
const repoPath =
|
|
72809
|
+
const repoPath = path54.resolve(argv.repo);
|
|
72341
72810
|
const runs = listRuns(repoPath, { stageId: argv.stage, limit: argv.limit });
|
|
72342
72811
|
if (argv.json) {
|
|
72343
72812
|
process.stdout.write(JSON.stringify({ runs }, null, 2) + "\n");
|
|
@@ -72354,7 +72823,7 @@ async function handleRunsList(argv) {
|
|
|
72354
72823
|
}
|
|
72355
72824
|
}
|
|
72356
72825
|
async function handleRunsGet(argv) {
|
|
72357
|
-
const run2 = getRun(
|
|
72826
|
+
const run2 = getRun(path54.resolve(argv.repo), argv.runId);
|
|
72358
72827
|
if (!run2) {
|
|
72359
72828
|
error(`Run not found: ${argv.runId}`);
|
|
72360
72829
|
return finishCommand(1);
|
|
@@ -72436,27 +72905,27 @@ function printNextSteps() {
|
|
|
72436
72905
|
}
|
|
72437
72906
|
|
|
72438
72907
|
// src/cli/commands/control.ts
|
|
72439
|
-
var
|
|
72908
|
+
var path58 = __toESM(require("path"));
|
|
72440
72909
|
init_control_config();
|
|
72441
72910
|
init_control_port();
|
|
72442
72911
|
init_control_sync();
|
|
72443
72912
|
|
|
72444
72913
|
// src/core/control-sync-selection.ts
|
|
72445
|
-
var
|
|
72446
|
-
var
|
|
72447
|
-
var
|
|
72914
|
+
var fs47 = __toESM(require("fs"));
|
|
72915
|
+
var os19 = __toESM(require("os"));
|
|
72916
|
+
var path55 = __toESM(require("path"));
|
|
72448
72917
|
init_control_repo_path();
|
|
72449
72918
|
function getSelectionPath() {
|
|
72450
72919
|
if (process.env.HAR_CONTROL_SYNC_SELECTION_PATH) {
|
|
72451
|
-
return
|
|
72920
|
+
return path55.resolve(process.env.HAR_CONTROL_SYNC_SELECTION_PATH);
|
|
72452
72921
|
}
|
|
72453
|
-
return
|
|
72922
|
+
return path55.join(os19.homedir(), ".har", "sync-selection.json");
|
|
72454
72923
|
}
|
|
72455
72924
|
function readSyncSelection() {
|
|
72456
72925
|
const selectionPath = getSelectionPath();
|
|
72457
72926
|
try {
|
|
72458
|
-
if (!
|
|
72459
|
-
const parsed = JSON.parse(
|
|
72927
|
+
if (!fs47.existsSync(selectionPath)) return null;
|
|
72928
|
+
const parsed = JSON.parse(fs47.readFileSync(selectionPath, "utf8"));
|
|
72460
72929
|
if (!Array.isArray(parsed.repos)) return null;
|
|
72461
72930
|
return parsed.repos.map((repoPath) => canonicalizeControlRepoPath(repoPath));
|
|
72462
72931
|
} catch {
|
|
@@ -72466,8 +72935,8 @@ function readSyncSelection() {
|
|
|
72466
72935
|
function writeSyncSelection(repos) {
|
|
72467
72936
|
const selectionPath = getSelectionPath();
|
|
72468
72937
|
const canonical = Array.from(new Set(repos.map((repoPath) => canonicalizeControlRepoPath(repoPath))));
|
|
72469
|
-
|
|
72470
|
-
|
|
72938
|
+
fs47.mkdirSync(path55.dirname(selectionPath), { recursive: true });
|
|
72939
|
+
fs47.writeFileSync(selectionPath, JSON.stringify({ repos: canonical }, null, 2) + "\n");
|
|
72471
72940
|
}
|
|
72472
72941
|
function resolveSyncSelection(input) {
|
|
72473
72942
|
const { discovered, stored, forceSelect, isTTY } = input;
|
|
@@ -72499,13 +72968,13 @@ init_portal_credentials();
|
|
|
72499
72968
|
// src/core/portal-login.ts
|
|
72500
72969
|
var http = __toESM(require("http"));
|
|
72501
72970
|
var import_crypto = require("crypto");
|
|
72502
|
-
var
|
|
72971
|
+
var import_child_process14 = require("child_process");
|
|
72503
72972
|
var CALLBACK_PATH = "/callback";
|
|
72504
72973
|
var LOGIN_TIMEOUT_MS = 3 * 6e4;
|
|
72505
72974
|
function openBrowser(url) {
|
|
72506
72975
|
const [cmd, args] = process.platform === "darwin" ? ["open", [url]] : process.platform === "win32" ? ["cmd", ["/c", "start", "", url]] : ["xdg-open", [url]];
|
|
72507
72976
|
try {
|
|
72508
|
-
const child = (0,
|
|
72977
|
+
const child = (0, import_child_process14.spawn)(cmd, args, { stdio: "ignore", detached: true });
|
|
72509
72978
|
child.on("error", () => {
|
|
72510
72979
|
});
|
|
72511
72980
|
child.unref();
|
|
@@ -72514,7 +72983,7 @@ function openBrowser(url) {
|
|
|
72514
72983
|
}
|
|
72515
72984
|
async function loginViaBrowser(portalUrl, openUrl = openBrowser) {
|
|
72516
72985
|
const state = (0, import_crypto.randomUUID)();
|
|
72517
|
-
return new Promise((
|
|
72986
|
+
return new Promise((resolve49, reject) => {
|
|
72518
72987
|
let timer;
|
|
72519
72988
|
const server = http.createServer((req, res) => {
|
|
72520
72989
|
const requestUrl = new URL(req.url ?? "", "http://127.0.0.1");
|
|
@@ -72539,7 +73008,7 @@ async function loginViaBrowser(portalUrl, openUrl = openBrowser) {
|
|
|
72539
73008
|
res.writeHead(200, { "Content-Type": "text/html" });
|
|
72540
73009
|
res.end("<h1>Logged in</h1><p>You can close this tab and return to the terminal.</p>");
|
|
72541
73010
|
cleanup();
|
|
72542
|
-
|
|
73011
|
+
resolve49({
|
|
72543
73012
|
portalUrl,
|
|
72544
73013
|
token,
|
|
72545
73014
|
workspace,
|
|
@@ -72574,8 +73043,8 @@ If your browser did not open, paste that URL.
|
|
|
72574
73043
|
}
|
|
72575
73044
|
|
|
72576
73045
|
// src/core/control-unregister.ts
|
|
72577
|
-
var
|
|
72578
|
-
var
|
|
73046
|
+
var fs48 = __toESM(require("fs"));
|
|
73047
|
+
var path56 = __toESM(require("path"));
|
|
72579
73048
|
init_control_repo_path();
|
|
72580
73049
|
init_control_registry();
|
|
72581
73050
|
init_control_config();
|
|
@@ -72585,9 +73054,9 @@ function listUnregisterWorktreeCandidates(repoPath) {
|
|
|
72585
73054
|
const harnessRoot = canonicalizeControlRepoPath(repoPath);
|
|
72586
73055
|
const byPath = /* @__PURE__ */ new Map();
|
|
72587
73056
|
const add = (partial2) => {
|
|
72588
|
-
const resolved =
|
|
73057
|
+
const resolved = path56.resolve(partial2.worktreePath);
|
|
72589
73058
|
if (!resolved || resolved === harnessRoot) return;
|
|
72590
|
-
const exists = partial2.exists ??
|
|
73059
|
+
const exists = partial2.exists ?? fs48.existsSync(resolved);
|
|
72591
73060
|
const prev = byPath.get(resolved);
|
|
72592
73061
|
if (prev) {
|
|
72593
73062
|
byPath.set(resolved, {
|
|
@@ -72638,8 +73107,8 @@ async function askYesNo5(question) {
|
|
|
72638
73107
|
if (!process.stdin.isTTY || !process.stdout.isTTY) return false;
|
|
72639
73108
|
const readline8 = await import("readline");
|
|
72640
73109
|
const rl = readline8.createInterface({ input: process.stdin, output: process.stderr });
|
|
72641
|
-
const answer = await new Promise((
|
|
72642
|
-
rl.question(question,
|
|
73110
|
+
const answer = await new Promise((resolve49) => {
|
|
73111
|
+
rl.question(question, resolve49);
|
|
72643
73112
|
});
|
|
72644
73113
|
rl.close();
|
|
72645
73114
|
return /^[Yy]$/.test(answer.trim());
|
|
@@ -72701,28 +73170,28 @@ async function teardownWorktrees(repoPath, candidates, dryRun) {
|
|
|
72701
73170
|
trigger: "cli"
|
|
72702
73171
|
});
|
|
72703
73172
|
if (result.code !== 0) {
|
|
72704
|
-
if (
|
|
72705
|
-
|
|
73173
|
+
if (fs48.existsSync(candidate.worktreePath)) {
|
|
73174
|
+
fs48.rmSync(candidate.worktreePath, { recursive: true, force: true });
|
|
72706
73175
|
}
|
|
72707
73176
|
}
|
|
72708
73177
|
outcomes.push({
|
|
72709
73178
|
path: candidate.worktreePath,
|
|
72710
73179
|
agentId: candidate.agentId,
|
|
72711
|
-
deleted: !
|
|
72712
|
-
error: result.code !== 0 &&
|
|
73180
|
+
deleted: !fs48.existsSync(candidate.worktreePath),
|
|
73181
|
+
error: result.code !== 0 && fs48.existsSync(candidate.worktreePath) ? result.stderr : void 0
|
|
72713
73182
|
});
|
|
72714
73183
|
} catch (err) {
|
|
72715
73184
|
const message = err instanceof Error ? err.message : String(err);
|
|
72716
73185
|
try {
|
|
72717
|
-
if (
|
|
72718
|
-
|
|
73186
|
+
if (fs48.existsSync(candidate.worktreePath)) {
|
|
73187
|
+
fs48.rmSync(candidate.worktreePath, { recursive: true, force: true });
|
|
72719
73188
|
}
|
|
72720
73189
|
} catch {
|
|
72721
73190
|
}
|
|
72722
73191
|
outcomes.push({
|
|
72723
73192
|
path: candidate.worktreePath,
|
|
72724
73193
|
agentId: candidate.agentId,
|
|
72725
|
-
deleted: !
|
|
73194
|
+
deleted: !fs48.existsSync(candidate.worktreePath),
|
|
72726
73195
|
error: message
|
|
72727
73196
|
});
|
|
72728
73197
|
}
|
|
@@ -72785,16 +73254,16 @@ init_control_config();
|
|
|
72785
73254
|
init_control_registry();
|
|
72786
73255
|
|
|
72787
73256
|
// src/core/harness-scrub.ts
|
|
72788
|
-
var
|
|
72789
|
-
var
|
|
73257
|
+
var fs49 = __toESM(require("fs"));
|
|
73258
|
+
var path57 = __toESM(require("path"));
|
|
72790
73259
|
var HARNESS_SCRUB_DIRS = ["runs", "validations", "state", "slots"];
|
|
72791
73260
|
function scrubLocalHarnessDirs(repoPath) {
|
|
72792
73261
|
const results = [];
|
|
72793
|
-
const resolved =
|
|
72794
|
-
if (!
|
|
73262
|
+
const resolved = path57.resolve(repoPath);
|
|
73263
|
+
if (!fs49.existsSync(resolved)) {
|
|
72795
73264
|
for (const directory of HARNESS_SCRUB_DIRS) {
|
|
72796
73265
|
results.push({
|
|
72797
|
-
path:
|
|
73266
|
+
path: path57.join(resolved, ".har", directory),
|
|
72798
73267
|
directory,
|
|
72799
73268
|
deleted: false,
|
|
72800
73269
|
error: "repository path does not exist"
|
|
@@ -72803,24 +73272,24 @@ function scrubLocalHarnessDirs(repoPath) {
|
|
|
72803
73272
|
return results;
|
|
72804
73273
|
}
|
|
72805
73274
|
for (const directory of HARNESS_SCRUB_DIRS) {
|
|
72806
|
-
const target =
|
|
72807
|
-
if (!
|
|
73275
|
+
const target = path57.join(resolved, ".har", directory);
|
|
73276
|
+
if (!fs49.existsSync(target)) {
|
|
72808
73277
|
results.push({ path: target, directory, deleted: true });
|
|
72809
73278
|
continue;
|
|
72810
73279
|
}
|
|
72811
73280
|
try {
|
|
72812
|
-
|
|
73281
|
+
fs49.rmSync(target, { recursive: true, force: true });
|
|
72813
73282
|
results.push({
|
|
72814
73283
|
path: target,
|
|
72815
73284
|
directory,
|
|
72816
|
-
deleted: !
|
|
72817
|
-
error:
|
|
73285
|
+
deleted: !fs49.existsSync(target),
|
|
73286
|
+
error: fs49.existsSync(target) ? "failed to remove directory" : void 0
|
|
72818
73287
|
});
|
|
72819
73288
|
} catch (err) {
|
|
72820
73289
|
results.push({
|
|
72821
73290
|
path: target,
|
|
72822
73291
|
directory,
|
|
72823
|
-
deleted: !
|
|
73292
|
+
deleted: !fs49.existsSync(target),
|
|
72824
73293
|
error: err instanceof Error ? err.message : String(err)
|
|
72825
73294
|
});
|
|
72826
73295
|
}
|
|
@@ -72831,7 +73300,7 @@ function scrubLocalHarnessForRepos(repoPaths) {
|
|
|
72831
73300
|
const results = [];
|
|
72832
73301
|
const seen = /* @__PURE__ */ new Set();
|
|
72833
73302
|
for (const repoPath of repoPaths) {
|
|
72834
|
-
const key =
|
|
73303
|
+
const key = path57.resolve(repoPath);
|
|
72835
73304
|
if (seen.has(key)) continue;
|
|
72836
73305
|
seen.add(key);
|
|
72837
73306
|
results.push(...scrubLocalHarnessDirs(key));
|
|
@@ -72844,8 +73313,8 @@ async function askYesNo6(question) {
|
|
|
72844
73313
|
if (!process.stdin.isTTY || !process.stdout.isTTY) return false;
|
|
72845
73314
|
const readline8 = await import("readline");
|
|
72846
73315
|
const rl = readline8.createInterface({ input: process.stdin, output: process.stderr });
|
|
72847
|
-
const answer = await new Promise((
|
|
72848
|
-
rl.question(question,
|
|
73316
|
+
const answer = await new Promise((resolve49) => {
|
|
73317
|
+
rl.question(question, resolve49);
|
|
72849
73318
|
});
|
|
72850
73319
|
rl.close();
|
|
72851
73320
|
return /^[Yy]$/.test(answer.trim());
|
|
@@ -73090,7 +73559,7 @@ async function handleDown() {
|
|
|
73090
73559
|
return finishCommand(code);
|
|
73091
73560
|
}
|
|
73092
73561
|
async function handleRegister(argv) {
|
|
73093
|
-
const repoPath =
|
|
73562
|
+
const repoPath = path58.resolve(argv.repo);
|
|
73094
73563
|
header("har control register");
|
|
73095
73564
|
info(`Repository: ${repoPath}`);
|
|
73096
73565
|
try {
|
|
@@ -73182,7 +73651,7 @@ async function handleReset(argv) {
|
|
|
73182
73651
|
}
|
|
73183
73652
|
}
|
|
73184
73653
|
async function handleUnregister(argv) {
|
|
73185
|
-
const repoPath =
|
|
73654
|
+
const repoPath = path58.resolve(argv.repo);
|
|
73186
73655
|
const worktrees = listUnregisterWorktreeCandidates(repoPath);
|
|
73187
73656
|
try {
|
|
73188
73657
|
let deleteWorktrees = argv.deleteWorktrees;
|
|
@@ -73364,12 +73833,12 @@ async function handleLogin(argv) {
|
|
|
73364
73833
|
}
|
|
73365
73834
|
|
|
73366
73835
|
// src/cli/commands/hooks.ts
|
|
73367
|
-
var
|
|
73836
|
+
var path60 = __toESM(require("path"));
|
|
73368
73837
|
init_hooks();
|
|
73369
73838
|
|
|
73370
73839
|
// src/core/claude-hooks.ts
|
|
73371
|
-
var
|
|
73372
|
-
var
|
|
73840
|
+
var fs50 = __toESM(require("fs"));
|
|
73841
|
+
var path59 = __toESM(require("path"));
|
|
73373
73842
|
var CLAUDE_GUARD_RELATIVE_PATH = ".har/hooks/claude-worktree-guard.sh";
|
|
73374
73843
|
var CLAUDE_SETTINGS_RELATIVE_PATH = ".claude/settings.json";
|
|
73375
73844
|
var GUARD_MATCHER = "Edit|Write|MultiEdit|NotebookEdit";
|
|
@@ -73380,8 +73849,8 @@ function isHarGuardEntry(entry) {
|
|
|
73380
73849
|
);
|
|
73381
73850
|
}
|
|
73382
73851
|
function readSettings(settingsPath) {
|
|
73383
|
-
if (!
|
|
73384
|
-
const raw =
|
|
73852
|
+
if (!fs50.existsSync(settingsPath)) return {};
|
|
73853
|
+
const raw = fs50.readFileSync(settingsPath, "utf8").trim();
|
|
73385
73854
|
if (raw === "") return {};
|
|
73386
73855
|
const parsed = JSON.parse(raw);
|
|
73387
73856
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
@@ -73390,19 +73859,19 @@ function readSettings(settingsPath) {
|
|
|
73390
73859
|
return parsed;
|
|
73391
73860
|
}
|
|
73392
73861
|
function writeSettings(settingsPath, settings) {
|
|
73393
|
-
|
|
73394
|
-
|
|
73862
|
+
fs50.mkdirSync(path59.dirname(settingsPath), { recursive: true });
|
|
73863
|
+
fs50.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
73395
73864
|
}
|
|
73396
73865
|
function installClaudeGuard(repoPath) {
|
|
73397
73866
|
const templatePath = resolveTemplateFile("claude-worktree-guard.sh.template");
|
|
73398
73867
|
if (!templatePath) {
|
|
73399
73868
|
throw new Error("Guard template not found (claude-worktree-guard.sh.template). Run npm run build.");
|
|
73400
73869
|
}
|
|
73401
|
-
const guardScript =
|
|
73402
|
-
|
|
73403
|
-
|
|
73404
|
-
|
|
73405
|
-
const settingsPath =
|
|
73870
|
+
const guardScript = path59.join(repoPath, CLAUDE_GUARD_RELATIVE_PATH);
|
|
73871
|
+
fs50.mkdirSync(path59.dirname(guardScript), { recursive: true });
|
|
73872
|
+
fs50.copyFileSync(templatePath, guardScript);
|
|
73873
|
+
fs50.chmodSync(guardScript, 493);
|
|
73874
|
+
const settingsPath = path59.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
|
|
73406
73875
|
const settings = readSettings(settingsPath);
|
|
73407
73876
|
const hooks = settings.hooks ?? {};
|
|
73408
73877
|
const preToolUse = (hooks.PreToolUse ?? []).filter((entry) => !isHarGuardEntry(entry));
|
|
@@ -73416,15 +73885,15 @@ function installClaudeGuard(repoPath) {
|
|
|
73416
73885
|
}
|
|
73417
73886
|
function uninstallClaudeGuard(repoPath) {
|
|
73418
73887
|
let removed = false;
|
|
73419
|
-
const guardScript =
|
|
73420
|
-
if (
|
|
73421
|
-
|
|
73888
|
+
const guardScript = path59.join(repoPath, CLAUDE_GUARD_RELATIVE_PATH);
|
|
73889
|
+
if (fs50.existsSync(guardScript)) {
|
|
73890
|
+
fs50.rmSync(guardScript);
|
|
73422
73891
|
removed = true;
|
|
73423
|
-
const parent =
|
|
73424
|
-
if (
|
|
73892
|
+
const parent = path59.dirname(guardScript);
|
|
73893
|
+
if (fs50.existsSync(parent) && fs50.readdirSync(parent).length === 0) fs50.rmdirSync(parent);
|
|
73425
73894
|
}
|
|
73426
|
-
const settingsPath =
|
|
73427
|
-
if (
|
|
73895
|
+
const settingsPath = path59.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
|
|
73896
|
+
if (fs50.existsSync(settingsPath)) {
|
|
73428
73897
|
const settings = readSettings(settingsPath);
|
|
73429
73898
|
const preToolUse = settings.hooks?.PreToolUse;
|
|
73430
73899
|
if (preToolUse) {
|
|
@@ -73449,8 +73918,8 @@ function uninstallClaudeGuard(repoPath) {
|
|
|
73449
73918
|
return { removed };
|
|
73450
73919
|
}
|
|
73451
73920
|
function claudeGuardInstalled(repoPath) {
|
|
73452
|
-
const settingsPath =
|
|
73453
|
-
if (!
|
|
73921
|
+
const settingsPath = path59.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
|
|
73922
|
+
if (!fs50.existsSync(settingsPath)) return false;
|
|
73454
73923
|
try {
|
|
73455
73924
|
const settings = readSettings(settingsPath);
|
|
73456
73925
|
return (settings.hooks?.PreToolUse ?? []).some(isHarGuardEntry);
|
|
@@ -73467,7 +73936,7 @@ function repoOption(y) {
|
|
|
73467
73936
|
function handleInstall2(argv) {
|
|
73468
73937
|
try {
|
|
73469
73938
|
if (argv.claude) {
|
|
73470
|
-
const result2 = installClaudeGuard(
|
|
73939
|
+
const result2 = installClaudeGuard(path60.resolve(argv.repo));
|
|
73471
73940
|
success("Claude Code worktree guard installed.");
|
|
73472
73941
|
info(`Guard script: ${result2.guardScript}`);
|
|
73473
73942
|
info(`Settings: ${result2.settingsPath} (PreToolUse: Edit|Write|MultiEdit|NotebookEdit)`);
|
|
@@ -73475,7 +73944,7 @@ function handleInstall2(argv) {
|
|
|
73475
73944
|
info("Commit both files so the guard travels with the repo.");
|
|
73476
73945
|
return;
|
|
73477
73946
|
}
|
|
73478
|
-
const result = installHooks({ repoPath:
|
|
73947
|
+
const result = installHooks({ repoPath: path60.resolve(argv.repo), force: argv.force });
|
|
73479
73948
|
success(`Commit gate installed in ${result.hooksDir}`);
|
|
73480
73949
|
info(`pre-commit: ${result.preCommit}, post-commit: ${result.postCommit}`);
|
|
73481
73950
|
info("Commits of unverified change batches will be blocked in agent worktrees.");
|
|
@@ -73488,7 +73957,7 @@ function handleInstall2(argv) {
|
|
|
73488
73957
|
function handleUninstall(argv) {
|
|
73489
73958
|
try {
|
|
73490
73959
|
if (argv.claude) {
|
|
73491
|
-
const result2 = uninstallClaudeGuard(
|
|
73960
|
+
const result2 = uninstallClaudeGuard(path60.resolve(argv.repo));
|
|
73492
73961
|
if (result2.removed) {
|
|
73493
73962
|
success("Claude Code worktree guard removed.");
|
|
73494
73963
|
} else {
|
|
@@ -73496,7 +73965,7 @@ function handleUninstall(argv) {
|
|
|
73496
73965
|
}
|
|
73497
73966
|
return;
|
|
73498
73967
|
}
|
|
73499
|
-
const result = uninstallHooks(
|
|
73968
|
+
const result = uninstallHooks(path60.resolve(argv.repo));
|
|
73500
73969
|
if (result.removed) {
|
|
73501
73970
|
success(`Commit gate removed from ${result.hooksDir}`);
|
|
73502
73971
|
} else {
|
|
@@ -73509,7 +73978,7 @@ function handleUninstall(argv) {
|
|
|
73509
73978
|
}
|
|
73510
73979
|
function handleStatus2(argv) {
|
|
73511
73980
|
try {
|
|
73512
|
-
const status = getHooksStatus(
|
|
73981
|
+
const status = getHooksStatus(path60.resolve(argv.repo));
|
|
73513
73982
|
if (argv.json) {
|
|
73514
73983
|
process.stdout.write(`${JSON.stringify(status, null, 2)}
|
|
73515
73984
|
`);
|
|
@@ -73527,7 +73996,7 @@ function handleStatus2(argv) {
|
|
|
73527
73996
|
);
|
|
73528
73997
|
info(`Effective: ${status.effectiveMode} (in this checkout)`);
|
|
73529
73998
|
info(
|
|
73530
|
-
`Claude guard: ${claudeGuardInstalled(
|
|
73999
|
+
`Claude guard: ${claudeGuardInstalled(path60.resolve(argv.repo)) ? `installed (${CLAUDE_GUARD_RELATIVE_PATH})` : "not installed"}`
|
|
73531
74000
|
);
|
|
73532
74001
|
} catch (err) {
|
|
73533
74002
|
error(err instanceof Error ? err.message : String(err));
|
|
@@ -73788,10 +74257,10 @@ function assignProp(target, prop, value) {
|
|
|
73788
74257
|
configurable: true
|
|
73789
74258
|
});
|
|
73790
74259
|
}
|
|
73791
|
-
function getElementAtPath(obj,
|
|
73792
|
-
if (!
|
|
74260
|
+
function getElementAtPath(obj, path65) {
|
|
74261
|
+
if (!path65)
|
|
73793
74262
|
return obj;
|
|
73794
|
-
return
|
|
74263
|
+
return path65.reduce((acc, key) => acc?.[key], obj);
|
|
73795
74264
|
}
|
|
73796
74265
|
function promiseAllObject(promisesObj) {
|
|
73797
74266
|
const keys = Object.keys(promisesObj);
|
|
@@ -74111,11 +74580,11 @@ function aborted(x, startIndex = 0) {
|
|
|
74111
74580
|
}
|
|
74112
74581
|
return false;
|
|
74113
74582
|
}
|
|
74114
|
-
function prefixIssues(
|
|
74583
|
+
function prefixIssues(path65, issues) {
|
|
74115
74584
|
return issues.map((iss) => {
|
|
74116
74585
|
var _a2;
|
|
74117
74586
|
(_a2 = iss).path ?? (_a2.path = []);
|
|
74118
|
-
iss.path.unshift(
|
|
74587
|
+
iss.path.unshift(path65);
|
|
74119
74588
|
return iss;
|
|
74120
74589
|
});
|
|
74121
74590
|
}
|
|
@@ -79438,7 +79907,7 @@ var Protocol = class {
|
|
|
79438
79907
|
return;
|
|
79439
79908
|
}
|
|
79440
79909
|
const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
|
|
79441
|
-
await new Promise((
|
|
79910
|
+
await new Promise((resolve49) => setTimeout(resolve49, pollInterval));
|
|
79442
79911
|
options?.signal?.throwIfAborted();
|
|
79443
79912
|
}
|
|
79444
79913
|
} catch (error3) {
|
|
@@ -79455,7 +79924,7 @@ var Protocol = class {
|
|
|
79455
79924
|
*/
|
|
79456
79925
|
request(request, resultSchema, options) {
|
|
79457
79926
|
const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
|
|
79458
|
-
return new Promise((
|
|
79927
|
+
return new Promise((resolve49, reject) => {
|
|
79459
79928
|
const earlyReject = (error3) => {
|
|
79460
79929
|
reject(error3);
|
|
79461
79930
|
};
|
|
@@ -79533,7 +80002,7 @@ var Protocol = class {
|
|
|
79533
80002
|
if (!parseResult.success) {
|
|
79534
80003
|
reject(parseResult.error);
|
|
79535
80004
|
} else {
|
|
79536
|
-
|
|
80005
|
+
resolve49(parseResult.data);
|
|
79537
80006
|
}
|
|
79538
80007
|
} catch (error3) {
|
|
79539
80008
|
reject(error3);
|
|
@@ -79794,12 +80263,12 @@ var Protocol = class {
|
|
|
79794
80263
|
}
|
|
79795
80264
|
} catch {
|
|
79796
80265
|
}
|
|
79797
|
-
return new Promise((
|
|
80266
|
+
return new Promise((resolve49, reject) => {
|
|
79798
80267
|
if (signal.aborted) {
|
|
79799
80268
|
reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
79800
80269
|
return;
|
|
79801
80270
|
}
|
|
79802
|
-
const timeoutId = setTimeout(
|
|
80271
|
+
const timeoutId = setTimeout(resolve49, interval);
|
|
79803
80272
|
signal.addEventListener("abort", () => {
|
|
79804
80273
|
clearTimeout(timeoutId);
|
|
79805
80274
|
reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
@@ -80589,7 +81058,7 @@ var Server = class extends Protocol {
|
|
|
80589
81058
|
};
|
|
80590
81059
|
|
|
80591
81060
|
// src/mcp/server.ts
|
|
80592
|
-
var
|
|
81061
|
+
var path61 = __toESM(require("path"));
|
|
80593
81062
|
|
|
80594
81063
|
// node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
|
|
80595
81064
|
var import_node_process3 = __toESM(require("node:process"), 1);
|
|
@@ -80672,12 +81141,12 @@ var StdioServerTransport = class {
|
|
|
80672
81141
|
this.onclose?.();
|
|
80673
81142
|
}
|
|
80674
81143
|
send(message) {
|
|
80675
|
-
return new Promise((
|
|
81144
|
+
return new Promise((resolve49) => {
|
|
80676
81145
|
const json = serializeMessage(message);
|
|
80677
81146
|
if (this._stdout.write(json)) {
|
|
80678
|
-
|
|
81147
|
+
resolve49();
|
|
80679
81148
|
} else {
|
|
80680
|
-
this._stdout.once("drain",
|
|
81149
|
+
this._stdout.once("drain", resolve49);
|
|
80681
81150
|
}
|
|
80682
81151
|
});
|
|
80683
81152
|
}
|
|
@@ -81232,7 +81701,7 @@ async function handleMcpToolCall(toolName, args, defaultRepo = ".") {
|
|
|
81232
81701
|
const input = ControlUpInputSchema.parse({ ...args, repo });
|
|
81233
81702
|
const result = await startControlAndSync({
|
|
81234
81703
|
detach: input.detach,
|
|
81235
|
-
cwd:
|
|
81704
|
+
cwd: path61.resolve(input.repo)
|
|
81236
81705
|
});
|
|
81237
81706
|
if (result.code !== 0) {
|
|
81238
81707
|
return {
|
|
@@ -81296,11 +81765,11 @@ var mcpCommand = {
|
|
|
81296
81765
|
};
|
|
81297
81766
|
|
|
81298
81767
|
// src/cli/commands/onboard.ts
|
|
81299
|
-
var
|
|
81768
|
+
var path63 = __toESM(require("path"));
|
|
81300
81769
|
init_stages();
|
|
81301
81770
|
|
|
81302
81771
|
// src/core/onboarding.ts
|
|
81303
|
-
var
|
|
81772
|
+
var path62 = __toESM(require("path"));
|
|
81304
81773
|
init_control_config();
|
|
81305
81774
|
init_control_sync();
|
|
81306
81775
|
init_otel_hooks();
|
|
@@ -81345,7 +81814,8 @@ function listPluginChoices() {
|
|
|
81345
81814
|
return listPluginIds().map((id) => {
|
|
81346
81815
|
try {
|
|
81347
81816
|
const manifest = readPluginManifest(id);
|
|
81348
|
-
const
|
|
81817
|
+
const stages = normalizePluginStages(manifest);
|
|
81818
|
+
const description = typeof stages[0]?.description === "string" ? stages[0].description : `Adds stage ${primaryStageId(manifest)}`;
|
|
81349
81819
|
return {
|
|
81350
81820
|
id,
|
|
81351
81821
|
label: `${id} \u2014 ${description}`,
|
|
@@ -81435,7 +81905,7 @@ async function defaultEnsureControl(options) {
|
|
|
81435
81905
|
return { started: true, apiUrl: result.apiUrl };
|
|
81436
81906
|
}
|
|
81437
81907
|
async function runOnboarding(options, deps = {}) {
|
|
81438
|
-
const repoPath =
|
|
81908
|
+
const repoPath = path62.resolve(options.repoPath);
|
|
81439
81909
|
const applyTelemetry = deps.applyTelemetry ?? applyOnboardingTelemetry;
|
|
81440
81910
|
const ensureControl = deps.ensureControl ?? defaultEnsureControl;
|
|
81441
81911
|
const init = deps.initHarness ?? initHarness;
|
|
@@ -81623,7 +82093,7 @@ async function promptChoices(args) {
|
|
|
81623
82093
|
};
|
|
81624
82094
|
}
|
|
81625
82095
|
const pluginChoices = listPluginChoices();
|
|
81626
|
-
const repoPath =
|
|
82096
|
+
const repoPath = path63.resolve(args.repo);
|
|
81627
82097
|
const alreadyPresent = harnessExists(repoPath);
|
|
81628
82098
|
const needProfile = !alreadyPresent && !args.skipInit && args.profile === void 0;
|
|
81629
82099
|
const needAgentSlots = shouldConfigureSlots && flaggedSlots === void 0;
|
|
@@ -81740,7 +82210,7 @@ function printSummary(result) {
|
|
|
81740
82210
|
console.error("");
|
|
81741
82211
|
}
|
|
81742
82212
|
async function handleOnboard(argv) {
|
|
81743
|
-
const repoPath =
|
|
82213
|
+
const repoPath = path63.resolve(argv.repo);
|
|
81744
82214
|
header("har onboard");
|
|
81745
82215
|
info(`Repository: ${repoPath}`);
|
|
81746
82216
|
try {
|
|
@@ -81971,7 +82441,7 @@ var preferencesCommand = {
|
|
|
81971
82441
|
};
|
|
81972
82442
|
|
|
81973
82443
|
// src/cli/commands/telemetry.ts
|
|
81974
|
-
var
|
|
82444
|
+
var path64 = __toESM(require("path"));
|
|
81975
82445
|
init_control_config();
|
|
81976
82446
|
init_control_sync();
|
|
81977
82447
|
init_manifest();
|
|
@@ -82064,7 +82534,7 @@ async function handleOff() {
|
|
|
82064
82534
|
info("Mission Control will not auto-start. Existing usage rows are kept.");
|
|
82065
82535
|
}
|
|
82066
82536
|
async function handleWriteEnv(argv) {
|
|
82067
|
-
const repoPath =
|
|
82537
|
+
const repoPath = path64.resolve(argv.repo);
|
|
82068
82538
|
const harnessRoot = resolveHarnessRoot(repoPath);
|
|
82069
82539
|
const session = readSlotRegistry(harnessRoot, argv.agentId);
|
|
82070
82540
|
const workDir = argv.workDir ?? session?.workDir ?? repoPath;
|
|
@@ -82076,7 +82546,7 @@ async function handleWriteEnv(argv) {
|
|
|
82076
82546
|
suffix,
|
|
82077
82547
|
createdAt: session?.createdAt
|
|
82078
82548
|
});
|
|
82079
|
-
const envFile = argv.envFile ??
|
|
82549
|
+
const envFile = argv.envFile ?? path64.join(workDir, `.env.agent.${argv.agentId}`);
|
|
82080
82550
|
const attrs = {
|
|
82081
82551
|
sessionKey,
|
|
82082
82552
|
agentId: argv.agentId,
|
|
@@ -82092,7 +82562,7 @@ async function handleWriteEnv(argv) {
|
|
|
82092
82562
|
success(`Wrote session attribution to ${envFile}`);
|
|
82093
82563
|
}
|
|
82094
82564
|
function handlePrintEnv(argv) {
|
|
82095
|
-
const repoPath =
|
|
82565
|
+
const repoPath = path64.resolve(argv.repo);
|
|
82096
82566
|
const workDir = argv.workDir ?? repoPath;
|
|
82097
82567
|
const sessionKey = buildSessionKey({
|
|
82098
82568
|
branch: argv.branch,
|