@linzumi/cli 0.0.51-beta → 0.0.53-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -1
- package/dist/index.js +643 -352
- package/package.json +4 -2
- package/scripts/codex_history_table.mjs +628 -0
package/dist/index.js
CHANGED
|
@@ -4,21 +4,35 @@ var __getProtoOf = Object.getPrototypeOf;
|
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
function __accessProp(key) {
|
|
8
|
+
return this[key];
|
|
9
|
+
}
|
|
10
|
+
var __toESMCache_node;
|
|
11
|
+
var __toESMCache_esm;
|
|
7
12
|
var __toESM = (mod, isNodeMode, target) => {
|
|
13
|
+
var canCache = mod != null && typeof mod === "object";
|
|
14
|
+
if (canCache) {
|
|
15
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
16
|
+
var cached = cache.get(mod);
|
|
17
|
+
if (cached)
|
|
18
|
+
return cached;
|
|
19
|
+
}
|
|
8
20
|
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
21
|
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
22
|
for (let key of __getOwnPropNames(mod))
|
|
11
23
|
if (!__hasOwnProp.call(to, key))
|
|
12
24
|
__defProp(to, key, {
|
|
13
|
-
get: (
|
|
25
|
+
get: __accessProp.bind(mod, key),
|
|
14
26
|
enumerable: true
|
|
15
27
|
});
|
|
28
|
+
if (canCache)
|
|
29
|
+
cache.set(mod, to);
|
|
16
30
|
return to;
|
|
17
31
|
};
|
|
18
32
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
19
33
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
20
34
|
|
|
21
|
-
//
|
|
35
|
+
// node_modules/yoctocolors-cjs/index.js
|
|
22
36
|
var require_yoctocolors_cjs = __commonJS((exports, module) => {
|
|
23
37
|
var tty = __require("node:tty");
|
|
24
38
|
var hasColors = tty?.WriteStream?.prototype?.hasColors?.() ?? false;
|
|
@@ -92,7 +106,7 @@ var require_yoctocolors_cjs = __commonJS((exports, module) => {
|
|
|
92
106
|
module.exports = colors;
|
|
93
107
|
});
|
|
94
108
|
|
|
95
|
-
//
|
|
109
|
+
// node_modules/cli-width/index.js
|
|
96
110
|
var require_cli_width = __commonJS((exports, module) => {
|
|
97
111
|
module.exports = cliWidth;
|
|
98
112
|
function normalizeOpts(options) {
|
|
@@ -132,7 +146,7 @@ var require_cli_width = __commonJS((exports, module) => {
|
|
|
132
146
|
}
|
|
133
147
|
});
|
|
134
148
|
|
|
135
|
-
//
|
|
149
|
+
// node_modules/ansi-regex/index.js
|
|
136
150
|
var require_ansi_regex = __commonJS((exports, module) => {
|
|
137
151
|
module.exports = ({ onlyFirst = false } = {}) => {
|
|
138
152
|
const pattern = [
|
|
@@ -143,13 +157,13 @@ var require_ansi_regex = __commonJS((exports, module) => {
|
|
|
143
157
|
};
|
|
144
158
|
});
|
|
145
159
|
|
|
146
|
-
//
|
|
160
|
+
// node_modules/strip-ansi/index.js
|
|
147
161
|
var require_strip_ansi = __commonJS((exports, module) => {
|
|
148
162
|
var ansiRegex = require_ansi_regex();
|
|
149
163
|
module.exports = (string) => typeof string === "string" ? string.replace(ansiRegex(), "") : string;
|
|
150
164
|
});
|
|
151
165
|
|
|
152
|
-
//
|
|
166
|
+
// node_modules/is-fullwidth-code-point/index.js
|
|
153
167
|
var require_is_fullwidth_code_point = __commonJS((exports, module) => {
|
|
154
168
|
var isFullwidthCodePoint = (codePoint) => {
|
|
155
169
|
if (Number.isNaN(codePoint)) {
|
|
@@ -164,14 +178,14 @@ var require_is_fullwidth_code_point = __commonJS((exports, module) => {
|
|
|
164
178
|
module.exports.default = isFullwidthCodePoint;
|
|
165
179
|
});
|
|
166
180
|
|
|
167
|
-
//
|
|
181
|
+
// node_modules/emoji-regex/index.js
|
|
168
182
|
var require_emoji_regex = __commonJS((exports, module) => {
|
|
169
183
|
module.exports = function() {
|
|
170
184
|
return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F|\uD83D\uDC68(?:\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68\uD83C\uDFFB|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|[\u2695\u2696\u2708]\uFE0F|\uD83D[\uDC66\uDC67]|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708])\uFE0F|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C[\uDFFB-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)\uD83C\uDFFB|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB\uDFFC])|\uD83D\uDC69(?:\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB-\uDFFD])|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|(?:(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)\uFE0F|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\u200D[\u2640\u2642])|\uD83C\uDFF4\u200D\u2620)\uFE0F|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF4\uD83C\uDDF2|\uD83C\uDDF6\uD83C\uDDE6|[#\*0-9]\uFE0F\u20E3|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83D\uDC69(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270A-\u270D]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC70\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDCAA\uDD74\uDD7A\uDD90\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD36\uDDB5\uDDB6\uDDBB\uDDD2-\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5\uDEEB\uDEEC\uDEF4-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g;
|
|
171
185
|
};
|
|
172
186
|
});
|
|
173
187
|
|
|
174
|
-
//
|
|
188
|
+
// node_modules/string-width/index.js
|
|
175
189
|
var require_string_width = __commonJS((exports, module) => {
|
|
176
190
|
var stripAnsi = require_strip_ansi();
|
|
177
191
|
var isFullwidthCodePoint = require_is_fullwidth_code_point();
|
|
@@ -205,7 +219,7 @@ var require_string_width = __commonJS((exports, module) => {
|
|
|
205
219
|
module.exports.default = stringWidth;
|
|
206
220
|
});
|
|
207
221
|
|
|
208
|
-
//
|
|
222
|
+
// node_modules/color-name/index.js
|
|
209
223
|
var require_color_name = __commonJS((exports, module) => {
|
|
210
224
|
module.exports = {
|
|
211
225
|
aliceblue: [240, 248, 255],
|
|
@@ -359,7 +373,7 @@ var require_color_name = __commonJS((exports, module) => {
|
|
|
359
373
|
};
|
|
360
374
|
});
|
|
361
375
|
|
|
362
|
-
//
|
|
376
|
+
// node_modules/color-convert/conversions.js
|
|
363
377
|
var require_conversions = __commonJS((exports, module) => {
|
|
364
378
|
var cssKeywords = require_color_name();
|
|
365
379
|
var reverseKeywords = {};
|
|
@@ -1028,7 +1042,7 @@ var require_conversions = __commonJS((exports, module) => {
|
|
|
1028
1042
|
};
|
|
1029
1043
|
});
|
|
1030
1044
|
|
|
1031
|
-
//
|
|
1045
|
+
// node_modules/color-convert/route.js
|
|
1032
1046
|
var require_route = __commonJS((exports, module) => {
|
|
1033
1047
|
var conversions = require_conversions();
|
|
1034
1048
|
function buildGraph() {
|
|
@@ -1094,7 +1108,7 @@ var require_route = __commonJS((exports, module) => {
|
|
|
1094
1108
|
};
|
|
1095
1109
|
});
|
|
1096
1110
|
|
|
1097
|
-
//
|
|
1111
|
+
// node_modules/color-convert/index.js
|
|
1098
1112
|
var require_color_convert = __commonJS((exports, module) => {
|
|
1099
1113
|
var conversions = require_conversions();
|
|
1100
1114
|
var route = require_route();
|
|
@@ -1153,7 +1167,7 @@ var require_color_convert = __commonJS((exports, module) => {
|
|
|
1153
1167
|
module.exports = convert;
|
|
1154
1168
|
});
|
|
1155
1169
|
|
|
1156
|
-
//
|
|
1170
|
+
// node_modules/ansi-styles/index.js
|
|
1157
1171
|
var require_ansi_styles = __commonJS((exports, module) => {
|
|
1158
1172
|
var wrapAnsi16 = (fn, offset) => (...args) => {
|
|
1159
1173
|
const code = fn(...args);
|
|
@@ -1289,7 +1303,7 @@ var require_ansi_styles = __commonJS((exports, module) => {
|
|
|
1289
1303
|
});
|
|
1290
1304
|
});
|
|
1291
1305
|
|
|
1292
|
-
//
|
|
1306
|
+
// node_modules/wrap-ansi/index.js
|
|
1293
1307
|
var require_wrap_ansi = __commonJS((exports, module) => {
|
|
1294
1308
|
var stringWidth = require_string_width();
|
|
1295
1309
|
var stripAnsi = require_strip_ansi();
|
|
@@ -1425,7 +1439,7 @@ var require_wrap_ansi = __commonJS((exports, module) => {
|
|
|
1425
1439
|
};
|
|
1426
1440
|
});
|
|
1427
1441
|
|
|
1428
|
-
//
|
|
1442
|
+
// node_modules/mute-stream/lib/index.js
|
|
1429
1443
|
var require_lib = __commonJS((exports, module) => {
|
|
1430
1444
|
var Stream = __require("stream");
|
|
1431
1445
|
|
|
@@ -1757,6 +1771,7 @@ function localRunnerPayload(options, instanceId, eventType, codexThreadId, conte
|
|
|
1757
1771
|
fast: options.fast ?? false,
|
|
1758
1772
|
sandbox: options.channelSession?.sandbox ?? null,
|
|
1759
1773
|
approval_policy: options.channelSession?.approvalPolicy ?? null,
|
|
1774
|
+
allow_port_forwarding_by_default: options.channelSession?.allowPortForwardingByDefault ?? null,
|
|
1760
1775
|
user_id: context.runnerIdentity.actorUserId ?? null,
|
|
1761
1776
|
...sourceMessageSeq === undefined ? {} : { source_message_seq: sourceMessageSeq }
|
|
1762
1777
|
}
|
|
@@ -3362,8 +3377,17 @@ function reviewPortForwardCandidate(options) {
|
|
|
3362
3377
|
reason: "listener_changed"
|
|
3363
3378
|
};
|
|
3364
3379
|
}
|
|
3365
|
-
|
|
3366
|
-
|
|
3380
|
+
const pendingRequest = options.pendingRequests.find((request) => request.port === options.candidate.port);
|
|
3381
|
+
if (pendingRequest !== undefined) {
|
|
3382
|
+
if (sameForwardCandidate(approvedTargetFromRequest(pendingRequest), options.candidate)) {
|
|
3383
|
+
return { type: "skip", reason: "already_pending" };
|
|
3384
|
+
}
|
|
3385
|
+
return {
|
|
3386
|
+
type: "replace_pending",
|
|
3387
|
+
expired: pendingRequest,
|
|
3388
|
+
candidate: options.candidate,
|
|
3389
|
+
reason: "listener_changed"
|
|
3390
|
+
};
|
|
3367
3391
|
}
|
|
3368
3392
|
return { type: "prompt", candidate: options.candidate };
|
|
3369
3393
|
}
|
|
@@ -4319,7 +4343,7 @@ async function bindChannelSession(args, state, payloadContext) {
|
|
|
4319
4343
|
}
|
|
4320
4344
|
async function handleChannelSessionControl(args, state, payloadContext, control) {
|
|
4321
4345
|
if (control.type === "update_session_settings") {
|
|
4322
|
-
return updateSessionSettings(args, state, control);
|
|
4346
|
+
return updateSessionSettings(args, state, payloadContext, control);
|
|
4323
4347
|
}
|
|
4324
4348
|
if (control.type === "resolve_codex_approval_request") {
|
|
4325
4349
|
return resolvePendingCodexApprovalRequest(args, state, control);
|
|
@@ -4386,7 +4410,7 @@ async function handleChannelSessionControl(args, state, payloadContext, control)
|
|
|
4386
4410
|
interruptedQueuedMessages: interrupted.ok ? interrupted.selectedCount : 0
|
|
4387
4411
|
};
|
|
4388
4412
|
}
|
|
4389
|
-
async function updateSessionSettings(args, state, control) {
|
|
4413
|
+
async function updateSessionSettings(args, state, payloadContext, control) {
|
|
4390
4414
|
if (state.codexThreadId !== control.threadId) {
|
|
4391
4415
|
return;
|
|
4392
4416
|
}
|
|
@@ -4410,8 +4434,12 @@ async function updateSessionSettings(args, state, control) {
|
|
|
4410
4434
|
reasoning_effort: state.runtimeSettings.reasoningEffort ?? null,
|
|
4411
4435
|
approval_policy: state.runtimeSettings.approvalPolicy ?? null,
|
|
4412
4436
|
sandbox: state.runtimeSettings.sandbox ?? null,
|
|
4413
|
-
fast: state.runtimeSettings.fast ?? null
|
|
4437
|
+
fast: state.runtimeSettings.fast ?? null,
|
|
4438
|
+
allow_port_forwarding_by_default: state.runtimeSettings.allowPortForwardingByDefault ?? null
|
|
4414
4439
|
});
|
|
4440
|
+
if (state.runtimeSettings.allowPortForwardingByDefault === true) {
|
|
4441
|
+
await approvePendingPortForwardRequestsByDefault(args, state, payloadContext);
|
|
4442
|
+
}
|
|
4415
4443
|
await tryResumeCodexThreadForPendingRuntimeSettings(args, state);
|
|
4416
4444
|
return {
|
|
4417
4445
|
instanceId: args.instanceId,
|
|
@@ -4420,7 +4448,8 @@ async function updateSessionSettings(args, state, control) {
|
|
|
4420
4448
|
reasoningEffort: state.runtimeSettings.reasoningEffort ?? null,
|
|
4421
4449
|
approvalPolicy: state.runtimeSettings.approvalPolicy ?? null,
|
|
4422
4450
|
sandbox: state.runtimeSettings.sandbox ?? null,
|
|
4423
|
-
fast: state.runtimeSettings.fast ?? null
|
|
4451
|
+
fast: state.runtimeSettings.fast ?? null,
|
|
4452
|
+
allowPortForwardingByDefault: state.runtimeSettings.allowPortForwardingByDefault ?? null
|
|
4424
4453
|
};
|
|
4425
4454
|
}
|
|
4426
4455
|
async function resumeCodexThreadForPendingRuntimeSettings(args, state) {
|
|
@@ -4570,6 +4599,29 @@ async function resolvePendingPortForwardRequest(args, state, payloadContext, con
|
|
|
4570
4599
|
await drainQueuedPortForwardPrompt(args, state, payloadContext);
|
|
4571
4600
|
return { instanceId: args.instanceId, ok: true };
|
|
4572
4601
|
}
|
|
4602
|
+
await approvePortForwardRequest(args, state, payloadContext, request, {
|
|
4603
|
+
publishMessageState: true,
|
|
4604
|
+
logEvent: "port_forward.request_approved"
|
|
4605
|
+
});
|
|
4606
|
+
await drainQueuedPortForwardPrompt(args, state, payloadContext);
|
|
4607
|
+
return { instanceId: args.instanceId, ok: true, port: request.port };
|
|
4608
|
+
}
|
|
4609
|
+
async function expirePendingPortForwardRequest(args, state, request, reason) {
|
|
4610
|
+
const failedReason = reason === "listener_exited" ? "port_forward_listener_exited" : "port_forward_listener_changed";
|
|
4611
|
+
state.pendingPortForwardRequests.delete(request.requestId);
|
|
4612
|
+
await publishForwardPortResolvedEvent(args, request, {
|
|
4613
|
+
decision: "expired",
|
|
4614
|
+
reason
|
|
4615
|
+
});
|
|
4616
|
+
await publishMessageStateForPortForwardResult(args, state, request, "failed", failedReason);
|
|
4617
|
+
args.log("port_forward.pending_request_expired", {
|
|
4618
|
+
request_id: request.requestId,
|
|
4619
|
+
port: request.port,
|
|
4620
|
+
pid: request.pid,
|
|
4621
|
+
reason
|
|
4622
|
+
});
|
|
4623
|
+
}
|
|
4624
|
+
async function approvePortForwardRequest(args, state, payloadContext, request, options) {
|
|
4573
4625
|
state.approvedForwardPorts.add(request.port);
|
|
4574
4626
|
state.approvedForwardTargets.set(request.port, approvedTargetFromRequest(request));
|
|
4575
4627
|
const processIdentity = guessCanonicalProcessFromCommand(request.command);
|
|
@@ -4584,15 +4636,15 @@ async function resolvePendingPortForwardRequest(args, state, payloadContext, con
|
|
|
4584
4636
|
decision: "approve",
|
|
4585
4637
|
capabilities
|
|
4586
4638
|
});
|
|
4587
|
-
|
|
4639
|
+
if (options.publishMessageState) {
|
|
4640
|
+
await publishMessageStateForPortForwardResult(args, state, request, "processed");
|
|
4641
|
+
}
|
|
4588
4642
|
await publishPortForwardReadyMessage(args, state, payloadContext, request);
|
|
4589
|
-
args.log(
|
|
4590
|
-
request_id:
|
|
4643
|
+
args.log(options.logEvent, {
|
|
4644
|
+
request_id: request.requestId,
|
|
4591
4645
|
port: request.port,
|
|
4592
4646
|
pid: request.pid
|
|
4593
4647
|
});
|
|
4594
|
-
await drainQueuedPortForwardPrompt(args, state, payloadContext);
|
|
4595
|
-
return { instanceId: args.instanceId, ok: true, port: request.port };
|
|
4596
4648
|
}
|
|
4597
4649
|
function portForwardControlSenderAllowed(args, payloadContext, control) {
|
|
4598
4650
|
if (control.actorSlug === undefined && control.actorUserId === undefined) {
|
|
@@ -4621,6 +4673,7 @@ async function publishPortForwardPrompt(args, state, payloadContext, candidate)
|
|
|
4621
4673
|
dismissedTargets: state.dismissedForwardTargets,
|
|
4622
4674
|
pendingRequests: Array.from(state.pendingPortForwardRequests.values())
|
|
4623
4675
|
});
|
|
4676
|
+
const allowByDefault = state.runtimeSettings.allowPortForwardingByDefault === true;
|
|
4624
4677
|
switch (review.type) {
|
|
4625
4678
|
case "skip":
|
|
4626
4679
|
return;
|
|
@@ -4628,7 +4681,7 @@ async function publishPortForwardPrompt(args, state, payloadContext, candidate)
|
|
|
4628
4681
|
state.approvedForwardTargets.set(review.target.port, review.target);
|
|
4629
4682
|
return;
|
|
4630
4683
|
case "revoke_and_prompt":
|
|
4631
|
-
if (state.pendingPortForwardRequests.size > 0) {
|
|
4684
|
+
if (state.pendingPortForwardRequests.size > 0 && !allowByDefault) {
|
|
4632
4685
|
state.queuedPortForwardCandidates.set(candidate.port, candidate);
|
|
4633
4686
|
args.log("port_forward.request_queued", {
|
|
4634
4687
|
port: candidate.port,
|
|
@@ -4638,8 +4691,32 @@ async function publishPortForwardPrompt(args, state, payloadContext, candidate)
|
|
|
4638
4691
|
return;
|
|
4639
4692
|
}
|
|
4640
4693
|
await revokeApprovedForwardPort(args, state, review.revoked, review.reason);
|
|
4694
|
+
if (allowByDefault) {
|
|
4695
|
+
await autoApprovePortForwardCandidate(args, state, payloadContext, candidate);
|
|
4696
|
+
return;
|
|
4697
|
+
}
|
|
4698
|
+
break;
|
|
4699
|
+
case "replace_pending":
|
|
4700
|
+
await expirePendingPortForwardRequest(args, state, review.expired, review.reason);
|
|
4701
|
+
if (allowByDefault) {
|
|
4702
|
+
await autoApprovePortForwardCandidate(args, state, payloadContext, review.candidate);
|
|
4703
|
+
return;
|
|
4704
|
+
}
|
|
4705
|
+
if (state.pendingPortForwardRequests.size > 0) {
|
|
4706
|
+
state.queuedPortForwardCandidates.set(review.candidate.port, review.candidate);
|
|
4707
|
+
args.log("port_forward.request_queued", {
|
|
4708
|
+
port: review.candidate.port,
|
|
4709
|
+
pid: review.candidate.pid,
|
|
4710
|
+
pending_count: state.pendingPortForwardRequests.size
|
|
4711
|
+
});
|
|
4712
|
+
return;
|
|
4713
|
+
}
|
|
4641
4714
|
break;
|
|
4642
4715
|
case "prompt":
|
|
4716
|
+
if (allowByDefault) {
|
|
4717
|
+
await autoApprovePortForwardCandidate(args, state, payloadContext, candidate);
|
|
4718
|
+
return;
|
|
4719
|
+
}
|
|
4643
4720
|
if (state.pendingPortForwardRequests.size > 0) {
|
|
4644
4721
|
state.queuedPortForwardCandidates.set(candidate.port, candidate);
|
|
4645
4722
|
args.log("port_forward.request_queued", {
|
|
@@ -4717,6 +4794,45 @@ async function publishPortForwardPrompt(args, state, payloadContext, candidate)
|
|
|
4717
4794
|
pid: candidate.pid
|
|
4718
4795
|
});
|
|
4719
4796
|
}
|
|
4797
|
+
async function autoApprovePortForwardCandidate(args, state, payloadContext, candidate) {
|
|
4798
|
+
const sourceSeq = portForwardApprovalSourceSeq(state);
|
|
4799
|
+
if (sourceSeq === undefined) {
|
|
4800
|
+
args.log("port_forward.auto_approval_skipped", {
|
|
4801
|
+
port: candidate.port,
|
|
4802
|
+
pid: candidate.pid,
|
|
4803
|
+
reason: "source_seq_missing"
|
|
4804
|
+
});
|
|
4805
|
+
return;
|
|
4806
|
+
}
|
|
4807
|
+
const request = pendingRequestFromCandidate({
|
|
4808
|
+
requestId: `port-forward-auto-${randomUUID()}`,
|
|
4809
|
+
sourceSeq,
|
|
4810
|
+
candidate
|
|
4811
|
+
});
|
|
4812
|
+
await approvePortForwardRequest(args, state, payloadContext, request, {
|
|
4813
|
+
publishMessageState: false,
|
|
4814
|
+
logEvent: "port_forward.request_auto_approved"
|
|
4815
|
+
});
|
|
4816
|
+
}
|
|
4817
|
+
async function approvePendingPortForwardRequestsByDefault(args, state, payloadContext) {
|
|
4818
|
+
for (const request of Array.from(state.pendingPortForwardRequests.values())) {
|
|
4819
|
+
state.pendingPortForwardRequests.delete(request.requestId);
|
|
4820
|
+
await approvePortForwardRequest(args, state, payloadContext, request, {
|
|
4821
|
+
publishMessageState: true,
|
|
4822
|
+
logEvent: "port_forward.request_auto_approved"
|
|
4823
|
+
});
|
|
4824
|
+
}
|
|
4825
|
+
await drainQueuedPortForwardPromptsByDefault(args, state, payloadContext);
|
|
4826
|
+
}
|
|
4827
|
+
async function drainQueuedPortForwardPromptsByDefault(args, state, payloadContext) {
|
|
4828
|
+
const next = Array.from(state.queuedPortForwardCandidates.values()).sort((left, right) => left.port - right.port)[0];
|
|
4829
|
+
if (next === undefined) {
|
|
4830
|
+
return;
|
|
4831
|
+
}
|
|
4832
|
+
state.queuedPortForwardCandidates.delete(next.port);
|
|
4833
|
+
await publishPortForwardPrompt(args, state, payloadContext, next);
|
|
4834
|
+
await drainQueuedPortForwardPromptsByDefault(args, state, payloadContext);
|
|
4835
|
+
}
|
|
4720
4836
|
function portForwardApprovalSourceSeq(state) {
|
|
4721
4837
|
return state.activeProcessingState?.seq ?? state.rootSeq;
|
|
4722
4838
|
}
|
|
@@ -4750,18 +4866,7 @@ async function expireLostPendingPortForwardRequest(args, state, payloadContext,
|
|
|
4750
4866
|
if (request === undefined) {
|
|
4751
4867
|
return;
|
|
4752
4868
|
}
|
|
4753
|
-
state
|
|
4754
|
-
await publishForwardPortResolvedEvent(args, request, {
|
|
4755
|
-
decision: "expired",
|
|
4756
|
-
reason: "listener_exited"
|
|
4757
|
-
});
|
|
4758
|
-
await publishMessageStateForPortForwardResult(args, state, request, "failed", "port_forward_listener_exited");
|
|
4759
|
-
args.log("port_forward.pending_request_expired", {
|
|
4760
|
-
request_id: request.requestId,
|
|
4761
|
-
port: request.port,
|
|
4762
|
-
pid: request.pid,
|
|
4763
|
-
reason: "listener_exited"
|
|
4764
|
-
});
|
|
4869
|
+
await expirePendingPortForwardRequest(args, state, request, "listener_exited");
|
|
4765
4870
|
await drainQueuedPortForwardPrompt(args, state, payloadContext);
|
|
4766
4871
|
}
|
|
4767
4872
|
async function publishPortForwardReadyMessage(args, state, payloadContext, request) {
|
|
@@ -4995,10 +5100,6 @@ async function handleKandanChatEvent(args, state, runnerIdentity, payloadContext
|
|
|
4995
5100
|
actor_user_id: event.actorUserId ?? null,
|
|
4996
5101
|
reason: "different_thread"
|
|
4997
5102
|
});
|
|
4998
|
-
await publishKandanMessageState(args, event, {
|
|
4999
|
-
status: "ignored",
|
|
5000
|
-
reason: "different_thread"
|
|
5001
|
-
});
|
|
5002
5103
|
return;
|
|
5003
5104
|
}
|
|
5004
5105
|
if (!claimKandanMessage(args, state, event)) {
|
|
@@ -5416,48 +5517,15 @@ async function forwardCompletedCodexTurn(args, state, turnId, payloadContext) {
|
|
|
5416
5517
|
if (completingLocalTuiTurn && sourceMessageSeqForTurn(state, turnId) === undefined) {
|
|
5417
5518
|
throw new LogicalProjectionError(`Cannot forward Codex output for local TUI turn ${turnId} before mirroring its human input`);
|
|
5418
5519
|
}
|
|
5419
|
-
|
|
5420
|
-
|
|
5421
|
-
|
|
5422
|
-
|
|
5423
|
-
|
|
5424
|
-
|
|
5425
|
-
|
|
5426
|
-
|
|
5427
|
-
|
|
5428
|
-
item_key: message.itemKey,
|
|
5429
|
-
structured_kind: stringValue(message.structured.kind) ?? null,
|
|
5430
|
-
command: stringValue(message.structured.command) ?? null,
|
|
5431
|
-
file_paths: fileChangePaths(message.structured)
|
|
5432
|
-
});
|
|
5433
|
-
continue;
|
|
5434
|
-
}
|
|
5435
|
-
if (stringValue(message.structured.kind) === "codex_terminal_input" && state.forwardedTerminalInputKeys.has(message.itemKey)) {
|
|
5436
|
-
continue;
|
|
5437
|
-
}
|
|
5438
|
-
const streamed = resolveStreamingAssistantOutputForCompletedMessage(state, turnId, message.itemKey, message.body, message.structured);
|
|
5439
|
-
switch (streamed.status) {
|
|
5440
|
-
case "none":
|
|
5441
|
-
await streamCompletedCodexOutput(args, state, payloadContext, {
|
|
5442
|
-
turnId,
|
|
5443
|
-
sourceMessageSeq,
|
|
5444
|
-
rootSeq,
|
|
5445
|
-
message
|
|
5446
|
-
});
|
|
5447
|
-
break;
|
|
5448
|
-
case "matched":
|
|
5449
|
-
await editStreamedCodexOutput(args, state, streamed.output.seq, message.itemKey, message.body, "completed");
|
|
5450
|
-
forgetStreamingAssistantOutput(state, streamed.output.itemKey);
|
|
5451
|
-
break;
|
|
5452
|
-
case "ambiguous":
|
|
5453
|
-
throw new LogicalProjectionError(`Cannot reconcile completed assistant item ${message.itemKey} for turn ${turnId}; ${streamed.candidateCount} active streamed assistant outputs exist`);
|
|
5454
|
-
}
|
|
5455
|
-
args.log("kandan.codex_output_forwarded", {
|
|
5456
|
-
turn_id: turnId,
|
|
5457
|
-
item_key: message.itemKey,
|
|
5458
|
-
structured_kind: stringValue(message.structured.kind) ?? null,
|
|
5459
|
-
command: stringValue(message.structured.command) ?? null,
|
|
5460
|
-
file_paths: fileChangePaths(message.structured)
|
|
5520
|
+
const completedOutputs = completedOutputProjectionsForTurn(state, turnId, messages);
|
|
5521
|
+
const sourceMessageSeq = sourceMessageSeqForTurn(state, turnId);
|
|
5522
|
+
const rootSeq = state.rootSeq;
|
|
5523
|
+
for (const output of completedOutputs) {
|
|
5524
|
+
await postCompletedOutputProjection(args, state, payloadContext, {
|
|
5525
|
+
turnId,
|
|
5526
|
+
sourceMessageSeq,
|
|
5527
|
+
rootSeq,
|
|
5528
|
+
output
|
|
5461
5529
|
});
|
|
5462
5530
|
}
|
|
5463
5531
|
rememberForwardedTurnId(state, turnId);
|
|
@@ -5506,6 +5574,202 @@ async function forwardCompletedCodexTurn(args, state, turnId, payloadContext) {
|
|
|
5506
5574
|
}
|
|
5507
5575
|
}
|
|
5508
5576
|
}
|
|
5577
|
+
function completedOutputProjectionsForTurn(state, turnId, messages) {
|
|
5578
|
+
const snapshotOutputs = messages.flatMap((message, snapshotIndex) => completedSnapshotOutputProjection(state, turnId, message, snapshotIndex));
|
|
5579
|
+
const matchedStructuredKeys = new Set(snapshotOutputs.flatMap((output) => {
|
|
5580
|
+
switch (output.match.kind) {
|
|
5581
|
+
case "structured":
|
|
5582
|
+
return [output.match.matchKey];
|
|
5583
|
+
case "assistant":
|
|
5584
|
+
case "none":
|
|
5585
|
+
return [];
|
|
5586
|
+
}
|
|
5587
|
+
}));
|
|
5588
|
+
const filteredReasoningOutputs = boundedCacheValues(state.streamingReasoningOutputs).filter((output) => output.turnId === turnId && !matchedStructuredKeys.has(structuredOutputMatchKey("codex_reasoning", output.itemKey)));
|
|
5589
|
+
const filteredCommandOutputs = boundedCacheValues(state.streamingCommandOutputs).filter((output) => output.turnId === turnId && !matchedStructuredKeys.has(structuredOutputMatchKey("codex_command_execution", output.itemKey)));
|
|
5590
|
+
const filteredFileChangeOutputs = boundedCacheValues(state.streamingFileChangeOutputs).filter((output) => output.turnId === turnId && !matchedStructuredKeys.has(structuredOutputMatchKey("codex_file_change", output.itemKey)));
|
|
5591
|
+
const cachedOutputs = [
|
|
5592
|
+
...filteredReasoningOutputs.map((output, index) => ({
|
|
5593
|
+
kind: "cached_reasoning",
|
|
5594
|
+
sortOrder: output.seq,
|
|
5595
|
+
snapshotIndex: messages.length + index,
|
|
5596
|
+
output
|
|
5597
|
+
})),
|
|
5598
|
+
...filteredCommandOutputs.map((output, index) => ({
|
|
5599
|
+
kind: "cached_command",
|
|
5600
|
+
sortOrder: output.seq,
|
|
5601
|
+
snapshotIndex: messages.length + filteredReasoningOutputs.length + index,
|
|
5602
|
+
output
|
|
5603
|
+
})),
|
|
5604
|
+
...filteredFileChangeOutputs.map((output, index) => ({
|
|
5605
|
+
kind: "cached_file_change",
|
|
5606
|
+
sortOrder: output.seq,
|
|
5607
|
+
snapshotIndex: messages.length + filteredReasoningOutputs.length + filteredCommandOutputs.length + index,
|
|
5608
|
+
output
|
|
5609
|
+
}))
|
|
5610
|
+
];
|
|
5611
|
+
const fallbackSortOrderBase = fallbackSnapshotOutputBase([
|
|
5612
|
+
...snapshotOutputs.flatMap((output) => {
|
|
5613
|
+
switch (output.match.kind) {
|
|
5614
|
+
case "assistant":
|
|
5615
|
+
case "structured":
|
|
5616
|
+
return [output.sortOrder];
|
|
5617
|
+
case "none":
|
|
5618
|
+
return [];
|
|
5619
|
+
}
|
|
5620
|
+
}),
|
|
5621
|
+
...cachedOutputs.map((output) => output.sortOrder)
|
|
5622
|
+
]);
|
|
5623
|
+
const orderedSnapshotOutputs = snapshotOutputs.map((output) => {
|
|
5624
|
+
switch (output.match.kind) {
|
|
5625
|
+
case "none":
|
|
5626
|
+
return {
|
|
5627
|
+
...output,
|
|
5628
|
+
sortOrder: fallbackSnapshotOutputOrder(fallbackSortOrderBase, output.snapshotIndex)
|
|
5629
|
+
};
|
|
5630
|
+
case "assistant":
|
|
5631
|
+
case "structured":
|
|
5632
|
+
return output;
|
|
5633
|
+
}
|
|
5634
|
+
});
|
|
5635
|
+
return [...orderedSnapshotOutputs, ...cachedOutputs].sort(compareCompletedOutputProjection);
|
|
5636
|
+
}
|
|
5637
|
+
function completedSnapshotOutputProjection(state, turnId, message, snapshotIndex) {
|
|
5638
|
+
const streamedStructured = resolveStreamingStructuredOutputForCompletedMessage(state, message.itemKey, message.structured);
|
|
5639
|
+
if (streamedStructured !== undefined) {
|
|
5640
|
+
const structuredKind = stringValue(message.structured.kind) ?? "";
|
|
5641
|
+
return [
|
|
5642
|
+
{
|
|
5643
|
+
kind: "snapshot",
|
|
5644
|
+
sortOrder: streamedStructured.seq,
|
|
5645
|
+
snapshotIndex,
|
|
5646
|
+
message,
|
|
5647
|
+
match: {
|
|
5648
|
+
kind: "structured",
|
|
5649
|
+
itemKey: message.itemKey,
|
|
5650
|
+
structured: message.structured,
|
|
5651
|
+
matchKey: structuredOutputMatchKey(structuredKind, message.itemKey)
|
|
5652
|
+
}
|
|
5653
|
+
}
|
|
5654
|
+
];
|
|
5655
|
+
}
|
|
5656
|
+
if (stringValue(message.structured.kind) === "codex_terminal_input" && state.forwardedTerminalInputKeys.has(message.itemKey)) {
|
|
5657
|
+
return [];
|
|
5658
|
+
}
|
|
5659
|
+
const streamed = resolveStreamingAssistantOutputForCompletedMessage(state, turnId, message.itemKey, message.body, message.structured);
|
|
5660
|
+
switch (streamed.status) {
|
|
5661
|
+
case "none":
|
|
5662
|
+
return [
|
|
5663
|
+
{
|
|
5664
|
+
kind: "snapshot",
|
|
5665
|
+
sortOrder: snapshotIndex,
|
|
5666
|
+
snapshotIndex,
|
|
5667
|
+
message,
|
|
5668
|
+
match: { kind: "none" }
|
|
5669
|
+
}
|
|
5670
|
+
];
|
|
5671
|
+
case "matched":
|
|
5672
|
+
return [
|
|
5673
|
+
{
|
|
5674
|
+
kind: "snapshot",
|
|
5675
|
+
sortOrder: streamed.output.seq,
|
|
5676
|
+
snapshotIndex,
|
|
5677
|
+
message,
|
|
5678
|
+
match: { kind: "assistant", itemKey: streamed.output.itemKey }
|
|
5679
|
+
}
|
|
5680
|
+
];
|
|
5681
|
+
case "ambiguous":
|
|
5682
|
+
throw new LogicalProjectionError(`Cannot reconcile completed assistant item ${message.itemKey} for turn ${turnId}; ${streamed.candidateCount} active streamed assistant outputs exist`);
|
|
5683
|
+
}
|
|
5684
|
+
}
|
|
5685
|
+
async function postCompletedOutputProjection(args, state, payloadContext, params) {
|
|
5686
|
+
switch (params.output.kind) {
|
|
5687
|
+
case "snapshot": {
|
|
5688
|
+
switch (params.output.match.kind) {
|
|
5689
|
+
case "none":
|
|
5690
|
+
await streamCompletedCodexOutput(args, state, payloadContext, {
|
|
5691
|
+
turnId: params.turnId,
|
|
5692
|
+
sourceMessageSeq: params.sourceMessageSeq,
|
|
5693
|
+
rootSeq: params.rootSeq,
|
|
5694
|
+
message: params.output.message
|
|
5695
|
+
});
|
|
5696
|
+
break;
|
|
5697
|
+
case "assistant":
|
|
5698
|
+
await editStreamedCodexOutput(args, state, params.output.sortOrder, params.output.message.itemKey, params.output.message.body, "completed");
|
|
5699
|
+
forgetStreamingAssistantOutput(state, params.output.match.itemKey);
|
|
5700
|
+
break;
|
|
5701
|
+
case "structured":
|
|
5702
|
+
await editCodexStructuredOutput(args, state, params.output.sortOrder, params.output.message.body, params.output.message.structured);
|
|
5703
|
+
forgetStreamingStructuredOutput(state, params.output.match.itemKey, params.output.match.structured);
|
|
5704
|
+
break;
|
|
5705
|
+
}
|
|
5706
|
+
logCompletedCodexOutput(args, params.turnId, params.output.message);
|
|
5707
|
+
break;
|
|
5708
|
+
}
|
|
5709
|
+
case "cached_reasoning": {
|
|
5710
|
+
const output = params.output.output;
|
|
5711
|
+
const message = {
|
|
5712
|
+
itemKey: output.itemKey,
|
|
5713
|
+
body: output.content,
|
|
5714
|
+
structured: codexReasoningStructuredMessage(output.itemKey, output.content, "completed")
|
|
5715
|
+
};
|
|
5716
|
+
await editCodexStructuredOutput(args, state, output.seq, message.body, message.structured);
|
|
5717
|
+
forgetStreamingReasoningOutput(state, output.itemKey);
|
|
5718
|
+
logCompletedCodexOutput(args, params.turnId, message);
|
|
5719
|
+
break;
|
|
5720
|
+
}
|
|
5721
|
+
case "cached_command": {
|
|
5722
|
+
const output = params.output.output;
|
|
5723
|
+
const message = {
|
|
5724
|
+
itemKey: output.itemKey,
|
|
5725
|
+
body: codexCommandOutputBody("command output", output.output),
|
|
5726
|
+
structured: codexCommandExecutionStructuredMessage(output.itemKey, {
|
|
5727
|
+
command: "command output",
|
|
5728
|
+
output: output.output,
|
|
5729
|
+
processId: output.processId,
|
|
5730
|
+
stream: output.stream
|
|
5731
|
+
}, "completed")
|
|
5732
|
+
};
|
|
5733
|
+
await editCodexStructuredOutput(args, state, output.seq, message.body, message.structured);
|
|
5734
|
+
forgetStreamingCommandOutput(state, output.itemKey);
|
|
5735
|
+
logCompletedCodexOutput(args, params.turnId, message);
|
|
5736
|
+
break;
|
|
5737
|
+
}
|
|
5738
|
+
case "cached_file_change": {
|
|
5739
|
+
const output = params.output.output;
|
|
5740
|
+
const message = {
|
|
5741
|
+
itemKey: output.itemKey,
|
|
5742
|
+
body: output.patchText,
|
|
5743
|
+
structured: codexFileChangeStructuredMessage(output.itemKey, output.patchText, "completed", "completed")
|
|
5744
|
+
};
|
|
5745
|
+
await editCodexStructuredOutput(args, state, output.seq, message.body, message.structured);
|
|
5746
|
+
forgetStreamingFileChangeOutput(state, output.itemKey);
|
|
5747
|
+
logCompletedCodexOutput(args, params.turnId, message);
|
|
5748
|
+
break;
|
|
5749
|
+
}
|
|
5750
|
+
}
|
|
5751
|
+
}
|
|
5752
|
+
function logCompletedCodexOutput(args, turnId, message) {
|
|
5753
|
+
args.log("kandan.codex_output_forwarded", {
|
|
5754
|
+
turn_id: turnId,
|
|
5755
|
+
item_key: message.itemKey,
|
|
5756
|
+
structured_kind: stringValue(message.structured.kind) ?? null,
|
|
5757
|
+
command: stringValue(message.structured.command) ?? null,
|
|
5758
|
+
file_paths: fileChangePaths(message.structured)
|
|
5759
|
+
});
|
|
5760
|
+
}
|
|
5761
|
+
function compareCompletedOutputProjection(left, right) {
|
|
5762
|
+
return left.sortOrder === right.sortOrder ? left.snapshotIndex - right.snapshotIndex : left.sortOrder - right.sortOrder;
|
|
5763
|
+
}
|
|
5764
|
+
function fallbackSnapshotOutputBase(sortOrders) {
|
|
5765
|
+
return sortOrders.reduce((max, sortOrder) => Math.max(max, sortOrder), 0) + 1;
|
|
5766
|
+
}
|
|
5767
|
+
function fallbackSnapshotOutputOrder(base, snapshotIndex) {
|
|
5768
|
+
return base + snapshotIndex;
|
|
5769
|
+
}
|
|
5770
|
+
function structuredOutputMatchKey(kind, itemKey) {
|
|
5771
|
+
return `${kind}:${itemKey}`;
|
|
5772
|
+
}
|
|
5509
5773
|
async function forwardAssistantDeltaPayload(args, state, delta, payloadContext) {
|
|
5510
5774
|
if (state.kandanThreadId === undefined || state.codexThreadId === undefined) {
|
|
5511
5775
|
return;
|
|
@@ -6846,7 +7110,8 @@ function runtimeSettingsFromOptions(options) {
|
|
|
6846
7110
|
reasoningEffort: options.channelSession.reasoningEffort,
|
|
6847
7111
|
approvalPolicy: codexApprovalPolicySetting(options.channelSession.approvalPolicy, options.channelSession.sandbox),
|
|
6848
7112
|
sandbox: options.channelSession.sandbox,
|
|
6849
|
-
fast: options.fast
|
|
7113
|
+
fast: options.fast,
|
|
7114
|
+
allowPortForwardingByDefault: options.channelSession.allowPortForwardingByDefault
|
|
6850
7115
|
};
|
|
6851
7116
|
}
|
|
6852
7117
|
function mergeRuntimeSettings(current, update) {
|
|
@@ -6856,7 +7121,8 @@ function mergeRuntimeSettings(current, update) {
|
|
|
6856
7121
|
reasoningEffort: mergeOptionalStringRuntimeSetting(current.reasoningEffort, update, "reasoningEffort"),
|
|
6857
7122
|
approvalPolicy: mergeOptionalApprovalPolicyRuntimeSetting(current.approvalPolicy, update, sandbox),
|
|
6858
7123
|
sandbox,
|
|
6859
|
-
fast: update.fast ?? current.fast
|
|
7124
|
+
fast: update.fast ?? current.fast,
|
|
7125
|
+
allowPortForwardingByDefault: update.allowPortForwardingByDefault ?? current.allowPortForwardingByDefault
|
|
6860
7126
|
};
|
|
6861
7127
|
}
|
|
6862
7128
|
function mergeOptionalApprovalPolicyRuntimeSetting(current, update, sandbox) {
|
|
@@ -6880,7 +7146,8 @@ function runtimeOptionsForSettings(options, settings) {
|
|
|
6880
7146
|
model: settings.model,
|
|
6881
7147
|
reasoningEffort: settings.reasoningEffort,
|
|
6882
7148
|
approvalPolicy: settings.approvalPolicy,
|
|
6883
|
-
sandbox: settings.sandbox
|
|
7149
|
+
sandbox: settings.sandbox,
|
|
7150
|
+
allowPortForwardingByDefault: settings.allowPortForwardingByDefault
|
|
6884
7151
|
}
|
|
6885
7152
|
};
|
|
6886
7153
|
}
|
|
@@ -6899,6 +7166,7 @@ async function publishRuntimeSettings(args, state) {
|
|
|
6899
7166
|
approvalPolicy: state.runtimeSettings.approvalPolicy ?? null,
|
|
6900
7167
|
sandbox: state.runtimeSettings.sandbox ?? null,
|
|
6901
7168
|
fast: state.runtimeSettings.fast ?? null,
|
|
7169
|
+
allowPortForwardingByDefault: state.runtimeSettings.allowPortForwardingByDefault ?? null,
|
|
6902
7170
|
updated_at: new Date().toISOString()
|
|
6903
7171
|
});
|
|
6904
7172
|
}
|
|
@@ -8776,7 +9044,7 @@ function kandanHttpBaseUrl(kandanUrl) {
|
|
|
8776
9044
|
case "https:":
|
|
8777
9045
|
break;
|
|
8778
9046
|
default:
|
|
8779
|
-
throw new Error("--
|
|
9047
|
+
throw new Error("--api-url must be ws://, wss://, http://, or https://");
|
|
8780
9048
|
}
|
|
8781
9049
|
parsed.pathname = "";
|
|
8782
9050
|
parsed.search = "";
|
|
@@ -9414,7 +9682,8 @@ function probeTool(command, cwd) {
|
|
|
9414
9682
|
});
|
|
9415
9683
|
const child = spawn5(command, args, {
|
|
9416
9684
|
cwd,
|
|
9417
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
9685
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
9686
|
+
detached: process.platform !== "win32"
|
|
9418
9687
|
});
|
|
9419
9688
|
writeCliAuditEvent("process.spawned", {
|
|
9420
9689
|
command,
|
|
@@ -9435,7 +9704,7 @@ function probeTool(command, cwd) {
|
|
|
9435
9704
|
resolve5(status);
|
|
9436
9705
|
};
|
|
9437
9706
|
const timeout = setTimeout(() => {
|
|
9438
|
-
child.
|
|
9707
|
+
killDependencyProbe(child.pid);
|
|
9439
9708
|
writeCliAuditEvent("process.exit", {
|
|
9440
9709
|
command,
|
|
9441
9710
|
args,
|
|
@@ -9485,6 +9754,18 @@ function probeTool(command, cwd) {
|
|
|
9485
9754
|
});
|
|
9486
9755
|
});
|
|
9487
9756
|
}
|
|
9757
|
+
function killDependencyProbe(pid) {
|
|
9758
|
+
if (pid === undefined) {
|
|
9759
|
+
return;
|
|
9760
|
+
}
|
|
9761
|
+
try {
|
|
9762
|
+
process.kill(process.platform === "win32" ? pid : -pid, "SIGKILL");
|
|
9763
|
+
} catch (_error) {
|
|
9764
|
+
try {
|
|
9765
|
+
process.kill(pid, "SIGKILL");
|
|
9766
|
+
} catch (_nestedError) {}
|
|
9767
|
+
}
|
|
9768
|
+
}
|
|
9488
9769
|
async function buildRunnerDependencyStatus(args) {
|
|
9489
9770
|
const [bun, codex, codeServer] = await Promise.all([
|
|
9490
9771
|
probeTool(process.execPath, args.cwd),
|
|
@@ -9617,6 +9898,21 @@ async function connectPhoenixClient(baseUrl, token, socketFactory = (url) => new
|
|
|
9617
9898
|
state.rejectReady = reject;
|
|
9618
9899
|
});
|
|
9619
9900
|
};
|
|
9901
|
+
const dispatchRejoinEvents = (topic, response) => {
|
|
9902
|
+
if (!topic.startsWith("chat:")) {
|
|
9903
|
+
return;
|
|
9904
|
+
}
|
|
9905
|
+
const events = response.events;
|
|
9906
|
+
if (events === undefined || events === null) {
|
|
9907
|
+
return;
|
|
9908
|
+
}
|
|
9909
|
+
if (!Array.isArray(events)) {
|
|
9910
|
+
throw new Error(`phoenix rejoin returned invalid events for ${topic}`);
|
|
9911
|
+
}
|
|
9912
|
+
events.forEach((backlogEvent) => {
|
|
9913
|
+
eventCallbacks.forEach((callback) => callback(topic, "event", backlogEvent));
|
|
9914
|
+
});
|
|
9915
|
+
};
|
|
9620
9916
|
const handleMessage = (event) => {
|
|
9621
9917
|
const frame = decodeFrame(String(event.data));
|
|
9622
9918
|
const [, ref, topic, name, payload] = frame;
|
|
@@ -9630,6 +9926,14 @@ async function connectPhoenixClient(baseUrl, token, socketFactory = (url) => new
|
|
|
9630
9926
|
} else if (isNonOkPushReply(payload) && pendingPush.event !== "phx_join") {
|
|
9631
9927
|
pendingPush.reject(new Error(`phoenix push failed: ${replyErrorMessage(payload)}`));
|
|
9632
9928
|
} else {
|
|
9929
|
+
if (pendingPush.event === "phx_join" && state.connectionGeneration > 1 && joins.has(topic) && isJoinReply(payload)) {
|
|
9930
|
+
try {
|
|
9931
|
+
dispatchRejoinEvents(topic, payload.response);
|
|
9932
|
+
} catch (error) {
|
|
9933
|
+
pendingPush.reject(error instanceof Error ? error : new Error(String(error)));
|
|
9934
|
+
return;
|
|
9935
|
+
}
|
|
9936
|
+
}
|
|
9633
9937
|
pendingPush.resolve(payload);
|
|
9634
9938
|
}
|
|
9635
9939
|
}
|
|
@@ -10152,7 +10456,7 @@ function realpathOrResolved(pathValue) {
|
|
|
10152
10456
|
}
|
|
10153
10457
|
|
|
10154
10458
|
// src/version.ts
|
|
10155
|
-
var linzumiCliVersion = "0.0.
|
|
10459
|
+
var linzumiCliVersion = "0.0.53-beta";
|
|
10156
10460
|
var linzumiCliVersionText = `linzumi ${linzumiCliVersion}`;
|
|
10157
10461
|
|
|
10158
10462
|
// src/runnerLock.ts
|
|
@@ -10761,6 +11065,25 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
|
|
|
10761
11065
|
}
|
|
10762
11066
|
revokeEditorForwardPort(review.revoked.port, review.reason);
|
|
10763
11067
|
break;
|
|
11068
|
+
case "replace_pending":
|
|
11069
|
+
localEditorForwardState.pendingRequests.delete(review.expired.port);
|
|
11070
|
+
pushEditorPortForwardEvent("forward_port_resolved", {
|
|
11071
|
+
instanceId,
|
|
11072
|
+
requestId: review.expired.requestId,
|
|
11073
|
+
source: "local_editor",
|
|
11074
|
+
port: review.expired.port,
|
|
11075
|
+
pid: review.expired.pid,
|
|
11076
|
+
command: review.expired.command,
|
|
11077
|
+
...review.expired.cwd === undefined ? {} : { cwd: review.expired.cwd },
|
|
11078
|
+
decision: "expired",
|
|
11079
|
+
reason: review.reason,
|
|
11080
|
+
capabilities: capabilitiesPayload()
|
|
11081
|
+
});
|
|
11082
|
+
if (localEditorForwardState.pendingRequests.size > 0) {
|
|
11083
|
+
localEditorForwardState.queuedCandidates.set(review.candidate.port, review.candidate);
|
|
11084
|
+
return;
|
|
11085
|
+
}
|
|
11086
|
+
break;
|
|
10764
11087
|
case "prompt":
|
|
10765
11088
|
if (localEditorForwardState.pendingRequests.size > 0) {
|
|
10766
11089
|
localEditorForwardState.queuedCandidates.set(candidate.port, candidate);
|
|
@@ -10917,8 +11240,7 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
|
|
|
10917
11240
|
const codex = await connectCodexAppServer(codexUrl);
|
|
10918
11241
|
cleanup.actions.push(() => codex.close());
|
|
10919
11242
|
const seq = { value: 0 };
|
|
10920
|
-
const
|
|
10921
|
-
const discoveredCodexThreads = { value: codexThreads };
|
|
11243
|
+
const discoveredCodexThreads = { value: [] };
|
|
10922
11244
|
const runtimeDefaults = runnerRuntimeDefaults(options);
|
|
10923
11245
|
const instancePayload = {
|
|
10924
11246
|
instanceId,
|
|
@@ -10927,11 +11249,12 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
|
|
|
10927
11249
|
tuiLaunched: options.launchTui,
|
|
10928
11250
|
cwd: options.cwd,
|
|
10929
11251
|
hostname: runnerHost,
|
|
10930
|
-
codexThreads,
|
|
11252
|
+
codexThreads: discoveredCodexThreads.value,
|
|
10931
11253
|
workspace: runnerWorkspaceSlug(options) ?? null,
|
|
10932
11254
|
channel: options.channelSession?.channelSlug ?? null,
|
|
10933
11255
|
model: runtimeDefaults.model ?? null,
|
|
10934
11256
|
reasoningEffort: runtimeDefaults.reasoningEffort ?? null,
|
|
11257
|
+
allowPortForwardingByDefault: runtimeDefaults.allowPortForwardingByDefault ?? null,
|
|
10935
11258
|
fast: options.fast ?? false
|
|
10936
11259
|
};
|
|
10937
11260
|
await kandan.push(topic, "instance_started", instancePayload);
|
|
@@ -11039,7 +11362,8 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
|
|
|
11039
11362
|
model: runtimeSettings.model,
|
|
11040
11363
|
reasoningEffort: runtimeSettings.reasoningEffort,
|
|
11041
11364
|
sandbox: runtimeSettings.sandbox,
|
|
11042
|
-
approvalPolicy: runtimeSettings.approvalPolicy
|
|
11365
|
+
approvalPolicy: runtimeSettings.approvalPolicy,
|
|
11366
|
+
allowPortForwardingByDefault: runtimeSettings.allowPortForwardingByDefault
|
|
11043
11367
|
}
|
|
11044
11368
|
},
|
|
11045
11369
|
log
|
|
@@ -11060,6 +11384,7 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
|
|
|
11060
11384
|
codexThreads: discoveredCodexThreads.value,
|
|
11061
11385
|
model: runtimeDefaults.model ?? null,
|
|
11062
11386
|
reasoningEffort: runtimeDefaults.reasoningEffort ?? null,
|
|
11387
|
+
allowPortForwardingByDefault: runtimeDefaults.allowPortForwardingByDefault ?? null,
|
|
11063
11388
|
fast: options.fast ?? false,
|
|
11064
11389
|
capabilities: capabilitiesPayload()
|
|
11065
11390
|
});
|
|
@@ -11068,19 +11393,11 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
|
|
|
11068
11393
|
message: error instanceof Error ? error.message : String(error)
|
|
11069
11394
|
});
|
|
11070
11395
|
});
|
|
11071
|
-
const refreshDiscoveredCodexThreads = () => discoverCodexThreads(codex, options.cwd).then((threads) => {
|
|
11072
|
-
discoveredCodexThreads.value = threads;
|
|
11073
|
-
return kandan.push(topic, "heartbeat", heartbeatPayload());
|
|
11074
|
-
}).catch((error) => {
|
|
11075
|
-
log("kandan.codex_threads_refresh_failed", {
|
|
11076
|
-
message: error instanceof Error ? error.message : String(error)
|
|
11077
|
-
});
|
|
11078
|
-
});
|
|
11079
11396
|
const heartbeatInterval = setInterval(() => {
|
|
11080
|
-
|
|
11397
|
+
pushHeartbeat();
|
|
11081
11398
|
}, 15000);
|
|
11082
11399
|
cleanup.actions.push(() => clearInterval(heartbeatInterval));
|
|
11083
|
-
kandan.onReconnect(() =>
|
|
11400
|
+
kandan.onReconnect(() => pushHeartbeat().then(() => {
|
|
11084
11401
|
return;
|
|
11085
11402
|
}));
|
|
11086
11403
|
pushHeartbeat();
|
|
@@ -11350,25 +11667,6 @@ async function closeCleanupStack(cleanup) {
|
|
|
11350
11667
|
})();
|
|
11351
11668
|
return cleanup.closePromise;
|
|
11352
11669
|
}
|
|
11353
|
-
async function discoverCodexThreads(codex, cwd) {
|
|
11354
|
-
const response = await codex.request("thread/list", { cwd });
|
|
11355
|
-
if ("error" in response) {
|
|
11356
|
-
return [];
|
|
11357
|
-
}
|
|
11358
|
-
const result = objectValue(response.result);
|
|
11359
|
-
const data = arrayValue(result?.data);
|
|
11360
|
-
return data === undefined ? [] : data.filter(isJsonObject).map((thread) => ({
|
|
11361
|
-
id: stringValue(thread.id) ?? "",
|
|
11362
|
-
title: stringValue(thread.title) ?? stringValue(thread.name) ?? stringValue(thread.preview) ?? "",
|
|
11363
|
-
description: stringValue(thread.description) ?? stringValue(thread.summary) ?? stringValue(thread.preview) ?? "",
|
|
11364
|
-
preview: stringValue(thread.preview) ?? "",
|
|
11365
|
-
cwd: stringValue(thread.cwd) ?? "",
|
|
11366
|
-
source: stringValue(thread.source) ?? "",
|
|
11367
|
-
createdAt: integerValue(thread.createdAt) ?? stringValue(thread.createdAt) ?? null,
|
|
11368
|
-
updatedAt: integerValue(thread.updatedAt) ?? null,
|
|
11369
|
-
status: objectValue(thread.status) ?? null
|
|
11370
|
-
})).filter((thread) => thread.id !== "");
|
|
11371
|
-
}
|
|
11372
11670
|
function extractStartedThreadId(response) {
|
|
11373
11671
|
if ("error" in response) {
|
|
11374
11672
|
throw new Error(`thread/start failed: ${response.error.message}`);
|
|
@@ -11801,6 +12099,10 @@ You MUST NOT ask the Bootstrapper Codex to do implementation work.
|
|
|
11801
12099
|
You MUST NOT inspect unrelated repositories or folders.
|
|
11802
12100
|
You MUST report the exact blocker if a command, preview, editor, or tunnel step
|
|
11803
12101
|
fails.
|
|
12102
|
+
When several Linzumi Codex sessions work in the same repository, create or use
|
|
12103
|
+
a separate checkout or git worktree for this task before making changes, unless
|
|
12104
|
+
the human explicitly asks you to share the current checkout. Do not overwrite or
|
|
12105
|
+
revert another session's work.
|
|
11804
12106
|
</rules>
|
|
11805
12107
|
|
|
11806
12108
|
<examples>
|
|
@@ -11892,7 +12194,8 @@ function startInstanceRuntimeSettings(options, control) {
|
|
|
11892
12194
|
reasoningEffort: control.reasoningEffort ?? defaults.reasoningEffort,
|
|
11893
12195
|
approvalPolicy: codexApprovalPolicyForRequest(control.approvalPolicy ?? defaults.approvalPolicy, sandbox),
|
|
11894
12196
|
sandbox,
|
|
11895
|
-
fast: control.fast ?? options.fast
|
|
12197
|
+
fast: control.fast ?? options.fast,
|
|
12198
|
+
allowPortForwardingByDefault: control.allowPortForwardingByDefault ?? defaults.allowPortForwardingByDefault
|
|
11896
12199
|
};
|
|
11897
12200
|
}
|
|
11898
12201
|
async function startOwnedCodexAppServer(options) {
|
|
@@ -11915,7 +12218,8 @@ function runnerRuntimeDefaults(options) {
|
|
|
11915
12218
|
model: defaults?.model ?? session?.model,
|
|
11916
12219
|
reasoningEffort: defaults?.reasoningEffort ?? session?.reasoningEffort,
|
|
11917
12220
|
approvalPolicy: codexApprovalPolicySetting(defaults?.approvalPolicy ?? session?.approvalPolicy, sandbox),
|
|
11918
|
-
sandbox
|
|
12221
|
+
sandbox,
|
|
12222
|
+
allowPortForwardingByDefault: defaults?.allowPortForwardingByDefault ?? session?.allowPortForwardingByDefault
|
|
11919
12223
|
};
|
|
11920
12224
|
}
|
|
11921
12225
|
function isUpdateRunnerConfigControl(control) {
|
|
@@ -13396,7 +13700,7 @@ To kick the agent off:
|
|
|
13396
13700
|
3. Paste into the thread. Codex will pick it up and start editing this folder.
|
|
13397
13701
|
`;
|
|
13398
13702
|
|
|
13399
|
-
//
|
|
13703
|
+
// node_modules/@inquirer/core/dist/esm/lib/key.js
|
|
13400
13704
|
var isUpKey = (key, keybindings = []) => key.name === "up" || keybindings.includes("vim") && key.name === "k" || keybindings.includes("emacs") && key.ctrl && key.name === "p";
|
|
13401
13705
|
var isDownKey = (key, keybindings = []) => key.name === "down" || keybindings.includes("vim") && key.name === "j" || keybindings.includes("emacs") && key.ctrl && key.name === "n";
|
|
13402
13706
|
var isSpaceKey = (key) => key.name === "space";
|
|
@@ -13404,7 +13708,7 @@ var isBackspaceKey = (key) => key.name === "backspace";
|
|
|
13404
13708
|
var isTabKey = (key) => key.name === "tab";
|
|
13405
13709
|
var isNumberKey = (key) => "1234567890".includes(key.name);
|
|
13406
13710
|
var isEnterKey = (key) => key.name === "enter" || key.name === "return";
|
|
13407
|
-
//
|
|
13711
|
+
// node_modules/@inquirer/core/dist/esm/lib/errors.js
|
|
13408
13712
|
class AbortPromptError extends Error {
|
|
13409
13713
|
name = "AbortPromptError";
|
|
13410
13714
|
message = "Prompt was aborted";
|
|
@@ -13430,10 +13734,10 @@ class HookError extends Error {
|
|
|
13430
13734
|
class ValidationError extends Error {
|
|
13431
13735
|
name = "ValidationError";
|
|
13432
13736
|
}
|
|
13433
|
-
//
|
|
13737
|
+
// node_modules/@inquirer/core/dist/esm/lib/use-state.js
|
|
13434
13738
|
import { AsyncResource as AsyncResource2 } from "node:async_hooks";
|
|
13435
13739
|
|
|
13436
|
-
//
|
|
13740
|
+
// node_modules/@inquirer/core/dist/esm/lib/hook-engine.js
|
|
13437
13741
|
import { AsyncLocalStorage, AsyncResource } from "node:async_hooks";
|
|
13438
13742
|
var hookStorage = new AsyncLocalStorage;
|
|
13439
13743
|
function createStore(rl) {
|
|
@@ -13538,7 +13842,7 @@ var effectScheduler = {
|
|
|
13538
13842
|
}
|
|
13539
13843
|
};
|
|
13540
13844
|
|
|
13541
|
-
//
|
|
13845
|
+
// node_modules/@inquirer/core/dist/esm/lib/use-state.js
|
|
13542
13846
|
function useState(defaultValue) {
|
|
13543
13847
|
return withPointer((pointer) => {
|
|
13544
13848
|
const setState = AsyncResource2.bind(function setState2(newValue) {
|
|
@@ -13556,7 +13860,7 @@ function useState(defaultValue) {
|
|
|
13556
13860
|
});
|
|
13557
13861
|
}
|
|
13558
13862
|
|
|
13559
|
-
//
|
|
13863
|
+
// node_modules/@inquirer/core/dist/esm/lib/use-effect.js
|
|
13560
13864
|
function useEffect(cb, depArray) {
|
|
13561
13865
|
withPointer((pointer) => {
|
|
13562
13866
|
const oldDeps = pointer.get();
|
|
@@ -13568,10 +13872,10 @@ function useEffect(cb, depArray) {
|
|
|
13568
13872
|
});
|
|
13569
13873
|
}
|
|
13570
13874
|
|
|
13571
|
-
//
|
|
13875
|
+
// node_modules/@inquirer/core/dist/esm/lib/theme.js
|
|
13572
13876
|
var import_yoctocolors_cjs = __toESM(require_yoctocolors_cjs(), 1);
|
|
13573
13877
|
|
|
13574
|
-
//
|
|
13878
|
+
// node_modules/@inquirer/figures/dist/esm/index.js
|
|
13575
13879
|
import process2 from "node:process";
|
|
13576
13880
|
function isUnicodeSupported() {
|
|
13577
13881
|
if (process2.platform !== "win32") {
|
|
@@ -13860,7 +14164,7 @@ var figures = shouldUseMain ? mainSymbols : fallbackSymbols;
|
|
|
13860
14164
|
var esm_default = figures;
|
|
13861
14165
|
var replacements = Object.entries(specialMainSymbols);
|
|
13862
14166
|
|
|
13863
|
-
//
|
|
14167
|
+
// node_modules/@inquirer/core/dist/esm/lib/theme.js
|
|
13864
14168
|
var defaultTheme = {
|
|
13865
14169
|
prefix: {
|
|
13866
14170
|
idle: import_yoctocolors_cjs.default.blue("?"),
|
|
@@ -13881,7 +14185,7 @@ var defaultTheme = {
|
|
|
13881
14185
|
}
|
|
13882
14186
|
};
|
|
13883
14187
|
|
|
13884
|
-
//
|
|
14188
|
+
// node_modules/@inquirer/core/dist/esm/lib/make-theme.js
|
|
13885
14189
|
function isPlainObject(value) {
|
|
13886
14190
|
if (typeof value !== "object" || value === null)
|
|
13887
14191
|
return false;
|
|
@@ -13909,7 +14213,7 @@ function makeTheme(...themes) {
|
|
|
13909
14213
|
return deepMerge(...themesToMerge);
|
|
13910
14214
|
}
|
|
13911
14215
|
|
|
13912
|
-
//
|
|
14216
|
+
// node_modules/@inquirer/core/dist/esm/lib/use-prefix.js
|
|
13913
14217
|
function usePrefix({ status = "idle", theme }) {
|
|
13914
14218
|
const [showLoader, setShowLoader] = useState(false);
|
|
13915
14219
|
const [tick, setTick] = useState(0);
|
|
@@ -13939,7 +14243,7 @@ function usePrefix({ status = "idle", theme }) {
|
|
|
13939
14243
|
const iconName = status === "loading" ? "idle" : status;
|
|
13940
14244
|
return typeof prefix === "string" ? prefix : prefix[iconName] ?? prefix["idle"];
|
|
13941
14245
|
}
|
|
13942
|
-
//
|
|
14246
|
+
// node_modules/@inquirer/core/dist/esm/lib/use-memo.js
|
|
13943
14247
|
function useMemo(fn, dependencies) {
|
|
13944
14248
|
return withPointer((pointer) => {
|
|
13945
14249
|
const prev = pointer.get();
|
|
@@ -13951,11 +14255,11 @@ function useMemo(fn, dependencies) {
|
|
|
13951
14255
|
return prev.value;
|
|
13952
14256
|
});
|
|
13953
14257
|
}
|
|
13954
|
-
//
|
|
14258
|
+
// node_modules/@inquirer/core/dist/esm/lib/use-ref.js
|
|
13955
14259
|
function useRef(val) {
|
|
13956
14260
|
return useState({ current: val })[0];
|
|
13957
14261
|
}
|
|
13958
|
-
//
|
|
14262
|
+
// node_modules/@inquirer/core/dist/esm/lib/use-keypress.js
|
|
13959
14263
|
function useKeypress(userHandler) {
|
|
13960
14264
|
const signal = useRef(userHandler);
|
|
13961
14265
|
signal.current = userHandler;
|
|
@@ -13973,7 +14277,7 @@ function useKeypress(userHandler) {
|
|
|
13973
14277
|
};
|
|
13974
14278
|
}, []);
|
|
13975
14279
|
}
|
|
13976
|
-
//
|
|
14280
|
+
// node_modules/@inquirer/core/dist/esm/lib/utils.js
|
|
13977
14281
|
var import_cli_width = __toESM(require_cli_width(), 1);
|
|
13978
14282
|
var import_wrap_ansi = __toESM(require_wrap_ansi(), 1);
|
|
13979
14283
|
function breakLines(content, width) {
|
|
@@ -13986,7 +14290,7 @@ function readlineWidth() {
|
|
|
13986
14290
|
return import_cli_width.default({ defaultWidth: 80, output: readline().output });
|
|
13987
14291
|
}
|
|
13988
14292
|
|
|
13989
|
-
//
|
|
14293
|
+
// node_modules/@inquirer/core/dist/esm/lib/pagination/use-pagination.js
|
|
13990
14294
|
function usePointerPosition({ active, renderedItems, pageSize, loop }) {
|
|
13991
14295
|
const state = useRef({
|
|
13992
14296
|
lastPointer: active,
|
|
@@ -14052,12 +14356,12 @@ function usePagination({ items, active, renderItem, pageSize, loop = true }) {
|
|
|
14052
14356
|
return pageBuffer.filter((line) => typeof line === "string").join(`
|
|
14053
14357
|
`);
|
|
14054
14358
|
}
|
|
14055
|
-
//
|
|
14359
|
+
// node_modules/@inquirer/core/dist/esm/lib/create-prompt.js
|
|
14056
14360
|
var import_mute_stream = __toESM(require_lib(), 1);
|
|
14057
14361
|
import * as readline2 from "node:readline";
|
|
14058
14362
|
import { AsyncResource as AsyncResource3 } from "node:async_hooks";
|
|
14059
14363
|
|
|
14060
|
-
//
|
|
14364
|
+
// node_modules/signal-exit/dist/mjs/signals.js
|
|
14061
14365
|
var signals = [];
|
|
14062
14366
|
signals.push("SIGHUP", "SIGINT", "SIGTERM");
|
|
14063
14367
|
if (process.platform !== "win32") {
|
|
@@ -14067,7 +14371,7 @@ if (process.platform === "linux") {
|
|
|
14067
14371
|
signals.push("SIGIO", "SIGPOLL", "SIGPWR", "SIGSTKFLT");
|
|
14068
14372
|
}
|
|
14069
14373
|
|
|
14070
|
-
//
|
|
14374
|
+
// node_modules/signal-exit/dist/mjs/index.js
|
|
14071
14375
|
var processOk = (process3) => !!process3 && typeof process3 === "object" && typeof process3.removeListener === "function" && typeof process3.emit === "function" && typeof process3.reallyExit === "function" && typeof process3.listeners === "function" && typeof process3.kill === "function" && typeof process3.pid === "number" && typeof process3.on === "function";
|
|
14072
14376
|
var kExitEmitter = Symbol.for("signal-exit emitter");
|
|
14073
14377
|
var global = globalThis;
|
|
@@ -14265,10 +14569,10 @@ var {
|
|
|
14265
14569
|
unload
|
|
14266
14570
|
} = signalExitWrap(processOk(process3) ? new SignalExit(process3) : new SignalExitFallback);
|
|
14267
14571
|
|
|
14268
|
-
//
|
|
14572
|
+
// node_modules/@inquirer/core/dist/esm/lib/screen-manager.js
|
|
14269
14573
|
import { stripVTControlCharacters } from "node:util";
|
|
14270
14574
|
|
|
14271
|
-
//
|
|
14575
|
+
// node_modules/@inquirer/ansi/dist/esm/index.js
|
|
14272
14576
|
var ESC = "\x1B[";
|
|
14273
14577
|
var cursorLeft = ESC + "G";
|
|
14274
14578
|
var cursorHide = ESC + "?25l";
|
|
@@ -14284,7 +14588,7 @@ var cursorTo = (x, y) => {
|
|
|
14284
14588
|
var eraseLine = ESC + "2K";
|
|
14285
14589
|
var eraseLines = (lines) => lines > 0 ? (eraseLine + cursorUp(1)).repeat(lines - 1) + eraseLine + cursorLeft : "";
|
|
14286
14590
|
|
|
14287
|
-
//
|
|
14591
|
+
// node_modules/@inquirer/core/dist/esm/lib/screen-manager.js
|
|
14288
14592
|
var height = (content) => content.split(`
|
|
14289
14593
|
`).length;
|
|
14290
14594
|
var lastLine = (content) => content.split(`
|
|
@@ -14349,7 +14653,7 @@ class ScreenManager {
|
|
|
14349
14653
|
}
|
|
14350
14654
|
}
|
|
14351
14655
|
|
|
14352
|
-
//
|
|
14656
|
+
// node_modules/@inquirer/core/dist/esm/lib/promise-polyfill.js
|
|
14353
14657
|
class PromisePolyfill extends Promise {
|
|
14354
14658
|
static withResolver() {
|
|
14355
14659
|
let resolve8;
|
|
@@ -14362,7 +14666,7 @@ class PromisePolyfill extends Promise {
|
|
|
14362
14666
|
}
|
|
14363
14667
|
}
|
|
14364
14668
|
|
|
14365
|
-
//
|
|
14669
|
+
// node_modules/@inquirer/core/dist/esm/lib/create-prompt.js
|
|
14366
14670
|
function getCallSites() {
|
|
14367
14671
|
const _prepareStackTrace = Error.prepareStackTrace;
|
|
14368
14672
|
let result = [];
|
|
@@ -14448,7 +14752,7 @@ function createPrompt(view) {
|
|
|
14448
14752
|
};
|
|
14449
14753
|
return prompt;
|
|
14450
14754
|
}
|
|
14451
|
-
//
|
|
14755
|
+
// node_modules/@inquirer/core/dist/esm/lib/Separator.js
|
|
14452
14756
|
var import_yoctocolors_cjs2 = __toESM(require_yoctocolors_cjs(), 1);
|
|
14453
14757
|
class Separator {
|
|
14454
14758
|
separator = import_yoctocolors_cjs2.default.dim(Array.from({ length: 15 }).join(esm_default.line));
|
|
@@ -14462,7 +14766,7 @@ class Separator {
|
|
|
14462
14766
|
return Boolean(choice && typeof choice === "object" && "type" in choice && choice.type === "separator");
|
|
14463
14767
|
}
|
|
14464
14768
|
}
|
|
14465
|
-
//
|
|
14769
|
+
// node_modules/@inquirer/checkbox/dist/esm/index.js
|
|
14466
14770
|
var import_yoctocolors_cjs3 = __toESM(require_yoctocolors_cjs(), 1);
|
|
14467
14771
|
var checkboxTheme = {
|
|
14468
14772
|
icon: {
|
|
@@ -14649,7 +14953,7 @@ var esm_default2 = createPrompt((config, done) => {
|
|
|
14649
14953
|
`).trimEnd();
|
|
14650
14954
|
return `${lines}${cursorHide}`;
|
|
14651
14955
|
});
|
|
14652
|
-
//
|
|
14956
|
+
// node_modules/@inquirer/input/dist/esm/index.js
|
|
14653
14957
|
var inputTheme = {
|
|
14654
14958
|
validationFailureMode: "keep"
|
|
14655
14959
|
};
|
|
@@ -14733,7 +15037,7 @@ var esm_default3 = createPrompt((config, done) => {
|
|
|
14733
15037
|
error
|
|
14734
15038
|
];
|
|
14735
15039
|
});
|
|
14736
|
-
//
|
|
15040
|
+
// node_modules/@inquirer/select/dist/esm/index.js
|
|
14737
15041
|
var import_yoctocolors_cjs4 = __toESM(require_yoctocolors_cjs(), 1);
|
|
14738
15042
|
var selectTheme = {
|
|
14739
15043
|
icon: { cursor: esm_default.pointer },
|
|
@@ -14900,28 +15204,19 @@ var esm_default4 = createPrompt((config, done) => {
|
|
|
14900
15204
|
// src/signupFlow.ts
|
|
14901
15205
|
import { spawn as spawn7 } from "node:child_process";
|
|
14902
15206
|
import {
|
|
14903
|
-
closeSync as closeSync2,
|
|
14904
15207
|
existsSync as existsSync10,
|
|
14905
15208
|
constants as fsConstants,
|
|
14906
|
-
mkdirSync as mkdirSync10,
|
|
14907
15209
|
mkdtempSync as mkdtempSync3,
|
|
14908
|
-
openSync as openSync3,
|
|
14909
15210
|
readFileSync as readFileSync10,
|
|
14910
15211
|
readdirSync,
|
|
14911
15212
|
rmSync as rmSync3,
|
|
14912
15213
|
statSync,
|
|
14913
|
-
watch,
|
|
14914
15214
|
writeFileSync as writeFileSync8
|
|
14915
15215
|
} from "node:fs";
|
|
14916
15216
|
import { access } from "node:fs/promises";
|
|
14917
15217
|
import { homedir as homedir8, tmpdir as tmpdir2 } from "node:os";
|
|
14918
|
-
import { delimiter as delimiter2,
|
|
14919
|
-
import {
|
|
14920
|
-
argv as processArgv,
|
|
14921
|
-
execPath as processExecPath,
|
|
14922
|
-
stdin as defaultStdin,
|
|
14923
|
-
stdout as defaultStdout
|
|
14924
|
-
} from "node:process";
|
|
15218
|
+
import { delimiter as delimiter2, join as join12, resolve as resolve8 } from "node:path";
|
|
15219
|
+
import { stdin as defaultStdin, stdout as defaultStdout } from "node:process";
|
|
14925
15220
|
import { emitKeypressEvents } from "node:readline";
|
|
14926
15221
|
|
|
14927
15222
|
// src/signupServerClient.ts
|
|
@@ -15207,11 +15502,6 @@ function booleanValue(record, key) {
|
|
|
15207
15502
|
}
|
|
15208
15503
|
|
|
15209
15504
|
// src/signupFlow.ts
|
|
15210
|
-
var commanderConnectedMarkers = [
|
|
15211
|
-
"Connected to Linzumi",
|
|
15212
|
-
"Runner connected:",
|
|
15213
|
-
'"event":"runner.instance_started"'
|
|
15214
|
-
];
|
|
15215
15505
|
var blue = (value) => `\x1B[38;5;75m${value}\x1B[0m`;
|
|
15216
15506
|
var green = (value) => `\x1B[38;5;114m${value}\x1B[0m`;
|
|
15217
15507
|
var red = (value) => `\x1B[38;5;203m${value}\x1B[0m`;
|
|
@@ -15519,6 +15809,8 @@ async function runSignupFlow(deps = {}) {
|
|
|
15519
15809
|
rootSeq: thread.rootSeq,
|
|
15520
15810
|
threadSeq: thread.threadSeq
|
|
15521
15811
|
}));
|
|
15812
|
+
const starterProjectPath = missionControl.config.starterProjectPath ?? starterProject.path;
|
|
15813
|
+
const verifiedCodexBin = verifiedCodexBinFromPreflightChecks(state.preflightChecks);
|
|
15522
15814
|
const storedSignupAuth = writeSignupCompletion({
|
|
15523
15815
|
email: verifiedAuth.user.primaryEmail ?? state.email ?? verifiedAuth.user.username,
|
|
15524
15816
|
serviceUrl,
|
|
@@ -15530,20 +15822,24 @@ async function runSignupFlow(deps = {}) {
|
|
|
15530
15822
|
launchUrl: missionControl.launchUrl,
|
|
15531
15823
|
allowedCwds: missionControl.config.allowedCwds
|
|
15532
15824
|
});
|
|
15533
|
-
const commanderLaunch =
|
|
15825
|
+
const commanderLaunch = verifiedCodexBin === undefined ? failedSignupCommanderLaunchForMissingCodex({
|
|
15826
|
+
serviceUrl,
|
|
15827
|
+
workspaceSlug: missionControl.workspace.slug,
|
|
15828
|
+
projectPath: starterProjectPath
|
|
15829
|
+
}) : await launchSignupCommanderForCompletedSignup(commanderLauncher, {
|
|
15534
15830
|
serviceUrl,
|
|
15535
15831
|
localRunnerAccessToken: missionControl.localRunnerToken.accessToken,
|
|
15536
15832
|
localRunnerExpiresInSeconds: missionControl.localRunnerToken.expiresInSeconds,
|
|
15537
15833
|
workspaceSlug: missionControl.workspace.slug,
|
|
15538
|
-
|
|
15539
|
-
|
|
15540
|
-
|
|
15834
|
+
projectPath: starterProjectPath,
|
|
15835
|
+
selectedProjectPaths: missionControl.config.allowedCwds,
|
|
15836
|
+
codexBin: verifiedCodexBin
|
|
15541
15837
|
});
|
|
15542
15838
|
const starterTaskLaunches = await startSignupTasksForCommander(signupServerClient, {
|
|
15543
15839
|
accessToken: verifiedAuth.accessToken,
|
|
15544
15840
|
missionControl,
|
|
15545
15841
|
commanderLaunch,
|
|
15546
|
-
starterProjectPath
|
|
15842
|
+
starterProjectPath,
|
|
15547
15843
|
threads: starterTaskThreads
|
|
15548
15844
|
});
|
|
15549
15845
|
state = updateSignupState(state, {
|
|
@@ -16022,7 +16318,7 @@ function writeLaunchSummary(output, state) {
|
|
|
16022
16318
|
writeBoundedLine(output, `${green("✓")} Local Commander connected this computer to Mission Control (${state.commanderLaunch.runnerId})`);
|
|
16023
16319
|
break;
|
|
16024
16320
|
case "failed":
|
|
16025
|
-
writeStatusMessage(output, red("x"), `Local Commander could not
|
|
16321
|
+
writeStatusMessage(output, red("x"), `Local Commander could not connect: ${state.commanderLaunch.error}`);
|
|
16026
16322
|
break;
|
|
16027
16323
|
}
|
|
16028
16324
|
}
|
|
@@ -16064,48 +16360,17 @@ async function defaultSignupCommanderLauncher(args) {
|
|
|
16064
16360
|
accessToken: args.localRunnerAccessToken,
|
|
16065
16361
|
expiresInSeconds: args.localRunnerExpiresInSeconds
|
|
16066
16362
|
});
|
|
16067
|
-
const scriptPath = processArgv[1];
|
|
16068
16363
|
const runnerId = signupCommanderRunnerId(args.workspaceSlug);
|
|
16069
16364
|
const restartCommand = signupConnectRestartCommand(args);
|
|
16070
|
-
if (scriptPath === undefined || scriptPath.trim() === "") {
|
|
16071
|
-
return {
|
|
16072
|
-
status: "failed",
|
|
16073
|
-
runnerId,
|
|
16074
|
-
restartCommand,
|
|
16075
|
-
error: "current CLI entrypoint could not be resolved"
|
|
16076
|
-
};
|
|
16077
|
-
}
|
|
16078
|
-
const logFile = signupCommanderLaunchLogFile(runnerId);
|
|
16079
|
-
let stdoutFd;
|
|
16080
|
-
let stderrFd;
|
|
16081
16365
|
try {
|
|
16082
|
-
|
|
16083
|
-
stdoutFd = openSync3(logFile, "a");
|
|
16084
|
-
stderrFd = openSync3(logFile, "a");
|
|
16085
|
-
const child = spawn7(processExecPath, signupCommanderConnectSpawnArgs(args, runnerId, logFile, scriptPath), {
|
|
16086
|
-
detached: true,
|
|
16087
|
-
stdio: ["ignore", stdoutFd, stderrFd]
|
|
16088
|
-
});
|
|
16089
|
-
closeSync2(stdoutFd);
|
|
16090
|
-
closeSync2(stderrFd);
|
|
16091
|
-
stdoutFd = undefined;
|
|
16092
|
-
stderrFd = undefined;
|
|
16093
|
-
child.unref();
|
|
16094
|
-
const connected = await waitForSignupCommanderConnection(logFile, 30000);
|
|
16095
|
-
if (!connected) {
|
|
16096
|
-
return {
|
|
16097
|
-
status: "failed",
|
|
16098
|
-
runnerId,
|
|
16099
|
-
restartCommand,
|
|
16100
|
-
error: `Local Commander did not connect within 30 seconds. Check ${logFile}`
|
|
16101
|
-
};
|
|
16102
|
-
}
|
|
16366
|
+
const handle = await runLocalCodexRunner(await signupCommanderRunnerOptions(args, runnerId));
|
|
16103
16367
|
return {
|
|
16104
16368
|
status: "started",
|
|
16105
16369
|
runnerId,
|
|
16106
16370
|
restartCommand,
|
|
16107
|
-
|
|
16108
|
-
|
|
16371
|
+
pid: process.pid,
|
|
16372
|
+
instanceId: handle.instanceId,
|
|
16373
|
+
codexUrl: handle.codexUrl
|
|
16109
16374
|
};
|
|
16110
16375
|
} catch (error) {
|
|
16111
16376
|
return {
|
|
@@ -16114,82 +16379,58 @@ async function defaultSignupCommanderLauncher(args) {
|
|
|
16114
16379
|
restartCommand,
|
|
16115
16380
|
error: error instanceof Error ? error.message : String(error)
|
|
16116
16381
|
};
|
|
16117
|
-
} finally {
|
|
16118
|
-
closeFileDescriptor(stdoutFd);
|
|
16119
|
-
closeFileDescriptor(stderrFd);
|
|
16120
|
-
}
|
|
16121
|
-
}
|
|
16122
|
-
async function waitForSignupCommanderConnection(logFile, timeoutMs) {
|
|
16123
|
-
const deadline = Date.now() + timeoutMs;
|
|
16124
|
-
while (Date.now() <= deadline) {
|
|
16125
|
-
const log = readTextFile(logFile);
|
|
16126
|
-
if (log !== undefined && signupCommanderLogIsConnected(log)) {
|
|
16127
|
-
return true;
|
|
16128
|
-
}
|
|
16129
|
-
await waitForSignupCommanderLogChange(logFile, deadline, () => {
|
|
16130
|
-
const updatedLog = readTextFile(logFile);
|
|
16131
|
-
return updatedLog !== undefined && signupCommanderLogIsConnected(updatedLog);
|
|
16132
|
-
});
|
|
16133
16382
|
}
|
|
16134
|
-
return false;
|
|
16135
|
-
}
|
|
16136
|
-
function signupCommanderLogIsConnected(log) {
|
|
16137
|
-
return commanderConnectedMarkers.some((marker) => log.includes(marker));
|
|
16138
|
-
}
|
|
16139
|
-
function readTextFile(path) {
|
|
16140
|
-
try {
|
|
16141
|
-
return readFileSync10(path, "utf8");
|
|
16142
|
-
} catch (_error) {
|
|
16143
|
-
return;
|
|
16144
|
-
}
|
|
16145
|
-
}
|
|
16146
|
-
function closeFileDescriptor(fd) {
|
|
16147
|
-
if (fd === undefined) {
|
|
16148
|
-
return;
|
|
16149
|
-
}
|
|
16150
|
-
try {
|
|
16151
|
-
closeSync2(fd);
|
|
16152
|
-
} catch (_error) {}
|
|
16153
|
-
}
|
|
16154
|
-
async function waitForSignupCommanderLogChange(logFile, deadline, ready2) {
|
|
16155
|
-
const remaining = Math.max(0, deadline - Date.now());
|
|
16156
|
-
await new Promise((resolve9) => {
|
|
16157
|
-
let resolved = false;
|
|
16158
|
-
let watcher;
|
|
16159
|
-
const finish = () => {
|
|
16160
|
-
if (resolved) {
|
|
16161
|
-
return;
|
|
16162
|
-
}
|
|
16163
|
-
resolved = true;
|
|
16164
|
-
watcher?.close();
|
|
16165
|
-
clearTimeout(timer);
|
|
16166
|
-
resolve9();
|
|
16167
|
-
};
|
|
16168
|
-
const timer = setTimeout(finish, remaining);
|
|
16169
|
-
try {
|
|
16170
|
-
watcher = watch(logFile, finish);
|
|
16171
|
-
watcher.on("error", finish);
|
|
16172
|
-
if (ready2()) {
|
|
16173
|
-
finish();
|
|
16174
|
-
}
|
|
16175
|
-
} catch (_error) {
|
|
16176
|
-
if (ready2()) {
|
|
16177
|
-
finish();
|
|
16178
|
-
return;
|
|
16179
|
-
}
|
|
16180
|
-
try {
|
|
16181
|
-
watcher = watch(dirname9(logFile), finish);
|
|
16182
|
-
watcher.on("error", finish);
|
|
16183
|
-
} catch (_nestedError) {}
|
|
16184
|
-
}
|
|
16185
|
-
});
|
|
16186
16383
|
}
|
|
16187
16384
|
function signupCommanderRunnerId(workspaceSlug) {
|
|
16188
16385
|
return `signup-${workspaceSlug}-commander`;
|
|
16189
16386
|
}
|
|
16190
|
-
function
|
|
16191
|
-
|
|
16192
|
-
|
|
16387
|
+
function failedSignupCommanderLaunchForMissingCodex(args) {
|
|
16388
|
+
return {
|
|
16389
|
+
status: "failed",
|
|
16390
|
+
runnerId: signupCommanderRunnerId(args.workspaceSlug),
|
|
16391
|
+
restartCommand: signupConnectRestartCommand(args),
|
|
16392
|
+
error: "Codex preflight did not resolve a verified Codex command. Install Codex or fix the Codex CLI on PATH, then rerun signup."
|
|
16393
|
+
};
|
|
16394
|
+
}
|
|
16395
|
+
async function signupCommanderRunnerOptions(args, runnerId) {
|
|
16396
|
+
const trust = kandanTlsTrustFromEnv();
|
|
16397
|
+
const editorRuntime = await resolveEditorRuntime({
|
|
16398
|
+
kandanUrl: args.serviceUrl,
|
|
16399
|
+
token: args.localRunnerAccessToken,
|
|
16400
|
+
fetchImpl: trustedFetch(trust)
|
|
16401
|
+
});
|
|
16402
|
+
const dependencyStatus = await buildRunnerDependencyStatus({
|
|
16403
|
+
cwd: args.projectPath,
|
|
16404
|
+
codexBin: args.codexBin,
|
|
16405
|
+
codeServerBin: editorRuntime.codeServerBin,
|
|
16406
|
+
editorRuntime: editorRuntime.status
|
|
16407
|
+
});
|
|
16408
|
+
assertStartDependencies(dependencyStatus);
|
|
16409
|
+
return {
|
|
16410
|
+
kandanUrl: args.serviceUrl,
|
|
16411
|
+
token: args.localRunnerAccessToken,
|
|
16412
|
+
runnerId,
|
|
16413
|
+
machineId: ensureLocalMachineIdForLinzumiUrl(args.serviceUrl),
|
|
16414
|
+
workspaceSlug: args.workspaceSlug,
|
|
16415
|
+
cwd: args.projectPath,
|
|
16416
|
+
codexBin: args.codexBin,
|
|
16417
|
+
codexUrl: undefined,
|
|
16418
|
+
launchTui: false,
|
|
16419
|
+
fast: false,
|
|
16420
|
+
allowedCwds: Array.from(new Set([args.projectPath, ...args.selectedProjectPaths])),
|
|
16421
|
+
allowedForwardPorts: [],
|
|
16422
|
+
codeServerBin: editorRuntime.codeServerBin,
|
|
16423
|
+
editorRuntime: editorRuntime.runtime,
|
|
16424
|
+
socketFactory: trustedWebSocketFactory(trust),
|
|
16425
|
+
dependencyStatus,
|
|
16426
|
+
runtimeDefaults: {
|
|
16427
|
+
model: undefined,
|
|
16428
|
+
reasoningEffort: undefined,
|
|
16429
|
+
approvalPolicy: undefined,
|
|
16430
|
+
sandbox: undefined
|
|
16431
|
+
},
|
|
16432
|
+
channelSession: undefined
|
|
16433
|
+
};
|
|
16193
16434
|
}
|
|
16194
16435
|
function signupConnectRestartCommand(args) {
|
|
16195
16436
|
return [
|
|
@@ -16199,23 +16440,12 @@ function signupConnectRestartCommand(args) {
|
|
|
16199
16440
|
"connect",
|
|
16200
16441
|
"--workspace",
|
|
16201
16442
|
args.workspaceSlug,
|
|
16202
|
-
...args.
|
|
16443
|
+
...args.codexBin === undefined ? [] : ["--codex-bin", args.codexBin],
|
|
16444
|
+
"--cwd",
|
|
16445
|
+
args.projectPath,
|
|
16446
|
+
...args.serviceUrl === defaultLinzumiHttpUrl ? [] : ["--api-url", args.serviceUrl]
|
|
16203
16447
|
].map(shellArg).join(" ");
|
|
16204
16448
|
}
|
|
16205
|
-
function signupCommanderConnectSpawnArgs(args, runnerId, logFile, scriptPath) {
|
|
16206
|
-
return [
|
|
16207
|
-
scriptPath,
|
|
16208
|
-
"connect",
|
|
16209
|
-
"--linzumi-url",
|
|
16210
|
-
args.serviceUrl,
|
|
16211
|
-
"--workspace",
|
|
16212
|
-
args.workspaceSlug,
|
|
16213
|
-
"--runner-id",
|
|
16214
|
-
runnerId,
|
|
16215
|
-
"--log-file",
|
|
16216
|
-
logFile
|
|
16217
|
-
];
|
|
16218
|
-
}
|
|
16219
16449
|
function shellArg(value) {
|
|
16220
16450
|
if (/^[A-Za-z0-9_./:=@%+-]+$/.test(value)) {
|
|
16221
16451
|
return value;
|
|
@@ -17036,6 +17266,10 @@ function defaultPreflightRuntime() {
|
|
|
17036
17266
|
checkBrowserHandoff: async () => true
|
|
17037
17267
|
};
|
|
17038
17268
|
}
|
|
17269
|
+
function verifiedCodexBinFromPreflightChecks(checks) {
|
|
17270
|
+
const codex = checks.find((check2) => check2.id === "codex");
|
|
17271
|
+
return codex?.command;
|
|
17272
|
+
}
|
|
17039
17273
|
function defaultProjectDiscoveryRuntime() {
|
|
17040
17274
|
const cwd = process.cwd();
|
|
17041
17275
|
return {
|
|
@@ -17162,13 +17396,9 @@ async function resolveSignupCodexCommand(env = process.env, homeDir = homedir8()
|
|
|
17162
17396
|
env.LINZUMI_CODEX_BIN
|
|
17163
17397
|
]);
|
|
17164
17398
|
if (override !== undefined) {
|
|
17165
|
-
return
|
|
17399
|
+
return resolveCodexCommandOverride(override, homeDir);
|
|
17166
17400
|
}
|
|
17167
|
-
const homeCandidates =
|
|
17168
|
-
join12(homeDir, ".volta", "bin", "codex"),
|
|
17169
|
-
join12(homeDir, ".local", "bin", "codex"),
|
|
17170
|
-
join12(homeDir, "bin", "codex")
|
|
17171
|
-
];
|
|
17401
|
+
const homeCandidates = homeManagedCodexCandidates(homeDir);
|
|
17172
17402
|
const homeCodex = await firstExecutablePath(homeCandidates, executableExists);
|
|
17173
17403
|
if (homeCodex !== undefined) {
|
|
17174
17404
|
return homeCodex;
|
|
@@ -17200,6 +17430,20 @@ function resolveHomePath(path, homeDir) {
|
|
|
17200
17430
|
}
|
|
17201
17431
|
return resolve8(path);
|
|
17202
17432
|
}
|
|
17433
|
+
function resolveCodexCommandOverride(command, homeDir) {
|
|
17434
|
+
const trimmed = command.trim();
|
|
17435
|
+
return commandLooksPathLike(trimmed) ? resolveHomePath(trimmed, homeDir) : trimmed;
|
|
17436
|
+
}
|
|
17437
|
+
function commandLooksPathLike(command) {
|
|
17438
|
+
return command === "~" || command.startsWith("~/") || command.startsWith("/") || command.startsWith("./") || command.startsWith("../") || command.includes("/") || command.includes("\\");
|
|
17439
|
+
}
|
|
17440
|
+
function homeManagedCodexCandidates(homeDir) {
|
|
17441
|
+
return [
|
|
17442
|
+
join12(homeDir, ".volta", "bin", "codex"),
|
|
17443
|
+
join12(homeDir, ".local", "bin", "codex"),
|
|
17444
|
+
join12(homeDir, "bin", "codex")
|
|
17445
|
+
];
|
|
17446
|
+
}
|
|
17203
17447
|
async function firstExecutablePath(paths, executableExists) {
|
|
17204
17448
|
for (const path of paths) {
|
|
17205
17449
|
if (await executableExists(path)) {
|
|
@@ -17363,19 +17607,51 @@ async function checkGit(runtime) {
|
|
|
17363
17607
|
};
|
|
17364
17608
|
}
|
|
17365
17609
|
async function checkCodex(runtime) {
|
|
17366
|
-
const
|
|
17367
|
-
|
|
17368
|
-
|
|
17369
|
-
|
|
17370
|
-
|
|
17371
|
-
|
|
17610
|
+
const configuredCodex = process.env.LINZUMI_SIGNUP_CODEX_BIN !== undefined && process.env.LINZUMI_SIGNUP_CODEX_BIN.trim() !== "" ? {
|
|
17611
|
+
value: process.env.LINZUMI_SIGNUP_CODEX_BIN,
|
|
17612
|
+
source: "LINZUMI_SIGNUP_CODEX_BIN"
|
|
17613
|
+
} : process.env.LINZUMI_CODEX_BIN !== undefined && process.env.LINZUMI_CODEX_BIN.trim() !== "" ? {
|
|
17614
|
+
value: process.env.LINZUMI_CODEX_BIN,
|
|
17615
|
+
source: "LINZUMI_CODEX_BIN"
|
|
17616
|
+
} : undefined;
|
|
17617
|
+
const configuredCommand = configuredCodex === undefined ? undefined : resolveCodexCommandOverride(configuredCodex.value, runtime.homeDir);
|
|
17618
|
+
if (configuredCommand !== undefined) {
|
|
17619
|
+
const codex2 = await runtime.probeTool(configuredCommand, runtime.cwd);
|
|
17620
|
+
const location2 = `from ${configuredCodex?.source ?? "configured env"}`;
|
|
17621
|
+
return {
|
|
17622
|
+
id: "codex",
|
|
17623
|
+
title: "Codex CLI",
|
|
17624
|
+
detail: codex2.available ? `${codex2.version ?? "codex found"} ${location2}` : `${configuredCommand} ${location2} did not pass --version`,
|
|
17625
|
+
status: codex2.available ? "pass" : "warn",
|
|
17626
|
+
command: codex2.available ? codex2.command : undefined
|
|
17627
|
+
};
|
|
17628
|
+
}
|
|
17629
|
+
const candidates = ["codex", ...homeManagedCodexCandidates(runtime.homeDir)];
|
|
17630
|
+
const [firstCodex, ...otherCodexes] = await Promise.all(candidates.map((candidate) => runtime.probeTool(candidate, runtime.cwd)));
|
|
17631
|
+
const codex = [firstCodex, ...otherCodexes].find((status) => status.available) ?? firstCodex;
|
|
17632
|
+
const location = codexPreflightLocation(codex.command, runtime.homeDir);
|
|
17372
17633
|
return {
|
|
17373
17634
|
id: "codex",
|
|
17374
17635
|
title: "Codex CLI",
|
|
17375
17636
|
detail: codex.available ? `${codex.version ?? "codex found"} ${location}` : "codex not found",
|
|
17376
|
-
status: codex.available ? "pass" : "warn"
|
|
17637
|
+
status: codex.available ? "pass" : "warn",
|
|
17638
|
+
command: codex.available ? codex.command : undefined
|
|
17377
17639
|
};
|
|
17378
17640
|
}
|
|
17641
|
+
function codexPreflightLocation(command, homeDir) {
|
|
17642
|
+
switch (command) {
|
|
17643
|
+
case "codex":
|
|
17644
|
+
return "on PATH";
|
|
17645
|
+
case join12(homeDir, ".volta", "bin", "codex"):
|
|
17646
|
+
return "via Volta";
|
|
17647
|
+
case join12(homeDir, ".local", "bin", "codex"):
|
|
17648
|
+
return "via ~/.local/bin";
|
|
17649
|
+
case join12(homeDir, "bin", "codex"):
|
|
17650
|
+
return "via ~/bin";
|
|
17651
|
+
default:
|
|
17652
|
+
return "from configured path";
|
|
17653
|
+
}
|
|
17654
|
+
}
|
|
17379
17655
|
async function checkGitEmail(runtime) {
|
|
17380
17656
|
const email = await runtime.readGitEmail(runtime.cwd);
|
|
17381
17657
|
return {
|
|
@@ -17703,15 +17979,15 @@ function renderPreflightRow(check2, spinnerFrame, columns) {
|
|
|
17703
17979
|
// src/commanderDaemon.ts
|
|
17704
17980
|
import {
|
|
17705
17981
|
existsSync as existsSync11,
|
|
17706
|
-
closeSync as
|
|
17982
|
+
closeSync as closeSync2,
|
|
17707
17983
|
mkdirSync as mkdirSync11,
|
|
17708
|
-
openSync as
|
|
17984
|
+
openSync as openSync3,
|
|
17709
17985
|
readFileSync as readFileSync11,
|
|
17710
|
-
watch
|
|
17986
|
+
watch,
|
|
17711
17987
|
writeFileSync as writeFileSync9
|
|
17712
17988
|
} from "node:fs";
|
|
17713
17989
|
import { homedir as homedir9 } from "node:os";
|
|
17714
|
-
import { dirname as
|
|
17990
|
+
import { dirname as dirname9, join as join13, resolve as resolve9 } from "node:path";
|
|
17715
17991
|
import { execFileSync, spawn as spawn8 } from "node:child_process";
|
|
17716
17992
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
17717
17993
|
var connectedMarkers = ["Connected to Linzumi", "Runner connected:"];
|
|
@@ -17744,9 +18020,9 @@ function startCommanderDaemon(options) {
|
|
|
17744
18020
|
logFile
|
|
17745
18021
|
];
|
|
17746
18022
|
mkdirSync11(statusDir, { recursive: true });
|
|
17747
|
-
mkdirSync11(
|
|
17748
|
-
const out =
|
|
17749
|
-
const err =
|
|
18023
|
+
mkdirSync11(dirname9(logFile), { recursive: true });
|
|
18024
|
+
const out = openSync3(logFile, "a");
|
|
18025
|
+
const err = openSync3(logFile, "a");
|
|
17750
18026
|
writeCliAuditEvent("process.spawn", {
|
|
17751
18027
|
command: nodeBin,
|
|
17752
18028
|
args: command,
|
|
@@ -17765,8 +18041,8 @@ function startCommanderDaemon(options) {
|
|
|
17765
18041
|
pid: child.pid,
|
|
17766
18042
|
purpose: "commander_daemon.start"
|
|
17767
18043
|
}, { sessionId: options.runnerId });
|
|
17768
|
-
|
|
17769
|
-
|
|
18044
|
+
closeSync2(out);
|
|
18045
|
+
closeSync2(err);
|
|
17770
18046
|
child.unref();
|
|
17771
18047
|
if (child.pid === undefined) {
|
|
17772
18048
|
throw new Error("commander daemon did not report a pid");
|
|
@@ -17796,7 +18072,7 @@ function commanderDaemonStatus(runnerId, statusDir = commanderStatusDir(), proce
|
|
|
17796
18072
|
}
|
|
17797
18073
|
async function waitForCommanderDaemon(options) {
|
|
17798
18074
|
const now = options.now ?? (() => Date.now());
|
|
17799
|
-
const
|
|
18075
|
+
const readTextFile = options.readTextFile ?? ((path) => existsSync11(path) ? readFileSync11(path, "utf8") : undefined);
|
|
17800
18076
|
const statusImpl = options.statusImpl ?? commanderDaemonStatus;
|
|
17801
18077
|
const deadline = now() + options.timeoutMs;
|
|
17802
18078
|
while (now() <= deadline) {
|
|
@@ -17807,7 +18083,7 @@ async function waitForCommanderDaemon(options) {
|
|
|
17807
18083
|
case "stopped":
|
|
17808
18084
|
return { ok: false, reason: "stopped" };
|
|
17809
18085
|
case "running": {
|
|
17810
|
-
const log =
|
|
18086
|
+
const log = readTextFile(status.record.logFile);
|
|
17811
18087
|
if (log === undefined) {
|
|
17812
18088
|
return { ok: false, reason: "timeout" };
|
|
17813
18089
|
}
|
|
@@ -17815,7 +18091,7 @@ async function waitForCommanderDaemon(options) {
|
|
|
17815
18091
|
return { ok: true, record: status.record };
|
|
17816
18092
|
}
|
|
17817
18093
|
await waitForFileChangeOrTimeout(status.record.logFile, deadline, now, () => {
|
|
17818
|
-
const updatedLog =
|
|
18094
|
+
const updatedLog = readTextFile(status.record.logFile);
|
|
17819
18095
|
return updatedLog !== undefined && commanderLogIsConnected(updatedLog);
|
|
17820
18096
|
});
|
|
17821
18097
|
}
|
|
@@ -17941,7 +18217,7 @@ async function waitForFileChangeOrTimeout(path, deadline, now, ready2 = () => fa
|
|
|
17941
18217
|
};
|
|
17942
18218
|
const timer = setTimeout(finish, remaining);
|
|
17943
18219
|
try {
|
|
17944
|
-
watcher =
|
|
18220
|
+
watcher = watch(path, finish);
|
|
17945
18221
|
watcher.on("error", finish);
|
|
17946
18222
|
if (ready2()) {
|
|
17947
18223
|
finish();
|
|
@@ -17959,8 +18235,8 @@ async function waitForFileChangeOrTimeout(path, deadline, now, ready2 = () => fa
|
|
|
17959
18235
|
// src/index.ts
|
|
17960
18236
|
var flagDefinitions = new Map([
|
|
17961
18237
|
["version", { kind: "boolean" }],
|
|
18238
|
+
["api-url", { kind: "value" }],
|
|
17962
18239
|
["linzumi-url", { kind: "value" }],
|
|
17963
|
-
["kandan-url", { kind: "value" }],
|
|
17964
18240
|
["token", { kind: "value" }],
|
|
17965
18241
|
["runner-id", { kind: "value" }],
|
|
17966
18242
|
["cwd", { kind: "value" }],
|
|
@@ -17970,12 +18246,12 @@ var flagDefinitions = new Map([
|
|
|
17970
18246
|
["workspace", { kind: "value" }],
|
|
17971
18247
|
["channel", { kind: "value" }],
|
|
17972
18248
|
["linzumi-thread-id", { kind: "value" }],
|
|
17973
|
-
["kandan-thread-id", { kind: "value" }],
|
|
17974
18249
|
["listen-user", { kind: "value" }],
|
|
17975
18250
|
["model", { kind: "value" }],
|
|
17976
18251
|
["reasoning-effort", { kind: "value" }],
|
|
17977
18252
|
["sandbox", { kind: "value" }],
|
|
17978
18253
|
["approval-policy", { kind: "value" }],
|
|
18254
|
+
["allow-port-forwarding-by-default", { kind: "boolean" }],
|
|
17979
18255
|
["stream-flush-ms", { kind: "value" }],
|
|
17980
18256
|
["allowed-cwd", { kind: "value" }],
|
|
17981
18257
|
["forward-port", { kind: "value" }],
|
|
@@ -17989,10 +18265,6 @@ var flagDefinitions = new Map([
|
|
|
17989
18265
|
["oauth-callback-host", { kind: "value" }],
|
|
17990
18266
|
["help", { kind: "boolean" }]
|
|
17991
18267
|
]);
|
|
17992
|
-
var flagAliases = new Map([
|
|
17993
|
-
["kandan-url", "linzumi-url"],
|
|
17994
|
-
["kandan-thread-id", "linzumi-thread-id"]
|
|
17995
|
-
]);
|
|
17996
18268
|
var helloFlagDefinitions = new Map([
|
|
17997
18269
|
["dir", { kind: "value" }],
|
|
17998
18270
|
["parent-dir", { kind: "value" }],
|
|
@@ -18248,8 +18520,7 @@ function parsePathsCommandArgs(args) {
|
|
|
18248
18520
|
case "--help":
|
|
18249
18521
|
help = true;
|
|
18250
18522
|
break;
|
|
18251
|
-
case "--
|
|
18252
|
-
case "--kandan-url": {
|
|
18523
|
+
case "--api-url": {
|
|
18253
18524
|
const value = args[index + 1];
|
|
18254
18525
|
if (value === undefined || value.startsWith("--")) {
|
|
18255
18526
|
throw new Error(`missing value for ${arg}`);
|
|
@@ -18360,7 +18631,7 @@ async function runAuthCommand(args) {
|
|
|
18360
18631
|
process.stdout.write(helpText());
|
|
18361
18632
|
return;
|
|
18362
18633
|
}
|
|
18363
|
-
const kandanUrl =
|
|
18634
|
+
const kandanUrl = requiredKandanUrl(values);
|
|
18364
18635
|
const target = parseOptionalChannelTarget(values);
|
|
18365
18636
|
const token = await acquireLocalRunnerTokenDetails({
|
|
18366
18637
|
kandanUrl,
|
|
@@ -18391,7 +18662,7 @@ async function parseStartRunnerArgs(args, deps = {
|
|
|
18391
18662
|
process.exit(0);
|
|
18392
18663
|
}
|
|
18393
18664
|
rejectStartTargetingFlags(values);
|
|
18394
|
-
const kandanUrl =
|
|
18665
|
+
const kandanUrl = kandanUrlValue(values) ?? defaultLinzumiWebSocketUrl;
|
|
18395
18666
|
const requestedCwd = resolveUserPath(cwdArg ?? process.cwd());
|
|
18396
18667
|
const cwd = assertConfiguredAllowedCwds([requestedCwd])[0] ?? requestedCwd;
|
|
18397
18668
|
const explicitAllowedCwds = values.has("allowed-cwd") ? assertConfiguredAllowedCwds(parseAllowedCwdList(stringValue4(values, "allowed-cwd"))) : [];
|
|
@@ -18475,6 +18746,7 @@ async function parseStartRunnerArgs(args, deps = {
|
|
|
18475
18746
|
reasoningEffort: stringValue4(values, "reasoning-effort"),
|
|
18476
18747
|
sandbox: stringValue4(values, "sandbox"),
|
|
18477
18748
|
approvalPolicy: stringValue4(values, "approval-policy"),
|
|
18749
|
+
allowPortForwardingByDefault: booleanFlagValue(values, "allow-port-forwarding-by-default"),
|
|
18478
18750
|
streamFlushMs: positiveIntegerValue2(values, "stream-flush-ms")
|
|
18479
18751
|
}
|
|
18480
18752
|
};
|
|
@@ -18507,9 +18779,10 @@ async function parseAgentRunnerArgs(args, deps = {
|
|
|
18507
18779
|
reasoningEffort: stringValue4(values, "reasoning-effort"),
|
|
18508
18780
|
sandbox: stringValue4(values, "sandbox"),
|
|
18509
18781
|
approvalPolicy: stringValue4(values, "approval-policy"),
|
|
18782
|
+
allowPortForwardingByDefault: booleanFlagValue(values, "allow-port-forwarding-by-default"),
|
|
18510
18783
|
streamFlushMs: positiveIntegerValue2(values, "stream-flush-ms")
|
|
18511
18784
|
};
|
|
18512
|
-
const kandanUrl =
|
|
18785
|
+
const kandanUrl = kandanUrlValue(values) ?? agentApiUrlToKandanUrl(tokenFile.apiUrl);
|
|
18513
18786
|
const requestedCwdValue = cwdArg ?? stringValue4(values, "cwd");
|
|
18514
18787
|
const requestedCwd = resolveUserPath(requestedCwdValue ?? process.cwd());
|
|
18515
18788
|
const configuredAllowedCwds2 = requestedCwdValue === undefined && !values.has("allowed-cwd") ? readConfiguredAllowedCwdDetailsForLinzumiUrl(kandanUrl) : { allowedCwds: [], missingAllowedCwds: [] };
|
|
@@ -18641,7 +18914,7 @@ async function parseRunnerArgs(args, deps = {
|
|
|
18641
18914
|
}
|
|
18642
18915
|
rejectConnectChannelFlags(values);
|
|
18643
18916
|
const workspaceSlug = stringValue4(values, "workspace");
|
|
18644
|
-
const kandanUrl =
|
|
18917
|
+
const kandanUrl = kandanUrlValue(values) ?? defaultLinzumiWebSocketUrl;
|
|
18645
18918
|
const cwd = stringValue4(values, "cwd") ?? process.cwd();
|
|
18646
18919
|
const cwdAllowedCwds = assertConfiguredAllowedCwds([cwd]);
|
|
18647
18920
|
const localConfiguredAllowedCwds = values.has("allowed-cwd") ? { allowedCwds: [], missingAllowedCwds: [] } : readConfiguredAllowedCwdDetailsForLinzumiUrl(kandanUrl);
|
|
@@ -18699,9 +18972,28 @@ function runnerRuntimeDefaultsFromValues(values) {
|
|
|
18699
18972
|
model: stringValue4(values, "model"),
|
|
18700
18973
|
reasoningEffort: stringValue4(values, "reasoning-effort"),
|
|
18701
18974
|
approvalPolicy: stringValue4(values, "approval-policy"),
|
|
18702
|
-
sandbox: stringValue4(values, "sandbox")
|
|
18975
|
+
sandbox: stringValue4(values, "sandbox"),
|
|
18976
|
+
allowPortForwardingByDefault: booleanFlagValue(values, "allow-port-forwarding-by-default")
|
|
18703
18977
|
};
|
|
18704
18978
|
}
|
|
18979
|
+
function kandanUrlValue(values) {
|
|
18980
|
+
const apiUrl = stringValue4(values, "api-url");
|
|
18981
|
+
const linzumiUrl = stringValue4(values, "linzumi-url");
|
|
18982
|
+
if (apiUrl !== undefined && linzumiUrl !== undefined && apiUrl !== linzumiUrl) {
|
|
18983
|
+
throw new Error("use only one of --api-url or --linzumi-url");
|
|
18984
|
+
}
|
|
18985
|
+
return apiUrl ?? linzumiUrl;
|
|
18986
|
+
}
|
|
18987
|
+
function requiredKandanUrl(values) {
|
|
18988
|
+
const value = kandanUrlValue(values);
|
|
18989
|
+
if (value === undefined) {
|
|
18990
|
+
throw new Error("missing required flag: --api-url or --linzumi-url");
|
|
18991
|
+
}
|
|
18992
|
+
return value;
|
|
18993
|
+
}
|
|
18994
|
+
function booleanFlagValue(values, key) {
|
|
18995
|
+
return values.get(key) === true ? true : undefined;
|
|
18996
|
+
}
|
|
18705
18997
|
function strictFlagValues(args, definitions = flagDefinitions) {
|
|
18706
18998
|
const values = new Map;
|
|
18707
18999
|
for (let index = 0;index < args.length; index += 1) {
|
|
@@ -18714,16 +19006,15 @@ function strictFlagValues(args, definitions = flagDefinitions) {
|
|
|
18714
19006
|
if (definition === undefined) {
|
|
18715
19007
|
throw new Error(`invalid flag: --${rawKey}`);
|
|
18716
19008
|
}
|
|
18717
|
-
const key = flagAliases.get(rawKey) ?? rawKey;
|
|
18718
19009
|
if (definition.kind === "boolean") {
|
|
18719
|
-
values.set(
|
|
19010
|
+
values.set(rawKey, true);
|
|
18720
19011
|
continue;
|
|
18721
19012
|
}
|
|
18722
19013
|
const next = args[index + 1];
|
|
18723
19014
|
if (next === undefined || next.startsWith("--")) {
|
|
18724
19015
|
throw new Error(`missing value for --${rawKey}`);
|
|
18725
19016
|
}
|
|
18726
|
-
values.set(
|
|
19017
|
+
values.set(rawKey, next);
|
|
18727
19018
|
index += 1;
|
|
18728
19019
|
}
|
|
18729
19020
|
return values;
|
|
@@ -18905,11 +19196,11 @@ Usage:
|
|
|
18905
19196
|
linzumi start <folder> [options]
|
|
18906
19197
|
linzumi paths list|add|remove [path]
|
|
18907
19198
|
linzumi connect --workspace <slug> [options]
|
|
18908
|
-
linzumi auth --
|
|
19199
|
+
linzumi auth --api-url <url> [--workspace <slug> --channel <slug>]
|
|
18909
19200
|
|
|
18910
19201
|
Connection:
|
|
18911
|
-
--
|
|
18912
|
-
|
|
19202
|
+
--api-url <url> Linzumi API URL, default ${defaultLinzumiWebSocketUrl}
|
|
19203
|
+
--linzumi-url <url> Alias for --api-url
|
|
18913
19204
|
--token <jwt> Optional override token. Otherwise ~/.linzumi/auth.json is validated or OAuth opens.
|
|
18914
19205
|
--auth-file <path> Auth cache path, default ~/.linzumi/auth.json
|
|
18915
19206
|
--oauth-callback-host <ip> Callback host reachable by your browser
|
|
@@ -18926,6 +19217,8 @@ Codex:
|
|
|
18926
19217
|
--reasoning-effort <value> Reasoning effort requested for Codex and shown in Linzumi
|
|
18927
19218
|
--sandbox <value> Sandbox metadata shown in Linzumi
|
|
18928
19219
|
--approval-policy <value> Approval-policy metadata shown in Linzumi
|
|
19220
|
+
--allow-port-forwarding-by-default
|
|
19221
|
+
Auto-approve detected port-forward candidates for started sessions
|
|
18929
19222
|
--stream-flush-ms <ms> Batch live Codex deltas before Linzumi persistence, default 150
|
|
18930
19223
|
--fast Mark this runner as low-latency/fast in the availability message
|
|
18931
19224
|
--log-file <path> JSONL event log path, default <cwd>/.linzumi-runner.log
|
|
@@ -19022,12 +19315,12 @@ function pathsHelpText() {
|
|
|
19022
19315
|
return `Linzumi trusted paths
|
|
19023
19316
|
|
|
19024
19317
|
Usage:
|
|
19025
|
-
linzumi paths [--
|
|
19026
|
-
linzumi paths [--
|
|
19027
|
-
linzumi paths [--
|
|
19318
|
+
linzumi paths [--api-url <url>] list
|
|
19319
|
+
linzumi paths [--api-url <url>] add <path>
|
|
19320
|
+
linzumi paths [--api-url <url>] remove <path>
|
|
19028
19321
|
|
|
19029
19322
|
Trusted paths are stored in ~/.linzumi/config.json. Production/default paths
|
|
19030
|
-
use the root config fields; explicit --
|
|
19323
|
+
use the root config fields; explicit --api-url paths use a URL-scoped config
|
|
19031
19324
|
section so local, staging, and production runners do not share trust state.
|
|
19032
19325
|
`;
|
|
19033
19326
|
}
|
|
@@ -19044,8 +19337,7 @@ What it does:
|
|
|
19044
19337
|
previews, and the browser VS Code editor.
|
|
19045
19338
|
|
|
19046
19339
|
Options:
|
|
19047
|
-
--
|
|
19048
|
-
(deprecated alias: --kandan-url)
|
|
19340
|
+
--api-url <url> Linzumi API URL, default ${defaultLinzumiWebSocketUrl}
|
|
19049
19341
|
--token <jwt> Optional scoped local-runner token override
|
|
19050
19342
|
--auth-file <path> Auth cache path, default ~/.linzumi/auth.json
|
|
19051
19343
|
--oauth-callback-host <ip> Callback host reachable by your browser
|
|
@@ -19085,8 +19377,7 @@ What it does:
|
|
|
19085
19377
|
|
|
19086
19378
|
Options:
|
|
19087
19379
|
--agent-token-file <path> Agent token cache, default ~/.linzumi/agent-token.json
|
|
19088
|
-
--
|
|
19089
|
-
(deprecated alias: --kandan-url)
|
|
19380
|
+
--api-url <url> Linzumi API URL. Defaults deterministically from the stored apiUrl.
|
|
19090
19381
|
--runner-id <id> Stable Commander id
|
|
19091
19382
|
--codex-bin <path> Codex executable, default codex
|
|
19092
19383
|
--code-server-bin <path> Custom development code-server executable. By default Linzumi installs the approved editor runtime.
|
|
@@ -19102,7 +19393,7 @@ Options:
|
|
|
19102
19393
|
Examples:
|
|
19103
19394
|
linzumi paths add "$PWD"
|
|
19104
19395
|
linzumi commander daemon --runner-id hello-world-commander
|
|
19105
|
-
linzumi commander ~/code/my-app --
|
|
19396
|
+
linzumi commander ~/code/my-app --api-url http://127.0.0.1:4162 --runner-id local-qa-commander
|
|
19106
19397
|
`;
|
|
19107
19398
|
}
|
|
19108
19399
|
function connectGuideText() {
|