@osfactory/har 1.0.0-rc.1 → 1.0.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +587 -523
- package/dist/templates/adaptation-prompt-plugin.md +40 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -593,8 +593,8 @@ var init_parseUtil = __esm({
|
|
|
593
593
|
init_errors();
|
|
594
594
|
init_en();
|
|
595
595
|
makeIssue = (params) => {
|
|
596
|
-
const { data, path:
|
|
597
|
-
const fullPath = [...
|
|
596
|
+
const { data, path: path89, errorMaps, issueData } = params;
|
|
597
|
+
const fullPath = [...path89, ...issueData.path || []];
|
|
598
598
|
const fullIssue = {
|
|
599
599
|
...issueData,
|
|
600
600
|
path: fullPath
|
|
@@ -902,11 +902,11 @@ var init_types = __esm({
|
|
|
902
902
|
init_parseUtil();
|
|
903
903
|
init_util();
|
|
904
904
|
ParseInputLazyPath = class {
|
|
905
|
-
constructor(parent, value,
|
|
905
|
+
constructor(parent, value, path89, key) {
|
|
906
906
|
this._cachedPath = [];
|
|
907
907
|
this.parent = parent;
|
|
908
908
|
this.data = value;
|
|
909
|
-
this._path =
|
|
909
|
+
this._path = path89;
|
|
910
910
|
this._key = key;
|
|
911
911
|
}
|
|
912
912
|
get path() {
|
|
@@ -31543,8 +31543,8 @@ var init_parseUtil2 = __esm({
|
|
|
31543
31543
|
init_errors2();
|
|
31544
31544
|
init_en2();
|
|
31545
31545
|
makeIssue2 = (params) => {
|
|
31546
|
-
const { data, path:
|
|
31547
|
-
const fullPath = [...
|
|
31546
|
+
const { data, path: path89, errorMaps, issueData } = params;
|
|
31547
|
+
const fullPath = [...path89, ...issueData.path || []];
|
|
31548
31548
|
const fullIssue = {
|
|
31549
31549
|
...issueData,
|
|
31550
31550
|
path: fullPath
|
|
@@ -31852,11 +31852,11 @@ var init_types2 = __esm({
|
|
|
31852
31852
|
init_parseUtil2();
|
|
31853
31853
|
init_util2();
|
|
31854
31854
|
ParseInputLazyPath2 = class {
|
|
31855
|
-
constructor(parent, value,
|
|
31855
|
+
constructor(parent, value, path89, key) {
|
|
31856
31856
|
this._cachedPath = [];
|
|
31857
31857
|
this.parent = parent;
|
|
31858
31858
|
this.data = value;
|
|
31859
|
-
this._path =
|
|
31859
|
+
this._path = path89;
|
|
31860
31860
|
this._key = key;
|
|
31861
31861
|
}
|
|
31862
31862
|
get path() {
|
|
@@ -38852,16 +38852,16 @@ var init_local_executor = __esm({
|
|
|
38852
38852
|
const walk = (dir, prefix) => {
|
|
38853
38853
|
for (const entry of fs35.readdirSync(dir, { withFileTypes: true })) {
|
|
38854
38854
|
const full = path36.join(dir, entry.name);
|
|
38855
|
-
const
|
|
38855
|
+
const relative5 = path36.join(prefix, entry.name);
|
|
38856
38856
|
if (entry.isDirectory()) {
|
|
38857
|
-
walk(full,
|
|
38857
|
+
walk(full, relative5);
|
|
38858
38858
|
continue;
|
|
38859
38859
|
}
|
|
38860
|
-
if (filter2?.stageId && !
|
|
38860
|
+
if (filter2?.stageId && !relative5.includes(filter2.stageId)) continue;
|
|
38861
38861
|
const stat = fs35.statSync(full);
|
|
38862
38862
|
entries.push({
|
|
38863
38863
|
path: full,
|
|
38864
|
-
relativePath:
|
|
38864
|
+
relativePath: relative5,
|
|
38865
38865
|
sizeBytes: stat.size,
|
|
38866
38866
|
modifiedAt: stat.mtime.toISOString()
|
|
38867
38867
|
});
|
|
@@ -43100,15 +43100,15 @@ var require_route = __commonJS({
|
|
|
43100
43100
|
};
|
|
43101
43101
|
}
|
|
43102
43102
|
function wrapConversion(toModel, graph) {
|
|
43103
|
-
const
|
|
43103
|
+
const path89 = [graph[toModel].parent, toModel];
|
|
43104
43104
|
let fn = conversions[graph[toModel].parent][toModel];
|
|
43105
43105
|
let cur = graph[toModel].parent;
|
|
43106
43106
|
while (graph[cur].parent) {
|
|
43107
|
-
|
|
43107
|
+
path89.unshift(graph[cur].parent);
|
|
43108
43108
|
fn = link(conversions[graph[cur].parent][cur], fn);
|
|
43109
43109
|
cur = graph[cur].parent;
|
|
43110
43110
|
}
|
|
43111
|
-
fn.conversion =
|
|
43111
|
+
fn.conversion = path89;
|
|
43112
43112
|
return fn;
|
|
43113
43113
|
}
|
|
43114
43114
|
module2.exports = function(fromModel) {
|
|
@@ -49038,7 +49038,7 @@ var require_iso2022 = __commonJS({
|
|
|
49038
49038
|
// node_modules/chardet/index.js
|
|
49039
49039
|
var require_chardet = __commonJS({
|
|
49040
49040
|
"node_modules/chardet/index.js"(exports2, module2) {
|
|
49041
|
-
var
|
|
49041
|
+
var fs75 = require("fs");
|
|
49042
49042
|
var utf8 = require_utf8();
|
|
49043
49043
|
var unicode = require_unicode();
|
|
49044
49044
|
var mbcs = require_mbcs();
|
|
@@ -49112,28 +49112,28 @@ var require_chardet = __commonJS({
|
|
|
49112
49112
|
var fd;
|
|
49113
49113
|
var handler = function(err, buffer) {
|
|
49114
49114
|
if (fd) {
|
|
49115
|
-
|
|
49115
|
+
fs75.closeSync(fd);
|
|
49116
49116
|
}
|
|
49117
49117
|
if (err) return cb(err, null);
|
|
49118
49118
|
cb(null, self.detect(buffer, opts));
|
|
49119
49119
|
};
|
|
49120
49120
|
if (opts && opts.sampleSize) {
|
|
49121
|
-
fd =
|
|
49122
|
-
|
|
49121
|
+
fd = fs75.openSync(filepath, "r"), sample = Buffer.allocUnsafe(opts.sampleSize);
|
|
49122
|
+
fs75.read(fd, sample, 0, opts.sampleSize, null, function(err) {
|
|
49123
49123
|
handler(err, sample);
|
|
49124
49124
|
});
|
|
49125
49125
|
return;
|
|
49126
49126
|
}
|
|
49127
|
-
|
|
49127
|
+
fs75.readFile(filepath, handler);
|
|
49128
49128
|
};
|
|
49129
49129
|
module2.exports.detectFileSync = function(filepath, opts) {
|
|
49130
49130
|
if (opts && opts.sampleSize) {
|
|
49131
|
-
var fd =
|
|
49132
|
-
|
|
49133
|
-
|
|
49131
|
+
var fd = fs75.openSync(filepath, "r"), sample2 = Buffer.allocUnsafe(opts.sampleSize);
|
|
49132
|
+
fs75.readSync(fd, sample2, 0, opts.sampleSize);
|
|
49133
|
+
fs75.closeSync(fd);
|
|
49134
49134
|
return self.detect(sample2, opts);
|
|
49135
49135
|
}
|
|
49136
|
-
return self.detect(
|
|
49136
|
+
return self.detect(fs75.readFileSync(filepath), opts);
|
|
49137
49137
|
};
|
|
49138
49138
|
module2.exports.detectAll = function(buffer, opts) {
|
|
49139
49139
|
if (typeof opts !== "object") {
|
|
@@ -52598,16 +52598,16 @@ var require_os_tmpdir = __commonJS({
|
|
|
52598
52598
|
var isWindows = process.platform === "win32";
|
|
52599
52599
|
var trailingSlashRe = isWindows ? /[^:]\\$/ : /.\/$/;
|
|
52600
52600
|
module2.exports = function() {
|
|
52601
|
-
var
|
|
52601
|
+
var path89;
|
|
52602
52602
|
if (isWindows) {
|
|
52603
|
-
|
|
52603
|
+
path89 = process.env.TEMP || process.env.TMP || (process.env.SystemRoot || process.env.windir) + "\\temp";
|
|
52604
52604
|
} else {
|
|
52605
|
-
|
|
52605
|
+
path89 = process.env.TMPDIR || process.env.TMP || process.env.TEMP || "/tmp";
|
|
52606
52606
|
}
|
|
52607
|
-
if (trailingSlashRe.test(
|
|
52608
|
-
|
|
52607
|
+
if (trailingSlashRe.test(path89)) {
|
|
52608
|
+
path89 = path89.slice(0, -1);
|
|
52609
52609
|
}
|
|
52610
|
-
return
|
|
52610
|
+
return path89;
|
|
52611
52611
|
};
|
|
52612
52612
|
}
|
|
52613
52613
|
});
|
|
@@ -52615,8 +52615,8 @@ var require_os_tmpdir = __commonJS({
|
|
|
52615
52615
|
// node_modules/tmp/lib/tmp.js
|
|
52616
52616
|
var require_tmp = __commonJS({
|
|
52617
52617
|
"node_modules/tmp/lib/tmp.js"(exports2, module2) {
|
|
52618
|
-
var
|
|
52619
|
-
var
|
|
52618
|
+
var fs75 = require("fs");
|
|
52619
|
+
var path89 = require("path");
|
|
52620
52620
|
var crypto8 = require("crypto");
|
|
52621
52621
|
var osTmpDir = require_os_tmpdir();
|
|
52622
52622
|
var _c2 = process.binding("constants");
|
|
@@ -52658,7 +52658,7 @@ var require_tmp = __commonJS({
|
|
|
52658
52658
|
}
|
|
52659
52659
|
function _generateTmpName(opts) {
|
|
52660
52660
|
if (opts.name) {
|
|
52661
|
-
return
|
|
52661
|
+
return path89.join(opts.dir || tmpDir, opts.name);
|
|
52662
52662
|
}
|
|
52663
52663
|
if (opts.template) {
|
|
52664
52664
|
return opts.template.replace(TEMPLATE_PATTERN, _randomChars(6));
|
|
@@ -52669,7 +52669,7 @@ var require_tmp = __commonJS({
|
|
|
52669
52669
|
_randomChars(12),
|
|
52670
52670
|
opts.postfix || ""
|
|
52671
52671
|
].join("");
|
|
52672
|
-
return
|
|
52672
|
+
return path89.join(opts.dir || tmpDir, name);
|
|
52673
52673
|
}
|
|
52674
52674
|
function tmpName(options, callback) {
|
|
52675
52675
|
var args = _parseArguments(options, callback), opts = args[0], cb = args[1], tries = opts.name ? 1 : opts.tries || DEFAULT_TRIES;
|
|
@@ -52679,7 +52679,7 @@ var require_tmp = __commonJS({
|
|
|
52679
52679
|
return cb(new Error("Invalid template provided"));
|
|
52680
52680
|
(function _getUniqueName() {
|
|
52681
52681
|
const name = _generateTmpName(opts);
|
|
52682
|
-
|
|
52682
|
+
fs75.stat(name, function(err) {
|
|
52683
52683
|
if (!err) {
|
|
52684
52684
|
if (tries-- > 0) return _getUniqueName();
|
|
52685
52685
|
return cb(new Error("Could not get a unique tmp filename, max tries reached " + name));
|
|
@@ -52697,7 +52697,7 @@ var require_tmp = __commonJS({
|
|
|
52697
52697
|
do {
|
|
52698
52698
|
const name = _generateTmpName(opts);
|
|
52699
52699
|
try {
|
|
52700
|
-
|
|
52700
|
+
fs75.statSync(name);
|
|
52701
52701
|
} catch (e) {
|
|
52702
52702
|
return name;
|
|
52703
52703
|
}
|
|
@@ -52709,13 +52709,13 @@ var require_tmp = __commonJS({
|
|
|
52709
52709
|
opts.postfix = _isUndefined(opts.postfix) ? ".tmp" : opts.postfix;
|
|
52710
52710
|
tmpName(opts, function _tmpNameCreated(err, name) {
|
|
52711
52711
|
if (err) return cb(err);
|
|
52712
|
-
|
|
52712
|
+
fs75.open(name, CREATE_FLAGS, opts.mode || FILE_MODE, function _fileCreated(err2, fd) {
|
|
52713
52713
|
if (err2) return cb(err2);
|
|
52714
52714
|
if (opts.discardDescriptor) {
|
|
52715
|
-
return
|
|
52715
|
+
return fs75.close(fd, function _discardCallback(err3) {
|
|
52716
52716
|
if (err3) {
|
|
52717
52717
|
try {
|
|
52718
|
-
|
|
52718
|
+
fs75.unlinkSync(name);
|
|
52719
52719
|
} catch (e) {
|
|
52720
52720
|
if (!isENOENT(e)) {
|
|
52721
52721
|
err3 = e;
|
|
@@ -52738,9 +52738,9 @@ var require_tmp = __commonJS({
|
|
|
52738
52738
|
opts.postfix = opts.postfix || ".tmp";
|
|
52739
52739
|
const discardOrDetachDescriptor = opts.discardDescriptor || opts.detachDescriptor;
|
|
52740
52740
|
const name = tmpNameSync(opts);
|
|
52741
|
-
var fd =
|
|
52741
|
+
var fd = fs75.openSync(name, CREATE_FLAGS, opts.mode || FILE_MODE);
|
|
52742
52742
|
if (opts.discardDescriptor) {
|
|
52743
|
-
|
|
52743
|
+
fs75.closeSync(fd);
|
|
52744
52744
|
fd = void 0;
|
|
52745
52745
|
}
|
|
52746
52746
|
return {
|
|
@@ -52752,9 +52752,9 @@ var require_tmp = __commonJS({
|
|
|
52752
52752
|
function _rmdirRecursiveSync(root) {
|
|
52753
52753
|
const dirs = [root];
|
|
52754
52754
|
do {
|
|
52755
|
-
var dir2 = dirs.pop(), deferred = false, files =
|
|
52755
|
+
var dir2 = dirs.pop(), deferred = false, files = fs75.readdirSync(dir2);
|
|
52756
52756
|
for (var i = 0, length = files.length; i < length; i++) {
|
|
52757
|
-
var file2 =
|
|
52757
|
+
var file2 = path89.join(dir2, files[i]), stat = fs75.lstatSync(file2);
|
|
52758
52758
|
if (stat.isDirectory()) {
|
|
52759
52759
|
if (!deferred) {
|
|
52760
52760
|
deferred = true;
|
|
@@ -52762,11 +52762,11 @@ var require_tmp = __commonJS({
|
|
|
52762
52762
|
}
|
|
52763
52763
|
dirs.push(file2);
|
|
52764
52764
|
} else {
|
|
52765
|
-
|
|
52765
|
+
fs75.unlinkSync(file2);
|
|
52766
52766
|
}
|
|
52767
52767
|
}
|
|
52768
52768
|
if (!deferred) {
|
|
52769
|
-
|
|
52769
|
+
fs75.rmdirSync(dir2);
|
|
52770
52770
|
}
|
|
52771
52771
|
} while (dirs.length !== 0);
|
|
52772
52772
|
}
|
|
@@ -52774,7 +52774,7 @@ var require_tmp = __commonJS({
|
|
|
52774
52774
|
var args = _parseArguments(options, callback), opts = args[0], cb = args[1];
|
|
52775
52775
|
tmpName(opts, function _tmpNameCreated(err, name) {
|
|
52776
52776
|
if (err) return cb(err);
|
|
52777
|
-
|
|
52777
|
+
fs75.mkdir(name, opts.mode || DIR_MODE, function _dirCreated(err2) {
|
|
52778
52778
|
if (err2) return cb(err2);
|
|
52779
52779
|
cb(null, name, _prepareTmpDirRemoveCallback(name, opts));
|
|
52780
52780
|
});
|
|
@@ -52783,7 +52783,7 @@ var require_tmp = __commonJS({
|
|
|
52783
52783
|
function dirSync(options) {
|
|
52784
52784
|
var args = _parseArguments(options), opts = args[0];
|
|
52785
52785
|
const name = tmpNameSync(opts);
|
|
52786
|
-
|
|
52786
|
+
fs75.mkdirSync(name, opts.mode || DIR_MODE);
|
|
52787
52787
|
return {
|
|
52788
52788
|
name,
|
|
52789
52789
|
removeCallback: _prepareTmpDirRemoveCallback(name, opts)
|
|
@@ -52793,7 +52793,7 @@ var require_tmp = __commonJS({
|
|
|
52793
52793
|
const removeCallback = _prepareRemoveCallback(function _removeCallback(fdPath) {
|
|
52794
52794
|
try {
|
|
52795
52795
|
if (0 <= fdPath[0]) {
|
|
52796
|
-
|
|
52796
|
+
fs75.closeSync(fdPath[0]);
|
|
52797
52797
|
}
|
|
52798
52798
|
} catch (e) {
|
|
52799
52799
|
if (!isEBADF(e) && !isENOENT(e)) {
|
|
@@ -52801,7 +52801,7 @@ var require_tmp = __commonJS({
|
|
|
52801
52801
|
}
|
|
52802
52802
|
}
|
|
52803
52803
|
try {
|
|
52804
|
-
|
|
52804
|
+
fs75.unlinkSync(fdPath[1]);
|
|
52805
52805
|
} catch (e) {
|
|
52806
52806
|
if (!isENOENT(e)) {
|
|
52807
52807
|
throw e;
|
|
@@ -52814,7 +52814,7 @@ var require_tmp = __commonJS({
|
|
|
52814
52814
|
return removeCallback;
|
|
52815
52815
|
}
|
|
52816
52816
|
function _prepareTmpDirRemoveCallback(name, opts) {
|
|
52817
|
-
const removeFunction = opts.unsafeCleanup ? _rmdirRecursiveSync :
|
|
52817
|
+
const removeFunction = opts.unsafeCleanup ? _rmdirRecursiveSync : fs75.rmdirSync.bind(fs75);
|
|
52818
52818
|
const removeCallback = _prepareRemoveCallback(removeFunction, name);
|
|
52819
52819
|
if (!opts.keep) {
|
|
52820
52820
|
_removeObjects.unshift(removeCallback);
|
|
@@ -62773,32 +62773,32 @@ __export(otel_hooks_exports, {
|
|
|
62773
62773
|
});
|
|
62774
62774
|
function getOtelHooksHome() {
|
|
62775
62775
|
if (process.env.HAR_OTEL_HOOKS_HOME) {
|
|
62776
|
-
return
|
|
62776
|
+
return path71.resolve(process.env.HAR_OTEL_HOOKS_HOME);
|
|
62777
62777
|
}
|
|
62778
|
-
return
|
|
62778
|
+
return path71.join(os21.homedir(), ".har", "otel-hooks");
|
|
62779
62779
|
}
|
|
62780
62780
|
function getOtelHooksConfigPath(hooksHome = getOtelHooksHome()) {
|
|
62781
|
-
return
|
|
62781
|
+
return path71.join(hooksHome, "otel_config.json");
|
|
62782
62782
|
}
|
|
62783
62783
|
function getOtelHooksWrapperPath(hooksHome = getOtelHooksHome()) {
|
|
62784
|
-
return
|
|
62784
|
+
return path71.join(hooksHome, "run-otel-hook.sh");
|
|
62785
62785
|
}
|
|
62786
62786
|
function getOtelHooksStateDir(hooksHome = getOtelHooksHome()) {
|
|
62787
|
-
return
|
|
62787
|
+
return path71.join(hooksHome, "state");
|
|
62788
62788
|
}
|
|
62789
62789
|
function localOtelHookBin(hooksHome) {
|
|
62790
|
-
return
|
|
62790
|
+
return path71.join(hooksHome, "node_modules", ".bin", "otel-hook");
|
|
62791
62791
|
}
|
|
62792
62792
|
function installedPackageVersion(hooksHome) {
|
|
62793
62793
|
try {
|
|
62794
|
-
const pkgPath =
|
|
62794
|
+
const pkgPath = path71.join(
|
|
62795
62795
|
hooksHome,
|
|
62796
62796
|
"node_modules",
|
|
62797
62797
|
"@osfactory",
|
|
62798
62798
|
"otel-hook",
|
|
62799
62799
|
"package.json"
|
|
62800
62800
|
);
|
|
62801
|
-
const pkg = JSON.parse(
|
|
62801
|
+
const pkg = JSON.parse(fs65.readFileSync(pkgPath, "utf8"));
|
|
62802
62802
|
return typeof pkg.version === "string" ? pkg.version : null;
|
|
62803
62803
|
} catch {
|
|
62804
62804
|
return null;
|
|
@@ -62849,15 +62849,15 @@ function buildOtelHooksConfig(options) {
|
|
|
62849
62849
|
};
|
|
62850
62850
|
}
|
|
62851
62851
|
function writeOtelHooksConfig(config2, hooksHome = getOtelHooksHome()) {
|
|
62852
|
-
|
|
62852
|
+
fs65.mkdirSync(hooksHome, { recursive: true });
|
|
62853
62853
|
const configPath = getOtelHooksConfigPath(hooksHome);
|
|
62854
|
-
|
|
62854
|
+
fs65.writeFileSync(configPath, `${JSON.stringify(config2, null, 2)}
|
|
62855
62855
|
`);
|
|
62856
62856
|
return configPath;
|
|
62857
62857
|
}
|
|
62858
62858
|
function writeOtelHooksWrapper(otelHookCommand, hooksHome = getOtelHooksHome()) {
|
|
62859
|
-
|
|
62860
|
-
|
|
62859
|
+
fs65.mkdirSync(hooksHome, { recursive: true });
|
|
62860
|
+
fs65.mkdirSync(getOtelHooksStateDir(hooksHome), { recursive: true });
|
|
62861
62861
|
const wrapperPath = getOtelHooksWrapperPath(hooksHome);
|
|
62862
62862
|
const configPath = getOtelHooksConfigPath(hooksHome);
|
|
62863
62863
|
const stateDir = getOtelHooksStateDir(hooksHome);
|
|
@@ -62869,9 +62869,9 @@ exec "${otelHookCommand}" run \\
|
|
|
62869
62869
|
--state-dir "${stateDir}" \\
|
|
62870
62870
|
"$@"
|
|
62871
62871
|
`;
|
|
62872
|
-
|
|
62872
|
+
fs65.writeFileSync(wrapperPath, script, { mode: 493 });
|
|
62873
62873
|
try {
|
|
62874
|
-
|
|
62874
|
+
fs65.chmodSync(wrapperPath, 493);
|
|
62875
62875
|
} catch {
|
|
62876
62876
|
}
|
|
62877
62877
|
return wrapperPath;
|
|
@@ -62884,7 +62884,7 @@ function commandExists3(command2) {
|
|
|
62884
62884
|
}
|
|
62885
62885
|
function resolveOtelHookCommand(hooksHome) {
|
|
62886
62886
|
const local = localOtelHookBin(hooksHome);
|
|
62887
|
-
if (
|
|
62887
|
+
if (fs65.existsSync(local)) return local;
|
|
62888
62888
|
return null;
|
|
62889
62889
|
}
|
|
62890
62890
|
function resolveHooksInstaller(hooksHome) {
|
|
@@ -62899,7 +62899,7 @@ function resolveHooksInstaller(hooksHome) {
|
|
|
62899
62899
|
return candidates.find((candidate) => commandExists3(candidate.command)) ?? null;
|
|
62900
62900
|
}
|
|
62901
62901
|
function tryInstallPackage(hooksHome) {
|
|
62902
|
-
|
|
62902
|
+
fs65.mkdirSync(hooksHome, { recursive: true });
|
|
62903
62903
|
const installer = resolveHooksInstaller(hooksHome);
|
|
62904
62904
|
if (!installer) {
|
|
62905
62905
|
return {
|
|
@@ -62912,7 +62912,7 @@ function tryInstallPackage(hooksHome) {
|
|
|
62912
62912
|
encoding: "utf8",
|
|
62913
62913
|
timeout: 18e4
|
|
62914
62914
|
});
|
|
62915
|
-
if (result.status === 0 &&
|
|
62915
|
+
if (result.status === 0 && fs65.existsSync(localOtelHookBin(hooksHome))) {
|
|
62916
62916
|
return { ok: true, detail: described };
|
|
62917
62917
|
}
|
|
62918
62918
|
return {
|
|
@@ -62938,14 +62938,14 @@ function uninstallLegacyPythonHooks(hooksHome) {
|
|
|
62938
62938
|
}
|
|
62939
62939
|
function removeLegacyPythonArtifacts(hooksHome) {
|
|
62940
62940
|
const legacyPaths = [
|
|
62941
|
-
|
|
62942
|
-
|
|
62943
|
-
|
|
62941
|
+
path71.join(hooksHome, ".venv"),
|
|
62942
|
+
path71.join(hooksHome, "otel_config.yaml"),
|
|
62943
|
+
path71.join(hooksHome, "venv")
|
|
62944
62944
|
];
|
|
62945
62945
|
for (const target of legacyPaths) {
|
|
62946
62946
|
try {
|
|
62947
|
-
if (
|
|
62948
|
-
|
|
62947
|
+
if (fs65.existsSync(target)) {
|
|
62948
|
+
fs65.rmSync(target, { recursive: true, force: true });
|
|
62949
62949
|
}
|
|
62950
62950
|
} catch {
|
|
62951
62951
|
}
|
|
@@ -62986,10 +62986,10 @@ function runSetupProvider(providerId, otelHookCommand, wrapperPath) {
|
|
|
62986
62986
|
};
|
|
62987
62987
|
}
|
|
62988
62988
|
function rewriteHookCommandsToWrapper(filePath, wrapperPath) {
|
|
62989
|
-
if (!
|
|
62989
|
+
if (!fs65.existsSync(filePath)) return false;
|
|
62990
62990
|
let raw;
|
|
62991
62991
|
try {
|
|
62992
|
-
raw =
|
|
62992
|
+
raw = fs65.readFileSync(filePath, "utf8");
|
|
62993
62993
|
} catch {
|
|
62994
62994
|
return false;
|
|
62995
62995
|
}
|
|
@@ -63036,15 +63036,15 @@ function rewriteHookCommandsToWrapper(filePath, wrapperPath) {
|
|
|
63036
63036
|
return changed;
|
|
63037
63037
|
};
|
|
63038
63038
|
if (!walk(parsed)) return false;
|
|
63039
|
-
|
|
63039
|
+
fs65.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
|
|
63040
63040
|
`);
|
|
63041
63041
|
return true;
|
|
63042
63042
|
}
|
|
63043
63043
|
function pruneLegacyCursorHookEvents(filePath, wrapperPath) {
|
|
63044
|
-
if (!
|
|
63044
|
+
if (!fs65.existsSync(filePath)) return false;
|
|
63045
63045
|
let raw;
|
|
63046
63046
|
try {
|
|
63047
|
-
raw =
|
|
63047
|
+
raw = fs65.readFileSync(filePath, "utf8");
|
|
63048
63048
|
} catch {
|
|
63049
63049
|
return false;
|
|
63050
63050
|
}
|
|
@@ -63079,21 +63079,21 @@ function pruneLegacyCursorHookEvents(filePath, wrapperPath) {
|
|
|
63079
63079
|
}
|
|
63080
63080
|
}
|
|
63081
63081
|
if (!changed) return false;
|
|
63082
|
-
|
|
63082
|
+
fs65.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
|
|
63083
63083
|
`);
|
|
63084
63084
|
return true;
|
|
63085
63085
|
}
|
|
63086
63086
|
function rewriteKnownHookRegistrations(wrapperPath) {
|
|
63087
63087
|
const home = os21.homedir();
|
|
63088
63088
|
const candidates = [
|
|
63089
|
-
|
|
63090
|
-
|
|
63091
|
-
|
|
63089
|
+
path71.join(home, ".cursor", "hooks.json"),
|
|
63090
|
+
path71.join(home, ".claude", "settings.json"),
|
|
63091
|
+
path71.join(home, ".codex", "hooks.json")
|
|
63092
63092
|
];
|
|
63093
63093
|
for (const filePath of candidates) {
|
|
63094
63094
|
try {
|
|
63095
63095
|
rewriteHookCommandsToWrapper(filePath, wrapperPath);
|
|
63096
|
-
if (filePath.endsWith(`${
|
|
63096
|
+
if (filePath.endsWith(`${path71.sep}.cursor${path71.sep}hooks.json`)) {
|
|
63097
63097
|
pruneLegacyCursorHookEvents(filePath, wrapperPath);
|
|
63098
63098
|
}
|
|
63099
63099
|
} catch {
|
|
@@ -63109,7 +63109,7 @@ function ensureOtelHooks(options) {
|
|
|
63109
63109
|
const hooksHome = getOtelHooksHome();
|
|
63110
63110
|
const errors = [];
|
|
63111
63111
|
const providersSetup = [];
|
|
63112
|
-
|
|
63112
|
+
fs65.mkdirSync(hooksHome, { recursive: true });
|
|
63113
63113
|
let otelHookCommand = resolveOtelHookCommand(hooksHome);
|
|
63114
63114
|
const needsInstall = !otelHookCommand || installedPackageVersion(hooksHome) !== pinnedVersion();
|
|
63115
63115
|
if (needsInstall) {
|
|
@@ -63203,14 +63203,14 @@ function ensureOtelHooks(options) {
|
|
|
63203
63203
|
function disableOtelHooksExport() {
|
|
63204
63204
|
return writeOtelHooksConfig(buildOtelHooksConfig({ enabled: false }));
|
|
63205
63205
|
}
|
|
63206
|
-
var import_child_process18,
|
|
63206
|
+
var import_child_process18, fs65, os21, path71, OTEL_HOOKS_PACKAGE, OTEL_HOOKS_PROVIDERS, OTEL_HOOKS_AGENTS, LEGACY_CURSOR_ONLY_HOOK_EVENTS;
|
|
63207
63207
|
var init_otel_hooks = __esm({
|
|
63208
63208
|
"src/core/otel-hooks.ts"() {
|
|
63209
63209
|
"use strict";
|
|
63210
63210
|
import_child_process18 = require("child_process");
|
|
63211
|
-
|
|
63211
|
+
fs65 = __toESM(require("fs"));
|
|
63212
63212
|
os21 = __toESM(require("os"));
|
|
63213
|
-
|
|
63213
|
+
path71 = __toESM(require("path"));
|
|
63214
63214
|
init_control_config();
|
|
63215
63215
|
init_telemetry_config();
|
|
63216
63216
|
OTEL_HOOKS_PACKAGE = "@osfactory/otel-hook@0.2.0";
|
|
@@ -66430,8 +66430,8 @@ var require_utils = __commonJS({
|
|
|
66430
66430
|
}
|
|
66431
66431
|
return ind;
|
|
66432
66432
|
}
|
|
66433
|
-
function removeDotSegments(
|
|
66434
|
-
let input =
|
|
66433
|
+
function removeDotSegments(path89) {
|
|
66434
|
+
let input = path89;
|
|
66435
66435
|
const output = [];
|
|
66436
66436
|
let nextSlash = -1;
|
|
66437
66437
|
let len = 0;
|
|
@@ -66683,8 +66683,8 @@ var require_schemes = __commonJS({
|
|
|
66683
66683
|
wsComponent.secure = void 0;
|
|
66684
66684
|
}
|
|
66685
66685
|
if (wsComponent.resourceName) {
|
|
66686
|
-
const [
|
|
66687
|
-
wsComponent.path =
|
|
66686
|
+
const [path89, query] = wsComponent.resourceName.split("?");
|
|
66687
|
+
wsComponent.path = path89 && path89 !== "/" ? path89 : void 0;
|
|
66688
66688
|
wsComponent.query = query;
|
|
66689
66689
|
wsComponent.resourceName = void 0;
|
|
66690
66690
|
}
|
|
@@ -66849,49 +66849,49 @@ var require_fast_uri = __commonJS({
|
|
|
66849
66849
|
schemelessOptions.skipEscape = true;
|
|
66850
66850
|
return serialize(resolved, schemelessOptions);
|
|
66851
66851
|
}
|
|
66852
|
-
function resolveComponent(base,
|
|
66852
|
+
function resolveComponent(base, relative5, options, skipNormalization) {
|
|
66853
66853
|
const target = {};
|
|
66854
66854
|
if (!skipNormalization) {
|
|
66855
66855
|
base = parse4(serialize(base, options), options);
|
|
66856
|
-
|
|
66856
|
+
relative5 = parse4(serialize(relative5, options), options);
|
|
66857
66857
|
}
|
|
66858
66858
|
options = options || {};
|
|
66859
|
-
if (!options.tolerant &&
|
|
66860
|
-
target.scheme =
|
|
66861
|
-
target.userinfo =
|
|
66862
|
-
target.host =
|
|
66863
|
-
target.port =
|
|
66864
|
-
target.path = removeDotSegments(
|
|
66865
|
-
target.query =
|
|
66859
|
+
if (!options.tolerant && relative5.scheme) {
|
|
66860
|
+
target.scheme = relative5.scheme;
|
|
66861
|
+
target.userinfo = relative5.userinfo;
|
|
66862
|
+
target.host = relative5.host;
|
|
66863
|
+
target.port = relative5.port;
|
|
66864
|
+
target.path = removeDotSegments(relative5.path || "");
|
|
66865
|
+
target.query = relative5.query;
|
|
66866
66866
|
} else {
|
|
66867
|
-
if (
|
|
66868
|
-
target.userinfo =
|
|
66869
|
-
target.host =
|
|
66870
|
-
target.port =
|
|
66871
|
-
target.path = removeDotSegments(
|
|
66872
|
-
target.query =
|
|
66867
|
+
if (relative5.userinfo !== void 0 || relative5.host !== void 0 || relative5.port !== void 0) {
|
|
66868
|
+
target.userinfo = relative5.userinfo;
|
|
66869
|
+
target.host = relative5.host;
|
|
66870
|
+
target.port = relative5.port;
|
|
66871
|
+
target.path = removeDotSegments(relative5.path || "");
|
|
66872
|
+
target.query = relative5.query;
|
|
66873
66873
|
} else {
|
|
66874
|
-
if (!
|
|
66874
|
+
if (!relative5.path) {
|
|
66875
66875
|
target.path = base.path;
|
|
66876
|
-
if (
|
|
66877
|
-
target.query =
|
|
66876
|
+
if (relative5.query !== void 0) {
|
|
66877
|
+
target.query = relative5.query;
|
|
66878
66878
|
} else {
|
|
66879
66879
|
target.query = base.query;
|
|
66880
66880
|
}
|
|
66881
66881
|
} else {
|
|
66882
|
-
if (
|
|
66883
|
-
target.path = removeDotSegments(
|
|
66882
|
+
if (relative5.path[0] === "/") {
|
|
66883
|
+
target.path = removeDotSegments(relative5.path);
|
|
66884
66884
|
} else {
|
|
66885
66885
|
if ((base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0) && !base.path) {
|
|
66886
|
-
target.path = "/" +
|
|
66886
|
+
target.path = "/" + relative5.path;
|
|
66887
66887
|
} else if (!base.path) {
|
|
66888
|
-
target.path =
|
|
66888
|
+
target.path = relative5.path;
|
|
66889
66889
|
} else {
|
|
66890
|
-
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) +
|
|
66890
|
+
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative5.path;
|
|
66891
66891
|
}
|
|
66892
66892
|
target.path = removeDotSegments(target.path);
|
|
66893
66893
|
}
|
|
66894
|
-
target.query =
|
|
66894
|
+
target.query = relative5.query;
|
|
66895
66895
|
}
|
|
66896
66896
|
target.userinfo = base.userinfo;
|
|
66897
66897
|
target.host = base.host;
|
|
@@ -66899,7 +66899,7 @@ var require_fast_uri = __commonJS({
|
|
|
66899
66899
|
}
|
|
66900
66900
|
target.scheme = base.scheme;
|
|
66901
66901
|
}
|
|
66902
|
-
target.fragment =
|
|
66902
|
+
target.fragment = relative5.fragment;
|
|
66903
66903
|
return target;
|
|
66904
66904
|
}
|
|
66905
66905
|
function equal(uriA, uriB, options) {
|
|
@@ -70077,12 +70077,12 @@ var require_dist = __commonJS({
|
|
|
70077
70077
|
throw new Error(`Unknown format "${name}"`);
|
|
70078
70078
|
return f;
|
|
70079
70079
|
};
|
|
70080
|
-
function addFormats(ajv, list,
|
|
70080
|
+
function addFormats(ajv, list, fs75, exportName) {
|
|
70081
70081
|
var _a2;
|
|
70082
70082
|
var _b2;
|
|
70083
70083
|
(_a2 = (_b2 = ajv.opts.code).formats) !== null && _a2 !== void 0 ? _a2 : _b2.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
|
|
70084
70084
|
for (const f of list)
|
|
70085
|
-
ajv.addFormat(f,
|
|
70085
|
+
ajv.addFormat(f, fs75[f]);
|
|
70086
70086
|
}
|
|
70087
70087
|
module2.exports = exports2 = formatsPlugin;
|
|
70088
70088
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -71366,11 +71366,11 @@ var parser = new YargsParser({
|
|
|
71366
71366
|
resolve: import_path2.resolve,
|
|
71367
71367
|
// TODO: figure out a way to combine ESM and CJS coverage, such that
|
|
71368
71368
|
// we can exercise all the lines below:
|
|
71369
|
-
require: (
|
|
71369
|
+
require: (path89) => {
|
|
71370
71370
|
if (typeof require !== "undefined") {
|
|
71371
|
-
return require(
|
|
71372
|
-
} else if (
|
|
71373
|
-
return JSON.parse((0, import_fs2.readFileSync)(
|
|
71371
|
+
return require(path89);
|
|
71372
|
+
} else if (path89.match(/\.json$/)) {
|
|
71373
|
+
return JSON.parse((0, import_fs2.readFileSync)(path89, "utf8"));
|
|
71374
71374
|
} else {
|
|
71375
71375
|
throw Error("only .json config files are supported in ESM");
|
|
71376
71376
|
}
|
|
@@ -75240,7 +75240,8 @@ function handleRemove(argv) {
|
|
|
75240
75240
|
}
|
|
75241
75241
|
|
|
75242
75242
|
// src/cli/commands/env.ts
|
|
75243
|
-
var
|
|
75243
|
+
var fs68 = __toESM(require("fs"));
|
|
75244
|
+
var path75 = __toESM(require("path"));
|
|
75244
75245
|
|
|
75245
75246
|
// src/cli/finish-command.ts
|
|
75246
75247
|
init_sync_context();
|
|
@@ -75250,8 +75251,8 @@ async function finishCommand(code) {
|
|
|
75250
75251
|
}
|
|
75251
75252
|
|
|
75252
75253
|
// src/core/harness.ts
|
|
75253
|
-
var
|
|
75254
|
-
var
|
|
75254
|
+
var fs62 = __toESM(require("fs"));
|
|
75255
|
+
var path67 = __toESM(require("path"));
|
|
75255
75256
|
|
|
75256
75257
|
// src/harness/generator.ts
|
|
75257
75258
|
var fs47 = __toESM(require("fs"));
|
|
@@ -77717,9 +77718,9 @@ var import_run_async = __toESM(require_run_async(), 1);
|
|
|
77717
77718
|
var import_mute_stream2 = __toESM(require_lib(), 1);
|
|
77718
77719
|
var import_ansi_escapes5 = __toESM(require_ansi_escapes(), 1);
|
|
77719
77720
|
var _ = {
|
|
77720
|
-
set: (obj,
|
|
77721
|
+
set: (obj, path89 = "", value) => {
|
|
77721
77722
|
let pointer = obj;
|
|
77722
|
-
|
|
77723
|
+
path89.split(".").forEach((key, index, arr) => {
|
|
77723
77724
|
if (key === "__proto__" || key === "constructor")
|
|
77724
77725
|
return;
|
|
77725
77726
|
if (index === arr.length - 1) {
|
|
@@ -77730,8 +77731,8 @@ var _ = {
|
|
|
77730
77731
|
pointer = pointer[key];
|
|
77731
77732
|
});
|
|
77732
77733
|
},
|
|
77733
|
-
get: (obj,
|
|
77734
|
-
const travel = (regexp) => String.prototype.split.call(
|
|
77734
|
+
get: (obj, path89 = "", defaultValue) => {
|
|
77735
|
+
const travel = (regexp) => String.prototype.split.call(path89, regexp).filter(Boolean).reduce(
|
|
77735
77736
|
// @ts-expect-error implicit any on res[key]
|
|
77736
77737
|
(res, key) => res !== null && res !== void 0 ? res[key] : res,
|
|
77737
77738
|
obj
|
|
@@ -78836,21 +78837,21 @@ async function smokeTestHarness(repoPath) {
|
|
|
78836
78837
|
}
|
|
78837
78838
|
|
|
78838
78839
|
// src/harness/maintain-bundle.ts
|
|
78839
|
-
var
|
|
78840
|
+
var fs57 = __toESM(require("fs"));
|
|
78840
78841
|
var os20 = __toESM(require("os"));
|
|
78841
|
-
var
|
|
78842
|
+
var path62 = __toESM(require("path"));
|
|
78842
78843
|
init_file_ops();
|
|
78843
78844
|
init_shell();
|
|
78844
78845
|
init_manifest();
|
|
78845
78846
|
|
|
78846
78847
|
// src/harness/plugin-drift.ts
|
|
78847
|
-
var
|
|
78848
|
-
var
|
|
78848
|
+
var fs56 = __toESM(require("fs"));
|
|
78849
|
+
var path61 = __toESM(require("path"));
|
|
78849
78850
|
init_manifest();
|
|
78850
78851
|
|
|
78851
78852
|
// src/harness/plugins.ts
|
|
78852
|
-
var
|
|
78853
|
-
var
|
|
78853
|
+
var fs55 = __toESM(require("fs"));
|
|
78854
|
+
var path60 = __toESM(require("path"));
|
|
78854
78855
|
init_zod2();
|
|
78855
78856
|
init_logging();
|
|
78856
78857
|
init_paths();
|
|
@@ -79114,6 +79115,55 @@ function cleanupResolvedPlugin(source) {
|
|
|
79114
79115
|
}
|
|
79115
79116
|
}
|
|
79116
79117
|
|
|
79118
|
+
// src/harness/plugin-prompt.ts
|
|
79119
|
+
var fs54 = __toESM(require("fs"));
|
|
79120
|
+
var path59 = __toESM(require("path"));
|
|
79121
|
+
init_paths();
|
|
79122
|
+
init_file_ops();
|
|
79123
|
+
init_node_pm();
|
|
79124
|
+
init_manifest();
|
|
79125
|
+
init_env();
|
|
79126
|
+
function pluginAdaptationPromptFile(pluginId) {
|
|
79127
|
+
return `ADAPT-PROMPT-${pluginId}.md`;
|
|
79128
|
+
}
|
|
79129
|
+
function loadTemplate() {
|
|
79130
|
+
const filePath = resolveTemplateFile("adaptation-prompt-plugin.md");
|
|
79131
|
+
if (!filePath) {
|
|
79132
|
+
throw new Error(
|
|
79133
|
+
"Plugin adaptation prompt template not found: adaptation-prompt-plugin.md. Run npm run build."
|
|
79134
|
+
);
|
|
79135
|
+
}
|
|
79136
|
+
return fs54.readFileSync(filePath, "utf8");
|
|
79137
|
+
}
|
|
79138
|
+
function resolveInstallCommand(repoPath) {
|
|
79139
|
+
const env3 = readHarnessEnv(repoPath);
|
|
79140
|
+
if (env3.HARNESS_INSTALL_CMD) return env3.HARNESS_INSTALL_CMD;
|
|
79141
|
+
return `${nodePackageManager(repoPath, env3)} install`;
|
|
79142
|
+
}
|
|
79143
|
+
var BARE_INSTALL_RE = /^(npm|pnpm|yarn|bun)\s+install$/;
|
|
79144
|
+
function buildPluginAdaptationPrompt(repoPath, result) {
|
|
79145
|
+
const mergedPackageJson = result.filesWritten.includes("package.json");
|
|
79146
|
+
const installCmd = resolveInstallCommand(repoPath);
|
|
79147
|
+
const packageMergeNote = mergedPackageJson ? [
|
|
79148
|
+
"## Dependencies: merged is NOT installed",
|
|
79149
|
+
"",
|
|
79150
|
+
"The plugin merged new `devDependencies` into `package.json` \u2014 it did **not**",
|
|
79151
|
+
"install them. Install first or every later step fails:",
|
|
79152
|
+
"",
|
|
79153
|
+
"```bash",
|
|
79154
|
+
installCmd,
|
|
79155
|
+
"```"
|
|
79156
|
+
].join("\n") : "## Dependencies\n\nThis plugin merged no package.json fragment \u2014 no dependency install is required.";
|
|
79157
|
+
const setupSteps = result.nextSteps.filter((step) => !(mergedPackageJson && BARE_INSTALL_RE.test(step.trim()))).map((step, i) => `${i + 1}. \`${step}\``).join("\n");
|
|
79158
|
+
const filesWritten = result.filesWritten.filter((f) => f !== "package.json").map((f) => ` - \`${f}\``).join("\n");
|
|
79159
|
+
return loadTemplate().replace(/\{\{PLUGIN_ID\}\}/g, result.pluginId).replace(/\{\{STAGE_IDS\}\}/g, result.stageIds.map((id) => `\`${id}\``).join(", ")).replace(/\{\{DOCS_PATH\}\}/g, result.docsPath).replace("{{PACKAGE_MERGE_NOTE}}", packageMergeNote).replace("{{PLUGIN_SETUP_STEPS}}", setupSteps || "_No plugin-specific setup steps declared._").replace("{{FILES_WRITTEN}}", filesWritten || " - _(no scaffolded files)_");
|
|
79160
|
+
}
|
|
79161
|
+
function writePluginAdaptationPrompt(repoPath, pluginId, content) {
|
|
79162
|
+
const filePath = path59.join(getHarnessDir(repoPath), pluginAdaptationPromptFile(pluginId));
|
|
79163
|
+
writeFileSafe(filePath, content);
|
|
79164
|
+
return filePath;
|
|
79165
|
+
}
|
|
79166
|
+
|
|
79117
79167
|
// src/harness/plugins.ts
|
|
79118
79168
|
init_schema2();
|
|
79119
79169
|
init_stages();
|
|
@@ -79162,19 +79212,19 @@ function primaryStageId(manifest) {
|
|
|
79162
79212
|
return manifest.stageId ?? stages[0].id;
|
|
79163
79213
|
}
|
|
79164
79214
|
function resolveBundledPluginDir(pluginId) {
|
|
79165
|
-
const dir =
|
|
79166
|
-
if (!
|
|
79215
|
+
const dir = path60.join(resolveTemplatesDir(), "plugins", pluginId);
|
|
79216
|
+
if (!fs55.existsSync(dir)) {
|
|
79167
79217
|
throw new Error(`Plugin not found: ${pluginId}. Run npm run build.`);
|
|
79168
79218
|
}
|
|
79169
79219
|
return dir;
|
|
79170
79220
|
}
|
|
79171
79221
|
function readPluginManifestFromDir(pluginDir, expectedId) {
|
|
79172
|
-
const manifestPath =
|
|
79173
|
-
if (!
|
|
79222
|
+
const manifestPath = path60.join(pluginDir, "template.manifest.json");
|
|
79223
|
+
if (!fs55.existsSync(manifestPath)) {
|
|
79174
79224
|
throw new Error(`No template.manifest.json in ${pluginDir}`);
|
|
79175
79225
|
}
|
|
79176
79226
|
const parsed = PluginManifestSchema.safeParse(
|
|
79177
|
-
JSON.parse(
|
|
79227
|
+
JSON.parse(fs55.readFileSync(manifestPath, "utf8"))
|
|
79178
79228
|
);
|
|
79179
79229
|
if (!parsed.success) {
|
|
79180
79230
|
throw new Error(`Invalid plugin manifest: ${parsed.error.message}`);
|
|
@@ -79188,40 +79238,40 @@ function readPluginManifest(pluginId) {
|
|
|
79188
79238
|
return readPluginManifestFromDir(resolveBundledPluginDir(pluginId), pluginId);
|
|
79189
79239
|
}
|
|
79190
79240
|
function ensureParentDir(filePath) {
|
|
79191
|
-
const parent =
|
|
79192
|
-
if (!
|
|
79193
|
-
|
|
79241
|
+
const parent = path60.dirname(filePath);
|
|
79242
|
+
if (!fs55.existsSync(parent)) {
|
|
79243
|
+
fs55.mkdirSync(parent, { recursive: true });
|
|
79194
79244
|
}
|
|
79195
79245
|
}
|
|
79196
79246
|
function copyPluginFile(pluginDir, file, repoPath, force) {
|
|
79197
|
-
const srcPath =
|
|
79198
|
-
const destPath =
|
|
79199
|
-
if (!
|
|
79247
|
+
const srcPath = path60.join(pluginDir, file.src);
|
|
79248
|
+
const destPath = path60.join(repoPath, file.dest);
|
|
79249
|
+
if (!fs55.existsSync(srcPath)) {
|
|
79200
79250
|
throw new Error(`Plugin file missing: ${file.src}`);
|
|
79201
79251
|
}
|
|
79202
|
-
if (
|
|
79252
|
+
if (fs55.existsSync(destPath) && !force) {
|
|
79203
79253
|
throw new Error(
|
|
79204
79254
|
`File already exists: ${file.dest}. Use --force to overwrite or remove it first.`
|
|
79205
79255
|
);
|
|
79206
79256
|
}
|
|
79207
79257
|
ensureParentDir(destPath);
|
|
79208
|
-
|
|
79258
|
+
fs55.copyFileSync(srcPath, destPath);
|
|
79209
79259
|
if (file.executable) {
|
|
79210
|
-
|
|
79260
|
+
fs55.chmodSync(destPath, 493);
|
|
79211
79261
|
}
|
|
79212
79262
|
return { written: true, path: file.dest };
|
|
79213
79263
|
}
|
|
79214
79264
|
function mergePackageJson(repoPath, pluginDir, fragmentRelPath, warnings) {
|
|
79215
|
-
const packagePath =
|
|
79216
|
-
if (!
|
|
79265
|
+
const packagePath = path60.join(repoPath, "package.json");
|
|
79266
|
+
if (!fs55.existsSync(packagePath)) {
|
|
79217
79267
|
throw new Error("No package.json in repo root. Add one before applying this plugin.");
|
|
79218
79268
|
}
|
|
79219
|
-
const fragmentPath =
|
|
79220
|
-
if (!
|
|
79269
|
+
const fragmentPath = path60.join(pluginDir, fragmentRelPath);
|
|
79270
|
+
if (!fs55.existsSync(fragmentPath)) {
|
|
79221
79271
|
throw new Error(`Package fragment missing: ${fragmentRelPath}`);
|
|
79222
79272
|
}
|
|
79223
|
-
const pkg = JSON.parse(
|
|
79224
|
-
const fragment = JSON.parse(
|
|
79273
|
+
const pkg = JSON.parse(fs55.readFileSync(packagePath, "utf8"));
|
|
79274
|
+
const fragment = JSON.parse(fs55.readFileSync(fragmentPath, "utf8"));
|
|
79225
79275
|
for (const section of ["scripts", "devDependencies"]) {
|
|
79226
79276
|
const existing = pkg[section] ?? {};
|
|
79227
79277
|
const incoming = fragment[section] ?? {};
|
|
@@ -79234,7 +79284,7 @@ function mergePackageJson(repoPath, pluginDir, fragmentRelPath, warnings) {
|
|
|
79234
79284
|
}
|
|
79235
79285
|
pkg[section] = existing;
|
|
79236
79286
|
}
|
|
79237
|
-
|
|
79287
|
+
fs55.writeFileSync(packagePath, JSON.stringify(pkg, null, 2) + "\n");
|
|
79238
79288
|
}
|
|
79239
79289
|
function patchStageRegistry(repoPath, stages, verificationStageIds, force) {
|
|
79240
79290
|
const registry2 = readStageRegistry(repoPath);
|
|
@@ -79270,8 +79320,8 @@ function assertStagesNotPresent(repoPath, stageIds, force) {
|
|
|
79270
79320
|
if (force) return;
|
|
79271
79321
|
const registry2 = readStageRegistry(repoPath);
|
|
79272
79322
|
for (const stageId of stageIds) {
|
|
79273
|
-
const scriptPath =
|
|
79274
|
-
if (
|
|
79323
|
+
const scriptPath = path60.join(repoPath, ".har", "stages", `${stageId}.sh`);
|
|
79324
|
+
if (fs55.existsSync(scriptPath)) {
|
|
79275
79325
|
throw new Error(
|
|
79276
79326
|
`Stage script already exists: .har/stages/${stageId}.sh. Use --force to overwrite.`
|
|
79277
79327
|
);
|
|
@@ -79284,7 +79334,7 @@ function assertStagesNotPresent(repoPath, stageIds, force) {
|
|
|
79284
79334
|
}
|
|
79285
79335
|
}
|
|
79286
79336
|
function applyPluginFromDir(repoPath, pluginDir, options, meta) {
|
|
79287
|
-
const resolved =
|
|
79337
|
+
const resolved = path60.resolve(repoPath);
|
|
79288
79338
|
const force = options.force ?? false;
|
|
79289
79339
|
const warnings = [];
|
|
79290
79340
|
const filesWritten = [];
|
|
@@ -79304,7 +79354,7 @@ function applyPluginFromDir(repoPath, pluginDir, options, meta) {
|
|
|
79304
79354
|
if (file.skipFlag === "skipCi" && options.skipCi) {
|
|
79305
79355
|
continue;
|
|
79306
79356
|
}
|
|
79307
|
-
if (
|
|
79357
|
+
if (fs55.existsSync(path60.join(resolved, file.dest)) && !force) {
|
|
79308
79358
|
warnings.push(`Skipped optional file (exists): ${file.dest}`);
|
|
79309
79359
|
continue;
|
|
79310
79360
|
}
|
|
@@ -79330,15 +79380,7 @@ function applyPluginFromDir(repoPath, pluginDir, options, meta) {
|
|
|
79330
79380
|
installedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
79331
79381
|
});
|
|
79332
79382
|
const primary = primaryStageId(manifest);
|
|
79333
|
-
|
|
79334
|
-
info(`Registered stage(s): ${stageIds.join(", ")}`);
|
|
79335
|
-
for (const file of filesWritten) {
|
|
79336
|
-
info(` + ${file}`);
|
|
79337
|
-
}
|
|
79338
|
-
for (const warning of warnings) {
|
|
79339
|
-
warn(` \u26A0 ${warning}`);
|
|
79340
|
-
}
|
|
79341
|
-
return {
|
|
79383
|
+
const partialResult = {
|
|
79342
79384
|
pluginId: manifest.id,
|
|
79343
79385
|
stageId: primary,
|
|
79344
79386
|
stageIds,
|
|
@@ -79348,6 +79390,22 @@ function applyPluginFromDir(repoPath, pluginDir, options, meta) {
|
|
|
79348
79390
|
docsPath: manifest.docsPath,
|
|
79349
79391
|
source: meta.source
|
|
79350
79392
|
};
|
|
79393
|
+
const promptContent = buildPluginAdaptationPrompt(resolved, {
|
|
79394
|
+
...partialResult,
|
|
79395
|
+
adaptPromptPath: ""
|
|
79396
|
+
});
|
|
79397
|
+
const promptAbsPath = writePluginAdaptationPrompt(resolved, manifest.id, promptContent);
|
|
79398
|
+
const adaptPromptPath = path60.relative(resolved, promptAbsPath);
|
|
79399
|
+
success(`Applied plugin: ${manifest.id}`);
|
|
79400
|
+
info(`Registered stage(s): ${stageIds.join(", ")}`);
|
|
79401
|
+
for (const file of filesWritten) {
|
|
79402
|
+
info(` + ${file}`);
|
|
79403
|
+
}
|
|
79404
|
+
info(` + ${adaptPromptPath} (adaptation prompt for your coding agent)`);
|
|
79405
|
+
for (const warning of warnings) {
|
|
79406
|
+
warn(` \u26A0 ${warning}`);
|
|
79407
|
+
}
|
|
79408
|
+
return { ...partialResult, adaptPromptPath };
|
|
79351
79409
|
}
|
|
79352
79410
|
function applyPlugin(repoPath, pluginSpec, options = {}) {
|
|
79353
79411
|
const spec = options.spec ?? pluginSpec;
|
|
@@ -79371,13 +79429,13 @@ init_stages();
|
|
|
79371
79429
|
init_paths();
|
|
79372
79430
|
var PACKAGE_SECTIONS = ["scripts", "devDependencies"];
|
|
79373
79431
|
function detectInstalledPlugins(repoPath) {
|
|
79374
|
-
const resolved =
|
|
79432
|
+
const resolved = path61.resolve(repoPath);
|
|
79375
79433
|
const ledger = readPluginLedger(resolved);
|
|
79376
79434
|
if (ledger && ledger.plugins.length > 0) {
|
|
79377
79435
|
return ledger.plugins.map((p) => p.id).sort();
|
|
79378
79436
|
}
|
|
79379
|
-
const registryPath =
|
|
79380
|
-
if (!
|
|
79437
|
+
const registryPath = path61.join(resolved, ".har", "stages.json");
|
|
79438
|
+
if (!fs56.existsSync(registryPath)) return [];
|
|
79381
79439
|
const registry2 = readStageRegistry(resolved);
|
|
79382
79440
|
const stageIds = new Set(registry2.stages.map((stage) => stage.id));
|
|
79383
79441
|
const installed = [];
|
|
@@ -79394,18 +79452,18 @@ function detectInstalledPlugins(repoPath) {
|
|
|
79394
79452
|
return installed.sort();
|
|
79395
79453
|
}
|
|
79396
79454
|
function resolvePluginBaseline(repoPath, pluginId) {
|
|
79397
|
-
const resolved =
|
|
79455
|
+
const resolved = path61.resolve(repoPath);
|
|
79398
79456
|
const ledger = readPluginLedger(resolved);
|
|
79399
79457
|
const entry = ledger?.plugins.find((p) => p.id === pluginId);
|
|
79400
79458
|
if (entry?.source === "local") {
|
|
79401
|
-
const localDir =
|
|
79402
|
-
if (
|
|
79459
|
+
const localDir = path61.join(resolved, LOCAL_PLUGINS_DIR, pluginId);
|
|
79460
|
+
if (fs56.existsSync(path61.join(localDir, "template.manifest.json"))) {
|
|
79403
79461
|
return { kind: "local", dir: localDir, manifest: readPluginManifestFromDir(localDir) };
|
|
79404
79462
|
}
|
|
79405
79463
|
return null;
|
|
79406
79464
|
}
|
|
79407
|
-
const bundled =
|
|
79408
|
-
if (
|
|
79465
|
+
const bundled = path61.join(resolveTemplatesDir(), "plugins", pluginId);
|
|
79466
|
+
if (fs56.existsSync(path61.join(bundled, "template.manifest.json"))) {
|
|
79409
79467
|
return { kind: "bundled", dir: bundled, manifest: readPluginManifestFromDir(bundled) };
|
|
79410
79468
|
}
|
|
79411
79469
|
return null;
|
|
@@ -79418,14 +79476,14 @@ function requireBaseline(repoPath, pluginId) {
|
|
|
79418
79476
|
return baseline;
|
|
79419
79477
|
}
|
|
79420
79478
|
function readBaselineFile(baseline, srcRel) {
|
|
79421
|
-
return
|
|
79479
|
+
return fs56.readFileSync(path61.join(baseline.dir, srcRel), "utf8");
|
|
79422
79480
|
}
|
|
79423
79481
|
function listPluginDestPaths(baseline, repoPath) {
|
|
79424
79482
|
const manifest = baseline.manifest;
|
|
79425
79483
|
const paths = manifest.files.map((file) => file.dest);
|
|
79426
79484
|
if (manifest.optionalFiles) {
|
|
79427
79485
|
for (const file of manifest.optionalFiles) {
|
|
79428
|
-
if (
|
|
79486
|
+
if (fs56.existsSync(path61.join(repoPath, file.dest))) {
|
|
79429
79487
|
paths.push(file.dest);
|
|
79430
79488
|
}
|
|
79431
79489
|
}
|
|
@@ -79484,9 +79542,9 @@ function readTemplatePluginFile(repoPath, pluginId, dest) {
|
|
|
79484
79542
|
return null;
|
|
79485
79543
|
}
|
|
79486
79544
|
function readInstalledPluginFile(repoPath, pluginId, dest) {
|
|
79487
|
-
const installedPath =
|
|
79488
|
-
if (!
|
|
79489
|
-
const content =
|
|
79545
|
+
const installedPath = path61.join(path61.resolve(repoPath), dest);
|
|
79546
|
+
if (!fs56.existsSync(installedPath)) return null;
|
|
79547
|
+
const content = fs56.readFileSync(installedPath, "utf8");
|
|
79490
79548
|
const baseline = requireBaseline(repoPath, pluginId);
|
|
79491
79549
|
const fragmentRel = baseline.manifest.merge?.[dest];
|
|
79492
79550
|
if (fragmentRel) {
|
|
@@ -79510,7 +79568,7 @@ function pluginActionHint(pluginId, dest, kind, baseline) {
|
|
|
79510
79568
|
return `Merge maintain/plugins/${pluginId}/diffs/${dest}.diff or run: har env add-plugin ${pluginId} --force`;
|
|
79511
79569
|
}
|
|
79512
79570
|
function comparePluginToTemplate(repoPath, pluginId) {
|
|
79513
|
-
const resolved =
|
|
79571
|
+
const resolved = path61.resolve(repoPath);
|
|
79514
79572
|
const baseline = requireBaseline(resolved, pluginId);
|
|
79515
79573
|
const manifest = baseline.manifest;
|
|
79516
79574
|
const destPaths = listPluginDestPaths(baseline, resolved);
|
|
@@ -79527,8 +79585,8 @@ function comparePluginToTemplate(repoPath, pluginId) {
|
|
|
79527
79585
|
}
|
|
79528
79586
|
if (dest === "package.json") {
|
|
79529
79587
|
const fragmentRel = manifest.merge?.[dest];
|
|
79530
|
-
const installedPath =
|
|
79531
|
-
const installedRaw =
|
|
79588
|
+
const installedPath = path61.join(resolved, dest);
|
|
79589
|
+
const installedRaw = fs56.readFileSync(installedPath, "utf8");
|
|
79532
79590
|
if (fragmentRel && pluginKeysMatch(installedRaw, readBaselineFile(baseline, fragmentRel))) {
|
|
79533
79591
|
unchanged.push(dest);
|
|
79534
79592
|
} else if (computeFileChecksum(installedContent) === computeFileChecksum(templateContent)) {
|
|
@@ -79590,7 +79648,7 @@ init_profiles();
|
|
|
79590
79648
|
var MAINTAIN_DIR = "maintain";
|
|
79591
79649
|
var substituteProjectName2 = substituteTemplateTokens;
|
|
79592
79650
|
function projectNameFromRepo(repoPath) {
|
|
79593
|
-
return
|
|
79651
|
+
return path62.basename(repoPath).toLowerCase().replace(/[^a-z0-9]/g, "_");
|
|
79594
79652
|
}
|
|
79595
79653
|
function readBundledTemplateContent(repoPath, profile, file) {
|
|
79596
79654
|
const entry = composeProfileTemplateMap(profile).get(templateFileForHarness(file));
|
|
@@ -79628,12 +79686,12 @@ function actionHint(file, kind) {
|
|
|
79628
79686
|
return `Upstream template updated since your last finalize \u2014 read maintain/diffs/${file}.diff and apply into .har/${file}.`;
|
|
79629
79687
|
}
|
|
79630
79688
|
function createUnifiedDiff(installedContent, templateContent, installedLabel, templateLabel) {
|
|
79631
|
-
const tmpDir =
|
|
79689
|
+
const tmpDir = fs57.mkdtempSync(path62.join(os20.tmpdir(), "har-maintain-diff-"));
|
|
79632
79690
|
try {
|
|
79633
|
-
const installedPath =
|
|
79634
|
-
const templatePath =
|
|
79635
|
-
|
|
79636
|
-
|
|
79691
|
+
const installedPath = path62.join(tmpDir, "installed");
|
|
79692
|
+
const templatePath = path62.join(tmpDir, "template");
|
|
79693
|
+
fs57.writeFileSync(installedPath, installedContent);
|
|
79694
|
+
fs57.writeFileSync(templatePath, templateContent);
|
|
79637
79695
|
const result = run(`diff -u "${installedPath}" "${templatePath}"`);
|
|
79638
79696
|
const body = result.stdout.trim();
|
|
79639
79697
|
if (!body) return "";
|
|
@@ -79642,7 +79700,7 @@ function createUnifiedDiff(installedContent, templateContent, installedLabel, te
|
|
|
79642
79700
|
${body.split("\n").slice(2).join("\n")}
|
|
79643
79701
|
`;
|
|
79644
79702
|
} finally {
|
|
79645
|
-
|
|
79703
|
+
fs57.rmSync(tmpDir, { recursive: true, force: true });
|
|
79646
79704
|
}
|
|
79647
79705
|
}
|
|
79648
79706
|
function buildActions(repoPath, profile, drift) {
|
|
@@ -79661,12 +79719,12 @@ function buildActions(repoPath, profile, drift) {
|
|
|
79661
79719
|
...drift.conflict.map((f) => [f, "conflict"])
|
|
79662
79720
|
];
|
|
79663
79721
|
for (const [file, kind] of upstreamAffected) {
|
|
79664
|
-
const installedPath =
|
|
79722
|
+
const installedPath = path62.join(harnessDir, file);
|
|
79665
79723
|
actions.push({
|
|
79666
79724
|
file,
|
|
79667
79725
|
kind,
|
|
79668
79726
|
template: `maintain/templates/${file}`,
|
|
79669
|
-
installed:
|
|
79727
|
+
installed: fs57.existsSync(installedPath) ? `maintain/installed/${file}` : void 0,
|
|
79670
79728
|
diff: `maintain/diffs/${file}.diff`,
|
|
79671
79729
|
hint: actionHint(file, kind)
|
|
79672
79730
|
});
|
|
@@ -79837,28 +79895,28 @@ function buildReadme(report) {
|
|
|
79837
79895
|
}
|
|
79838
79896
|
function writeBundleArtifacts(repoPath, profile, drift, report) {
|
|
79839
79897
|
const harnessDir = getHarnessDir(repoPath);
|
|
79840
|
-
const bundleDir =
|
|
79841
|
-
if (
|
|
79842
|
-
|
|
79898
|
+
const bundleDir = path62.join(harnessDir, MAINTAIN_DIR);
|
|
79899
|
+
if (fs57.existsSync(bundleDir)) {
|
|
79900
|
+
fs57.rmSync(bundleDir, { recursive: true, force: true });
|
|
79843
79901
|
}
|
|
79844
79902
|
const dirs = [
|
|
79845
79903
|
bundleDir,
|
|
79846
|
-
|
|
79847
|
-
|
|
79848
|
-
|
|
79849
|
-
|
|
79904
|
+
path62.join(bundleDir, "templates"),
|
|
79905
|
+
path62.join(bundleDir, "installed"),
|
|
79906
|
+
path62.join(bundleDir, "diffs"),
|
|
79907
|
+
path62.join(bundleDir, "stale")
|
|
79850
79908
|
];
|
|
79851
79909
|
for (const dir of dirs) {
|
|
79852
|
-
|
|
79910
|
+
fs57.mkdirSync(dir, { recursive: true });
|
|
79853
79911
|
}
|
|
79854
79912
|
const affectedFiles = [...drift.missing, ...drift.upstreamUpdated, ...drift.conflict];
|
|
79855
79913
|
for (const file of affectedFiles) {
|
|
79856
79914
|
const templateContent = readBundledTemplateContent(repoPath, profile, file);
|
|
79857
|
-
writeFileSafe(
|
|
79858
|
-
const harnessPath =
|
|
79859
|
-
if (
|
|
79860
|
-
const installedContent =
|
|
79861
|
-
writeFileSafe(
|
|
79915
|
+
writeFileSafe(path62.join(bundleDir, "templates", file), templateContent);
|
|
79916
|
+
const harnessPath = path62.join(harnessDir, file);
|
|
79917
|
+
if (fs57.existsSync(harnessPath)) {
|
|
79918
|
+
const installedContent = fs57.readFileSync(harnessPath, "utf8");
|
|
79919
|
+
writeFileSafe(path62.join(bundleDir, "installed", file), installedContent);
|
|
79862
79920
|
const diff = createUnifiedDiff(
|
|
79863
79921
|
installedContent,
|
|
79864
79922
|
templateContent,
|
|
@@ -79866,14 +79924,14 @@ function writeBundleArtifacts(repoPath, profile, drift, report) {
|
|
|
79866
79924
|
`templates/${file}`
|
|
79867
79925
|
);
|
|
79868
79926
|
if (diff) {
|
|
79869
|
-
writeFileSafe(
|
|
79927
|
+
writeFileSafe(path62.join(bundleDir, "diffs", `${file}.diff`), diff);
|
|
79870
79928
|
}
|
|
79871
79929
|
}
|
|
79872
79930
|
}
|
|
79873
|
-
writeFileSafe(
|
|
79874
|
-
writeFileSafe(
|
|
79931
|
+
writeFileSafe(path62.join(bundleDir, "README.md"), buildReadme(report));
|
|
79932
|
+
writeFileSafe(path62.join(bundleDir, "drift-report.json"), JSON.stringify(report, null, 2) + "\n");
|
|
79875
79933
|
writeFileSafe(
|
|
79876
|
-
|
|
79934
|
+
path62.join(bundleDir, "validation.json"),
|
|
79877
79935
|
JSON.stringify(report.validation, null, 2) + "\n"
|
|
79878
79936
|
);
|
|
79879
79937
|
if (report.stale.length > 0) {
|
|
@@ -79885,34 +79943,34 @@ function writeBundleArtifacts(repoPath, profile, drift, report) {
|
|
|
79885
79943
|
...report.stale.map((s) => `- **${s.file}** \u2014 ${s.hint}`),
|
|
79886
79944
|
""
|
|
79887
79945
|
];
|
|
79888
|
-
writeFileSafe(
|
|
79946
|
+
writeFileSafe(path62.join(bundleDir, "stale", "MANIFEST.md"), staleLines.join("\n"));
|
|
79889
79947
|
}
|
|
79890
79948
|
return bundleDir;
|
|
79891
79949
|
}
|
|
79892
79950
|
function ensureParentDir2(filePath) {
|
|
79893
|
-
const parent =
|
|
79894
|
-
if (!
|
|
79895
|
-
|
|
79951
|
+
const parent = path62.dirname(filePath);
|
|
79952
|
+
if (!fs57.existsSync(parent)) {
|
|
79953
|
+
fs57.mkdirSync(parent, { recursive: true });
|
|
79896
79954
|
}
|
|
79897
79955
|
}
|
|
79898
79956
|
function writePluginBundleArtifacts(repoPath, bundleDir, report) {
|
|
79899
79957
|
if (report.pluginActions.length === 0) return;
|
|
79900
79958
|
for (const action of report.pluginActions) {
|
|
79901
|
-
const pluginRoot =
|
|
79902
|
-
const templatesDir =
|
|
79903
|
-
const installedDir =
|
|
79904
|
-
const diffsDir =
|
|
79959
|
+
const pluginRoot = path62.join(bundleDir, "plugins", action.pluginId);
|
|
79960
|
+
const templatesDir = path62.join(pluginRoot, "templates");
|
|
79961
|
+
const installedDir = path62.join(pluginRoot, "installed");
|
|
79962
|
+
const diffsDir = path62.join(pluginRoot, "diffs");
|
|
79905
79963
|
for (const dir of [templatesDir, installedDir, diffsDir]) {
|
|
79906
|
-
|
|
79964
|
+
fs57.mkdirSync(dir, { recursive: true });
|
|
79907
79965
|
}
|
|
79908
79966
|
const templateContent = readTemplatePluginFile(repoPath, action.pluginId, action.file);
|
|
79909
79967
|
if (templateContent === null) continue;
|
|
79910
|
-
const templatePath =
|
|
79968
|
+
const templatePath = path62.join(templatesDir, action.file);
|
|
79911
79969
|
ensureParentDir2(templatePath);
|
|
79912
79970
|
writeFileSafe(templatePath, templateContent);
|
|
79913
79971
|
const installedContent = readInstalledPluginFile(repoPath, action.pluginId, action.file);
|
|
79914
79972
|
if (installedContent !== null) {
|
|
79915
|
-
const installedPath =
|
|
79973
|
+
const installedPath = path62.join(installedDir, action.file);
|
|
79916
79974
|
ensureParentDir2(installedPath);
|
|
79917
79975
|
writeFileSafe(installedPath, installedContent);
|
|
79918
79976
|
const diff = createUnifiedDiff(
|
|
@@ -79922,7 +79980,7 @@ function writePluginBundleArtifacts(repoPath, bundleDir, report) {
|
|
|
79922
79980
|
`templates/${action.file}`
|
|
79923
79981
|
);
|
|
79924
79982
|
if (diff) {
|
|
79925
|
-
const diffPath =
|
|
79983
|
+
const diffPath = path62.join(diffsDir, `${action.file}.diff`);
|
|
79926
79984
|
ensureParentDir2(diffPath);
|
|
79927
79985
|
writeFileSafe(diffPath, diff);
|
|
79928
79986
|
}
|
|
@@ -79958,9 +80016,9 @@ function buildMaintainBundle(repoPath, validation2, drift) {
|
|
|
79958
80016
|
return { bundleDir, report };
|
|
79959
80017
|
}
|
|
79960
80018
|
function removeMaintainBundle(repoPath) {
|
|
79961
|
-
const bundleDir =
|
|
79962
|
-
if (
|
|
79963
|
-
|
|
80019
|
+
const bundleDir = path62.join(getHarnessDir(repoPath), MAINTAIN_DIR);
|
|
80020
|
+
if (fs57.existsSync(bundleDir)) {
|
|
80021
|
+
fs57.rmSync(bundleDir, { recursive: true, force: true });
|
|
79964
80022
|
}
|
|
79965
80023
|
}
|
|
79966
80024
|
function formatMaintainBundlePromptSection(report) {
|
|
@@ -80069,13 +80127,13 @@ init_manifest();
|
|
|
80069
80127
|
init_stages();
|
|
80070
80128
|
|
|
80071
80129
|
// src/harness/doctor.ts
|
|
80072
|
-
var
|
|
80073
|
-
var
|
|
80130
|
+
var fs59 = __toESM(require("fs"));
|
|
80131
|
+
var path64 = __toESM(require("path"));
|
|
80074
80132
|
init_slot_registry();
|
|
80075
80133
|
|
|
80076
80134
|
// src/harness/eject.ts
|
|
80077
|
-
var
|
|
80078
|
-
var
|
|
80135
|
+
var fs58 = __toESM(require("fs"));
|
|
80136
|
+
var path63 = __toESM(require("path"));
|
|
80079
80137
|
init_package_version();
|
|
80080
80138
|
init_manifest();
|
|
80081
80139
|
init_profiles();
|
|
@@ -80083,16 +80141,16 @@ var EJECTED_RUNTIME_DIR = "runtime";
|
|
|
80083
80141
|
var EJECTED_RUNTIME_BUNDLE = "har.cjs";
|
|
80084
80142
|
function resolveRuntimeBundleSource() {
|
|
80085
80143
|
if (process.env.HAR_EJECT_RUNTIME_SOURCE) {
|
|
80086
|
-
return
|
|
80144
|
+
return fs58.existsSync(process.env.HAR_EJECT_RUNTIME_SOURCE) ? process.env.HAR_EJECT_RUNTIME_SOURCE : null;
|
|
80087
80145
|
}
|
|
80088
80146
|
const candidates = [
|
|
80089
80147
|
// Bundled CLI: __dirname is dist/ and index.js is the self-contained runtime.
|
|
80090
|
-
|
|
80148
|
+
path63.join(__dirname, "index.js"),
|
|
80091
80149
|
// Dev (tsx src/…): fall back to a previously built dist/ at the repo root.
|
|
80092
|
-
|
|
80150
|
+
path63.resolve(__dirname, "..", "..", "dist", "index.js")
|
|
80093
80151
|
];
|
|
80094
80152
|
for (const candidate of candidates) {
|
|
80095
|
-
if (
|
|
80153
|
+
if (fs58.existsSync(candidate)) return candidate;
|
|
80096
80154
|
}
|
|
80097
80155
|
return null;
|
|
80098
80156
|
}
|
|
@@ -80139,7 +80197,7 @@ Return to managed shims (removes this directory, regenerates \`.har/*.sh\`):
|
|
|
80139
80197
|
|
|
80140
80198
|
`;
|
|
80141
80199
|
function ejectHarness(repoPath) {
|
|
80142
|
-
const resolved =
|
|
80200
|
+
const resolved = path63.resolve(repoPath);
|
|
80143
80201
|
const harnessDir = getHarnessDir(resolved);
|
|
80144
80202
|
const manifest = readManifest(resolved);
|
|
80145
80203
|
if (!manifest) {
|
|
@@ -80157,12 +80215,12 @@ function ejectHarness(repoPath) {
|
|
|
80157
80215
|
const version2 = getHarPackageVersion();
|
|
80158
80216
|
const profile = manifest.profile ?? "default";
|
|
80159
80217
|
const composed = composeProfileTemplateMap(profile);
|
|
80160
|
-
const runtimeDir =
|
|
80161
|
-
|
|
80162
|
-
const runtimeFile =
|
|
80163
|
-
|
|
80164
|
-
|
|
80165
|
-
|
|
80218
|
+
const runtimeDir = path63.join(harnessDir, EJECTED_RUNTIME_DIR);
|
|
80219
|
+
fs58.mkdirSync(runtimeDir, { recursive: true });
|
|
80220
|
+
const runtimeFile = path63.join(runtimeDir, EJECTED_RUNTIME_BUNDLE);
|
|
80221
|
+
fs58.copyFileSync(bundleSource, runtimeFile);
|
|
80222
|
+
fs58.chmodSync(runtimeFile, 493);
|
|
80223
|
+
fs58.writeFileSync(path63.join(runtimeDir, "README.md"), RUNTIME_README(version2));
|
|
80166
80224
|
const scripts = [];
|
|
80167
80225
|
for (const shim3 of RUNTIME_SHIM_FILES) {
|
|
80168
80226
|
const source = composed.get(shim3);
|
|
@@ -80170,9 +80228,9 @@ function ejectHarness(repoPath) {
|
|
|
80170
80228
|
const templateContent = readComposedTemplateContent(source);
|
|
80171
80229
|
const delegateArgs = shimDelegateArgs(templateContent);
|
|
80172
80230
|
if (!delegateArgs) continue;
|
|
80173
|
-
const scriptPath =
|
|
80174
|
-
|
|
80175
|
-
|
|
80231
|
+
const scriptPath = path63.join(harnessDir, shim3);
|
|
80232
|
+
fs58.writeFileSync(scriptPath, buildEjectedScript(shim3, delegateArgs, usageLine(templateContent), version2));
|
|
80233
|
+
fs58.chmodSync(scriptPath, 493);
|
|
80176
80234
|
scripts.push(shim3);
|
|
80177
80235
|
}
|
|
80178
80236
|
writeManifest(resolved, {
|
|
@@ -80185,7 +80243,7 @@ function ejectHarness(repoPath) {
|
|
|
80185
80243
|
return { scripts, runtimeFile, version: version2 };
|
|
80186
80244
|
}
|
|
80187
80245
|
function adoptHarness(repoPath) {
|
|
80188
|
-
const resolved =
|
|
80246
|
+
const resolved = path63.resolve(repoPath);
|
|
80189
80247
|
const harnessDir = getHarnessDir(resolved);
|
|
80190
80248
|
const manifest = readManifest(resolved);
|
|
80191
80249
|
if (!manifest) {
|
|
@@ -80196,18 +80254,18 @@ function adoptHarness(repoPath) {
|
|
|
80196
80254
|
}
|
|
80197
80255
|
const profile = manifest.profile ?? "default";
|
|
80198
80256
|
const composed = composeProfileTemplateMap(profile);
|
|
80199
|
-
const projectName =
|
|
80257
|
+
const projectName = path63.basename(resolved).toLowerCase().replace(/[^a-z0-9]/g, "_");
|
|
80200
80258
|
const scripts = [];
|
|
80201
80259
|
for (const shim3 of RUNTIME_SHIM_FILES) {
|
|
80202
80260
|
const source = composed.get(shim3);
|
|
80203
80261
|
if (!source) continue;
|
|
80204
80262
|
const rendered = substituteTemplateTokens(readComposedTemplateContent(source), projectName);
|
|
80205
|
-
const scriptPath =
|
|
80206
|
-
|
|
80207
|
-
|
|
80263
|
+
const scriptPath = path63.join(harnessDir, shim3);
|
|
80264
|
+
fs58.writeFileSync(scriptPath, rendered);
|
|
80265
|
+
fs58.chmodSync(scriptPath, 493);
|
|
80208
80266
|
scripts.push(shim3);
|
|
80209
80267
|
}
|
|
80210
|
-
|
|
80268
|
+
fs58.rmSync(path63.join(harnessDir, EJECTED_RUNTIME_DIR), { recursive: true, force: true });
|
|
80211
80269
|
const rest = { ...manifest };
|
|
80212
80270
|
delete rest.ejected;
|
|
80213
80271
|
delete rest.ejectedVersion;
|
|
@@ -80238,27 +80296,27 @@ var CHECK_LABELS = {
|
|
|
80238
80296
|
var PRE_1_0_FUNCTION_RE = /^\s*(har_infra_enabled|har_pg|har_node_[a-z_]+|har_pkg_exec)\s*\(\)/m;
|
|
80239
80297
|
var LEGACY_TRIPLET_RE = /^export\s+HARNESS_[A-Z0-9_]+_PORT_(DEFAULT|SCAN_START|SCAN_END)=/m;
|
|
80240
80298
|
function detectContract(harnessDir) {
|
|
80241
|
-
const envPath =
|
|
80242
|
-
if (!
|
|
80243
|
-
const content =
|
|
80299
|
+
const envPath = path64.join(harnessDir, "harness.env");
|
|
80300
|
+
if (!fs59.existsSync(envPath)) return "none";
|
|
80301
|
+
const content = fs59.readFileSync(envPath, "utf8");
|
|
80244
80302
|
if (PRE_1_0_FUNCTION_RE.test(content) || LEGACY_TRIPLET_RE.test(content)) {
|
|
80245
80303
|
return "pre-1.0";
|
|
80246
80304
|
}
|
|
80247
80305
|
return "1.0";
|
|
80248
80306
|
}
|
|
80249
80307
|
function resolveStageFile(harnessDir, stage) {
|
|
80250
|
-
if (stage.script) return
|
|
80308
|
+
if (stage.script) return path64.join(harnessDir, stage.script);
|
|
80251
80309
|
if (stage.command) {
|
|
80252
80310
|
const first = stage.command.trim().split(/\s+/)[0];
|
|
80253
80311
|
if (first.startsWith("./.har/")) {
|
|
80254
|
-
return
|
|
80312
|
+
return path64.join(harnessDir, first.replace(/^\.\/\.har\//, ""));
|
|
80255
80313
|
}
|
|
80256
80314
|
if (first.startsWith(".har/")) {
|
|
80257
|
-
return
|
|
80315
|
+
return path64.join(harnessDir, first.replace(/^\.har\//, ""));
|
|
80258
80316
|
}
|
|
80259
80317
|
return null;
|
|
80260
80318
|
}
|
|
80261
|
-
return
|
|
80319
|
+
return path64.join(harnessDir, "stages", `${stage.id}.sh`);
|
|
80262
80320
|
}
|
|
80263
80321
|
function checkStatus(findings, id) {
|
|
80264
80322
|
const mine = findings.filter((f) => f.check === id);
|
|
@@ -80270,7 +80328,7 @@ function runDoctor(repoPath) {
|
|
|
80270
80328
|
const harnessDir = getHarnessDir(repoPath);
|
|
80271
80329
|
const findings = [];
|
|
80272
80330
|
const skipped = /* @__PURE__ */ new Set();
|
|
80273
|
-
if (!
|
|
80331
|
+
if (!fs59.existsSync(harnessDir)) {
|
|
80274
80332
|
return {
|
|
80275
80333
|
ok: false,
|
|
80276
80334
|
contract: "none",
|
|
@@ -80317,9 +80375,9 @@ function runDoctor(repoPath) {
|
|
|
80317
80375
|
}
|
|
80318
80376
|
let registry2 = null;
|
|
80319
80377
|
try {
|
|
80320
|
-
const stagesPath =
|
|
80321
|
-
if (
|
|
80322
|
-
const raw = JSON.parse(
|
|
80378
|
+
const stagesPath = path64.join(harnessDir, "stages.json");
|
|
80379
|
+
if (fs59.existsSync(stagesPath)) {
|
|
80380
|
+
const raw = JSON.parse(fs59.readFileSync(stagesPath, "utf8"));
|
|
80323
80381
|
if (typeof raw !== "object" || raw === null || !Array.isArray(raw.stages)) {
|
|
80324
80382
|
throw new Error("stages.json has no `stages` array \u2014 the registry is structurally invalid");
|
|
80325
80383
|
}
|
|
@@ -80350,8 +80408,8 @@ function runDoctor(repoPath) {
|
|
|
80350
80408
|
for (const stage of registry2.stages) {
|
|
80351
80409
|
const file = resolveStageFile(harnessDir, stage);
|
|
80352
80410
|
if (!file) continue;
|
|
80353
|
-
const rel =
|
|
80354
|
-
if (!
|
|
80411
|
+
const rel = path64.relative(harnessDir, file);
|
|
80412
|
+
if (!fs59.existsSync(file)) {
|
|
80355
80413
|
findings.push({
|
|
80356
80414
|
check: "stage-files",
|
|
80357
80415
|
severity: contractSeverity,
|
|
@@ -80361,7 +80419,7 @@ function runDoctor(repoPath) {
|
|
|
80361
80419
|
});
|
|
80362
80420
|
continue;
|
|
80363
80421
|
}
|
|
80364
|
-
if (rel.endsWith(".sh") && !(
|
|
80422
|
+
if (rel.endsWith(".sh") && !(fs59.statSync(file).mode & 73)) {
|
|
80365
80423
|
findings.push({
|
|
80366
80424
|
check: "stage-files",
|
|
80367
80425
|
severity: "warning",
|
|
@@ -80384,13 +80442,13 @@ function runDoctor(repoPath) {
|
|
|
80384
80442
|
continue;
|
|
80385
80443
|
}
|
|
80386
80444
|
const file = resolveStageFile(harnessDir, stage);
|
|
80387
|
-
if (file && !
|
|
80445
|
+
if (file && !fs59.existsSync(file)) {
|
|
80388
80446
|
findings.push({
|
|
80389
80447
|
check: "lifecycle-stages",
|
|
80390
80448
|
severity: contractSeverity,
|
|
80391
|
-
file:
|
|
80449
|
+
file: path64.relative(harnessDir, file),
|
|
80392
80450
|
message: `Lifecycle stage \`${stage.id}\` (${kind}) points at a missing file`,
|
|
80393
|
-
remedy: `Restore .har/${
|
|
80451
|
+
remedy: `Restore .har/${path64.relative(harnessDir, file)} or fix the \`${stage.id}\` entry in stages.json`
|
|
80394
80452
|
});
|
|
80395
80453
|
}
|
|
80396
80454
|
}
|
|
@@ -80435,9 +80493,9 @@ function runDoctor(repoPath) {
|
|
|
80435
80493
|
if (!manifest?.ejected) {
|
|
80436
80494
|
skipped.add("ejected-runtime");
|
|
80437
80495
|
} else {
|
|
80438
|
-
const runtimeRel =
|
|
80439
|
-
const runtimePath =
|
|
80440
|
-
if (!
|
|
80496
|
+
const runtimeRel = path64.join(EJECTED_RUNTIME_DIR, EJECTED_RUNTIME_BUNDLE);
|
|
80497
|
+
const runtimePath = path64.join(harnessDir, runtimeRel);
|
|
80498
|
+
if (!fs59.existsSync(runtimePath)) {
|
|
80441
80499
|
findings.push({
|
|
80442
80500
|
check: "ejected-runtime",
|
|
80443
80501
|
severity: "error",
|
|
@@ -80447,9 +80505,9 @@ function runDoctor(repoPath) {
|
|
|
80447
80505
|
});
|
|
80448
80506
|
}
|
|
80449
80507
|
for (const shim3 of RUNTIME_SHIM_FILES) {
|
|
80450
|
-
const shimPath =
|
|
80451
|
-
if (!
|
|
80452
|
-
if (!(
|
|
80508
|
+
const shimPath = path64.join(harnessDir, shim3);
|
|
80509
|
+
if (!fs59.existsSync(shimPath)) continue;
|
|
80510
|
+
if (!(fs59.statSync(shimPath).mode & 73)) {
|
|
80453
80511
|
findings.push({
|
|
80454
80512
|
check: "ejected-runtime",
|
|
80455
80513
|
severity: "warning",
|
|
@@ -80463,7 +80521,7 @@ function runDoctor(repoPath) {
|
|
|
80463
80521
|
for (const entry of listSlotRegistryEntries(repoPath)) {
|
|
80464
80522
|
if (entry.status === "completed") continue;
|
|
80465
80523
|
const dir = entry.worktreePath ?? entry.workDir;
|
|
80466
|
-
if (dir && !
|
|
80524
|
+
if (dir && !fs59.existsSync(dir)) {
|
|
80467
80525
|
findings.push({
|
|
80468
80526
|
check: "slot-registry",
|
|
80469
80527
|
severity: "warning",
|
|
@@ -80473,11 +80531,11 @@ function runDoctor(repoPath) {
|
|
|
80473
80531
|
});
|
|
80474
80532
|
}
|
|
80475
80533
|
}
|
|
80476
|
-
const hooksDir =
|
|
80477
|
-
if (
|
|
80478
|
-
for (const file of
|
|
80479
|
-
const full =
|
|
80480
|
-
if (!
|
|
80534
|
+
const hooksDir = path64.join(harnessDir, "hooks");
|
|
80535
|
+
if (fs59.existsSync(hooksDir)) {
|
|
80536
|
+
for (const file of fs59.readdirSync(hooksDir).sort()) {
|
|
80537
|
+
const full = path64.join(hooksDir, file);
|
|
80538
|
+
if (!fs59.statSync(full).isFile() || !file.endsWith(".sh")) continue;
|
|
80481
80539
|
if (!LIFECYCLE_HOOKS.includes(file.replace(/\.sh$/, ""))) {
|
|
80482
80540
|
findings.push({
|
|
80483
80541
|
check: "hooks",
|
|
@@ -80488,7 +80546,7 @@ function runDoctor(repoPath) {
|
|
|
80488
80546
|
});
|
|
80489
80547
|
continue;
|
|
80490
80548
|
}
|
|
80491
|
-
if (!(
|
|
80549
|
+
if (!(fs59.statSync(full).mode & 73)) {
|
|
80492
80550
|
findings.push({
|
|
80493
80551
|
check: "hooks",
|
|
80494
80552
|
severity: "warning",
|
|
@@ -80544,16 +80602,16 @@ function summarizeDoctorReport(report) {
|
|
|
80544
80602
|
}
|
|
80545
80603
|
|
|
80546
80604
|
// src/harness/migrations.ts
|
|
80547
|
-
var
|
|
80548
|
-
var
|
|
80605
|
+
var fs60 = __toESM(require("fs"));
|
|
80606
|
+
var path65 = __toESM(require("path"));
|
|
80549
80607
|
init_schema2();
|
|
80550
80608
|
init_manifest();
|
|
80551
80609
|
init_profiles();
|
|
80552
80610
|
init_stages();
|
|
80553
80611
|
init_manifest();
|
|
80554
80612
|
var MIGRATE_DIR = "migrate";
|
|
80555
|
-
var MIGRATE_BACKUP_DIR =
|
|
80556
|
-
var MIGRATE_PLAN_FILE =
|
|
80613
|
+
var MIGRATE_BACKUP_DIR = path65.join(MIGRATE_DIR, "backup");
|
|
80614
|
+
var MIGRATE_PLAN_FILE = path65.join(MIGRATE_DIR, "plan.json");
|
|
80557
80615
|
var LEGACY_MACHINERY_FILES = [
|
|
80558
80616
|
"agent-slot.sh",
|
|
80559
80617
|
"provision-toolchain.sh",
|
|
@@ -80593,25 +80651,25 @@ function harnessEnvIsPre10(content) {
|
|
|
80593
80651
|
return /^\s*(har_infra_enabled|har_pg|har_node_[a-z_]+|har_pkg_exec)\s*\(\)/m.test(content) || /^export\s+HARNESS_[A-Z0-9_]+_PORT_(DEFAULT|SCAN_START|SCAN_END)=/m.test(content);
|
|
80594
80652
|
}
|
|
80595
80653
|
function scriptIsVendored(harnessDir, script) {
|
|
80596
|
-
const file =
|
|
80597
|
-
if (!
|
|
80598
|
-
const content =
|
|
80654
|
+
const file = path65.join(harnessDir, script);
|
|
80655
|
+
if (!fs60.existsSync(file)) return false;
|
|
80656
|
+
const content = fs60.readFileSync(file, "utf8");
|
|
80599
80657
|
return !content.includes("exec har env") && !content.includes("runtime/har.cjs");
|
|
80600
80658
|
}
|
|
80601
80659
|
function isPre10Harness(repoPath) {
|
|
80602
|
-
const resolved =
|
|
80660
|
+
const resolved = path65.resolve(repoPath);
|
|
80603
80661
|
const harnessDir = getHarnessDir(resolved);
|
|
80604
|
-
if (!
|
|
80662
|
+
if (!fs60.existsSync(harnessDir)) return false;
|
|
80605
80663
|
const manifest = readManifest(resolved);
|
|
80606
80664
|
if (manifest?.ejected) return false;
|
|
80607
80665
|
for (const file of LEGACY_MACHINERY_FILES) {
|
|
80608
|
-
if (
|
|
80666
|
+
if (fs60.existsSync(path65.join(harnessDir, file))) return true;
|
|
80609
80667
|
}
|
|
80610
80668
|
for (const script of RUNTIME_SHIM_FILES) {
|
|
80611
80669
|
if (scriptIsVendored(harnessDir, script)) return true;
|
|
80612
80670
|
}
|
|
80613
|
-
const envPath =
|
|
80614
|
-
if (
|
|
80671
|
+
const envPath = path65.join(harnessDir, "harness.env");
|
|
80672
|
+
if (fs60.existsSync(envPath) && harnessEnvIsPre10(fs60.readFileSync(envPath, "utf8"))) {
|
|
80615
80673
|
return true;
|
|
80616
80674
|
}
|
|
80617
80675
|
return false;
|
|
@@ -80744,10 +80802,10 @@ var SCRIPT_RESIDUE_TARGET = {
|
|
|
80744
80802
|
"agent-cli.sh": "review"
|
|
80745
80803
|
};
|
|
80746
80804
|
function backupRel(file) {
|
|
80747
|
-
return
|
|
80805
|
+
return path65.join(MIGRATE_BACKUP_DIR, file);
|
|
80748
80806
|
}
|
|
80749
80807
|
function buildPre10Plan(repoPath) {
|
|
80750
|
-
const resolved =
|
|
80808
|
+
const resolved = path65.resolve(repoPath);
|
|
80751
80809
|
const harnessDir = getHarnessDir(resolved);
|
|
80752
80810
|
const manifest = readManifest(resolved);
|
|
80753
80811
|
const profile = manifest?.profile ?? "default";
|
|
@@ -80757,11 +80815,11 @@ function buildPre10Plan(repoPath) {
|
|
|
80757
80815
|
const residue = [];
|
|
80758
80816
|
for (const script of RUNTIME_SHIM_FILES) {
|
|
80759
80817
|
if (!composed.has(script)) continue;
|
|
80760
|
-
if (!scriptIsVendored(harnessDir, script) &&
|
|
80818
|
+
if (!scriptIsVendored(harnessDir, script) && fs60.existsSync(path65.join(harnessDir, script))) {
|
|
80761
80819
|
continue;
|
|
80762
80820
|
}
|
|
80763
80821
|
replaceWithShims.push(script);
|
|
80764
|
-
if (
|
|
80822
|
+
if (fs60.existsSync(path65.join(harnessDir, script))) {
|
|
80765
80823
|
const target = SCRIPT_RESIDUE_TARGET[script] ?? "review";
|
|
80766
80824
|
residue.push({
|
|
80767
80825
|
source: script,
|
|
@@ -80773,27 +80831,27 @@ function buildPre10Plan(repoPath) {
|
|
|
80773
80831
|
}
|
|
80774
80832
|
const survivingScripts = [];
|
|
80775
80833
|
for (const dir of ["stages", "hooks"]) {
|
|
80776
|
-
const full =
|
|
80777
|
-
if (!
|
|
80778
|
-
for (const entry of
|
|
80779
|
-
if (entry.endsWith(".sh") || entry.endsWith(".mjs")) survivingScripts.push(
|
|
80834
|
+
const full = path65.join(harnessDir, dir);
|
|
80835
|
+
if (!fs60.existsSync(full)) continue;
|
|
80836
|
+
for (const entry of fs60.readdirSync(full)) {
|
|
80837
|
+
if (entry.endsWith(".sh") || entry.endsWith(".mjs")) survivingScripts.push(path65.join(dir, entry));
|
|
80780
80838
|
}
|
|
80781
80839
|
}
|
|
80782
80840
|
const referencedBy = (machineryFile) => {
|
|
80783
|
-
const base =
|
|
80841
|
+
const base = path65.basename(machineryFile).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
80784
80842
|
const loadRe = new RegExp(
|
|
80785
80843
|
`(?:\\bsource\\b|\\bbash\\b|\\bexec\\b|(?:^|[;&|(])\\s*\\.\\s)[^\\n#]*${base}`
|
|
80786
80844
|
);
|
|
80787
80845
|
return survivingScripts.filter(
|
|
80788
|
-
(script) =>
|
|
80846
|
+
(script) => fs60.readFileSync(path65.join(harnessDir, script), "utf8").split("\n").some((line) => !/^\s*#/.test(line) && loadRe.test(line))
|
|
80789
80847
|
);
|
|
80790
80848
|
};
|
|
80791
80849
|
const deleteMachinery = [];
|
|
80792
80850
|
const editedMachinery = [];
|
|
80793
80851
|
const retainMachinery = [];
|
|
80794
80852
|
for (const file of LEGACY_MACHINERY_FILES) {
|
|
80795
|
-
const full =
|
|
80796
|
-
if (!
|
|
80853
|
+
const full = path65.join(harnessDir, file);
|
|
80854
|
+
if (!fs60.existsSync(full)) continue;
|
|
80797
80855
|
const refs = referencedBy(file);
|
|
80798
80856
|
if (refs.length > 0) {
|
|
80799
80857
|
retainMachinery.push(file);
|
|
@@ -80807,7 +80865,7 @@ function buildPre10Plan(repoPath) {
|
|
|
80807
80865
|
}
|
|
80808
80866
|
deleteMachinery.push(file);
|
|
80809
80867
|
const recorded = fileBaseline[file];
|
|
80810
|
-
const installed = computeFileChecksum(
|
|
80868
|
+
const installed = computeFileChecksum(fs60.readFileSync(full, "utf8"));
|
|
80811
80869
|
if (recorded !== void 0 && installed !== recorded) {
|
|
80812
80870
|
editedMachinery.push(file);
|
|
80813
80871
|
residue.push({
|
|
@@ -80819,9 +80877,9 @@ function buildPre10Plan(repoPath) {
|
|
|
80819
80877
|
}
|
|
80820
80878
|
}
|
|
80821
80879
|
let env3 = null;
|
|
80822
|
-
const envPath =
|
|
80823
|
-
if (
|
|
80824
|
-
const content =
|
|
80880
|
+
const envPath = path65.join(harnessDir, "harness.env");
|
|
80881
|
+
if (fs60.existsSync(envPath)) {
|
|
80882
|
+
const content = fs60.readFileSync(envPath, "utf8");
|
|
80825
80883
|
if (harnessEnvIsPre10(content) || migrateHarnessEnvContent(content).commentedKeys.length > 0) {
|
|
80826
80884
|
env3 = migrateHarnessEnvContent(content);
|
|
80827
80885
|
for (const fn of env3.customFunctions) {
|
|
@@ -80846,7 +80904,7 @@ function buildPre10Plan(repoPath) {
|
|
|
80846
80904
|
for (const file of composed.keys()) {
|
|
80847
80905
|
if (RUNTIME_SHIM_FILES.includes(file)) continue;
|
|
80848
80906
|
if (file === "gitignore.template") continue;
|
|
80849
|
-
if (!
|
|
80907
|
+
if (!fs60.existsSync(path65.join(harnessDir, file))) installMissing.push(file);
|
|
80850
80908
|
}
|
|
80851
80909
|
let phantomVerificationIds = [];
|
|
80852
80910
|
try {
|
|
@@ -80876,51 +80934,51 @@ function buildPre10Plan(repoPath) {
|
|
|
80876
80934
|
};
|
|
80877
80935
|
}
|
|
80878
80936
|
function applyPre10Plan(repoPath, plan) {
|
|
80879
|
-
const resolved =
|
|
80937
|
+
const resolved = path65.resolve(repoPath);
|
|
80880
80938
|
const harnessDir = getHarnessDir(resolved);
|
|
80881
80939
|
const effective = plan ?? buildPre10Plan(resolved);
|
|
80882
|
-
const backupDir =
|
|
80883
|
-
|
|
80940
|
+
const backupDir = path65.join(harnessDir, MIGRATE_BACKUP_DIR);
|
|
80941
|
+
fs60.mkdirSync(backupDir, { recursive: true });
|
|
80884
80942
|
const backup = (file) => {
|
|
80885
|
-
const src =
|
|
80886
|
-
if (!
|
|
80887
|
-
const dest =
|
|
80888
|
-
|
|
80889
|
-
|
|
80943
|
+
const src = path65.join(harnessDir, file);
|
|
80944
|
+
if (!fs60.existsSync(src)) return;
|
|
80945
|
+
const dest = path65.join(backupDir, file);
|
|
80946
|
+
fs60.mkdirSync(path65.dirname(dest), { recursive: true });
|
|
80947
|
+
fs60.copyFileSync(src, dest);
|
|
80890
80948
|
};
|
|
80891
80949
|
const written = [];
|
|
80892
80950
|
const deleted = [];
|
|
80893
|
-
const projectName =
|
|
80951
|
+
const projectName = path65.basename(resolved).toLowerCase().replace(/[^a-z0-9]/g, "_");
|
|
80894
80952
|
const composed = composeProfileTemplateMap(effective.profile);
|
|
80895
80953
|
for (const script of effective.replaceWithShims) {
|
|
80896
80954
|
const source = composed.get(script);
|
|
80897
80955
|
if (!source) continue;
|
|
80898
80956
|
backup(script);
|
|
80899
80957
|
const rendered = substituteTemplateTokens(readComposedTemplateContent(source), projectName);
|
|
80900
|
-
const dest =
|
|
80901
|
-
|
|
80902
|
-
|
|
80958
|
+
const dest = path65.join(harnessDir, script);
|
|
80959
|
+
fs60.writeFileSync(dest, rendered);
|
|
80960
|
+
fs60.chmodSync(dest, 493);
|
|
80903
80961
|
written.push(script);
|
|
80904
80962
|
}
|
|
80905
80963
|
for (const file of effective.deleteMachinery) {
|
|
80906
80964
|
backup(file);
|
|
80907
|
-
|
|
80965
|
+
fs60.rmSync(path65.join(harnessDir, file), { force: true });
|
|
80908
80966
|
deleted.push(file);
|
|
80909
80967
|
}
|
|
80910
|
-
const libDir =
|
|
80911
|
-
if (
|
|
80912
|
-
|
|
80968
|
+
const libDir = path65.join(harnessDir, "lib");
|
|
80969
|
+
if (fs60.existsSync(libDir) && fs60.readdirSync(libDir).length === 0) {
|
|
80970
|
+
fs60.rmdirSync(libDir);
|
|
80913
80971
|
deleted.push("lib/");
|
|
80914
80972
|
}
|
|
80915
80973
|
for (const file of effective.installMissing ?? []) {
|
|
80916
80974
|
const source = composed.get(file);
|
|
80917
80975
|
if (!source) continue;
|
|
80918
|
-
const dest =
|
|
80919
|
-
if (
|
|
80976
|
+
const dest = path65.join(harnessDir, file);
|
|
80977
|
+
if (fs60.existsSync(dest)) continue;
|
|
80920
80978
|
const rendered = substituteTemplateTokens(readComposedTemplateContent(source), projectName);
|
|
80921
|
-
|
|
80922
|
-
|
|
80923
|
-
if (/\.(sh|mjs)$/.test(file))
|
|
80979
|
+
fs60.mkdirSync(path65.dirname(dest), { recursive: true });
|
|
80980
|
+
fs60.writeFileSync(dest, rendered);
|
|
80981
|
+
if (/\.(sh|mjs)$/.test(file)) fs60.chmodSync(dest, 493);
|
|
80924
80982
|
written.push(file);
|
|
80925
80983
|
}
|
|
80926
80984
|
if (effective.phantomVerificationIds.length > 0) {
|
|
@@ -80935,7 +80993,7 @@ function applyPre10Plan(repoPath, plan) {
|
|
|
80935
80993
|
}
|
|
80936
80994
|
if (effective.env) {
|
|
80937
80995
|
backup("harness.env");
|
|
80938
|
-
|
|
80996
|
+
fs60.writeFileSync(path65.join(harnessDir, "harness.env"), effective.env.content);
|
|
80939
80997
|
written.push("harness.env");
|
|
80940
80998
|
}
|
|
80941
80999
|
const manifest = readManifest(resolved);
|
|
@@ -80950,8 +81008,8 @@ function applyPre10Plan(repoPath, plan) {
|
|
|
80950
81008
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
80951
81009
|
});
|
|
80952
81010
|
}
|
|
80953
|
-
|
|
80954
|
-
|
|
81011
|
+
fs60.writeFileSync(
|
|
81012
|
+
path65.join(harnessDir, MIGRATE_PLAN_FILE),
|
|
80955
81013
|
JSON.stringify({ ...effective, appliedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2) + "\n"
|
|
80956
81014
|
);
|
|
80957
81015
|
return { plan: effective, backupDir, written, deleted };
|
|
@@ -80971,21 +81029,21 @@ function pendingMigrations(repoPath) {
|
|
|
80971
81029
|
);
|
|
80972
81030
|
}
|
|
80973
81031
|
function writeMigrationPlan(repoPath, plan) {
|
|
80974
|
-
const harnessDir = getHarnessDir(
|
|
80975
|
-
const planPath =
|
|
80976
|
-
|
|
80977
|
-
|
|
81032
|
+
const harnessDir = getHarnessDir(path65.resolve(repoPath));
|
|
81033
|
+
const planPath = path65.join(harnessDir, MIGRATE_PLAN_FILE);
|
|
81034
|
+
fs60.mkdirSync(path65.dirname(planPath), { recursive: true });
|
|
81035
|
+
fs60.writeFileSync(planPath, JSON.stringify(plan, null, 2) + "\n");
|
|
80978
81036
|
return planPath;
|
|
80979
81037
|
}
|
|
80980
81038
|
function removeMigrationArtifacts(repoPath) {
|
|
80981
|
-
const harnessDir = getHarnessDir(
|
|
80982
|
-
|
|
80983
|
-
|
|
81039
|
+
const harnessDir = getHarnessDir(path65.resolve(repoPath));
|
|
81040
|
+
fs60.rmSync(path65.join(harnessDir, MIGRATE_DIR), { recursive: true, force: true });
|
|
81041
|
+
fs60.rmSync(path65.join(harnessDir, "MIGRATE-PROMPT.md"), { force: true });
|
|
80984
81042
|
}
|
|
80985
81043
|
|
|
80986
81044
|
// src/harness/migrate-prompt.ts
|
|
80987
|
-
var
|
|
80988
|
-
var
|
|
81045
|
+
var fs61 = __toESM(require("fs"));
|
|
81046
|
+
var path66 = __toESM(require("path"));
|
|
80989
81047
|
init_paths();
|
|
80990
81048
|
init_file_ops();
|
|
80991
81049
|
init_manifest();
|
|
@@ -81094,18 +81152,18 @@ function buildMigrationSection(plan, applied) {
|
|
|
81094
81152
|
lines2.push(...residueTable(plan), "");
|
|
81095
81153
|
return lines2.join("\n");
|
|
81096
81154
|
}
|
|
81097
|
-
function
|
|
81155
|
+
function loadTemplate2() {
|
|
81098
81156
|
const filePath = resolveTemplateFile("migration-prompt.md");
|
|
81099
81157
|
if (!filePath) {
|
|
81100
81158
|
throw new Error("Migration prompt template not found: migration-prompt.md. Run npm run build.");
|
|
81101
81159
|
}
|
|
81102
|
-
return
|
|
81160
|
+
return fs61.readFileSync(filePath, "utf8");
|
|
81103
81161
|
}
|
|
81104
81162
|
function buildMigrationPrompt(plan, applied) {
|
|
81105
|
-
return
|
|
81163
|
+
return loadTemplate2().replace("{{MIGRATION_SECTION}}", buildMigrationSection(plan, applied));
|
|
81106
81164
|
}
|
|
81107
81165
|
function writeMigrationPrompt(repoPath, content) {
|
|
81108
|
-
const filePath =
|
|
81166
|
+
const filePath = path66.join(getHarnessDir(repoPath), MIGRATE_PROMPT_FILE);
|
|
81109
81167
|
writeFileSafe(filePath, content);
|
|
81110
81168
|
return filePath;
|
|
81111
81169
|
}
|
|
@@ -81113,11 +81171,11 @@ function writeMigrationPrompt(repoPath, content) {
|
|
|
81113
81171
|
// src/core/harness.ts
|
|
81114
81172
|
function listHarnessScripts(repoPath) {
|
|
81115
81173
|
const harnessDir = getHarnessDir(repoPath);
|
|
81116
|
-
if (!
|
|
81117
|
-
return
|
|
81174
|
+
if (!fs62.existsSync(harnessDir)) return [];
|
|
81175
|
+
return fs62.readdirSync(harnessDir).filter((name) => name.endsWith(".sh")).sort();
|
|
81118
81176
|
}
|
|
81119
81177
|
function describeProject(repoPath) {
|
|
81120
|
-
const resolved =
|
|
81178
|
+
const resolved = path67.resolve(repoPath);
|
|
81121
81179
|
const manifest = readManifest(resolved);
|
|
81122
81180
|
const present = harnessExists(resolved);
|
|
81123
81181
|
return {
|
|
@@ -81137,8 +81195,8 @@ function describeProject(repoPath) {
|
|
|
81137
81195
|
};
|
|
81138
81196
|
}
|
|
81139
81197
|
async function initHarness(options) {
|
|
81140
|
-
const repoPath =
|
|
81141
|
-
if (!
|
|
81198
|
+
const repoPath = path67.resolve(options.repoPath);
|
|
81199
|
+
if (!fs62.existsSync(repoPath)) {
|
|
81142
81200
|
throw new Error(`Path not found: ${repoPath}`);
|
|
81143
81201
|
}
|
|
81144
81202
|
const scaffold = scaffoldHarnessBoilerplate(repoPath, {
|
|
@@ -81159,9 +81217,9 @@ async function initHarness(options) {
|
|
|
81159
81217
|
};
|
|
81160
81218
|
}
|
|
81161
81219
|
async function maintainHarness(options) {
|
|
81162
|
-
const repoPath =
|
|
81220
|
+
const repoPath = path67.resolve(options.repoPath);
|
|
81163
81221
|
const harnessDir = getHarnessDir(repoPath);
|
|
81164
|
-
if (!
|
|
81222
|
+
if (!fs62.existsSync(harnessDir)) {
|
|
81165
81223
|
throw new Error('No .har/ found. Run "har env init" first.');
|
|
81166
81224
|
}
|
|
81167
81225
|
let migration;
|
|
@@ -81237,8 +81295,8 @@ function addPlugin(repoPath, pluginId, options = {}) {
|
|
|
81237
81295
|
}
|
|
81238
81296
|
|
|
81239
81297
|
// src/harness/adaptation-prompt.ts
|
|
81240
|
-
var
|
|
81241
|
-
var
|
|
81298
|
+
var fs63 = __toESM(require("fs"));
|
|
81299
|
+
var path68 = __toESM(require("path"));
|
|
81242
81300
|
var readline5 = __toESM(require("readline"));
|
|
81243
81301
|
|
|
81244
81302
|
// src/utils/clipboard.ts
|
|
@@ -81324,21 +81382,21 @@ var PROFILE_HINTS = {
|
|
|
81324
81382
|
cli: "CLI/library profile (typical SWE-bench) \u2014 no PM2. Optional Docker Compose via HARNESS_INFRA_SERVICES. Git worktree by default. Launch provisions toolchain declaratively (HARNESS_ECOSYSTEM auto-detects common ecosystems); verify must use resolved tool paths from .env.agent.<id>, never hardcoded interpreter or package-manager paths.",
|
|
81325
81383
|
ios: "iOS mobile app profile \u2014 xcodebuild + iOS Simulator in an isolated git worktree. Set HARNESS_XCODE_SCHEME, workspace/project, HARNESS_SIMULATOR_NAME, HARNESS_BUNDLE_ID. Launch writes XCODEBUILD_BIN to .env.agent.<id>; verify uses it."
|
|
81326
81384
|
};
|
|
81327
|
-
function
|
|
81385
|
+
function loadTemplate3(name) {
|
|
81328
81386
|
const filePath = resolveTemplateFile(name);
|
|
81329
81387
|
if (!filePath) {
|
|
81330
81388
|
throw new Error(`Adaptation prompt template not found: ${name}. Run npm run build.`);
|
|
81331
81389
|
}
|
|
81332
|
-
return
|
|
81390
|
+
return fs63.readFileSync(filePath, "utf8");
|
|
81333
81391
|
}
|
|
81334
81392
|
function applyProfilePlaceholders(content, profile) {
|
|
81335
81393
|
return content.replace(/\{\{PROFILE\}\}/g, profile).replace(/\{\{PROFILE_HINT\}\}/g, PROFILE_HINTS[profile]);
|
|
81336
81394
|
}
|
|
81337
81395
|
function buildInitAdaptationPrompt(_repoPath, profile) {
|
|
81338
|
-
return applyProfilePlaceholders(
|
|
81396
|
+
return applyProfilePlaceholders(loadTemplate3("adaptation-prompt-init.md"), profile);
|
|
81339
81397
|
}
|
|
81340
81398
|
function buildMaintainAdaptationPrompt(_repoPath, bundleReport) {
|
|
81341
|
-
const template =
|
|
81399
|
+
const template = loadTemplate3("adaptation-prompt-maintain.md");
|
|
81342
81400
|
const section = bundleReport ? formatMaintainBundlePromptSection(bundleReport) : [
|
|
81343
81401
|
"## Step 0 \u2014 Read the maintenance bundle",
|
|
81344
81402
|
"",
|
|
@@ -81351,7 +81409,7 @@ function buildMaintainAdaptationPrompt(_repoPath, bundleReport) {
|
|
|
81351
81409
|
}
|
|
81352
81410
|
function writeAdaptationPrompt(repoPath, content) {
|
|
81353
81411
|
const harnessDir = getHarnessDir(repoPath);
|
|
81354
|
-
const filePath =
|
|
81412
|
+
const filePath = path68.join(harnessDir, ADAPTATION_PROMPT_FILE);
|
|
81355
81413
|
writeFileSafe(filePath, content);
|
|
81356
81414
|
return filePath;
|
|
81357
81415
|
}
|
|
@@ -81380,9 +81438,10 @@ function askYesNo2(question) {
|
|
|
81380
81438
|
});
|
|
81381
81439
|
}
|
|
81382
81440
|
async function offerAdaptationPromptClipboard(content, options = {}) {
|
|
81441
|
+
const fileLabel = options.fileLabel ?? `.har/${ADAPTATION_PROMPT_FILE}`;
|
|
81383
81442
|
const interactive = Boolean(process.stdin.isTTY && process.stderr.isTTY);
|
|
81384
81443
|
if (!interactive && !options.autoYes) {
|
|
81385
|
-
info(
|
|
81444
|
+
info(`Prompt also saved to ${fileLabel} (open or copy from there)`);
|
|
81386
81445
|
return false;
|
|
81387
81446
|
}
|
|
81388
81447
|
let shouldCopy = options.autoYes === true;
|
|
@@ -81390,7 +81449,7 @@ async function offerAdaptationPromptClipboard(content, options = {}) {
|
|
|
81390
81449
|
shouldCopy = await askYesNo2("Copy adaptation prompt to clipboard for your coding agent? [Y/n]");
|
|
81391
81450
|
}
|
|
81392
81451
|
if (!shouldCopy) {
|
|
81393
|
-
info(
|
|
81452
|
+
info(`Skipped clipboard copy \u2014 prompt is in ${fileLabel}`);
|
|
81394
81453
|
return false;
|
|
81395
81454
|
}
|
|
81396
81455
|
const result = copyTextToClipboard(content);
|
|
@@ -81401,33 +81460,33 @@ async function offerAdaptationPromptClipboard(content, options = {}) {
|
|
|
81401
81460
|
return true;
|
|
81402
81461
|
}
|
|
81403
81462
|
warn(`Could not copy to clipboard: ${result.detail}`);
|
|
81404
|
-
info(
|
|
81463
|
+
info(`Open ${fileLabel} and paste that into your coding agent instead`);
|
|
81405
81464
|
return false;
|
|
81406
81465
|
}
|
|
81407
81466
|
|
|
81408
81467
|
// src/harness/cursor-rule.ts
|
|
81409
|
-
var
|
|
81410
|
-
var
|
|
81468
|
+
var fs64 = __toESM(require("fs"));
|
|
81469
|
+
var path69 = __toESM(require("path"));
|
|
81411
81470
|
var readline6 = __toESM(require("readline"));
|
|
81412
81471
|
init_file_ops();
|
|
81413
81472
|
init_logging();
|
|
81414
81473
|
init_paths();
|
|
81415
81474
|
var CURSOR_RULE_RELATIVE_PATH = ".cursor/rules/har-workflow.mdc";
|
|
81416
81475
|
function getCursorRulePath(repoPath) {
|
|
81417
|
-
return
|
|
81476
|
+
return path69.join(repoPath, CURSOR_RULE_RELATIVE_PATH);
|
|
81418
81477
|
}
|
|
81419
81478
|
function isCursorWorkspace(repoPath) {
|
|
81420
|
-
return
|
|
81479
|
+
return fs64.existsSync(path69.join(repoPath, ".cursor"));
|
|
81421
81480
|
}
|
|
81422
81481
|
function cursorRuleExists(repoPath) {
|
|
81423
|
-
return
|
|
81482
|
+
return fs64.existsSync(getCursorRulePath(repoPath));
|
|
81424
81483
|
}
|
|
81425
81484
|
function scaffoldCursorRule(repoPath) {
|
|
81426
81485
|
const templatePath = resolveTemplateFile("cursor-rule.mdc.template");
|
|
81427
81486
|
if (!templatePath) {
|
|
81428
81487
|
throw new Error("Cursor rule template not found (cursor-rule.mdc.template). Run npm run build.");
|
|
81429
81488
|
}
|
|
81430
|
-
const content =
|
|
81489
|
+
const content = fs64.readFileSync(templatePath, "utf8");
|
|
81431
81490
|
writeFileSafe(getCursorRulePath(repoPath), content);
|
|
81432
81491
|
}
|
|
81433
81492
|
async function handleCursorRule(options) {
|
|
@@ -81518,7 +81577,7 @@ init_control_config();
|
|
|
81518
81577
|
|
|
81519
81578
|
// src/core/control-lifecycle.ts
|
|
81520
81579
|
var import_child_process17 = require("child_process");
|
|
81521
|
-
var
|
|
81580
|
+
var path70 = __toESM(require("path"));
|
|
81522
81581
|
|
|
81523
81582
|
// src/core/control-image.ts
|
|
81524
81583
|
init_package_version();
|
|
@@ -81545,10 +81604,10 @@ var CONTROL_DATA_VOLUME = "har_control_data";
|
|
|
81545
81604
|
var CONTROL_CONTAINER_PORT = 3847;
|
|
81546
81605
|
var CONTROL_DATA_DB_URL = "file:/data/har_control.db";
|
|
81547
81606
|
function resolveControlDir() {
|
|
81548
|
-
return
|
|
81607
|
+
return path70.resolve(__dirname, "..", "control");
|
|
81549
81608
|
}
|
|
81550
81609
|
function resolveControlBuildContext() {
|
|
81551
|
-
return
|
|
81610
|
+
return path70.resolve(resolveControlDir(), "..");
|
|
81552
81611
|
}
|
|
81553
81612
|
function buildDockerRunArgs(options) {
|
|
81554
81613
|
const name = options.containerName ?? CONTROL_CONTAINER_NAME;
|
|
@@ -81604,7 +81663,7 @@ async function startMissionControl(options) {
|
|
|
81604
81663
|
"-t",
|
|
81605
81664
|
imageRef,
|
|
81606
81665
|
"-f",
|
|
81607
|
-
|
|
81666
|
+
path70.join(resolveControlDir(), "Dockerfile"),
|
|
81608
81667
|
resolveControlBuildContext()
|
|
81609
81668
|
]);
|
|
81610
81669
|
if (buildCode !== 0) {
|
|
@@ -81751,7 +81810,7 @@ async function ensureTelemetryInfrastructure(options) {
|
|
|
81751
81810
|
// src/core/run-service.ts
|
|
81752
81811
|
init_telemetry_config();
|
|
81753
81812
|
init_telemetry_env();
|
|
81754
|
-
var
|
|
81813
|
+
var path72 = __toESM(require("path"));
|
|
81755
81814
|
init_local_executor();
|
|
81756
81815
|
function extractShellOutput(result) {
|
|
81757
81816
|
const stdout = result.logs?.find((log) => log.stream === "stdout")?.content ?? result.logs?.find((log) => !log.stream)?.content ?? "";
|
|
@@ -81974,12 +82033,12 @@ Usage from Cursor / Claude / Codex (@osfactory/otel-hook) will appear under Work
|
|
|
81974
82033
|
suffix: session.suffix,
|
|
81975
82034
|
createdAt: session.createdAt
|
|
81976
82035
|
});
|
|
81977
|
-
const envFile =
|
|
82036
|
+
const envFile = path72.join(session.workDir, `.env.agent.${options.agentId}`);
|
|
81978
82037
|
try {
|
|
81979
82038
|
appendTelemetryEnvToFile(envFile, {
|
|
81980
82039
|
sessionKey,
|
|
81981
82040
|
agentId: options.agentId,
|
|
81982
|
-
repoPath:
|
|
82041
|
+
repoPath: path72.resolve(options.repoPath),
|
|
81983
82042
|
workDir: session.workDir,
|
|
81984
82043
|
branch: session.branch,
|
|
81985
82044
|
suffix: session.suffix,
|
|
@@ -82221,9 +82280,9 @@ init_work_units();
|
|
|
82221
82280
|
init_manifest();
|
|
82222
82281
|
|
|
82223
82282
|
// src/core/cleanup-service.ts
|
|
82224
|
-
var
|
|
82283
|
+
var fs66 = __toESM(require("fs"));
|
|
82225
82284
|
var os22 = __toESM(require("os"));
|
|
82226
|
-
var
|
|
82285
|
+
var path73 = __toESM(require("path"));
|
|
82227
82286
|
var import_child_process19 = require("child_process");
|
|
82228
82287
|
init_control_sync();
|
|
82229
82288
|
init_control_repo_path();
|
|
@@ -82232,9 +82291,9 @@ init_manifest();
|
|
|
82232
82291
|
var DEFAULT_STALE_DAYS = 7;
|
|
82233
82292
|
function getWorktreesRoot() {
|
|
82234
82293
|
if (process.env.HAR_WORKTREES_ROOT) {
|
|
82235
|
-
return
|
|
82294
|
+
return path73.resolve(process.env.HAR_WORKTREES_ROOT);
|
|
82236
82295
|
}
|
|
82237
|
-
return
|
|
82296
|
+
return path73.join(process.env.HOME || os22.homedir(), "worktrees");
|
|
82238
82297
|
}
|
|
82239
82298
|
function runGit3(cwd, args) {
|
|
82240
82299
|
try {
|
|
@@ -82248,7 +82307,7 @@ function runGit3(cwd, args) {
|
|
|
82248
82307
|
}
|
|
82249
82308
|
}
|
|
82250
82309
|
function basenameRepo(repoPath) {
|
|
82251
|
-
return
|
|
82310
|
+
return path73.basename(canonicalizeControlRepoPath(repoPath));
|
|
82252
82311
|
}
|
|
82253
82312
|
function ageDaysFrom(iso) {
|
|
82254
82313
|
if (!iso) return void 0;
|
|
@@ -82260,12 +82319,12 @@ function matchesKeep(candidate, keep) {
|
|
|
82260
82319
|
if (!keep?.length) return false;
|
|
82261
82320
|
for (const pin of keep) {
|
|
82262
82321
|
if (pin.worktreePath && candidate.worktreePath) {
|
|
82263
|
-
if (
|
|
82322
|
+
if (path73.resolve(pin.worktreePath) === path73.resolve(candidate.worktreePath)) return true;
|
|
82264
82323
|
}
|
|
82265
82324
|
if (pin.repoPath && pin.agentId !== void 0 && candidate.agentId !== void 0) {
|
|
82266
82325
|
const repo = canonicalizeControlRepoPath(pin.repoPath);
|
|
82267
|
-
const candidateRepo =
|
|
82268
|
-
if ((repo === candidateRepo ||
|
|
82326
|
+
const candidateRepo = path73.resolve(candidate.repoPath);
|
|
82327
|
+
if ((repo === candidateRepo || path73.resolve(pin.repoPath) === candidateRepo) && pin.agentId === candidate.agentId) {
|
|
82269
82328
|
return true;
|
|
82270
82329
|
}
|
|
82271
82330
|
}
|
|
@@ -82320,20 +82379,20 @@ function classifySlotCandidate(repoPath, projectName, slot, options) {
|
|
|
82320
82379
|
return candidate;
|
|
82321
82380
|
}
|
|
82322
82381
|
function resolveRepoForWorktree(worktreePath) {
|
|
82323
|
-
if (!
|
|
82382
|
+
if (!fs66.existsSync(worktreePath)) return void 0;
|
|
82324
82383
|
const commonDir = runGit3(worktreePath, "rev-parse --git-common-dir");
|
|
82325
82384
|
if (!commonDir) return void 0;
|
|
82326
|
-
const gitRoot =
|
|
82385
|
+
const gitRoot = path73.resolve(worktreePath, commonDir, "..");
|
|
82327
82386
|
if (!readManifest(gitRoot)) return void 0;
|
|
82328
82387
|
return canonicalizeControlRepoPath(gitRoot);
|
|
82329
82388
|
}
|
|
82330
82389
|
function discoverOrphanWorktrees(knownPaths) {
|
|
82331
82390
|
const worktreesRoot = getWorktreesRoot();
|
|
82332
|
-
if (!
|
|
82391
|
+
if (!fs66.existsSync(worktreesRoot)) return [];
|
|
82333
82392
|
const orphans = [];
|
|
82334
|
-
for (const entry of
|
|
82393
|
+
for (const entry of fs66.readdirSync(worktreesRoot, { withFileTypes: true })) {
|
|
82335
82394
|
if (!entry.isDirectory() || !entry.name.includes("-har-agent-")) continue;
|
|
82336
|
-
const worktreePath =
|
|
82395
|
+
const worktreePath = path73.resolve(path73.join(worktreesRoot, entry.name));
|
|
82337
82396
|
if (knownPaths.has(worktreePath)) continue;
|
|
82338
82397
|
const repoPath = resolveRepoForWorktree(worktreePath) ?? worktreesRoot;
|
|
82339
82398
|
const porcelain = runGit3(worktreePath, "status --porcelain");
|
|
@@ -82358,14 +82417,14 @@ async function discoverCleanupCandidates(options = {}) {
|
|
|
82358
82417
|
const candidates = [];
|
|
82359
82418
|
const knownWorktreePaths = /* @__PURE__ */ new Set();
|
|
82360
82419
|
for (const repoPath of repoPaths) {
|
|
82361
|
-
if (!
|
|
82420
|
+
if (!fs66.existsSync(repoPath) || !readManifest(repoPath)) continue;
|
|
82362
82421
|
const harnessRoot = resolveHarnessRoot(repoPath);
|
|
82363
82422
|
const canonicalRepo = canonicalizeControlRepoPath(harnessRoot);
|
|
82364
82423
|
const status = collectEnvironmentStatus(harnessRoot);
|
|
82365
82424
|
const projectName = basenameRepo(harnessRoot);
|
|
82366
82425
|
for (const slot of status.slots) {
|
|
82367
|
-
if (slot.worktreePath) knownWorktreePaths.add(
|
|
82368
|
-
if (slot.workDir) knownWorktreePaths.add(
|
|
82426
|
+
if (slot.worktreePath) knownWorktreePaths.add(path73.resolve(slot.worktreePath));
|
|
82427
|
+
if (slot.workDir) knownWorktreePaths.add(path73.resolve(slot.workDir));
|
|
82369
82428
|
const candidate = classifySlotCandidate(canonicalRepo, projectName, slot, {
|
|
82370
82429
|
staleDays: options.staleDays,
|
|
82371
82430
|
keep: options.keep
|
|
@@ -82471,7 +82530,7 @@ async function executeCleanupCandidates(candidates, options = {}) {
|
|
|
82471
82530
|
continue;
|
|
82472
82531
|
}
|
|
82473
82532
|
if (candidate.kind === "orphan_worktree" && candidate.worktreePath) {
|
|
82474
|
-
if (
|
|
82533
|
+
if (fs66.existsSync(candidate.worktreePath)) {
|
|
82475
82534
|
const repoRoot = candidate.repoPath !== getWorktreesRoot() ? candidate.repoPath : resolveRepoForWorktree(candidate.worktreePath);
|
|
82476
82535
|
if (repoRoot) {
|
|
82477
82536
|
try {
|
|
@@ -82482,8 +82541,8 @@ async function executeCleanupCandidates(candidates, options = {}) {
|
|
|
82482
82541
|
} catch {
|
|
82483
82542
|
}
|
|
82484
82543
|
}
|
|
82485
|
-
if (
|
|
82486
|
-
|
|
82544
|
+
if (fs66.existsSync(candidate.worktreePath)) {
|
|
82545
|
+
fs66.rmSync(candidate.worktreePath, { recursive: true, force: true });
|
|
82487
82546
|
}
|
|
82488
82547
|
}
|
|
82489
82548
|
outcomes.push({ candidate, ok: true });
|
|
@@ -82509,7 +82568,7 @@ function parseCleanupKeepPins(values) {
|
|
|
82509
82568
|
}
|
|
82510
82569
|
if (raw.startsWith("/") || raw.startsWith("~")) {
|
|
82511
82570
|
return {
|
|
82512
|
-
worktreePath: raw.startsWith("~") ?
|
|
82571
|
+
worktreePath: raw.startsWith("~") ? path73.join(process.env.HOME || os22.homedir(), raw.slice(2)) : path73.resolve(raw)
|
|
82513
82572
|
};
|
|
82514
82573
|
}
|
|
82515
82574
|
return { repoPath: raw };
|
|
@@ -82629,21 +82688,21 @@ function warnIfDockerUnavailable(status = detectDockerStatus()) {
|
|
|
82629
82688
|
}
|
|
82630
82689
|
|
|
82631
82690
|
// src/core/onboarding-preferences.ts
|
|
82632
|
-
var
|
|
82691
|
+
var fs67 = __toESM(require("fs"));
|
|
82633
82692
|
var os23 = __toESM(require("os"));
|
|
82634
|
-
var
|
|
82693
|
+
var path74 = __toESM(require("path"));
|
|
82635
82694
|
init_schema2();
|
|
82636
82695
|
function getOnboardingPreferencesPath() {
|
|
82637
82696
|
if (process.env.HAR_PREFERENCES_PATH) {
|
|
82638
|
-
return
|
|
82697
|
+
return path74.resolve(process.env.HAR_PREFERENCES_PATH);
|
|
82639
82698
|
}
|
|
82640
|
-
return
|
|
82699
|
+
return path74.join(os23.homedir(), ".har", "preferences.json");
|
|
82641
82700
|
}
|
|
82642
82701
|
function readOnboardingPreferences() {
|
|
82643
82702
|
const preferencePath = getOnboardingPreferencesPath();
|
|
82644
82703
|
try {
|
|
82645
|
-
if (!
|
|
82646
|
-
return OnboardingPreferencesSchema.parse(JSON.parse(
|
|
82704
|
+
if (!fs67.existsSync(preferencePath)) return OnboardingPreferencesSchema.parse({});
|
|
82705
|
+
return OnboardingPreferencesSchema.parse(JSON.parse(fs67.readFileSync(preferencePath, "utf8")));
|
|
82647
82706
|
} catch {
|
|
82648
82707
|
return OnboardingPreferencesSchema.parse({});
|
|
82649
82708
|
}
|
|
@@ -82668,8 +82727,8 @@ function writeOnboardingPreferences(overrides) {
|
|
|
82668
82727
|
};
|
|
82669
82728
|
const parsed = OnboardingPreferencesSchema.parse(preference);
|
|
82670
82729
|
const preferencePath = getOnboardingPreferencesPath();
|
|
82671
|
-
|
|
82672
|
-
|
|
82730
|
+
fs67.mkdirSync(path74.dirname(preferencePath), { recursive: true });
|
|
82731
|
+
fs67.writeFileSync(preferencePath, `${JSON.stringify(parsed, null, 2)}
|
|
82673
82732
|
`);
|
|
82674
82733
|
return parsed;
|
|
82675
82734
|
}
|
|
@@ -83055,7 +83114,7 @@ var envCommand = {
|
|
|
83055
83114
|
}
|
|
83056
83115
|
};
|
|
83057
83116
|
async function handleInit(argv) {
|
|
83058
|
-
const repoPath =
|
|
83117
|
+
const repoPath = path75.resolve(argv.repo);
|
|
83059
83118
|
const onboarding = resolveOnboardingOptions(argv);
|
|
83060
83119
|
header("har env init");
|
|
83061
83120
|
info(`Repository: ${repoPath}`);
|
|
@@ -83102,7 +83161,7 @@ async function handleInit(argv) {
|
|
|
83102
83161
|
}
|
|
83103
83162
|
}
|
|
83104
83163
|
async function handleMaintain(argv) {
|
|
83105
|
-
const repoPath =
|
|
83164
|
+
const repoPath = path75.resolve(argv.repo);
|
|
83106
83165
|
const onboarding = resolveOnboardingOptions(argv);
|
|
83107
83166
|
header("har env maintain");
|
|
83108
83167
|
info(`Repository: ${repoPath}`);
|
|
@@ -83257,7 +83316,7 @@ async function applyAgentIntegrations(options) {
|
|
|
83257
83316
|
}
|
|
83258
83317
|
}
|
|
83259
83318
|
async function handleAddPlugin(argv) {
|
|
83260
|
-
const repoPath =
|
|
83319
|
+
const repoPath = path75.resolve(argv.repo);
|
|
83261
83320
|
const available = listPluginIds();
|
|
83262
83321
|
if (argv.list) {
|
|
83263
83322
|
for (const id of available) {
|
|
@@ -83292,6 +83351,9 @@ async function handleAddPlugin(argv) {
|
|
|
83292
83351
|
console.error("");
|
|
83293
83352
|
console.error(` Docs: ${result.docsPath}`);
|
|
83294
83353
|
console.error("");
|
|
83354
|
+
info(`Adaptation prompt saved to ${result.adaptPromptPath}`);
|
|
83355
|
+
const promptContent = fs68.readFileSync(path75.join(repoPath, result.adaptPromptPath), "utf8");
|
|
83356
|
+
await offerAdaptationPromptClipboard(promptContent, { fileLabel: result.adaptPromptPath });
|
|
83295
83357
|
} catch (err) {
|
|
83296
83358
|
error(err.message);
|
|
83297
83359
|
return finishCommand(1);
|
|
@@ -83332,7 +83394,7 @@ async function handleAddStage(argv) {
|
|
|
83332
83394
|
});
|
|
83333
83395
|
}
|
|
83334
83396
|
async function handlePreflight(argv) {
|
|
83335
|
-
const repo =
|
|
83397
|
+
const repo = path75.resolve(argv.repo);
|
|
83336
83398
|
const agentId = validateAgentId(argv.id, repo);
|
|
83337
83399
|
const result = await preflightEnvironment({
|
|
83338
83400
|
repoPath: repo,
|
|
@@ -83348,7 +83410,7 @@ async function handlePreflight(argv) {
|
|
|
83348
83410
|
return finishCommand(result.code);
|
|
83349
83411
|
}
|
|
83350
83412
|
async function handleLaunch(argv) {
|
|
83351
|
-
const repo =
|
|
83413
|
+
const repo = path75.resolve(argv.repo);
|
|
83352
83414
|
const agentId = validateAgentId(argv.id, repo);
|
|
83353
83415
|
const result = await launchEnvironment({
|
|
83354
83416
|
repoPath: repo,
|
|
@@ -83390,7 +83452,7 @@ async function handleWorkLink(argv) {
|
|
|
83390
83452
|
error("Provide --link or both --source and --url");
|
|
83391
83453
|
return finishCommand(1);
|
|
83392
83454
|
}
|
|
83393
|
-
const harnessRoot = resolveHarnessRoot(
|
|
83455
|
+
const harnessRoot = resolveHarnessRoot(path75.resolve(argv.repo));
|
|
83394
83456
|
const links = argv.link ? [parseWorkLinkSpec(argv.link)] : [{ source: argv.source, url: argv.url, label: argv.label }];
|
|
83395
83457
|
try {
|
|
83396
83458
|
const record2 = addWorkUnitLinks(harnessRoot, argv.workId, links);
|
|
@@ -83416,7 +83478,7 @@ async function handleRecover(argv) {
|
|
|
83416
83478
|
});
|
|
83417
83479
|
}
|
|
83418
83480
|
async function handleVerify(argv) {
|
|
83419
|
-
const repo =
|
|
83481
|
+
const repo = path75.resolve(argv.repo);
|
|
83420
83482
|
const agentId = validateAgentId(argv.id, repo);
|
|
83421
83483
|
const result = await runVerification({
|
|
83422
83484
|
repoPath: repo,
|
|
@@ -83445,7 +83507,7 @@ async function handleVerify(argv) {
|
|
|
83445
83507
|
return finishCommand(result.code);
|
|
83446
83508
|
}
|
|
83447
83509
|
async function handleTeardown(argv) {
|
|
83448
|
-
const repo =
|
|
83510
|
+
const repo = path75.resolve(argv.repo);
|
|
83449
83511
|
const agentId = validateAgentId(argv.id, repo);
|
|
83450
83512
|
const result = await teardownEnvironment({
|
|
83451
83513
|
repoPath: repo,
|
|
@@ -83456,7 +83518,7 @@ async function handleTeardown(argv) {
|
|
|
83456
83518
|
return finishCommand(result.code);
|
|
83457
83519
|
}
|
|
83458
83520
|
async function handleComplete(argv) {
|
|
83459
|
-
const repo =
|
|
83521
|
+
const repo = path75.resolve(argv.repo);
|
|
83460
83522
|
const agentId = validateAgentId(argv.id, repo);
|
|
83461
83523
|
const result = await completeEnvironment({
|
|
83462
83524
|
repoPath: repo,
|
|
@@ -83477,7 +83539,7 @@ async function handleComplete(argv) {
|
|
|
83477
83539
|
return finishCommand(result.code);
|
|
83478
83540
|
}
|
|
83479
83541
|
async function handleSetupInfra(argv) {
|
|
83480
|
-
const repo =
|
|
83542
|
+
const repo = path75.resolve(argv.repo);
|
|
83481
83543
|
const result = await runStage({
|
|
83482
83544
|
repoPath: repo,
|
|
83483
83545
|
kind: "setup",
|
|
@@ -83487,7 +83549,7 @@ async function handleSetupInfra(argv) {
|
|
|
83487
83549
|
return finishCommand(result.code ?? (result.status === "pass" ? 0 : 1));
|
|
83488
83550
|
}
|
|
83489
83551
|
async function handleAgent(argv) {
|
|
83490
|
-
const repo =
|
|
83552
|
+
const repo = path75.resolve(argv.repo);
|
|
83491
83553
|
const agentId = validateAgentId(argv.id, repo);
|
|
83492
83554
|
const result = await runAgentOp({
|
|
83493
83555
|
repoPath: repo,
|
|
@@ -83498,7 +83560,7 @@ async function handleAgent(argv) {
|
|
|
83498
83560
|
return finishCommand(result.code);
|
|
83499
83561
|
}
|
|
83500
83562
|
async function handleDoctor(argv) {
|
|
83501
|
-
const repoPath =
|
|
83563
|
+
const repoPath = path75.resolve(argv.repo);
|
|
83502
83564
|
const report = runDoctor(repoPath);
|
|
83503
83565
|
if (argv.json) {
|
|
83504
83566
|
console.log(JSON.stringify(report, null, 2));
|
|
@@ -83527,7 +83589,7 @@ async function confirm(question) {
|
|
|
83527
83589
|
return /^y(es)?$/i.test(answer.trim());
|
|
83528
83590
|
}
|
|
83529
83591
|
async function handleEject(argv) {
|
|
83530
|
-
const repoPath = resolveHarnessRoot(
|
|
83592
|
+
const repoPath = resolveHarnessRoot(path75.resolve(argv.repo));
|
|
83531
83593
|
header("har env eject");
|
|
83532
83594
|
warn("This vendors the complete HAR runtime into .har/runtime/ and rewrites the");
|
|
83533
83595
|
warn(".har/*.sh scripts to execute it directly \u2014 from then on YOU OWN those files:");
|
|
@@ -83557,7 +83619,7 @@ async function handleEject(argv) {
|
|
|
83557
83619
|
return finishCommand(0);
|
|
83558
83620
|
}
|
|
83559
83621
|
async function handleAdopt(argv) {
|
|
83560
|
-
const repoPath = resolveHarnessRoot(
|
|
83622
|
+
const repoPath = resolveHarnessRoot(path75.resolve(argv.repo));
|
|
83561
83623
|
try {
|
|
83562
83624
|
const result = adoptHarness(repoPath);
|
|
83563
83625
|
success("Returned to managed shims \u2014 .har/runtime/ removed, eject flag cleared.");
|
|
@@ -83570,7 +83632,7 @@ async function handleAdopt(argv) {
|
|
|
83570
83632
|
return finishCommand(0);
|
|
83571
83633
|
}
|
|
83572
83634
|
async function handleStatus(argv) {
|
|
83573
|
-
const repoPath =
|
|
83635
|
+
const repoPath = path75.resolve(argv.repo);
|
|
83574
83636
|
const result = await getEnvironmentStatus({
|
|
83575
83637
|
repoPath,
|
|
83576
83638
|
capture: false
|
|
@@ -83583,7 +83645,7 @@ async function handleStatus(argv) {
|
|
|
83583
83645
|
if (result.stdout) process.stdout.write(result.stdout);
|
|
83584
83646
|
}
|
|
83585
83647
|
async function handleLogs(argv) {
|
|
83586
|
-
const repo =
|
|
83648
|
+
const repo = path75.resolve(argv.repo);
|
|
83587
83649
|
const agentId = validateAgentId(argv.id, repo);
|
|
83588
83650
|
const result = await getEnvironmentLogs({
|
|
83589
83651
|
repoPath: repo,
|
|
@@ -83595,7 +83657,7 @@ async function handleLogs(argv) {
|
|
|
83595
83657
|
return finishCommand(result.code);
|
|
83596
83658
|
}
|
|
83597
83659
|
async function handleRunStage(argv) {
|
|
83598
|
-
const repo =
|
|
83660
|
+
const repo = path75.resolve(argv.repo);
|
|
83599
83661
|
const agentId = validateAgentId(argv.id, repo);
|
|
83600
83662
|
if (!argv.stage) {
|
|
83601
83663
|
error("Missing stage id. Usage: har env run-stage <id> <stage> [args..]");
|
|
@@ -83621,7 +83683,7 @@ async function handleRunStage(argv) {
|
|
|
83621
83683
|
}
|
|
83622
83684
|
async function handleArtifacts(argv) {
|
|
83623
83685
|
const artifacts = listArtifacts({
|
|
83624
|
-
repoPath:
|
|
83686
|
+
repoPath: path75.resolve(argv.repo),
|
|
83625
83687
|
stageId: argv.stage
|
|
83626
83688
|
});
|
|
83627
83689
|
if (argv.json) {
|
|
@@ -83640,7 +83702,7 @@ async function handleArtifacts(argv) {
|
|
|
83640
83702
|
async function handleCleanup(argv) {
|
|
83641
83703
|
const keepValues = argv.keep?.split(",").map((value) => value.trim()).filter(Boolean);
|
|
83642
83704
|
const keep = parseCleanupKeepPins(keepValues);
|
|
83643
|
-
const repoPaths = argv.repo ? [
|
|
83705
|
+
const repoPaths = argv.repo ? [path75.resolve(argv.repo)] : void 0;
|
|
83644
83706
|
const plan = await discoverCleanupCandidates({
|
|
83645
83707
|
cwd: process.cwd(),
|
|
83646
83708
|
repoPaths,
|
|
@@ -83689,7 +83751,7 @@ async function handleCleanup(argv) {
|
|
|
83689
83751
|
return finishCommand(failed > 0 ? 1 : 0);
|
|
83690
83752
|
}
|
|
83691
83753
|
async function handleRunsList(argv) {
|
|
83692
|
-
const repoPath =
|
|
83754
|
+
const repoPath = path75.resolve(argv.repo);
|
|
83693
83755
|
const runs = listRuns(repoPath, { stageId: argv.stage, limit: argv.limit });
|
|
83694
83756
|
if (argv.json) {
|
|
83695
83757
|
process.stdout.write(JSON.stringify({ runs }, null, 2) + "\n");
|
|
@@ -83706,7 +83768,7 @@ async function handleRunsList(argv) {
|
|
|
83706
83768
|
}
|
|
83707
83769
|
}
|
|
83708
83770
|
async function handleRunsGet(argv) {
|
|
83709
|
-
const run2 = getRun(
|
|
83771
|
+
const run2 = getRun(path75.resolve(argv.repo), argv.runId);
|
|
83710
83772
|
if (!run2) {
|
|
83711
83773
|
error(`Run not found: ${argv.runId}`);
|
|
83712
83774
|
return finishCommand(1);
|
|
@@ -83823,7 +83885,7 @@ function printNextSteps() {
|
|
|
83823
83885
|
}
|
|
83824
83886
|
|
|
83825
83887
|
// src/cli/commands/control.ts
|
|
83826
|
-
var
|
|
83888
|
+
var path80 = __toESM(require("path"));
|
|
83827
83889
|
init_control_config();
|
|
83828
83890
|
init_portal_targets();
|
|
83829
83891
|
|
|
@@ -83831,8 +83893,8 @@ init_portal_targets();
|
|
|
83831
83893
|
init_control_config();
|
|
83832
83894
|
|
|
83833
83895
|
// src/core/portal-connect.ts
|
|
83834
|
-
var
|
|
83835
|
-
var
|
|
83896
|
+
var fs69 = __toESM(require("fs"));
|
|
83897
|
+
var path76 = __toESM(require("path"));
|
|
83836
83898
|
var import_crypto2 = require("crypto");
|
|
83837
83899
|
init_control_repo_path();
|
|
83838
83900
|
init_control_registry();
|
|
@@ -84001,8 +84063,8 @@ function remainingConnections(connections, usedAliases) {
|
|
|
84001
84063
|
// src/core/portal-connect.ts
|
|
84002
84064
|
init_portal_targets();
|
|
84003
84065
|
function attachRepoIfPresent(alias, repoPath) {
|
|
84004
|
-
const resolved =
|
|
84005
|
-
if (!
|
|
84066
|
+
const resolved = path76.resolve(repoPath ?? ".");
|
|
84067
|
+
if (!fs69.existsSync(resolved)) return null;
|
|
84006
84068
|
const canonical = canonicalizeControlRepoPath(resolved);
|
|
84007
84069
|
attachRepoPortalTarget(canonical, alias);
|
|
84008
84070
|
recordRepoForControlSync(canonical);
|
|
@@ -84069,8 +84131,8 @@ async function runPortalConnect(input) {
|
|
|
84069
84131
|
return { record: record2, attachedRepo, extraAttached, mappedInBrowser: true };
|
|
84070
84132
|
}
|
|
84071
84133
|
function listRegisteredReposForConnect(repoPath) {
|
|
84072
|
-
const resolved = repoPath ?
|
|
84073
|
-
const current = resolved &&
|
|
84134
|
+
const resolved = repoPath ? path76.resolve(repoPath) : null;
|
|
84135
|
+
const current = resolved && fs69.existsSync(resolved) ? canonicalizeControlRepoPath(resolved) : null;
|
|
84074
84136
|
return [.../* @__PURE__ */ new Set([...current ? [current] : [], ...listRegisteredRepos()])];
|
|
84075
84137
|
}
|
|
84076
84138
|
|
|
@@ -84386,21 +84448,21 @@ init_control_port();
|
|
|
84386
84448
|
init_control_sync();
|
|
84387
84449
|
|
|
84388
84450
|
// src/core/control-sync-selection.ts
|
|
84389
|
-
var
|
|
84451
|
+
var fs70 = __toESM(require("fs"));
|
|
84390
84452
|
var os24 = __toESM(require("os"));
|
|
84391
|
-
var
|
|
84453
|
+
var path77 = __toESM(require("path"));
|
|
84392
84454
|
init_control_repo_path();
|
|
84393
84455
|
function getSelectionPath() {
|
|
84394
84456
|
if (process.env.HAR_CONTROL_SYNC_SELECTION_PATH) {
|
|
84395
|
-
return
|
|
84457
|
+
return path77.resolve(process.env.HAR_CONTROL_SYNC_SELECTION_PATH);
|
|
84396
84458
|
}
|
|
84397
|
-
return
|
|
84459
|
+
return path77.join(os24.homedir(), ".har", "sync-selection.json");
|
|
84398
84460
|
}
|
|
84399
84461
|
function readSyncSelection() {
|
|
84400
84462
|
const selectionPath = getSelectionPath();
|
|
84401
84463
|
try {
|
|
84402
|
-
if (!
|
|
84403
|
-
const parsed = JSON.parse(
|
|
84464
|
+
if (!fs70.existsSync(selectionPath)) return null;
|
|
84465
|
+
const parsed = JSON.parse(fs70.readFileSync(selectionPath, "utf8"));
|
|
84404
84466
|
if (!Array.isArray(parsed.repos)) return null;
|
|
84405
84467
|
return parsed.repos.map((repoPath) => canonicalizeControlRepoPath(repoPath));
|
|
84406
84468
|
} catch {
|
|
@@ -84410,8 +84472,8 @@ function readSyncSelection() {
|
|
|
84410
84472
|
function writeSyncSelection(repos) {
|
|
84411
84473
|
const selectionPath = getSelectionPath();
|
|
84412
84474
|
const canonical = Array.from(new Set(repos.map((repoPath) => canonicalizeControlRepoPath(repoPath))));
|
|
84413
|
-
|
|
84414
|
-
|
|
84475
|
+
fs70.mkdirSync(path77.dirname(selectionPath), { recursive: true });
|
|
84476
|
+
fs70.writeFileSync(selectionPath, JSON.stringify({ repos: canonical }, null, 2) + "\n");
|
|
84415
84477
|
}
|
|
84416
84478
|
function resolveSyncSelection(input) {
|
|
84417
84479
|
const { discovered, stored, forceSelect, isTTY } = input;
|
|
@@ -84438,8 +84500,8 @@ function resolveSyncSelection(input) {
|
|
|
84438
84500
|
}
|
|
84439
84501
|
|
|
84440
84502
|
// src/core/control-unregister.ts
|
|
84441
|
-
var
|
|
84442
|
-
var
|
|
84503
|
+
var fs71 = __toESM(require("fs"));
|
|
84504
|
+
var path78 = __toESM(require("path"));
|
|
84443
84505
|
init_control_repo_path();
|
|
84444
84506
|
init_control_registry();
|
|
84445
84507
|
init_control_config();
|
|
@@ -84449,9 +84511,9 @@ function listUnregisterWorktreeCandidates(repoPath) {
|
|
|
84449
84511
|
const harnessRoot = canonicalizeControlRepoPath(repoPath);
|
|
84450
84512
|
const byPath = /* @__PURE__ */ new Map();
|
|
84451
84513
|
const add = (partial2) => {
|
|
84452
|
-
const resolved =
|
|
84514
|
+
const resolved = path78.resolve(partial2.worktreePath);
|
|
84453
84515
|
if (!resolved || resolved === harnessRoot) return;
|
|
84454
|
-
const exists = partial2.exists ??
|
|
84516
|
+
const exists = partial2.exists ?? fs71.existsSync(resolved);
|
|
84455
84517
|
const prev = byPath.get(resolved);
|
|
84456
84518
|
if (prev) {
|
|
84457
84519
|
byPath.set(resolved, {
|
|
@@ -84565,28 +84627,28 @@ async function teardownWorktrees(repoPath, candidates, dryRun) {
|
|
|
84565
84627
|
trigger: "cli"
|
|
84566
84628
|
});
|
|
84567
84629
|
if (result.code !== 0) {
|
|
84568
|
-
if (
|
|
84569
|
-
|
|
84630
|
+
if (fs71.existsSync(candidate.worktreePath)) {
|
|
84631
|
+
fs71.rmSync(candidate.worktreePath, { recursive: true, force: true });
|
|
84570
84632
|
}
|
|
84571
84633
|
}
|
|
84572
84634
|
outcomes.push({
|
|
84573
84635
|
path: candidate.worktreePath,
|
|
84574
84636
|
agentId: candidate.agentId,
|
|
84575
|
-
deleted: !
|
|
84576
|
-
error: result.code !== 0 &&
|
|
84637
|
+
deleted: !fs71.existsSync(candidate.worktreePath),
|
|
84638
|
+
error: result.code !== 0 && fs71.existsSync(candidate.worktreePath) ? result.stderr : void 0
|
|
84577
84639
|
});
|
|
84578
84640
|
} catch (err) {
|
|
84579
84641
|
const message = err instanceof Error ? err.message : String(err);
|
|
84580
84642
|
try {
|
|
84581
|
-
if (
|
|
84582
|
-
|
|
84643
|
+
if (fs71.existsSync(candidate.worktreePath)) {
|
|
84644
|
+
fs71.rmSync(candidate.worktreePath, { recursive: true, force: true });
|
|
84583
84645
|
}
|
|
84584
84646
|
} catch {
|
|
84585
84647
|
}
|
|
84586
84648
|
outcomes.push({
|
|
84587
84649
|
path: candidate.worktreePath,
|
|
84588
84650
|
agentId: candidate.agentId,
|
|
84589
|
-
deleted: !
|
|
84651
|
+
deleted: !fs71.existsSync(candidate.worktreePath),
|
|
84590
84652
|
error: message
|
|
84591
84653
|
});
|
|
84592
84654
|
}
|
|
@@ -84649,16 +84711,16 @@ init_control_config();
|
|
|
84649
84711
|
init_control_registry();
|
|
84650
84712
|
|
|
84651
84713
|
// src/core/harness-scrub.ts
|
|
84652
|
-
var
|
|
84653
|
-
var
|
|
84714
|
+
var fs72 = __toESM(require("fs"));
|
|
84715
|
+
var path79 = __toESM(require("path"));
|
|
84654
84716
|
var HARNESS_SCRUB_DIRS = ["runs", "validations", "state", "slots"];
|
|
84655
84717
|
function scrubLocalHarnessDirs(repoPath) {
|
|
84656
84718
|
const results = [];
|
|
84657
|
-
const resolved =
|
|
84658
|
-
if (!
|
|
84719
|
+
const resolved = path79.resolve(repoPath);
|
|
84720
|
+
if (!fs72.existsSync(resolved)) {
|
|
84659
84721
|
for (const directory of HARNESS_SCRUB_DIRS) {
|
|
84660
84722
|
results.push({
|
|
84661
|
-
path:
|
|
84723
|
+
path: path79.join(resolved, ".har", directory),
|
|
84662
84724
|
directory,
|
|
84663
84725
|
deleted: false,
|
|
84664
84726
|
error: "repository path does not exist"
|
|
@@ -84667,24 +84729,24 @@ function scrubLocalHarnessDirs(repoPath) {
|
|
|
84667
84729
|
return results;
|
|
84668
84730
|
}
|
|
84669
84731
|
for (const directory of HARNESS_SCRUB_DIRS) {
|
|
84670
|
-
const target =
|
|
84671
|
-
if (!
|
|
84732
|
+
const target = path79.join(resolved, ".har", directory);
|
|
84733
|
+
if (!fs72.existsSync(target)) {
|
|
84672
84734
|
results.push({ path: target, directory, deleted: true });
|
|
84673
84735
|
continue;
|
|
84674
84736
|
}
|
|
84675
84737
|
try {
|
|
84676
|
-
|
|
84738
|
+
fs72.rmSync(target, { recursive: true, force: true });
|
|
84677
84739
|
results.push({
|
|
84678
84740
|
path: target,
|
|
84679
84741
|
directory,
|
|
84680
|
-
deleted: !
|
|
84681
|
-
error:
|
|
84742
|
+
deleted: !fs72.existsSync(target),
|
|
84743
|
+
error: fs72.existsSync(target) ? "failed to remove directory" : void 0
|
|
84682
84744
|
});
|
|
84683
84745
|
} catch (err) {
|
|
84684
84746
|
results.push({
|
|
84685
84747
|
path: target,
|
|
84686
84748
|
directory,
|
|
84687
|
-
deleted: !
|
|
84749
|
+
deleted: !fs72.existsSync(target),
|
|
84688
84750
|
error: err instanceof Error ? err.message : String(err)
|
|
84689
84751
|
});
|
|
84690
84752
|
}
|
|
@@ -84695,7 +84757,7 @@ function scrubLocalHarnessForRepos(repoPaths) {
|
|
|
84695
84757
|
const results = [];
|
|
84696
84758
|
const seen = /* @__PURE__ */ new Set();
|
|
84697
84759
|
for (const repoPath of repoPaths) {
|
|
84698
|
-
const key =
|
|
84760
|
+
const key = path79.resolve(repoPath);
|
|
84699
84761
|
if (seen.has(key)) continue;
|
|
84700
84762
|
seen.add(key);
|
|
84701
84763
|
results.push(...scrubLocalHarnessDirs(key));
|
|
@@ -84988,7 +85050,7 @@ async function handleDown() {
|
|
|
84988
85050
|
return finishCommand(code);
|
|
84989
85051
|
}
|
|
84990
85052
|
async function handleRegister(argv) {
|
|
84991
|
-
const repoPath =
|
|
85053
|
+
const repoPath = path80.resolve(argv.repo);
|
|
84992
85054
|
header("har control register");
|
|
84993
85055
|
info(`Repository: ${repoPath}`);
|
|
84994
85056
|
try {
|
|
@@ -85086,7 +85148,7 @@ async function handleReset(argv) {
|
|
|
85086
85148
|
}
|
|
85087
85149
|
}
|
|
85088
85150
|
async function handleUnregister(argv) {
|
|
85089
|
-
const repoPath =
|
|
85151
|
+
const repoPath = path80.resolve(argv.repo);
|
|
85090
85152
|
const worktrees = listUnregisterWorktreeCandidates(repoPath);
|
|
85091
85153
|
try {
|
|
85092
85154
|
let deleteWorktrees = argv.deleteWorktrees;
|
|
@@ -85367,12 +85429,12 @@ async function handleTrajectory(argv) {
|
|
|
85367
85429
|
}
|
|
85368
85430
|
|
|
85369
85431
|
// src/cli/commands/hooks.ts
|
|
85370
|
-
var
|
|
85432
|
+
var path82 = __toESM(require("path"));
|
|
85371
85433
|
init_hooks();
|
|
85372
85434
|
|
|
85373
85435
|
// src/core/claude-hooks.ts
|
|
85374
|
-
var
|
|
85375
|
-
var
|
|
85436
|
+
var fs73 = __toESM(require("fs"));
|
|
85437
|
+
var path81 = __toESM(require("path"));
|
|
85376
85438
|
init_paths();
|
|
85377
85439
|
var CLAUDE_GUARD_RELATIVE_PATH = ".har/hooks/claude-worktree-guard.sh";
|
|
85378
85440
|
var CLAUDE_SETTINGS_RELATIVE_PATH = ".claude/settings.json";
|
|
@@ -85384,8 +85446,8 @@ function isHarGuardEntry(entry) {
|
|
|
85384
85446
|
);
|
|
85385
85447
|
}
|
|
85386
85448
|
function readSettings(settingsPath) {
|
|
85387
|
-
if (!
|
|
85388
|
-
const raw =
|
|
85449
|
+
if (!fs73.existsSync(settingsPath)) return {};
|
|
85450
|
+
const raw = fs73.readFileSync(settingsPath, "utf8").trim();
|
|
85389
85451
|
if (raw === "") return {};
|
|
85390
85452
|
const parsed = JSON.parse(raw);
|
|
85391
85453
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
@@ -85394,19 +85456,19 @@ function readSettings(settingsPath) {
|
|
|
85394
85456
|
return parsed;
|
|
85395
85457
|
}
|
|
85396
85458
|
function writeSettings(settingsPath, settings) {
|
|
85397
|
-
|
|
85398
|
-
|
|
85459
|
+
fs73.mkdirSync(path81.dirname(settingsPath), { recursive: true });
|
|
85460
|
+
fs73.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
85399
85461
|
}
|
|
85400
85462
|
function installClaudeGuard(repoPath) {
|
|
85401
85463
|
const templatePath = resolveTemplateFile("claude-worktree-guard.sh.template");
|
|
85402
85464
|
if (!templatePath) {
|
|
85403
85465
|
throw new Error("Guard template not found (claude-worktree-guard.sh.template). Run npm run build.");
|
|
85404
85466
|
}
|
|
85405
|
-
const guardScript =
|
|
85406
|
-
|
|
85407
|
-
|
|
85408
|
-
|
|
85409
|
-
const settingsPath =
|
|
85467
|
+
const guardScript = path81.join(repoPath, CLAUDE_GUARD_RELATIVE_PATH);
|
|
85468
|
+
fs73.mkdirSync(path81.dirname(guardScript), { recursive: true });
|
|
85469
|
+
fs73.copyFileSync(templatePath, guardScript);
|
|
85470
|
+
fs73.chmodSync(guardScript, 493);
|
|
85471
|
+
const settingsPath = path81.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
|
|
85410
85472
|
const settings = readSettings(settingsPath);
|
|
85411
85473
|
const hooks = settings.hooks ?? {};
|
|
85412
85474
|
const preToolUse = (hooks.PreToolUse ?? []).filter((entry) => !isHarGuardEntry(entry));
|
|
@@ -85420,15 +85482,15 @@ function installClaudeGuard(repoPath) {
|
|
|
85420
85482
|
}
|
|
85421
85483
|
function uninstallClaudeGuard(repoPath) {
|
|
85422
85484
|
let removed = false;
|
|
85423
|
-
const guardScript =
|
|
85424
|
-
if (
|
|
85425
|
-
|
|
85485
|
+
const guardScript = path81.join(repoPath, CLAUDE_GUARD_RELATIVE_PATH);
|
|
85486
|
+
if (fs73.existsSync(guardScript)) {
|
|
85487
|
+
fs73.rmSync(guardScript);
|
|
85426
85488
|
removed = true;
|
|
85427
|
-
const parent =
|
|
85428
|
-
if (
|
|
85489
|
+
const parent = path81.dirname(guardScript);
|
|
85490
|
+
if (fs73.existsSync(parent) && fs73.readdirSync(parent).length === 0) fs73.rmdirSync(parent);
|
|
85429
85491
|
}
|
|
85430
|
-
const settingsPath =
|
|
85431
|
-
if (
|
|
85492
|
+
const settingsPath = path81.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
|
|
85493
|
+
if (fs73.existsSync(settingsPath)) {
|
|
85432
85494
|
const settings = readSettings(settingsPath);
|
|
85433
85495
|
const preToolUse = settings.hooks?.PreToolUse;
|
|
85434
85496
|
if (preToolUse) {
|
|
@@ -85453,8 +85515,8 @@ function uninstallClaudeGuard(repoPath) {
|
|
|
85453
85515
|
return { removed };
|
|
85454
85516
|
}
|
|
85455
85517
|
function claudeGuardInstalled(repoPath) {
|
|
85456
|
-
const settingsPath =
|
|
85457
|
-
if (!
|
|
85518
|
+
const settingsPath = path81.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
|
|
85519
|
+
if (!fs73.existsSync(settingsPath)) return false;
|
|
85458
85520
|
try {
|
|
85459
85521
|
const settings = readSettings(settingsPath);
|
|
85460
85522
|
return (settings.hooks?.PreToolUse ?? []).some(isHarGuardEntry);
|
|
@@ -85471,7 +85533,7 @@ function repoOption(y) {
|
|
|
85471
85533
|
function handleInstall2(argv) {
|
|
85472
85534
|
try {
|
|
85473
85535
|
if (argv.claude) {
|
|
85474
|
-
const result2 = installClaudeGuard(
|
|
85536
|
+
const result2 = installClaudeGuard(path82.resolve(argv.repo));
|
|
85475
85537
|
success("Claude Code worktree guard installed.");
|
|
85476
85538
|
info(`Guard script: ${result2.guardScript}`);
|
|
85477
85539
|
info(`Settings: ${result2.settingsPath} (PreToolUse: Edit|Write|MultiEdit|NotebookEdit)`);
|
|
@@ -85479,7 +85541,7 @@ function handleInstall2(argv) {
|
|
|
85479
85541
|
info("Commit both files so the guard travels with the repo.");
|
|
85480
85542
|
return;
|
|
85481
85543
|
}
|
|
85482
|
-
const result = installHooks({ repoPath:
|
|
85544
|
+
const result = installHooks({ repoPath: path82.resolve(argv.repo), force: argv.force });
|
|
85483
85545
|
success(`Commit gate installed in ${result.hooksDir}`);
|
|
85484
85546
|
info(`pre-commit: ${result.preCommit}, post-commit: ${result.postCommit}`);
|
|
85485
85547
|
info("Commits of unverified change batches will be blocked in agent worktrees.");
|
|
@@ -85492,7 +85554,7 @@ function handleInstall2(argv) {
|
|
|
85492
85554
|
function handleUninstall(argv) {
|
|
85493
85555
|
try {
|
|
85494
85556
|
if (argv.claude) {
|
|
85495
|
-
const result2 = uninstallClaudeGuard(
|
|
85557
|
+
const result2 = uninstallClaudeGuard(path82.resolve(argv.repo));
|
|
85496
85558
|
if (result2.removed) {
|
|
85497
85559
|
success("Claude Code worktree guard removed.");
|
|
85498
85560
|
} else {
|
|
@@ -85500,7 +85562,7 @@ function handleUninstall(argv) {
|
|
|
85500
85562
|
}
|
|
85501
85563
|
return;
|
|
85502
85564
|
}
|
|
85503
|
-
const result = uninstallHooks(
|
|
85565
|
+
const result = uninstallHooks(path82.resolve(argv.repo));
|
|
85504
85566
|
if (result.removed) {
|
|
85505
85567
|
success(`Commit gate removed from ${result.hooksDir}`);
|
|
85506
85568
|
} else {
|
|
@@ -85513,7 +85575,7 @@ function handleUninstall(argv) {
|
|
|
85513
85575
|
}
|
|
85514
85576
|
function handleStatus2(argv) {
|
|
85515
85577
|
try {
|
|
85516
|
-
const status = getHooksStatus(
|
|
85578
|
+
const status = getHooksStatus(path82.resolve(argv.repo));
|
|
85517
85579
|
if (argv.json) {
|
|
85518
85580
|
process.stdout.write(`${JSON.stringify(status, null, 2)}
|
|
85519
85581
|
`);
|
|
@@ -85531,7 +85593,7 @@ function handleStatus2(argv) {
|
|
|
85531
85593
|
);
|
|
85532
85594
|
info(`Effective: ${status.effectiveMode} (in this checkout)`);
|
|
85533
85595
|
info(
|
|
85534
|
-
`Claude guard: ${claudeGuardInstalled(
|
|
85596
|
+
`Claude guard: ${claudeGuardInstalled(path82.resolve(argv.repo)) ? `installed (${CLAUDE_GUARD_RELATIVE_PATH})` : "not installed"}`
|
|
85535
85597
|
);
|
|
85536
85598
|
} catch (err) {
|
|
85537
85599
|
error(err instanceof Error ? err.message : String(err));
|
|
@@ -85792,10 +85854,10 @@ function assignProp(target, prop, value) {
|
|
|
85792
85854
|
configurable: true
|
|
85793
85855
|
});
|
|
85794
85856
|
}
|
|
85795
|
-
function getElementAtPath(obj,
|
|
85796
|
-
if (!
|
|
85857
|
+
function getElementAtPath(obj, path89) {
|
|
85858
|
+
if (!path89)
|
|
85797
85859
|
return obj;
|
|
85798
|
-
return
|
|
85860
|
+
return path89.reduce((acc, key) => acc?.[key], obj);
|
|
85799
85861
|
}
|
|
85800
85862
|
function promiseAllObject(promisesObj) {
|
|
85801
85863
|
const keys = Object.keys(promisesObj);
|
|
@@ -86115,11 +86177,11 @@ function aborted(x, startIndex = 0) {
|
|
|
86115
86177
|
}
|
|
86116
86178
|
return false;
|
|
86117
86179
|
}
|
|
86118
|
-
function prefixIssues(
|
|
86180
|
+
function prefixIssues(path89, issues) {
|
|
86119
86181
|
return issues.map((iss) => {
|
|
86120
86182
|
var _a2;
|
|
86121
86183
|
(_a2 = iss).path ?? (_a2.path = []);
|
|
86122
|
-
iss.path.unshift(
|
|
86184
|
+
iss.path.unshift(path89);
|
|
86123
86185
|
return iss;
|
|
86124
86186
|
});
|
|
86125
86187
|
}
|
|
@@ -92593,7 +92655,7 @@ var Server = class extends Protocol {
|
|
|
92593
92655
|
};
|
|
92594
92656
|
|
|
92595
92657
|
// src/mcp/server.ts
|
|
92596
|
-
var
|
|
92658
|
+
var path83 = __toESM(require("path"));
|
|
92597
92659
|
|
|
92598
92660
|
// node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
|
|
92599
92661
|
var import_node_process3 = __toESM(require("node:process"), 1);
|
|
@@ -93214,7 +93276,8 @@ async function handleMcpToolCall(toolName, args, defaultRepo = ".") {
|
|
|
93214
93276
|
warnings: result.warnings,
|
|
93215
93277
|
nextSteps: result.nextSteps,
|
|
93216
93278
|
docsPath: result.docsPath,
|
|
93217
|
-
source: result.source
|
|
93279
|
+
source: result.source,
|
|
93280
|
+
adaptPromptPath: result.adaptPromptPath
|
|
93218
93281
|
});
|
|
93219
93282
|
}
|
|
93220
93283
|
case "har_launch_environment": {
|
|
@@ -93416,7 +93479,7 @@ async function handleMcpToolCall(toolName, args, defaultRepo = ".") {
|
|
|
93416
93479
|
const input = ControlUpInputSchema.parse({ ...args, repo });
|
|
93417
93480
|
const result = await startControlAndSync({
|
|
93418
93481
|
detach: input.detach,
|
|
93419
|
-
cwd:
|
|
93482
|
+
cwd: path83.resolve(input.repo)
|
|
93420
93483
|
});
|
|
93421
93484
|
if (result.code !== 0) {
|
|
93422
93485
|
return {
|
|
@@ -93480,11 +93543,11 @@ var mcpCommand = {
|
|
|
93480
93543
|
};
|
|
93481
93544
|
|
|
93482
93545
|
// src/cli/commands/onboard.ts
|
|
93483
|
-
var
|
|
93546
|
+
var path85 = __toESM(require("path"));
|
|
93484
93547
|
init_stages();
|
|
93485
93548
|
|
|
93486
93549
|
// src/core/onboarding.ts
|
|
93487
|
-
var
|
|
93550
|
+
var path84 = __toESM(require("path"));
|
|
93488
93551
|
init_control_config();
|
|
93489
93552
|
init_control_sync();
|
|
93490
93553
|
init_otel_hooks();
|
|
@@ -93628,7 +93691,7 @@ async function defaultEnsureControl(options) {
|
|
|
93628
93691
|
return { started: true, apiUrl: result.apiUrl };
|
|
93629
93692
|
}
|
|
93630
93693
|
async function runOnboarding(options, deps = {}) {
|
|
93631
|
-
const repoPath =
|
|
93694
|
+
const repoPath = path84.resolve(options.repoPath);
|
|
93632
93695
|
const applyTelemetry = deps.applyTelemetry ?? applyOnboardingTelemetry;
|
|
93633
93696
|
const ensureControl = deps.ensureControl ?? defaultEnsureControl;
|
|
93634
93697
|
const init = deps.initHarness ?? initHarness;
|
|
@@ -93826,7 +93889,7 @@ async function promptChoices(args, docker) {
|
|
|
93826
93889
|
};
|
|
93827
93890
|
}
|
|
93828
93891
|
const pluginChoices = listPluginChoices();
|
|
93829
|
-
const repoPath =
|
|
93892
|
+
const repoPath = path85.resolve(args.repo);
|
|
93830
93893
|
const alreadyPresent = harnessExists(repoPath);
|
|
93831
93894
|
const needProfile = !alreadyPresent && !args.skipInit && args.profile === void 0;
|
|
93832
93895
|
const needAgentSlots = shouldConfigureSlots && flaggedSlots === void 0;
|
|
@@ -93947,7 +94010,7 @@ function printSummary(result) {
|
|
|
93947
94010
|
console.error("");
|
|
93948
94011
|
}
|
|
93949
94012
|
async function handleOnboard(argv) {
|
|
93950
|
-
const repoPath =
|
|
94013
|
+
const repoPath = path85.resolve(argv.repo);
|
|
93951
94014
|
header("har onboard");
|
|
93952
94015
|
info(`Repository: ${repoPath}`);
|
|
93953
94016
|
try {
|
|
@@ -94065,23 +94128,23 @@ var onboardCommand = {
|
|
|
94065
94128
|
};
|
|
94066
94129
|
|
|
94067
94130
|
// src/cli/commands/plugin.ts
|
|
94068
|
-
var
|
|
94131
|
+
var path87 = __toESM(require("path"));
|
|
94069
94132
|
|
|
94070
94133
|
// src/harness/plugin-create.ts
|
|
94071
|
-
var
|
|
94072
|
-
var
|
|
94134
|
+
var fs74 = __toESM(require("fs"));
|
|
94135
|
+
var path86 = __toESM(require("path"));
|
|
94073
94136
|
init_paths();
|
|
94074
94137
|
init_schema2();
|
|
94075
94138
|
var PLUGIN_ID_PATTERN = /^[a-z0-9][a-z0-9._-]*$/;
|
|
94076
94139
|
function renderSkeleton(templatePath, tokens) {
|
|
94077
|
-
let content =
|
|
94140
|
+
let content = fs74.readFileSync(templatePath, "utf8");
|
|
94078
94141
|
for (const [token, value] of Object.entries(tokens)) {
|
|
94079
94142
|
content = content.replace(new RegExp(token, "g"), value);
|
|
94080
94143
|
}
|
|
94081
94144
|
return content;
|
|
94082
94145
|
}
|
|
94083
94146
|
function createLocalPlugin(repoPath, options) {
|
|
94084
|
-
const resolved =
|
|
94147
|
+
const resolved = path86.resolve(repoPath);
|
|
94085
94148
|
if (!harnessExists(resolved)) {
|
|
94086
94149
|
throw new Error('No .har/ harness found. Run "har env init" first.');
|
|
94087
94150
|
}
|
|
@@ -94097,9 +94160,9 @@ function createLocalPlugin(repoPath, options) {
|
|
|
94097
94160
|
`Invalid stage kind "${kind}". Available: ${HarnessStageKindSchema.options.join(", ")}`
|
|
94098
94161
|
);
|
|
94099
94162
|
}
|
|
94100
|
-
const pluginDir =
|
|
94163
|
+
const pluginDir = path86.join(resolved, LOCAL_PLUGINS_DIR, id);
|
|
94101
94164
|
const pluginDirRel = `${LOCAL_PLUGINS_DIR}/${id}`;
|
|
94102
|
-
if (
|
|
94165
|
+
if (fs74.existsSync(pluginDir) && !options.force) {
|
|
94103
94166
|
throw new Error(`Plugin already exists: ${pluginDirRel}/. Use --force to overwrite.`);
|
|
94104
94167
|
}
|
|
94105
94168
|
const description = options.description ?? `Custom ${kind} stage (local plugin: ${id})`;
|
|
@@ -94141,16 +94204,16 @@ function createLocalPlugin(repoPath, options) {
|
|
|
94141
94204
|
});
|
|
94142
94205
|
const filesWritten = [];
|
|
94143
94206
|
const write = (rel, content, executable = false) => {
|
|
94144
|
-
const abs =
|
|
94145
|
-
|
|
94146
|
-
|
|
94147
|
-
if (executable)
|
|
94207
|
+
const abs = path86.join(pluginDir, rel);
|
|
94208
|
+
fs74.mkdirSync(path86.dirname(abs), { recursive: true });
|
|
94209
|
+
fs74.writeFileSync(abs, content);
|
|
94210
|
+
if (executable) fs74.chmodSync(abs, 493);
|
|
94148
94211
|
filesWritten.push(`${pluginDirRel}/${rel}`);
|
|
94149
94212
|
};
|
|
94150
94213
|
write("template.manifest.json", `${JSON.stringify(manifest, null, 2)}
|
|
94151
94214
|
`);
|
|
94152
94215
|
const stageScript = renderSkeleton(
|
|
94153
|
-
|
|
94216
|
+
path86.join(resolveTemplatesDir(), "plugins", "custom-stage-skeleton.sh"),
|
|
94154
94217
|
{
|
|
94155
94218
|
__STAGE_ID__: id,
|
|
94156
94219
|
__STAGE_KIND__: kind,
|
|
@@ -94159,7 +94222,7 @@ function createLocalPlugin(repoPath, options) {
|
|
|
94159
94222
|
);
|
|
94160
94223
|
write(`stages/${id}.sh`, stageScript, true);
|
|
94161
94224
|
const readme = renderSkeleton(
|
|
94162
|
-
|
|
94225
|
+
path86.join(resolveTemplatesDir(), "plugins", "local-plugin-skeleton", "README.md"),
|
|
94163
94226
|
{ __PLUGIN_ID__: id }
|
|
94164
94227
|
);
|
|
94165
94228
|
write("README.md", readme);
|
|
@@ -94177,6 +94240,7 @@ function createLocalPlugin(repoPath, options) {
|
|
|
94177
94240
|
nextSteps: [
|
|
94178
94241
|
`Edit ${pluginDirRel}/stages/${id}.sh \u2014 replace the TODO block with the real check`,
|
|
94179
94242
|
`Install it: har env add-plugin ${id} (re-run with --force after changes)`,
|
|
94243
|
+
`Installing writes .har/ADAPT-PROMPT-${id}.md \u2014 a ready adaptation prompt for your coding agent`,
|
|
94180
94244
|
`Document what it checks in ${pluginDirRel}/README.md`,
|
|
94181
94245
|
"Publishing later (npm/git) needs zero format changes \u2014 see the README"
|
|
94182
94246
|
]
|
|
@@ -94190,7 +94254,7 @@ async function handlePluginCreate(argv) {
|
|
|
94190
94254
|
error('Missing plugin id. Usage: har plugin create <id> [--kind test] [--description "..."]');
|
|
94191
94255
|
return finishCommand(1);
|
|
94192
94256
|
}
|
|
94193
|
-
const repoPath =
|
|
94257
|
+
const repoPath = path87.resolve(argv.repo);
|
|
94194
94258
|
header("har plugin create");
|
|
94195
94259
|
info(`Repository: ${repoPath}`);
|
|
94196
94260
|
info(`Plugin: ${argv.id}`);
|
|
@@ -94221,7 +94285,7 @@ async function handlePluginCreate(argv) {
|
|
|
94221
94285
|
}
|
|
94222
94286
|
}
|
|
94223
94287
|
function handlePluginList(argv) {
|
|
94224
|
-
const repoPath =
|
|
94288
|
+
const repoPath = path87.resolve(argv.repo);
|
|
94225
94289
|
for (const id of listPluginIds()) {
|
|
94226
94290
|
console.log(`${id} (bundled)`);
|
|
94227
94291
|
}
|
|
@@ -94388,7 +94452,7 @@ var preferencesCommand = {
|
|
|
94388
94452
|
};
|
|
94389
94453
|
|
|
94390
94454
|
// src/cli/commands/telemetry.ts
|
|
94391
|
-
var
|
|
94455
|
+
var path88 = __toESM(require("path"));
|
|
94392
94456
|
init_control_config();
|
|
94393
94457
|
init_control_sync();
|
|
94394
94458
|
init_manifest();
|
|
@@ -94481,7 +94545,7 @@ async function handleOff() {
|
|
|
94481
94545
|
info("Mission Control will not auto-start. Existing usage rows are kept.");
|
|
94482
94546
|
}
|
|
94483
94547
|
async function handleWriteEnv(argv) {
|
|
94484
|
-
const repoPath =
|
|
94548
|
+
const repoPath = path88.resolve(argv.repo);
|
|
94485
94549
|
const harnessRoot = resolveHarnessRoot(repoPath);
|
|
94486
94550
|
const session = readSlotRegistry(harnessRoot, argv.agentId);
|
|
94487
94551
|
const workDir = argv.workDir ?? session?.workDir ?? repoPath;
|
|
@@ -94493,7 +94557,7 @@ async function handleWriteEnv(argv) {
|
|
|
94493
94557
|
suffix,
|
|
94494
94558
|
createdAt: session?.createdAt
|
|
94495
94559
|
});
|
|
94496
|
-
const envFile = argv.envFile ??
|
|
94560
|
+
const envFile = argv.envFile ?? path88.join(workDir, `.env.agent.${argv.agentId}`);
|
|
94497
94561
|
const attrs = {
|
|
94498
94562
|
sessionKey,
|
|
94499
94563
|
agentId: argv.agentId,
|
|
@@ -94509,7 +94573,7 @@ async function handleWriteEnv(argv) {
|
|
|
94509
94573
|
success(`Wrote session attribution to ${envFile}`);
|
|
94510
94574
|
}
|
|
94511
94575
|
function handlePrintEnv(argv) {
|
|
94512
|
-
const repoPath =
|
|
94576
|
+
const repoPath = path88.resolve(argv.repo);
|
|
94513
94577
|
const workDir = argv.workDir ?? repoPath;
|
|
94514
94578
|
const sessionKey = buildSessionKey({
|
|
94515
94579
|
branch: argv.branch,
|