@brainervirus/workit-cursor 8.12.1 → 8.12.3
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/.cursor-plugin/plugin.json +1 -1
- package/dist/cursor-session-start.js +1285 -202
- package/dist/mcp-server.js +52 -4
- package/dist/workit-hook.js +1342 -195
- package/package.json +3 -3
|
@@ -17960,7 +17960,63 @@ var init_session_marker = __esm(() => {
|
|
|
17960
17960
|
});
|
|
17961
17961
|
|
|
17962
17962
|
// packages/workit-core/src/hooks/shell-words.ts
|
|
17963
|
-
var
|
|
17963
|
+
var ShellAnalysisError, MAX_NESTING = 64, OPEN = "", COMMA = "", CLOSE = "", MARKERS, literal2 = (word) => word.replaceAll(OPEN, "{").replaceAll(COMMA, ",").replaceAll(CLOSE, "}"), BRACE_LIMIT = 64, BRACE_PENDING = 512, BRACE_DEPTH = 16, braceGroup = (word) => {
|
|
17964
|
+
for (let start = 0;start < word.length; start++) {
|
|
17965
|
+
if (word[start] !== OPEN)
|
|
17966
|
+
continue;
|
|
17967
|
+
let depth = 0;
|
|
17968
|
+
let end = start;
|
|
17969
|
+
const commas = [];
|
|
17970
|
+
for (;end < word.length; end++) {
|
|
17971
|
+
if (word[end] === OPEN)
|
|
17972
|
+
depth++;
|
|
17973
|
+
else if (word[end] === CLOSE && --depth === 0)
|
|
17974
|
+
break;
|
|
17975
|
+
else if (word[end] === COMMA && depth === 1)
|
|
17976
|
+
commas.push(end);
|
|
17977
|
+
}
|
|
17978
|
+
if (end < word.length && commas.length)
|
|
17979
|
+
return { start, end, commas };
|
|
17980
|
+
}
|
|
17981
|
+
return null;
|
|
17982
|
+
}, expandBraces = (word) => {
|
|
17983
|
+
let depth = 0;
|
|
17984
|
+
for (const char of word) {
|
|
17985
|
+
if (char === OPEN && ++depth > BRACE_DEPTH)
|
|
17986
|
+
return [literal2(word)];
|
|
17987
|
+
if (char === CLOSE && depth > 0)
|
|
17988
|
+
depth--;
|
|
17989
|
+
}
|
|
17990
|
+
const done = new Set;
|
|
17991
|
+
const queue = [word];
|
|
17992
|
+
const queued = new Set(queue);
|
|
17993
|
+
for (let at = 0;at < queue.length; at++) {
|
|
17994
|
+
const current = queue[at];
|
|
17995
|
+
const group = braceGroup(current);
|
|
17996
|
+
if (!group) {
|
|
17997
|
+
const text = literal2(current);
|
|
17998
|
+
if (text)
|
|
17999
|
+
done.add(text);
|
|
18000
|
+
if (done.size > BRACE_LIMIT)
|
|
18001
|
+
return [literal2(word)];
|
|
18002
|
+
continue;
|
|
18003
|
+
}
|
|
18004
|
+
const pre = current.slice(0, group.start);
|
|
18005
|
+
const post = current.slice(group.end + 1);
|
|
18006
|
+
let from = group.start + 1;
|
|
18007
|
+
for (const comma of [...group.commas, group.end]) {
|
|
18008
|
+
const next = pre + current.slice(from, comma) + post;
|
|
18009
|
+
from = comma + 1;
|
|
18010
|
+
if (queued.has(next))
|
|
18011
|
+
continue;
|
|
18012
|
+
queued.add(next);
|
|
18013
|
+
queue.push(next);
|
|
18014
|
+
}
|
|
18015
|
+
if (queue.length - at > BRACE_PENDING)
|
|
18016
|
+
return [literal2(word)];
|
|
18017
|
+
}
|
|
18018
|
+
return [...done];
|
|
18019
|
+
}, closingQuote = (command, start, dialect, nesting = 0) => {
|
|
17964
18020
|
const quote = command[start];
|
|
17965
18021
|
for (let index = start + 1;index < command.length; index++) {
|
|
17966
18022
|
const char = command[index];
|
|
@@ -17977,49 +18033,241 @@ var closingQuote = (command, start, dialect) => {
|
|
|
17977
18033
|
index++;
|
|
17978
18034
|
continue;
|
|
17979
18035
|
}
|
|
18036
|
+
if (dialect === "posix" && char === "$" && command[index + 1] === "(") {
|
|
18037
|
+
index = substitutionEnd(command, index + 1, nesting + 1);
|
|
18038
|
+
continue;
|
|
18039
|
+
}
|
|
18040
|
+
if (dialect === "posix" && char === "`") {
|
|
18041
|
+
index = backtickEnd(command, index);
|
|
18042
|
+
continue;
|
|
18043
|
+
}
|
|
17980
18044
|
if (char === '"')
|
|
17981
18045
|
return index;
|
|
17982
18046
|
}
|
|
17983
18047
|
return -1;
|
|
18048
|
+
}, backtickEnd = (command, start) => {
|
|
18049
|
+
for (let index = start + 1;index < command.length; index++) {
|
|
18050
|
+
if (command[index] === "\\")
|
|
18051
|
+
index++;
|
|
18052
|
+
else if (command[index] === "`")
|
|
18053
|
+
return index;
|
|
18054
|
+
}
|
|
18055
|
+
return command.length;
|
|
18056
|
+
}, heredocDelimiter = (command, start) => {
|
|
18057
|
+
let index = start;
|
|
18058
|
+
if (command[index] === "-")
|
|
18059
|
+
index++;
|
|
18060
|
+
while (command[index] === " " || command[index] === "\t")
|
|
18061
|
+
index++;
|
|
18062
|
+
let delimiter = "";
|
|
18063
|
+
for (;index < command.length && !/[\s;&|<>()]/.test(command[index]); index++) {
|
|
18064
|
+
const char = command[index];
|
|
18065
|
+
if (char === "'" || char === '"') {
|
|
18066
|
+
const end = command.indexOf(char, index + 1);
|
|
18067
|
+
if (end < 0)
|
|
18068
|
+
break;
|
|
18069
|
+
delimiter += command.slice(index + 1, end);
|
|
18070
|
+
index = end;
|
|
18071
|
+
} else if (char === "\\")
|
|
18072
|
+
delimiter += command[++index] ?? "";
|
|
18073
|
+
else
|
|
18074
|
+
delimiter += char;
|
|
18075
|
+
}
|
|
18076
|
+
return { delimiter, end: index - 1 };
|
|
18077
|
+
}, skipHeredocs = (command, newline, delimiters) => {
|
|
18078
|
+
let index = newline;
|
|
18079
|
+
while (delimiters.length) {
|
|
18080
|
+
const delimiter = delimiters.shift();
|
|
18081
|
+
for (;; ) {
|
|
18082
|
+
const lineEnd = command.indexOf(`
|
|
18083
|
+
`, index + 1);
|
|
18084
|
+
const line = command.slice(index + 1, lineEnd < 0 ? undefined : lineEnd);
|
|
18085
|
+
index = lineEnd < 0 ? command.length : lineEnd;
|
|
18086
|
+
if (line.trim() === delimiter || lineEnd < 0)
|
|
18087
|
+
break;
|
|
18088
|
+
}
|
|
18089
|
+
}
|
|
18090
|
+
return index;
|
|
18091
|
+
}, substitutionEnd = (command, start, nesting = 0) => {
|
|
18092
|
+
if (nesting > MAX_NESTING)
|
|
18093
|
+
throw new ShellAnalysisError("substitutions nest too deep");
|
|
18094
|
+
let depth = 0;
|
|
18095
|
+
let wordStart = true;
|
|
18096
|
+
const heredocs = [];
|
|
18097
|
+
for (let index = start;index < command.length; index++) {
|
|
18098
|
+
const char = command[index];
|
|
18099
|
+
const atWordStart = wordStart;
|
|
18100
|
+
wordStart = /[\s;&|()]/.test(char);
|
|
18101
|
+
if (char === "\\")
|
|
18102
|
+
index++;
|
|
18103
|
+
else if (char === `
|
|
18104
|
+
` && heredocs.length) {
|
|
18105
|
+
index = skipHeredocs(command, index, heredocs);
|
|
18106
|
+
wordStart = true;
|
|
18107
|
+
} else if (char === "'" || char === '"') {
|
|
18108
|
+
const end = closingQuote(command, index, "posix", nesting);
|
|
18109
|
+
if (end < 0)
|
|
18110
|
+
return command.length;
|
|
18111
|
+
index = end;
|
|
18112
|
+
} else if (char === "`")
|
|
18113
|
+
index = backtickEnd(command, index);
|
|
18114
|
+
else if (char === "#" && atWordStart) {
|
|
18115
|
+
const newline = command.indexOf(`
|
|
18116
|
+
`, index);
|
|
18117
|
+
index = newline < 0 ? command.length : newline - 1;
|
|
18118
|
+
} else if (char === "<" && command[index + 1] === "<" && command[index + 2] !== "<") {
|
|
18119
|
+
const { delimiter, end } = heredocDelimiter(command, index + 2);
|
|
18120
|
+
if (delimiter)
|
|
18121
|
+
heredocs.push(delimiter);
|
|
18122
|
+
index = end;
|
|
18123
|
+
} else if (char === "<" && command[index + 1] === "<")
|
|
18124
|
+
index += 2;
|
|
18125
|
+
else if (char === "$" && command[index + 1] === "(")
|
|
18126
|
+
index = substitutionEnd(command, index + 1, nesting + 1);
|
|
18127
|
+
else if (char === "(")
|
|
18128
|
+
depth++;
|
|
18129
|
+
else if (char === ")" && --depth === 0)
|
|
18130
|
+
return index;
|
|
18131
|
+
}
|
|
18132
|
+
return command.length;
|
|
17984
18133
|
}, unquote = (body, quote, dialect) => {
|
|
17985
18134
|
if (quote === "'")
|
|
17986
18135
|
return dialect === "powershell" ? body.replaceAll("''", "'") : body;
|
|
17987
|
-
return dialect === "posix" ? body.replace(/\\(["\\$`])/g, "$1") : body.replace(/`(.)/g, "$1");
|
|
18136
|
+
return dialect === "posix" ? body.replace(/\\\n/g, "").replace(/\\(["\\$`])/g, "$1") : body.replace(/`(.)/g, "$1");
|
|
18137
|
+
}, C_ESCAPES, ansiC = (command, start) => {
|
|
18138
|
+
let text = "";
|
|
18139
|
+
let index = start + 1;
|
|
18140
|
+
for (;index < command.length && command[index] !== "'"; index++) {
|
|
18141
|
+
const char = command[index];
|
|
18142
|
+
if (char !== "\\" || index + 1 >= command.length) {
|
|
18143
|
+
text += char;
|
|
18144
|
+
continue;
|
|
18145
|
+
}
|
|
18146
|
+
const rest = command.slice(++index);
|
|
18147
|
+
const hex = /^x([0-9a-fA-F]{1,2})/.exec(rest);
|
|
18148
|
+
const octal = /^[0-7]{1,3}/.exec(rest);
|
|
18149
|
+
if (hex) {
|
|
18150
|
+
text += String.fromCharCode(Number.parseInt(hex[1], 16));
|
|
18151
|
+
index += hex[0].length - 1;
|
|
18152
|
+
} else if (octal) {
|
|
18153
|
+
text += String.fromCharCode(Number.parseInt(octal[0], 8));
|
|
18154
|
+
index += octal[0].length - 1;
|
|
18155
|
+
} else
|
|
18156
|
+
text += C_ESCAPES[rest[0]] ?? rest[0];
|
|
18157
|
+
}
|
|
18158
|
+
return { text, end: index };
|
|
18159
|
+
}, substitutions = (body) => {
|
|
18160
|
+
const found = [];
|
|
18161
|
+
for (let index = 0;index < body.length; index++) {
|
|
18162
|
+
const char = body[index];
|
|
18163
|
+
if (char === "\\")
|
|
18164
|
+
index++;
|
|
18165
|
+
else if (char === "`") {
|
|
18166
|
+
const end = backtickEnd(body, index);
|
|
18167
|
+
found.push(body.slice(index + 1, end).replace(/\\(.)/g, "$1"));
|
|
18168
|
+
index = end;
|
|
18169
|
+
} else if (char === "$" && body[index + 1] === "(") {
|
|
18170
|
+
const end = substitutionEnd(body, index + 1);
|
|
18171
|
+
found.push(body.slice(index + 2, end));
|
|
18172
|
+
index = end;
|
|
18173
|
+
}
|
|
18174
|
+
}
|
|
18175
|
+
return found;
|
|
18176
|
+
}, PLAIN_POSIX, PLAIN_POWERSHELL, arithmeticEnd = (command, start) => {
|
|
18177
|
+
const end = substitutionEnd(command, start);
|
|
18178
|
+
return command[end - 1] === ")" && end > start + 2 ? end : 0;
|
|
17988
18179
|
}, segmentsOf = (command, dialect = "posix") => {
|
|
18180
|
+
try {
|
|
18181
|
+
return tokenize(command, dialect);
|
|
18182
|
+
} catch (error) {
|
|
18183
|
+
const why = error instanceof ShellAnalysisError ? error.message : String(error);
|
|
18184
|
+
return [{ words: [], redirects: [], unanalyzable: why }];
|
|
18185
|
+
}
|
|
18186
|
+
}, tokenize = (command, dialect) => {
|
|
18187
|
+
const posix = dialect === "posix";
|
|
17989
18188
|
const segments = [];
|
|
17990
18189
|
let current = { words: [], redirects: [] };
|
|
17991
18190
|
let word = "";
|
|
17992
18191
|
let inWord = false;
|
|
17993
18192
|
let pending = null;
|
|
17994
18193
|
const heredocs = [];
|
|
17995
|
-
const escape =
|
|
18194
|
+
const escape = posix ? "\\" : "`";
|
|
17996
18195
|
const flushWord = () => {
|
|
17997
18196
|
if (!inWord)
|
|
17998
18197
|
return;
|
|
18198
|
+
const text = MARKERS.test(word) ? literal2(word) : word;
|
|
17999
18199
|
if (pending === "redirect") {
|
|
18000
|
-
if (!
|
|
18001
|
-
current.redirects.push(
|
|
18200
|
+
if (!text.startsWith("&"))
|
|
18201
|
+
current.redirects.push(text);
|
|
18002
18202
|
} else if (pending === "heredoc")
|
|
18003
|
-
heredocs.push(
|
|
18203
|
+
heredocs.push({ delimiter: text.replace(/^-/, ""), owner: current });
|
|
18204
|
+
else if (pending === "herestring")
|
|
18205
|
+
(current.stdin ??= []).push(text);
|
|
18004
18206
|
else if (pending !== "input")
|
|
18005
|
-
current.words.push(word);
|
|
18207
|
+
current.words.push(...MARKERS.test(word) ? expandBraces(word) : [word]);
|
|
18006
18208
|
pending = null;
|
|
18007
18209
|
word = "";
|
|
18008
18210
|
inWord = false;
|
|
18009
18211
|
};
|
|
18010
18212
|
const flushSegment = () => {
|
|
18011
18213
|
flushWord();
|
|
18012
|
-
if (current.words.length || current.redirects.length)
|
|
18214
|
+
if (current.words.length || current.redirects.length || current.stdin || current.subs)
|
|
18013
18215
|
segments.push(current);
|
|
18014
18216
|
current = { words: [], redirects: [] };
|
|
18015
18217
|
};
|
|
18218
|
+
const group = (kind) => {
|
|
18219
|
+
flushSegment();
|
|
18220
|
+
pending = null;
|
|
18221
|
+
segments.push({ words: [], redirects: [], group: kind });
|
|
18222
|
+
};
|
|
18223
|
+
const substitution = (inner, text) => {
|
|
18224
|
+
(current.subs ??= []).push(inner);
|
|
18225
|
+
word += text;
|
|
18226
|
+
inWord = true;
|
|
18227
|
+
};
|
|
18228
|
+
const plain = posix ? PLAIN_POSIX : PLAIN_POWERSHELL;
|
|
18016
18229
|
for (let index = 0;index < command.length; index++) {
|
|
18230
|
+
plain.lastIndex = index;
|
|
18231
|
+
const run = plain.exec(command);
|
|
18232
|
+
if (run) {
|
|
18233
|
+
word += run[0];
|
|
18234
|
+
inWord = true;
|
|
18235
|
+
index += run[0].length - 1;
|
|
18236
|
+
continue;
|
|
18237
|
+
}
|
|
18017
18238
|
const char = command[index];
|
|
18018
|
-
|
|
18239
|
+
const next = command[index + 1];
|
|
18240
|
+
if (char === escape && (next === `
|
|
18241
|
+
` || next === "\r" && command[index + 2] === `
|
|
18242
|
+
`))
|
|
18243
|
+
index += next === "\r" ? 2 : 1;
|
|
18244
|
+
else if (char === "#" && !inWord) {
|
|
18245
|
+
const newline = command.indexOf(`
|
|
18246
|
+
`, index);
|
|
18247
|
+
index = (newline < 0 ? command.length : newline) - 1;
|
|
18248
|
+
} else if (!posix && char === "<" && next === "#") {
|
|
18249
|
+
const end = command.indexOf("#>", index + 2);
|
|
18250
|
+
index = end < 0 ? command.length : end + 1;
|
|
18251
|
+
} else if (posix && char === "$" && next === "'") {
|
|
18252
|
+
const { text, end } = ansiC(command, index + 1);
|
|
18253
|
+
word += text;
|
|
18254
|
+
inWord = true;
|
|
18255
|
+
index = end;
|
|
18256
|
+
} else if (posix && char === "$" && next === '"')
|
|
18257
|
+
continue;
|
|
18258
|
+
else if (char === "'" || char === '"') {
|
|
18019
18259
|
const end = closingQuote(command, index, dialect);
|
|
18020
|
-
|
|
18260
|
+
const body = command.slice(index + 1, end < 0 ? undefined : end);
|
|
18261
|
+
if (posix && char === '"' && /\$\(|`/.test(body))
|
|
18262
|
+
(current.subs ??= []).push(...substitutions(body));
|
|
18263
|
+
word += unquote(body, char, dialect);
|
|
18021
18264
|
inWord = true;
|
|
18022
18265
|
index = end < 0 ? command.length : end;
|
|
18266
|
+
} else if (posix && char === "`") {
|
|
18267
|
+
const end = backtickEnd(command, index);
|
|
18268
|
+
const inner = command.slice(index + 1, end);
|
|
18269
|
+
substitution(inner.replace(/\\(.)/g, "$1"), `\`${inner}\``);
|
|
18270
|
+
index = end;
|
|
18023
18271
|
} else if (char === escape && index + 1 < command.length) {
|
|
18024
18272
|
word += command[++index];
|
|
18025
18273
|
inWord = true;
|
|
@@ -18027,26 +18275,56 @@ var closingQuote = (command, start, dialect) => {
|
|
|
18027
18275
|
`) {
|
|
18028
18276
|
flushSegment();
|
|
18029
18277
|
while (heredocs.length) {
|
|
18030
|
-
const delimiter = heredocs.shift();
|
|
18278
|
+
const { delimiter, owner } = heredocs.shift();
|
|
18031
18279
|
const lines = command.slice(index + 1).split(`
|
|
18032
18280
|
`);
|
|
18033
18281
|
const at = lines.findIndex((line) => line.trim() === delimiter);
|
|
18034
|
-
|
|
18282
|
+
(owner.stdin ??= []).push((at < 0 ? lines : lines.slice(0, at)).join(`
|
|
18283
|
+
`));
|
|
18284
|
+
index += (at < 0 ? lines : lines.slice(0, at + 1)).join(`
|
|
18035
18285
|
`).length + 1;
|
|
18036
|
-
index += skipped;
|
|
18037
18286
|
}
|
|
18038
18287
|
} else if (/\s/.test(char))
|
|
18039
18288
|
flushWord();
|
|
18040
|
-
else if (char === "("
|
|
18289
|
+
else if (posix && char === "(" && inWord && word.endsWith("$")) {
|
|
18290
|
+
const end = substitutionEnd(command, index);
|
|
18291
|
+
const inner = command.slice(index + 1, end);
|
|
18292
|
+
substitution(inner, `(${inner})`);
|
|
18293
|
+
index = end;
|
|
18294
|
+
} else if (posix && char === "(" && (pending === "input" || pending === "redirect")) {
|
|
18295
|
+
const sign = pending === "input" ? "<" : ">";
|
|
18296
|
+
pending = null;
|
|
18297
|
+
const end = substitutionEnd(command, index);
|
|
18298
|
+
const inner = command.slice(index + 1, end);
|
|
18299
|
+
substitution(inner, `${sign}(${inner})`);
|
|
18300
|
+
index = end;
|
|
18301
|
+
} else if (posix && char === "(" && next === "(" && !inWord && arithmeticEnd(command, index)) {
|
|
18302
|
+
flushSegment();
|
|
18303
|
+
index = arithmeticEnd(command, index);
|
|
18304
|
+
} else if (char === "(" || char === ")") {
|
|
18041
18305
|
if (char === "(" && inWord && word.endsWith("$")) {
|
|
18042
18306
|
word = word.slice(0, -1);
|
|
18043
18307
|
inWord = word !== "";
|
|
18044
18308
|
}
|
|
18309
|
+
group(char === "(" ? "open" : "close");
|
|
18310
|
+
} else if (!posix && (char === "{" || char === "}")) {
|
|
18311
|
+
if (char === "{" && inWord && word.endsWith("@")) {
|
|
18312
|
+
word += char;
|
|
18313
|
+
continue;
|
|
18314
|
+
}
|
|
18045
18315
|
flushSegment();
|
|
18046
|
-
segments.push({ words: [], redirects: [], group: char === "(" ? "open" : "close" });
|
|
18047
18316
|
} else if (";&|".includes(char)) {
|
|
18048
|
-
if (char === "&" &&
|
|
18317
|
+
if (char === "&" && next === ">")
|
|
18049
18318
|
continue;
|
|
18319
|
+
if (char === "|" && next === "|")
|
|
18320
|
+
index++;
|
|
18321
|
+
else if (char === "|") {
|
|
18322
|
+
flushWord();
|
|
18323
|
+
if (current.words.length)
|
|
18324
|
+
current.pipe = true;
|
|
18325
|
+
if (next === "&")
|
|
18326
|
+
index++;
|
|
18327
|
+
}
|
|
18050
18328
|
flushSegment();
|
|
18051
18329
|
} else if (char === ">") {
|
|
18052
18330
|
if (inWord && /^\d$/.test(word)) {
|
|
@@ -18062,16 +18340,24 @@ var closingQuote = (command, start, dialect) => {
|
|
|
18062
18340
|
inWord = true;
|
|
18063
18341
|
}
|
|
18064
18342
|
pending = "redirect";
|
|
18065
|
-
} else if (char === "<" &&
|
|
18343
|
+
} else if (char === "<" && posix) {
|
|
18066
18344
|
flushWord();
|
|
18067
|
-
if (command[index +
|
|
18345
|
+
if (next === "<" && command[index + 2] === "<") {
|
|
18346
|
+
index += 2;
|
|
18347
|
+
pending = "herestring";
|
|
18348
|
+
} else if (next === "<") {
|
|
18068
18349
|
index++;
|
|
18069
|
-
if (command[index + 1] === "<")
|
|
18070
|
-
index++;
|
|
18071
18350
|
pending = "heredoc";
|
|
18072
18351
|
} else
|
|
18073
18352
|
pending = "input";
|
|
18074
|
-
} else {
|
|
18353
|
+
} else if (posix && char === "{" && !word.endsWith("$")) {
|
|
18354
|
+
word += OPEN;
|
|
18355
|
+
inWord = true;
|
|
18356
|
+
} else if (posix && char === "," && word.includes(OPEN))
|
|
18357
|
+
word += COMMA;
|
|
18358
|
+
else if (posix && char === "}" && word.includes(OPEN))
|
|
18359
|
+
word += CLOSE;
|
|
18360
|
+
else {
|
|
18075
18361
|
word += char;
|
|
18076
18362
|
inWord = true;
|
|
18077
18363
|
}
|
|
@@ -18079,6 +18365,25 @@ var closingQuote = (command, start, dialect) => {
|
|
|
18079
18365
|
flushSegment();
|
|
18080
18366
|
return segments;
|
|
18081
18367
|
};
|
|
18368
|
+
var init_shell_words = __esm(() => {
|
|
18369
|
+
ShellAnalysisError = class ShellAnalysisError extends Error {
|
|
18370
|
+
};
|
|
18371
|
+
MARKERS = /[\uE000-\uE002]/u;
|
|
18372
|
+
C_ESCAPES = {
|
|
18373
|
+
n: `
|
|
18374
|
+
`,
|
|
18375
|
+
t: "\t",
|
|
18376
|
+
r: "\r",
|
|
18377
|
+
a: "\x07",
|
|
18378
|
+
b: "\b",
|
|
18379
|
+
e: "\x1B",
|
|
18380
|
+
E: "\x1B",
|
|
18381
|
+
f: "\f",
|
|
18382
|
+
v: "\v"
|
|
18383
|
+
};
|
|
18384
|
+
PLAIN_POSIX = /[^\s'"\\`$(){},<>|;&#]+/uy;
|
|
18385
|
+
PLAIN_POWERSHELL = /[^\s'"`(){}<>|;&#]+/uy;
|
|
18386
|
+
});
|
|
18082
18387
|
|
|
18083
18388
|
// packages/workit-core/src/hooks/raw-git.ts
|
|
18084
18389
|
import { spawnSync as spawnSync11 } from "node:child_process";
|
|
@@ -18087,67 +18392,124 @@ import fs16 from "node:fs";
|
|
|
18087
18392
|
import os5 from "node:os";
|
|
18088
18393
|
import path20 from "node:path";
|
|
18089
18394
|
function rawInvocations(command, dialect = "posix", depth = 0) {
|
|
18395
|
+
if (depth > 0)
|
|
18396
|
+
return walk2(command, dialect, depth);
|
|
18397
|
+
const key = `${dialect}\x00${command}`;
|
|
18398
|
+
const cached = RECENT.get(key);
|
|
18399
|
+
if (cached)
|
|
18400
|
+
return cached;
|
|
18401
|
+
let found;
|
|
18402
|
+
try {
|
|
18403
|
+
found = walk2(command, dialect, depth);
|
|
18404
|
+
} catch (error) {
|
|
18405
|
+
throw error instanceof ShellAnalysisError ? error : new ShellAnalysisError(error instanceof Error ? error.message : String(error));
|
|
18406
|
+
}
|
|
18407
|
+
RECENT.set(key, found);
|
|
18408
|
+
if (RECENT.size > 8)
|
|
18409
|
+
RECENT.delete(RECENT.keys().next().value);
|
|
18410
|
+
return found;
|
|
18411
|
+
}
|
|
18412
|
+
function walk2(command, dialect, depth) {
|
|
18090
18413
|
const found = [];
|
|
18091
18414
|
let dir = null;
|
|
18092
18415
|
const groups = [];
|
|
18093
18416
|
let stack = [];
|
|
18094
|
-
|
|
18095
|
-
|
|
18096
|
-
|
|
18097
|
-
|
|
18098
|
-
|
|
18099
|
-
|
|
18100
|
-
|
|
18101
|
-
|
|
18102
|
-
|
|
18103
|
-
|
|
18104
|
-
|
|
18105
|
-
const
|
|
18417
|
+
const vars = new Map;
|
|
18418
|
+
const exported = {};
|
|
18419
|
+
const sessionConfig = [];
|
|
18420
|
+
const nested = (script, inner) => {
|
|
18421
|
+
if (!script || depth >= MAX_DEPTH)
|
|
18422
|
+
return;
|
|
18423
|
+
for (const invocation of rawInvocations(script, inner, depth + 1))
|
|
18424
|
+
found.push({ ...invocation, dir: rebase(dir, invocation.dir) });
|
|
18425
|
+
};
|
|
18426
|
+
const visit = (input, stdin, hops) => {
|
|
18427
|
+
const line = /^\$[\w:]+$/.test(input[0] ?? "") && input[1] === "=" ? input.slice(2) : input;
|
|
18428
|
+
const split = splitString(line);
|
|
18429
|
+
if (split !== null)
|
|
18430
|
+
return nested(split, "posix");
|
|
18431
|
+
const { words, env } = stripPrefixes(line);
|
|
18106
18432
|
const name = commandName(words[0]);
|
|
18433
|
+
if (!name)
|
|
18434
|
+
return;
|
|
18435
|
+
const runs = (lines) => {
|
|
18436
|
+
if (hops < MAX_DEPTH)
|
|
18437
|
+
for (const next of lines)
|
|
18438
|
+
visit(next, undefined, hops + 1);
|
|
18439
|
+
};
|
|
18107
18440
|
if (CD.has(name)) {
|
|
18108
18441
|
const target = cdTarget(words);
|
|
18109
18442
|
dir = target === null ? os5.homedir() : joinDir(dir, target);
|
|
18110
|
-
|
|
18111
|
-
}
|
|
18112
|
-
if (PUSHD.has(name)) {
|
|
18443
|
+
} else if (PUSHD.has(name)) {
|
|
18113
18444
|
const target = cdTarget(words);
|
|
18114
18445
|
stack.push(dir);
|
|
18115
18446
|
dir = target === null || target === "-" ? undefined : joinDir(dir, target);
|
|
18116
|
-
|
|
18117
|
-
}
|
|
18118
|
-
if (POPD.has(name)) {
|
|
18447
|
+
} else if (POPD.has(name))
|
|
18119
18448
|
dir = stack.length ? stack.pop() : undefined;
|
|
18120
|
-
|
|
18449
|
+
else if (EVALS.has(name)) {
|
|
18450
|
+
const args = /^-c(?:o(?:m(?:m(?:a(?:n(?:d)?)?)?)?)?)?$/i.test(words[1] ?? "") ? words.slice(2) : words.slice(1);
|
|
18451
|
+
nested(args.join(" "), dialect);
|
|
18452
|
+
} else if (SHELLS.has(name))
|
|
18453
|
+
nested(shellScript(words, stdin), "posix");
|
|
18454
|
+
else if ((name === "source" || name === ".") && dialect === "posix")
|
|
18455
|
+
nested(processSubstitutionText(words[1]), "posix");
|
|
18456
|
+
else if (name === "trap" && dialect === "posix" && !/^-[lp]$/.test(words[1] ?? ""))
|
|
18457
|
+
nested(words[1], "posix");
|
|
18458
|
+
else if (name === "script")
|
|
18459
|
+
nested(scriptCommand(words), "posix");
|
|
18460
|
+
else if (name === "parallel")
|
|
18461
|
+
runs(parallelCommands(words));
|
|
18462
|
+
else if (dialect === "powershell" && /^(?:start-process|saps|start)$/.test(name)) {
|
|
18463
|
+
const started = startProcessCommand(words);
|
|
18464
|
+
if (started)
|
|
18465
|
+
runs([started]);
|
|
18466
|
+
} else if (POWERSHELLS.has(name))
|
|
18467
|
+
nested(powershellScript(words, stdin), "powershell");
|
|
18468
|
+
else if (name === "cmd")
|
|
18469
|
+
nested(cmdScript(words), "powershell");
|
|
18470
|
+
else if (name === "xargs" || name === "find")
|
|
18471
|
+
runs(name === "xargs" ? xargsCommands(words, stdin) : findCommands(words));
|
|
18472
|
+
else if (name === "gh" || name === "glab")
|
|
18473
|
+
found.push({
|
|
18474
|
+
tool: name,
|
|
18475
|
+
dir,
|
|
18476
|
+
args: words.slice(1),
|
|
18477
|
+
...stdin === undefined ? {} : { stdin }
|
|
18478
|
+
});
|
|
18479
|
+
else if (name === "git") {
|
|
18480
|
+
const invocation = gitInvocation(words.slice(1), dir, { ...exported, ...env }, stdin, sessionConfig);
|
|
18481
|
+
found.push(invocation);
|
|
18482
|
+
sessionConfig.push(...configSetBy(invocation.args));
|
|
18121
18483
|
}
|
|
18122
|
-
|
|
18123
|
-
|
|
18124
|
-
|
|
18125
|
-
|
|
18126
|
-
|
|
18127
|
-
found.push({
|
|
18128
|
-
...inner,
|
|
18129
|
-
dir: inner.dir === null ? dir : inner.dir === undefined ? undefined : joinDir(dir, inner.dir)
|
|
18130
|
-
});
|
|
18484
|
+
};
|
|
18485
|
+
const segments = segmentsOf(command, dialect);
|
|
18486
|
+
for (const [index, segment] of segments.entries()) {
|
|
18487
|
+
if (segment.group === "open") {
|
|
18488
|
+
groups.push({ dir, stack: [...stack] });
|
|
18131
18489
|
continue;
|
|
18132
18490
|
}
|
|
18133
|
-
if (
|
|
18134
|
-
|
|
18491
|
+
if (segment.group === "close") {
|
|
18492
|
+
const saved = groups.pop();
|
|
18493
|
+
if (saved)
|
|
18494
|
+
({ dir, stack } = saved);
|
|
18135
18495
|
continue;
|
|
18136
18496
|
}
|
|
18137
|
-
if (
|
|
18497
|
+
if (segment.unanalyzable)
|
|
18498
|
+
throw new ShellAnalysisError(segment.unanalyzable);
|
|
18499
|
+
for (const sub of segment.subs ?? [])
|
|
18500
|
+
nested(sub, "posix");
|
|
18501
|
+
const set = assignments(segment.words, vars);
|
|
18502
|
+
if (set) {
|
|
18503
|
+
for (const [name, values] of set) {
|
|
18504
|
+
vars.set(name, values);
|
|
18505
|
+
if (segment.words[0] === "export" && GIT_CONFIG_ENV.test(name) && values[0] !== undefined)
|
|
18506
|
+
exported[name] = values[0];
|
|
18507
|
+
}
|
|
18138
18508
|
continue;
|
|
18139
|
-
let here = dir;
|
|
18140
|
-
let index = 1;
|
|
18141
|
-
for (;index < words.length; index++) {
|
|
18142
|
-
const word = words[index];
|
|
18143
|
-
if (word === "-C")
|
|
18144
|
-
here = words[index + 1] ? joinDir(here, words[++index]) : here;
|
|
18145
|
-
else if (GIT_VALUE_OPTIONS.has(word))
|
|
18146
|
-
index++;
|
|
18147
|
-
else if (!word.startsWith("-"))
|
|
18148
|
-
break;
|
|
18149
18509
|
}
|
|
18150
|
-
|
|
18510
|
+
const stdin = stdinOf(segment, segments[index - 1]);
|
|
18511
|
+
for (const line of substitute(segment.words, vars))
|
|
18512
|
+
visit(line, stdin, 0);
|
|
18151
18513
|
}
|
|
18152
18514
|
return found;
|
|
18153
18515
|
}
|
|
@@ -18170,20 +18532,40 @@ function workitInvocations(command, dialect = "posix", depth = 0) {
|
|
|
18170
18532
|
}
|
|
18171
18533
|
function rawAction(invocation) {
|
|
18172
18534
|
const args = invocation.args;
|
|
18535
|
+
if (invocation.tool !== "git" && args[0] === "api")
|
|
18536
|
+
return apiMerges(invocation.tool, args, invocation.stdin) ? { kind: "merge", forge: invocation.tool, via: "api" } : null;
|
|
18173
18537
|
if (asksHelp(invocation))
|
|
18174
18538
|
return null;
|
|
18175
|
-
const [first
|
|
18539
|
+
const [first] = args;
|
|
18176
18540
|
if (invocation.tool === "git") {
|
|
18541
|
+
const second = args[1];
|
|
18177
18542
|
if (first === "commit")
|
|
18178
18543
|
return args.includes("--dry-run") ? null : { kind: "commit", amend: args.includes("--amend") };
|
|
18179
18544
|
if (first === "push")
|
|
18180
18545
|
return pushAction(args);
|
|
18546
|
+
if (first === "send-pack")
|
|
18547
|
+
return pushAction([
|
|
18548
|
+
"push",
|
|
18549
|
+
...args.slice(1).filter((arg) => arg !== "--stdin"),
|
|
18550
|
+
...args.includes("--stdin") ? (invocation.stdin ?? "").split(/\s+/).filter(Boolean) : []
|
|
18551
|
+
]);
|
|
18552
|
+
if (first === "subtree" && second === "push")
|
|
18553
|
+
return subtreePush(args);
|
|
18181
18554
|
return null;
|
|
18182
18555
|
}
|
|
18183
18556
|
const forge = invocation.tool;
|
|
18184
18557
|
const noun = forge === "gh" ? "pr" : "mr";
|
|
18185
18558
|
if (first !== noun)
|
|
18186
18559
|
return null;
|
|
18560
|
+
const values = VALUE_OPTIONS[forge];
|
|
18561
|
+
let second;
|
|
18562
|
+
for (let index = 1;index < args.length && second === undefined; index++) {
|
|
18563
|
+
const arg = args[index];
|
|
18564
|
+
if (values.has(arg))
|
|
18565
|
+
index++;
|
|
18566
|
+
else if (!arg.startsWith("-"))
|
|
18567
|
+
second = arg;
|
|
18568
|
+
}
|
|
18187
18569
|
if (second === "merge")
|
|
18188
18570
|
return { kind: "merge", forge };
|
|
18189
18571
|
if (second === "create")
|
|
@@ -18194,31 +18576,18 @@ function rawAction(invocation) {
|
|
|
18194
18576
|
}
|
|
18195
18577
|
function rawGitPre(input, command, options = {}) {
|
|
18196
18578
|
try {
|
|
18197
|
-
if (!mentionsRawTool(command))
|
|
18198
|
-
return NONE2;
|
|
18199
18579
|
const dialect = dialectOf(input);
|
|
18200
18580
|
const nudges = new Map;
|
|
18201
18581
|
let store = null;
|
|
18202
|
-
|
|
18582
|
+
const cache = new Map;
|
|
18583
|
+
for (const { action, repo, invocation } of actionsIn(input.cwd, command, dialect, cache)) {
|
|
18203
18584
|
store ??= repo.location.dir;
|
|
18204
18585
|
if (action.kind === "merge")
|
|
18205
18586
|
return deny(refusal(action, null));
|
|
18206
|
-
if (action.kind === "push"
|
|
18207
|
-
|
|
18208
|
-
|
|
18209
|
-
|
|
18210
|
-
const branch = target ?? repo.branch;
|
|
18211
|
-
if (branch && guardedBranch(repo.dir, branch))
|
|
18212
|
-
return deny(refusal(action, branch, repo.dir));
|
|
18213
|
-
}
|
|
18214
|
-
const remote = action.remote ?? pushRemoteName(repo.dir, repo.branch) ?? "origin";
|
|
18215
|
-
const facts = refFacts(repo, remote);
|
|
18216
|
-
const tagDeny = tagRefusal(action, facts);
|
|
18217
|
-
if (tagDeny)
|
|
18218
|
-
return deny(tagDeny);
|
|
18219
|
-
const nameDeny = action.deletes ? null : offPolicyPush(action, repo, facts, remote);
|
|
18220
|
-
if (nameDeny)
|
|
18221
|
-
return deny(nameDeny);
|
|
18587
|
+
if (action.kind === "push") {
|
|
18588
|
+
const refused = pushRefusal(action, repo, gitConfig(repo.dir, invocation, cache));
|
|
18589
|
+
if (refused)
|
|
18590
|
+
return deny(refused);
|
|
18222
18591
|
}
|
|
18223
18592
|
const nudge = nudgeFor(action, input.host, input.session.id);
|
|
18224
18593
|
if (nudge && !nudges.has(nudgeKind(action)))
|
|
@@ -18231,8 +18600,8 @@ function rawGitPre(input, command, options = {}) {
|
|
|
18231
18600
|
const shown = unseenNudges(input, nudges, store);
|
|
18232
18601
|
return shown.length ? { kind: "context", text: shown.join(`
|
|
18233
18602
|
`) } : NONE2;
|
|
18234
|
-
} catch {
|
|
18235
|
-
return NONE2;
|
|
18603
|
+
} catch (error) {
|
|
18604
|
+
return error instanceof ShellAnalysisError ? analysisDenial(error) : NONE2;
|
|
18236
18605
|
}
|
|
18237
18606
|
}
|
|
18238
18607
|
function noteRawCommit(input, command, key) {
|
|
@@ -18271,12 +18640,13 @@ function settlePendingCommit(input) {
|
|
|
18271
18640
|
settle2(input, repo, file);
|
|
18272
18641
|
} catch {}
|
|
18273
18642
|
}
|
|
18274
|
-
var NONE2, SHELLS,
|
|
18643
|
+
var NONE2, SHELLS, POWERSHELLS, EVALS, WRAPPERS, WRAPPER_VALUES, KEYWORDS, DECLARATIONS, SCRIPT_FLAG, CD, PUSHD, POPD, GIT_VALUE_OPTIONS, GIT_CONFIG_OPTIONS, GIT_CONFIG_ENV, ASSIGNMENT, MAX_DEPTH = 4, MAX_EXPANSIONS = 16, isAbsolute = (value) => path20.isAbsolute(value) || /^[A-Za-z]:[\\/]/.test(value) || value.startsWith("\\\\"), HERE, joinDir = (base, raw) => {
|
|
18644
|
+
const next = raw.replace(HERE, ".");
|
|
18275
18645
|
if (base === undefined || /[$`*?]/.test(next) || next === "-")
|
|
18276
18646
|
return;
|
|
18277
18647
|
const expanded = next === "~" || next.startsWith("~/") ? path20.join(os5.homedir(), next.slice(1)) : next;
|
|
18278
18648
|
return base === null || isAbsolute(expanded) ? expanded : path20.join(base, expanded);
|
|
18279
|
-
}, cdTarget = (words) => {
|
|
18649
|
+
}, rebase = (base, inner) => inner === null ? base : inner === undefined ? undefined : joinDir(base, inner), cdTarget = (words) => {
|
|
18280
18650
|
const args = words.slice(1);
|
|
18281
18651
|
const flag = args.findIndex((word) => /^-(?:literal)?path$/i.test(word));
|
|
18282
18652
|
if (flag >= 0)
|
|
@@ -18284,25 +18654,328 @@ var NONE2, SHELLS, PREFIXES2, SCRIPT_FLAG, CD, PUSHD, POPD, GIT_VALUE_OPTIONS, i
|
|
|
18284
18654
|
return args.find((word) => word === "-" || !word.startsWith("-")) ?? null;
|
|
18285
18655
|
}, stripPrefixes = (input) => {
|
|
18286
18656
|
let words = input;
|
|
18657
|
+
const env = {};
|
|
18287
18658
|
for (;; ) {
|
|
18288
18659
|
const first = words[0];
|
|
18289
18660
|
if (first === undefined)
|
|
18290
|
-
return words;
|
|
18291
|
-
|
|
18661
|
+
return { words, env };
|
|
18662
|
+
const assignment = ASSIGNMENT.exec(first);
|
|
18663
|
+
if (assignment) {
|
|
18664
|
+
if (GIT_CONFIG_ENV.test(assignment[1]))
|
|
18665
|
+
env[assignment[1]] = assignment[2];
|
|
18292
18666
|
words = words.slice(1);
|
|
18293
|
-
else if (
|
|
18667
|
+
} else if (KEYWORDS.has(first))
|
|
18294
18668
|
words = words.slice(1);
|
|
18295
|
-
|
|
18296
|
-
|
|
18297
|
-
|
|
18669
|
+
else if (first === "function")
|
|
18670
|
+
words = words.slice(2);
|
|
18671
|
+
else if (Object.hasOwn(WRAPPERS, commandName(first))) {
|
|
18672
|
+
const name = commandName(first);
|
|
18673
|
+
const values = WRAPPER_VALUES.get(name);
|
|
18298
18674
|
words = words.slice(1);
|
|
18299
|
-
|
|
18675
|
+
const takesValue = (option) => values.has(option) || /^-[a-zA-Z]{2,}$/.test(option) && values.has(`-${option.at(-1)}`);
|
|
18676
|
+
while (words[0]?.startsWith("-") && words[0] !== "--")
|
|
18677
|
+
words = words.slice(takesValue(words[0]) ? 2 : 1);
|
|
18678
|
+
if (words[0] === "--")
|
|
18300
18679
|
words = words.slice(1);
|
|
18301
|
-
words = words.slice(
|
|
18680
|
+
words = words.slice(WRAPPERS[name].operands ?? 0);
|
|
18302
18681
|
} else
|
|
18303
|
-
return words;
|
|
18682
|
+
return { words, env };
|
|
18683
|
+
}
|
|
18684
|
+
}, commandName = (word) => (word?.split(/[\\/]/).at(-1) ?? "").toLowerCase().replace(/\.exe$/, ""), VARIABLE, expandWord = (word, vars) => {
|
|
18685
|
+
if (!word.includes("$"))
|
|
18686
|
+
return [word];
|
|
18687
|
+
let results = [""];
|
|
18688
|
+
let last = 0;
|
|
18689
|
+
for (const match of word.matchAll(VARIABLE)) {
|
|
18690
|
+
const values = vars.get(match[1] ?? match[2]) ?? [match[0]];
|
|
18691
|
+
const before = word.slice(last, match.index);
|
|
18692
|
+
results = results.flatMap((result) => values.map((value) => result + before + value)).slice(0, MAX_EXPANSIONS);
|
|
18693
|
+
last = match.index + match[0].length;
|
|
18694
|
+
}
|
|
18695
|
+
return results.map((result) => result + word.slice(last));
|
|
18696
|
+
}, substitute = (words, vars) => {
|
|
18697
|
+
if (vars.size === 0)
|
|
18698
|
+
return [words];
|
|
18699
|
+
let lines = [[]];
|
|
18700
|
+
for (const word of words) {
|
|
18701
|
+
const values = expandWord(word, vars);
|
|
18702
|
+
lines = lines.flatMap((line) => values.map((value) => [...line, value])).slice(0, MAX_EXPANSIONS);
|
|
18703
|
+
}
|
|
18704
|
+
return lines;
|
|
18705
|
+
}, assignments = (words, vars) => {
|
|
18706
|
+
if (words[0] === "for" && words[2] === "in" && /^\w+$/.test(words[1] ?? "")) {
|
|
18707
|
+
const values = words.slice(3).flatMap((word) => expandWord(word, vars));
|
|
18708
|
+
return [[words[1], values.slice(0, MAX_EXPANSIONS)]];
|
|
18709
|
+
}
|
|
18710
|
+
let rest = words;
|
|
18711
|
+
if (DECLARATIONS.has(rest[0] ?? "")) {
|
|
18712
|
+
rest = rest.slice(1);
|
|
18713
|
+
while (rest[0]?.startsWith("-"))
|
|
18714
|
+
rest = rest.slice(1);
|
|
18715
|
+
}
|
|
18716
|
+
if (rest.length === 0 || !rest.every((word) => ASSIGNMENT.test(word)))
|
|
18717
|
+
return null;
|
|
18718
|
+
return rest.map((word) => {
|
|
18719
|
+
const [, name, value] = ASSIGNMENT.exec(word);
|
|
18720
|
+
return [name, expandWord(value, vars)];
|
|
18721
|
+
});
|
|
18722
|
+
}, literalOutput = (segment) => {
|
|
18723
|
+
if (!segment?.pipe)
|
|
18724
|
+
return;
|
|
18725
|
+
const { words } = stripPrefixes(segment.words);
|
|
18726
|
+
const name = commandName(words[0]);
|
|
18727
|
+
if (name === "echo") {
|
|
18728
|
+
let args = words.slice(1);
|
|
18729
|
+
while (/^-[neE]+$/.test(args[0] ?? ""))
|
|
18730
|
+
args = args.slice(1);
|
|
18731
|
+
return args.join(" ");
|
|
18732
|
+
}
|
|
18733
|
+
if (name === "printf") {
|
|
18734
|
+
const [format = "", ...args] = words.slice(1);
|
|
18735
|
+
return (args.length ? args.join(`
|
|
18736
|
+
`) : format).replace(/\\n/g, `
|
|
18737
|
+
`);
|
|
18738
|
+
}
|
|
18739
|
+
if (name === "cat" && words.length === 1 && segment.stdin)
|
|
18740
|
+
return segment.stdin.join(`
|
|
18741
|
+
`);
|
|
18742
|
+
return;
|
|
18743
|
+
}, stdinOf = (segment, previous) => segment.stdin ? segment.stdin.join(`
|
|
18744
|
+
`) : literalOutput(previous), XARGS_VALUES, xargsCommands = (words, input) => {
|
|
18745
|
+
let replace = null;
|
|
18746
|
+
let index = 1;
|
|
18747
|
+
for (;index < words.length; index++) {
|
|
18748
|
+
const word = words[index];
|
|
18749
|
+
if (word === "--") {
|
|
18750
|
+
index++;
|
|
18751
|
+
break;
|
|
18752
|
+
}
|
|
18753
|
+
if (!word.startsWith("-"))
|
|
18754
|
+
break;
|
|
18755
|
+
if (word === "-I")
|
|
18756
|
+
replace = words[++index] ?? "{}";
|
|
18757
|
+
else if (word === "--replace" || word === "-i")
|
|
18758
|
+
replace = "{}";
|
|
18759
|
+
else if (word.startsWith("--replace="))
|
|
18760
|
+
replace = word.slice("--replace=".length);
|
|
18761
|
+
else if (/^-[Ii]./.test(word))
|
|
18762
|
+
replace = word.slice(2);
|
|
18763
|
+
else if (XARGS_VALUES.has(word))
|
|
18764
|
+
index++;
|
|
18765
|
+
}
|
|
18766
|
+
const command = words.slice(index);
|
|
18767
|
+
if (command.length === 0)
|
|
18768
|
+
return [];
|
|
18769
|
+
if (input === undefined)
|
|
18770
|
+
return [command];
|
|
18771
|
+
if (replace === null)
|
|
18772
|
+
return [[...command, ...input.split(/\s+/).filter(Boolean)]];
|
|
18773
|
+
const token = replace;
|
|
18774
|
+
return input.split(`
|
|
18775
|
+
`).map((line) => line.trim()).filter(Boolean).slice(0, MAX_EXPANSIONS).map((line) => command.map((word) => word.replaceAll(token, line)));
|
|
18776
|
+
}, findCommands = (words) => {
|
|
18777
|
+
const found = [];
|
|
18778
|
+
for (let index = 1;index < words.length; index++) {
|
|
18779
|
+
if (!/^-(?:exec|execdir|ok|okdir)$/.test(words[index]))
|
|
18780
|
+
continue;
|
|
18781
|
+
const end = words.findIndex((word, at) => at > index && (word === ";" || word === "+"));
|
|
18782
|
+
found.push(words.slice(index + 1, end < 0 ? undefined : end));
|
|
18783
|
+
if (end < 0)
|
|
18784
|
+
break;
|
|
18785
|
+
index = end;
|
|
18786
|
+
}
|
|
18787
|
+
return found;
|
|
18788
|
+
}, POWERSHELL_VALUES, powershellScript = (words, stdin) => {
|
|
18789
|
+
for (let index = 1;index < words.length; index++) {
|
|
18790
|
+
const word = words[index];
|
|
18791
|
+
if (!/^[-/]/.test(word))
|
|
18792
|
+
return null;
|
|
18793
|
+
const flag = word.replace(/^[-/]+/, "").toLowerCase();
|
|
18794
|
+
if (!flag)
|
|
18795
|
+
return null;
|
|
18796
|
+
if (flag === "e" || flag === "ec" || flag.length >= 2 && "encodedcommand".startsWith(flag)) {
|
|
18797
|
+
try {
|
|
18798
|
+
return Buffer.from(words[index + 1] ?? "", "base64").toString("utf16le");
|
|
18799
|
+
} catch {
|
|
18800
|
+
return null;
|
|
18801
|
+
}
|
|
18802
|
+
}
|
|
18803
|
+
if (flag === "cwa" || flag.length >= 8 && "commandwithargs".startsWith(flag))
|
|
18804
|
+
return words[index + 1] ?? null;
|
|
18805
|
+
if ("command".startsWith(flag))
|
|
18806
|
+
return words[index + 1] === "-" ? stdin ?? null : words.slice(index + 1).join(" ");
|
|
18807
|
+
if (POWERSHELL_VALUES.test(`-${flag}`)) {
|
|
18808
|
+
if (flag === "f" || flag === "file")
|
|
18809
|
+
return null;
|
|
18810
|
+
index++;
|
|
18811
|
+
}
|
|
18812
|
+
}
|
|
18813
|
+
return null;
|
|
18814
|
+
}, cmdScript = (words) => {
|
|
18815
|
+
const at = words.findIndex((word, index) => index > 0 && /^\/[ck]$/i.test(word));
|
|
18816
|
+
if (at > 0)
|
|
18817
|
+
return words.slice(at + 1).join(" ");
|
|
18818
|
+
const attached = words.find((word, index) => index > 0 && /^\/[ck]./i.test(word));
|
|
18819
|
+
return attached ? [attached.slice(2), ...words.slice(words.indexOf(attached) + 1)].join(" ") : null;
|
|
18820
|
+
}, processSubstitutionText = (word) => {
|
|
18821
|
+
const inner = /^<\(([\s\S]*)\)$/.exec(word ?? "")?.[1];
|
|
18822
|
+
if (inner === undefined)
|
|
18823
|
+
return;
|
|
18824
|
+
const segments = segmentsOf(inner);
|
|
18825
|
+
return segments.length === 1 ? literalOutput({ ...segments[0], pipe: true }) : undefined;
|
|
18826
|
+
}, shellScript = (words, stdin) => {
|
|
18827
|
+
const flag = words.findIndex((word, index) => index > 0 && SCRIPT_FLAG.test(word));
|
|
18828
|
+
if (flag > 0)
|
|
18829
|
+
return words[flag + 1] === "--" ? words[flag + 2] : words[flag + 1];
|
|
18830
|
+
const operand = words.slice(1).find((word) => !word.startsWith("-"));
|
|
18831
|
+
if (operand !== undefined)
|
|
18832
|
+
return processSubstitutionText(operand);
|
|
18833
|
+
return stdin;
|
|
18834
|
+
}, scriptCommand = (words) => {
|
|
18835
|
+
for (let index = 1;index < words.length; index++) {
|
|
18836
|
+
const word = words[index];
|
|
18837
|
+
if (word === "--command" || /^-[a-zA-Z]*c$/.test(word))
|
|
18838
|
+
return words[index + 1];
|
|
18839
|
+
if (word.startsWith("--command="))
|
|
18840
|
+
return word.slice("--command=".length);
|
|
18841
|
+
}
|
|
18842
|
+
return;
|
|
18843
|
+
}, PARALLEL_VALUES, parallelCommands = (words) => {
|
|
18844
|
+
let index = 1;
|
|
18845
|
+
while (index < words.length && words[index].startsWith("-"))
|
|
18846
|
+
index += PARALLEL_VALUES.has(words[index]) ? 2 : 1;
|
|
18847
|
+
const separator = words.indexOf(":::", index);
|
|
18848
|
+
const command = words.slice(index, separator < 0 ? undefined : separator);
|
|
18849
|
+
if (separator < 0)
|
|
18850
|
+
return command.length ? [command] : [];
|
|
18851
|
+
return words.slice(separator + 1).filter((arg) => !arg.startsWith(":::")).slice(0, MAX_EXPANSIONS).map((arg) => command.some((word) => word.includes("{}")) ? command.map((word) => word.replaceAll("{}", arg)) : [...command, arg]);
|
|
18852
|
+
}, START_PROCESS_VALUES, startProcessCommand = (words) => {
|
|
18853
|
+
let file;
|
|
18854
|
+
let args;
|
|
18855
|
+
const positionals = [];
|
|
18856
|
+
for (let index = 1;index < words.length; index++) {
|
|
18857
|
+
const word = words[index];
|
|
18858
|
+
const flag = word.startsWith("-") ? word.slice(1).toLowerCase() : null;
|
|
18859
|
+
if (flag === null)
|
|
18860
|
+
positionals.push(word);
|
|
18861
|
+
else if (flag && "filepath".startsWith(flag))
|
|
18862
|
+
file = words[++index];
|
|
18863
|
+
else if (flag && (flag === "args" || "argumentlist".startsWith(flag)))
|
|
18864
|
+
args = words[++index];
|
|
18865
|
+
else if (START_PROCESS_VALUES.test(word))
|
|
18866
|
+
index++;
|
|
18867
|
+
}
|
|
18868
|
+
file ??= positionals.shift();
|
|
18869
|
+
args ??= positionals.shift();
|
|
18870
|
+
if (!file)
|
|
18871
|
+
return null;
|
|
18872
|
+
return [file, ...(args ?? "").split(/[\s,]+/).filter(Boolean)];
|
|
18873
|
+
}, splitString = (line) => {
|
|
18874
|
+
if (commandName(line[0]) !== "env")
|
|
18875
|
+
return null;
|
|
18876
|
+
for (let index = 1;index < line.length; index++) {
|
|
18877
|
+
const word = line[index];
|
|
18878
|
+
if (word === "-S" || word === "--split-string")
|
|
18879
|
+
return line.slice(index + 1).join(" ");
|
|
18880
|
+
if (word.startsWith("--split-string="))
|
|
18881
|
+
return line.slice(index).join(" ").slice(15);
|
|
18882
|
+
if (/^-S./.test(word))
|
|
18883
|
+
return [word.slice(2), ...line.slice(index + 1)].join(" ");
|
|
18884
|
+
if (!word.startsWith("-") && !ASSIGNMENT.test(word))
|
|
18885
|
+
return null;
|
|
18304
18886
|
}
|
|
18305
|
-
|
|
18887
|
+
return null;
|
|
18888
|
+
}, CONFIG_READS, configSetBy = (args) => {
|
|
18889
|
+
const positionals = args.filter((arg, index) => index > 0 && !arg.startsWith("-"));
|
|
18890
|
+
if (args[0] === "remote" && (positionals[0] === "add" || positionals[0] === "set-url")) {
|
|
18891
|
+
const [, name, url] = positionals;
|
|
18892
|
+
const key = args.includes("--push") ? "pushurl" : "url";
|
|
18893
|
+
return name && url ? ["-c", `remote.${name}.${key}=${url}`] : [];
|
|
18894
|
+
}
|
|
18895
|
+
if (args[0] !== "config" || args.some((arg) => CONFIG_READS.test(arg)))
|
|
18896
|
+
return [];
|
|
18897
|
+
const [key, value] = positionals[0] === "set" ? positionals.slice(1) : positionals;
|
|
18898
|
+
return key?.includes(".") && value !== undefined && positionals.length <= 3 ? ["-c", `${key}=${value}`] : [];
|
|
18899
|
+
}, gitInvocation = (words, dir, env = {}, stdin, inherited = []) => {
|
|
18900
|
+
let here = dir;
|
|
18901
|
+
const config = [...inherited];
|
|
18902
|
+
let gitDir = env.GIT_DIR;
|
|
18903
|
+
let index = 0;
|
|
18904
|
+
for (;index < words.length; index++) {
|
|
18905
|
+
const word = words[index];
|
|
18906
|
+
if (word === "-C")
|
|
18907
|
+
here = words[index + 1] ? joinDir(here, words[++index]) : here;
|
|
18908
|
+
else if (GIT_CONFIG_OPTIONS.has(word)) {
|
|
18909
|
+
if (word === "--git-dir")
|
|
18910
|
+
gitDir = words[index + 1];
|
|
18911
|
+
if (words[index + 1] !== undefined)
|
|
18912
|
+
config.push(word, words[++index]);
|
|
18913
|
+
} else if (/^--(?:config-env|git-dir)=/.test(word)) {
|
|
18914
|
+
if (word.startsWith("--git-dir="))
|
|
18915
|
+
gitDir = word.slice("--git-dir=".length);
|
|
18916
|
+
config.push(word);
|
|
18917
|
+
} else if (GIT_VALUE_OPTIONS.has(word))
|
|
18918
|
+
index++;
|
|
18919
|
+
else if (!word.startsWith("-"))
|
|
18920
|
+
break;
|
|
18921
|
+
}
|
|
18922
|
+
if (gitDir)
|
|
18923
|
+
here = joinDir(here, gitDir.replace(/(?:^|[\\/]+)\.git[\\/]*$/, "") || ".");
|
|
18924
|
+
return {
|
|
18925
|
+
tool: "git",
|
|
18926
|
+
dir: here,
|
|
18927
|
+
args: words.slice(index),
|
|
18928
|
+
...config.length ? { config } : {},
|
|
18929
|
+
...Object.keys(env).length ? { env } : {},
|
|
18930
|
+
...stdin === undefined ? {} : { stdin }
|
|
18931
|
+
};
|
|
18932
|
+
}, RECENT, LAUNCHERS, WORKIT_BIN, PUSH_VALUE_OPTIONS, CURRENT_BRANCH, pushDestination = (destination) => {
|
|
18933
|
+
if (destination === "HEAD" || destination === "@" || CURRENT_BRANCH.test(destination))
|
|
18934
|
+
return { name: null };
|
|
18935
|
+
if (destination.startsWith("refs/heads/"))
|
|
18936
|
+
return { name: destination.slice(11) };
|
|
18937
|
+
if (destination.startsWith("refs/tags/"))
|
|
18938
|
+
return { name: undefined, tag: destination.slice(10) };
|
|
18939
|
+
if (destination.startsWith("refs/"))
|
|
18940
|
+
return { name: undefined };
|
|
18941
|
+
return { name: destination };
|
|
18942
|
+
}, pushRefspecs = (specs) => {
|
|
18943
|
+
let force = false;
|
|
18944
|
+
let matching = false;
|
|
18945
|
+
const targets = [];
|
|
18946
|
+
const tags = [];
|
|
18947
|
+
const deleted = [];
|
|
18948
|
+
const globs = [];
|
|
18949
|
+
for (const raw of specs) {
|
|
18950
|
+
if (raw.startsWith("+"))
|
|
18951
|
+
force = true;
|
|
18952
|
+
const spec = raw.replace(/^\+/, "");
|
|
18953
|
+
if (spec.startsWith("^"))
|
|
18954
|
+
continue;
|
|
18955
|
+
if (spec === ":") {
|
|
18956
|
+
matching = true;
|
|
18957
|
+
continue;
|
|
18958
|
+
}
|
|
18959
|
+
const colon = spec.indexOf(":");
|
|
18960
|
+
const source = colon >= 0 ? spec.slice(0, colon) : spec;
|
|
18961
|
+
const destination = colon >= 0 ? spec.slice(colon + 1) : spec;
|
|
18962
|
+
if (!destination)
|
|
18963
|
+
continue;
|
|
18964
|
+
if (destination.includes("*")) {
|
|
18965
|
+
globs.push({ source, destination });
|
|
18966
|
+
continue;
|
|
18967
|
+
}
|
|
18968
|
+
const { name, tag } = pushDestination(destination);
|
|
18969
|
+
if (tag !== undefined)
|
|
18970
|
+
tags.push(tag);
|
|
18971
|
+
if (name === undefined)
|
|
18972
|
+
continue;
|
|
18973
|
+
targets.push(name);
|
|
18974
|
+
if (colon === 0 && name !== null)
|
|
18975
|
+
deleted.push(name);
|
|
18976
|
+
}
|
|
18977
|
+
return { force, matching, targets, tags, deleted, globs };
|
|
18978
|
+
}, pushAction = (args) => {
|
|
18306
18979
|
let force = false;
|
|
18307
18980
|
let lease = false;
|
|
18308
18981
|
let wholesale = false;
|
|
@@ -18311,6 +18984,7 @@ var NONE2, SHELLS, PREFIXES2, SCRIPT_FLAG, CD, PUSHD, POPD, GIT_VALUE_OPTIONS, i
|
|
|
18311
18984
|
let allBranches = false;
|
|
18312
18985
|
let mirror = false;
|
|
18313
18986
|
let remote = null;
|
|
18987
|
+
let dryRun = false;
|
|
18314
18988
|
const positionals = [];
|
|
18315
18989
|
for (let index = 1;index < args.length; index++) {
|
|
18316
18990
|
const arg = args[index];
|
|
@@ -18318,9 +18992,11 @@ var NONE2, SHELLS, PREFIXES2, SCRIPT_FLAG, CD, PUSHD, POPD, GIT_VALUE_OPTIONS, i
|
|
|
18318
18992
|
positionals.push(...args.slice(index + 1));
|
|
18319
18993
|
break;
|
|
18320
18994
|
}
|
|
18321
|
-
if (arg
|
|
18322
|
-
|
|
18323
|
-
if (arg
|
|
18995
|
+
if (/^--dr(?:y(?:-(?:r(?:un?)?)?)?)?$/.test(arg) || /^-[a-zA-Z]*n[a-zA-Z]*$/.test(arg))
|
|
18996
|
+
dryRun = true;
|
|
18997
|
+
else if (/^--no-dr(?:y(?:-(?:r(?:un?)?)?)?)?$/.test(arg))
|
|
18998
|
+
dryRun = false;
|
|
18999
|
+
else if (arg === "--repo")
|
|
18324
19000
|
remote = args[++index] ?? null;
|
|
18325
19001
|
else if (arg.startsWith("--repo="))
|
|
18326
19002
|
remote = arg.slice("--repo=".length);
|
|
@@ -18341,41 +19017,28 @@ var NONE2, SHELLS, PREFIXES2, SCRIPT_FLAG, CD, PUSHD, POPD, GIT_VALUE_OPTIONS, i
|
|
|
18341
19017
|
else if (!arg.startsWith("-"))
|
|
18342
19018
|
positionals.push(arg);
|
|
18343
19019
|
}
|
|
19020
|
+
if (dryRun)
|
|
19021
|
+
return null;
|
|
18344
19022
|
const specs = remote === null ? positionals.slice(1) : positionals;
|
|
18345
19023
|
remote ??= positionals[0] ?? null;
|
|
18346
|
-
const
|
|
18347
|
-
const
|
|
18348
|
-
|
|
18349
|
-
|
|
18350
|
-
if (raw.startsWith("+"))
|
|
18351
|
-
force = true;
|
|
18352
|
-
const spec = raw.replace(/^\+/, "");
|
|
18353
|
-
const colon = spec.indexOf(":");
|
|
18354
|
-
const destination = colon >= 0 ? spec.slice(colon + 1) : spec;
|
|
18355
|
-
if (!destination)
|
|
18356
|
-
continue;
|
|
18357
|
-
const name = destination === "HEAD" ? null : destination.startsWith("refs/heads/") ? destination.slice(11) : destination.startsWith("refs/") ? undefined : destination;
|
|
18358
|
-
if (destination.startsWith("refs/tags/"))
|
|
18359
|
-
tags.push(destination.slice(10));
|
|
18360
|
-
if (name === undefined)
|
|
18361
|
-
continue;
|
|
18362
|
-
targets.push(name);
|
|
18363
|
-
if (colon === 0 && name !== null)
|
|
18364
|
-
deleted.push(name);
|
|
18365
|
-
}
|
|
18366
|
-
if (specs.length === 0 && !wholesale)
|
|
18367
|
-
targets.push(null);
|
|
19024
|
+
const parsed = pushRefspecs(specs);
|
|
19025
|
+
const implicit = specs.length === 0 && !wholesale;
|
|
19026
|
+
if (implicit)
|
|
19027
|
+
parsed.targets.push(null);
|
|
18368
19028
|
return {
|
|
18369
19029
|
kind: "push",
|
|
18370
|
-
targets,
|
|
18371
|
-
blindForce: force && !lease,
|
|
19030
|
+
targets: parsed.targets,
|
|
19031
|
+
blindForce: (force || parsed.force) && !lease,
|
|
18372
19032
|
remote,
|
|
18373
|
-
...tags.length ? { tags } : {},
|
|
19033
|
+
...parsed.tags.length ? { tags: parsed.tags } : {},
|
|
18374
19034
|
...allTags ? { allTags: true } : {},
|
|
18375
19035
|
...deletes ? { deletes: true } : {},
|
|
18376
|
-
...deleted.length ? { deleted } : {},
|
|
19036
|
+
...parsed.deleted.length ? { deleted: parsed.deleted } : {},
|
|
18377
19037
|
...allBranches ? { allBranches: true } : {},
|
|
18378
|
-
...mirror ? { mirror: true } : {}
|
|
19038
|
+
...mirror ? { mirror: true } : {},
|
|
19039
|
+
...implicit ? { implicit: true } : {},
|
|
19040
|
+
...parsed.globs.length ? { globs: parsed.globs } : {},
|
|
19041
|
+
...parsed.matching ? { matching: true } : {}
|
|
18379
19042
|
};
|
|
18380
19043
|
}, VALUE_OPTIONS, asksHelp = (invocation) => {
|
|
18381
19044
|
const { tool, args } = invocation;
|
|
@@ -18392,6 +19055,59 @@ var NONE2, SHELLS, PREFIXES2, SCRIPT_FLAG, CD, PUSHD, POPD, GIT_VALUE_OPTIONS, i
|
|
|
18392
19055
|
index++;
|
|
18393
19056
|
}
|
|
18394
19057
|
return false;
|
|
19058
|
+
}, API_VALUES, API_SHORT_VALUES = "XHfFqtp", API_FIELDS, API_MERGE, GRAPHQL_MERGE, apiMerges = (tool, args, stdin) => {
|
|
19059
|
+
const request = { method: null, body: false };
|
|
19060
|
+
let endpoint = null;
|
|
19061
|
+
const values = [];
|
|
19062
|
+
const take = (name, value) => {
|
|
19063
|
+
if (name === "-X" || name === "--method")
|
|
19064
|
+
request.method = value.toUpperCase();
|
|
19065
|
+
if (API_FIELDS.has(name) || name === "--input")
|
|
19066
|
+
request.body = true;
|
|
19067
|
+
values.push(value);
|
|
19068
|
+
const fromStdin = name === "--input" ? value === "-" : /^(?:[^=]*=)?@-$/.test(value);
|
|
19069
|
+
if (fromStdin && stdin !== undefined)
|
|
19070
|
+
values.push(stdin);
|
|
19071
|
+
};
|
|
19072
|
+
for (let index = 1;index < args.length; index++) {
|
|
19073
|
+
const arg = args[index];
|
|
19074
|
+
if (arg === "--") {
|
|
19075
|
+
endpoint ??= args[index + 1] ?? null;
|
|
19076
|
+
break;
|
|
19077
|
+
}
|
|
19078
|
+
if (arg.startsWith("--")) {
|
|
19079
|
+
const eq = arg.indexOf("=");
|
|
19080
|
+
const name = eq > 0 ? arg.slice(0, eq) : arg;
|
|
19081
|
+
if (API_VALUES.has(name))
|
|
19082
|
+
take(name, eq > 0 ? arg.slice(eq + 1) : args[++index] ?? "");
|
|
19083
|
+
} else if (arg.startsWith("-") && arg.length > 1) {
|
|
19084
|
+
for (let at = 1;at < arg.length; at++) {
|
|
19085
|
+
if (!API_SHORT_VALUES.includes(arg[at]))
|
|
19086
|
+
continue;
|
|
19087
|
+
take(`-${arg[at]}`, at + 1 < arg.length ? arg.slice(at + 1) : args[++index] ?? "");
|
|
19088
|
+
break;
|
|
19089
|
+
}
|
|
19090
|
+
} else
|
|
19091
|
+
endpoint ??= arg;
|
|
19092
|
+
}
|
|
19093
|
+
if (!endpoint)
|
|
19094
|
+
return false;
|
|
19095
|
+
endpoint = endpoint.replace(/(?<!:)\/{2,}/g, "/");
|
|
19096
|
+
if (/(?:^|\/)graphql\/?$/i.test(endpoint))
|
|
19097
|
+
return values.some((value) => GRAPHQL_MERGE.test(value));
|
|
19098
|
+
const verb = request.method ?? (request.body ? "POST" : "GET");
|
|
19099
|
+
return verb !== "GET" && verb !== "HEAD" && API_MERGE[tool].test(endpoint);
|
|
19100
|
+
}, subtreePush = (args) => {
|
|
19101
|
+
const positionals = [];
|
|
19102
|
+
for (let index = 2;index < args.length; index++) {
|
|
19103
|
+
const arg = args[index];
|
|
19104
|
+
if (arg === "-P" || arg === "--prefix" || arg === "-m" || arg === "--message")
|
|
19105
|
+
index++;
|
|
19106
|
+
else if (!arg.startsWith("-"))
|
|
19107
|
+
positionals.push(arg);
|
|
19108
|
+
}
|
|
19109
|
+
const [remote, branch] = positionals;
|
|
19110
|
+
return remote && branch ? pushAction(["push", remote, `HEAD:refs/heads/${branch}`]) : null;
|
|
18395
19111
|
}, repoAt = (dir) => {
|
|
18396
19112
|
const location = resolveStore(dir);
|
|
18397
19113
|
if (location instanceof Error || !location.shared)
|
|
@@ -18412,15 +19128,6 @@ var NONE2, SHELLS, PREFIXES2, SCRIPT_FLAG, CD, PUSHD, POPD, GIT_VALUE_OPTIONS, i
|
|
|
18412
19128
|
} catch {
|
|
18413
19129
|
return false;
|
|
18414
19130
|
}
|
|
18415
|
-
}, toPushRemote = (repo, remote) => {
|
|
18416
|
-
if (remote === null)
|
|
18417
|
-
return true;
|
|
18418
|
-
try {
|
|
18419
|
-
const pushRemote = pushRemoteName(repo.dir, repo.branch);
|
|
18420
|
-
return pushRemote === null || pushRemote === remote;
|
|
18421
|
-
} catch {
|
|
18422
|
-
return false;
|
|
18423
|
-
}
|
|
18424
19131
|
}, headSha2 = (repo) => {
|
|
18425
19132
|
const git = repo.location.git;
|
|
18426
19133
|
if (!git || git.reftable)
|
|
@@ -18441,9 +19148,141 @@ var NONE2, SHELLS, PREFIXES2, SCRIPT_FLAG, CD, PUSHD, POPD, GIT_VALUE_OPTIONS, i
|
|
|
18441
19148
|
} catch {
|
|
18442
19149
|
return null;
|
|
18443
19150
|
}
|
|
19151
|
+
}, gitConfig = (dir, invocation, cache) => {
|
|
19152
|
+
const key = JSON.stringify([dir, invocation.config ?? [], invocation.env ?? {}]);
|
|
19153
|
+
const cached = cache.get(key);
|
|
19154
|
+
if (cached)
|
|
19155
|
+
return cached;
|
|
19156
|
+
const config = new Map;
|
|
19157
|
+
const listed = spawnSync11("git", [...invocation.config ?? [], "config", "-z", "--list"], {
|
|
19158
|
+
cwd: dir,
|
|
19159
|
+
encoding: "utf8",
|
|
19160
|
+
timeout: 3000,
|
|
19161
|
+
windowsHide: true,
|
|
19162
|
+
env: { ...process.env, ...invocation.env, GIT_TERMINAL_PROMPT: "0", GIT_OPTIONAL_LOCKS: "0" }
|
|
19163
|
+
});
|
|
19164
|
+
for (const entry of (listed.status === 0 ? listed.stdout : "").split("\x00")) {
|
|
19165
|
+
if (!entry)
|
|
19166
|
+
continue;
|
|
19167
|
+
const newline = entry.indexOf(`
|
|
19168
|
+
`);
|
|
19169
|
+
const name = newline < 0 ? entry : entry.slice(0, newline);
|
|
19170
|
+
config.set(name, [
|
|
19171
|
+
...config.get(name) ?? [],
|
|
19172
|
+
newline < 0 ? "true" : entry.slice(newline + 1)
|
|
19173
|
+
]);
|
|
19174
|
+
}
|
|
19175
|
+
cache.set(key, config);
|
|
19176
|
+
return config;
|
|
19177
|
+
}, configValue = (config, key) => config.get(key)?.at(-1), GIT_COMMANDS, JUDGED_COMMANDS, editDistance2 = (a, b) => {
|
|
19178
|
+
let before = [];
|
|
19179
|
+
let previous = Array.from({ length: b.length + 1 }, (_, index) => index);
|
|
19180
|
+
for (let i = 1;i <= a.length; i++) {
|
|
19181
|
+
const row = [i];
|
|
19182
|
+
for (let j = 1;j <= b.length; j++) {
|
|
19183
|
+
row[j] = Math.min(previous[j] + 1, row[j - 1] + 1, previous[j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1));
|
|
19184
|
+
if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1])
|
|
19185
|
+
row[j] = Math.min(row[j], before[j - 2] + 1);
|
|
19186
|
+
}
|
|
19187
|
+
[before, previous] = [previous, row];
|
|
19188
|
+
}
|
|
19189
|
+
return previous[b.length];
|
|
19190
|
+
}, autocorrected = (name, config) => {
|
|
19191
|
+
const setting = (configValue(config, "help.autocorrect") ?? "0").toLowerCase();
|
|
19192
|
+
if (setting !== "immediate" && !/^-?[1-9]\d*$/.test(setting))
|
|
19193
|
+
return null;
|
|
19194
|
+
let best = null;
|
|
19195
|
+
let bestDistance = 3;
|
|
19196
|
+
let tie = false;
|
|
19197
|
+
for (const command of JUDGED_COMMANDS) {
|
|
19198
|
+
const distance = editDistance2(name, command);
|
|
19199
|
+
if (distance < bestDistance)
|
|
19200
|
+
[best, bestDistance, tie] = [command, distance, false];
|
|
19201
|
+
else if (distance === bestDistance)
|
|
19202
|
+
tie = true;
|
|
19203
|
+
}
|
|
19204
|
+
return tie ? null : best;
|
|
19205
|
+
}, shellQuote = (word) => `'${word.replaceAll("'", "'\\''")}'`, positional = (script, args) => {
|
|
19206
|
+
const word = (arg) => /^[\w./@+:=-]+$/.test(arg) ? arg : shellQuote(arg);
|
|
19207
|
+
return script.replace(/\$\{?([1-9])\}?/g, (_, n) => word(args[Number(n) - 1] ?? "")).replace(/\$\{?[@*]\}?/g, args.map(word).join(" "));
|
|
19208
|
+
}, expandGitAliases = (root, invocation, cache = new Map, depth = 0) => {
|
|
19209
|
+
const sub = invocation.args[0];
|
|
19210
|
+
if (invocation.tool !== "git" || invocation.dir === undefined || !sub || sub.startsWith("-") || GIT_COMMANDS.has(sub) || depth >= MAX_DEPTH)
|
|
19211
|
+
return [invocation];
|
|
19212
|
+
const dir = path20.resolve(root, invocation.dir ?? ".");
|
|
19213
|
+
if (!fs16.existsSync(dir))
|
|
19214
|
+
return [invocation];
|
|
19215
|
+
const config = gitConfig(dir, invocation, cache);
|
|
19216
|
+
const alias = configValue(config, `alias.${sub.toLowerCase()}`);
|
|
19217
|
+
if (alias === undefined) {
|
|
19218
|
+
const corrected = autocorrected(sub, config);
|
|
19219
|
+
return corrected ? [{ ...invocation, args: [corrected, ...invocation.args.slice(1)] }] : [invocation];
|
|
19220
|
+
}
|
|
19221
|
+
const rest = invocation.args.slice(1);
|
|
19222
|
+
const expanded = alias.startsWith("!") ? rawInvocations([positional(alias.slice(1), rest), ...rest.map(shellQuote)].join(" ")).map((inner) => ({
|
|
19223
|
+
...inner,
|
|
19224
|
+
dir: rebase(invocation.dir, inner.dir),
|
|
19225
|
+
...inner.tool === "git" && (invocation.config || inner.config) ? { config: [...invocation.config ?? [], ...inner.config ?? []] } : {},
|
|
19226
|
+
...inner.tool === "git" && (invocation.env || inner.env) ? { env: { ...invocation.env, ...inner.env } } : {}
|
|
19227
|
+
})) : [
|
|
19228
|
+
gitInvocation([...segmentsOf(alias)[0]?.words ?? [], ...rest], invocation.dir, invocation.env, invocation.stdin, invocation.config)
|
|
19229
|
+
];
|
|
19230
|
+
return expanded.flatMap((inner) => expandGitAliases(root, inner, cache, depth + 1));
|
|
19231
|
+
}, normalizedUrl = (url, dir) => {
|
|
19232
|
+
const trimmed = url.trim();
|
|
19233
|
+
if (/^file:\/\//i.test(trimmed))
|
|
19234
|
+
return path20.resolve(dir, trimmed.slice(7)).replace(/\/+$/, "").replace(/\.git$/, "");
|
|
19235
|
+
const scheme = /^[a-z][a-z0-9+.-]*:\/\//i.exec(trimmed);
|
|
19236
|
+
const scp = !scheme && /^(?:[^@/\\]+@)?[^/\\:]{2,}:/.test(trimmed);
|
|
19237
|
+
if (!scheme && !scp)
|
|
19238
|
+
return path20.resolve(dir, trimmed).replace(/\/+$/, "").replace(/\.git$/, "");
|
|
19239
|
+
const value = scheme ? trimmed.slice(scheme[0].length).replace(/^[^@/]*@/, "").replace(/^([^/:]+):\d+(?=\/)/, "$1") : trimmed.replace(/^[^@/]*@/, "").replace(":", "/");
|
|
19240
|
+
return value.toLowerCase().replace(/\/{2,}/g, "/").replace(/^www\./, "").replace(/\/+$/, "").replace(/\.git$/, "");
|
|
19241
|
+
}, rewrittenUrl = (url, config) => {
|
|
19242
|
+
for (const kind of ["pushinsteadof", "insteadof"]) {
|
|
19243
|
+
let best = null;
|
|
19244
|
+
for (const [key, prefixes] of config) {
|
|
19245
|
+
if (!key.startsWith("url.") || !key.endsWith(`.${kind}`))
|
|
19246
|
+
continue;
|
|
19247
|
+
const base = key.slice(4, -(kind.length + 1));
|
|
19248
|
+
for (const prefix of prefixes)
|
|
19249
|
+
if (url.startsWith(prefix) && prefix.length > (best?.prefix.length ?? -1))
|
|
19250
|
+
best = { base, prefix };
|
|
19251
|
+
}
|
|
19252
|
+
if (best)
|
|
19253
|
+
return best.base + url.slice(best.prefix.length);
|
|
19254
|
+
}
|
|
19255
|
+
return url;
|
|
19256
|
+
}, pushUrl = (config, remote, dir) => {
|
|
19257
|
+
const configured = configValue(config, `remote.${remote}.pushurl`) ?? configValue(config, `remote.${remote}.url`);
|
|
19258
|
+
return normalizedUrl(rewrittenUrl(configured ?? remote, config), dir);
|
|
19259
|
+
}, pushRemoteOf = (config, branch) => {
|
|
19260
|
+
const remotes = new Set;
|
|
19261
|
+
for (const key of config.keys()) {
|
|
19262
|
+
const name = /^remote\.(.+)\.url$/.exec(key)?.[1];
|
|
19263
|
+
if (name)
|
|
19264
|
+
remotes.add(name);
|
|
19265
|
+
}
|
|
19266
|
+
for (const candidate of [
|
|
19267
|
+
branch ? configValue(config, `branch.${branch}.pushremote`) : undefined,
|
|
19268
|
+
configValue(config, "remote.pushdefault"),
|
|
19269
|
+
branch ? configValue(config, `branch.${branch}.remote`) : undefined
|
|
19270
|
+
])
|
|
19271
|
+
if (candidate && candidate !== "." && remotes.has(candidate))
|
|
19272
|
+
return candidate;
|
|
19273
|
+
if (remotes.has("origin"))
|
|
19274
|
+
return "origin";
|
|
19275
|
+
return remotes.size === 1 ? [...remotes][0] : null;
|
|
19276
|
+
}, toPushRemote = (repo, remote, config) => {
|
|
19277
|
+
if (remote === null || /[$`]/.test(remote))
|
|
19278
|
+
return true;
|
|
19279
|
+
const pushRemote = pushRemoteOf(config, repo.branch);
|
|
19280
|
+
if (pushRemote === null || pushRemote === remote)
|
|
19281
|
+
return true;
|
|
19282
|
+
return pushUrl(config, remote, repo.dir) === pushUrl(config, pushRemote, repo.dir);
|
|
18444
19283
|
}, quote = (text) => `\`${text}\``, refusal = (action, branch, dir) => {
|
|
18445
19284
|
if (action.kind === "merge")
|
|
18446
|
-
return `workit: raw ${quote(action.forge === "gh" ? "gh pr merge" : "glab mr merge")} bypasses the merge grant and the verdict gate. Run ${quote("workit pr merge")} instead (it checks both; ${quote("workit help pr")}).`;
|
|
19285
|
+
return `workit: raw ${quote(action.via === "api" ? `${action.forge} api` : action.forge === "gh" ? "gh pr merge" : "glab mr merge")}${action.via === "api" ? " merge" : ""} bypasses the merge grant and the verdict gate. Run ${quote("workit pr merge")} instead (it checks both; ${quote("workit help pr")}).`;
|
|
18447
19286
|
const plainPush = action.kind === "push" && !action.blindForce && !action.deletes;
|
|
18448
19287
|
if (dir && branch && plainPush && releaseBranch(dir, branch))
|
|
18449
19288
|
return `workit: raw ${quote("git push")} onto ${branch}, a protected release branch, bypasses workit's protected-branch check. To finish a release or hotfix, push it with ${quote(`workit git push --release ${branch} [--release v<version>]`)}: it pushes ${branch} (fast-forward only) and the release tag, verifies the remote and records it, under the ${quote("release")} grant (if refused, ask the user to run ${quote("workit grant set <workspace> release=true")}). Feature work goes through ${quote("workit git push")} and ${quote("workit pr merge")}.`;
|
|
@@ -18462,6 +19301,70 @@ var NONE2, SHELLS, PREFIXES2, SCRIPT_FLAG, CD, PUSHD, POPD, GIT_VALUE_OPTIONS, i
|
|
|
18462
19301
|
facts.remoteHeads.add(ref.slice(remotePrefix.length));
|
|
18463
19302
|
}
|
|
18464
19303
|
return facts;
|
|
19304
|
+
}, globBranches = (repo, glob) => {
|
|
19305
|
+
const source = glob.source.startsWith("refs/") ? glob.source : `refs/heads/${glob.source}`;
|
|
19306
|
+
const [sourcePrefix, sourceSuffix = ""] = source.split("*");
|
|
19307
|
+
const [destinationPrefix, destinationSuffix = ""] = glob.destination.split("*");
|
|
19308
|
+
const listed = spawnSync11("git", [
|
|
19309
|
+
"for-each-ref",
|
|
19310
|
+
"--format=%(refname)",
|
|
19311
|
+
sourcePrefix.slice(0, sourcePrefix.lastIndexOf("/") + 1)
|
|
19312
|
+
], { cwd: repo.dir, encoding: "utf8", timeout: 5000, windowsHide: true });
|
|
19313
|
+
const names = [];
|
|
19314
|
+
for (const ref of (listed.stdout ?? "").split(`
|
|
19315
|
+
`)) {
|
|
19316
|
+
if (!ref.startsWith(sourcePrefix) || !ref.endsWith(sourceSuffix))
|
|
19317
|
+
continue;
|
|
19318
|
+
const middle = ref.slice(sourcePrefix.length, ref.length - sourceSuffix.length);
|
|
19319
|
+
const { name } = pushDestination(destinationPrefix + middle + destinationSuffix);
|
|
19320
|
+
if (name)
|
|
19321
|
+
names.push(name);
|
|
19322
|
+
}
|
|
19323
|
+
return names;
|
|
19324
|
+
}, pushedBranches = (action, repo, config, facts, remote) => {
|
|
19325
|
+
const targets = action.implicit ? [] : [...action.targets];
|
|
19326
|
+
const globs = [...action.globs ?? []];
|
|
19327
|
+
let matching = action.matching === true;
|
|
19328
|
+
const configured = action.implicit ? config.get(`remote.${remote}.push`) : undefined;
|
|
19329
|
+
if (configured?.length) {
|
|
19330
|
+
const parsed = pushRefspecs(configured);
|
|
19331
|
+
targets.push(...parsed.targets);
|
|
19332
|
+
globs.push(...parsed.globs);
|
|
19333
|
+
matching ||= parsed.matching;
|
|
19334
|
+
} else if (action.implicit) {
|
|
19335
|
+
const mode = (configValue(config, "push.default") ?? "simple").toLowerCase();
|
|
19336
|
+
const merge = repo.branch ? configValue(config, `branch.${repo.branch}.merge`) : undefined;
|
|
19337
|
+
if (mode === "matching")
|
|
19338
|
+
matching = true;
|
|
19339
|
+
else if ((mode === "upstream" || mode === "tracking") && merge?.startsWith("refs/heads/"))
|
|
19340
|
+
targets.push(merge.slice(11));
|
|
19341
|
+
else if (mode !== "nothing")
|
|
19342
|
+
targets.push(null);
|
|
19343
|
+
}
|
|
19344
|
+
if (action.allBranches)
|
|
19345
|
+
targets.push(...facts.heads);
|
|
19346
|
+
if (matching) {
|
|
19347
|
+
for (const head of facts.heads)
|
|
19348
|
+
if (facts.remoteHeads.has(head))
|
|
19349
|
+
targets.push(head);
|
|
19350
|
+
}
|
|
19351
|
+
for (const glob of globs)
|
|
19352
|
+
targets.push(...globBranches(repo, glob));
|
|
19353
|
+
return targets;
|
|
19354
|
+
}, literalReadings = (name) => {
|
|
19355
|
+
if (!/[$`]/.test(name))
|
|
19356
|
+
return [name];
|
|
19357
|
+
const withDefaults = name.replace(/\$\{\w+:?[-=]([^}$`]*)\}/g, "$1").replace(/\$\{\w+\}|\$\w+/g, "");
|
|
19358
|
+
return /[$`]/.test(withDefaults) || !withDefaults ? [] : [withDefaults];
|
|
19359
|
+
}, guardedTarget = (dir, target) => {
|
|
19360
|
+
for (const branch of literalReadings(target)) {
|
|
19361
|
+
if (guardedBranch(dir, branch))
|
|
19362
|
+
return branch;
|
|
19363
|
+
const bare = branch.startsWith("heads/") ? branch.slice(6) : null;
|
|
19364
|
+
if (bare && guardedBranch(dir, bare))
|
|
19365
|
+
return bare;
|
|
19366
|
+
}
|
|
19367
|
+
return null;
|
|
18465
19368
|
}, isTag = (facts, name) => facts.tags.has(name) && !facts.heads.has(name), tagRefusal = (action, facts) => {
|
|
18466
19369
|
const tags = [
|
|
18467
19370
|
...action.tags ?? [],
|
|
@@ -18471,23 +19374,31 @@ var NONE2, SHELLS, PREFIXES2, SCRIPT_FLAG, CD, PUSHD, POPD, GIT_VALUE_OPTIONS, i
|
|
|
18471
19374
|
return null;
|
|
18472
19375
|
const named = tags.length ? tags.join(" --release ") : "v<version>";
|
|
18473
19376
|
return `workit: raw ${quote(`git push${action.allTags ? " --tags" : ""}`)} of ${tags.length ? `tag ${tags.join(", ")}` : "tags"} bypasses the release grant. Push a release tag with ${quote(`workit git push --release ${named}`)} (v<version> tags whose commit the production branch already has; a tag never moves), under the ${quote("release")} grant (if refused, ask the user to run ${quote("workit grant set <workspace> release=true")}).`;
|
|
18474
|
-
},
|
|
18475
|
-
const listed = spawnSync11("git", ["ls-remote", "--heads", remote
|
|
19377
|
+
}, remoteHeads = (repo, remote) => {
|
|
19378
|
+
const listed = spawnSync11("git", ["ls-remote", "--heads", remote], {
|
|
18476
19379
|
cwd: repo.dir,
|
|
18477
19380
|
encoding: "utf8",
|
|
18478
19381
|
timeout: 3000,
|
|
19382
|
+
windowsHide: true,
|
|
18479
19383
|
env: { ...process.env, GIT_TERMINAL_PROMPT: "0" }
|
|
18480
19384
|
});
|
|
18481
|
-
|
|
19385
|
+
if (listed.status !== 0)
|
|
19386
|
+
return null;
|
|
19387
|
+
return new Set((listed.stdout ?? "").split(`
|
|
19388
|
+
`).map((line) => line.split("\t")[1] ?? "").filter((ref) => ref.startsWith("refs/heads/")).map((ref) => ref.slice(11)));
|
|
18482
19389
|
}, offPolicyPush = (action, repo, facts, remote) => {
|
|
18483
19390
|
const names = action.allBranches ? [...facts.heads] : action.targets.map((target) => target ?? repo.branch);
|
|
19391
|
+
let listed;
|
|
19392
|
+
const remoteHas = (branch) => (listed === undefined ? listed = remoteHeads(repo, remote) : listed)?.has(branch) ?? true;
|
|
18484
19393
|
for (const branch of names) {
|
|
18485
|
-
if (!branch ||
|
|
19394
|
+
if (!branch || /[$`]/.test(branch))
|
|
19395
|
+
continue;
|
|
19396
|
+
if (action.deleted?.includes(branch) || isTag(facts, branch))
|
|
18486
19397
|
continue;
|
|
18487
19398
|
if (facts.remoteHeads.has(branch))
|
|
18488
19399
|
continue;
|
|
18489
19400
|
const check = validateBranchNameFor(repo.dir, branch);
|
|
18490
|
-
if (check.ok || check.rule !== "allowed_pattern" || remoteHas(
|
|
19401
|
+
if (check.ok || check.rule !== "allowed_pattern" || remoteHas(branch))
|
|
18491
19402
|
continue;
|
|
18492
19403
|
return `workit: raw ${quote("git push")} onto ${branch}: ${check.error}`;
|
|
18493
19404
|
}
|
|
@@ -18507,23 +19418,49 @@ var NONE2, SHELLS, PREFIXES2, SCRIPT_FLAG, CD, PUSHD, POPD, GIT_VALUE_OPTIONS, i
|
|
|
18507
19418
|
case "merge":
|
|
18508
19419
|
return null;
|
|
18509
19420
|
}
|
|
18510
|
-
},
|
|
19421
|
+
}, pushRefusal = (action, repo, config) => {
|
|
19422
|
+
if (!toPushRemote(repo, action.remote, config))
|
|
19423
|
+
return null;
|
|
19424
|
+
if (action.mirror)
|
|
19425
|
+
return `workit: raw ${quote("git push --mirror")} rewrites and deletes every remote ref, protected branches and tags included. Push one branch with ${quote("workit git push")}.`;
|
|
19426
|
+
const remote = action.remote ?? pushRemoteOf(config, repo.branch) ?? "origin";
|
|
19427
|
+
const facts = refFacts(repo, remote);
|
|
19428
|
+
const targets = pushedBranches(action, repo, config, facts, remote);
|
|
19429
|
+
const pushed = { ...action, targets };
|
|
19430
|
+
const offPolicy = action.allBranches ? offPolicyPush(pushed, repo, facts, remote) : null;
|
|
19431
|
+
if (offPolicy)
|
|
19432
|
+
return offPolicy;
|
|
19433
|
+
for (const target of targets) {
|
|
19434
|
+
const guarded = guardedTarget(repo.dir, target ?? repo.branch ?? "");
|
|
19435
|
+
if (guarded)
|
|
19436
|
+
return refusal(action, guarded, repo.dir);
|
|
19437
|
+
}
|
|
19438
|
+
return tagRefusal(pushed, facts) ?? (action.deletes ? null : offPolicyPush(pushed, repo, facts, remote));
|
|
19439
|
+
}, actionsIn = (cwd, command, dialect, cache = new Map) => {
|
|
18511
19440
|
const out = [];
|
|
18512
19441
|
const repos = new Map;
|
|
18513
|
-
|
|
18514
|
-
|
|
18515
|
-
continue;
|
|
18516
|
-
const action = rawAction(invocation);
|
|
18517
|
-
if (!action)
|
|
18518
|
-
continue;
|
|
18519
|
-
const dir = path20.resolve(cwd, invocation.dir ?? ".");
|
|
19442
|
+
const repoFor = (relative) => {
|
|
19443
|
+
const dir = path20.resolve(cwd, relative ?? ".");
|
|
18520
19444
|
if (!repos.has(dir)) {
|
|
18521
19445
|
const repo = repoAt(dir);
|
|
18522
19446
|
repos.set(dir, repo && isWorkitWorkspace(repo) ? repo : null);
|
|
18523
19447
|
}
|
|
18524
|
-
|
|
18525
|
-
|
|
18526
|
-
|
|
19448
|
+
return repos.get(dir) ?? null;
|
|
19449
|
+
};
|
|
19450
|
+
for (const raw of rawInvocations(command, dialect)) {
|
|
19451
|
+
if (raw.dir === undefined)
|
|
19452
|
+
continue;
|
|
19453
|
+
const known = raw.tool !== "git" || GIT_COMMANDS.has(raw.args[0] ?? "");
|
|
19454
|
+
if (!known && !repoFor(raw.dir))
|
|
19455
|
+
continue;
|
|
19456
|
+
for (const invocation of known ? [raw] : expandGitAliases(cwd, raw, cache)) {
|
|
19457
|
+
if (invocation.dir === undefined)
|
|
19458
|
+
continue;
|
|
19459
|
+
const action = rawAction(invocation);
|
|
19460
|
+
const repo = action ? repoFor(invocation.dir) : null;
|
|
19461
|
+
if (action && repo)
|
|
19462
|
+
out.push({ action, repo, invocation });
|
|
19463
|
+
}
|
|
18527
19464
|
}
|
|
18528
19465
|
return out;
|
|
18529
19466
|
}, inWorkitWorkspace = (dir) => {
|
|
@@ -18543,7 +19480,11 @@ var NONE2, SHELLS, PREFIXES2, SCRIPT_FLAG, CD, PUSHD, POPD, GIT_VALUE_OPTIONS, i
|
|
|
18543
19480
|
raw: [...marker.raw, ...fresh.map((kind) => agent + kind)]
|
|
18544
19481
|
});
|
|
18545
19482
|
return fresh.map((kind) => nudges.get(kind));
|
|
18546
|
-
}, deny = (reason) => ({ kind: "deny", reason, unblock: null }),
|
|
19483
|
+
}, deny = (reason) => ({ kind: "deny", reason, unblock: null }), SPLIT_IT = "Split it into simpler commands (no deeply nested substitutions or huge brace lists) and run them one at a time.", analysisDenial = (error) => ({
|
|
19484
|
+
kind: "deny",
|
|
19485
|
+
reason: `workit: the shell hook could not analyze this command (${error.message}), so it does not run. ${SPLIT_IT}`,
|
|
19486
|
+
unblock: SPLIT_IT
|
|
19487
|
+
}), NEXT_COMMAND = "next", MARKER_TTL_SECONDS = 3600, markerFile = (repo, session, key) => path20.join(repo.location.dir, "hooks", `commit-${createHash14("sha256").update(`${session}\x00${key}`).digest("hex").slice(0, 32)}.json`), callKey = (toolUseId, command) => toolUseId ?? `cmd:${createHash14("sha256").update(command).digest("hex")}`, headCommit = (dir) => {
|
|
18547
19488
|
const run = spawnSync11("git", [
|
|
18548
19489
|
"log",
|
|
18549
19490
|
"-1",
|
|
@@ -18599,13 +19540,40 @@ var NONE2, SHELLS, PREFIXES2, SCRIPT_FLAG, CD, PUSHD, POPD, GIT_VALUE_OPTIONS, i
|
|
|
18599
19540
|
var init_raw_git = __esm(() => {
|
|
18600
19541
|
init_branch();
|
|
18601
19542
|
init_workspaces();
|
|
18602
|
-
init_rev();
|
|
18603
19543
|
init_ledger();
|
|
18604
19544
|
init_paths();
|
|
18605
19545
|
init_session_marker();
|
|
19546
|
+
init_shell_words();
|
|
18606
19547
|
NONE2 = { kind: "none" };
|
|
18607
|
-
SHELLS = new Set(["sh", "bash", "zsh", "dash", "ksh"]);
|
|
18608
|
-
|
|
19548
|
+
SHELLS = new Set(["sh", "bash", "zsh", "dash", "ksh", "ash", "mksh", "yash", "fish"]);
|
|
19549
|
+
POWERSHELLS = new Set(["pwsh", "powershell"]);
|
|
19550
|
+
EVALS = new Set(["eval", "iex", "invoke-expression"]);
|
|
19551
|
+
WRAPPERS = {
|
|
19552
|
+
sudo: { values: "-u -g -h -p -C -D -R -T -r -t -U --user --group --host --prompt --chdir" },
|
|
19553
|
+
doas: { values: "-u -C" },
|
|
19554
|
+
command: { values: "" },
|
|
19555
|
+
builtin: { values: "" },
|
|
19556
|
+
env: { values: "-u -C --unset --chdir" },
|
|
19557
|
+
nohup: { values: "" },
|
|
19558
|
+
setsid: { values: "" },
|
|
19559
|
+
time: { values: "-f -o --format --output" },
|
|
19560
|
+
exec: { values: "-a" },
|
|
19561
|
+
nice: { values: "-n --adjustment" },
|
|
19562
|
+
ionice: { values: "-c -n -p --class --classdata" },
|
|
19563
|
+
stdbuf: { values: "-i -o -e --input --output --error" },
|
|
19564
|
+
chronic: { values: "" },
|
|
19565
|
+
unbuffer: { values: "" },
|
|
19566
|
+
wsl: { values: "-d -u --cd --distribution --user" },
|
|
19567
|
+
timeout: { values: "-s -k --signal --kill-after", operands: 1 },
|
|
19568
|
+
flock: { values: "-w -E --timeout --conflict-exit-code", operands: 1 },
|
|
19569
|
+
coproc: { values: "" },
|
|
19570
|
+
taskset: { values: "", operands: 1 },
|
|
19571
|
+
watch: { values: "-n -d --interval --differences -q --equexit" },
|
|
19572
|
+
"&": { values: "" }
|
|
19573
|
+
};
|
|
19574
|
+
WRAPPER_VALUES = new Map(Object.entries(WRAPPERS).map(([name, wrapper]) => [name, new Set(wrapper.values.split(" "))]));
|
|
19575
|
+
KEYWORDS = new Set(["if", "then", "else", "elif", "while", "until", "do", "!", "{"]);
|
|
19576
|
+
DECLARATIONS = new Set(["export", "local", "declare", "readonly", "typeset"]);
|
|
18609
19577
|
SCRIPT_FLAG = /^-[a-zA-Z]*c[a-zA-Z]*$/;
|
|
18610
19578
|
CD = new Set(["cd", "chdir", "set-location", "sl"]);
|
|
18611
19579
|
PUSHD = new Set(["pushd", "push-location"]);
|
|
@@ -18619,6 +19587,24 @@ var init_raw_git = __esm(() => {
|
|
|
18619
19587
|
"--config-env",
|
|
18620
19588
|
"--super-prefix"
|
|
18621
19589
|
]);
|
|
19590
|
+
GIT_CONFIG_OPTIONS = new Set(["-c", "--config-env", "--git-dir"]);
|
|
19591
|
+
GIT_CONFIG_ENV = /^GIT_(?:CONFIG\w*|DIR|COMMON_DIR|WORK_TREE)$/;
|
|
19592
|
+
ASSIGNMENT = /^([A-Za-z_]\w*)=([\s\S]*)$/;
|
|
19593
|
+
HERE = /^(?:\$PWD|\$\{PWD\}|\$\(\s*pwd\s*\)|`pwd`|\$\(\s*git\s+rev-parse\s+--show-toplevel\s*\))(?=$|[\\/])/;
|
|
19594
|
+
VARIABLE = /\$(?:\{(\w+)\}|(\w+))/g;
|
|
19595
|
+
XARGS_VALUES = new Set(["-n", "-L", "-l", "-P", "-d", "-E", "-e", "-s", "-a", "--arg-file", "--delimiter"].concat([
|
|
19596
|
+
"--max-args",
|
|
19597
|
+
"--max-lines",
|
|
19598
|
+
"--max-procs",
|
|
19599
|
+
"--eof",
|
|
19600
|
+
"--max-chars",
|
|
19601
|
+
"--process-slot-var"
|
|
19602
|
+
]));
|
|
19603
|
+
POWERSHELL_VALUES = /^-(?:f|file|ex|executionpolicy|wd|workingdirectory|config|configurationname|o|outputformat|if|inputformat|inp|w|windowstyle|settingsfile|custompipename|psconsolefile)$/;
|
|
19604
|
+
PARALLEL_VALUES = new Set(["-j", "--jobs", "-N", "-n", "-S", "--sshlogin", "-P", "--delay"]);
|
|
19605
|
+
START_PROCESS_VALUES = /^-(?:workingdirectory|wd|redirectstandard\w*|verb|windowstyle|credential|environment)$/i;
|
|
19606
|
+
CONFIG_READS = /^(?:--get\S*|-l|--list|--unset\S*|--remove-section|--rename-section|-e|--edit|--show-\S+|--name-only)$/;
|
|
19607
|
+
RECENT = new Map;
|
|
18622
19608
|
LAUNCHERS = new Set([
|
|
18623
19609
|
"npx",
|
|
18624
19610
|
"bunx",
|
|
@@ -18634,6 +19620,7 @@ var init_raw_git = __esm(() => {
|
|
|
18634
19620
|
]);
|
|
18635
19621
|
WORKIT_BIN = /(?:^|[\\/])workit(?:\.exe)?$|^@brainervirus\/workit-cli$/;
|
|
18636
19622
|
PUSH_VALUE_OPTIONS = new Set(["-o", "--push-option", "--receive-pack", "--exec", "--repo"]);
|
|
19623
|
+
CURRENT_BRANCH = /^\$\(\s*git\s+(?:branch\s+--show-current|rev-parse\s+--abbrev-ref\s+HEAD|symbolic-ref\s+--short\s+HEAD)\s*\)$/;
|
|
18637
19624
|
VALUE_OPTIONS = {
|
|
18638
19625
|
git: new Set([
|
|
18639
19626
|
"-m",
|
|
@@ -18661,24 +19648,56 @@ var init_raw_git = __esm(() => {
|
|
|
18661
19648
|
gh: new Set(["-b", "--body", "-F", "--body-file", "-t", "--title", "--subject", "-A", "--author-email"].concat(["-B", "--base", "-H", "--head", "-l", "--label", "-a", "--assignee"]).concat(["-r", "--reviewer", "-m", "--milestone", "-p", "--project", "-T", "--template"]).concat(["--match-head-commit", "-R", "--repo"])),
|
|
18662
19649
|
glab: new Set(["-m", "--message", "--squash-message", "--sha", "-t", "--title", "-d", "--description"].concat(["-b", "--target-branch", "-s", "--source-branch", "-l", "--label"]).concat(["-a", "--assignee", "--reviewer", "-R", "--repo"]))
|
|
18663
19650
|
};
|
|
19651
|
+
API_VALUES = new Set(["--method", "--header", "--raw-field", "--field", "--jq", "--template", "--input"].concat([
|
|
19652
|
+
"--hostname",
|
|
19653
|
+
"--preview",
|
|
19654
|
+
"--cache",
|
|
19655
|
+
"--output"
|
|
19656
|
+
]));
|
|
19657
|
+
API_FIELDS = new Set(["-f", "-F", "--raw-field", "--field"]);
|
|
19658
|
+
API_MERGE = {
|
|
19659
|
+
gh: /(?:^|\/)(?:pulls\/[^/?#]+\/merge|merges)\/?(?:[?#]|$)/i,
|
|
19660
|
+
glab: /(?:^|\/)merge_requests\/[^/?#]+\/merge\/?(?:[?#]|$)/i
|
|
19661
|
+
};
|
|
19662
|
+
GRAPHQL_MERGE = /\b(?:mergePullRequest|enablePullRequestAutoMerge|mergeBranch|mergeRequestAccept)\b/;
|
|
19663
|
+
GIT_COMMANDS = new Set(("add am annotate apply archive bisect blame branch bugreport bundle cat-file check-attr " + "check-ignore check-mailmap check-ref-format checkout checkout-index cherry cherry-pick " + "citool clean clone column commit commit-graph commit-tree config count-objects credential " + "daemon describe diagnose diff diff-files diff-index diff-tree difftool fast-export " + "fast-import fetch fetch-pack filter-branch fmt-merge-msg for-each-ref for-each-repo " + "format-patch fsck gc get-tar-commit-id grep gui hash-object help hook index-pack init " + "instaweb interpret-trailers lfs log ls-files ls-remote ls-tree mailinfo mailsplit " + "maintenance merge merge-base merge-file merge-index merge-tree mergetool mktag mktree " + "multi-pack-index mv name-rev notes pack-objects pack-refs patch-id prune pull push " + "range-diff read-tree rebase reflog remote repack replace request-pull rerere reset " + "restore rev-list rev-parse revert rm send-email shortlog show show-branch show-ref " + "sparse-checkout stage stash status stripspace submodule subtree switch symbolic-ref tag " + "update-index update-ref var verify-commit verify-pack verify-tag version whatchanged " + "worktree write-tree").split(" "));
|
|
19664
|
+
JUDGED_COMMANDS = [
|
|
19665
|
+
"push",
|
|
19666
|
+
"commit",
|
|
19667
|
+
"switch",
|
|
19668
|
+
"checkout",
|
|
19669
|
+
"branch",
|
|
19670
|
+
"worktree",
|
|
19671
|
+
"stash",
|
|
19672
|
+
"update-ref",
|
|
19673
|
+
"symbolic-ref",
|
|
19674
|
+
"fetch",
|
|
19675
|
+
"pull",
|
|
19676
|
+
"subtree"
|
|
19677
|
+
];
|
|
18664
19678
|
});
|
|
18665
19679
|
|
|
18666
19680
|
// packages/workit-core/src/core/route-intent.ts
|
|
18667
19681
|
import { spawnSync as spawnSync12 } from "node:child_process";
|
|
18668
19682
|
import { existsSync as existsSync6 } from "node:fs";
|
|
18669
19683
|
import path21 from "node:path";
|
|
18670
|
-
var UNKNOWABLE, SWITCH_CREATE, CHECKOUT_CREATE, WORKTREE_CREATE, BRANCH_NO_CREATE, BRANCH_RENAME, flagValue = (args, flags) => {
|
|
19684
|
+
var UNKNOWABLE, SWITCH_CREATE, CHECKOUT_CREATE, WORKTREE_CREATE, SUBTREE_CREATE, BRANCH_NO_CREATE, BRANCH_RENAME, longOption = (name, flags) => flags.has(name) || name.length >= 3 && [...flags].some((flag) => flag.startsWith("--") && flag.startsWith(name)), shortsOf = (flags) => [...flags].filter((flag) => /^-[^-]$/u.test(flag)).join("").replaceAll("-", ""), flagValue = (args, flags) => {
|
|
19685
|
+
const shorts = shortsOf(flags);
|
|
18671
19686
|
for (let index = 1;index < args.length; index++) {
|
|
18672
19687
|
const arg = args[index];
|
|
18673
19688
|
if (arg === "--")
|
|
18674
19689
|
return null;
|
|
18675
|
-
if (
|
|
18676
|
-
|
|
18677
|
-
|
|
18678
|
-
|
|
18679
|
-
return arg.slice(eq + 1);
|
|
18680
|
-
|
|
18681
|
-
|
|
19690
|
+
if (arg.startsWith("--")) {
|
|
19691
|
+
const eq = arg.indexOf("=");
|
|
19692
|
+
if (!longOption(eq > 0 ? arg.slice(0, eq) : arg, flags))
|
|
19693
|
+
continue;
|
|
19694
|
+
return eq > 0 ? arg.slice(eq + 1) : args[index + 1] ?? null;
|
|
19695
|
+
}
|
|
19696
|
+
if (!arg.startsWith("-") || arg.length < 2)
|
|
19697
|
+
continue;
|
|
19698
|
+
for (let at = 1;at < arg.length; at++)
|
|
19699
|
+
if (shorts.includes(arg[at]))
|
|
19700
|
+
return at + 1 < arg.length ? arg.slice(at + 1) : args[index + 1] ?? null;
|
|
18682
19701
|
}
|
|
18683
19702
|
return null;
|
|
18684
19703
|
}, WORKTREE_VALUES, worktreeTarget = (args) => {
|
|
@@ -18708,51 +19727,102 @@ var UNKNOWABLE, SWITCH_CREATE, CHECKOUT_CREATE, WORKTREE_CREATE, BRANCH_NO_CREAT
|
|
|
18708
19727
|
positionals.push(...args.slice(index + 1));
|
|
18709
19728
|
break;
|
|
18710
19729
|
}
|
|
18711
|
-
|
|
18712
|
-
|
|
18713
|
-
|
|
18714
|
-
|
|
18715
|
-
|
|
18716
|
-
|
|
19730
|
+
if (arg.startsWith("--")) {
|
|
19731
|
+
const flag = arg.split("=", 1)[0];
|
|
19732
|
+
if (longOption(flag, BRANCH_NO_CREATE))
|
|
19733
|
+
return null;
|
|
19734
|
+
if (longOption(flag, BRANCH_RENAME))
|
|
19735
|
+
rename = true;
|
|
19736
|
+
} else if (arg.startsWith("-") && arg.length > 1) {
|
|
19737
|
+
const shorts = arg.slice(1).split("");
|
|
19738
|
+
if (shorts.some((short) => BRANCH_NO_CREATE.has(`-${short}`)))
|
|
19739
|
+
return null;
|
|
19740
|
+
if (shorts.some((short) => BRANCH_RENAME.has(`-${short}`)))
|
|
19741
|
+
rename = true;
|
|
19742
|
+
} else
|
|
18717
19743
|
positionals.push(arg);
|
|
18718
19744
|
}
|
|
18719
19745
|
if (positionals.length < 1 || positionals.length > 2)
|
|
18720
19746
|
return null;
|
|
18721
19747
|
return rename ? positionals.at(-1) ?? null : positionals[0];
|
|
18722
|
-
},
|
|
18723
|
-
const [sub, second] = args;
|
|
18724
|
-
const target = sub === "switch" ? flagValue(args, SWITCH_CREATE) : sub === "checkout" ? flagValue(args, CHECKOUT_CREATE) : sub === "branch" ? branchCommandTarget(args) : sub === "worktree" && second === "add" ? worktreeTarget(args.slice(1)) : null;
|
|
18725
|
-
return target && !target.startsWith("-") && !UNKNOWABLE.test(target) ? target : null;
|
|
18726
|
-
}, shellBranchTargets = (command, dialect = "posix") => {
|
|
18727
|
-
if (!/\bgit\b/u.test(command))
|
|
18728
|
-
return [];
|
|
19748
|
+
}, positionalsOf = (args, skip, values = new Set) => {
|
|
18729
19749
|
const found = [];
|
|
18730
|
-
for (
|
|
18731
|
-
|
|
18732
|
-
|
|
18733
|
-
|
|
18734
|
-
if (
|
|
18735
|
-
|
|
19750
|
+
for (let index = skip;index < args.length; index++) {
|
|
19751
|
+
const arg = args[index];
|
|
19752
|
+
if (arg === "--")
|
|
19753
|
+
return [...found, ...args.slice(index + 1)];
|
|
19754
|
+
if (values.has(arg))
|
|
19755
|
+
index++;
|
|
19756
|
+
else if (!arg.startsWith("-") || arg === "-")
|
|
19757
|
+
found.push(arg);
|
|
18736
19758
|
}
|
|
18737
19759
|
return found;
|
|
18738
|
-
},
|
|
19760
|
+
}, localHead = (ref) => ref.startsWith("refs/heads/") ? ref.slice("refs/heads/".length) : null, updateRefTargets = (args, stdin) => {
|
|
19761
|
+
if (args.some((arg) => arg === "-d" || arg === "--delete"))
|
|
19762
|
+
return [];
|
|
19763
|
+
if (args.includes("--stdin"))
|
|
19764
|
+
return (stdin ?? "").split(/[\n\0]/u).map((line) => /^\s*(?:create|update)\s+(\S+)/u.exec(line)?.[1] ?? "").map(localHead).filter((name) => name !== null);
|
|
19765
|
+
const [ref] = positionalsOf(args, 1, new Set(["-m"]));
|
|
19766
|
+
const name = ref ? localHead(ref) : null;
|
|
19767
|
+
return name ? [name] : [];
|
|
19768
|
+
}, symbolicRefTarget = (args) => {
|
|
19769
|
+
if (args.some((arg) => arg === "-d" || arg === "--delete"))
|
|
19770
|
+
return null;
|
|
19771
|
+
const [, ref] = positionalsOf(args, 1, new Set(["-m"]));
|
|
19772
|
+
return ref ? localHead(ref) : null;
|
|
19773
|
+
}, FETCH_VALUES, fetchTargets = (args, stdin) => {
|
|
19774
|
+
if (args.includes("--all") || args.includes("--multiple"))
|
|
19775
|
+
return [];
|
|
19776
|
+
const specs = args.includes("--stdin") ? (stdin ?? "").split(/\s+/u).filter(Boolean) : positionalsOf(args, 1, FETCH_VALUES).slice(1);
|
|
19777
|
+
const names = [];
|
|
19778
|
+
for (const raw of specs) {
|
|
19779
|
+
const colon = raw.indexOf(":");
|
|
19780
|
+
const destination = colon >= 0 ? raw.slice(colon + 1) : "";
|
|
19781
|
+
if (!destination || destination.includes("*"))
|
|
19782
|
+
continue;
|
|
19783
|
+
const name = destination.startsWith("refs/") ? localHead(destination) : destination;
|
|
19784
|
+
if (name)
|
|
19785
|
+
names.push(name);
|
|
19786
|
+
}
|
|
19787
|
+
return names;
|
|
19788
|
+
}, localPushTargets = (args) => {
|
|
19789
|
+
const action = pushAction(args);
|
|
19790
|
+
if (action?.kind !== "push" || action.remote !== "." || action.deletes)
|
|
19791
|
+
return [];
|
|
19792
|
+
return action.targets.filter((name) => name !== null);
|
|
19793
|
+
}, gitBranchCreations = (args, stdin) => {
|
|
19794
|
+
const [sub, second] = args;
|
|
19795
|
+
const targets = sub === "switch" ? [flagValue(args, SWITCH_CREATE)] : sub === "checkout" ? [flagValue(args, CHECKOUT_CREATE)] : sub === "branch" ? [branchCommandTarget(args)] : sub === "worktree" && second === "add" ? [worktreeTarget(args.slice(1))] : sub === "stash" && second === "branch" ? positionalsOf(args, 2).slice(0, 1) : sub === "update-ref" ? updateRefTargets(args, stdin) : sub === "symbolic-ref" ? [symbolicRefTarget(args)] : sub === "fetch" || sub === "pull" ? fetchTargets(args, stdin) : sub === "push" ? localPushTargets(args) : sub === "subtree" && second === "split" ? [flagValue(args.slice(1), SUBTREE_CREATE)] : [];
|
|
19796
|
+
return targets.filter((target) => target !== null && target !== "" && !target.startsWith("-") && !UNKNOWABLE.test(target));
|
|
19797
|
+
}, targetsOf = (invocations) => invocations.flatMap((invocation) => invocation.tool === "git" ? gitBranchCreations(invocation.args, invocation.stdin).map((branch) => ({
|
|
19798
|
+
branch,
|
|
19799
|
+
dir: invocation.dir
|
|
19800
|
+
})) : []), localBranchExists = (dir, branch) => spawnSync12("git", ["show-ref", "--verify", "--quiet", `refs/heads/${branch}`], {
|
|
18739
19801
|
cwd: dir,
|
|
18740
19802
|
stdio: "ignore",
|
|
18741
19803
|
timeout: 5000
|
|
18742
|
-
}).status === 0,
|
|
19804
|
+
}).status === 0, judgedDir = (root, dir) => {
|
|
19805
|
+
if (dir === undefined)
|
|
19806
|
+
return null;
|
|
19807
|
+
if (dir === null)
|
|
19808
|
+
return root;
|
|
19809
|
+
const resolved = path21.resolve(root, dir);
|
|
19810
|
+
return existsSync6(resolved) && inWorkitWorkspace(resolved) ? resolved : null;
|
|
19811
|
+
}, shellBranchPolicyViolation = (root, command, dialect = "posix") => {
|
|
18743
19812
|
let judged = false;
|
|
18744
|
-
|
|
18745
|
-
|
|
19813
|
+
const cache = new Map;
|
|
19814
|
+
for (const raw of rawInvocations(command, dialect)) {
|
|
19815
|
+
if (raw.tool !== "git" || judgedDir(root, raw.dir) === null)
|
|
18746
19816
|
continue;
|
|
18747
|
-
const
|
|
18748
|
-
|
|
18749
|
-
|
|
18750
|
-
|
|
18751
|
-
|
|
18752
|
-
|
|
18753
|
-
|
|
18754
|
-
|
|
18755
|
-
|
|
19817
|
+
for (const target of targetsOf(expandGitAliases(root, raw, cache))) {
|
|
19818
|
+
const dir = judgedDir(root, target.dir);
|
|
19819
|
+
if (dir === null || localBranchExists(dir, target.branch))
|
|
19820
|
+
continue;
|
|
19821
|
+
judged = true;
|
|
19822
|
+
const check = validateBranchNameFor(dir, target.branch);
|
|
19823
|
+
if (!check.ok)
|
|
19824
|
+
return check;
|
|
19825
|
+
}
|
|
18756
19826
|
}
|
|
18757
19827
|
return judged ? { ok: true } : null;
|
|
18758
19828
|
};
|
|
@@ -18763,18 +19833,29 @@ var init_route_intent = __esm(() => {
|
|
|
18763
19833
|
SWITCH_CREATE = new Set(["-c", "--create", "-C", "--force-create", "--orphan"]);
|
|
18764
19834
|
CHECKOUT_CREATE = new Set(["-b", "-B", "--orphan"]);
|
|
18765
19835
|
WORKTREE_CREATE = new Set(["-b", "-B"]);
|
|
19836
|
+
SUBTREE_CREATE = new Set(["-b", "--branch"]);
|
|
18766
19837
|
BRANCH_NO_CREATE = new Set(["-d", "-D", "--delete", "-l", "--list", "-a", "--all", "-r", "--remotes", "--show-current"].concat(["-v", "-vv", "--verbose", "--contains", "--no-contains", "--merged", "--no-merged"]).concat(["--points-at", "--sort", "--format", "--column", "--no-column", "-u"]).concat(["--set-upstream-to", "--unset-upstream", "--edit-description", "-i", "--ignore-case"]));
|
|
18767
19838
|
BRANCH_RENAME = new Set(["-m", "-M", "--move", "-c", "-C", "--copy"]);
|
|
18768
19839
|
WORKTREE_VALUES = new Set(["--reason"]);
|
|
19840
|
+
FETCH_VALUES = new Set(["--depth", "--deepen", "--shallow-since", "--shallow-exclude", "--refmap", "-j", "--jobs"].concat(["--upload-pack", "-o", "--server-option", "--negotiation-tip", "--filter"]).concat(["--recurse-submodules-default", "--submodule-prefix", "-s", "--strategy", "-X"]).concat(["--strategy-option"]));
|
|
18769
19841
|
});
|
|
18770
19842
|
|
|
18771
19843
|
// packages/workit-core/src/hooks/policy.ts
|
|
18772
19844
|
var shellPolicy = (cwd, command, dialect = "posix") => {
|
|
18773
|
-
|
|
19845
|
+
let policy;
|
|
19846
|
+
try {
|
|
19847
|
+
policy = shellBranchPolicyViolation(cwd, command, dialect);
|
|
19848
|
+
} catch (error) {
|
|
19849
|
+
if (error instanceof ShellAnalysisError)
|
|
19850
|
+
return analysisDenial(error);
|
|
19851
|
+
throw error;
|
|
19852
|
+
}
|
|
18774
19853
|
return policy && !policy.ok ? { kind: "deny", reason: `branch_policy_denied: ${policy.error}`, unblock: null } : { kind: "none" };
|
|
18775
19854
|
};
|
|
18776
19855
|
var init_policy = __esm(() => {
|
|
18777
19856
|
init_route_intent();
|
|
19857
|
+
init_raw_git();
|
|
19858
|
+
init_shell_words();
|
|
18778
19859
|
});
|
|
18779
19860
|
|
|
18780
19861
|
// packages/workit-core/src/hooks/write-gate.ts
|
|
@@ -18816,9 +19897,9 @@ var NONE3, CASE_INSENSITIVE, canonical2 = (file) => {
|
|
|
18816
19897
|
const posix = relative.split(path22.sep).join("/");
|
|
18817
19898
|
const segments = posix.split("/");
|
|
18818
19899
|
return /\.mdx?$/i.test(posix) || segments[0] === "docs" || segments.includes("plans") || [...plans].some((plan) => fold(plan) === posix);
|
|
18819
|
-
},
|
|
19900
|
+
}, PREFIXES2, operands = (words) => words.filter((item) => !item.startsWith("-")), editsOf = (input) => {
|
|
18820
19901
|
let words = input;
|
|
18821
|
-
while (words.length && (
|
|
19902
|
+
while (words.length && (PREFIXES2.has(words[0]) || /^\w+=/.test(words[0])))
|
|
18822
19903
|
words = words.slice(1);
|
|
18823
19904
|
const [verb, ...args] = words;
|
|
18824
19905
|
const name = (verb?.split(/[\\/]/).at(-1) ?? "").toLowerCase();
|
|
@@ -18947,9 +20028,10 @@ var init_write_gate = __esm(() => {
|
|
|
18947
20028
|
init_derive();
|
|
18948
20029
|
init_task_evaluation();
|
|
18949
20030
|
init_ledger();
|
|
20031
|
+
init_shell_words();
|
|
18950
20032
|
NONE3 = { kind: "none" };
|
|
18951
20033
|
CASE_INSENSITIVE = process.platform === "darwin" || process.platform === "win32";
|
|
18952
|
-
|
|
20034
|
+
PREFIXES2 = new Set(["sudo", "command", "env", "nohup", "time", "exec", "xargs"]);
|
|
18953
20035
|
cache2 = new Map;
|
|
18954
20036
|
});
|
|
18955
20037
|
|
|
@@ -19265,6 +20347,7 @@ var init_skill_nudge = __esm(() => {
|
|
|
19265
20347
|
init_ledger();
|
|
19266
20348
|
init_raw_git();
|
|
19267
20349
|
init_session_marker();
|
|
20350
|
+
init_shell_words();
|
|
19268
20351
|
USER_INVOKED = new Set(["workit-retro", "workit-architecture"]);
|
|
19269
20352
|
SKILL_HOST = {
|
|
19270
20353
|
claude_code: "claude-code",
|
|
@@ -20243,7 +21326,7 @@ var init_cursor = __esm(() => {
|
|
|
20243
21326
|
"compact.pre": { support: "partial", native: "preCompact" },
|
|
20244
21327
|
stop: { support: "native", native: "stop" }
|
|
20245
21328
|
},
|
|
20246
|
-
shellPolicy: { deny: "native", channel: "exit2+json", failClosed:
|
|
21329
|
+
shellPolicy: { deny: "native", channel: "exit2+json", failClosed: false },
|
|
20247
21330
|
context: {
|
|
20248
21331
|
sessionStart: "native",
|
|
20249
21332
|
perTurn: "none",
|