@linzumi/cli 0.0.51-beta → 0.0.52-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 +1 -1
- package/dist/index.js +706 -336
- 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.52-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,7 +11240,12 @@ 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 codexThreads = options.channelSession === undefined ? await discoverCodexThreads(codex, options.cwd)
|
|
11243
|
+
const codexThreads = options.channelSession === undefined ? await discoverCodexThreads(codex, options.cwd).catch((error) => {
|
|
11244
|
+
log("kandan.codex_threads_startup_discovery_failed", {
|
|
11245
|
+
message: error instanceof Error ? error.message : String(error)
|
|
11246
|
+
});
|
|
11247
|
+
return [];
|
|
11248
|
+
}) : [];
|
|
10921
11249
|
const discoveredCodexThreads = { value: codexThreads };
|
|
10922
11250
|
const runtimeDefaults = runnerRuntimeDefaults(options);
|
|
10923
11251
|
const instancePayload = {
|
|
@@ -10932,6 +11260,7 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
|
|
|
10932
11260
|
channel: options.channelSession?.channelSlug ?? null,
|
|
10933
11261
|
model: runtimeDefaults.model ?? null,
|
|
10934
11262
|
reasoningEffort: runtimeDefaults.reasoningEffort ?? null,
|
|
11263
|
+
allowPortForwardingByDefault: runtimeDefaults.allowPortForwardingByDefault ?? null,
|
|
10935
11264
|
fast: options.fast ?? false
|
|
10936
11265
|
};
|
|
10937
11266
|
await kandan.push(topic, "instance_started", instancePayload);
|
|
@@ -11039,7 +11368,8 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
|
|
|
11039
11368
|
model: runtimeSettings.model,
|
|
11040
11369
|
reasoningEffort: runtimeSettings.reasoningEffort,
|
|
11041
11370
|
sandbox: runtimeSettings.sandbox,
|
|
11042
|
-
approvalPolicy: runtimeSettings.approvalPolicy
|
|
11371
|
+
approvalPolicy: runtimeSettings.approvalPolicy,
|
|
11372
|
+
allowPortForwardingByDefault: runtimeSettings.allowPortForwardingByDefault
|
|
11043
11373
|
}
|
|
11044
11374
|
},
|
|
11045
11375
|
log
|
|
@@ -11060,6 +11390,7 @@ async function openLocalCodexRunner(options, log, cleanup, close) {
|
|
|
11060
11390
|
codexThreads: discoveredCodexThreads.value,
|
|
11061
11391
|
model: runtimeDefaults.model ?? null,
|
|
11062
11392
|
reasoningEffort: runtimeDefaults.reasoningEffort ?? null,
|
|
11393
|
+
allowPortForwardingByDefault: runtimeDefaults.allowPortForwardingByDefault ?? null,
|
|
11063
11394
|
fast: options.fast ?? false,
|
|
11064
11395
|
capabilities: capabilitiesPayload()
|
|
11065
11396
|
});
|
|
@@ -11350,24 +11681,95 @@ async function closeCleanupStack(cleanup) {
|
|
|
11350
11681
|
})();
|
|
11351
11682
|
return cleanup.closePromise;
|
|
11352
11683
|
}
|
|
11353
|
-
async function discoverCodexThreads(codex,
|
|
11354
|
-
const
|
|
11355
|
-
|
|
11356
|
-
|
|
11684
|
+
async function discoverCodexThreads(codex, _cwd) {
|
|
11685
|
+
const rowsById = new Map;
|
|
11686
|
+
const archivedModes = [false, true];
|
|
11687
|
+
const sourcePasses = [
|
|
11688
|
+
undefined,
|
|
11689
|
+
[
|
|
11690
|
+
"exec",
|
|
11691
|
+
"appServer",
|
|
11692
|
+
"subAgent",
|
|
11693
|
+
"subAgentReview",
|
|
11694
|
+
"subAgentCompact",
|
|
11695
|
+
"subAgentThreadSpawn",
|
|
11696
|
+
"subAgentOther",
|
|
11697
|
+
"unknown"
|
|
11698
|
+
]
|
|
11699
|
+
];
|
|
11700
|
+
for (const archived of archivedModes) {
|
|
11701
|
+
for (const sourceKinds of sourcePasses) {
|
|
11702
|
+
let cursor;
|
|
11703
|
+
while (true) {
|
|
11704
|
+
const response = await codex.request("thread/list", {
|
|
11705
|
+
limit: 50,
|
|
11706
|
+
sortKey: "updated_at",
|
|
11707
|
+
sortDirection: "desc",
|
|
11708
|
+
archived,
|
|
11709
|
+
useStateDbOnly: true,
|
|
11710
|
+
...cursor === undefined ? {} : { cursor },
|
|
11711
|
+
...sourceKinds === undefined ? {} : { sourceKinds }
|
|
11712
|
+
});
|
|
11713
|
+
if ("error" in response) {
|
|
11714
|
+
throw new Error(`thread/list failed: ${response.error.message}`);
|
|
11715
|
+
}
|
|
11716
|
+
const result = objectValue(response.result);
|
|
11717
|
+
const data = arrayValue(result?.data)?.filter(isJsonObject) ?? [];
|
|
11718
|
+
for (const thread of data) {
|
|
11719
|
+
const row = codexThreadHistoryRow(thread, archived);
|
|
11720
|
+
const id = stringValue(objectValue(row)?.id);
|
|
11721
|
+
if (id !== undefined && id !== "" && !rowsById.has(id)) {
|
|
11722
|
+
rowsById.set(id, row);
|
|
11723
|
+
}
|
|
11724
|
+
}
|
|
11725
|
+
const nextCursor = stringValue(result?.nextCursor);
|
|
11726
|
+
if (nextCursor === undefined || nextCursor === "" || data.length === 0) {
|
|
11727
|
+
break;
|
|
11728
|
+
}
|
|
11729
|
+
cursor = nextCursor;
|
|
11730
|
+
}
|
|
11731
|
+
}
|
|
11357
11732
|
}
|
|
11358
|
-
|
|
11359
|
-
|
|
11360
|
-
|
|
11733
|
+
return Array.from(rowsById.values()).sort(compareCodexThreadHistoryRows);
|
|
11734
|
+
}
|
|
11735
|
+
function codexThreadHistoryRow(thread, archived) {
|
|
11736
|
+
const gitInfo = objectValue(thread.gitInfo);
|
|
11737
|
+
const preview = stringValue(thread.preview) ?? "";
|
|
11738
|
+
const name = stringValue(thread.name) ?? "";
|
|
11739
|
+
const title = stringValue(thread.title) ?? (name === "" ? preview : name);
|
|
11740
|
+
const description = stringValue(thread.description) ?? stringValue(thread.summary) ?? preview;
|
|
11741
|
+
return {
|
|
11361
11742
|
id: stringValue(thread.id) ?? "",
|
|
11362
|
-
title:
|
|
11363
|
-
description:
|
|
11364
|
-
preview:
|
|
11743
|
+
title: title ?? "",
|
|
11744
|
+
description: description ?? "",
|
|
11745
|
+
preview: preview.replace(/\s+/g, " ").trim(),
|
|
11365
11746
|
cwd: stringValue(thread.cwd) ?? "",
|
|
11366
11747
|
source: stringValue(thread.source) ?? "",
|
|
11367
|
-
createdAt:
|
|
11368
|
-
updatedAt:
|
|
11369
|
-
|
|
11370
|
-
|
|
11748
|
+
createdAt: codexTimestamp(thread.createdAt),
|
|
11749
|
+
updatedAt: codexTimestamp(thread.updatedAt),
|
|
11750
|
+
archived,
|
|
11751
|
+
modelProvider: stringValue(thread.modelProvider) ?? "",
|
|
11752
|
+
cliVersion: stringValue(thread.cliVersion) ?? "",
|
|
11753
|
+
gitBranch: stringValue(gitInfo?.branch) ?? "",
|
|
11754
|
+
gitOriginUrl: stringValue(gitInfo?.originUrl) ?? "",
|
|
11755
|
+
path: stringValue(thread.path) ?? ""
|
|
11756
|
+
};
|
|
11757
|
+
}
|
|
11758
|
+
function codexTimestamp(value) {
|
|
11759
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
11760
|
+
return new Date(value * 1000).toISOString();
|
|
11761
|
+
}
|
|
11762
|
+
return stringValue(value) ?? "";
|
|
11763
|
+
}
|
|
11764
|
+
function compareCodexThreadHistoryRows(left, right) {
|
|
11765
|
+
const leftRow = objectValue(left);
|
|
11766
|
+
const rightRow = objectValue(right);
|
|
11767
|
+
const leftTime = Date.parse(stringValue(leftRow?.createdAt) ?? stringValue(leftRow?.updatedAt) ?? "");
|
|
11768
|
+
const rightTime = Date.parse(stringValue(rightRow?.createdAt) ?? stringValue(rightRow?.updatedAt) ?? "");
|
|
11769
|
+
return safeComparableTime(leftTime) - safeComparableTime(rightTime);
|
|
11770
|
+
}
|
|
11771
|
+
function safeComparableTime(value) {
|
|
11772
|
+
return Number.isFinite(value) ? value : Number.MAX_SAFE_INTEGER;
|
|
11371
11773
|
}
|
|
11372
11774
|
function extractStartedThreadId(response) {
|
|
11373
11775
|
if ("error" in response) {
|
|
@@ -11801,6 +12203,10 @@ You MUST NOT ask the Bootstrapper Codex to do implementation work.
|
|
|
11801
12203
|
You MUST NOT inspect unrelated repositories or folders.
|
|
11802
12204
|
You MUST report the exact blocker if a command, preview, editor, or tunnel step
|
|
11803
12205
|
fails.
|
|
12206
|
+
When several Linzumi Codex sessions work in the same repository, create or use
|
|
12207
|
+
a separate checkout or git worktree for this task before making changes, unless
|
|
12208
|
+
the human explicitly asks you to share the current checkout. Do not overwrite or
|
|
12209
|
+
revert another session's work.
|
|
11804
12210
|
</rules>
|
|
11805
12211
|
|
|
11806
12212
|
<examples>
|
|
@@ -11892,7 +12298,8 @@ function startInstanceRuntimeSettings(options, control) {
|
|
|
11892
12298
|
reasoningEffort: control.reasoningEffort ?? defaults.reasoningEffort,
|
|
11893
12299
|
approvalPolicy: codexApprovalPolicyForRequest(control.approvalPolicy ?? defaults.approvalPolicy, sandbox),
|
|
11894
12300
|
sandbox,
|
|
11895
|
-
fast: control.fast ?? options.fast
|
|
12301
|
+
fast: control.fast ?? options.fast,
|
|
12302
|
+
allowPortForwardingByDefault: control.allowPortForwardingByDefault ?? defaults.allowPortForwardingByDefault
|
|
11896
12303
|
};
|
|
11897
12304
|
}
|
|
11898
12305
|
async function startOwnedCodexAppServer(options) {
|
|
@@ -11915,7 +12322,8 @@ function runnerRuntimeDefaults(options) {
|
|
|
11915
12322
|
model: defaults?.model ?? session?.model,
|
|
11916
12323
|
reasoningEffort: defaults?.reasoningEffort ?? session?.reasoningEffort,
|
|
11917
12324
|
approvalPolicy: codexApprovalPolicySetting(defaults?.approvalPolicy ?? session?.approvalPolicy, sandbox),
|
|
11918
|
-
sandbox
|
|
12325
|
+
sandbox,
|
|
12326
|
+
allowPortForwardingByDefault: defaults?.allowPortForwardingByDefault ?? session?.allowPortForwardingByDefault
|
|
11919
12327
|
};
|
|
11920
12328
|
}
|
|
11921
12329
|
function isUpdateRunnerConfigControl(control) {
|
|
@@ -13396,7 +13804,7 @@ To kick the agent off:
|
|
|
13396
13804
|
3. Paste into the thread. Codex will pick it up and start editing this folder.
|
|
13397
13805
|
`;
|
|
13398
13806
|
|
|
13399
|
-
//
|
|
13807
|
+
// node_modules/@inquirer/core/dist/esm/lib/key.js
|
|
13400
13808
|
var isUpKey = (key, keybindings = []) => key.name === "up" || keybindings.includes("vim") && key.name === "k" || keybindings.includes("emacs") && key.ctrl && key.name === "p";
|
|
13401
13809
|
var isDownKey = (key, keybindings = []) => key.name === "down" || keybindings.includes("vim") && key.name === "j" || keybindings.includes("emacs") && key.ctrl && key.name === "n";
|
|
13402
13810
|
var isSpaceKey = (key) => key.name === "space";
|
|
@@ -13404,7 +13812,7 @@ var isBackspaceKey = (key) => key.name === "backspace";
|
|
|
13404
13812
|
var isTabKey = (key) => key.name === "tab";
|
|
13405
13813
|
var isNumberKey = (key) => "1234567890".includes(key.name);
|
|
13406
13814
|
var isEnterKey = (key) => key.name === "enter" || key.name === "return";
|
|
13407
|
-
//
|
|
13815
|
+
// node_modules/@inquirer/core/dist/esm/lib/errors.js
|
|
13408
13816
|
class AbortPromptError extends Error {
|
|
13409
13817
|
name = "AbortPromptError";
|
|
13410
13818
|
message = "Prompt was aborted";
|
|
@@ -13430,10 +13838,10 @@ class HookError extends Error {
|
|
|
13430
13838
|
class ValidationError extends Error {
|
|
13431
13839
|
name = "ValidationError";
|
|
13432
13840
|
}
|
|
13433
|
-
//
|
|
13841
|
+
// node_modules/@inquirer/core/dist/esm/lib/use-state.js
|
|
13434
13842
|
import { AsyncResource as AsyncResource2 } from "node:async_hooks";
|
|
13435
13843
|
|
|
13436
|
-
//
|
|
13844
|
+
// node_modules/@inquirer/core/dist/esm/lib/hook-engine.js
|
|
13437
13845
|
import { AsyncLocalStorage, AsyncResource } from "node:async_hooks";
|
|
13438
13846
|
var hookStorage = new AsyncLocalStorage;
|
|
13439
13847
|
function createStore(rl) {
|
|
@@ -13538,7 +13946,7 @@ var effectScheduler = {
|
|
|
13538
13946
|
}
|
|
13539
13947
|
};
|
|
13540
13948
|
|
|
13541
|
-
//
|
|
13949
|
+
// node_modules/@inquirer/core/dist/esm/lib/use-state.js
|
|
13542
13950
|
function useState(defaultValue) {
|
|
13543
13951
|
return withPointer((pointer) => {
|
|
13544
13952
|
const setState = AsyncResource2.bind(function setState2(newValue) {
|
|
@@ -13556,7 +13964,7 @@ function useState(defaultValue) {
|
|
|
13556
13964
|
});
|
|
13557
13965
|
}
|
|
13558
13966
|
|
|
13559
|
-
//
|
|
13967
|
+
// node_modules/@inquirer/core/dist/esm/lib/use-effect.js
|
|
13560
13968
|
function useEffect(cb, depArray) {
|
|
13561
13969
|
withPointer((pointer) => {
|
|
13562
13970
|
const oldDeps = pointer.get();
|
|
@@ -13568,10 +13976,10 @@ function useEffect(cb, depArray) {
|
|
|
13568
13976
|
});
|
|
13569
13977
|
}
|
|
13570
13978
|
|
|
13571
|
-
//
|
|
13979
|
+
// node_modules/@inquirer/core/dist/esm/lib/theme.js
|
|
13572
13980
|
var import_yoctocolors_cjs = __toESM(require_yoctocolors_cjs(), 1);
|
|
13573
13981
|
|
|
13574
|
-
//
|
|
13982
|
+
// node_modules/@inquirer/figures/dist/esm/index.js
|
|
13575
13983
|
import process2 from "node:process";
|
|
13576
13984
|
function isUnicodeSupported() {
|
|
13577
13985
|
if (process2.platform !== "win32") {
|
|
@@ -13860,7 +14268,7 @@ var figures = shouldUseMain ? mainSymbols : fallbackSymbols;
|
|
|
13860
14268
|
var esm_default = figures;
|
|
13861
14269
|
var replacements = Object.entries(specialMainSymbols);
|
|
13862
14270
|
|
|
13863
|
-
//
|
|
14271
|
+
// node_modules/@inquirer/core/dist/esm/lib/theme.js
|
|
13864
14272
|
var defaultTheme = {
|
|
13865
14273
|
prefix: {
|
|
13866
14274
|
idle: import_yoctocolors_cjs.default.blue("?"),
|
|
@@ -13881,7 +14289,7 @@ var defaultTheme = {
|
|
|
13881
14289
|
}
|
|
13882
14290
|
};
|
|
13883
14291
|
|
|
13884
|
-
//
|
|
14292
|
+
// node_modules/@inquirer/core/dist/esm/lib/make-theme.js
|
|
13885
14293
|
function isPlainObject(value) {
|
|
13886
14294
|
if (typeof value !== "object" || value === null)
|
|
13887
14295
|
return false;
|
|
@@ -13909,7 +14317,7 @@ function makeTheme(...themes) {
|
|
|
13909
14317
|
return deepMerge(...themesToMerge);
|
|
13910
14318
|
}
|
|
13911
14319
|
|
|
13912
|
-
//
|
|
14320
|
+
// node_modules/@inquirer/core/dist/esm/lib/use-prefix.js
|
|
13913
14321
|
function usePrefix({ status = "idle", theme }) {
|
|
13914
14322
|
const [showLoader, setShowLoader] = useState(false);
|
|
13915
14323
|
const [tick, setTick] = useState(0);
|
|
@@ -13939,7 +14347,7 @@ function usePrefix({ status = "idle", theme }) {
|
|
|
13939
14347
|
const iconName = status === "loading" ? "idle" : status;
|
|
13940
14348
|
return typeof prefix === "string" ? prefix : prefix[iconName] ?? prefix["idle"];
|
|
13941
14349
|
}
|
|
13942
|
-
//
|
|
14350
|
+
// node_modules/@inquirer/core/dist/esm/lib/use-memo.js
|
|
13943
14351
|
function useMemo(fn, dependencies) {
|
|
13944
14352
|
return withPointer((pointer) => {
|
|
13945
14353
|
const prev = pointer.get();
|
|
@@ -13951,11 +14359,11 @@ function useMemo(fn, dependencies) {
|
|
|
13951
14359
|
return prev.value;
|
|
13952
14360
|
});
|
|
13953
14361
|
}
|
|
13954
|
-
//
|
|
14362
|
+
// node_modules/@inquirer/core/dist/esm/lib/use-ref.js
|
|
13955
14363
|
function useRef(val) {
|
|
13956
14364
|
return useState({ current: val })[0];
|
|
13957
14365
|
}
|
|
13958
|
-
//
|
|
14366
|
+
// node_modules/@inquirer/core/dist/esm/lib/use-keypress.js
|
|
13959
14367
|
function useKeypress(userHandler) {
|
|
13960
14368
|
const signal = useRef(userHandler);
|
|
13961
14369
|
signal.current = userHandler;
|
|
@@ -13973,7 +14381,7 @@ function useKeypress(userHandler) {
|
|
|
13973
14381
|
};
|
|
13974
14382
|
}, []);
|
|
13975
14383
|
}
|
|
13976
|
-
//
|
|
14384
|
+
// node_modules/@inquirer/core/dist/esm/lib/utils.js
|
|
13977
14385
|
var import_cli_width = __toESM(require_cli_width(), 1);
|
|
13978
14386
|
var import_wrap_ansi = __toESM(require_wrap_ansi(), 1);
|
|
13979
14387
|
function breakLines(content, width) {
|
|
@@ -13986,7 +14394,7 @@ function readlineWidth() {
|
|
|
13986
14394
|
return import_cli_width.default({ defaultWidth: 80, output: readline().output });
|
|
13987
14395
|
}
|
|
13988
14396
|
|
|
13989
|
-
//
|
|
14397
|
+
// node_modules/@inquirer/core/dist/esm/lib/pagination/use-pagination.js
|
|
13990
14398
|
function usePointerPosition({ active, renderedItems, pageSize, loop }) {
|
|
13991
14399
|
const state = useRef({
|
|
13992
14400
|
lastPointer: active,
|
|
@@ -14052,12 +14460,12 @@ function usePagination({ items, active, renderItem, pageSize, loop = true }) {
|
|
|
14052
14460
|
return pageBuffer.filter((line) => typeof line === "string").join(`
|
|
14053
14461
|
`);
|
|
14054
14462
|
}
|
|
14055
|
-
//
|
|
14463
|
+
// node_modules/@inquirer/core/dist/esm/lib/create-prompt.js
|
|
14056
14464
|
var import_mute_stream = __toESM(require_lib(), 1);
|
|
14057
14465
|
import * as readline2 from "node:readline";
|
|
14058
14466
|
import { AsyncResource as AsyncResource3 } from "node:async_hooks";
|
|
14059
14467
|
|
|
14060
|
-
//
|
|
14468
|
+
// node_modules/signal-exit/dist/mjs/signals.js
|
|
14061
14469
|
var signals = [];
|
|
14062
14470
|
signals.push("SIGHUP", "SIGINT", "SIGTERM");
|
|
14063
14471
|
if (process.platform !== "win32") {
|
|
@@ -14067,7 +14475,7 @@ if (process.platform === "linux") {
|
|
|
14067
14475
|
signals.push("SIGIO", "SIGPOLL", "SIGPWR", "SIGSTKFLT");
|
|
14068
14476
|
}
|
|
14069
14477
|
|
|
14070
|
-
//
|
|
14478
|
+
// node_modules/signal-exit/dist/mjs/index.js
|
|
14071
14479
|
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
14480
|
var kExitEmitter = Symbol.for("signal-exit emitter");
|
|
14073
14481
|
var global = globalThis;
|
|
@@ -14265,10 +14673,10 @@ var {
|
|
|
14265
14673
|
unload
|
|
14266
14674
|
} = signalExitWrap(processOk(process3) ? new SignalExit(process3) : new SignalExitFallback);
|
|
14267
14675
|
|
|
14268
|
-
//
|
|
14676
|
+
// node_modules/@inquirer/core/dist/esm/lib/screen-manager.js
|
|
14269
14677
|
import { stripVTControlCharacters } from "node:util";
|
|
14270
14678
|
|
|
14271
|
-
//
|
|
14679
|
+
// node_modules/@inquirer/ansi/dist/esm/index.js
|
|
14272
14680
|
var ESC = "\x1B[";
|
|
14273
14681
|
var cursorLeft = ESC + "G";
|
|
14274
14682
|
var cursorHide = ESC + "?25l";
|
|
@@ -14284,7 +14692,7 @@ var cursorTo = (x, y) => {
|
|
|
14284
14692
|
var eraseLine = ESC + "2K";
|
|
14285
14693
|
var eraseLines = (lines) => lines > 0 ? (eraseLine + cursorUp(1)).repeat(lines - 1) + eraseLine + cursorLeft : "";
|
|
14286
14694
|
|
|
14287
|
-
//
|
|
14695
|
+
// node_modules/@inquirer/core/dist/esm/lib/screen-manager.js
|
|
14288
14696
|
var height = (content) => content.split(`
|
|
14289
14697
|
`).length;
|
|
14290
14698
|
var lastLine = (content) => content.split(`
|
|
@@ -14349,7 +14757,7 @@ class ScreenManager {
|
|
|
14349
14757
|
}
|
|
14350
14758
|
}
|
|
14351
14759
|
|
|
14352
|
-
//
|
|
14760
|
+
// node_modules/@inquirer/core/dist/esm/lib/promise-polyfill.js
|
|
14353
14761
|
class PromisePolyfill extends Promise {
|
|
14354
14762
|
static withResolver() {
|
|
14355
14763
|
let resolve8;
|
|
@@ -14362,7 +14770,7 @@ class PromisePolyfill extends Promise {
|
|
|
14362
14770
|
}
|
|
14363
14771
|
}
|
|
14364
14772
|
|
|
14365
|
-
//
|
|
14773
|
+
// node_modules/@inquirer/core/dist/esm/lib/create-prompt.js
|
|
14366
14774
|
function getCallSites() {
|
|
14367
14775
|
const _prepareStackTrace = Error.prepareStackTrace;
|
|
14368
14776
|
let result = [];
|
|
@@ -14448,7 +14856,7 @@ function createPrompt(view) {
|
|
|
14448
14856
|
};
|
|
14449
14857
|
return prompt;
|
|
14450
14858
|
}
|
|
14451
|
-
//
|
|
14859
|
+
// node_modules/@inquirer/core/dist/esm/lib/Separator.js
|
|
14452
14860
|
var import_yoctocolors_cjs2 = __toESM(require_yoctocolors_cjs(), 1);
|
|
14453
14861
|
class Separator {
|
|
14454
14862
|
separator = import_yoctocolors_cjs2.default.dim(Array.from({ length: 15 }).join(esm_default.line));
|
|
@@ -14462,7 +14870,7 @@ class Separator {
|
|
|
14462
14870
|
return Boolean(choice && typeof choice === "object" && "type" in choice && choice.type === "separator");
|
|
14463
14871
|
}
|
|
14464
14872
|
}
|
|
14465
|
-
//
|
|
14873
|
+
// node_modules/@inquirer/checkbox/dist/esm/index.js
|
|
14466
14874
|
var import_yoctocolors_cjs3 = __toESM(require_yoctocolors_cjs(), 1);
|
|
14467
14875
|
var checkboxTheme = {
|
|
14468
14876
|
icon: {
|
|
@@ -14649,7 +15057,7 @@ var esm_default2 = createPrompt((config, done) => {
|
|
|
14649
15057
|
`).trimEnd();
|
|
14650
15058
|
return `${lines}${cursorHide}`;
|
|
14651
15059
|
});
|
|
14652
|
-
//
|
|
15060
|
+
// node_modules/@inquirer/input/dist/esm/index.js
|
|
14653
15061
|
var inputTheme = {
|
|
14654
15062
|
validationFailureMode: "keep"
|
|
14655
15063
|
};
|
|
@@ -14733,7 +15141,7 @@ var esm_default3 = createPrompt((config, done) => {
|
|
|
14733
15141
|
error
|
|
14734
15142
|
];
|
|
14735
15143
|
});
|
|
14736
|
-
//
|
|
15144
|
+
// node_modules/@inquirer/select/dist/esm/index.js
|
|
14737
15145
|
var import_yoctocolors_cjs4 = __toESM(require_yoctocolors_cjs(), 1);
|
|
14738
15146
|
var selectTheme = {
|
|
14739
15147
|
icon: { cursor: esm_default.pointer },
|
|
@@ -14900,28 +15308,19 @@ var esm_default4 = createPrompt((config, done) => {
|
|
|
14900
15308
|
// src/signupFlow.ts
|
|
14901
15309
|
import { spawn as spawn7 } from "node:child_process";
|
|
14902
15310
|
import {
|
|
14903
|
-
closeSync as closeSync2,
|
|
14904
15311
|
existsSync as existsSync10,
|
|
14905
15312
|
constants as fsConstants,
|
|
14906
|
-
mkdirSync as mkdirSync10,
|
|
14907
15313
|
mkdtempSync as mkdtempSync3,
|
|
14908
|
-
openSync as openSync3,
|
|
14909
15314
|
readFileSync as readFileSync10,
|
|
14910
15315
|
readdirSync,
|
|
14911
15316
|
rmSync as rmSync3,
|
|
14912
15317
|
statSync,
|
|
14913
|
-
watch,
|
|
14914
15318
|
writeFileSync as writeFileSync8
|
|
14915
15319
|
} from "node:fs";
|
|
14916
15320
|
import { access } from "node:fs/promises";
|
|
14917
15321
|
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";
|
|
15322
|
+
import { delimiter as delimiter2, join as join12, resolve as resolve8 } from "node:path";
|
|
15323
|
+
import { stdin as defaultStdin, stdout as defaultStdout } from "node:process";
|
|
14925
15324
|
import { emitKeypressEvents } from "node:readline";
|
|
14926
15325
|
|
|
14927
15326
|
// src/signupServerClient.ts
|
|
@@ -15207,11 +15606,6 @@ function booleanValue(record, key) {
|
|
|
15207
15606
|
}
|
|
15208
15607
|
|
|
15209
15608
|
// src/signupFlow.ts
|
|
15210
|
-
var commanderConnectedMarkers = [
|
|
15211
|
-
"Connected to Linzumi",
|
|
15212
|
-
"Runner connected:",
|
|
15213
|
-
'"event":"runner.instance_started"'
|
|
15214
|
-
];
|
|
15215
15609
|
var blue = (value) => `\x1B[38;5;75m${value}\x1B[0m`;
|
|
15216
15610
|
var green = (value) => `\x1B[38;5;114m${value}\x1B[0m`;
|
|
15217
15611
|
var red = (value) => `\x1B[38;5;203m${value}\x1B[0m`;
|
|
@@ -15519,6 +15913,8 @@ async function runSignupFlow(deps = {}) {
|
|
|
15519
15913
|
rootSeq: thread.rootSeq,
|
|
15520
15914
|
threadSeq: thread.threadSeq
|
|
15521
15915
|
}));
|
|
15916
|
+
const starterProjectPath = missionControl.config.starterProjectPath ?? starterProject.path;
|
|
15917
|
+
const verifiedCodexBin = verifiedCodexBinFromPreflightChecks(state.preflightChecks);
|
|
15522
15918
|
const storedSignupAuth = writeSignupCompletion({
|
|
15523
15919
|
email: verifiedAuth.user.primaryEmail ?? state.email ?? verifiedAuth.user.username,
|
|
15524
15920
|
serviceUrl,
|
|
@@ -15530,20 +15926,24 @@ async function runSignupFlow(deps = {}) {
|
|
|
15530
15926
|
launchUrl: missionControl.launchUrl,
|
|
15531
15927
|
allowedCwds: missionControl.config.allowedCwds
|
|
15532
15928
|
});
|
|
15533
|
-
const commanderLaunch =
|
|
15929
|
+
const commanderLaunch = verifiedCodexBin === undefined ? failedSignupCommanderLaunchForMissingCodex({
|
|
15930
|
+
serviceUrl,
|
|
15931
|
+
workspaceSlug: missionControl.workspace.slug,
|
|
15932
|
+
projectPath: starterProjectPath
|
|
15933
|
+
}) : await launchSignupCommanderForCompletedSignup(commanderLauncher, {
|
|
15534
15934
|
serviceUrl,
|
|
15535
15935
|
localRunnerAccessToken: missionControl.localRunnerToken.accessToken,
|
|
15536
15936
|
localRunnerExpiresInSeconds: missionControl.localRunnerToken.expiresInSeconds,
|
|
15537
15937
|
workspaceSlug: missionControl.workspace.slug,
|
|
15538
|
-
|
|
15539
|
-
|
|
15540
|
-
|
|
15938
|
+
projectPath: starterProjectPath,
|
|
15939
|
+
selectedProjectPaths: missionControl.config.allowedCwds,
|
|
15940
|
+
codexBin: verifiedCodexBin
|
|
15541
15941
|
});
|
|
15542
15942
|
const starterTaskLaunches = await startSignupTasksForCommander(signupServerClient, {
|
|
15543
15943
|
accessToken: verifiedAuth.accessToken,
|
|
15544
15944
|
missionControl,
|
|
15545
15945
|
commanderLaunch,
|
|
15546
|
-
starterProjectPath
|
|
15946
|
+
starterProjectPath,
|
|
15547
15947
|
threads: starterTaskThreads
|
|
15548
15948
|
});
|
|
15549
15949
|
state = updateSignupState(state, {
|
|
@@ -16022,7 +16422,7 @@ function writeLaunchSummary(output, state) {
|
|
|
16022
16422
|
writeBoundedLine(output, `${green("✓")} Local Commander connected this computer to Mission Control (${state.commanderLaunch.runnerId})`);
|
|
16023
16423
|
break;
|
|
16024
16424
|
case "failed":
|
|
16025
|
-
writeStatusMessage(output, red("x"), `Local Commander could not
|
|
16425
|
+
writeStatusMessage(output, red("x"), `Local Commander could not connect: ${state.commanderLaunch.error}`);
|
|
16026
16426
|
break;
|
|
16027
16427
|
}
|
|
16028
16428
|
}
|
|
@@ -16064,48 +16464,17 @@ async function defaultSignupCommanderLauncher(args) {
|
|
|
16064
16464
|
accessToken: args.localRunnerAccessToken,
|
|
16065
16465
|
expiresInSeconds: args.localRunnerExpiresInSeconds
|
|
16066
16466
|
});
|
|
16067
|
-
const scriptPath = processArgv[1];
|
|
16068
16467
|
const runnerId = signupCommanderRunnerId(args.workspaceSlug);
|
|
16069
16468
|
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
16469
|
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
|
-
}
|
|
16470
|
+
const handle = await runLocalCodexRunner(await signupCommanderRunnerOptions(args, runnerId));
|
|
16103
16471
|
return {
|
|
16104
16472
|
status: "started",
|
|
16105
16473
|
runnerId,
|
|
16106
16474
|
restartCommand,
|
|
16107
|
-
|
|
16108
|
-
|
|
16475
|
+
pid: process.pid,
|
|
16476
|
+
instanceId: handle.instanceId,
|
|
16477
|
+
codexUrl: handle.codexUrl
|
|
16109
16478
|
};
|
|
16110
16479
|
} catch (error) {
|
|
16111
16480
|
return {
|
|
@@ -16114,82 +16483,58 @@ async function defaultSignupCommanderLauncher(args) {
|
|
|
16114
16483
|
restartCommand,
|
|
16115
16484
|
error: error instanceof Error ? error.message : String(error)
|
|
16116
16485
|
};
|
|
16117
|
-
} finally {
|
|
16118
|
-
closeFileDescriptor(stdoutFd);
|
|
16119
|
-
closeFileDescriptor(stderrFd);
|
|
16120
16486
|
}
|
|
16121
16487
|
}
|
|
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
|
-
}
|
|
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
|
-
}
|
|
16187
16488
|
function signupCommanderRunnerId(workspaceSlug) {
|
|
16188
16489
|
return `signup-${workspaceSlug}-commander`;
|
|
16189
16490
|
}
|
|
16190
|
-
function
|
|
16191
|
-
|
|
16192
|
-
|
|
16491
|
+
function failedSignupCommanderLaunchForMissingCodex(args) {
|
|
16492
|
+
return {
|
|
16493
|
+
status: "failed",
|
|
16494
|
+
runnerId: signupCommanderRunnerId(args.workspaceSlug),
|
|
16495
|
+
restartCommand: signupConnectRestartCommand(args),
|
|
16496
|
+
error: "Codex preflight did not resolve a verified Codex command. Install Codex or fix the Codex CLI on PATH, then rerun signup."
|
|
16497
|
+
};
|
|
16498
|
+
}
|
|
16499
|
+
async function signupCommanderRunnerOptions(args, runnerId) {
|
|
16500
|
+
const trust = kandanTlsTrustFromEnv();
|
|
16501
|
+
const editorRuntime = await resolveEditorRuntime({
|
|
16502
|
+
kandanUrl: args.serviceUrl,
|
|
16503
|
+
token: args.localRunnerAccessToken,
|
|
16504
|
+
fetchImpl: trustedFetch(trust)
|
|
16505
|
+
});
|
|
16506
|
+
const dependencyStatus = await buildRunnerDependencyStatus({
|
|
16507
|
+
cwd: args.projectPath,
|
|
16508
|
+
codexBin: args.codexBin,
|
|
16509
|
+
codeServerBin: editorRuntime.codeServerBin,
|
|
16510
|
+
editorRuntime: editorRuntime.status
|
|
16511
|
+
});
|
|
16512
|
+
assertStartDependencies(dependencyStatus);
|
|
16513
|
+
return {
|
|
16514
|
+
kandanUrl: args.serviceUrl,
|
|
16515
|
+
token: args.localRunnerAccessToken,
|
|
16516
|
+
runnerId,
|
|
16517
|
+
machineId: ensureLocalMachineIdForLinzumiUrl(args.serviceUrl),
|
|
16518
|
+
workspaceSlug: args.workspaceSlug,
|
|
16519
|
+
cwd: args.projectPath,
|
|
16520
|
+
codexBin: args.codexBin,
|
|
16521
|
+
codexUrl: undefined,
|
|
16522
|
+
launchTui: false,
|
|
16523
|
+
fast: false,
|
|
16524
|
+
allowedCwds: Array.from(new Set([args.projectPath, ...args.selectedProjectPaths])),
|
|
16525
|
+
allowedForwardPorts: [],
|
|
16526
|
+
codeServerBin: editorRuntime.codeServerBin,
|
|
16527
|
+
editorRuntime: editorRuntime.runtime,
|
|
16528
|
+
socketFactory: trustedWebSocketFactory(trust),
|
|
16529
|
+
dependencyStatus,
|
|
16530
|
+
runtimeDefaults: {
|
|
16531
|
+
model: undefined,
|
|
16532
|
+
reasoningEffort: undefined,
|
|
16533
|
+
approvalPolicy: undefined,
|
|
16534
|
+
sandbox: undefined
|
|
16535
|
+
},
|
|
16536
|
+
channelSession: undefined
|
|
16537
|
+
};
|
|
16193
16538
|
}
|
|
16194
16539
|
function signupConnectRestartCommand(args) {
|
|
16195
16540
|
return [
|
|
@@ -16199,23 +16544,12 @@ function signupConnectRestartCommand(args) {
|
|
|
16199
16544
|
"connect",
|
|
16200
16545
|
"--workspace",
|
|
16201
16546
|
args.workspaceSlug,
|
|
16202
|
-
...args.
|
|
16547
|
+
...args.codexBin === undefined ? [] : ["--codex-bin", args.codexBin],
|
|
16548
|
+
"--cwd",
|
|
16549
|
+
args.projectPath,
|
|
16550
|
+
...args.serviceUrl === defaultLinzumiHttpUrl ? [] : ["--api-url", args.serviceUrl]
|
|
16203
16551
|
].map(shellArg).join(" ");
|
|
16204
16552
|
}
|
|
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
16553
|
function shellArg(value) {
|
|
16220
16554
|
if (/^[A-Za-z0-9_./:=@%+-]+$/.test(value)) {
|
|
16221
16555
|
return value;
|
|
@@ -17036,6 +17370,10 @@ function defaultPreflightRuntime() {
|
|
|
17036
17370
|
checkBrowserHandoff: async () => true
|
|
17037
17371
|
};
|
|
17038
17372
|
}
|
|
17373
|
+
function verifiedCodexBinFromPreflightChecks(checks) {
|
|
17374
|
+
const codex = checks.find((check2) => check2.id === "codex");
|
|
17375
|
+
return codex?.command;
|
|
17376
|
+
}
|
|
17039
17377
|
function defaultProjectDiscoveryRuntime() {
|
|
17040
17378
|
const cwd = process.cwd();
|
|
17041
17379
|
return {
|
|
@@ -17162,13 +17500,9 @@ async function resolveSignupCodexCommand(env = process.env, homeDir = homedir8()
|
|
|
17162
17500
|
env.LINZUMI_CODEX_BIN
|
|
17163
17501
|
]);
|
|
17164
17502
|
if (override !== undefined) {
|
|
17165
|
-
return
|
|
17503
|
+
return resolveCodexCommandOverride(override, homeDir);
|
|
17166
17504
|
}
|
|
17167
|
-
const homeCandidates =
|
|
17168
|
-
join12(homeDir, ".volta", "bin", "codex"),
|
|
17169
|
-
join12(homeDir, ".local", "bin", "codex"),
|
|
17170
|
-
join12(homeDir, "bin", "codex")
|
|
17171
|
-
];
|
|
17505
|
+
const homeCandidates = homeManagedCodexCandidates(homeDir);
|
|
17172
17506
|
const homeCodex = await firstExecutablePath(homeCandidates, executableExists);
|
|
17173
17507
|
if (homeCodex !== undefined) {
|
|
17174
17508
|
return homeCodex;
|
|
@@ -17200,6 +17534,20 @@ function resolveHomePath(path, homeDir) {
|
|
|
17200
17534
|
}
|
|
17201
17535
|
return resolve8(path);
|
|
17202
17536
|
}
|
|
17537
|
+
function resolveCodexCommandOverride(command, homeDir) {
|
|
17538
|
+
const trimmed = command.trim();
|
|
17539
|
+
return commandLooksPathLike(trimmed) ? resolveHomePath(trimmed, homeDir) : trimmed;
|
|
17540
|
+
}
|
|
17541
|
+
function commandLooksPathLike(command) {
|
|
17542
|
+
return command === "~" || command.startsWith("~/") || command.startsWith("/") || command.startsWith("./") || command.startsWith("../") || command.includes("/") || command.includes("\\");
|
|
17543
|
+
}
|
|
17544
|
+
function homeManagedCodexCandidates(homeDir) {
|
|
17545
|
+
return [
|
|
17546
|
+
join12(homeDir, ".volta", "bin", "codex"),
|
|
17547
|
+
join12(homeDir, ".local", "bin", "codex"),
|
|
17548
|
+
join12(homeDir, "bin", "codex")
|
|
17549
|
+
];
|
|
17550
|
+
}
|
|
17203
17551
|
async function firstExecutablePath(paths, executableExists) {
|
|
17204
17552
|
for (const path of paths) {
|
|
17205
17553
|
if (await executableExists(path)) {
|
|
@@ -17363,19 +17711,51 @@ async function checkGit(runtime) {
|
|
|
17363
17711
|
};
|
|
17364
17712
|
}
|
|
17365
17713
|
async function checkCodex(runtime) {
|
|
17366
|
-
const
|
|
17367
|
-
|
|
17368
|
-
|
|
17369
|
-
|
|
17370
|
-
|
|
17371
|
-
|
|
17714
|
+
const configuredCodex = process.env.LINZUMI_SIGNUP_CODEX_BIN !== undefined && process.env.LINZUMI_SIGNUP_CODEX_BIN.trim() !== "" ? {
|
|
17715
|
+
value: process.env.LINZUMI_SIGNUP_CODEX_BIN,
|
|
17716
|
+
source: "LINZUMI_SIGNUP_CODEX_BIN"
|
|
17717
|
+
} : process.env.LINZUMI_CODEX_BIN !== undefined && process.env.LINZUMI_CODEX_BIN.trim() !== "" ? {
|
|
17718
|
+
value: process.env.LINZUMI_CODEX_BIN,
|
|
17719
|
+
source: "LINZUMI_CODEX_BIN"
|
|
17720
|
+
} : undefined;
|
|
17721
|
+
const configuredCommand = configuredCodex === undefined ? undefined : resolveCodexCommandOverride(configuredCodex.value, runtime.homeDir);
|
|
17722
|
+
if (configuredCommand !== undefined) {
|
|
17723
|
+
const codex2 = await runtime.probeTool(configuredCommand, runtime.cwd);
|
|
17724
|
+
const location2 = `from ${configuredCodex?.source ?? "configured env"}`;
|
|
17725
|
+
return {
|
|
17726
|
+
id: "codex",
|
|
17727
|
+
title: "Codex CLI",
|
|
17728
|
+
detail: codex2.available ? `${codex2.version ?? "codex found"} ${location2}` : `${configuredCommand} ${location2} did not pass --version`,
|
|
17729
|
+
status: codex2.available ? "pass" : "warn",
|
|
17730
|
+
command: codex2.available ? codex2.command : undefined
|
|
17731
|
+
};
|
|
17732
|
+
}
|
|
17733
|
+
const candidates = ["codex", ...homeManagedCodexCandidates(runtime.homeDir)];
|
|
17734
|
+
const [firstCodex, ...otherCodexes] = await Promise.all(candidates.map((candidate) => runtime.probeTool(candidate, runtime.cwd)));
|
|
17735
|
+
const codex = [firstCodex, ...otherCodexes].find((status) => status.available) ?? firstCodex;
|
|
17736
|
+
const location = codexPreflightLocation(codex.command, runtime.homeDir);
|
|
17372
17737
|
return {
|
|
17373
17738
|
id: "codex",
|
|
17374
17739
|
title: "Codex CLI",
|
|
17375
17740
|
detail: codex.available ? `${codex.version ?? "codex found"} ${location}` : "codex not found",
|
|
17376
|
-
status: codex.available ? "pass" : "warn"
|
|
17741
|
+
status: codex.available ? "pass" : "warn",
|
|
17742
|
+
command: codex.available ? codex.command : undefined
|
|
17377
17743
|
};
|
|
17378
17744
|
}
|
|
17745
|
+
function codexPreflightLocation(command, homeDir) {
|
|
17746
|
+
switch (command) {
|
|
17747
|
+
case "codex":
|
|
17748
|
+
return "on PATH";
|
|
17749
|
+
case join12(homeDir, ".volta", "bin", "codex"):
|
|
17750
|
+
return "via Volta";
|
|
17751
|
+
case join12(homeDir, ".local", "bin", "codex"):
|
|
17752
|
+
return "via ~/.local/bin";
|
|
17753
|
+
case join12(homeDir, "bin", "codex"):
|
|
17754
|
+
return "via ~/bin";
|
|
17755
|
+
default:
|
|
17756
|
+
return "from configured path";
|
|
17757
|
+
}
|
|
17758
|
+
}
|
|
17379
17759
|
async function checkGitEmail(runtime) {
|
|
17380
17760
|
const email = await runtime.readGitEmail(runtime.cwd);
|
|
17381
17761
|
return {
|
|
@@ -17703,15 +18083,15 @@ function renderPreflightRow(check2, spinnerFrame, columns) {
|
|
|
17703
18083
|
// src/commanderDaemon.ts
|
|
17704
18084
|
import {
|
|
17705
18085
|
existsSync as existsSync11,
|
|
17706
|
-
closeSync as
|
|
18086
|
+
closeSync as closeSync2,
|
|
17707
18087
|
mkdirSync as mkdirSync11,
|
|
17708
|
-
openSync as
|
|
18088
|
+
openSync as openSync3,
|
|
17709
18089
|
readFileSync as readFileSync11,
|
|
17710
|
-
watch
|
|
18090
|
+
watch,
|
|
17711
18091
|
writeFileSync as writeFileSync9
|
|
17712
18092
|
} from "node:fs";
|
|
17713
18093
|
import { homedir as homedir9 } from "node:os";
|
|
17714
|
-
import { dirname as
|
|
18094
|
+
import { dirname as dirname9, join as join13, resolve as resolve9 } from "node:path";
|
|
17715
18095
|
import { execFileSync, spawn as spawn8 } from "node:child_process";
|
|
17716
18096
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
17717
18097
|
var connectedMarkers = ["Connected to Linzumi", "Runner connected:"];
|
|
@@ -17744,9 +18124,9 @@ function startCommanderDaemon(options) {
|
|
|
17744
18124
|
logFile
|
|
17745
18125
|
];
|
|
17746
18126
|
mkdirSync11(statusDir, { recursive: true });
|
|
17747
|
-
mkdirSync11(
|
|
17748
|
-
const out =
|
|
17749
|
-
const err =
|
|
18127
|
+
mkdirSync11(dirname9(logFile), { recursive: true });
|
|
18128
|
+
const out = openSync3(logFile, "a");
|
|
18129
|
+
const err = openSync3(logFile, "a");
|
|
17750
18130
|
writeCliAuditEvent("process.spawn", {
|
|
17751
18131
|
command: nodeBin,
|
|
17752
18132
|
args: command,
|
|
@@ -17765,8 +18145,8 @@ function startCommanderDaemon(options) {
|
|
|
17765
18145
|
pid: child.pid,
|
|
17766
18146
|
purpose: "commander_daemon.start"
|
|
17767
18147
|
}, { sessionId: options.runnerId });
|
|
17768
|
-
|
|
17769
|
-
|
|
18148
|
+
closeSync2(out);
|
|
18149
|
+
closeSync2(err);
|
|
17770
18150
|
child.unref();
|
|
17771
18151
|
if (child.pid === undefined) {
|
|
17772
18152
|
throw new Error("commander daemon did not report a pid");
|
|
@@ -17796,7 +18176,7 @@ function commanderDaemonStatus(runnerId, statusDir = commanderStatusDir(), proce
|
|
|
17796
18176
|
}
|
|
17797
18177
|
async function waitForCommanderDaemon(options) {
|
|
17798
18178
|
const now = options.now ?? (() => Date.now());
|
|
17799
|
-
const
|
|
18179
|
+
const readTextFile = options.readTextFile ?? ((path) => existsSync11(path) ? readFileSync11(path, "utf8") : undefined);
|
|
17800
18180
|
const statusImpl = options.statusImpl ?? commanderDaemonStatus;
|
|
17801
18181
|
const deadline = now() + options.timeoutMs;
|
|
17802
18182
|
while (now() <= deadline) {
|
|
@@ -17807,7 +18187,7 @@ async function waitForCommanderDaemon(options) {
|
|
|
17807
18187
|
case "stopped":
|
|
17808
18188
|
return { ok: false, reason: "stopped" };
|
|
17809
18189
|
case "running": {
|
|
17810
|
-
const log =
|
|
18190
|
+
const log = readTextFile(status.record.logFile);
|
|
17811
18191
|
if (log === undefined) {
|
|
17812
18192
|
return { ok: false, reason: "timeout" };
|
|
17813
18193
|
}
|
|
@@ -17815,7 +18195,7 @@ async function waitForCommanderDaemon(options) {
|
|
|
17815
18195
|
return { ok: true, record: status.record };
|
|
17816
18196
|
}
|
|
17817
18197
|
await waitForFileChangeOrTimeout(status.record.logFile, deadline, now, () => {
|
|
17818
|
-
const updatedLog =
|
|
18198
|
+
const updatedLog = readTextFile(status.record.logFile);
|
|
17819
18199
|
return updatedLog !== undefined && commanderLogIsConnected(updatedLog);
|
|
17820
18200
|
});
|
|
17821
18201
|
}
|
|
@@ -17941,7 +18321,7 @@ async function waitForFileChangeOrTimeout(path, deadline, now, ready2 = () => fa
|
|
|
17941
18321
|
};
|
|
17942
18322
|
const timer = setTimeout(finish, remaining);
|
|
17943
18323
|
try {
|
|
17944
|
-
watcher =
|
|
18324
|
+
watcher = watch(path, finish);
|
|
17945
18325
|
watcher.on("error", finish);
|
|
17946
18326
|
if (ready2()) {
|
|
17947
18327
|
finish();
|
|
@@ -17959,8 +18339,7 @@ async function waitForFileChangeOrTimeout(path, deadline, now, ready2 = () => fa
|
|
|
17959
18339
|
// src/index.ts
|
|
17960
18340
|
var flagDefinitions = new Map([
|
|
17961
18341
|
["version", { kind: "boolean" }],
|
|
17962
|
-
["
|
|
17963
|
-
["kandan-url", { kind: "value" }],
|
|
18342
|
+
["api-url", { kind: "value" }],
|
|
17964
18343
|
["token", { kind: "value" }],
|
|
17965
18344
|
["runner-id", { kind: "value" }],
|
|
17966
18345
|
["cwd", { kind: "value" }],
|
|
@@ -17970,7 +18349,6 @@ var flagDefinitions = new Map([
|
|
|
17970
18349
|
["workspace", { kind: "value" }],
|
|
17971
18350
|
["channel", { kind: "value" }],
|
|
17972
18351
|
["linzumi-thread-id", { kind: "value" }],
|
|
17973
|
-
["kandan-thread-id", { kind: "value" }],
|
|
17974
18352
|
["listen-user", { kind: "value" }],
|
|
17975
18353
|
["model", { kind: "value" }],
|
|
17976
18354
|
["reasoning-effort", { kind: "value" }],
|
|
@@ -17989,10 +18367,6 @@ var flagDefinitions = new Map([
|
|
|
17989
18367
|
["oauth-callback-host", { kind: "value" }],
|
|
17990
18368
|
["help", { kind: "boolean" }]
|
|
17991
18369
|
]);
|
|
17992
|
-
var flagAliases = new Map([
|
|
17993
|
-
["kandan-url", "linzumi-url"],
|
|
17994
|
-
["kandan-thread-id", "linzumi-thread-id"]
|
|
17995
|
-
]);
|
|
17996
18370
|
var helloFlagDefinitions = new Map([
|
|
17997
18371
|
["dir", { kind: "value" }],
|
|
17998
18372
|
["parent-dir", { kind: "value" }],
|
|
@@ -18248,8 +18622,7 @@ function parsePathsCommandArgs(args) {
|
|
|
18248
18622
|
case "--help":
|
|
18249
18623
|
help = true;
|
|
18250
18624
|
break;
|
|
18251
|
-
case "--
|
|
18252
|
-
case "--kandan-url": {
|
|
18625
|
+
case "--api-url": {
|
|
18253
18626
|
const value = args[index + 1];
|
|
18254
18627
|
if (value === undefined || value.startsWith("--")) {
|
|
18255
18628
|
throw new Error(`missing value for ${arg}`);
|
|
@@ -18360,7 +18733,7 @@ async function runAuthCommand(args) {
|
|
|
18360
18733
|
process.stdout.write(helpText());
|
|
18361
18734
|
return;
|
|
18362
18735
|
}
|
|
18363
|
-
const kandanUrl = required(values, "
|
|
18736
|
+
const kandanUrl = required(values, "api-url");
|
|
18364
18737
|
const target = parseOptionalChannelTarget(values);
|
|
18365
18738
|
const token = await acquireLocalRunnerTokenDetails({
|
|
18366
18739
|
kandanUrl,
|
|
@@ -18391,7 +18764,7 @@ async function parseStartRunnerArgs(args, deps = {
|
|
|
18391
18764
|
process.exit(0);
|
|
18392
18765
|
}
|
|
18393
18766
|
rejectStartTargetingFlags(values);
|
|
18394
|
-
const kandanUrl = stringValue4(values, "
|
|
18767
|
+
const kandanUrl = stringValue4(values, "api-url") ?? defaultLinzumiWebSocketUrl;
|
|
18395
18768
|
const requestedCwd = resolveUserPath(cwdArg ?? process.cwd());
|
|
18396
18769
|
const cwd = assertConfiguredAllowedCwds([requestedCwd])[0] ?? requestedCwd;
|
|
18397
18770
|
const explicitAllowedCwds = values.has("allowed-cwd") ? assertConfiguredAllowedCwds(parseAllowedCwdList(stringValue4(values, "allowed-cwd"))) : [];
|
|
@@ -18509,7 +18882,7 @@ async function parseAgentRunnerArgs(args, deps = {
|
|
|
18509
18882
|
approvalPolicy: stringValue4(values, "approval-policy"),
|
|
18510
18883
|
streamFlushMs: positiveIntegerValue2(values, "stream-flush-ms")
|
|
18511
18884
|
};
|
|
18512
|
-
const kandanUrl = stringValue4(values, "
|
|
18885
|
+
const kandanUrl = stringValue4(values, "api-url") ?? agentApiUrlToKandanUrl(tokenFile.apiUrl);
|
|
18513
18886
|
const requestedCwdValue = cwdArg ?? stringValue4(values, "cwd");
|
|
18514
18887
|
const requestedCwd = resolveUserPath(requestedCwdValue ?? process.cwd());
|
|
18515
18888
|
const configuredAllowedCwds2 = requestedCwdValue === undefined && !values.has("allowed-cwd") ? readConfiguredAllowedCwdDetailsForLinzumiUrl(kandanUrl) : { allowedCwds: [], missingAllowedCwds: [] };
|
|
@@ -18641,7 +19014,7 @@ async function parseRunnerArgs(args, deps = {
|
|
|
18641
19014
|
}
|
|
18642
19015
|
rejectConnectChannelFlags(values);
|
|
18643
19016
|
const workspaceSlug = stringValue4(values, "workspace");
|
|
18644
|
-
const kandanUrl = stringValue4(values, "
|
|
19017
|
+
const kandanUrl = stringValue4(values, "api-url") ?? defaultLinzumiWebSocketUrl;
|
|
18645
19018
|
const cwd = stringValue4(values, "cwd") ?? process.cwd();
|
|
18646
19019
|
const cwdAllowedCwds = assertConfiguredAllowedCwds([cwd]);
|
|
18647
19020
|
const localConfiguredAllowedCwds = values.has("allowed-cwd") ? { allowedCwds: [], missingAllowedCwds: [] } : readConfiguredAllowedCwdDetailsForLinzumiUrl(kandanUrl);
|
|
@@ -18699,7 +19072,8 @@ function runnerRuntimeDefaultsFromValues(values) {
|
|
|
18699
19072
|
model: stringValue4(values, "model"),
|
|
18700
19073
|
reasoningEffort: stringValue4(values, "reasoning-effort"),
|
|
18701
19074
|
approvalPolicy: stringValue4(values, "approval-policy"),
|
|
18702
|
-
sandbox: stringValue4(values, "sandbox")
|
|
19075
|
+
sandbox: stringValue4(values, "sandbox"),
|
|
19076
|
+
allowPortForwardingByDefault: undefined
|
|
18703
19077
|
};
|
|
18704
19078
|
}
|
|
18705
19079
|
function strictFlagValues(args, definitions = flagDefinitions) {
|
|
@@ -18714,16 +19088,15 @@ function strictFlagValues(args, definitions = flagDefinitions) {
|
|
|
18714
19088
|
if (definition === undefined) {
|
|
18715
19089
|
throw new Error(`invalid flag: --${rawKey}`);
|
|
18716
19090
|
}
|
|
18717
|
-
const key = flagAliases.get(rawKey) ?? rawKey;
|
|
18718
19091
|
if (definition.kind === "boolean") {
|
|
18719
|
-
values.set(
|
|
19092
|
+
values.set(rawKey, true);
|
|
18720
19093
|
continue;
|
|
18721
19094
|
}
|
|
18722
19095
|
const next = args[index + 1];
|
|
18723
19096
|
if (next === undefined || next.startsWith("--")) {
|
|
18724
19097
|
throw new Error(`missing value for --${rawKey}`);
|
|
18725
19098
|
}
|
|
18726
|
-
values.set(
|
|
19099
|
+
values.set(rawKey, next);
|
|
18727
19100
|
index += 1;
|
|
18728
19101
|
}
|
|
18729
19102
|
return values;
|
|
@@ -18905,11 +19278,10 @@ Usage:
|
|
|
18905
19278
|
linzumi start <folder> [options]
|
|
18906
19279
|
linzumi paths list|add|remove [path]
|
|
18907
19280
|
linzumi connect --workspace <slug> [options]
|
|
18908
|
-
linzumi auth --
|
|
19281
|
+
linzumi auth --api-url <url> [--workspace <slug> --channel <slug>]
|
|
18909
19282
|
|
|
18910
19283
|
Connection:
|
|
18911
|
-
--
|
|
18912
|
-
(deprecated alias: --kandan-url)
|
|
19284
|
+
--api-url <url> Linzumi API URL, default ${defaultLinzumiWebSocketUrl}
|
|
18913
19285
|
--token <jwt> Optional override token. Otherwise ~/.linzumi/auth.json is validated or OAuth opens.
|
|
18914
19286
|
--auth-file <path> Auth cache path, default ~/.linzumi/auth.json
|
|
18915
19287
|
--oauth-callback-host <ip> Callback host reachable by your browser
|
|
@@ -19022,12 +19394,12 @@ function pathsHelpText() {
|
|
|
19022
19394
|
return `Linzumi trusted paths
|
|
19023
19395
|
|
|
19024
19396
|
Usage:
|
|
19025
|
-
linzumi paths [--
|
|
19026
|
-
linzumi paths [--
|
|
19027
|
-
linzumi paths [--
|
|
19397
|
+
linzumi paths [--api-url <url>] list
|
|
19398
|
+
linzumi paths [--api-url <url>] add <path>
|
|
19399
|
+
linzumi paths [--api-url <url>] remove <path>
|
|
19028
19400
|
|
|
19029
19401
|
Trusted paths are stored in ~/.linzumi/config.json. Production/default paths
|
|
19030
|
-
use the root config fields; explicit --
|
|
19402
|
+
use the root config fields; explicit --api-url paths use a URL-scoped config
|
|
19031
19403
|
section so local, staging, and production runners do not share trust state.
|
|
19032
19404
|
`;
|
|
19033
19405
|
}
|
|
@@ -19044,8 +19416,7 @@ What it does:
|
|
|
19044
19416
|
previews, and the browser VS Code editor.
|
|
19045
19417
|
|
|
19046
19418
|
Options:
|
|
19047
|
-
--
|
|
19048
|
-
(deprecated alias: --kandan-url)
|
|
19419
|
+
--api-url <url> Linzumi API URL, default ${defaultLinzumiWebSocketUrl}
|
|
19049
19420
|
--token <jwt> Optional scoped local-runner token override
|
|
19050
19421
|
--auth-file <path> Auth cache path, default ~/.linzumi/auth.json
|
|
19051
19422
|
--oauth-callback-host <ip> Callback host reachable by your browser
|
|
@@ -19085,8 +19456,7 @@ What it does:
|
|
|
19085
19456
|
|
|
19086
19457
|
Options:
|
|
19087
19458
|
--agent-token-file <path> Agent token cache, default ~/.linzumi/agent-token.json
|
|
19088
|
-
--
|
|
19089
|
-
(deprecated alias: --kandan-url)
|
|
19459
|
+
--api-url <url> Linzumi API URL. Defaults deterministically from the stored apiUrl.
|
|
19090
19460
|
--runner-id <id> Stable Commander id
|
|
19091
19461
|
--codex-bin <path> Codex executable, default codex
|
|
19092
19462
|
--code-server-bin <path> Custom development code-server executable. By default Linzumi installs the approved editor runtime.
|
|
@@ -19102,7 +19472,7 @@ Options:
|
|
|
19102
19472
|
Examples:
|
|
19103
19473
|
linzumi paths add "$PWD"
|
|
19104
19474
|
linzumi commander daemon --runner-id hello-world-commander
|
|
19105
|
-
linzumi commander ~/code/my-app --
|
|
19475
|
+
linzumi commander ~/code/my-app --api-url http://127.0.0.1:4162 --runner-id local-qa-commander
|
|
19106
19476
|
`;
|
|
19107
19477
|
}
|
|
19108
19478
|
function connectGuideText() {
|