@notiamo/runner 0.2.0 → 0.2.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/README.md +39 -0
- package/dist/cli.js +441 -259
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1045,8 +1045,8 @@ var require_safePathNames = __commonJS({
|
|
|
1045
1045
|
})();
|
|
1046
1046
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1047
1047
|
exports.isSafePathName = isSafePathName;
|
|
1048
|
-
var
|
|
1049
|
-
function isSafePathName(name, localPath =
|
|
1048
|
+
var path14 = __importStar(__require("path"));
|
|
1049
|
+
function isSafePathName(name, localPath = path14) {
|
|
1050
1050
|
if (!name || name === "." || name === ".." || name.includes("/")) {
|
|
1051
1051
|
return false;
|
|
1052
1052
|
}
|
|
@@ -1704,8 +1704,8 @@ var require_Client = __commonJS({
|
|
|
1704
1704
|
/**
|
|
1705
1705
|
* Set the working directory.
|
|
1706
1706
|
*/
|
|
1707
|
-
async cd(
|
|
1708
|
-
const validPath = await this.protectWhitespace(
|
|
1707
|
+
async cd(path14) {
|
|
1708
|
+
const validPath = await this.protectWhitespace(path14);
|
|
1709
1709
|
return this.send("CWD " + validPath);
|
|
1710
1710
|
}
|
|
1711
1711
|
/**
|
|
@@ -1718,8 +1718,8 @@ var require_Client = __commonJS({
|
|
|
1718
1718
|
* Get the last modified time of a file. This is not supported by every FTP server, in which case
|
|
1719
1719
|
* calling this method will throw an exception.
|
|
1720
1720
|
*/
|
|
1721
|
-
async lastMod(
|
|
1722
|
-
const validPath = await this.protectWhitespace(
|
|
1721
|
+
async lastMod(path14) {
|
|
1722
|
+
const validPath = await this.protectWhitespace(path14);
|
|
1723
1723
|
const res = await this.send(`MDTM ${validPath}`);
|
|
1724
1724
|
const date5 = res.message.slice(4);
|
|
1725
1725
|
return (0, parseListMLSD_1.parseMLSxDate)(date5);
|
|
@@ -1727,8 +1727,8 @@ var require_Client = __commonJS({
|
|
|
1727
1727
|
/**
|
|
1728
1728
|
* Get the size of a file.
|
|
1729
1729
|
*/
|
|
1730
|
-
async size(
|
|
1731
|
-
const validPath = await this.protectWhitespace(
|
|
1730
|
+
async size(path14) {
|
|
1731
|
+
const validPath = await this.protectWhitespace(path14);
|
|
1732
1732
|
const command = `SIZE ${validPath}`;
|
|
1733
1733
|
const res = await this.send(command);
|
|
1734
1734
|
const size = parseInt(res.message.slice(4), 10);
|
|
@@ -1755,8 +1755,8 @@ var require_Client = __commonJS({
|
|
|
1755
1755
|
* You can ignore FTP error return codes which won't throw an exception if e.g.
|
|
1756
1756
|
* the file doesn't exist.
|
|
1757
1757
|
*/
|
|
1758
|
-
async remove(
|
|
1759
|
-
const validPath = await this.protectWhitespace(
|
|
1758
|
+
async remove(path14, ignoreErrorCodes = false) {
|
|
1759
|
+
const validPath = await this.protectWhitespace(path14);
|
|
1760
1760
|
if (ignoreErrorCodes) {
|
|
1761
1761
|
return this.sendIgnoringError(`DELE ${validPath}`);
|
|
1762
1762
|
}
|
|
@@ -1915,8 +1915,8 @@ var require_Client = __commonJS({
|
|
|
1915
1915
|
*
|
|
1916
1916
|
* @param [path] Path to remote file or directory.
|
|
1917
1917
|
*/
|
|
1918
|
-
async list(
|
|
1919
|
-
const validPath = await this.protectWhitespace(
|
|
1918
|
+
async list(path14 = "") {
|
|
1919
|
+
const validPath = await this.protectWhitespace(path14);
|
|
1920
1920
|
let lastError;
|
|
1921
1921
|
for (const candidate of this.availableListCommands) {
|
|
1922
1922
|
const command = validPath === "" ? candidate : `${candidate} ${validPath}`;
|
|
@@ -2085,21 +2085,21 @@ var require_Client = __commonJS({
|
|
|
2085
2085
|
/**
|
|
2086
2086
|
* Remove an empty directory, will fail if not empty.
|
|
2087
2087
|
*/
|
|
2088
|
-
async removeEmptyDir(
|
|
2089
|
-
const validPath = await this.protectWhitespace(
|
|
2088
|
+
async removeEmptyDir(path14) {
|
|
2089
|
+
const validPath = await this.protectWhitespace(path14);
|
|
2090
2090
|
return this.send(`RMD ${validPath}`);
|
|
2091
2091
|
}
|
|
2092
2092
|
/**
|
|
2093
2093
|
* FTP servers can't handle filenames that have leading whitespace. This method transforms
|
|
2094
2094
|
* a given path to fix that issue for most cases.
|
|
2095
2095
|
*/
|
|
2096
|
-
async protectWhitespace(
|
|
2097
|
-
if (!
|
|
2098
|
-
return
|
|
2096
|
+
async protectWhitespace(path14) {
|
|
2097
|
+
if (!path14.startsWith(" ")) {
|
|
2098
|
+
return path14;
|
|
2099
2099
|
}
|
|
2100
2100
|
const pwd = await this.pwd();
|
|
2101
2101
|
const absolutePathPrefix = pwd.endsWith("/") ? pwd : pwd + "/";
|
|
2102
|
-
return absolutePathPrefix +
|
|
2102
|
+
return absolutePathPrefix + path14;
|
|
2103
2103
|
}
|
|
2104
2104
|
async _exitAtCurrentDirectory(func) {
|
|
2105
2105
|
const userDir = await this.pwd();
|
|
@@ -2176,11 +2176,11 @@ var require_Client = __commonJS({
|
|
|
2176
2176
|
}
|
|
2177
2177
|
};
|
|
2178
2178
|
exports.Client = Client3;
|
|
2179
|
-
async function ensureLocalDirectory(
|
|
2179
|
+
async function ensureLocalDirectory(path14) {
|
|
2180
2180
|
try {
|
|
2181
|
-
await fsStat(
|
|
2181
|
+
await fsStat(path14);
|
|
2182
2182
|
} catch (_a3) {
|
|
2183
|
-
await fsMkDir(
|
|
2183
|
+
await fsMkDir(path14, { recursive: true });
|
|
2184
2184
|
}
|
|
2185
2185
|
}
|
|
2186
2186
|
async function expectedBytesFromLocalFile(fd, options) {
|
|
@@ -5088,20 +5088,20 @@ var require_compile = __commonJS({
|
|
|
5088
5088
|
var util_1 = require_util();
|
|
5089
5089
|
var validate_1 = require_validate();
|
|
5090
5090
|
var SchemaEnv = class {
|
|
5091
|
-
constructor(
|
|
5091
|
+
constructor(env2) {
|
|
5092
5092
|
var _a3;
|
|
5093
5093
|
this.refs = {};
|
|
5094
5094
|
this.dynamicAnchors = {};
|
|
5095
5095
|
let schema;
|
|
5096
|
-
if (typeof
|
|
5097
|
-
schema =
|
|
5098
|
-
this.schema =
|
|
5099
|
-
this.schemaId =
|
|
5100
|
-
this.root =
|
|
5101
|
-
this.baseId = (_a3 =
|
|
5102
|
-
this.schemaPath =
|
|
5103
|
-
this.localRefs =
|
|
5104
|
-
this.meta =
|
|
5096
|
+
if (typeof env2.schema == "object")
|
|
5097
|
+
schema = env2.schema;
|
|
5098
|
+
this.schema = env2.schema;
|
|
5099
|
+
this.schemaId = env2.schemaId;
|
|
5100
|
+
this.root = env2.root || this;
|
|
5101
|
+
this.baseId = (_a3 = env2.baseId) !== null && _a3 !== void 0 ? _a3 : (0, resolve_1.normalizeId)(schema === null || schema === void 0 ? void 0 : schema[env2.schemaId || "$id"]);
|
|
5102
|
+
this.schemaPath = env2.schemaPath;
|
|
5103
|
+
this.localRefs = env2.localRefs;
|
|
5104
|
+
this.meta = env2.meta;
|
|
5105
5105
|
this.$async = schema === null || schema === void 0 ? void 0 : schema.$async;
|
|
5106
5106
|
this.refs = {};
|
|
5107
5107
|
}
|
|
@@ -5285,15 +5285,15 @@ var require_compile = __commonJS({
|
|
|
5285
5285
|
baseId = (0, resolve_1.resolveUrl)(this.opts.uriResolver, baseId, schId);
|
|
5286
5286
|
}
|
|
5287
5287
|
}
|
|
5288
|
-
let
|
|
5288
|
+
let env2;
|
|
5289
5289
|
if (typeof schema != "boolean" && schema.$ref && !(0, util_1.schemaHasRulesButRef)(schema, this.RULES)) {
|
|
5290
5290
|
const $ref = (0, resolve_1.resolveUrl)(this.opts.uriResolver, baseId, schema.$ref);
|
|
5291
|
-
|
|
5291
|
+
env2 = resolveSchema.call(this, root, $ref);
|
|
5292
5292
|
}
|
|
5293
5293
|
const { schemaId } = this.opts;
|
|
5294
|
-
|
|
5295
|
-
if (
|
|
5296
|
-
return
|
|
5294
|
+
env2 = env2 || new SchemaEnv({ schema, schemaId, root, baseId });
|
|
5295
|
+
if (env2.schema !== env2.root.schema)
|
|
5296
|
+
return env2;
|
|
5297
5297
|
return void 0;
|
|
5298
5298
|
}
|
|
5299
5299
|
}
|
|
@@ -5477,8 +5477,8 @@ var require_utils = __commonJS({
|
|
|
5477
5477
|
}
|
|
5478
5478
|
return ind;
|
|
5479
5479
|
}
|
|
5480
|
-
function removeDotSegments(
|
|
5481
|
-
let input2 =
|
|
5480
|
+
function removeDotSegments(path14) {
|
|
5481
|
+
let input2 = path14;
|
|
5482
5482
|
const output2 = [];
|
|
5483
5483
|
let nextSlash = -1;
|
|
5484
5484
|
let len = 0;
|
|
@@ -5887,8 +5887,8 @@ var require_schemes = __commonJS({
|
|
|
5887
5887
|
}
|
|
5888
5888
|
if (wsComponent.resourceName) {
|
|
5889
5889
|
const queryIndex = wsComponent.resourceName.indexOf("?");
|
|
5890
|
-
const
|
|
5891
|
-
wsComponent.path =
|
|
5890
|
+
const path14 = queryIndex === -1 ? wsComponent.resourceName : wsComponent.resourceName.slice(0, queryIndex);
|
|
5891
|
+
wsComponent.path = path14 && path14 !== "/" ? path14 : void 0;
|
|
5892
5892
|
wsComponent.query = queryIndex === -1 ? void 0 : wsComponent.resourceName.slice(queryIndex + 1);
|
|
5893
5893
|
wsComponent.resourceName = void 0;
|
|
5894
5894
|
}
|
|
@@ -7091,8 +7091,8 @@ var require_ref = __commonJS({
|
|
|
7091
7091
|
schemaType: "string",
|
|
7092
7092
|
code(cxt) {
|
|
7093
7093
|
const { gen, schema: $ref, it } = cxt;
|
|
7094
|
-
const { baseId, schemaEnv:
|
|
7095
|
-
const { root } =
|
|
7094
|
+
const { baseId, schemaEnv: env2, validateName, opts, self: self2 } = it;
|
|
7095
|
+
const { root } = env2;
|
|
7096
7096
|
if (($ref === "#" || $ref === "#/") && baseId === root.baseId)
|
|
7097
7097
|
return callRootRef();
|
|
7098
7098
|
const schOrEnv = compile_1.resolveRef.call(self2, root, baseId, $ref);
|
|
@@ -7102,8 +7102,8 @@ var require_ref = __commonJS({
|
|
|
7102
7102
|
return callValidate(schOrEnv);
|
|
7103
7103
|
return inlineRefSchema(schOrEnv);
|
|
7104
7104
|
function callRootRef() {
|
|
7105
|
-
if (
|
|
7106
|
-
return callRef(cxt, validateName,
|
|
7105
|
+
if (env2 === root)
|
|
7106
|
+
return callRef(cxt, validateName, env2, env2.$async);
|
|
7107
7107
|
const rootName = gen.scopeValue("root", { ref: root });
|
|
7108
7108
|
return callRef(cxt, (0, codegen_1._)`${rootName}.validate`, root, root.$async);
|
|
7109
7109
|
}
|
|
@@ -7133,14 +7133,14 @@ var require_ref = __commonJS({
|
|
|
7133
7133
|
exports.getValidate = getValidate;
|
|
7134
7134
|
function callRef(cxt, v, sch, $async) {
|
|
7135
7135
|
const { gen, it } = cxt;
|
|
7136
|
-
const { allErrors, schemaEnv:
|
|
7136
|
+
const { allErrors, schemaEnv: env2, opts } = it;
|
|
7137
7137
|
const passCxt = opts.passContext ? names_1.default.this : codegen_1.nil;
|
|
7138
7138
|
if ($async)
|
|
7139
7139
|
callAsyncRef();
|
|
7140
7140
|
else
|
|
7141
7141
|
callSyncRef();
|
|
7142
7142
|
function callAsyncRef() {
|
|
7143
|
-
if (!
|
|
7143
|
+
if (!env2.$async)
|
|
7144
7144
|
throw new Error("async schema referenced by sync schema");
|
|
7145
7145
|
const valid = gen.let("valid");
|
|
7146
7146
|
gen.try(() => {
|
|
@@ -17567,11 +17567,11 @@ var require_agent = __commonJS({
|
|
|
17567
17567
|
};
|
|
17568
17568
|
})();
|
|
17569
17569
|
var WINDOWS_PIPE_REGEX = /^[/\\][/\\]\.[/\\]pipe[/\\].+/;
|
|
17570
|
-
function createAgent(
|
|
17571
|
-
if (process.platform === "win32" && !WINDOWS_PIPE_REGEX.test(
|
|
17572
|
-
return
|
|
17570
|
+
function createAgent(path14) {
|
|
17571
|
+
if (process.platform === "win32" && !WINDOWS_PIPE_REGEX.test(path14)) {
|
|
17572
|
+
return path14 === "pageant" ? new PageantAgent() : new CygwinAgent(path14);
|
|
17573
17573
|
}
|
|
17574
|
-
return new OpenSSHAgent(
|
|
17574
|
+
return new OpenSSHAgent(path14);
|
|
17575
17575
|
}
|
|
17576
17576
|
var AgentProtocol = (() => {
|
|
17577
17577
|
const SSH_AGENTC_REQUEST_IDENTITIES = 11;
|
|
@@ -22815,17 +22815,17 @@ var require_SFTP = __commonJS({
|
|
|
22815
22815
|
// ===========================================================================
|
|
22816
22816
|
// Client-specific ===========================================================
|
|
22817
22817
|
// ===========================================================================
|
|
22818
|
-
createReadStream(
|
|
22818
|
+
createReadStream(path14, options) {
|
|
22819
22819
|
if (this.server)
|
|
22820
22820
|
throw new Error("Client-only method called in server mode");
|
|
22821
|
-
return new ReadStream(this,
|
|
22821
|
+
return new ReadStream(this, path14, options);
|
|
22822
22822
|
}
|
|
22823
|
-
createWriteStream(
|
|
22823
|
+
createWriteStream(path14, options) {
|
|
22824
22824
|
if (this.server)
|
|
22825
22825
|
throw new Error("Client-only method called in server mode");
|
|
22826
|
-
return new WriteStream(this,
|
|
22826
|
+
return new WriteStream(this, path14, options);
|
|
22827
22827
|
}
|
|
22828
|
-
open(
|
|
22828
|
+
open(path14, flags_, attrs, cb) {
|
|
22829
22829
|
if (this.server)
|
|
22830
22830
|
throw new Error("Client-only method called in server mode");
|
|
22831
22831
|
if (typeof attrs === "function") {
|
|
@@ -22844,7 +22844,7 @@ var require_SFTP = __commonJS({
|
|
|
22844
22844
|
attrsFlags = attrs.flags;
|
|
22845
22845
|
attrsLen = attrs.nb;
|
|
22846
22846
|
}
|
|
22847
|
-
const pathLen = Buffer.byteLength(
|
|
22847
|
+
const pathLen = Buffer.byteLength(path14);
|
|
22848
22848
|
let p = 9;
|
|
22849
22849
|
const buf = Buffer.allocUnsafe(4 + 1 + 4 + 4 + pathLen + 4 + 4 + attrsLen);
|
|
22850
22850
|
writeUInt32BE(buf, buf.length - 4, 0);
|
|
@@ -22852,7 +22852,7 @@ var require_SFTP = __commonJS({
|
|
|
22852
22852
|
const reqid = this._writeReqid = this._writeReqid + 1 & MAX_REQID;
|
|
22853
22853
|
writeUInt32BE(buf, reqid, 5);
|
|
22854
22854
|
writeUInt32BE(buf, pathLen, p);
|
|
22855
|
-
buf.utf8Write(
|
|
22855
|
+
buf.utf8Write(path14, p += 4, pathLen);
|
|
22856
22856
|
writeUInt32BE(buf, flags, p += pathLen);
|
|
22857
22857
|
writeUInt32BE(buf, attrsFlags, p += 4);
|
|
22858
22858
|
if (attrsLen) {
|
|
@@ -22983,7 +22983,7 @@ var require_SFTP = __commonJS({
|
|
|
22983
22983
|
throw new Error("Client-only method called in server mode");
|
|
22984
22984
|
fastXfer(fs, this, localPath, remotePath, opts, cb);
|
|
22985
22985
|
}
|
|
22986
|
-
readFile(
|
|
22986
|
+
readFile(path14, options, callback_) {
|
|
22987
22987
|
if (this.server)
|
|
22988
22988
|
throw new Error("Client-only method called in server mode");
|
|
22989
22989
|
let callback;
|
|
@@ -23056,13 +23056,13 @@ var require_SFTP = __commonJS({
|
|
|
23056
23056
|
return callback && callback(er, buffer);
|
|
23057
23057
|
});
|
|
23058
23058
|
};
|
|
23059
|
-
this.open(
|
|
23059
|
+
this.open(path14, flag, 438, (er, handle_) => {
|
|
23060
23060
|
if (er)
|
|
23061
23061
|
return callback && callback(er);
|
|
23062
23062
|
handle = handle_;
|
|
23063
23063
|
const tryStat = (er2, st) => {
|
|
23064
23064
|
if (er2) {
|
|
23065
|
-
this.stat(
|
|
23065
|
+
this.stat(path14, (er_, st_) => {
|
|
23066
23066
|
if (er_) {
|
|
23067
23067
|
return this.close(handle, () => {
|
|
23068
23068
|
callback && callback(er2);
|
|
@@ -23083,7 +23083,7 @@ var require_SFTP = __commonJS({
|
|
|
23083
23083
|
this.fstat(handle, tryStat);
|
|
23084
23084
|
});
|
|
23085
23085
|
}
|
|
23086
|
-
writeFile(
|
|
23086
|
+
writeFile(path14, data, options, callback_) {
|
|
23087
23087
|
if (this.server)
|
|
23088
23088
|
throw new Error("Client-only method called in server mode");
|
|
23089
23089
|
let callback;
|
|
@@ -23102,7 +23102,7 @@ var require_SFTP = __commonJS({
|
|
|
23102
23102
|
if (options.encoding && !Buffer.isEncoding(options.encoding))
|
|
23103
23103
|
throw new Error(`Unknown encoding: ${options.encoding}`);
|
|
23104
23104
|
const flag = options.flag || "w";
|
|
23105
|
-
this.open(
|
|
23105
|
+
this.open(path14, flag, options.mode, (openErr, handle) => {
|
|
23106
23106
|
if (openErr) {
|
|
23107
23107
|
callback && callback(openErr);
|
|
23108
23108
|
} else {
|
|
@@ -23111,7 +23111,7 @@ var require_SFTP = __commonJS({
|
|
|
23111
23111
|
if (position === null) {
|
|
23112
23112
|
const tryStat = (er, st) => {
|
|
23113
23113
|
if (er) {
|
|
23114
|
-
this.stat(
|
|
23114
|
+
this.stat(path14, (er_, st_) => {
|
|
23115
23115
|
if (er_) {
|
|
23116
23116
|
return this.close(handle, () => {
|
|
23117
23117
|
callback && callback(er);
|
|
@@ -23130,7 +23130,7 @@ var require_SFTP = __commonJS({
|
|
|
23130
23130
|
}
|
|
23131
23131
|
});
|
|
23132
23132
|
}
|
|
23133
|
-
appendFile(
|
|
23133
|
+
appendFile(path14, data, options, callback_) {
|
|
23134
23134
|
if (this.server)
|
|
23135
23135
|
throw new Error("Client-only method called in server mode");
|
|
23136
23136
|
let callback;
|
|
@@ -23148,12 +23148,12 @@ var require_SFTP = __commonJS({
|
|
|
23148
23148
|
throw new TypeError("Bad arguments");
|
|
23149
23149
|
if (!options.flag)
|
|
23150
23150
|
options = Object.assign({ flag: "a" }, options);
|
|
23151
|
-
this.writeFile(
|
|
23151
|
+
this.writeFile(path14, data, options, callback);
|
|
23152
23152
|
}
|
|
23153
|
-
exists(
|
|
23153
|
+
exists(path14, cb) {
|
|
23154
23154
|
if (this.server)
|
|
23155
23155
|
throw new Error("Client-only method called in server mode");
|
|
23156
|
-
this.stat(
|
|
23156
|
+
this.stat(path14, (err) => {
|
|
23157
23157
|
cb && cb(err ? false : true);
|
|
23158
23158
|
});
|
|
23159
23159
|
}
|
|
@@ -23196,7 +23196,7 @@ var require_SFTP = __commonJS({
|
|
|
23196
23196
|
`SFTP: Outbound: ${isBuffered ? "Buffered" : "Sending"} RENAME`
|
|
23197
23197
|
);
|
|
23198
23198
|
}
|
|
23199
|
-
mkdir(
|
|
23199
|
+
mkdir(path14, attrs, cb) {
|
|
23200
23200
|
if (this.server)
|
|
23201
23201
|
throw new Error("Client-only method called in server mode");
|
|
23202
23202
|
let flags = 0;
|
|
@@ -23210,7 +23210,7 @@ var require_SFTP = __commonJS({
|
|
|
23210
23210
|
flags = attrs.flags;
|
|
23211
23211
|
attrsLen = attrs.nb;
|
|
23212
23212
|
}
|
|
23213
|
-
const pathLen = Buffer.byteLength(
|
|
23213
|
+
const pathLen = Buffer.byteLength(path14);
|
|
23214
23214
|
let p = 9;
|
|
23215
23215
|
const buf = Buffer.allocUnsafe(4 + 1 + 4 + 4 + pathLen + 4 + attrsLen);
|
|
23216
23216
|
writeUInt32BE(buf, buf.length - 4, 0);
|
|
@@ -23218,7 +23218,7 @@ var require_SFTP = __commonJS({
|
|
|
23218
23218
|
const reqid = this._writeReqid = this._writeReqid + 1 & MAX_REQID;
|
|
23219
23219
|
writeUInt32BE(buf, reqid, 5);
|
|
23220
23220
|
writeUInt32BE(buf, pathLen, p);
|
|
23221
|
-
buf.utf8Write(
|
|
23221
|
+
buf.utf8Write(path14, p += 4, pathLen);
|
|
23222
23222
|
writeUInt32BE(buf, flags, p += pathLen);
|
|
23223
23223
|
if (attrsLen) {
|
|
23224
23224
|
p += 4;
|
|
@@ -23234,10 +23234,10 @@ var require_SFTP = __commonJS({
|
|
|
23234
23234
|
`SFTP: Outbound: ${isBuffered ? "Buffered" : "Sending"} MKDIR`
|
|
23235
23235
|
);
|
|
23236
23236
|
}
|
|
23237
|
-
rmdir(
|
|
23237
|
+
rmdir(path14, cb) {
|
|
23238
23238
|
if (this.server)
|
|
23239
23239
|
throw new Error("Client-only method called in server mode");
|
|
23240
|
-
const pathLen = Buffer.byteLength(
|
|
23240
|
+
const pathLen = Buffer.byteLength(path14);
|
|
23241
23241
|
let p = 9;
|
|
23242
23242
|
const buf = Buffer.allocUnsafe(4 + 1 + 4 + 4 + pathLen);
|
|
23243
23243
|
writeUInt32BE(buf, buf.length - 4, 0);
|
|
@@ -23245,7 +23245,7 @@ var require_SFTP = __commonJS({
|
|
|
23245
23245
|
const reqid = this._writeReqid = this._writeReqid + 1 & MAX_REQID;
|
|
23246
23246
|
writeUInt32BE(buf, reqid, 5);
|
|
23247
23247
|
writeUInt32BE(buf, pathLen, p);
|
|
23248
|
-
buf.utf8Write(
|
|
23248
|
+
buf.utf8Write(path14, p += 4, pathLen);
|
|
23249
23249
|
this._requests[reqid] = { cb };
|
|
23250
23250
|
const isBuffered = sendOrBuffer(this, buf);
|
|
23251
23251
|
this._debug && this._debug(
|
|
@@ -23335,10 +23335,10 @@ var require_SFTP = __commonJS({
|
|
|
23335
23335
|
`SFTP: Outbound: ${isBuffered ? "Buffered" : "Sending"} FSTAT`
|
|
23336
23336
|
);
|
|
23337
23337
|
}
|
|
23338
|
-
stat(
|
|
23338
|
+
stat(path14, cb) {
|
|
23339
23339
|
if (this.server)
|
|
23340
23340
|
throw new Error("Client-only method called in server mode");
|
|
23341
|
-
const pathLen = Buffer.byteLength(
|
|
23341
|
+
const pathLen = Buffer.byteLength(path14);
|
|
23342
23342
|
let p = 9;
|
|
23343
23343
|
const buf = Buffer.allocUnsafe(4 + 1 + 4 + 4 + pathLen);
|
|
23344
23344
|
writeUInt32BE(buf, buf.length - 4, 0);
|
|
@@ -23346,17 +23346,17 @@ var require_SFTP = __commonJS({
|
|
|
23346
23346
|
const reqid = this._writeReqid = this._writeReqid + 1 & MAX_REQID;
|
|
23347
23347
|
writeUInt32BE(buf, reqid, 5);
|
|
23348
23348
|
writeUInt32BE(buf, pathLen, p);
|
|
23349
|
-
buf.utf8Write(
|
|
23349
|
+
buf.utf8Write(path14, p += 4, pathLen);
|
|
23350
23350
|
this._requests[reqid] = { cb };
|
|
23351
23351
|
const isBuffered = sendOrBuffer(this, buf);
|
|
23352
23352
|
this._debug && this._debug(
|
|
23353
23353
|
`SFTP: Outbound: ${isBuffered ? "Buffered" : "Sending"} STAT`
|
|
23354
23354
|
);
|
|
23355
23355
|
}
|
|
23356
|
-
lstat(
|
|
23356
|
+
lstat(path14, cb) {
|
|
23357
23357
|
if (this.server)
|
|
23358
23358
|
throw new Error("Client-only method called in server mode");
|
|
23359
|
-
const pathLen = Buffer.byteLength(
|
|
23359
|
+
const pathLen = Buffer.byteLength(path14);
|
|
23360
23360
|
let p = 9;
|
|
23361
23361
|
const buf = Buffer.allocUnsafe(4 + 1 + 4 + 4 + pathLen);
|
|
23362
23362
|
writeUInt32BE(buf, buf.length - 4, 0);
|
|
@@ -23364,17 +23364,17 @@ var require_SFTP = __commonJS({
|
|
|
23364
23364
|
const reqid = this._writeReqid = this._writeReqid + 1 & MAX_REQID;
|
|
23365
23365
|
writeUInt32BE(buf, reqid, 5);
|
|
23366
23366
|
writeUInt32BE(buf, pathLen, p);
|
|
23367
|
-
buf.utf8Write(
|
|
23367
|
+
buf.utf8Write(path14, p += 4, pathLen);
|
|
23368
23368
|
this._requests[reqid] = { cb };
|
|
23369
23369
|
const isBuffered = sendOrBuffer(this, buf);
|
|
23370
23370
|
this._debug && this._debug(
|
|
23371
23371
|
`SFTP: Outbound: ${isBuffered ? "Buffered" : "Sending"} LSTAT`
|
|
23372
23372
|
);
|
|
23373
23373
|
}
|
|
23374
|
-
opendir(
|
|
23374
|
+
opendir(path14, cb) {
|
|
23375
23375
|
if (this.server)
|
|
23376
23376
|
throw new Error("Client-only method called in server mode");
|
|
23377
|
-
const pathLen = Buffer.byteLength(
|
|
23377
|
+
const pathLen = Buffer.byteLength(path14);
|
|
23378
23378
|
let p = 9;
|
|
23379
23379
|
const buf = Buffer.allocUnsafe(4 + 1 + 4 + 4 + pathLen);
|
|
23380
23380
|
writeUInt32BE(buf, buf.length - 4, 0);
|
|
@@ -23382,14 +23382,14 @@ var require_SFTP = __commonJS({
|
|
|
23382
23382
|
const reqid = this._writeReqid = this._writeReqid + 1 & MAX_REQID;
|
|
23383
23383
|
writeUInt32BE(buf, reqid, 5);
|
|
23384
23384
|
writeUInt32BE(buf, pathLen, p);
|
|
23385
|
-
buf.utf8Write(
|
|
23385
|
+
buf.utf8Write(path14, p += 4, pathLen);
|
|
23386
23386
|
this._requests[reqid] = { cb };
|
|
23387
23387
|
const isBuffered = sendOrBuffer(this, buf);
|
|
23388
23388
|
this._debug && this._debug(
|
|
23389
23389
|
`SFTP: Outbound: ${isBuffered ? "Buffered" : "Sending"} OPENDIR`
|
|
23390
23390
|
);
|
|
23391
23391
|
}
|
|
23392
|
-
setstat(
|
|
23392
|
+
setstat(path14, attrs, cb) {
|
|
23393
23393
|
if (this.server)
|
|
23394
23394
|
throw new Error("Client-only method called in server mode");
|
|
23395
23395
|
let flags = 0;
|
|
@@ -23401,7 +23401,7 @@ var require_SFTP = __commonJS({
|
|
|
23401
23401
|
} else if (typeof attrs === "function") {
|
|
23402
23402
|
cb = attrs;
|
|
23403
23403
|
}
|
|
23404
|
-
const pathLen = Buffer.byteLength(
|
|
23404
|
+
const pathLen = Buffer.byteLength(path14);
|
|
23405
23405
|
let p = 9;
|
|
23406
23406
|
const buf = Buffer.allocUnsafe(4 + 1 + 4 + 4 + pathLen + 4 + attrsLen);
|
|
23407
23407
|
writeUInt32BE(buf, buf.length - 4, 0);
|
|
@@ -23409,7 +23409,7 @@ var require_SFTP = __commonJS({
|
|
|
23409
23409
|
const reqid = this._writeReqid = this._writeReqid + 1 & MAX_REQID;
|
|
23410
23410
|
writeUInt32BE(buf, reqid, 5);
|
|
23411
23411
|
writeUInt32BE(buf, pathLen, p);
|
|
23412
|
-
buf.utf8Write(
|
|
23412
|
+
buf.utf8Write(path14, p += 4, pathLen);
|
|
23413
23413
|
writeUInt32BE(buf, flags, p += pathLen);
|
|
23414
23414
|
if (attrsLen) {
|
|
23415
23415
|
p += 4;
|
|
@@ -23469,8 +23469,8 @@ var require_SFTP = __commonJS({
|
|
|
23469
23469
|
mtime: toUnixTimestamp(mtime)
|
|
23470
23470
|
}, cb);
|
|
23471
23471
|
}
|
|
23472
|
-
utimes(
|
|
23473
|
-
return this.setstat(
|
|
23472
|
+
utimes(path14, atime, mtime, cb) {
|
|
23473
|
+
return this.setstat(path14, {
|
|
23474
23474
|
atime: toUnixTimestamp(atime),
|
|
23475
23475
|
mtime: toUnixTimestamp(mtime)
|
|
23476
23476
|
}, cb);
|
|
@@ -23481,8 +23481,8 @@ var require_SFTP = __commonJS({
|
|
|
23481
23481
|
gid
|
|
23482
23482
|
}, cb);
|
|
23483
23483
|
}
|
|
23484
|
-
chown(
|
|
23485
|
-
return this.setstat(
|
|
23484
|
+
chown(path14, uid, gid, cb) {
|
|
23485
|
+
return this.setstat(path14, {
|
|
23486
23486
|
uid,
|
|
23487
23487
|
gid
|
|
23488
23488
|
}, cb);
|
|
@@ -23492,15 +23492,15 @@ var require_SFTP = __commonJS({
|
|
|
23492
23492
|
mode
|
|
23493
23493
|
}, cb);
|
|
23494
23494
|
}
|
|
23495
|
-
chmod(
|
|
23496
|
-
return this.setstat(
|
|
23495
|
+
chmod(path14, mode, cb) {
|
|
23496
|
+
return this.setstat(path14, {
|
|
23497
23497
|
mode
|
|
23498
23498
|
}, cb);
|
|
23499
23499
|
}
|
|
23500
|
-
readlink(
|
|
23500
|
+
readlink(path14, cb) {
|
|
23501
23501
|
if (this.server)
|
|
23502
23502
|
throw new Error("Client-only method called in server mode");
|
|
23503
|
-
const pathLen = Buffer.byteLength(
|
|
23503
|
+
const pathLen = Buffer.byteLength(path14);
|
|
23504
23504
|
let p = 9;
|
|
23505
23505
|
const buf = Buffer.allocUnsafe(4 + 1 + 4 + 4 + pathLen);
|
|
23506
23506
|
writeUInt32BE(buf, buf.length - 4, 0);
|
|
@@ -23508,7 +23508,7 @@ var require_SFTP = __commonJS({
|
|
|
23508
23508
|
const reqid = this._writeReqid = this._writeReqid + 1 & MAX_REQID;
|
|
23509
23509
|
writeUInt32BE(buf, reqid, 5);
|
|
23510
23510
|
writeUInt32BE(buf, pathLen, p);
|
|
23511
|
-
buf.utf8Write(
|
|
23511
|
+
buf.utf8Write(path14, p += 4, pathLen);
|
|
23512
23512
|
this._requests[reqid] = {
|
|
23513
23513
|
cb: (err, names) => {
|
|
23514
23514
|
if (typeof cb !== "function")
|
|
@@ -23553,10 +23553,10 @@ var require_SFTP = __commonJS({
|
|
|
23553
23553
|
`SFTP: Outbound: ${isBuffered ? "Buffered" : "Sending"} SYMLINK`
|
|
23554
23554
|
);
|
|
23555
23555
|
}
|
|
23556
|
-
realpath(
|
|
23556
|
+
realpath(path14, cb) {
|
|
23557
23557
|
if (this.server)
|
|
23558
23558
|
throw new Error("Client-only method called in server mode");
|
|
23559
|
-
const pathLen = Buffer.byteLength(
|
|
23559
|
+
const pathLen = Buffer.byteLength(path14);
|
|
23560
23560
|
let p = 9;
|
|
23561
23561
|
const buf = Buffer.allocUnsafe(4 + 1 + 4 + 4 + pathLen);
|
|
23562
23562
|
writeUInt32BE(buf, buf.length - 4, 0);
|
|
@@ -23564,7 +23564,7 @@ var require_SFTP = __commonJS({
|
|
|
23564
23564
|
const reqid = this._writeReqid = this._writeReqid + 1 & MAX_REQID;
|
|
23565
23565
|
writeUInt32BE(buf, reqid, 5);
|
|
23566
23566
|
writeUInt32BE(buf, pathLen, p);
|
|
23567
|
-
buf.utf8Write(
|
|
23567
|
+
buf.utf8Write(path14, p += 4, pathLen);
|
|
23568
23568
|
this._requests[reqid] = {
|
|
23569
23569
|
cb: (err, names) => {
|
|
23570
23570
|
if (typeof cb !== "function")
|
|
@@ -23609,13 +23609,13 @@ var require_SFTP = __commonJS({
|
|
|
23609
23609
|
this._debug(`SFTP: Outbound: ${which} posix-rename@openssh.com`);
|
|
23610
23610
|
}
|
|
23611
23611
|
}
|
|
23612
|
-
ext_openssh_statvfs(
|
|
23612
|
+
ext_openssh_statvfs(path14, cb) {
|
|
23613
23613
|
if (this.server)
|
|
23614
23614
|
throw new Error("Client-only method called in server mode");
|
|
23615
23615
|
const ext = this._extensions["statvfs@openssh.com"];
|
|
23616
23616
|
if (!ext || ext !== "2")
|
|
23617
23617
|
throw new Error("Server does not support this extended request");
|
|
23618
|
-
const pathLen = Buffer.byteLength(
|
|
23618
|
+
const pathLen = Buffer.byteLength(path14);
|
|
23619
23619
|
let p = 9;
|
|
23620
23620
|
const buf = Buffer.allocUnsafe(4 + 1 + 4 + 4 + 19 + 4 + pathLen);
|
|
23621
23621
|
writeUInt32BE(buf, buf.length - 4, 0);
|
|
@@ -23625,7 +23625,7 @@ var require_SFTP = __commonJS({
|
|
|
23625
23625
|
writeUInt32BE(buf, 19, p);
|
|
23626
23626
|
buf.utf8Write("statvfs@openssh.com", p += 4, 19);
|
|
23627
23627
|
writeUInt32BE(buf, pathLen, p += 19);
|
|
23628
|
-
buf.utf8Write(
|
|
23628
|
+
buf.utf8Write(path14, p += 4, pathLen);
|
|
23629
23629
|
this._requests[reqid] = { extended: "statvfs@openssh.com", cb };
|
|
23630
23630
|
const isBuffered = sendOrBuffer(this, buf);
|
|
23631
23631
|
if (this._debug) {
|
|
@@ -23711,7 +23711,7 @@ var require_SFTP = __commonJS({
|
|
|
23711
23711
|
`SFTP: Outbound: ${isBuffered ? "Buffered" : "Sending"} fsync@openssh.com`
|
|
23712
23712
|
);
|
|
23713
23713
|
}
|
|
23714
|
-
ext_openssh_lsetstat(
|
|
23714
|
+
ext_openssh_lsetstat(path14, attrs, cb) {
|
|
23715
23715
|
if (this.server)
|
|
23716
23716
|
throw new Error("Client-only method called in server mode");
|
|
23717
23717
|
const ext = this._extensions["lsetstat@openssh.com"];
|
|
@@ -23726,7 +23726,7 @@ var require_SFTP = __commonJS({
|
|
|
23726
23726
|
} else if (typeof attrs === "function") {
|
|
23727
23727
|
cb = attrs;
|
|
23728
23728
|
}
|
|
23729
|
-
const pathLen = Buffer.byteLength(
|
|
23729
|
+
const pathLen = Buffer.byteLength(path14);
|
|
23730
23730
|
let p = 9;
|
|
23731
23731
|
const buf = Buffer.allocUnsafe(4 + 1 + 4 + 4 + 20 + 4 + pathLen + 4 + attrsLen);
|
|
23732
23732
|
writeUInt32BE(buf, buf.length - 4, 0);
|
|
@@ -23736,7 +23736,7 @@ var require_SFTP = __commonJS({
|
|
|
23736
23736
|
writeUInt32BE(buf, 20, p);
|
|
23737
23737
|
buf.utf8Write("lsetstat@openssh.com", p += 4, 20);
|
|
23738
23738
|
writeUInt32BE(buf, pathLen, p += 20);
|
|
23739
|
-
buf.utf8Write(
|
|
23739
|
+
buf.utf8Write(path14, p += 4, pathLen);
|
|
23740
23740
|
writeUInt32BE(buf, flags, p += pathLen);
|
|
23741
23741
|
if (attrsLen) {
|
|
23742
23742
|
p += 4;
|
|
@@ -23753,13 +23753,13 @@ var require_SFTP = __commonJS({
|
|
|
23753
23753
|
this._debug(`SFTP: Outbound: ${status5} lsetstat@openssh.com`);
|
|
23754
23754
|
}
|
|
23755
23755
|
}
|
|
23756
|
-
ext_openssh_expandPath(
|
|
23756
|
+
ext_openssh_expandPath(path14, cb) {
|
|
23757
23757
|
if (this.server)
|
|
23758
23758
|
throw new Error("Client-only method called in server mode");
|
|
23759
23759
|
const ext = this._extensions["expand-path@openssh.com"];
|
|
23760
23760
|
if (ext !== "1")
|
|
23761
23761
|
throw new Error("Server does not support this extended request");
|
|
23762
|
-
const pathLen = Buffer.byteLength(
|
|
23762
|
+
const pathLen = Buffer.byteLength(path14);
|
|
23763
23763
|
let p = 9;
|
|
23764
23764
|
const buf = Buffer.allocUnsafe(4 + 1 + 4 + 4 + 23 + 4 + pathLen);
|
|
23765
23765
|
writeUInt32BE(buf, buf.length - 4, 0);
|
|
@@ -23769,7 +23769,7 @@ var require_SFTP = __commonJS({
|
|
|
23769
23769
|
writeUInt32BE(buf, 23, p);
|
|
23770
23770
|
buf.utf8Write("expand-path@openssh.com", p += 4, 23);
|
|
23771
23771
|
writeUInt32BE(buf, pathLen, p += 20);
|
|
23772
|
-
buf.utf8Write(
|
|
23772
|
+
buf.utf8Write(path14, p += 4, pathLen);
|
|
23773
23773
|
this._requests[reqid] = {
|
|
23774
23774
|
cb: (err, names) => {
|
|
23775
23775
|
if (typeof cb !== "function")
|
|
@@ -25047,12 +25047,12 @@ var require_SFTP = __commonJS({
|
|
|
25047
25047
|
[REQUEST.LSTAT]: (sftp, payload) => {
|
|
25048
25048
|
bufferParser.init(payload, 1);
|
|
25049
25049
|
const reqID = bufferParser.readUInt32BE();
|
|
25050
|
-
const
|
|
25050
|
+
const path14 = bufferParser.readString(true);
|
|
25051
25051
|
bufferParser.clear();
|
|
25052
|
-
if (
|
|
25052
|
+
if (path14 === void 0)
|
|
25053
25053
|
return doFatalSFTPError(sftp, "Malformed LSTAT packet");
|
|
25054
25054
|
sftp._debug && sftp._debug(`SFTP: Inbound: Received LSTAT (id:${reqID})`);
|
|
25055
|
-
if (!sftp.emit("LSTAT", reqID,
|
|
25055
|
+
if (!sftp.emit("LSTAT", reqID, path14)) {
|
|
25056
25056
|
sftp.status(reqID, STATUS_CODE.OP_UNSUPPORTED);
|
|
25057
25057
|
}
|
|
25058
25058
|
},
|
|
@@ -25071,13 +25071,13 @@ var require_SFTP = __commonJS({
|
|
|
25071
25071
|
[REQUEST.SETSTAT]: (sftp, payload) => {
|
|
25072
25072
|
bufferParser.init(payload, 1);
|
|
25073
25073
|
const reqID = bufferParser.readUInt32BE();
|
|
25074
|
-
const
|
|
25074
|
+
const path14 = bufferParser.readString(true);
|
|
25075
25075
|
const attrs = readAttrs(sftp._biOpt);
|
|
25076
25076
|
bufferParser.clear();
|
|
25077
25077
|
if (attrs === void 0)
|
|
25078
25078
|
return doFatalSFTPError(sftp, "Malformed SETSTAT packet");
|
|
25079
25079
|
sftp._debug && sftp._debug(`SFTP: Inbound: Received SETSTAT (id:${reqID})`);
|
|
25080
|
-
if (!sftp.emit("SETSTAT", reqID,
|
|
25080
|
+
if (!sftp.emit("SETSTAT", reqID, path14, attrs)) {
|
|
25081
25081
|
sftp.status(reqID, STATUS_CODE.OP_UNSUPPORTED);
|
|
25082
25082
|
}
|
|
25083
25083
|
},
|
|
@@ -25099,12 +25099,12 @@ var require_SFTP = __commonJS({
|
|
|
25099
25099
|
[REQUEST.OPENDIR]: (sftp, payload) => {
|
|
25100
25100
|
bufferParser.init(payload, 1);
|
|
25101
25101
|
const reqID = bufferParser.readUInt32BE();
|
|
25102
|
-
const
|
|
25102
|
+
const path14 = bufferParser.readString(true);
|
|
25103
25103
|
bufferParser.clear();
|
|
25104
|
-
if (
|
|
25104
|
+
if (path14 === void 0)
|
|
25105
25105
|
return doFatalSFTPError(sftp, "Malformed OPENDIR packet");
|
|
25106
25106
|
sftp._debug && sftp._debug(`SFTP: Inbound: Received OPENDIR (id:${reqID})`);
|
|
25107
|
-
if (!sftp.emit("OPENDIR", reqID,
|
|
25107
|
+
if (!sftp.emit("OPENDIR", reqID, path14)) {
|
|
25108
25108
|
sftp.status(reqID, STATUS_CODE.OP_UNSUPPORTED);
|
|
25109
25109
|
}
|
|
25110
25110
|
},
|
|
@@ -25123,63 +25123,63 @@ var require_SFTP = __commonJS({
|
|
|
25123
25123
|
[REQUEST.REMOVE]: (sftp, payload) => {
|
|
25124
25124
|
bufferParser.init(payload, 1);
|
|
25125
25125
|
const reqID = bufferParser.readUInt32BE();
|
|
25126
|
-
const
|
|
25126
|
+
const path14 = bufferParser.readString(true);
|
|
25127
25127
|
bufferParser.clear();
|
|
25128
|
-
if (
|
|
25128
|
+
if (path14 === void 0)
|
|
25129
25129
|
return doFatalSFTPError(sftp, "Malformed REMOVE packet");
|
|
25130
25130
|
sftp._debug && sftp._debug(`SFTP: Inbound: Received REMOVE (id:${reqID})`);
|
|
25131
|
-
if (!sftp.emit("REMOVE", reqID,
|
|
25131
|
+
if (!sftp.emit("REMOVE", reqID, path14)) {
|
|
25132
25132
|
sftp.status(reqID, STATUS_CODE.OP_UNSUPPORTED);
|
|
25133
25133
|
}
|
|
25134
25134
|
},
|
|
25135
25135
|
[REQUEST.MKDIR]: (sftp, payload) => {
|
|
25136
25136
|
bufferParser.init(payload, 1);
|
|
25137
25137
|
const reqID = bufferParser.readUInt32BE();
|
|
25138
|
-
const
|
|
25138
|
+
const path14 = bufferParser.readString(true);
|
|
25139
25139
|
const attrs = readAttrs(sftp._biOpt);
|
|
25140
25140
|
bufferParser.clear();
|
|
25141
25141
|
if (attrs === void 0)
|
|
25142
25142
|
return doFatalSFTPError(sftp, "Malformed MKDIR packet");
|
|
25143
25143
|
sftp._debug && sftp._debug(`SFTP: Inbound: Received MKDIR (id:${reqID})`);
|
|
25144
|
-
if (!sftp.emit("MKDIR", reqID,
|
|
25144
|
+
if (!sftp.emit("MKDIR", reqID, path14, attrs)) {
|
|
25145
25145
|
sftp.status(reqID, STATUS_CODE.OP_UNSUPPORTED);
|
|
25146
25146
|
}
|
|
25147
25147
|
},
|
|
25148
25148
|
[REQUEST.RMDIR]: (sftp, payload) => {
|
|
25149
25149
|
bufferParser.init(payload, 1);
|
|
25150
25150
|
const reqID = bufferParser.readUInt32BE();
|
|
25151
|
-
const
|
|
25151
|
+
const path14 = bufferParser.readString(true);
|
|
25152
25152
|
bufferParser.clear();
|
|
25153
|
-
if (
|
|
25153
|
+
if (path14 === void 0)
|
|
25154
25154
|
return doFatalSFTPError(sftp, "Malformed RMDIR packet");
|
|
25155
25155
|
sftp._debug && sftp._debug(`SFTP: Inbound: Received RMDIR (id:${reqID})`);
|
|
25156
|
-
if (!sftp.emit("RMDIR", reqID,
|
|
25156
|
+
if (!sftp.emit("RMDIR", reqID, path14)) {
|
|
25157
25157
|
sftp.status(reqID, STATUS_CODE.OP_UNSUPPORTED);
|
|
25158
25158
|
}
|
|
25159
25159
|
},
|
|
25160
25160
|
[REQUEST.REALPATH]: (sftp, payload) => {
|
|
25161
25161
|
bufferParser.init(payload, 1);
|
|
25162
25162
|
const reqID = bufferParser.readUInt32BE();
|
|
25163
|
-
const
|
|
25163
|
+
const path14 = bufferParser.readString(true);
|
|
25164
25164
|
bufferParser.clear();
|
|
25165
|
-
if (
|
|
25165
|
+
if (path14 === void 0)
|
|
25166
25166
|
return doFatalSFTPError(sftp, "Malformed REALPATH packet");
|
|
25167
25167
|
sftp._debug && sftp._debug(
|
|
25168
25168
|
`SFTP: Inbound: Received REALPATH (id:${reqID})`
|
|
25169
25169
|
);
|
|
25170
|
-
if (!sftp.emit("REALPATH", reqID,
|
|
25170
|
+
if (!sftp.emit("REALPATH", reqID, path14)) {
|
|
25171
25171
|
sftp.status(reqID, STATUS_CODE.OP_UNSUPPORTED);
|
|
25172
25172
|
}
|
|
25173
25173
|
},
|
|
25174
25174
|
[REQUEST.STAT]: (sftp, payload) => {
|
|
25175
25175
|
bufferParser.init(payload, 1);
|
|
25176
25176
|
const reqID = bufferParser.readUInt32BE();
|
|
25177
|
-
const
|
|
25177
|
+
const path14 = bufferParser.readString(true);
|
|
25178
25178
|
bufferParser.clear();
|
|
25179
|
-
if (
|
|
25179
|
+
if (path14 === void 0)
|
|
25180
25180
|
return doFatalSFTPError(sftp, "Malformed STAT packet");
|
|
25181
25181
|
sftp._debug && sftp._debug(`SFTP: Inbound: Received STAT (id:${reqID})`);
|
|
25182
|
-
if (!sftp.emit("STAT", reqID,
|
|
25182
|
+
if (!sftp.emit("STAT", reqID, path14)) {
|
|
25183
25183
|
sftp.status(reqID, STATUS_CODE.OP_UNSUPPORTED);
|
|
25184
25184
|
}
|
|
25185
25185
|
},
|
|
@@ -25199,14 +25199,14 @@ var require_SFTP = __commonJS({
|
|
|
25199
25199
|
[REQUEST.READLINK]: (sftp, payload) => {
|
|
25200
25200
|
bufferParser.init(payload, 1);
|
|
25201
25201
|
const reqID = bufferParser.readUInt32BE();
|
|
25202
|
-
const
|
|
25202
|
+
const path14 = bufferParser.readString(true);
|
|
25203
25203
|
bufferParser.clear();
|
|
25204
|
-
if (
|
|
25204
|
+
if (path14 === void 0)
|
|
25205
25205
|
return doFatalSFTPError(sftp, "Malformed READLINK packet");
|
|
25206
25206
|
sftp._debug && sftp._debug(
|
|
25207
25207
|
`SFTP: Inbound: Received READLINK (id:${reqID})`
|
|
25208
25208
|
);
|
|
25209
|
-
if (!sftp.emit("READLINK", reqID,
|
|
25209
|
+
if (!sftp.emit("READLINK", reqID, path14)) {
|
|
25210
25210
|
sftp.status(reqID, STATUS_CODE.OP_UNSUPPORTED);
|
|
25211
25211
|
}
|
|
25212
25212
|
},
|
|
@@ -25277,7 +25277,7 @@ var require_SFTP = __commonJS({
|
|
|
25277
25277
|
function roundUpToMultipleOf8(n) {
|
|
25278
25278
|
return n + 7 & ~7;
|
|
25279
25279
|
}
|
|
25280
|
-
function ReadStream(sftp,
|
|
25280
|
+
function ReadStream(sftp, path14, options) {
|
|
25281
25281
|
if (options === void 0)
|
|
25282
25282
|
options = {};
|
|
25283
25283
|
else if (typeof options === "string")
|
|
@@ -25291,7 +25291,7 @@ var require_SFTP = __commonJS({
|
|
|
25291
25291
|
options.emitClose = false;
|
|
25292
25292
|
options.autoDestroy = false;
|
|
25293
25293
|
ReadableStream2.call(this, options);
|
|
25294
|
-
this.path =
|
|
25294
|
+
this.path = path14;
|
|
25295
25295
|
this.flags = options.flags === void 0 ? "r" : options.flags;
|
|
25296
25296
|
this.mode = options.mode === void 0 ? 438 : options.mode;
|
|
25297
25297
|
this.start = options.start;
|
|
@@ -25422,7 +25422,7 @@ var require_SFTP = __commonJS({
|
|
|
25422
25422
|
},
|
|
25423
25423
|
configurable: true
|
|
25424
25424
|
});
|
|
25425
|
-
function WriteStream(sftp,
|
|
25425
|
+
function WriteStream(sftp, path14, options) {
|
|
25426
25426
|
if (options === void 0)
|
|
25427
25427
|
options = {};
|
|
25428
25428
|
else if (typeof options === "string")
|
|
@@ -25434,7 +25434,7 @@ var require_SFTP = __commonJS({
|
|
|
25434
25434
|
options.emitClose = false;
|
|
25435
25435
|
options.autoDestroy = false;
|
|
25436
25436
|
WritableStream.call(this, options);
|
|
25437
|
-
this.path =
|
|
25437
|
+
this.path = path14;
|
|
25438
25438
|
this.flags = options.flags === void 0 ? "w" : options.flags;
|
|
25439
25439
|
this.mode = options.mode === void 0 ? 438 : options.mode;
|
|
25440
25440
|
this.start = options.start;
|
|
@@ -27403,12 +27403,12 @@ var require_client = __commonJS({
|
|
|
27403
27403
|
);
|
|
27404
27404
|
return this;
|
|
27405
27405
|
}
|
|
27406
|
-
sftp(
|
|
27406
|
+
sftp(env2, cb) {
|
|
27407
27407
|
if (!this._sock || !isWritable(this._sock))
|
|
27408
27408
|
throw new Error("Not connected");
|
|
27409
|
-
if (typeof
|
|
27410
|
-
cb =
|
|
27411
|
-
|
|
27409
|
+
if (typeof env2 === "function") {
|
|
27410
|
+
cb = env2;
|
|
27411
|
+
env2 = void 0;
|
|
27412
27412
|
}
|
|
27413
27413
|
openChannel(this, "sftp", (err, sftp) => {
|
|
27414
27414
|
if (err) {
|
|
@@ -27451,8 +27451,8 @@ var require_client = __commonJS({
|
|
|
27451
27451
|
sftp.on("ready", onReady).on("error", onError).on("exit", onExit).on("close", onExit);
|
|
27452
27452
|
sftp._init();
|
|
27453
27453
|
};
|
|
27454
|
-
if (typeof
|
|
27455
|
-
reqEnv(sftp,
|
|
27454
|
+
if (typeof env2 === "object" && env2 !== null) {
|
|
27455
|
+
reqEnv(sftp, env2, (err2) => {
|
|
27456
27456
|
if (err2) {
|
|
27457
27457
|
cb(err2);
|
|
27458
27458
|
return;
|
|
@@ -27657,7 +27657,7 @@ var require_client = __commonJS({
|
|
|
27657
27657
|
});
|
|
27658
27658
|
chan._client._protocol.exec(chan.outgoing.id, cmd, true);
|
|
27659
27659
|
}
|
|
27660
|
-
function reqEnv(chan,
|
|
27660
|
+
function reqEnv(chan, env2, cb) {
|
|
27661
27661
|
const wantReply = typeof cb === "function";
|
|
27662
27662
|
if (chan.outgoing.state !== "open") {
|
|
27663
27663
|
if (wantReply)
|
|
@@ -27673,10 +27673,10 @@ var require_client = __commonJS({
|
|
|
27673
27673
|
cb();
|
|
27674
27674
|
});
|
|
27675
27675
|
}
|
|
27676
|
-
const keys = Object.keys(
|
|
27676
|
+
const keys = Object.keys(env2 || {});
|
|
27677
27677
|
for (let i = 0; i < keys.length; ++i) {
|
|
27678
27678
|
const key = keys[i];
|
|
27679
|
-
const val =
|
|
27679
|
+
const val = env2[key];
|
|
27680
27680
|
chan._client._protocol.env(chan.outgoing.id, key, val, wantReply);
|
|
27681
27681
|
}
|
|
27682
27682
|
}
|
|
@@ -29659,7 +29659,9 @@ function paths(dir) {
|
|
|
29659
29659
|
/** Each run's Claude Code settings file, `<runId>.json`, there only while the run lasts. */
|
|
29660
29660
|
runsDir: path.join(dir, "runs"),
|
|
29661
29661
|
/** The runner's bare mirrors of the projects' repositories: the only ones that talk to GitHub. */
|
|
29662
|
-
gitDir: path.join(dir, "git")
|
|
29662
|
+
gitDir: path.join(dir, "git"),
|
|
29663
|
+
/** One `<projectId>.env` per project the machine's owner gives variables to (see project-env.ts). */
|
|
29664
|
+
envDir: path.join(dir, "env")
|
|
29663
29665
|
};
|
|
29664
29666
|
}
|
|
29665
29667
|
function loadConfig(dir = defaultDir()) {
|
|
@@ -29682,6 +29684,7 @@ function saveConfig(cfg, dir = defaultDir()) {
|
|
|
29682
29684
|
}
|
|
29683
29685
|
|
|
29684
29686
|
// src/args.ts
|
|
29687
|
+
var WITH_ARG = /* @__PURE__ */ new Set(["env"]);
|
|
29685
29688
|
function parseArgs(argv) {
|
|
29686
29689
|
const out = {};
|
|
29687
29690
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -29691,13 +29694,14 @@ function parseArgs(argv) {
|
|
|
29691
29694
|
if (!v || !PROFILE_RE.test(v)) return { error: `--profile needs a name of letters, digits and dashes (1 to 32), not "${v ?? ""}".` };
|
|
29692
29695
|
out.profile = v;
|
|
29693
29696
|
} else if (out.cmd === void 0) out.cmd = a;
|
|
29697
|
+
else if (out.arg === void 0 && WITH_ARG.has(out.cmd)) out.arg = a;
|
|
29694
29698
|
else return { error: `Unexpected argument: ${a}` };
|
|
29695
29699
|
}
|
|
29696
29700
|
return out;
|
|
29697
29701
|
}
|
|
29698
29702
|
|
|
29699
29703
|
// src/commands.ts
|
|
29700
|
-
import { readFileSync as
|
|
29704
|
+
import { readFileSync as readFileSync5 } from "node:fs";
|
|
29701
29705
|
import os6 from "node:os";
|
|
29702
29706
|
import { createInterface } from "node:readline/promises";
|
|
29703
29707
|
import { Writable as Writable2 } from "node:stream";
|
|
@@ -29813,9 +29817,9 @@ var ENV_ALLOW_WINDOWS = [
|
|
|
29813
29817
|
"TEMP",
|
|
29814
29818
|
"TMP"
|
|
29815
29819
|
];
|
|
29816
|
-
function baseEnv(
|
|
29820
|
+
function baseEnv(env2, windows) {
|
|
29817
29821
|
const out = {};
|
|
29818
|
-
for (const [k, v] of Object.entries(
|
|
29822
|
+
for (const [k, v] of Object.entries(env2)) {
|
|
29819
29823
|
if (v === void 0) continue;
|
|
29820
29824
|
const key = windows ? k.toUpperCase() : k;
|
|
29821
29825
|
if (!(ENV_ALLOW.includes(key) || ENV_ALLOW_PREFIX.some((p) => key.startsWith(p)) || windows && ENV_ALLOW_WINDOWS.includes(key))) continue;
|
|
@@ -29884,8 +29888,9 @@ function claudeEngine(deps = {}) {
|
|
|
29884
29888
|
"user"
|
|
29885
29889
|
];
|
|
29886
29890
|
const engineEnv = (o) => ({
|
|
29887
|
-
|
|
29891
|
+
// The project's own variables first: the runner's environment (PATH, proxies, CA files…) and its tokens win.
|
|
29888
29892
|
...o.env,
|
|
29893
|
+
...baseEnv(deps.env ?? process.env, windows),
|
|
29889
29894
|
...AGENT_GIT_ENV,
|
|
29890
29895
|
CLAUDE_CONFIG_DIR: o.claudeConfigDir,
|
|
29891
29896
|
NOTIAMO_RUN_TOKEN: o.mcp.token,
|
|
@@ -30156,11 +30161,11 @@ var realExec = async (file2, args, opts) => {
|
|
|
30156
30161
|
if (r.code === 127 && process.platform === "win32") return run(file2, args.map(quoteForCmd), opts?.env, true, opts?.timeout);
|
|
30157
30162
|
return r;
|
|
30158
30163
|
};
|
|
30159
|
-
function run(file2, args,
|
|
30164
|
+
function run(file2, args, env2, shell, timeout) {
|
|
30160
30165
|
return new Promise((resolve) => {
|
|
30161
30166
|
let stdout = "";
|
|
30162
30167
|
let stderr = "";
|
|
30163
|
-
const child = spawn2(file2, args, { env:
|
|
30168
|
+
const child = spawn2(file2, args, { env: env2 ?? process.env, shell, stdio: ["ignore", "pipe", "pipe"], windowsHide: true, ...timeout ? { timeout, killSignal: "SIGKILL" } : {} });
|
|
30164
30169
|
child.stdout.on("data", (d) => {
|
|
30165
30170
|
stdout += d.toString();
|
|
30166
30171
|
});
|
|
@@ -30267,8 +30272,8 @@ function findOnPath(name, dirs, platform) {
|
|
|
30267
30272
|
}
|
|
30268
30273
|
return null;
|
|
30269
30274
|
}
|
|
30270
|
-
function machineToolDirs(
|
|
30271
|
-
const pathDirs = (
|
|
30275
|
+
function machineToolDirs(env2 = process.env, argv1 = process.argv[1], execPath = process.execPath, platform = process.platform) {
|
|
30276
|
+
const pathDirs = (env2.PATH ?? env2.Path ?? "").split(path2.delimiter).filter((d) => d && path2.isAbsolute(d));
|
|
30272
30277
|
const dirs = pathDirs.map(realPath);
|
|
30273
30278
|
for (const bin of ["git", "claude"]) {
|
|
30274
30279
|
const found = findOnPath(bin, pathDirs, platform);
|
|
@@ -30422,8 +30427,9 @@ function sandboxSettings(o) {
|
|
|
30422
30427
|
},
|
|
30423
30428
|
network: {
|
|
30424
30429
|
allowedDomains: [...new Set(domains)],
|
|
30425
|
-
// macOS: lets the engine's shell commands reach the run's local helper on
|
|
30426
|
-
|
|
30430
|
+
// macOS: lets the engine's shell commands reach 127.0.0.1: the run's local helper on a WordPress run, the
|
|
30431
|
+
// owner's own services (Postgres, MinIO…) on a project with an env file (no effect on Linux).
|
|
30432
|
+
...o.wordpressHost || o.localServices ? { allowLocalBinding: true } : {}
|
|
30427
30433
|
}
|
|
30428
30434
|
}
|
|
30429
30435
|
};
|
|
@@ -30444,9 +30450,9 @@ import path3 from "node:path";
|
|
|
30444
30450
|
|
|
30445
30451
|
// src/service/common.ts
|
|
30446
30452
|
var startArgs = (profile) => profile ? ["start", "--profile", profile] : ["start"];
|
|
30447
|
-
function serviceEnv(
|
|
30453
|
+
function serviceEnv(env2 = {}) {
|
|
30448
30454
|
const out = {};
|
|
30449
|
-
for (const k of ["PATH", "NOTIAMO_RUNNER_HOME"]) if (
|
|
30455
|
+
for (const k of ["PATH", "NOTIAMO_RUNNER_HOME"]) if (env2[k]) out[k] = env2[k];
|
|
30450
30456
|
return out;
|
|
30451
30457
|
}
|
|
30452
30458
|
function must(what, r) {
|
|
@@ -30461,7 +30467,7 @@ var BOOTSTRAP_TRIES = 5;
|
|
|
30461
30467
|
var BOOTSTRAP_RETRY_MS = 500;
|
|
30462
30468
|
var esc = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
30463
30469
|
function renderPlist(o) {
|
|
30464
|
-
const
|
|
30470
|
+
const env2 = Object.entries(serviceEnv(o.env)).map(([k, v]) => ` <key>${esc(k)}</key>
|
|
30465
30471
|
<string>${esc(v)}</string>`).join("\n");
|
|
30466
30472
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
30467
30473
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
@@ -30487,7 +30493,7 @@ ${startArgs(o.profile).map((a) => ` <string>${esc(a)}</string>`).join("\n")}
|
|
|
30487
30493
|
<string>${esc(o.log)}</string>
|
|
30488
30494
|
<key>EnvironmentVariables</key>
|
|
30489
30495
|
<dict>
|
|
30490
|
-
${
|
|
30496
|
+
${env2}
|
|
30491
30497
|
</dict>
|
|
30492
30498
|
</dict>
|
|
30493
30499
|
</plist>
|
|
@@ -30536,7 +30542,7 @@ var unit = (profile) => profile ? `notiamo-runner-${profile}` : "notiamo-runner"
|
|
|
30536
30542
|
var unitPath = (home, profile) => path4.join(home, ".config", "systemd", "user", `${unit(profile)}.service`);
|
|
30537
30543
|
var q = (s) => `"${s.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
30538
30544
|
function renderUnit(o) {
|
|
30539
|
-
const
|
|
30545
|
+
const env2 = Object.entries(serviceEnv(o.env)).map(([k, v]) => `Environment=${q(`${k}=${v}`)}`).join("\n");
|
|
30540
30546
|
return `[Unit]
|
|
30541
30547
|
Description=Notiamo runner${o.profile ? ` (${o.profile})` : ""}
|
|
30542
30548
|
After=network-online.target
|
|
@@ -30547,7 +30553,7 @@ Restart=always
|
|
|
30547
30553
|
RestartSec=5
|
|
30548
30554
|
StandardOutput=append:${o.log}
|
|
30549
30555
|
StandardError=append:${o.log}
|
|
30550
|
-
${
|
|
30556
|
+
${env2}
|
|
30551
30557
|
|
|
30552
30558
|
[Install]
|
|
30553
30559
|
WantedBy=default.target
|
|
@@ -30623,8 +30629,8 @@ var serviceStatus = async (o) => impl(o).status(withUid(o));
|
|
|
30623
30629
|
// src/init.ts
|
|
30624
30630
|
var DEFAULT_HOST = "https://my.notiamo.com";
|
|
30625
30631
|
var KEYCHAIN_WARNING = "Warning: this user's keychain holds a GitHub login. A run on this machine could reach it. Remove it (Keychain Access, search github.com) or install the runner under a separate macOS user. The runner itself does not need it.";
|
|
30626
|
-
var runInteractive = (file2, args,
|
|
30627
|
-
const child = spawn3(file2, args, { stdio: "inherit", env, shell: process.platform === "win32" });
|
|
30632
|
+
var runInteractive = (file2, args, env2) => new Promise((resolve, reject) => {
|
|
30633
|
+
const child = spawn3(file2, args, { stdio: "inherit", env: env2, shell: process.platform === "win32" });
|
|
30628
30634
|
child.on("error", reject);
|
|
30629
30635
|
child.on("exit", (code) => resolve(code ?? 1));
|
|
30630
30636
|
});
|
|
@@ -30636,7 +30642,7 @@ async function runInit(deps) {
|
|
|
30636
30642
|
const dir = deps.dir ?? profileDir(deps.profile);
|
|
30637
30643
|
const platform = deps.platform ?? process.platform;
|
|
30638
30644
|
const p = paths(dir);
|
|
30639
|
-
const
|
|
30645
|
+
const env2 = deps.env ?? process.env;
|
|
30640
30646
|
const print = deps.print ?? ((s) => console.log(s));
|
|
30641
30647
|
const ask = async (q2, def) => (await deps.prompt(q2, { default: def })).trim() || def;
|
|
30642
30648
|
const token = (await deps.prompt("Runner token (made in Notiamo under Settings \u203A Agent runs \u203A Runners; nothing shows while you paste it): ", { hidden: true })).trim();
|
|
@@ -30644,55 +30650,90 @@ async function runInit(deps) {
|
|
|
30644
30650
|
const host = normalizeHost(await ask("Notiamo address: ", DEFAULT_HOST));
|
|
30645
30651
|
const hostname3 = deps.hostname ?? os4.hostname();
|
|
30646
30652
|
const name = await ask("Name of this runner: ", hostname3);
|
|
30647
|
-
const
|
|
30653
|
+
const engineVersion = await checkMachine(deps, env2, platform, print);
|
|
30654
|
+
try {
|
|
30655
|
+
await new NotiamoApi({ host, token }, deps.fetch).hello({ version: VERSION, os: platform, engine: "claude", engineVersion });
|
|
30656
|
+
} catch (e) {
|
|
30657
|
+
if (e instanceof ApiError && e.status === 401) throw new Error("The runner token was not accepted.");
|
|
30658
|
+
throw new Error(`Notiamo at ${host} did not answer: ${e instanceof Error ? e.message : String(e)}`);
|
|
30659
|
+
}
|
|
30660
|
+
const claudeEnv = { ...env2, CLAUDE_CONFIG_DIR: p.claudeConfigDir };
|
|
30661
|
+
if (!deps.skipLogin) {
|
|
30662
|
+
print("Sign Claude Code in for the runner (its own sign-in, kept apart from yours):");
|
|
30663
|
+
await (deps.interactive ?? runInteractive)("claude", ["auth", "login"], claudeEnv);
|
|
30664
|
+
}
|
|
30665
|
+
const check2 = await deps.exec("claude", ["-p", "say ok"], { env: claudeEnv });
|
|
30666
|
+
if (check2.code !== 0) throw new Error("Claude Code is not signed in for the runner.");
|
|
30667
|
+
await warnKeychain(deps, env2, platform, print);
|
|
30668
|
+
saveConfig({ host, token, name, dataDir: dir, engine: "claude" }, dir);
|
|
30669
|
+
await installService({
|
|
30670
|
+
platform,
|
|
30671
|
+
profile: deps.profile,
|
|
30672
|
+
paths: p,
|
|
30673
|
+
exec: deps.exec,
|
|
30674
|
+
home: deps.home ?? os4.homedir(),
|
|
30675
|
+
env: env2,
|
|
30676
|
+
nodePath: deps.nodePath ?? process.execPath,
|
|
30677
|
+
cliPath: deps.cliPath ?? process.argv[1]
|
|
30678
|
+
});
|
|
30679
|
+
print(`Runner ${name}${deps.profile ? ` (profile ${deps.profile})` : ""} is installed and running. Logs: ${p.log}`);
|
|
30680
|
+
}
|
|
30681
|
+
async function checkMachine(deps, env2, platform, print) {
|
|
30682
|
+
const version2 = await deps.exec("claude", ["--version"], { env: env2 });
|
|
30648
30683
|
if (version2.code !== 0) throw new Error("Claude Code is not installed. Install it first: https://claude.com/claude-code");
|
|
30649
30684
|
const engineVersion = version2.stdout.trim().slice(0, 100) || "unknown";
|
|
30650
30685
|
if (engineTooOld(engineVersion)) throw new Error(`Claude Code 2.1.314 or newer is needed (yours: ${engineVersion}). Update it: claude update`);
|
|
30651
|
-
const git = await deps.exec("git", ["--version"], { env });
|
|
30686
|
+
const git = await deps.exec("git", ["--version"], { env: env2 });
|
|
30652
30687
|
const gitVersion = git.code === 0 ? /git version (\d+)\.(\d+)/.exec(git.stdout) ?? null : null;
|
|
30653
30688
|
if (!gitVersion || Number(gitVersion[1]) < 2 || Number(gitVersion[1]) === 2 && Number(gitVersion[2]) < 31) {
|
|
30654
30689
|
const yours = git.code === 0 ? git.stdout.trim().replace(/^git version /, "").slice(0, 60) || "unknown" : "not installed";
|
|
30655
30690
|
throw new Error(`git 2.31 or newer is needed (yours: ${yours}). Update git.`);
|
|
30656
30691
|
}
|
|
30657
30692
|
if (platform === "linux") {
|
|
30658
|
-
const bwrap = await deps.exec("which", ["bwrap"], { env });
|
|
30659
|
-
const socat = await deps.exec("which", ["socat"], { env });
|
|
30693
|
+
const bwrap = await deps.exec("which", ["bwrap"], { env: env2 });
|
|
30694
|
+
const socat = await deps.exec("which", ["socat"], { env: env2 });
|
|
30660
30695
|
if (bwrap.code !== 0 || socat.code !== 0) {
|
|
30661
30696
|
throw new Error("The sandbox needs bubblewrap and socat. Install them (Debian/Ubuntu: sudo apt install bubblewrap socat), then run init again.");
|
|
30662
30697
|
}
|
|
30663
30698
|
} else if (platform === "win32") {
|
|
30664
30699
|
print("Note: on Windows without WSL2, shell commands of a run are not sandboxed; Claude's own file tools are still limited to the run folder.");
|
|
30665
30700
|
}
|
|
30701
|
+
return engineVersion;
|
|
30702
|
+
}
|
|
30703
|
+
async function warnKeychain(deps, env2, platform, print) {
|
|
30704
|
+
if (platform !== "darwin") return;
|
|
30705
|
+
const git = await deps.exec("security", ["find-internet-password", "-s", "github.com"], { env: env2, timeout: 1e4 });
|
|
30706
|
+
const gh = await deps.exec("security", ["find-generic-password", "-s", "gh:github.com"], { env: env2, timeout: 1e4 });
|
|
30707
|
+
if (git.code === 0 || gh.code === 0) print(KEYCHAIN_WARNING);
|
|
30708
|
+
}
|
|
30709
|
+
async function runUpdate(deps) {
|
|
30710
|
+
const dir = deps.dir ?? profileDir(deps.profile);
|
|
30711
|
+
const platform = deps.platform ?? process.platform;
|
|
30712
|
+
const p = paths(dir);
|
|
30713
|
+
const env2 = deps.env ?? process.env;
|
|
30714
|
+
const print = deps.print ?? ((s) => console.log(s));
|
|
30715
|
+
const cfg = loadConfig(dir);
|
|
30716
|
+
const engineVersion = await checkMachine(deps, env2, platform, print);
|
|
30666
30717
|
try {
|
|
30667
|
-
await new NotiamoApi({ host, token }, deps.fetch).hello({ version: VERSION, os: platform, engine: "claude", engineVersion });
|
|
30718
|
+
await new NotiamoApi({ host: cfg.host, token: cfg.token }, deps.fetch).hello({ version: VERSION, os: platform, engine: "claude", engineVersion });
|
|
30668
30719
|
} catch (e) {
|
|
30669
|
-
if (e instanceof ApiError && e.status === 401) throw new Error("The runner token
|
|
30670
|
-
throw new Error(`Notiamo at ${host} did not answer: ${e instanceof Error ? e.message : String(e)}`);
|
|
30720
|
+
if (e instanceof ApiError && e.status === 401) throw new Error("The saved runner token is not accepted any more (revoked or deleted). Make a new runner in Notiamo and run init.");
|
|
30721
|
+
throw new Error(`Notiamo at ${cfg.host} did not answer: ${e instanceof Error ? e.message : String(e)}`);
|
|
30671
30722
|
}
|
|
30672
|
-
const
|
|
30673
|
-
if (
|
|
30674
|
-
|
|
30675
|
-
await (deps.interactive ?? runInteractive)("claude", ["auth", "login"], claudeEnv);
|
|
30676
|
-
}
|
|
30677
|
-
const check2 = await deps.exec("claude", ["-p", "say ok"], { env: claudeEnv });
|
|
30678
|
-
if (check2.code !== 0) throw new Error("Claude Code is not signed in for the runner.");
|
|
30679
|
-
if (platform === "darwin") {
|
|
30680
|
-
const git2 = await deps.exec("security", ["find-internet-password", "-s", "github.com"], { env, timeout: 1e4 });
|
|
30681
|
-
const gh = await deps.exec("security", ["find-generic-password", "-s", "gh:github.com"], { env, timeout: 1e4 });
|
|
30682
|
-
if (git2.code === 0 || gh.code === 0) print(KEYCHAIN_WARNING);
|
|
30683
|
-
}
|
|
30684
|
-
saveConfig({ host, token, name, dataDir: dir, engine: "claude" }, dir);
|
|
30723
|
+
const check2 = await deps.exec("claude", ["-p", "say ok"], { env: { ...env2, CLAUDE_CONFIG_DIR: p.claudeConfigDir } });
|
|
30724
|
+
if (check2.code !== 0) throw new Error("Claude Code is not signed in for the runner. Run: notiamo-runner init");
|
|
30725
|
+
await warnKeychain(deps, env2, platform, print);
|
|
30685
30726
|
await installService({
|
|
30686
30727
|
platform,
|
|
30687
30728
|
profile: deps.profile,
|
|
30688
30729
|
paths: p,
|
|
30689
30730
|
exec: deps.exec,
|
|
30690
30731
|
home: deps.home ?? os4.homedir(),
|
|
30691
|
-
env,
|
|
30732
|
+
env: env2,
|
|
30692
30733
|
nodePath: deps.nodePath ?? process.execPath,
|
|
30693
30734
|
cliPath: deps.cliPath ?? process.argv[1]
|
|
30694
30735
|
});
|
|
30695
|
-
print(`Runner ${name}${deps.profile ? ` (profile ${deps.profile})` : ""}
|
|
30736
|
+
print(`Runner ${cfg.name}${deps.profile ? ` (profile ${deps.profile})` : ""} now runs version ${VERSION}. Logs: ${p.log}`);
|
|
30696
30737
|
}
|
|
30697
30738
|
|
|
30698
30739
|
// src/log.ts
|
|
@@ -30713,8 +30754,8 @@ function createLogger(file2) {
|
|
|
30713
30754
|
}
|
|
30714
30755
|
|
|
30715
30756
|
// src/loop.ts
|
|
30716
|
-
import { mkdirSync as
|
|
30717
|
-
import
|
|
30757
|
+
import { mkdirSync as mkdirSync9, readFileSync as readFileSync4, renameSync as renameSync2, rmSync as rmSync6, writeFileSync as writeFileSync8 } from "node:fs";
|
|
30758
|
+
import path13 from "node:path";
|
|
30718
30759
|
import { setTimeout as delay2 } from "node:timers/promises";
|
|
30719
30760
|
|
|
30720
30761
|
// src/clones.ts
|
|
@@ -30808,8 +30849,8 @@ function removeStaleClones(projectsDir, gitDir, keepDays, busyProjectIds, now, l
|
|
|
30808
30849
|
var errorText = (e) => e instanceof Error ? e.message : String(e);
|
|
30809
30850
|
|
|
30810
30851
|
// src/run.ts
|
|
30811
|
-
import { chmodSync as
|
|
30812
|
-
import
|
|
30852
|
+
import { chmodSync as chmodSync3, mkdirSync as mkdirSync8, mkdtempSync, rmSync as rmSync5, writeFileSync as writeFileSync7 } from "node:fs";
|
|
30853
|
+
import path12 from "node:path";
|
|
30813
30854
|
|
|
30814
30855
|
// src/project-folder.ts
|
|
30815
30856
|
import { execFile } from "node:child_process";
|
|
@@ -30830,9 +30871,9 @@ var execFileAsync = async (file2, args, opts) => {
|
|
|
30830
30871
|
};
|
|
30831
30872
|
var SAFE_GIT = ["-c", "core.hooksPath=/dev/null", "-c", "core.fsmonitor=false"];
|
|
30832
30873
|
function gitEnv() {
|
|
30833
|
-
const
|
|
30834
|
-
for (const k of Object.keys(
|
|
30835
|
-
return
|
|
30874
|
+
const env2 = { ...process.env, GIT_TERMINAL_PROMPT: "0", GIT_CONFIG_NOSYSTEM: "1", GIT_CONFIG_GLOBAL: os5.devNull };
|
|
30875
|
+
for (const k of Object.keys(env2)) if (/^GIT_CONFIG_(COUNT|KEY_\d+|VALUE_\d+|PARAMETERS)$/.test(k) || k === "GIT_ASKPASS") delete env2[k];
|
|
30876
|
+
return env2;
|
|
30836
30877
|
}
|
|
30837
30878
|
function githubAuthEnv(token) {
|
|
30838
30879
|
return {
|
|
@@ -30855,8 +30896,8 @@ async function prepareGithubFolder(dirs, projectId, g, token, exec = execFileAsy
|
|
|
30855
30896
|
const folder = projectFolder(dirs.projectsDir, slot, projectId);
|
|
30856
30897
|
const bare = barePath(dirs.gitDir, projectId);
|
|
30857
30898
|
const saved = savedSnapshotPath(dirs.gitDir, projectId, slot);
|
|
30858
|
-
const
|
|
30859
|
-
const gitIn = (dir, args, timeout = GIT_TIMEOUT_MS) => exec("git", [...SAFE_GIT, "-C", dir, ...args], { env, timeout });
|
|
30899
|
+
const env2 = gitEnv();
|
|
30900
|
+
const gitIn = (dir, args, timeout = GIT_TIMEOUT_MS) => exec("git", [...SAFE_GIT, "-C", dir, ...args], { env: env2, timeout });
|
|
30860
30901
|
if (existsSync4(path7.join(bare, "HEAD"))) {
|
|
30861
30902
|
await gitIn(bare, ["remote", "set-url", "--", "origin", g.cloneUrl]);
|
|
30862
30903
|
await exec("git", [...SAFE_GIT, "-C", bare, "fetch", "origin", "--prune", "+refs/heads/*:refs/heads/*"], { env: githubAuthEnv(await token()), timeout: CLONE_TIMEOUT_MS });
|
|
@@ -30880,7 +30921,7 @@ async function prepareGithubFolder(dirs, projectId, g, token, exec = execFileAsy
|
|
|
30880
30921
|
await gitIn(folder, ["fetch", "origin", "--prune"]);
|
|
30881
30922
|
} else {
|
|
30882
30923
|
mkdirSync6(slotDir, { recursive: true, mode: 448 });
|
|
30883
|
-
await exec("git", [...SAFE_GIT, "clone", "--no-hardlinks", "--", bare, folder], { cwd: slotDir, env, timeout: CLONE_TIMEOUT_MS });
|
|
30924
|
+
await exec("git", [...SAFE_GIT, "clone", "--no-hardlinks", "--", bare, folder], { cwd: slotDir, env: env2, timeout: CLONE_TIMEOUT_MS });
|
|
30884
30925
|
}
|
|
30885
30926
|
const { stdout } = await gitIn(folder, ["rev-parse", "--abbrev-ref", "HEAD"]);
|
|
30886
30927
|
if (stdout.trim() !== g.branch) {
|
|
@@ -30912,8 +30953,8 @@ function readSavedSnapshot(file2) {
|
|
|
30912
30953
|
}
|
|
30913
30954
|
}
|
|
30914
30955
|
async function pushBranch(folder, bare, branch, token, exec = execFileAsync) {
|
|
30915
|
-
const
|
|
30916
|
-
await exec("git", [...SAFE_GIT, "-C", bare, "fetch", folder, `+refs/heads/${branch}:refs/heads/${branch}`], { env, timeout: GIT_TIMEOUT_MS }).catch(gitError);
|
|
30956
|
+
const env2 = gitEnv();
|
|
30957
|
+
await exec("git", [...SAFE_GIT, "-C", bare, "fetch", folder, `+refs/heads/${branch}:refs/heads/${branch}`], { env: env2, timeout: GIT_TIMEOUT_MS }).catch(gitError);
|
|
30917
30958
|
const auth = githubAuthEnv(await token());
|
|
30918
30959
|
await exec("git", [...SAFE_GIT, "-C", bare, "push", "--no-verify", "origin", branch], { env: auth, timeout: GIT_TIMEOUT_MS }).catch(gitError);
|
|
30919
30960
|
}
|
|
@@ -31006,6 +31047,110 @@ function exists(p) {
|
|
|
31006
31047
|
}
|
|
31007
31048
|
}
|
|
31008
31049
|
|
|
31050
|
+
// src/project-env.ts
|
|
31051
|
+
import { chmodSync as chmodSync2, existsSync as existsSync5, mkdirSync as mkdirSync7, readFileSync as readFileSync3, writeFileSync as writeFileSync6 } from "node:fs";
|
|
31052
|
+
import path8 from "node:path";
|
|
31053
|
+
var PROTECTED_KEYS = /* @__PURE__ */ new Set([
|
|
31054
|
+
"PATH",
|
|
31055
|
+
"HOME",
|
|
31056
|
+
"USER",
|
|
31057
|
+
"LOGNAME",
|
|
31058
|
+
"SHELL",
|
|
31059
|
+
"TMPDIR",
|
|
31060
|
+
"TERM",
|
|
31061
|
+
"LANG",
|
|
31062
|
+
"TZ",
|
|
31063
|
+
"CLAUDE_CONFIG_DIR",
|
|
31064
|
+
"HTTP_PROXY",
|
|
31065
|
+
"HTTPS_PROXY",
|
|
31066
|
+
"NO_PROXY",
|
|
31067
|
+
"NODE_EXTRA_CA_CERTS",
|
|
31068
|
+
"SSL_CERT_FILE",
|
|
31069
|
+
"SSL_CERT_DIR",
|
|
31070
|
+
"NODE_OPTIONS",
|
|
31071
|
+
"NODE_TLS_REJECT_UNAUTHORIZED",
|
|
31072
|
+
"PATHEXT",
|
|
31073
|
+
"SYSTEMROOT",
|
|
31074
|
+
"SYSTEMDRIVE",
|
|
31075
|
+
"WINDIR",
|
|
31076
|
+
"COMSPEC",
|
|
31077
|
+
"USERPROFILE",
|
|
31078
|
+
"USERNAME",
|
|
31079
|
+
"HOMEDRIVE",
|
|
31080
|
+
"HOMEPATH",
|
|
31081
|
+
"APPDATA",
|
|
31082
|
+
"LOCALAPPDATA",
|
|
31083
|
+
"PROGRAMDATA",
|
|
31084
|
+
"PROGRAMFILES",
|
|
31085
|
+
"PROGRAMFILES(X86)",
|
|
31086
|
+
"TEMP",
|
|
31087
|
+
"TMP"
|
|
31088
|
+
]);
|
|
31089
|
+
var PROTECTED_PREFIXES = ["NOTIAMO_", "GIT_", "CLAUDE_", "ANTHROPIC_", "LC_", "XDG_"];
|
|
31090
|
+
var KEY_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
31091
|
+
var PROJECT_ID_RE = /^[\w-]+$/;
|
|
31092
|
+
var isProtectedKey = (key) => PROTECTED_KEYS.has(key.toUpperCase()) || PROTECTED_PREFIXES.some((p) => key.toUpperCase().startsWith(p));
|
|
31093
|
+
var unescape2 = (s) => s.replace(/\\([ntr\\"])/g, (_, c) => ({ n: "\n", t: " ", r: "\r", "\\": "\\", '"': '"' })[c]);
|
|
31094
|
+
function parseEnvFile(text) {
|
|
31095
|
+
const env2 = {};
|
|
31096
|
+
const skipped = [];
|
|
31097
|
+
const lines2 = text.split(/\r?\n/);
|
|
31098
|
+
for (let i = 0; i < lines2.length; i++) {
|
|
31099
|
+
const raw = lines2[i].trim();
|
|
31100
|
+
if (raw === "" || raw.startsWith("#")) continue;
|
|
31101
|
+
const line = raw.startsWith("export ") ? raw.slice(7).trimStart() : raw;
|
|
31102
|
+
const eq = line.indexOf("=");
|
|
31103
|
+
const key = eq < 0 ? "" : line.slice(0, eq).trim();
|
|
31104
|
+
if (eq < 0 || !KEY_RE.test(key)) {
|
|
31105
|
+
skipped.push({ line: i + 1, key: KEY_RE.test(key) ? key : key.split(/\s/)[0] ?? "", reason: "bad_line" });
|
|
31106
|
+
continue;
|
|
31107
|
+
}
|
|
31108
|
+
if (isProtectedKey(key)) {
|
|
31109
|
+
skipped.push({ line: i + 1, key, reason: "protected" });
|
|
31110
|
+
continue;
|
|
31111
|
+
}
|
|
31112
|
+
let value = line.slice(eq + 1).trim();
|
|
31113
|
+
if (value.length >= 2 && value.startsWith('"') && value.endsWith('"')) value = unescape2(value.slice(1, -1));
|
|
31114
|
+
else if (value.length >= 2 && value.startsWith("'") && value.endsWith("'")) value = value.slice(1, -1);
|
|
31115
|
+
env2[key] = value;
|
|
31116
|
+
}
|
|
31117
|
+
return { env: env2, skipped };
|
|
31118
|
+
}
|
|
31119
|
+
function projectEnvPath(envDir, projectId) {
|
|
31120
|
+
if (!PROJECT_ID_RE.test(projectId)) throw new Error(`Not a project id: ${JSON.stringify(projectId)}. It is the last part of the project page's address.`);
|
|
31121
|
+
return path8.join(envDir, `${projectId}.env`);
|
|
31122
|
+
}
|
|
31123
|
+
function loadProjectEnv(envDir, projectId, log) {
|
|
31124
|
+
const file2 = projectEnvPath(envDir, projectId);
|
|
31125
|
+
if (!existsSync5(file2)) return null;
|
|
31126
|
+
const { env: env2, skipped } = parseEnvFile(readFileSync3(file2, "utf8"));
|
|
31127
|
+
for (const s of skipped) {
|
|
31128
|
+
log.warn(s.reason === "protected" ? `env file ${file2}: line ${s.line} sets ${s.key}, a protected variable: skipped` : `env file ${file2}: line ${s.line} is not KEY=VALUE: skipped`);
|
|
31129
|
+
}
|
|
31130
|
+
return { env: env2, names: Object.keys(env2).sort() };
|
|
31131
|
+
}
|
|
31132
|
+
var HEADER = `# Environment for the runs of this project on this machine (notiamo-runner).
|
|
31133
|
+
# One KEY=VALUE per line. Dev and test values only: the agent can read every variable. Never production keys.
|
|
31134
|
+
# With this file present, the run's shell may reach services on 127.0.0.1 (your Postgres, MinIO, Mailpit...) on macOS.
|
|
31135
|
+
# PATH, HOME, proxy and certificate variables, NODE_OPTIONS, NOTIAMO_*, GIT_*, CLAUDE_* and ANTHROPIC_* are ignored here.
|
|
31136
|
+
`;
|
|
31137
|
+
function ensureProjectEnv(envDir, projectId) {
|
|
31138
|
+
const file2 = projectEnvPath(envDir, projectId);
|
|
31139
|
+
mkdirSync7(envDir, { recursive: true, mode: 448 });
|
|
31140
|
+
try {
|
|
31141
|
+
chmodSync2(envDir, 448);
|
|
31142
|
+
} catch {
|
|
31143
|
+
}
|
|
31144
|
+
if (!existsSync5(file2)) {
|
|
31145
|
+
writeFileSync6(file2, HEADER, { mode: 384 });
|
|
31146
|
+
try {
|
|
31147
|
+
chmodSync2(file2, 384);
|
|
31148
|
+
} catch {
|
|
31149
|
+
}
|
|
31150
|
+
}
|
|
31151
|
+
return file2;
|
|
31152
|
+
}
|
|
31153
|
+
|
|
31009
31154
|
// src/scrub.ts
|
|
31010
31155
|
function scrub(line, secrets) {
|
|
31011
31156
|
const forms = /* @__PURE__ */ new Set();
|
|
@@ -31075,12 +31220,12 @@ function resolveRoute(siteUrl, route) {
|
|
|
31075
31220
|
return { error: "route is not a valid URL path" };
|
|
31076
31221
|
}
|
|
31077
31222
|
if (url2.origin !== site.origin || !url2.pathname.startsWith(prefix + "/wp/v2/")) return { error: "route must stay under /wp/v2/" };
|
|
31078
|
-
const
|
|
31079
|
-
return { path:
|
|
31223
|
+
const path14 = url2.pathname.slice(prefix.length);
|
|
31224
|
+
return { path: path14, route: path14 + url2.search, query: url2.searchParams };
|
|
31080
31225
|
}
|
|
31081
31226
|
|
|
31082
31227
|
// src/wp/backup.ts
|
|
31083
|
-
import
|
|
31228
|
+
import path9 from "node:path";
|
|
31084
31229
|
|
|
31085
31230
|
// src/wp/transport.ts
|
|
31086
31231
|
var shellQuote = (a) => /^[A-Za-z0-9_\-.,/:=@%+]+$/.test(a) ? a : `'${a.replace(/'/g, `'\\''`)}'`;
|
|
@@ -31099,7 +31244,7 @@ async function backupBefore(t, root) {
|
|
|
31099
31244
|
const wp = await dump(`{ wp db export - --path=${shellQuote(root)} || echo ${FAILED} >&2; } | gzip`);
|
|
31100
31245
|
if (wp === "overflow") throw new Error("backup_failed: the database dump is over 200 MB");
|
|
31101
31246
|
if (wp) return { dump: wp, how: "wp-cli" };
|
|
31102
|
-
const config2 = await t.getFile(
|
|
31247
|
+
const config2 = await t.getFile(path9.posix.join(root, "wp-config.php")).catch(() => null);
|
|
31103
31248
|
const db = config2 ? dbCredentials(config2) : null;
|
|
31104
31249
|
if (!db) throw new Error("backup_failed: no wp-cli export and no database credentials in wp-config.php");
|
|
31105
31250
|
const [host, port] = splitHost(db.host);
|
|
@@ -31231,7 +31376,7 @@ async function ftpTransport(conn) {
|
|
|
31231
31376
|
// src/wp/helper.ts
|
|
31232
31377
|
import { randomBytes, timingSafeEqual } from "node:crypto";
|
|
31233
31378
|
import http from "node:http";
|
|
31234
|
-
import
|
|
31379
|
+
import path10 from "node:path";
|
|
31235
31380
|
|
|
31236
31381
|
// ../../node_modules/.pnpm/zod@4.6.7/node_modules/zod/v3/helpers/util.js
|
|
31237
31382
|
var util;
|
|
@@ -31607,8 +31752,8 @@ function getErrorMap() {
|
|
|
31607
31752
|
|
|
31608
31753
|
// ../../node_modules/.pnpm/zod@4.6.7/node_modules/zod/v3/helpers/parseUtil.js
|
|
31609
31754
|
var makeIssue = (params) => {
|
|
31610
|
-
const { data, path:
|
|
31611
|
-
const fullPath = [...
|
|
31755
|
+
const { data, path: path14, errorMaps, issueData } = params;
|
|
31756
|
+
const fullPath = [...path14, ...issueData.path || []];
|
|
31612
31757
|
const fullIssue = {
|
|
31613
31758
|
...issueData,
|
|
31614
31759
|
path: fullPath
|
|
@@ -31723,11 +31868,11 @@ var errorUtil;
|
|
|
31723
31868
|
|
|
31724
31869
|
// ../../node_modules/.pnpm/zod@4.6.7/node_modules/zod/v3/types.js
|
|
31725
31870
|
var ParseInputLazyPath = class {
|
|
31726
|
-
constructor(parent, value,
|
|
31871
|
+
constructor(parent, value, path14, key) {
|
|
31727
31872
|
this._cachedPath = [];
|
|
31728
31873
|
this.parent = parent;
|
|
31729
31874
|
this.data = value;
|
|
31730
|
-
this._path =
|
|
31875
|
+
this._path = path14;
|
|
31731
31876
|
this._key = key;
|
|
31732
31877
|
}
|
|
31733
31878
|
get path() {
|
|
@@ -35682,10 +35827,10 @@ function mergeDefs(...defs) {
|
|
|
35682
35827
|
function cloneDef(schema) {
|
|
35683
35828
|
return mergeDefs(schema._zod.def);
|
|
35684
35829
|
}
|
|
35685
|
-
function getElementAtPath(obj,
|
|
35686
|
-
if (!
|
|
35830
|
+
function getElementAtPath(obj, path14) {
|
|
35831
|
+
if (!path14)
|
|
35687
35832
|
return obj;
|
|
35688
|
-
return
|
|
35833
|
+
return path14.reduce((acc, key) => acc?.[key], obj);
|
|
35689
35834
|
}
|
|
35690
35835
|
function promiseAllObject(promisesObj) {
|
|
35691
35836
|
const keys = Object.keys(promisesObj);
|
|
@@ -36025,11 +36170,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
36025
36170
|
}
|
|
36026
36171
|
return false;
|
|
36027
36172
|
}
|
|
36028
|
-
function prefixIssues(
|
|
36173
|
+
function prefixIssues(path14, issues) {
|
|
36029
36174
|
return issues.map((iss) => {
|
|
36030
36175
|
var _a3;
|
|
36031
36176
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
36032
|
-
iss.path.unshift(
|
|
36177
|
+
iss.path.unshift(path14);
|
|
36033
36178
|
return iss;
|
|
36034
36179
|
});
|
|
36035
36180
|
}
|
|
@@ -36491,16 +36636,16 @@ function flattenError(error62, mapper = (issue2) => issue2.message) {
|
|
|
36491
36636
|
}
|
|
36492
36637
|
function formatError(error62, mapper = (issue2) => issue2.message) {
|
|
36493
36638
|
const fieldErrors = { _errors: [] };
|
|
36494
|
-
const processError = (error63,
|
|
36639
|
+
const processError = (error63, path14 = []) => {
|
|
36495
36640
|
for (const issue2 of error63.issues) {
|
|
36496
36641
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
36497
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
36642
|
+
issue2.errors.map((issues) => processError({ issues }, [...path14, ...issue2.path]));
|
|
36498
36643
|
} else if (issue2.code === "invalid_key") {
|
|
36499
|
-
processError({ issues: issue2.issues }, [...
|
|
36644
|
+
processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
|
|
36500
36645
|
} else if (issue2.code === "invalid_element") {
|
|
36501
|
-
processError({ issues: issue2.issues }, [...
|
|
36646
|
+
processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
|
|
36502
36647
|
} else {
|
|
36503
|
-
const fullpath = [...
|
|
36648
|
+
const fullpath = [...path14, ...issue2.path];
|
|
36504
36649
|
if (fullpath.length === 0) {
|
|
36505
36650
|
fieldErrors._errors.push(mapper(issue2));
|
|
36506
36651
|
} else {
|
|
@@ -36539,17 +36684,17 @@ function formatError(error62, mapper = (issue2) => issue2.message) {
|
|
|
36539
36684
|
}
|
|
36540
36685
|
function treeifyError(error62, mapper = (issue2) => issue2.message) {
|
|
36541
36686
|
const result = { errors: [] };
|
|
36542
|
-
const processError = (error63,
|
|
36687
|
+
const processError = (error63, path14 = []) => {
|
|
36543
36688
|
var _a3;
|
|
36544
36689
|
for (const issue2 of error63.issues) {
|
|
36545
36690
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
36546
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
36691
|
+
issue2.errors.map((issues) => processError({ issues }, [...path14, ...issue2.path]));
|
|
36547
36692
|
} else if (issue2.code === "invalid_key") {
|
|
36548
|
-
processError({ issues: issue2.issues }, [...
|
|
36693
|
+
processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
|
|
36549
36694
|
} else if (issue2.code === "invalid_element") {
|
|
36550
|
-
processError({ issues: issue2.issues }, [...
|
|
36695
|
+
processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
|
|
36551
36696
|
} else {
|
|
36552
|
-
const fullpath = [...
|
|
36697
|
+
const fullpath = [...path14, ...issue2.path];
|
|
36553
36698
|
if (fullpath.length === 0) {
|
|
36554
36699
|
result.errors.push(mapper(issue2));
|
|
36555
36700
|
continue;
|
|
@@ -36588,8 +36733,8 @@ function treeifyError(error62, mapper = (issue2) => issue2.message) {
|
|
|
36588
36733
|
}
|
|
36589
36734
|
function toDotPath(_path) {
|
|
36590
36735
|
const segs = [];
|
|
36591
|
-
const
|
|
36592
|
-
for (const seg of
|
|
36736
|
+
const path14 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
36737
|
+
for (const seg of path14) {
|
|
36593
36738
|
if (typeof seg === "number")
|
|
36594
36739
|
segs.push(`[${seg}]`);
|
|
36595
36740
|
else if (typeof seg === "symbol")
|
|
@@ -52140,11 +52285,11 @@ function normalizeObjectSchema(schema) {
|
|
|
52140
52285
|
}
|
|
52141
52286
|
return void 0;
|
|
52142
52287
|
}
|
|
52143
|
-
function getDotPath(
|
|
52144
|
-
if (
|
|
52288
|
+
function getDotPath(path14) {
|
|
52289
|
+
if (path14.length === 0) {
|
|
52145
52290
|
return "object root";
|
|
52146
52291
|
}
|
|
52147
|
-
return
|
|
52292
|
+
return path14.reduce((acc, seg, index) => {
|
|
52148
52293
|
if (index === 0) {
|
|
52149
52294
|
return String(seg);
|
|
52150
52295
|
}
|
|
@@ -54371,13 +54516,13 @@ function resolveRef(ref, ctx) {
|
|
|
54371
54516
|
if (!ref.startsWith("#")) {
|
|
54372
54517
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
54373
54518
|
}
|
|
54374
|
-
const
|
|
54375
|
-
if (
|
|
54519
|
+
const path14 = ref.slice(1).split("/").filter(Boolean);
|
|
54520
|
+
if (path14.length === 0) {
|
|
54376
54521
|
return ctx.rootSchema;
|
|
54377
54522
|
}
|
|
54378
54523
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
54379
|
-
if (
|
|
54380
|
-
const key =
|
|
54524
|
+
if (path14[0] === defsKey) {
|
|
54525
|
+
const key = path14[1] === void 0 ? void 0 : decodeJSONPointerSegment(path14[1]);
|
|
54381
54526
|
if (!key || !ctx.defs[key]) {
|
|
54382
54527
|
throw new Error(`Reference not found: ${ref}`);
|
|
54383
54528
|
}
|
|
@@ -61643,15 +61788,15 @@ var CONNECTION_SYMBOL_KEY = /* @__PURE__ */ Symbol("CONNECTION_SYMBOL_KEY");
|
|
|
61643
61788
|
var WAIT_FOR_WEBSOCKET_SYMBOL = /* @__PURE__ */ Symbol("WAIT_FOR_WEBSOCKET_SYMBOL");
|
|
61644
61789
|
var upgradeWebSocket = defineWebSocketHelper(async (c, events, options) => {
|
|
61645
61790
|
if (c.req.header("upgrade")?.toLowerCase() !== "websocket") return;
|
|
61646
|
-
const
|
|
61647
|
-
const waitForWebSocket =
|
|
61648
|
-
if (!waitForWebSocket || !
|
|
61791
|
+
const env2 = c.env;
|
|
61792
|
+
const waitForWebSocket = env2[WAIT_FOR_WEBSOCKET_SYMBOL];
|
|
61793
|
+
if (!waitForWebSocket || !env2.incoming) return new Response(null, { status: 500 });
|
|
61649
61794
|
const connectionSymbol = generateConnectionSymbol();
|
|
61650
|
-
|
|
61795
|
+
env2[CONNECTION_SYMBOL_KEY] = connectionSymbol;
|
|
61651
61796
|
(async () => {
|
|
61652
61797
|
let ws;
|
|
61653
61798
|
try {
|
|
61654
|
-
ws = await waitForWebSocket(
|
|
61799
|
+
ws = await waitForWebSocket(env2.incoming, connectionSymbol);
|
|
61655
61800
|
} catch {
|
|
61656
61801
|
return;
|
|
61657
61802
|
}
|
|
@@ -62825,7 +62970,7 @@ function buildServer(t) {
|
|
|
62825
62970
|
if (!t.allow.files && !t.allow.all) return fail("the files group is off for this project");
|
|
62826
62971
|
if (t.root === null) return fail("wordpress_root_not_found: the WordPress folder was not found on the server");
|
|
62827
62972
|
const bad = pathRefusal(p, t.allow.all);
|
|
62828
|
-
return bad ? fail(bad) :
|
|
62973
|
+
return bad ? fail(bad) : path10.posix.join(t.root, p);
|
|
62829
62974
|
};
|
|
62830
62975
|
server.registerTool("wp_get_file", {
|
|
62831
62976
|
description: "Reads a file of the WordPress site, by its path relative to the WordPress folder (e.g. wp-content/themes/x/style.css).",
|
|
@@ -62897,9 +63042,9 @@ function apiRefusal(route, query, method, body, allow) {
|
|
|
62897
63042
|
}
|
|
62898
63043
|
function pathRefusal(p, all) {
|
|
62899
63044
|
if (p.startsWith("/") || p.includes("\\") || p.includes("\0")) return "path must be relative to the WordPress folder";
|
|
62900
|
-
const norm =
|
|
63045
|
+
const norm = path10.posix.normalize(p);
|
|
62901
63046
|
if (norm === ".." || norm.startsWith("../") || p.split("/").includes("..")) return "path must stay inside the WordPress folder";
|
|
62902
|
-
if (!all && PROTECTED_FILES.has(
|
|
63047
|
+
if (!all && PROTECTED_FILES.has(path10.posix.basename(norm))) return `refused: ${path10.posix.basename(norm)} is never changed unless "Allow everything" is on`;
|
|
62903
63048
|
return null;
|
|
62904
63049
|
}
|
|
62905
63050
|
function publishedLink(json3) {
|
|
@@ -62911,7 +63056,7 @@ var cut2 = (s) => s.length > MAX_OUTPUT ? `${s.slice(0, MAX_OUTPUT)}
|
|
|
62911
63056
|
[cut at ${MAX_OUTPUT} characters]` : s;
|
|
62912
63057
|
|
|
62913
63058
|
// src/wp/root.ts
|
|
62914
|
-
import
|
|
63059
|
+
import path11 from "node:path";
|
|
62915
63060
|
var FTP_CANDIDATES = [".", "public_html", "www", "htdocs", "httpdocs", "html", "web"];
|
|
62916
63061
|
async function findRoot(t) {
|
|
62917
63062
|
if (t.run) {
|
|
@@ -62919,10 +63064,10 @@ async function findRoot(t) {
|
|
|
62919
63064
|
if (home?.code === 0) return ".";
|
|
62920
63065
|
const found = await t.run(["find", ".", "-maxdepth", "3", "-name", "wp-config.php"]).catch(() => null);
|
|
62921
63066
|
const first = found?.stdout.toString("utf8").split("\n").map((l) => l.trim()).filter(Boolean).sort((a, b) => a.split("/").length - b.split("/").length)[0];
|
|
62922
|
-
return first ?
|
|
63067
|
+
return first ? path11.posix.normalize(path11.posix.dirname(first)) : null;
|
|
62923
63068
|
}
|
|
62924
63069
|
for (const dir of FTP_CANDIDATES) {
|
|
62925
|
-
if (await t.getFile(
|
|
63070
|
+
if (await t.getFile(path11.posix.join(dir, "wp-config.php")).catch(() => null) !== null) return dir;
|
|
62926
63071
|
}
|
|
62927
63072
|
return null;
|
|
62928
63073
|
}
|
|
@@ -63055,17 +63200,23 @@ async function runOne(spec, deps) {
|
|
|
63055
63200
|
} else {
|
|
63056
63201
|
started = true;
|
|
63057
63202
|
const parent = projectFolder(deps.paths.projectsDir, slot, spec.projectId);
|
|
63058
|
-
|
|
63059
|
-
cwd = tempDir = mkdtempSync(
|
|
63203
|
+
mkdirSync8(parent, { recursive: true, mode: 448 });
|
|
63204
|
+
cwd = tempDir = mkdtempSync(path12.join(parent, "run-"));
|
|
63060
63205
|
if (deps.helperFactory) helper = await deps.helperFactory(spec);
|
|
63061
63206
|
}
|
|
63062
|
-
|
|
63207
|
+
const projectEnv = loadProjectEnv(deps.paths.envDir, spec.projectId, log);
|
|
63208
|
+
settingsFile = writeSettings(spec, deps, cwd, projectEnv !== null);
|
|
63209
|
+
if (projectEnv) {
|
|
63210
|
+
secrets.push(...Object.values(projectEnv.env));
|
|
63211
|
+
log.info(`run ${spec.runId}: env file with ${projectEnv.names.length} variable(s)`);
|
|
63212
|
+
}
|
|
63063
63213
|
const base = {
|
|
63214
|
+
// 127.0.0.1 is the machine's only on macOS: Linux's sandbox gives the shell its own network namespace.
|
|
63064
63215
|
cwd,
|
|
63065
|
-
systemPrompt: spec.systemPrompt,
|
|
63216
|
+
systemPrompt: projectEnv ? withEnvNote(spec.systemPrompt, projectEnv.names, deps.sandbox.platform === "darwin") : spec.systemPrompt,
|
|
63066
63217
|
mcp: { url: spec.mcp.url, token: spec.mcp.accessToken },
|
|
63067
63218
|
helper: helper ? { url: helper.url, token: helper.token } : void 0,
|
|
63068
|
-
env: {},
|
|
63219
|
+
env: projectEnv?.env ?? {},
|
|
63069
63220
|
maxMinutes: spec.maxRunMinutes,
|
|
63070
63221
|
claudeConfigDir: deps.paths.claudeConfigDir,
|
|
63071
63222
|
settingsFile
|
|
@@ -63189,7 +63340,14 @@ function githubToken(runId, g, api, secrets, now) {
|
|
|
63189
63340
|
return token;
|
|
63190
63341
|
};
|
|
63191
63342
|
}
|
|
63192
|
-
function
|
|
63343
|
+
function withEnvNote(systemPrompt, names, localServices) {
|
|
63344
|
+
const list = names.length > 0 ? `these environment variables for the project: ${names.join(", ")}` : "an environment file for the project (empty)";
|
|
63345
|
+
const local = localServices ? " Services they point to run on 127.0.0.1 and are reachable from your shell." : "";
|
|
63346
|
+
return `${systemPrompt}
|
|
63347
|
+
|
|
63348
|
+
This machine sets ${list}.${local} Use them for tests; do not print their values.`;
|
|
63349
|
+
}
|
|
63350
|
+
function writeSettings(spec, deps, cwd, localServices) {
|
|
63193
63351
|
const { sandbox } = deps;
|
|
63194
63352
|
let wordpressHost;
|
|
63195
63353
|
if (spec.wordpress) {
|
|
@@ -63199,8 +63357,8 @@ function writeSettings(spec, deps, cwd) {
|
|
|
63199
63357
|
}
|
|
63200
63358
|
}
|
|
63201
63359
|
if (!/^[\w-]+$/.test(spec.runId)) throw new Error("bad run id");
|
|
63202
|
-
const dir =
|
|
63203
|
-
|
|
63360
|
+
const dir = path12.resolve(deps.paths.runsDir);
|
|
63361
|
+
mkdirSync8(dir, { recursive: true, mode: 448 });
|
|
63204
63362
|
const settings = sandboxSettings({
|
|
63205
63363
|
platform: sandbox.platform,
|
|
63206
63364
|
runnerRoot: sandbox.runnerRoot,
|
|
@@ -63209,13 +63367,14 @@ function writeSettings(spec, deps, cwd) {
|
|
|
63209
63367
|
notiamoHost: sandbox.notiamoHost,
|
|
63210
63368
|
extraDomains: sandbox.allowedDomains(),
|
|
63211
63369
|
wordpressHost,
|
|
63370
|
+
localServices,
|
|
63212
63371
|
gitExecPath: sandbox.gitExecPath,
|
|
63213
63372
|
ghPath: sandbox.ghPath
|
|
63214
63373
|
});
|
|
63215
|
-
const file2 =
|
|
63216
|
-
|
|
63374
|
+
const file2 = path12.join(dir, `${spec.runId}.json`);
|
|
63375
|
+
writeFileSync7(file2, JSON.stringify(settings, null, 2) + "\n", { mode: 384 });
|
|
63217
63376
|
try {
|
|
63218
|
-
|
|
63377
|
+
chmodSync3(file2, 384);
|
|
63219
63378
|
} catch {
|
|
63220
63379
|
}
|
|
63221
63380
|
return file2;
|
|
@@ -63376,7 +63535,7 @@ async function startLoop(deps) {
|
|
|
63376
63535
|
const running = /* @__PURE__ */ new Map();
|
|
63377
63536
|
for (let i = 0; i < SLOT_FOLDERS; i++) {
|
|
63378
63537
|
try {
|
|
63379
|
-
|
|
63538
|
+
mkdirSync9(path13.join(deps.paths.projectsDir, String(i)), { recursive: true, mode: 448 });
|
|
63380
63539
|
} catch (e) {
|
|
63381
63540
|
log.warn(`slot folder ${i} not made: ${errorText3(e)}`);
|
|
63382
63541
|
}
|
|
@@ -63476,7 +63635,7 @@ async function startLoop(deps) {
|
|
|
63476
63635
|
var errorText3 = (e) => e instanceof Error ? e.message : String(e);
|
|
63477
63636
|
function readState(file2) {
|
|
63478
63637
|
try {
|
|
63479
|
-
const s = JSON.parse(
|
|
63638
|
+
const s = JSON.parse(readFileSync4(file2, "utf8"));
|
|
63480
63639
|
if (Array.isArray(s.busyRunIds)) return s.busyRunIds.filter((x) => typeof x === "string");
|
|
63481
63640
|
return typeof s.busyRunId === "string" ? [s.busyRunId] : [];
|
|
63482
63641
|
} catch {
|
|
@@ -63488,9 +63647,9 @@ function writeState(file2, busyRunIds) {
|
|
|
63488
63647
|
rmSync6(file2, { force: true });
|
|
63489
63648
|
return;
|
|
63490
63649
|
}
|
|
63491
|
-
|
|
63650
|
+
mkdirSync9(path13.dirname(file2), { recursive: true, mode: 448 });
|
|
63492
63651
|
const tmp = `${file2}.tmp`;
|
|
63493
|
-
|
|
63652
|
+
writeFileSync8(tmp, JSON.stringify({ busyRunIds }) + "\n", { mode: 384 });
|
|
63494
63653
|
renameSync2(tmp, file2);
|
|
63495
63654
|
}
|
|
63496
63655
|
|
|
@@ -63529,6 +63688,9 @@ async function prompt(q2, opts = {}) {
|
|
|
63529
63688
|
async function init({ profile } = {}) {
|
|
63530
63689
|
await runInit({ prompt, exec: realExec, fetch, profile });
|
|
63531
63690
|
}
|
|
63691
|
+
async function update({ profile } = {}) {
|
|
63692
|
+
await runUpdate({ exec: realExec, fetch, profile });
|
|
63693
|
+
}
|
|
63532
63694
|
async function start({ profile } = {}) {
|
|
63533
63695
|
const dir = profileDir(profile);
|
|
63534
63696
|
const cfg = loadConfig(dir);
|
|
@@ -63593,6 +63755,13 @@ async function uninstall4({ profile } = {}) {
|
|
|
63593
63755
|
await uninstallService(serviceOptions(profile));
|
|
63594
63756
|
console.log(`The runner service is removed. Its folder ${profileDir(profile)} (config, sign-in, projects) stays; delete it to remove everything.`);
|
|
63595
63757
|
}
|
|
63758
|
+
async function env({ profile, projectId }) {
|
|
63759
|
+
const file2 = ensureProjectEnv(paths(profileDir(profile)).envDir, projectId);
|
|
63760
|
+
console.log(`Env file for project ${projectId}${profile ? ` (profile ${profile})` : ""}: ${file2}`);
|
|
63761
|
+
console.log("One KEY=VALUE per line. Dev and test values only: the agent can read every variable, never production keys.");
|
|
63762
|
+
console.log("With this file present, the runs of this project may reach services on 127.0.0.1 (Postgres, MinIO, Mailpit...) on macOS; on Linux the sandbox keeps 127.0.0.1 apart, use the machine's LAN address.");
|
|
63763
|
+
console.log("The next run of the project reads it; the runner needs no restart. Remove the file to take the variables away.");
|
|
63764
|
+
}
|
|
63596
63765
|
async function status4({ profile } = {}) {
|
|
63597
63766
|
const st = await serviceStatus(serviceOptions(profile));
|
|
63598
63767
|
let cfg = null;
|
|
@@ -63621,7 +63790,7 @@ function hostOf(url2) {
|
|
|
63621
63790
|
function tail(file2, n) {
|
|
63622
63791
|
let text;
|
|
63623
63792
|
try {
|
|
63624
|
-
text =
|
|
63793
|
+
text = readFileSync5(file2, "utf8");
|
|
63625
63794
|
} catch {
|
|
63626
63795
|
return [];
|
|
63627
63796
|
}
|
|
@@ -63634,17 +63803,19 @@ var HELP = `notiamo-runner ${VERSION}: runs Notiamo agent runs on this machine w
|
|
|
63634
63803
|
Usage: notiamo-runner <command> [--profile <name>]
|
|
63635
63804
|
|
|
63636
63805
|
init Set the runner up: token, Claude Code sign-in, start at login or boot
|
|
63806
|
+
update Move a runner that is set up to this version: keeps its token and sign-in
|
|
63637
63807
|
start Run in the foreground (what the service runs)
|
|
63638
63808
|
stop Stop the service until the next login or boot
|
|
63639
63809
|
status Whether the service is installed and running, and the last log line
|
|
63640
63810
|
logs The last 50 lines of the log
|
|
63641
63811
|
uninstall Remove the service (the runner's folder stays)
|
|
63812
|
+
env <projectId> Make or show the env file this machine gives the runs of one project (dev/test values)
|
|
63642
63813
|
--version Print the version
|
|
63643
63814
|
|
|
63644
63815
|
--profile <name> A second runner on this machine (say "staging"): its own folder, sign-in and service.
|
|
63645
63816
|
Give it to every command of that runner.`;
|
|
63646
63817
|
async function main(argv) {
|
|
63647
|
-
const { cmd, profile, error: error62 } = parseArgs(argv);
|
|
63818
|
+
const { cmd, arg, profile, error: error62 } = parseArgs(argv);
|
|
63648
63819
|
if (error62) {
|
|
63649
63820
|
console.error(`${error62}
|
|
63650
63821
|
|
|
@@ -63653,9 +63824,18 @@ ${HELP}`);
|
|
|
63653
63824
|
return;
|
|
63654
63825
|
}
|
|
63655
63826
|
const o = { profile };
|
|
63827
|
+
if (cmd === "env" && !arg) {
|
|
63828
|
+
console.error(`env needs the project id: the last part of the project page's address.
|
|
63829
|
+
|
|
63830
|
+
${HELP}`);
|
|
63831
|
+
process.exitCode = 1;
|
|
63832
|
+
return;
|
|
63833
|
+
}
|
|
63656
63834
|
switch (cmd) {
|
|
63657
63835
|
case "init":
|
|
63658
63836
|
return init(o);
|
|
63837
|
+
case "update":
|
|
63838
|
+
return update(o);
|
|
63659
63839
|
case "start":
|
|
63660
63840
|
return start(o);
|
|
63661
63841
|
case "stop":
|
|
@@ -63666,6 +63846,8 @@ ${HELP}`);
|
|
|
63666
63846
|
return logs(o);
|
|
63667
63847
|
case "uninstall":
|
|
63668
63848
|
return uninstall4(o);
|
|
63849
|
+
case "env":
|
|
63850
|
+
return env({ ...o, projectId: arg });
|
|
63669
63851
|
case "--version":
|
|
63670
63852
|
case "-v":
|
|
63671
63853
|
console.log(`notiamo-runner ${VERSION}`);
|