@linzumi/cli 0.0.50-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 +746 -353
- 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,23 +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
|
-
|
|
11368
|
-
|
|
11369
|
-
|
|
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;
|
|
11370
11773
|
}
|
|
11371
11774
|
function extractStartedThreadId(response) {
|
|
11372
11775
|
if ("error" in response) {
|
|
@@ -11747,6 +12150,22 @@ ${args.developerPrompt}
|
|
|
11747
12150
|
`;
|
|
11748
12151
|
const linzumiContext = args.linzumiContext === undefined ? "" : `
|
|
11749
12152
|
${formatLinzumiConversationContextForPrompt(args.linzumiContext)}
|
|
12153
|
+
`;
|
|
12154
|
+
const reviewGuidance = `
|
|
12155
|
+
<linzumi_pr_review_guidance>
|
|
12156
|
+
For frontend or other user-visible changes, ask whether the user wants
|
|
12157
|
+
screenshot or screen-recording proof, ideally before/after when that helps
|
|
12158
|
+
review the change. Screen recordings should be WebM or MP4. When the user asks
|
|
12159
|
+
you to open or update a PR, attach or link that proof in the PR when feasible,
|
|
12160
|
+
and state the exact blocker when it is not feasible.
|
|
12161
|
+
</linzumi_pr_review_guidance>
|
|
12162
|
+
|
|
12163
|
+
<linzumi_user_visible_writing_guide>
|
|
12164
|
+
When you write user-visible UI, status, error, or PR-review copy, keep it short,
|
|
12165
|
+
direct, and focused on the user's outcome. Avoid implementation-heavy sentences,
|
|
12166
|
+
stacked clauses, and internal mechanics unless the user explicitly needs that
|
|
12167
|
+
detail.
|
|
12168
|
+
</linzumi_user_visible_writing_guide>
|
|
11750
12169
|
`;
|
|
11751
12170
|
return `<context>
|
|
11752
12171
|
You are a Linzumi Codex session launched by the Linzumi Commander.
|
|
@@ -11784,6 +12203,10 @@ You MUST NOT ask the Bootstrapper Codex to do implementation work.
|
|
|
11784
12203
|
You MUST NOT inspect unrelated repositories or folders.
|
|
11785
12204
|
You MUST report the exact blocker if a command, preview, editor, or tunnel step
|
|
11786
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.
|
|
11787
12210
|
</rules>
|
|
11788
12211
|
|
|
11789
12212
|
<examples>
|
|
@@ -11791,6 +12214,7 @@ GOOD preview command: npm run dev -- --host 0.0.0.0 --port 8787
|
|
|
11791
12214
|
BAD preview command: npm run dev -- --host 127.0.0.1
|
|
11792
12215
|
</examples>
|
|
11793
12216
|
${linzumiContext}
|
|
12217
|
+
${reviewGuidance}
|
|
11794
12218
|
${customPrompt}
|
|
11795
12219
|
<task_reminder>
|
|
11796
12220
|
You are the Commander-launched Linzumi Codex session. Do the implementation
|
|
@@ -11874,7 +12298,8 @@ function startInstanceRuntimeSettings(options, control) {
|
|
|
11874
12298
|
reasoningEffort: control.reasoningEffort ?? defaults.reasoningEffort,
|
|
11875
12299
|
approvalPolicy: codexApprovalPolicyForRequest(control.approvalPolicy ?? defaults.approvalPolicy, sandbox),
|
|
11876
12300
|
sandbox,
|
|
11877
|
-
fast: control.fast ?? options.fast
|
|
12301
|
+
fast: control.fast ?? options.fast,
|
|
12302
|
+
allowPortForwardingByDefault: control.allowPortForwardingByDefault ?? defaults.allowPortForwardingByDefault
|
|
11878
12303
|
};
|
|
11879
12304
|
}
|
|
11880
12305
|
async function startOwnedCodexAppServer(options) {
|
|
@@ -11897,7 +12322,8 @@ function runnerRuntimeDefaults(options) {
|
|
|
11897
12322
|
model: defaults?.model ?? session?.model,
|
|
11898
12323
|
reasoningEffort: defaults?.reasoningEffort ?? session?.reasoningEffort,
|
|
11899
12324
|
approvalPolicy: codexApprovalPolicySetting(defaults?.approvalPolicy ?? session?.approvalPolicy, sandbox),
|
|
11900
|
-
sandbox
|
|
12325
|
+
sandbox,
|
|
12326
|
+
allowPortForwardingByDefault: defaults?.allowPortForwardingByDefault ?? session?.allowPortForwardingByDefault
|
|
11901
12327
|
};
|
|
11902
12328
|
}
|
|
11903
12329
|
function isUpdateRunnerConfigControl(control) {
|
|
@@ -13378,7 +13804,7 @@ To kick the agent off:
|
|
|
13378
13804
|
3. Paste into the thread. Codex will pick it up and start editing this folder.
|
|
13379
13805
|
`;
|
|
13380
13806
|
|
|
13381
|
-
//
|
|
13807
|
+
// node_modules/@inquirer/core/dist/esm/lib/key.js
|
|
13382
13808
|
var isUpKey = (key, keybindings = []) => key.name === "up" || keybindings.includes("vim") && key.name === "k" || keybindings.includes("emacs") && key.ctrl && key.name === "p";
|
|
13383
13809
|
var isDownKey = (key, keybindings = []) => key.name === "down" || keybindings.includes("vim") && key.name === "j" || keybindings.includes("emacs") && key.ctrl && key.name === "n";
|
|
13384
13810
|
var isSpaceKey = (key) => key.name === "space";
|
|
@@ -13386,7 +13812,7 @@ var isBackspaceKey = (key) => key.name === "backspace";
|
|
|
13386
13812
|
var isTabKey = (key) => key.name === "tab";
|
|
13387
13813
|
var isNumberKey = (key) => "1234567890".includes(key.name);
|
|
13388
13814
|
var isEnterKey = (key) => key.name === "enter" || key.name === "return";
|
|
13389
|
-
//
|
|
13815
|
+
// node_modules/@inquirer/core/dist/esm/lib/errors.js
|
|
13390
13816
|
class AbortPromptError extends Error {
|
|
13391
13817
|
name = "AbortPromptError";
|
|
13392
13818
|
message = "Prompt was aborted";
|
|
@@ -13412,10 +13838,10 @@ class HookError extends Error {
|
|
|
13412
13838
|
class ValidationError extends Error {
|
|
13413
13839
|
name = "ValidationError";
|
|
13414
13840
|
}
|
|
13415
|
-
//
|
|
13841
|
+
// node_modules/@inquirer/core/dist/esm/lib/use-state.js
|
|
13416
13842
|
import { AsyncResource as AsyncResource2 } from "node:async_hooks";
|
|
13417
13843
|
|
|
13418
|
-
//
|
|
13844
|
+
// node_modules/@inquirer/core/dist/esm/lib/hook-engine.js
|
|
13419
13845
|
import { AsyncLocalStorage, AsyncResource } from "node:async_hooks";
|
|
13420
13846
|
var hookStorage = new AsyncLocalStorage;
|
|
13421
13847
|
function createStore(rl) {
|
|
@@ -13520,7 +13946,7 @@ var effectScheduler = {
|
|
|
13520
13946
|
}
|
|
13521
13947
|
};
|
|
13522
13948
|
|
|
13523
|
-
//
|
|
13949
|
+
// node_modules/@inquirer/core/dist/esm/lib/use-state.js
|
|
13524
13950
|
function useState(defaultValue) {
|
|
13525
13951
|
return withPointer((pointer) => {
|
|
13526
13952
|
const setState = AsyncResource2.bind(function setState2(newValue) {
|
|
@@ -13538,7 +13964,7 @@ function useState(defaultValue) {
|
|
|
13538
13964
|
});
|
|
13539
13965
|
}
|
|
13540
13966
|
|
|
13541
|
-
//
|
|
13967
|
+
// node_modules/@inquirer/core/dist/esm/lib/use-effect.js
|
|
13542
13968
|
function useEffect(cb, depArray) {
|
|
13543
13969
|
withPointer((pointer) => {
|
|
13544
13970
|
const oldDeps = pointer.get();
|
|
@@ -13550,10 +13976,10 @@ function useEffect(cb, depArray) {
|
|
|
13550
13976
|
});
|
|
13551
13977
|
}
|
|
13552
13978
|
|
|
13553
|
-
//
|
|
13979
|
+
// node_modules/@inquirer/core/dist/esm/lib/theme.js
|
|
13554
13980
|
var import_yoctocolors_cjs = __toESM(require_yoctocolors_cjs(), 1);
|
|
13555
13981
|
|
|
13556
|
-
//
|
|
13982
|
+
// node_modules/@inquirer/figures/dist/esm/index.js
|
|
13557
13983
|
import process2 from "node:process";
|
|
13558
13984
|
function isUnicodeSupported() {
|
|
13559
13985
|
if (process2.platform !== "win32") {
|
|
@@ -13842,7 +14268,7 @@ var figures = shouldUseMain ? mainSymbols : fallbackSymbols;
|
|
|
13842
14268
|
var esm_default = figures;
|
|
13843
14269
|
var replacements = Object.entries(specialMainSymbols);
|
|
13844
14270
|
|
|
13845
|
-
//
|
|
14271
|
+
// node_modules/@inquirer/core/dist/esm/lib/theme.js
|
|
13846
14272
|
var defaultTheme = {
|
|
13847
14273
|
prefix: {
|
|
13848
14274
|
idle: import_yoctocolors_cjs.default.blue("?"),
|
|
@@ -13863,7 +14289,7 @@ var defaultTheme = {
|
|
|
13863
14289
|
}
|
|
13864
14290
|
};
|
|
13865
14291
|
|
|
13866
|
-
//
|
|
14292
|
+
// node_modules/@inquirer/core/dist/esm/lib/make-theme.js
|
|
13867
14293
|
function isPlainObject(value) {
|
|
13868
14294
|
if (typeof value !== "object" || value === null)
|
|
13869
14295
|
return false;
|
|
@@ -13891,7 +14317,7 @@ function makeTheme(...themes) {
|
|
|
13891
14317
|
return deepMerge(...themesToMerge);
|
|
13892
14318
|
}
|
|
13893
14319
|
|
|
13894
|
-
//
|
|
14320
|
+
// node_modules/@inquirer/core/dist/esm/lib/use-prefix.js
|
|
13895
14321
|
function usePrefix({ status = "idle", theme }) {
|
|
13896
14322
|
const [showLoader, setShowLoader] = useState(false);
|
|
13897
14323
|
const [tick, setTick] = useState(0);
|
|
@@ -13921,7 +14347,7 @@ function usePrefix({ status = "idle", theme }) {
|
|
|
13921
14347
|
const iconName = status === "loading" ? "idle" : status;
|
|
13922
14348
|
return typeof prefix === "string" ? prefix : prefix[iconName] ?? prefix["idle"];
|
|
13923
14349
|
}
|
|
13924
|
-
//
|
|
14350
|
+
// node_modules/@inquirer/core/dist/esm/lib/use-memo.js
|
|
13925
14351
|
function useMemo(fn, dependencies) {
|
|
13926
14352
|
return withPointer((pointer) => {
|
|
13927
14353
|
const prev = pointer.get();
|
|
@@ -13933,11 +14359,11 @@ function useMemo(fn, dependencies) {
|
|
|
13933
14359
|
return prev.value;
|
|
13934
14360
|
});
|
|
13935
14361
|
}
|
|
13936
|
-
//
|
|
14362
|
+
// node_modules/@inquirer/core/dist/esm/lib/use-ref.js
|
|
13937
14363
|
function useRef(val) {
|
|
13938
14364
|
return useState({ current: val })[0];
|
|
13939
14365
|
}
|
|
13940
|
-
//
|
|
14366
|
+
// node_modules/@inquirer/core/dist/esm/lib/use-keypress.js
|
|
13941
14367
|
function useKeypress(userHandler) {
|
|
13942
14368
|
const signal = useRef(userHandler);
|
|
13943
14369
|
signal.current = userHandler;
|
|
@@ -13955,7 +14381,7 @@ function useKeypress(userHandler) {
|
|
|
13955
14381
|
};
|
|
13956
14382
|
}, []);
|
|
13957
14383
|
}
|
|
13958
|
-
//
|
|
14384
|
+
// node_modules/@inquirer/core/dist/esm/lib/utils.js
|
|
13959
14385
|
var import_cli_width = __toESM(require_cli_width(), 1);
|
|
13960
14386
|
var import_wrap_ansi = __toESM(require_wrap_ansi(), 1);
|
|
13961
14387
|
function breakLines(content, width) {
|
|
@@ -13968,7 +14394,7 @@ function readlineWidth() {
|
|
|
13968
14394
|
return import_cli_width.default({ defaultWidth: 80, output: readline().output });
|
|
13969
14395
|
}
|
|
13970
14396
|
|
|
13971
|
-
//
|
|
14397
|
+
// node_modules/@inquirer/core/dist/esm/lib/pagination/use-pagination.js
|
|
13972
14398
|
function usePointerPosition({ active, renderedItems, pageSize, loop }) {
|
|
13973
14399
|
const state = useRef({
|
|
13974
14400
|
lastPointer: active,
|
|
@@ -14034,12 +14460,12 @@ function usePagination({ items, active, renderItem, pageSize, loop = true }) {
|
|
|
14034
14460
|
return pageBuffer.filter((line) => typeof line === "string").join(`
|
|
14035
14461
|
`);
|
|
14036
14462
|
}
|
|
14037
|
-
//
|
|
14463
|
+
// node_modules/@inquirer/core/dist/esm/lib/create-prompt.js
|
|
14038
14464
|
var import_mute_stream = __toESM(require_lib(), 1);
|
|
14039
14465
|
import * as readline2 from "node:readline";
|
|
14040
14466
|
import { AsyncResource as AsyncResource3 } from "node:async_hooks";
|
|
14041
14467
|
|
|
14042
|
-
//
|
|
14468
|
+
// node_modules/signal-exit/dist/mjs/signals.js
|
|
14043
14469
|
var signals = [];
|
|
14044
14470
|
signals.push("SIGHUP", "SIGINT", "SIGTERM");
|
|
14045
14471
|
if (process.platform !== "win32") {
|
|
@@ -14049,7 +14475,7 @@ if (process.platform === "linux") {
|
|
|
14049
14475
|
signals.push("SIGIO", "SIGPOLL", "SIGPWR", "SIGSTKFLT");
|
|
14050
14476
|
}
|
|
14051
14477
|
|
|
14052
|
-
//
|
|
14478
|
+
// node_modules/signal-exit/dist/mjs/index.js
|
|
14053
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";
|
|
14054
14480
|
var kExitEmitter = Symbol.for("signal-exit emitter");
|
|
14055
14481
|
var global = globalThis;
|
|
@@ -14247,10 +14673,10 @@ var {
|
|
|
14247
14673
|
unload
|
|
14248
14674
|
} = signalExitWrap(processOk(process3) ? new SignalExit(process3) : new SignalExitFallback);
|
|
14249
14675
|
|
|
14250
|
-
//
|
|
14676
|
+
// node_modules/@inquirer/core/dist/esm/lib/screen-manager.js
|
|
14251
14677
|
import { stripVTControlCharacters } from "node:util";
|
|
14252
14678
|
|
|
14253
|
-
//
|
|
14679
|
+
// node_modules/@inquirer/ansi/dist/esm/index.js
|
|
14254
14680
|
var ESC = "\x1B[";
|
|
14255
14681
|
var cursorLeft = ESC + "G";
|
|
14256
14682
|
var cursorHide = ESC + "?25l";
|
|
@@ -14266,7 +14692,7 @@ var cursorTo = (x, y) => {
|
|
|
14266
14692
|
var eraseLine = ESC + "2K";
|
|
14267
14693
|
var eraseLines = (lines) => lines > 0 ? (eraseLine + cursorUp(1)).repeat(lines - 1) + eraseLine + cursorLeft : "";
|
|
14268
14694
|
|
|
14269
|
-
//
|
|
14695
|
+
// node_modules/@inquirer/core/dist/esm/lib/screen-manager.js
|
|
14270
14696
|
var height = (content) => content.split(`
|
|
14271
14697
|
`).length;
|
|
14272
14698
|
var lastLine = (content) => content.split(`
|
|
@@ -14331,7 +14757,7 @@ class ScreenManager {
|
|
|
14331
14757
|
}
|
|
14332
14758
|
}
|
|
14333
14759
|
|
|
14334
|
-
//
|
|
14760
|
+
// node_modules/@inquirer/core/dist/esm/lib/promise-polyfill.js
|
|
14335
14761
|
class PromisePolyfill extends Promise {
|
|
14336
14762
|
static withResolver() {
|
|
14337
14763
|
let resolve8;
|
|
@@ -14344,7 +14770,7 @@ class PromisePolyfill extends Promise {
|
|
|
14344
14770
|
}
|
|
14345
14771
|
}
|
|
14346
14772
|
|
|
14347
|
-
//
|
|
14773
|
+
// node_modules/@inquirer/core/dist/esm/lib/create-prompt.js
|
|
14348
14774
|
function getCallSites() {
|
|
14349
14775
|
const _prepareStackTrace = Error.prepareStackTrace;
|
|
14350
14776
|
let result = [];
|
|
@@ -14430,7 +14856,7 @@ function createPrompt(view) {
|
|
|
14430
14856
|
};
|
|
14431
14857
|
return prompt;
|
|
14432
14858
|
}
|
|
14433
|
-
//
|
|
14859
|
+
// node_modules/@inquirer/core/dist/esm/lib/Separator.js
|
|
14434
14860
|
var import_yoctocolors_cjs2 = __toESM(require_yoctocolors_cjs(), 1);
|
|
14435
14861
|
class Separator {
|
|
14436
14862
|
separator = import_yoctocolors_cjs2.default.dim(Array.from({ length: 15 }).join(esm_default.line));
|
|
@@ -14444,7 +14870,7 @@ class Separator {
|
|
|
14444
14870
|
return Boolean(choice && typeof choice === "object" && "type" in choice && choice.type === "separator");
|
|
14445
14871
|
}
|
|
14446
14872
|
}
|
|
14447
|
-
//
|
|
14873
|
+
// node_modules/@inquirer/checkbox/dist/esm/index.js
|
|
14448
14874
|
var import_yoctocolors_cjs3 = __toESM(require_yoctocolors_cjs(), 1);
|
|
14449
14875
|
var checkboxTheme = {
|
|
14450
14876
|
icon: {
|
|
@@ -14631,7 +15057,7 @@ var esm_default2 = createPrompt((config, done) => {
|
|
|
14631
15057
|
`).trimEnd();
|
|
14632
15058
|
return `${lines}${cursorHide}`;
|
|
14633
15059
|
});
|
|
14634
|
-
//
|
|
15060
|
+
// node_modules/@inquirer/input/dist/esm/index.js
|
|
14635
15061
|
var inputTheme = {
|
|
14636
15062
|
validationFailureMode: "keep"
|
|
14637
15063
|
};
|
|
@@ -14715,7 +15141,7 @@ var esm_default3 = createPrompt((config, done) => {
|
|
|
14715
15141
|
error
|
|
14716
15142
|
];
|
|
14717
15143
|
});
|
|
14718
|
-
//
|
|
15144
|
+
// node_modules/@inquirer/select/dist/esm/index.js
|
|
14719
15145
|
var import_yoctocolors_cjs4 = __toESM(require_yoctocolors_cjs(), 1);
|
|
14720
15146
|
var selectTheme = {
|
|
14721
15147
|
icon: { cursor: esm_default.pointer },
|
|
@@ -14884,24 +15310,17 @@ import { spawn as spawn7 } from "node:child_process";
|
|
|
14884
15310
|
import {
|
|
14885
15311
|
existsSync as existsSync10,
|
|
14886
15312
|
constants as fsConstants,
|
|
14887
|
-
mkdirSync as mkdirSync10,
|
|
14888
15313
|
mkdtempSync as mkdtempSync3,
|
|
14889
15314
|
readFileSync as readFileSync10,
|
|
14890
15315
|
readdirSync,
|
|
14891
15316
|
rmSync as rmSync3,
|
|
14892
15317
|
statSync,
|
|
14893
|
-
watch,
|
|
14894
15318
|
writeFileSync as writeFileSync8
|
|
14895
15319
|
} from "node:fs";
|
|
14896
15320
|
import { access } from "node:fs/promises";
|
|
14897
15321
|
import { homedir as homedir8, tmpdir as tmpdir2 } from "node:os";
|
|
14898
|
-
import { delimiter as delimiter2,
|
|
14899
|
-
import {
|
|
14900
|
-
argv as processArgv,
|
|
14901
|
-
execPath as processExecPath,
|
|
14902
|
-
stdin as defaultStdin,
|
|
14903
|
-
stdout as defaultStdout
|
|
14904
|
-
} 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";
|
|
14905
15324
|
import { emitKeypressEvents } from "node:readline";
|
|
14906
15325
|
|
|
14907
15326
|
// src/signupServerClient.ts
|
|
@@ -14916,7 +15335,8 @@ function createSignupServerClient(args) {
|
|
|
14916
15335
|
method: "POST",
|
|
14917
15336
|
body: {
|
|
14918
15337
|
email: request.email,
|
|
14919
|
-
mode: request.mode
|
|
15338
|
+
mode: request.mode,
|
|
15339
|
+
selected_tasks: request.selectedTasks ?? []
|
|
14920
15340
|
},
|
|
14921
15341
|
render: renderEmailCodeStart
|
|
14922
15342
|
}),
|
|
@@ -15186,11 +15606,6 @@ function booleanValue(record, key) {
|
|
|
15186
15606
|
}
|
|
15187
15607
|
|
|
15188
15608
|
// src/signupFlow.ts
|
|
15189
|
-
var commanderConnectedMarkers = [
|
|
15190
|
-
"Connected to Linzumi",
|
|
15191
|
-
"Runner connected:",
|
|
15192
|
-
'"event":"runner.instance_started"'
|
|
15193
|
-
];
|
|
15194
15609
|
var blue = (value) => `\x1B[38;5;75m${value}\x1B[0m`;
|
|
15195
15610
|
var green = (value) => `\x1B[38;5;114m${value}\x1B[0m`;
|
|
15196
15611
|
var red = (value) => `\x1B[38;5;203m${value}\x1B[0m`;
|
|
@@ -15429,7 +15844,8 @@ async function runSignupFlow(deps = {}) {
|
|
|
15429
15844
|
state = updateSignupState(state, { currentStep: "code", email });
|
|
15430
15845
|
const codeRequest = signupServerClient === undefined ? { type: "sent", request: { pendingId: "mock", email } } : await startEmailCodeForSignup(signupServerClient, {
|
|
15431
15846
|
email,
|
|
15432
|
-
mode: "existing_or_create"
|
|
15847
|
+
mode: "existing_or_create",
|
|
15848
|
+
selectedTasks: selectedTaskTitlesFromState(state)
|
|
15433
15849
|
});
|
|
15434
15850
|
if (codeRequest.type === "failed") {
|
|
15435
15851
|
state = updateSignupState(state, {
|
|
@@ -15497,6 +15913,8 @@ async function runSignupFlow(deps = {}) {
|
|
|
15497
15913
|
rootSeq: thread.rootSeq,
|
|
15498
15914
|
threadSeq: thread.threadSeq
|
|
15499
15915
|
}));
|
|
15916
|
+
const starterProjectPath = missionControl.config.starterProjectPath ?? starterProject.path;
|
|
15917
|
+
const verifiedCodexBin = verifiedCodexBinFromPreflightChecks(state.preflightChecks);
|
|
15500
15918
|
const storedSignupAuth = writeSignupCompletion({
|
|
15501
15919
|
email: verifiedAuth.user.primaryEmail ?? state.email ?? verifiedAuth.user.username,
|
|
15502
15920
|
serviceUrl,
|
|
@@ -15508,20 +15926,24 @@ async function runSignupFlow(deps = {}) {
|
|
|
15508
15926
|
launchUrl: missionControl.launchUrl,
|
|
15509
15927
|
allowedCwds: missionControl.config.allowedCwds
|
|
15510
15928
|
});
|
|
15511
|
-
const commanderLaunch =
|
|
15929
|
+
const commanderLaunch = verifiedCodexBin === undefined ? failedSignupCommanderLaunchForMissingCodex({
|
|
15930
|
+
serviceUrl,
|
|
15931
|
+
workspaceSlug: missionControl.workspace.slug,
|
|
15932
|
+
projectPath: starterProjectPath
|
|
15933
|
+
}) : await launchSignupCommanderForCompletedSignup(commanderLauncher, {
|
|
15512
15934
|
serviceUrl,
|
|
15513
15935
|
localRunnerAccessToken: missionControl.localRunnerToken.accessToken,
|
|
15514
15936
|
localRunnerExpiresInSeconds: missionControl.localRunnerToken.expiresInSeconds,
|
|
15515
15937
|
workspaceSlug: missionControl.workspace.slug,
|
|
15516
|
-
|
|
15517
|
-
|
|
15518
|
-
|
|
15938
|
+
projectPath: starterProjectPath,
|
|
15939
|
+
selectedProjectPaths: missionControl.config.allowedCwds,
|
|
15940
|
+
codexBin: verifiedCodexBin
|
|
15519
15941
|
});
|
|
15520
15942
|
const starterTaskLaunches = await startSignupTasksForCommander(signupServerClient, {
|
|
15521
15943
|
accessToken: verifiedAuth.accessToken,
|
|
15522
15944
|
missionControl,
|
|
15523
15945
|
commanderLaunch,
|
|
15524
|
-
starterProjectPath
|
|
15946
|
+
starterProjectPath,
|
|
15525
15947
|
threads: starterTaskThreads
|
|
15526
15948
|
});
|
|
15527
15949
|
state = updateSignupState(state, {
|
|
@@ -15839,7 +16261,7 @@ function signupProgressRows(state) {
|
|
|
15839
16261
|
checked: selectedTaskTitlesFromState(state).length > 0
|
|
15840
16262
|
},
|
|
15841
16263
|
{
|
|
15842
|
-
label: "
|
|
16264
|
+
label: "Mission Control will open with your work already running",
|
|
15843
16265
|
checked: state.currentStep === "launch"
|
|
15844
16266
|
}
|
|
15845
16267
|
];
|
|
@@ -15978,7 +16400,7 @@ function writeLaunchSummary(output, state) {
|
|
|
15978
16400
|
writeBoundedLine(output, blue(" npx -y @linzumi/cli@latest signup"));
|
|
15979
16401
|
return;
|
|
15980
16402
|
}
|
|
15981
|
-
writeBoundedLine(output, blue("7)
|
|
16403
|
+
writeBoundedLine(output, blue("7) Mission Control will open with your work already running"));
|
|
15982
16404
|
const taskCount = selectedTaskTitlesFromState(state).length;
|
|
15983
16405
|
writeBoundedLine(output, muted(` Starting ${taskCount} ${taskCount === 1 ? "task" : "tasks"} and saying hello to the Linzumi team...`));
|
|
15984
16406
|
state.starterTaskLaunches.forEach((launch) => {
|
|
@@ -16000,7 +16422,7 @@ function writeLaunchSummary(output, state) {
|
|
|
16000
16422
|
writeBoundedLine(output, `${green("✓")} Local Commander connected this computer to Mission Control (${state.commanderLaunch.runnerId})`);
|
|
16001
16423
|
break;
|
|
16002
16424
|
case "failed":
|
|
16003
|
-
writeStatusMessage(output, red("x"), `Local Commander could not
|
|
16425
|
+
writeStatusMessage(output, red("x"), `Local Commander could not connect: ${state.commanderLaunch.error}`);
|
|
16004
16426
|
break;
|
|
16005
16427
|
}
|
|
16006
16428
|
}
|
|
@@ -16042,40 +16464,17 @@ async function defaultSignupCommanderLauncher(args) {
|
|
|
16042
16464
|
accessToken: args.localRunnerAccessToken,
|
|
16043
16465
|
expiresInSeconds: args.localRunnerExpiresInSeconds
|
|
16044
16466
|
});
|
|
16045
|
-
const scriptPath = processArgv[1];
|
|
16046
16467
|
const runnerId = signupCommanderRunnerId(args.workspaceSlug);
|
|
16047
16468
|
const restartCommand = signupConnectRestartCommand(args);
|
|
16048
|
-
if (scriptPath === undefined || scriptPath.trim() === "") {
|
|
16049
|
-
return {
|
|
16050
|
-
status: "failed",
|
|
16051
|
-
runnerId,
|
|
16052
|
-
restartCommand,
|
|
16053
|
-
error: "current CLI entrypoint could not be resolved"
|
|
16054
|
-
};
|
|
16055
|
-
}
|
|
16056
|
-
const logFile = signupCommanderLaunchLogFile(runnerId);
|
|
16057
16469
|
try {
|
|
16058
|
-
|
|
16059
|
-
const child = spawn7(processExecPath, signupCommanderConnectSpawnArgs(args, runnerId, logFile, scriptPath), {
|
|
16060
|
-
detached: true,
|
|
16061
|
-
stdio: "ignore"
|
|
16062
|
-
});
|
|
16063
|
-
child.unref();
|
|
16064
|
-
const connected = await waitForSignupCommanderConnection(logFile, 30000);
|
|
16065
|
-
if (!connected) {
|
|
16066
|
-
return {
|
|
16067
|
-
status: "failed",
|
|
16068
|
-
runnerId,
|
|
16069
|
-
restartCommand,
|
|
16070
|
-
error: `Local Commander did not connect within 30 seconds. Check ${logFile}`
|
|
16071
|
-
};
|
|
16072
|
-
}
|
|
16470
|
+
const handle = await runLocalCodexRunner(await signupCommanderRunnerOptions(args, runnerId));
|
|
16073
16471
|
return {
|
|
16074
16472
|
status: "started",
|
|
16075
16473
|
runnerId,
|
|
16076
16474
|
restartCommand,
|
|
16077
|
-
|
|
16078
|
-
|
|
16475
|
+
pid: process.pid,
|
|
16476
|
+
instanceId: handle.instanceId,
|
|
16477
|
+
codexUrl: handle.codexUrl
|
|
16079
16478
|
};
|
|
16080
16479
|
} catch (error) {
|
|
16081
16480
|
return {
|
|
@@ -16086,69 +16485,56 @@ async function defaultSignupCommanderLauncher(args) {
|
|
|
16086
16485
|
};
|
|
16087
16486
|
}
|
|
16088
16487
|
}
|
|
16089
|
-
async function waitForSignupCommanderConnection(logFile, timeoutMs) {
|
|
16090
|
-
const deadline = Date.now() + timeoutMs;
|
|
16091
|
-
while (Date.now() <= deadline) {
|
|
16092
|
-
const log = readTextFile(logFile);
|
|
16093
|
-
if (log !== undefined && signupCommanderLogIsConnected(log)) {
|
|
16094
|
-
return true;
|
|
16095
|
-
}
|
|
16096
|
-
await waitForSignupCommanderLogChange(logFile, deadline, () => {
|
|
16097
|
-
const updatedLog = readTextFile(logFile);
|
|
16098
|
-
return updatedLog !== undefined && signupCommanderLogIsConnected(updatedLog);
|
|
16099
|
-
});
|
|
16100
|
-
}
|
|
16101
|
-
return false;
|
|
16102
|
-
}
|
|
16103
|
-
function signupCommanderLogIsConnected(log) {
|
|
16104
|
-
return commanderConnectedMarkers.some((marker) => log.includes(marker));
|
|
16105
|
-
}
|
|
16106
|
-
function readTextFile(path) {
|
|
16107
|
-
try {
|
|
16108
|
-
return readFileSync10(path, "utf8");
|
|
16109
|
-
} catch (_error) {
|
|
16110
|
-
return;
|
|
16111
|
-
}
|
|
16112
|
-
}
|
|
16113
|
-
async function waitForSignupCommanderLogChange(logFile, deadline, ready2) {
|
|
16114
|
-
const remaining = Math.max(0, deadline - Date.now());
|
|
16115
|
-
await new Promise((resolve9) => {
|
|
16116
|
-
let resolved = false;
|
|
16117
|
-
let watcher;
|
|
16118
|
-
const finish = () => {
|
|
16119
|
-
if (resolved) {
|
|
16120
|
-
return;
|
|
16121
|
-
}
|
|
16122
|
-
resolved = true;
|
|
16123
|
-
watcher?.close();
|
|
16124
|
-
clearTimeout(timer);
|
|
16125
|
-
resolve9();
|
|
16126
|
-
};
|
|
16127
|
-
const timer = setTimeout(finish, remaining);
|
|
16128
|
-
try {
|
|
16129
|
-
watcher = watch(logFile, finish);
|
|
16130
|
-
watcher.on("error", finish);
|
|
16131
|
-
if (ready2()) {
|
|
16132
|
-
finish();
|
|
16133
|
-
}
|
|
16134
|
-
} catch (_error) {
|
|
16135
|
-
if (ready2()) {
|
|
16136
|
-
finish();
|
|
16137
|
-
return;
|
|
16138
|
-
}
|
|
16139
|
-
try {
|
|
16140
|
-
watcher = watch(dirname9(logFile), finish);
|
|
16141
|
-
watcher.on("error", finish);
|
|
16142
|
-
} catch (_nestedError) {}
|
|
16143
|
-
}
|
|
16144
|
-
});
|
|
16145
|
-
}
|
|
16146
16488
|
function signupCommanderRunnerId(workspaceSlug) {
|
|
16147
16489
|
return `signup-${workspaceSlug}-commander`;
|
|
16148
16490
|
}
|
|
16149
|
-
function
|
|
16150
|
-
|
|
16151
|
-
|
|
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
|
+
};
|
|
16152
16538
|
}
|
|
16153
16539
|
function signupConnectRestartCommand(args) {
|
|
16154
16540
|
return [
|
|
@@ -16158,25 +16544,12 @@ function signupConnectRestartCommand(args) {
|
|
|
16158
16544
|
"connect",
|
|
16159
16545
|
"--workspace",
|
|
16160
16546
|
args.workspaceSlug,
|
|
16161
|
-
...args.
|
|
16547
|
+
...args.codexBin === undefined ? [] : ["--codex-bin", args.codexBin],
|
|
16548
|
+
"--cwd",
|
|
16549
|
+
args.projectPath,
|
|
16550
|
+
...args.serviceUrl === defaultLinzumiHttpUrl ? [] : ["--api-url", args.serviceUrl]
|
|
16162
16551
|
].map(shellArg).join(" ");
|
|
16163
16552
|
}
|
|
16164
|
-
function signupCommanderConnectSpawnArgs(args, runnerId, logFile, scriptPath) {
|
|
16165
|
-
return [
|
|
16166
|
-
scriptPath,
|
|
16167
|
-
"connect",
|
|
16168
|
-
"--linzumi-url",
|
|
16169
|
-
args.serviceUrl,
|
|
16170
|
-
"--workspace",
|
|
16171
|
-
args.workspaceSlug,
|
|
16172
|
-
"--channel",
|
|
16173
|
-
args.officeChannelSlug,
|
|
16174
|
-
"--runner-id",
|
|
16175
|
-
runnerId,
|
|
16176
|
-
"--log-file",
|
|
16177
|
-
logFile
|
|
16178
|
-
];
|
|
16179
|
-
}
|
|
16180
16553
|
function shellArg(value) {
|
|
16181
16554
|
if (/^[A-Za-z0-9_./:=@%+-]+$/.test(value)) {
|
|
16182
16555
|
return value;
|
|
@@ -16997,6 +17370,10 @@ function defaultPreflightRuntime() {
|
|
|
16997
17370
|
checkBrowserHandoff: async () => true
|
|
16998
17371
|
};
|
|
16999
17372
|
}
|
|
17373
|
+
function verifiedCodexBinFromPreflightChecks(checks) {
|
|
17374
|
+
const codex = checks.find((check2) => check2.id === "codex");
|
|
17375
|
+
return codex?.command;
|
|
17376
|
+
}
|
|
17000
17377
|
function defaultProjectDiscoveryRuntime() {
|
|
17001
17378
|
const cwd = process.cwd();
|
|
17002
17379
|
return {
|
|
@@ -17123,13 +17500,9 @@ async function resolveSignupCodexCommand(env = process.env, homeDir = homedir8()
|
|
|
17123
17500
|
env.LINZUMI_CODEX_BIN
|
|
17124
17501
|
]);
|
|
17125
17502
|
if (override !== undefined) {
|
|
17126
|
-
return
|
|
17503
|
+
return resolveCodexCommandOverride(override, homeDir);
|
|
17127
17504
|
}
|
|
17128
|
-
const homeCandidates =
|
|
17129
|
-
join12(homeDir, ".volta", "bin", "codex"),
|
|
17130
|
-
join12(homeDir, ".local", "bin", "codex"),
|
|
17131
|
-
join12(homeDir, "bin", "codex")
|
|
17132
|
-
];
|
|
17505
|
+
const homeCandidates = homeManagedCodexCandidates(homeDir);
|
|
17133
17506
|
const homeCodex = await firstExecutablePath(homeCandidates, executableExists);
|
|
17134
17507
|
if (homeCodex !== undefined) {
|
|
17135
17508
|
return homeCodex;
|
|
@@ -17161,6 +17534,20 @@ function resolveHomePath(path, homeDir) {
|
|
|
17161
17534
|
}
|
|
17162
17535
|
return resolve8(path);
|
|
17163
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
|
+
}
|
|
17164
17551
|
async function firstExecutablePath(paths, executableExists) {
|
|
17165
17552
|
for (const path of paths) {
|
|
17166
17553
|
if (await executableExists(path)) {
|
|
@@ -17324,19 +17711,51 @@ async function checkGit(runtime) {
|
|
|
17324
17711
|
};
|
|
17325
17712
|
}
|
|
17326
17713
|
async function checkCodex(runtime) {
|
|
17327
|
-
const
|
|
17328
|
-
|
|
17329
|
-
|
|
17330
|
-
|
|
17331
|
-
|
|
17332
|
-
|
|
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);
|
|
17333
17737
|
return {
|
|
17334
17738
|
id: "codex",
|
|
17335
17739
|
title: "Codex CLI",
|
|
17336
17740
|
detail: codex.available ? `${codex.version ?? "codex found"} ${location}` : "codex not found",
|
|
17337
|
-
status: codex.available ? "pass" : "warn"
|
|
17741
|
+
status: codex.available ? "pass" : "warn",
|
|
17742
|
+
command: codex.available ? codex.command : undefined
|
|
17338
17743
|
};
|
|
17339
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
|
+
}
|
|
17340
17759
|
async function checkGitEmail(runtime) {
|
|
17341
17760
|
const email = await runtime.readGitEmail(runtime.cwd);
|
|
17342
17761
|
return {
|
|
@@ -17668,11 +18087,11 @@ import {
|
|
|
17668
18087
|
mkdirSync as mkdirSync11,
|
|
17669
18088
|
openSync as openSync3,
|
|
17670
18089
|
readFileSync as readFileSync11,
|
|
17671
|
-
watch
|
|
18090
|
+
watch,
|
|
17672
18091
|
writeFileSync as writeFileSync9
|
|
17673
18092
|
} from "node:fs";
|
|
17674
18093
|
import { homedir as homedir9 } from "node:os";
|
|
17675
|
-
import { dirname as
|
|
18094
|
+
import { dirname as dirname9, join as join13, resolve as resolve9 } from "node:path";
|
|
17676
18095
|
import { execFileSync, spawn as spawn8 } from "node:child_process";
|
|
17677
18096
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
17678
18097
|
var connectedMarkers = ["Connected to Linzumi", "Runner connected:"];
|
|
@@ -17705,7 +18124,7 @@ function startCommanderDaemon(options) {
|
|
|
17705
18124
|
logFile
|
|
17706
18125
|
];
|
|
17707
18126
|
mkdirSync11(statusDir, { recursive: true });
|
|
17708
|
-
mkdirSync11(
|
|
18127
|
+
mkdirSync11(dirname9(logFile), { recursive: true });
|
|
17709
18128
|
const out = openSync3(logFile, "a");
|
|
17710
18129
|
const err = openSync3(logFile, "a");
|
|
17711
18130
|
writeCliAuditEvent("process.spawn", {
|
|
@@ -17757,7 +18176,7 @@ function commanderDaemonStatus(runnerId, statusDir = commanderStatusDir(), proce
|
|
|
17757
18176
|
}
|
|
17758
18177
|
async function waitForCommanderDaemon(options) {
|
|
17759
18178
|
const now = options.now ?? (() => Date.now());
|
|
17760
|
-
const
|
|
18179
|
+
const readTextFile = options.readTextFile ?? ((path) => existsSync11(path) ? readFileSync11(path, "utf8") : undefined);
|
|
17761
18180
|
const statusImpl = options.statusImpl ?? commanderDaemonStatus;
|
|
17762
18181
|
const deadline = now() + options.timeoutMs;
|
|
17763
18182
|
while (now() <= deadline) {
|
|
@@ -17768,7 +18187,7 @@ async function waitForCommanderDaemon(options) {
|
|
|
17768
18187
|
case "stopped":
|
|
17769
18188
|
return { ok: false, reason: "stopped" };
|
|
17770
18189
|
case "running": {
|
|
17771
|
-
const log =
|
|
18190
|
+
const log = readTextFile(status.record.logFile);
|
|
17772
18191
|
if (log === undefined) {
|
|
17773
18192
|
return { ok: false, reason: "timeout" };
|
|
17774
18193
|
}
|
|
@@ -17776,7 +18195,7 @@ async function waitForCommanderDaemon(options) {
|
|
|
17776
18195
|
return { ok: true, record: status.record };
|
|
17777
18196
|
}
|
|
17778
18197
|
await waitForFileChangeOrTimeout(status.record.logFile, deadline, now, () => {
|
|
17779
|
-
const updatedLog =
|
|
18198
|
+
const updatedLog = readTextFile(status.record.logFile);
|
|
17780
18199
|
return updatedLog !== undefined && commanderLogIsConnected(updatedLog);
|
|
17781
18200
|
});
|
|
17782
18201
|
}
|
|
@@ -17902,7 +18321,7 @@ async function waitForFileChangeOrTimeout(path, deadline, now, ready2 = () => fa
|
|
|
17902
18321
|
};
|
|
17903
18322
|
const timer = setTimeout(finish, remaining);
|
|
17904
18323
|
try {
|
|
17905
|
-
watcher =
|
|
18324
|
+
watcher = watch(path, finish);
|
|
17906
18325
|
watcher.on("error", finish);
|
|
17907
18326
|
if (ready2()) {
|
|
17908
18327
|
finish();
|
|
@@ -17920,8 +18339,7 @@ async function waitForFileChangeOrTimeout(path, deadline, now, ready2 = () => fa
|
|
|
17920
18339
|
// src/index.ts
|
|
17921
18340
|
var flagDefinitions = new Map([
|
|
17922
18341
|
["version", { kind: "boolean" }],
|
|
17923
|
-
["
|
|
17924
|
-
["kandan-url", { kind: "value" }],
|
|
18342
|
+
["api-url", { kind: "value" }],
|
|
17925
18343
|
["token", { kind: "value" }],
|
|
17926
18344
|
["runner-id", { kind: "value" }],
|
|
17927
18345
|
["cwd", { kind: "value" }],
|
|
@@ -17931,7 +18349,6 @@ var flagDefinitions = new Map([
|
|
|
17931
18349
|
["workspace", { kind: "value" }],
|
|
17932
18350
|
["channel", { kind: "value" }],
|
|
17933
18351
|
["linzumi-thread-id", { kind: "value" }],
|
|
17934
|
-
["kandan-thread-id", { kind: "value" }],
|
|
17935
18352
|
["listen-user", { kind: "value" }],
|
|
17936
18353
|
["model", { kind: "value" }],
|
|
17937
18354
|
["reasoning-effort", { kind: "value" }],
|
|
@@ -17950,10 +18367,6 @@ var flagDefinitions = new Map([
|
|
|
17950
18367
|
["oauth-callback-host", { kind: "value" }],
|
|
17951
18368
|
["help", { kind: "boolean" }]
|
|
17952
18369
|
]);
|
|
17953
|
-
var flagAliases = new Map([
|
|
17954
|
-
["kandan-url", "linzumi-url"],
|
|
17955
|
-
["kandan-thread-id", "linzumi-thread-id"]
|
|
17956
|
-
]);
|
|
17957
18370
|
var helloFlagDefinitions = new Map([
|
|
17958
18371
|
["dir", { kind: "value" }],
|
|
17959
18372
|
["parent-dir", { kind: "value" }],
|
|
@@ -18209,8 +18622,7 @@ function parsePathsCommandArgs(args) {
|
|
|
18209
18622
|
case "--help":
|
|
18210
18623
|
help = true;
|
|
18211
18624
|
break;
|
|
18212
|
-
case "--
|
|
18213
|
-
case "--kandan-url": {
|
|
18625
|
+
case "--api-url": {
|
|
18214
18626
|
const value = args[index + 1];
|
|
18215
18627
|
if (value === undefined || value.startsWith("--")) {
|
|
18216
18628
|
throw new Error(`missing value for ${arg}`);
|
|
@@ -18321,7 +18733,7 @@ async function runAuthCommand(args) {
|
|
|
18321
18733
|
process.stdout.write(helpText());
|
|
18322
18734
|
return;
|
|
18323
18735
|
}
|
|
18324
|
-
const kandanUrl = required(values, "
|
|
18736
|
+
const kandanUrl = required(values, "api-url");
|
|
18325
18737
|
const target = parseOptionalChannelTarget(values);
|
|
18326
18738
|
const token = await acquireLocalRunnerTokenDetails({
|
|
18327
18739
|
kandanUrl,
|
|
@@ -18352,7 +18764,7 @@ async function parseStartRunnerArgs(args, deps = {
|
|
|
18352
18764
|
process.exit(0);
|
|
18353
18765
|
}
|
|
18354
18766
|
rejectStartTargetingFlags(values);
|
|
18355
|
-
const kandanUrl = stringValue4(values, "
|
|
18767
|
+
const kandanUrl = stringValue4(values, "api-url") ?? defaultLinzumiWebSocketUrl;
|
|
18356
18768
|
const requestedCwd = resolveUserPath(cwdArg ?? process.cwd());
|
|
18357
18769
|
const cwd = assertConfiguredAllowedCwds([requestedCwd])[0] ?? requestedCwd;
|
|
18358
18770
|
const explicitAllowedCwds = values.has("allowed-cwd") ? assertConfiguredAllowedCwds(parseAllowedCwdList(stringValue4(values, "allowed-cwd"))) : [];
|
|
@@ -18470,7 +18882,7 @@ async function parseAgentRunnerArgs(args, deps = {
|
|
|
18470
18882
|
approvalPolicy: stringValue4(values, "approval-policy"),
|
|
18471
18883
|
streamFlushMs: positiveIntegerValue2(values, "stream-flush-ms")
|
|
18472
18884
|
};
|
|
18473
|
-
const kandanUrl = stringValue4(values, "
|
|
18885
|
+
const kandanUrl = stringValue4(values, "api-url") ?? agentApiUrlToKandanUrl(tokenFile.apiUrl);
|
|
18474
18886
|
const requestedCwdValue = cwdArg ?? stringValue4(values, "cwd");
|
|
18475
18887
|
const requestedCwd = resolveUserPath(requestedCwdValue ?? process.cwd());
|
|
18476
18888
|
const configuredAllowedCwds2 = requestedCwdValue === undefined && !values.has("allowed-cwd") ? readConfiguredAllowedCwdDetailsForLinzumiUrl(kandanUrl) : { allowedCwds: [], missingAllowedCwds: [] };
|
|
@@ -18600,8 +19012,9 @@ async function parseRunnerArgs(args, deps = {
|
|
|
18600
19012
|
`);
|
|
18601
19013
|
process.exit(0);
|
|
18602
19014
|
}
|
|
18603
|
-
|
|
18604
|
-
const
|
|
19015
|
+
rejectConnectChannelFlags(values);
|
|
19016
|
+
const workspaceSlug = stringValue4(values, "workspace");
|
|
19017
|
+
const kandanUrl = stringValue4(values, "api-url") ?? defaultLinzumiWebSocketUrl;
|
|
18605
19018
|
const cwd = stringValue4(values, "cwd") ?? process.cwd();
|
|
18606
19019
|
const cwdAllowedCwds = assertConfiguredAllowedCwds([cwd]);
|
|
18607
19020
|
const localConfiguredAllowedCwds = values.has("allowed-cwd") ? { allowedCwds: [], missingAllowedCwds: [] } : readConfiguredAllowedCwdDetailsForLinzumiUrl(kandanUrl);
|
|
@@ -18612,8 +19025,7 @@ async function parseRunnerArgs(args, deps = {
|
|
|
18612
19025
|
const token = await deps.resolveToken({
|
|
18613
19026
|
kandanUrl,
|
|
18614
19027
|
explicitToken,
|
|
18615
|
-
workspaceSlug
|
|
18616
|
-
channelSlug: connectTarget?.channelSlug,
|
|
19028
|
+
workspaceSlug,
|
|
18617
19029
|
authFilePath: stringValue4(values, "auth-file"),
|
|
18618
19030
|
callbackHost: stringValue4(values, "oauth-callback-host"),
|
|
18619
19031
|
reportRejectedCachedToken: () => {
|
|
@@ -18621,7 +19033,6 @@ async function parseRunnerArgs(args, deps = {
|
|
|
18621
19033
|
`);
|
|
18622
19034
|
}
|
|
18623
19035
|
});
|
|
18624
|
-
const channelSession = parseChannelSession(values, token, connectTarget);
|
|
18625
19036
|
const editorRuntime = await deps.resolveEditorRuntime({
|
|
18626
19037
|
kandanUrl,
|
|
18627
19038
|
token,
|
|
@@ -18652,9 +19063,8 @@ async function parseRunnerArgs(args, deps = {
|
|
|
18652
19063
|
editorRuntime: editorRuntime.runtime,
|
|
18653
19064
|
socketFactory: trustedWebSocketFactory(kandanTlsTrustFromEnv()),
|
|
18654
19065
|
dependencyStatus,
|
|
18655
|
-
workspaceSlug:
|
|
18656
|
-
runtimeDefaults: runnerRuntimeDefaultsFromValues(values)
|
|
18657
|
-
channelSession
|
|
19066
|
+
workspaceSlug: workspaceSlug ?? singleWorkspaceScopeFromAccessToken(token),
|
|
19067
|
+
runtimeDefaults: runnerRuntimeDefaultsFromValues(values)
|
|
18658
19068
|
};
|
|
18659
19069
|
}
|
|
18660
19070
|
function runnerRuntimeDefaultsFromValues(values) {
|
|
@@ -18662,7 +19072,8 @@ function runnerRuntimeDefaultsFromValues(values) {
|
|
|
18662
19072
|
model: stringValue4(values, "model"),
|
|
18663
19073
|
reasoningEffort: stringValue4(values, "reasoning-effort"),
|
|
18664
19074
|
approvalPolicy: stringValue4(values, "approval-policy"),
|
|
18665
|
-
sandbox: stringValue4(values, "sandbox")
|
|
19075
|
+
sandbox: stringValue4(values, "sandbox"),
|
|
19076
|
+
allowPortForwardingByDefault: undefined
|
|
18666
19077
|
};
|
|
18667
19078
|
}
|
|
18668
19079
|
function strictFlagValues(args, definitions = flagDefinitions) {
|
|
@@ -18677,16 +19088,15 @@ function strictFlagValues(args, definitions = flagDefinitions) {
|
|
|
18677
19088
|
if (definition === undefined) {
|
|
18678
19089
|
throw new Error(`invalid flag: --${rawKey}`);
|
|
18679
19090
|
}
|
|
18680
|
-
const key = flagAliases.get(rawKey) ?? rawKey;
|
|
18681
19091
|
if (definition.kind === "boolean") {
|
|
18682
|
-
values.set(
|
|
19092
|
+
values.set(rawKey, true);
|
|
18683
19093
|
continue;
|
|
18684
19094
|
}
|
|
18685
19095
|
const next = args[index + 1];
|
|
18686
19096
|
if (next === undefined || next.startsWith("--")) {
|
|
18687
19097
|
throw new Error(`missing value for --${rawKey}`);
|
|
18688
19098
|
}
|
|
18689
|
-
values.set(
|
|
19099
|
+
values.set(rawKey, next);
|
|
18690
19100
|
index += 1;
|
|
18691
19101
|
}
|
|
18692
19102
|
return values;
|
|
@@ -18751,7 +19161,7 @@ function stripDaemonSupervisorFlags(args) {
|
|
|
18751
19161
|
function rejectStartTargetingFlags(values) {
|
|
18752
19162
|
const unsupportedFlags = ["workspace", "channel"].filter((flag) => values.has(flag));
|
|
18753
19163
|
if (unsupportedFlags.length > 0) {
|
|
18754
|
-
throw new Error(`linzumi start chooses its workspace during browser onboarding; remove ${unsupportedFlags.map((flag) => `--${flag}`).join(", ")} or use linzumi connect for an explicit workspace
|
|
19164
|
+
throw new Error(`linzumi start chooses its workspace during browser onboarding; remove ${unsupportedFlags.map((flag) => `--${flag}`).join(", ")} or use linzumi connect --workspace for an explicit workspace.`);
|
|
18755
19165
|
}
|
|
18756
19166
|
}
|
|
18757
19167
|
function resolveUserPath(pathValue) {
|
|
@@ -18763,26 +19173,6 @@ function resolveUserPath(pathValue) {
|
|
|
18763
19173
|
}
|
|
18764
19174
|
return resolve10(pathValue);
|
|
18765
19175
|
}
|
|
18766
|
-
function parseChannelSession(values, token, target) {
|
|
18767
|
-
if (target === undefined || target.channelSlug === undefined) {
|
|
18768
|
-
return;
|
|
18769
|
-
}
|
|
18770
|
-
const listenUser = stringValue4(values, "listen-user") ?? defaultListenUserFromToken(token);
|
|
18771
|
-
return {
|
|
18772
|
-
workspaceSlug: target.workspaceSlug,
|
|
18773
|
-
channelSlug: target.channelSlug,
|
|
18774
|
-
kandanThreadId: stringValue4(values, "linzumi-thread-id"),
|
|
18775
|
-
listenUser,
|
|
18776
|
-
model: stringValue4(values, "model"),
|
|
18777
|
-
reasoningEffort: stringValue4(values, "reasoning-effort"),
|
|
18778
|
-
sandbox: stringValue4(values, "sandbox"),
|
|
18779
|
-
approvalPolicy: stringValue4(values, "approval-policy"),
|
|
18780
|
-
streamFlushMs: positiveIntegerValue2(values, "stream-flush-ms")
|
|
18781
|
-
};
|
|
18782
|
-
}
|
|
18783
|
-
function parseConnectTarget(values) {
|
|
18784
|
-
return parseOptionalChannelTarget(values);
|
|
18785
|
-
}
|
|
18786
19176
|
function defaultListenUserFromToken(token) {
|
|
18787
19177
|
const username = identityFromAccessToken(token).actorUsername;
|
|
18788
19178
|
if (username !== undefined) {
|
|
@@ -18790,6 +19180,17 @@ function defaultListenUserFromToken(token) {
|
|
|
18790
19180
|
}
|
|
18791
19181
|
throw new Error("missing --listen-user and authenticated user is unavailable");
|
|
18792
19182
|
}
|
|
19183
|
+
function rejectConnectChannelFlags(values) {
|
|
19184
|
+
const unsupportedFlags = [
|
|
19185
|
+
"channel",
|
|
19186
|
+
"linzumi-thread-id",
|
|
19187
|
+
"listen-user"
|
|
19188
|
+
].filter((flag) => values.has(flag));
|
|
19189
|
+
if (unsupportedFlags.length === 0) {
|
|
19190
|
+
return;
|
|
19191
|
+
}
|
|
19192
|
+
throw new Error(`linzumi connect starts a workspace Commander; remove ${unsupportedFlags.map((flag) => `--${flag}`).join(", ")}.`);
|
|
19193
|
+
}
|
|
18793
19194
|
function parseOptionalChannelTarget(values) {
|
|
18794
19195
|
const channel = stringValue4(values, "channel");
|
|
18795
19196
|
const workspace = stringValue4(values, "workspace");
|
|
@@ -18876,22 +19277,17 @@ Usage:
|
|
|
18876
19277
|
linzumi commander <folder> [options]
|
|
18877
19278
|
linzumi start <folder> [options]
|
|
18878
19279
|
linzumi paths list|add|remove [path]
|
|
18879
|
-
linzumi connect --workspace <slug> [
|
|
18880
|
-
linzumi auth --
|
|
19280
|
+
linzumi connect --workspace <slug> [options]
|
|
19281
|
+
linzumi auth --api-url <url> [--workspace <slug> --channel <slug>]
|
|
18881
19282
|
|
|
18882
19283
|
Connection:
|
|
18883
|
-
--
|
|
18884
|
-
(deprecated alias: --kandan-url)
|
|
19284
|
+
--api-url <url> Linzumi API URL, default ${defaultLinzumiWebSocketUrl}
|
|
18885
19285
|
--token <jwt> Optional override token. Otherwise ~/.linzumi/auth.json is validated or OAuth opens.
|
|
18886
19286
|
--auth-file <path> Auth cache path, default ~/.linzumi/auth.json
|
|
18887
19287
|
--oauth-callback-host <ip> Callback host reachable by your browser
|
|
18888
19288
|
|
|
18889
|
-
Workspace
|
|
19289
|
+
Workspace:
|
|
18890
19290
|
--workspace <slug> Workspace slug
|
|
18891
|
-
--channel <slug|w/c> Optional channel slug, or workspace/channel
|
|
18892
|
-
--linzumi-thread-id <uuid> Resume an existing Linzumi thread instead of announcing a new root
|
|
18893
|
-
(deprecated alias: --kandan-thread-id)
|
|
18894
|
-
--listen-user <user|all> User whose replies are accepted, default authenticated user
|
|
18895
19291
|
|
|
18896
19292
|
Codex:
|
|
18897
19293
|
--cwd <path> Working directory for Codex, default current directory
|
|
@@ -18923,16 +19319,15 @@ Examples:
|
|
|
18923
19319
|
linzumi start ~/code/my-app
|
|
18924
19320
|
linzumi connect --workspace <your-workspace> --launch-tui
|
|
18925
19321
|
linzumi connect --workspace <your-workspace> --model gpt-5 --reasoning-effort low --fast --launch-tui
|
|
18926
|
-
linzumi connect --workspace <your-workspace> --channel <your-channel>
|
|
18927
19322
|
linzumi auth --workspace <your-workspace> --channel <your-channel>
|
|
18928
19323
|
linzumi paths add ~/code/my-app
|
|
18929
19324
|
linzumi paths list
|
|
18930
19325
|
|
|
18931
19326
|
Bad:
|
|
18932
|
-
linzumi connect --
|
|
18933
|
-
|
|
18934
|
-
linzumi connect --token "$TOKEN" --listen-
|
|
18935
|
-
Invalid
|
|
19327
|
+
linzumi connect --workspace <your-workspace> --channel <your-channel>
|
|
19328
|
+
Invalid: Commanders connect to workspaces, not channels.
|
|
19329
|
+
linzumi connect --token "$TOKEN" --listen-user sean
|
|
19330
|
+
Invalid: Commanders connect to workspaces, not individual channel listeners.
|
|
18936
19331
|
linzumi connect --workspace <your-workspace> --allowed-cwd /does/not/exist
|
|
18937
19332
|
Invalid --allowed-cwd: allowed cwd roots must exist locally.
|
|
18938
19333
|
linzumi connect --workspace <your-workspace> --forward-port vite
|
|
@@ -18999,12 +19394,12 @@ function pathsHelpText() {
|
|
|
18999
19394
|
return `Linzumi trusted paths
|
|
19000
19395
|
|
|
19001
19396
|
Usage:
|
|
19002
|
-
linzumi paths [--
|
|
19003
|
-
linzumi paths [--
|
|
19004
|
-
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>
|
|
19005
19400
|
|
|
19006
19401
|
Trusted paths are stored in ~/.linzumi/config.json. Production/default paths
|
|
19007
|
-
use the root config fields; explicit --
|
|
19402
|
+
use the root config fields; explicit --api-url paths use a URL-scoped config
|
|
19008
19403
|
section so local, staging, and production runners do not share trust state.
|
|
19009
19404
|
`;
|
|
19010
19405
|
}
|
|
@@ -19021,8 +19416,7 @@ What it does:
|
|
|
19021
19416
|
previews, and the browser VS Code editor.
|
|
19022
19417
|
|
|
19023
19418
|
Options:
|
|
19024
|
-
--
|
|
19025
|
-
(deprecated alias: --kandan-url)
|
|
19419
|
+
--api-url <url> Linzumi API URL, default ${defaultLinzumiWebSocketUrl}
|
|
19026
19420
|
--token <jwt> Optional scoped local-runner token override
|
|
19027
19421
|
--auth-file <path> Auth cache path, default ~/.linzumi/auth.json
|
|
19028
19422
|
--oauth-callback-host <ip> Callback host reachable by your browser
|
|
@@ -19062,8 +19456,7 @@ What it does:
|
|
|
19062
19456
|
|
|
19063
19457
|
Options:
|
|
19064
19458
|
--agent-token-file <path> Agent token cache, default ~/.linzumi/agent-token.json
|
|
19065
|
-
--
|
|
19066
|
-
(deprecated alias: --kandan-url)
|
|
19459
|
+
--api-url <url> Linzumi API URL. Defaults deterministically from the stored apiUrl.
|
|
19067
19460
|
--runner-id <id> Stable Commander id
|
|
19068
19461
|
--codex-bin <path> Codex executable, default codex
|
|
19069
19462
|
--code-server-bin <path> Custom development code-server executable. By default Linzumi installs the approved editor runtime.
|
|
@@ -19079,7 +19472,7 @@ Options:
|
|
|
19079
19472
|
Examples:
|
|
19080
19473
|
linzumi paths add "$PWD"
|
|
19081
19474
|
linzumi commander daemon --runner-id hello-world-commander
|
|
19082
|
-
linzumi commander ~/code/my-app --
|
|
19475
|
+
linzumi commander ~/code/my-app --api-url http://127.0.0.1:4162 --runner-id local-qa-commander
|
|
19083
19476
|
`;
|
|
19084
19477
|
}
|
|
19085
19478
|
function connectGuideText() {
|