@kidlat-dakila/flightplan 0.1.7 → 0.1.8
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/backend/main.js +826 -1336
- package/backend/plugin/skills/live/SKILL.md +79 -0
- package/backend/plugin/skills/review/SKILL.md +8 -5
- package/frontend/assets/_branchId-Caxyy__g.js +1 -0
- package/frontend/assets/{_branchId-438YLxpk.js → _branchId-IJ4VEzEl.js} +1 -1
- package/frontend/assets/{_id-yAHjl11v.js → _id-3L9ONe4W.js} +1 -1
- package/frontend/assets/_id-CvORsoNj.js +1 -0
- package/frontend/assets/{agents-CUULznCR.js → agents-DnjhKMUc.js} +1 -1
- package/frontend/assets/agents-bla75JmI.js +1 -0
- package/frontend/assets/{create-Byti8N1q.js → create-B82q7ZMu.js} +1 -1
- package/frontend/assets/create-C9yw-thL.js +1 -0
- package/frontend/assets/{create-t6MxPYs8.js → create-CEpA1s8S.js} +1 -1
- package/frontend/assets/{create-DHjp2cB6.js → create-D0h6PRxn.js} +1 -1
- package/frontend/assets/{download-kIOYm7yl.js → download-CwWMZwNG.js} +1 -1
- package/frontend/assets/forges-BH3uXIQL.js +1 -0
- package/frontend/assets/{forges-5NgJFexV.js → forges-uSh1-w20.js} +1 -1
- package/frontend/assets/{index-DVMDfdCW.js → index--nj01XKS.js} +1 -1
- package/frontend/assets/index-0VAWT0gs.js +1 -0
- package/frontend/assets/{index-Dq71dq4Z.js → index-B0zuYONu.js} +1 -1
- package/frontend/assets/{index-WOMODjD2.js → index-BQaZ5gZR.js} +1 -1
- package/frontend/assets/{index-BUtsWXGk.js → index-BZ6iL63Z.js} +1 -1
- package/frontend/assets/{index-CRQLJ5uq.js → index-Bar8NyIm.js} +1 -1
- package/frontend/assets/{index-EFsgiJx1.js → index-BlTfCkr5.js} +1 -1
- package/frontend/assets/{index-Dz-E4Hhc.js → index-BvuPClj3.js} +1 -1
- package/frontend/assets/index-C9xsdcXo.js +1 -0
- package/frontend/assets/{index-Cjx98rmL.js → index-CJDNq1TA.js} +1 -1
- package/frontend/assets/{index-N0J0txvy.js → index-CJslcuJ0.js} +1 -1
- package/frontend/assets/index-CTKqkqZN.css +1 -0
- package/frontend/assets/{index-CAt5Gv5u.js → index-CXyB0ld0.js} +1 -1
- package/frontend/assets/{index-BDhIIxnY.js → index-CcORd1N6.js} +1 -1
- package/frontend/assets/{index-EItMs0kz.js → index-CrAQ5_e4.js} +1 -1
- package/frontend/assets/{index-CmW92SdM.js → index-DG0FDX8u.js} +1 -1
- package/frontend/assets/index-DKnoo-kT.js +455 -0
- package/frontend/assets/{index-BrL94etp.js → index-DKzDkR6v.js} +1 -1
- package/frontend/assets/{index-9MPLrKh9.js → index-DfKNJbUM.js} +40 -40
- package/frontend/assets/{index-CBObEG9P.js → index-DlUHisPA.js} +1 -1
- package/frontend/assets/{index-DYy-kFEi.js → index-Dv5cF6qF.js} +1 -1
- package/frontend/assets/{index-Qxg2C8CP.js → index-JPWJ3IiN.js} +1 -1
- package/frontend/assets/{index-RYSZy-Ra.js → index-V1avMli5.js} +1 -1
- package/frontend/assets/{index-Dk3p64fP.js → index-iRAoFOv3.js} +1 -1
- package/frontend/assets/repositories-DqGU7W63.js +1 -0
- package/frontend/assets/{repositories-VWl6aq7K.js → repositories-DuObN8PJ.js} +1 -1
- package/frontend/assets/review-BbbMUFsk.js +1 -0
- package/frontend/assets/{review-CXzRf1jk.js → review-C3k0h5Vl.js} +1 -1
- package/frontend/assets/{route--z3gnt4z.js → route-D8s8AylJ.js} +1 -1
- package/frontend/index.html +2 -2
- package/package.json +1 -2
- package/published-review/app.css +1 -1
- package/published-review/app.js +94 -96
- package/frontend/assets/_branchId-PhBseeXo.js +0 -1
- package/frontend/assets/_id-z15a_Wqg.js +0 -1
- package/frontend/assets/agents-CF_BNYuU.js +0 -1
- package/frontend/assets/create-DiPNM_Jx.js +0 -1
- package/frontend/assets/forges-Dz31lZmK.js +0 -1
- package/frontend/assets/index-BDgPH-og.js +0 -1
- package/frontend/assets/index-C8_4U9zA.js +0 -457
- package/frontend/assets/index-CSy69oc4.js +0 -1
- package/frontend/assets/index-Cmg8rxUj.css +0 -1
- package/frontend/assets/repositories-BrbB16PW.js +0 -1
- package/frontend/assets/review-BMO-QDpl.js +0 -1
package/backend/main.js
CHANGED
|
@@ -3921,50 +3921,50 @@ var require_fast_uri = __commonJS({
|
|
|
3921
3921
|
schemelessOptions.skipEscape = true;
|
|
3922
3922
|
return serialize(resolved, schemelessOptions);
|
|
3923
3923
|
}
|
|
3924
|
-
function resolveComponent(base,
|
|
3924
|
+
function resolveComponent(base, relative3, options, skipNormalization) {
|
|
3925
3925
|
const target = {};
|
|
3926
3926
|
if (!skipNormalization) {
|
|
3927
3927
|
base = parse8(serialize(base, options), options);
|
|
3928
|
-
|
|
3928
|
+
relative3 = parse8(serialize(relative3, options), options);
|
|
3929
3929
|
}
|
|
3930
3930
|
options = options || {};
|
|
3931
|
-
if (!options.tolerant &&
|
|
3932
|
-
target.scheme =
|
|
3933
|
-
target.userinfo =
|
|
3934
|
-
target.host =
|
|
3935
|
-
target.port =
|
|
3936
|
-
target.path = removeDotSegments(
|
|
3937
|
-
target.query =
|
|
3931
|
+
if (!options.tolerant && relative3.scheme) {
|
|
3932
|
+
target.scheme = relative3.scheme;
|
|
3933
|
+
target.userinfo = relative3.userinfo;
|
|
3934
|
+
target.host = relative3.host;
|
|
3935
|
+
target.port = relative3.port;
|
|
3936
|
+
target.path = removeDotSegments(relative3.path || "");
|
|
3937
|
+
target.query = relative3.query;
|
|
3938
3938
|
} else {
|
|
3939
|
-
if (
|
|
3940
|
-
target.userinfo =
|
|
3941
|
-
target.host =
|
|
3942
|
-
target.port =
|
|
3943
|
-
target.path = removeDotSegments(
|
|
3944
|
-
target.query =
|
|
3939
|
+
if (relative3.userinfo !== void 0 || relative3.host !== void 0 || relative3.port !== void 0) {
|
|
3940
|
+
target.userinfo = relative3.userinfo;
|
|
3941
|
+
target.host = relative3.host;
|
|
3942
|
+
target.port = relative3.port;
|
|
3943
|
+
target.path = removeDotSegments(relative3.path || "");
|
|
3944
|
+
target.query = relative3.query;
|
|
3945
3945
|
} else {
|
|
3946
|
-
if (!
|
|
3946
|
+
if (!relative3.path) {
|
|
3947
3947
|
target.path = base.path;
|
|
3948
|
-
if (
|
|
3949
|
-
target.query =
|
|
3948
|
+
if (relative3.query !== void 0) {
|
|
3949
|
+
target.query = relative3.query;
|
|
3950
3950
|
} else {
|
|
3951
3951
|
target.query = base.query;
|
|
3952
3952
|
}
|
|
3953
3953
|
} else {
|
|
3954
|
-
if (
|
|
3955
|
-
target.path = removeDotSegments(
|
|
3954
|
+
if (relative3.path[0] === "/") {
|
|
3955
|
+
target.path = removeDotSegments(relative3.path);
|
|
3956
3956
|
} else {
|
|
3957
3957
|
const baseHasAuthority = base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0;
|
|
3958
3958
|
if (baseHasAuthority && !base.path) {
|
|
3959
|
-
target.path = "/" +
|
|
3959
|
+
target.path = "/" + relative3.path;
|
|
3960
3960
|
} else if (!base.path) {
|
|
3961
|
-
target.path =
|
|
3961
|
+
target.path = relative3.path;
|
|
3962
3962
|
} else {
|
|
3963
|
-
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) +
|
|
3963
|
+
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative3.path;
|
|
3964
3964
|
}
|
|
3965
3965
|
target.path = base.scheme === void 0 && !baseHasAuthority && target.path[0] !== "/" ? removeDotSegmentsRelative(target.path) : removeDotSegments(target.path);
|
|
3966
3966
|
}
|
|
3967
|
-
target.query =
|
|
3967
|
+
target.query = relative3.query;
|
|
3968
3968
|
}
|
|
3969
3969
|
target.userinfo = base.userinfo;
|
|
3970
3970
|
target.host = base.host;
|
|
@@ -3972,7 +3972,7 @@ var require_fast_uri = __commonJS({
|
|
|
3972
3972
|
}
|
|
3973
3973
|
target.scheme = base.scheme;
|
|
3974
3974
|
}
|
|
3975
|
-
target.fragment =
|
|
3975
|
+
target.fragment = relative3.fragment;
|
|
3976
3976
|
return target;
|
|
3977
3977
|
}
|
|
3978
3978
|
function equal(uriA, uriB, options) {
|
|
@@ -7971,9 +7971,9 @@ var require_CachedInputFileSystem = __commonJS({
|
|
|
7971
7971
|
this.fileSystem.readFileSync,
|
|
7972
7972
|
this.fileSystem
|
|
7973
7973
|
);
|
|
7974
|
-
const
|
|
7974
|
+
const readFile6 = this._readFileBackend.provide;
|
|
7975
7975
|
this.readFile = /** @type {FileSystem["readFile"]} */
|
|
7976
|
-
|
|
7976
|
+
readFile6;
|
|
7977
7977
|
const readFileSync = this._readFileBackend.provideSync;
|
|
7978
7978
|
this.readFileSync = /** @type {SyncFileSystem["readFileSync"]} */
|
|
7979
7979
|
readFileSync;
|
|
@@ -8561,8 +8561,8 @@ var require_graceful_fs = __commonJS({
|
|
|
8561
8561
|
fs2.createReadStream = createReadStream;
|
|
8562
8562
|
fs2.createWriteStream = createWriteStream;
|
|
8563
8563
|
var fs$readFile = fs2.readFile;
|
|
8564
|
-
fs2.readFile =
|
|
8565
|
-
function
|
|
8564
|
+
fs2.readFile = readFile6;
|
|
8565
|
+
function readFile6(path11, options, cb) {
|
|
8566
8566
|
if (typeof options === "function")
|
|
8567
8567
|
cb = options, options = null;
|
|
8568
8568
|
return go$readFile(path11, options, cb);
|
|
@@ -9285,7 +9285,7 @@ var require_path = __commonJS({
|
|
|
9285
9285
|
}
|
|
9286
9286
|
return posixNormalize(maybePath);
|
|
9287
9287
|
};
|
|
9288
|
-
var
|
|
9288
|
+
var join21 = (rootPath, request) => {
|
|
9289
9289
|
if (!request) return normalize5(rootPath);
|
|
9290
9290
|
const requestType = getType(request);
|
|
9291
9291
|
switch (requestType) {
|
|
@@ -9330,7 +9330,7 @@ var require_path = __commonJS({
|
|
|
9330
9330
|
cacheEntry = inner.get(request);
|
|
9331
9331
|
if (cacheEntry !== void 0) return cacheEntry;
|
|
9332
9332
|
}
|
|
9333
|
-
cacheEntry =
|
|
9333
|
+
cacheEntry = join21(rootPath, request);
|
|
9334
9334
|
inner.set(request, cacheEntry);
|
|
9335
9335
|
return cacheEntry;
|
|
9336
9336
|
};
|
|
@@ -9446,7 +9446,7 @@ var require_path = __commonJS({
|
|
|
9446
9446
|
module2.exports.isRelativeRequest = isRelativeRequest;
|
|
9447
9447
|
module2.exports.isSubPath = isSubPath;
|
|
9448
9448
|
module2.exports.isWindowsPath = isWindowsPath;
|
|
9449
|
-
module2.exports.join =
|
|
9449
|
+
module2.exports.join = join21;
|
|
9450
9450
|
module2.exports.normalize = normalize5;
|
|
9451
9451
|
module2.exports.toPath = toPath;
|
|
9452
9452
|
}
|
|
@@ -44067,7 +44067,7 @@ var require_type_is = __commonJS({
|
|
|
44067
44067
|
var require_depd = __commonJS({
|
|
44068
44068
|
"node_modules/.pnpm/depd@2.0.0/node_modules/depd/index.js"(exports2, module2) {
|
|
44069
44069
|
"use strict";
|
|
44070
|
-
var
|
|
44070
|
+
var relative3 = require("path").relative;
|
|
44071
44071
|
module2.exports = depd;
|
|
44072
44072
|
var basePath = process.cwd();
|
|
44073
44073
|
function containsNamespace(str, namespace) {
|
|
@@ -44259,7 +44259,7 @@ var require_depd = __commonJS({
|
|
|
44259
44259
|
return formatted;
|
|
44260
44260
|
}
|
|
44261
44261
|
function formatLocation(callSite) {
|
|
44262
|
-
return
|
|
44262
|
+
return relative3(basePath, callSite[0]) + ":" + callSite[1] + ":" + callSite[2];
|
|
44263
44263
|
}
|
|
44264
44264
|
function getStack() {
|
|
44265
44265
|
var limit = Error.stackTraceLimit;
|
|
@@ -53284,7 +53284,7 @@ var require_thread_stream = __commonJS({
|
|
|
53284
53284
|
var { version: version3 } = require_package();
|
|
53285
53285
|
var { EventEmitter } = require("events");
|
|
53286
53286
|
var { Worker } = require("worker_threads");
|
|
53287
|
-
var { join:
|
|
53287
|
+
var { join: join21 } = require("path");
|
|
53288
53288
|
var { pathToFileURL } = require("url");
|
|
53289
53289
|
var { wait } = require_wait();
|
|
53290
53290
|
var {
|
|
@@ -53327,7 +53327,7 @@ var require_thread_stream = __commonJS({
|
|
|
53327
53327
|
function createWorker(stream, opts) {
|
|
53328
53328
|
const { filename, workerData } = opts;
|
|
53329
53329
|
const bundlerOverrides = "__bundlerPathsOverrides" in globalThis ? globalThis.__bundlerPathsOverrides : {};
|
|
53330
|
-
const toExecute = bundlerOverrides["thread-stream-worker"] ||
|
|
53330
|
+
const toExecute = bundlerOverrides["thread-stream-worker"] || join21(__dirname, "lib", "worker.js");
|
|
53331
53331
|
const worker = new Worker(toExecute, {
|
|
53332
53332
|
...opts.workerOpts,
|
|
53333
53333
|
trackUnmanagedFds: false,
|
|
@@ -53730,7 +53730,7 @@ var require_transport = __commonJS({
|
|
|
53730
53730
|
"use strict";
|
|
53731
53731
|
var { createRequire } = require("module");
|
|
53732
53732
|
var getCallers = require_caller();
|
|
53733
|
-
var { join:
|
|
53733
|
+
var { join: join21, isAbsolute: isAbsolute2, sep: sep3 } = require("node:path");
|
|
53734
53734
|
var sleep = require_atomic_sleep();
|
|
53735
53735
|
var onExit = require_on_exit_leak_free();
|
|
53736
53736
|
var ThreadStream = require_thread_stream();
|
|
@@ -53793,7 +53793,7 @@ var require_transport = __commonJS({
|
|
|
53793
53793
|
throw new Error("only one of target or targets can be specified");
|
|
53794
53794
|
}
|
|
53795
53795
|
if (targets) {
|
|
53796
|
-
target = bundlerOverrides["pino-worker"] ||
|
|
53796
|
+
target = bundlerOverrides["pino-worker"] || join21(__dirname, "worker.js");
|
|
53797
53797
|
options.targets = targets.filter((dest) => dest.target).map((dest) => {
|
|
53798
53798
|
return {
|
|
53799
53799
|
...dest,
|
|
@@ -53811,7 +53811,7 @@ var require_transport = __commonJS({
|
|
|
53811
53811
|
});
|
|
53812
53812
|
});
|
|
53813
53813
|
} else if (pipeline) {
|
|
53814
|
-
target = bundlerOverrides["pino-worker"] ||
|
|
53814
|
+
target = bundlerOverrides["pino-worker"] || join21(__dirname, "worker.js");
|
|
53815
53815
|
options.pipelines = [pipeline.map((dest) => {
|
|
53816
53816
|
return {
|
|
53817
53817
|
...dest,
|
|
@@ -53833,7 +53833,7 @@ var require_transport = __commonJS({
|
|
|
53833
53833
|
return origin;
|
|
53834
53834
|
}
|
|
53835
53835
|
if (origin === "pino/file") {
|
|
53836
|
-
return
|
|
53836
|
+
return join21(__dirname, "..", "file.js");
|
|
53837
53837
|
}
|
|
53838
53838
|
let fixTarget2;
|
|
53839
53839
|
for (const filePath of callers) {
|
|
@@ -54823,7 +54823,7 @@ var require_safe_stable_stringify = __commonJS({
|
|
|
54823
54823
|
return circularValue;
|
|
54824
54824
|
}
|
|
54825
54825
|
let res = "";
|
|
54826
|
-
let
|
|
54826
|
+
let join21 = ",";
|
|
54827
54827
|
const originalIndentation = indentation;
|
|
54828
54828
|
if (Array.isArray(value)) {
|
|
54829
54829
|
if (value.length === 0) {
|
|
@@ -54837,7 +54837,7 @@ var require_safe_stable_stringify = __commonJS({
|
|
|
54837
54837
|
indentation += spacer;
|
|
54838
54838
|
res += `
|
|
54839
54839
|
${indentation}`;
|
|
54840
|
-
|
|
54840
|
+
join21 = `,
|
|
54841
54841
|
${indentation}`;
|
|
54842
54842
|
}
|
|
54843
54843
|
const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
|
|
@@ -54845,13 +54845,13 @@ ${indentation}`;
|
|
|
54845
54845
|
for (; i155 < maximumValuesToStringify - 1; i155++) {
|
|
54846
54846
|
const tmp2 = stringifyFnReplacer(String(i155), value, stack, replacer, spacer, indentation);
|
|
54847
54847
|
res += tmp2 !== void 0 ? tmp2 : "null";
|
|
54848
|
-
res +=
|
|
54848
|
+
res += join21;
|
|
54849
54849
|
}
|
|
54850
54850
|
const tmp = stringifyFnReplacer(String(i155), value, stack, replacer, spacer, indentation);
|
|
54851
54851
|
res += tmp !== void 0 ? tmp : "null";
|
|
54852
54852
|
if (value.length - 1 > maximumBreadth) {
|
|
54853
54853
|
const removedKeys = value.length - maximumBreadth - 1;
|
|
54854
|
-
res += `${
|
|
54854
|
+
res += `${join21}"... ${getItemCount(removedKeys)} not stringified"`;
|
|
54855
54855
|
}
|
|
54856
54856
|
if (spacer !== "") {
|
|
54857
54857
|
res += `
|
|
@@ -54872,7 +54872,7 @@ ${originalIndentation}`;
|
|
|
54872
54872
|
let separator = "";
|
|
54873
54873
|
if (spacer !== "") {
|
|
54874
54874
|
indentation += spacer;
|
|
54875
|
-
|
|
54875
|
+
join21 = `,
|
|
54876
54876
|
${indentation}`;
|
|
54877
54877
|
whitespace = " ";
|
|
54878
54878
|
}
|
|
@@ -54886,13 +54886,13 @@ ${indentation}`;
|
|
|
54886
54886
|
const tmp = stringifyFnReplacer(key2, value, stack, replacer, spacer, indentation);
|
|
54887
54887
|
if (tmp !== void 0) {
|
|
54888
54888
|
res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
|
|
54889
|
-
separator =
|
|
54889
|
+
separator = join21;
|
|
54890
54890
|
}
|
|
54891
54891
|
}
|
|
54892
54892
|
if (keyLength > maximumBreadth) {
|
|
54893
54893
|
const removedKeys = keyLength - maximumBreadth;
|
|
54894
54894
|
res += `${separator}"...":${whitespace}"${getItemCount(removedKeys)} not stringified"`;
|
|
54895
|
-
separator =
|
|
54895
|
+
separator = join21;
|
|
54896
54896
|
}
|
|
54897
54897
|
if (spacer !== "" && separator.length > 1) {
|
|
54898
54898
|
res = `
|
|
@@ -54933,7 +54933,7 @@ ${originalIndentation}`;
|
|
|
54933
54933
|
}
|
|
54934
54934
|
const originalIndentation = indentation;
|
|
54935
54935
|
let res = "";
|
|
54936
|
-
let
|
|
54936
|
+
let join21 = ",";
|
|
54937
54937
|
if (Array.isArray(value)) {
|
|
54938
54938
|
if (value.length === 0) {
|
|
54939
54939
|
return "[]";
|
|
@@ -54946,7 +54946,7 @@ ${originalIndentation}`;
|
|
|
54946
54946
|
indentation += spacer;
|
|
54947
54947
|
res += `
|
|
54948
54948
|
${indentation}`;
|
|
54949
|
-
|
|
54949
|
+
join21 = `,
|
|
54950
54950
|
${indentation}`;
|
|
54951
54951
|
}
|
|
54952
54952
|
const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
|
|
@@ -54954,13 +54954,13 @@ ${indentation}`;
|
|
|
54954
54954
|
for (; i155 < maximumValuesToStringify - 1; i155++) {
|
|
54955
54955
|
const tmp2 = stringifyArrayReplacer(String(i155), value[i155], stack, replacer, spacer, indentation);
|
|
54956
54956
|
res += tmp2 !== void 0 ? tmp2 : "null";
|
|
54957
|
-
res +=
|
|
54957
|
+
res += join21;
|
|
54958
54958
|
}
|
|
54959
54959
|
const tmp = stringifyArrayReplacer(String(i155), value[i155], stack, replacer, spacer, indentation);
|
|
54960
54960
|
res += tmp !== void 0 ? tmp : "null";
|
|
54961
54961
|
if (value.length - 1 > maximumBreadth) {
|
|
54962
54962
|
const removedKeys = value.length - maximumBreadth - 1;
|
|
54963
|
-
res += `${
|
|
54963
|
+
res += `${join21}"... ${getItemCount(removedKeys)} not stringified"`;
|
|
54964
54964
|
}
|
|
54965
54965
|
if (spacer !== "") {
|
|
54966
54966
|
res += `
|
|
@@ -54973,7 +54973,7 @@ ${originalIndentation}`;
|
|
|
54973
54973
|
let whitespace = "";
|
|
54974
54974
|
if (spacer !== "") {
|
|
54975
54975
|
indentation += spacer;
|
|
54976
|
-
|
|
54976
|
+
join21 = `,
|
|
54977
54977
|
${indentation}`;
|
|
54978
54978
|
whitespace = " ";
|
|
54979
54979
|
}
|
|
@@ -54982,7 +54982,7 @@ ${indentation}`;
|
|
|
54982
54982
|
const tmp = stringifyArrayReplacer(key2, value[key2], stack, replacer, spacer, indentation);
|
|
54983
54983
|
if (tmp !== void 0) {
|
|
54984
54984
|
res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
|
|
54985
|
-
separator =
|
|
54985
|
+
separator = join21;
|
|
54986
54986
|
}
|
|
54987
54987
|
}
|
|
54988
54988
|
if (spacer !== "" && separator.length > 1) {
|
|
@@ -55040,20 +55040,20 @@ ${originalIndentation}`;
|
|
|
55040
55040
|
indentation += spacer;
|
|
55041
55041
|
let res2 = `
|
|
55042
55042
|
${indentation}`;
|
|
55043
|
-
const
|
|
55043
|
+
const join22 = `,
|
|
55044
55044
|
${indentation}`;
|
|
55045
55045
|
const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
|
|
55046
55046
|
let i155 = 0;
|
|
55047
55047
|
for (; i155 < maximumValuesToStringify - 1; i155++) {
|
|
55048
55048
|
const tmp2 = stringifyIndent(String(i155), value[i155], stack, spacer, indentation);
|
|
55049
55049
|
res2 += tmp2 !== void 0 ? tmp2 : "null";
|
|
55050
|
-
res2 +=
|
|
55050
|
+
res2 += join22;
|
|
55051
55051
|
}
|
|
55052
55052
|
const tmp = stringifyIndent(String(i155), value[i155], stack, spacer, indentation);
|
|
55053
55053
|
res2 += tmp !== void 0 ? tmp : "null";
|
|
55054
55054
|
if (value.length - 1 > maximumBreadth) {
|
|
55055
55055
|
const removedKeys = value.length - maximumBreadth - 1;
|
|
55056
|
-
res2 += `${
|
|
55056
|
+
res2 += `${join22}"... ${getItemCount(removedKeys)} not stringified"`;
|
|
55057
55057
|
}
|
|
55058
55058
|
res2 += `
|
|
55059
55059
|
${originalIndentation}`;
|
|
@@ -55069,16 +55069,16 @@ ${originalIndentation}`;
|
|
|
55069
55069
|
return '"[Object]"';
|
|
55070
55070
|
}
|
|
55071
55071
|
indentation += spacer;
|
|
55072
|
-
const
|
|
55072
|
+
const join21 = `,
|
|
55073
55073
|
${indentation}`;
|
|
55074
55074
|
let res = "";
|
|
55075
55075
|
let separator = "";
|
|
55076
55076
|
let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
|
|
55077
55077
|
if (isTypedArrayWithEntries(value)) {
|
|
55078
|
-
res += stringifyTypedArray(value,
|
|
55078
|
+
res += stringifyTypedArray(value, join21, maximumBreadth);
|
|
55079
55079
|
keys = keys.slice(value.length);
|
|
55080
55080
|
maximumPropertiesToStringify -= value.length;
|
|
55081
|
-
separator =
|
|
55081
|
+
separator = join21;
|
|
55082
55082
|
}
|
|
55083
55083
|
if (deterministic) {
|
|
55084
55084
|
keys = sort(keys, comparator);
|
|
@@ -55089,13 +55089,13 @@ ${indentation}`;
|
|
|
55089
55089
|
const tmp = stringifyIndent(key2, value[key2], stack, spacer, indentation);
|
|
55090
55090
|
if (tmp !== void 0) {
|
|
55091
55091
|
res += `${separator}${strEscape(key2)}: ${tmp}`;
|
|
55092
|
-
separator =
|
|
55092
|
+
separator = join21;
|
|
55093
55093
|
}
|
|
55094
55094
|
}
|
|
55095
55095
|
if (keyLength > maximumBreadth) {
|
|
55096
55096
|
const removedKeys = keyLength - maximumBreadth;
|
|
55097
55097
|
res += `${separator}"...": "${getItemCount(removedKeys)} not stringified"`;
|
|
55098
|
-
separator =
|
|
55098
|
+
separator = join21;
|
|
55099
55099
|
}
|
|
55100
55100
|
if (separator !== "") {
|
|
55101
55101
|
res = `
|
|
@@ -56838,15 +56838,15 @@ var require_reply = __commonJS({
|
|
|
56838
56838
|
notFound(this);
|
|
56839
56839
|
return this;
|
|
56840
56840
|
};
|
|
56841
|
-
Reply.prototype.then = function(fulfilled,
|
|
56841
|
+
Reply.prototype.then = function(fulfilled, rejected6) {
|
|
56842
56842
|
if (this.sent) {
|
|
56843
56843
|
fulfilled();
|
|
56844
56844
|
return;
|
|
56845
56845
|
}
|
|
56846
56846
|
eos(this.raw, (err) => {
|
|
56847
56847
|
if (err && err.code !== "ERR_STREAM_PREMATURE_CLOSE") {
|
|
56848
|
-
if (
|
|
56849
|
-
|
|
56848
|
+
if (rejected6) {
|
|
56849
|
+
rejected6(err);
|
|
56850
56850
|
} else {
|
|
56851
56851
|
this.log && this.log.warn("unhandled rejection on reply.then");
|
|
56852
56852
|
}
|
|
@@ -62041,51 +62041,51 @@ var require_fast_uri2 = __commonJS({
|
|
|
62041
62041
|
target.ipv6Zone = source.ipv6Zone;
|
|
62042
62042
|
}
|
|
62043
62043
|
}
|
|
62044
|
-
function resolveComponent(base,
|
|
62044
|
+
function resolveComponent(base, relative3, options, skipNormalization) {
|
|
62045
62045
|
const target = {};
|
|
62046
62046
|
if (!skipNormalization) {
|
|
62047
62047
|
base = parse8(serialize(base, options), options);
|
|
62048
|
-
|
|
62048
|
+
relative3 = parse8(serialize(relative3, options), options);
|
|
62049
62049
|
}
|
|
62050
62050
|
options = options || {};
|
|
62051
|
-
if (!options.tolerant &&
|
|
62052
|
-
target.scheme =
|
|
62053
|
-
target.userinfo =
|
|
62054
|
-
copyHost(target,
|
|
62055
|
-
target.port =
|
|
62056
|
-
const relativeSchemeHandler = getSchemeHandler(
|
|
62057
|
-
target.path = relativeSchemeHandler && relativeSchemeHandler.absolutePath ?
|
|
62058
|
-
target.query =
|
|
62051
|
+
if (!options.tolerant && relative3.scheme) {
|
|
62052
|
+
target.scheme = relative3.scheme;
|
|
62053
|
+
target.userinfo = relative3.userinfo;
|
|
62054
|
+
copyHost(target, relative3);
|
|
62055
|
+
target.port = relative3.port;
|
|
62056
|
+
const relativeSchemeHandler = getSchemeHandler(relative3.scheme);
|
|
62057
|
+
target.path = relativeSchemeHandler && relativeSchemeHandler.absolutePath ? relative3.path || "" : removeDotSegments(relative3.path || "");
|
|
62058
|
+
target.query = relative3.query;
|
|
62059
62059
|
} else {
|
|
62060
|
-
if (
|
|
62061
|
-
target.userinfo =
|
|
62062
|
-
copyHost(target,
|
|
62063
|
-
target.port =
|
|
62064
|
-
target.path = removeDotSegments(
|
|
62065
|
-
target.query =
|
|
62060
|
+
if (relative3.userinfo !== void 0 || relative3.host !== void 0 || relative3.port !== void 0) {
|
|
62061
|
+
target.userinfo = relative3.userinfo;
|
|
62062
|
+
copyHost(target, relative3);
|
|
62063
|
+
target.port = relative3.port;
|
|
62064
|
+
target.path = removeDotSegments(relative3.path || "");
|
|
62065
|
+
target.query = relative3.query;
|
|
62066
62066
|
} else {
|
|
62067
|
-
if (!
|
|
62067
|
+
if (!relative3.path) {
|
|
62068
62068
|
target.path = base.path;
|
|
62069
|
-
if (
|
|
62070
|
-
target.query =
|
|
62069
|
+
if (relative3.query !== void 0) {
|
|
62070
|
+
target.query = relative3.query;
|
|
62071
62071
|
} else {
|
|
62072
62072
|
target.query = base.query;
|
|
62073
62073
|
}
|
|
62074
62074
|
} else {
|
|
62075
|
-
if (
|
|
62076
|
-
target.path = removeDotSegments(
|
|
62075
|
+
if (relative3.path[0] === "/") {
|
|
62076
|
+
target.path = removeDotSegments(relative3.path);
|
|
62077
62077
|
} else {
|
|
62078
62078
|
const baseHasAuthority = base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0;
|
|
62079
62079
|
if (baseHasAuthority && !base.path) {
|
|
62080
|
-
target.path = "/" +
|
|
62080
|
+
target.path = "/" + relative3.path;
|
|
62081
62081
|
} else if (!base.path) {
|
|
62082
|
-
target.path =
|
|
62082
|
+
target.path = relative3.path;
|
|
62083
62083
|
} else {
|
|
62084
|
-
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) +
|
|
62084
|
+
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative3.path;
|
|
62085
62085
|
}
|
|
62086
62086
|
target.path = base.scheme === void 0 && !baseHasAuthority && target.path[0] !== "/" ? removeDotSegmentsRelative(target.path) : removeDotSegments(target.path);
|
|
62087
62087
|
}
|
|
62088
|
-
target.query =
|
|
62088
|
+
target.query = relative3.query;
|
|
62089
62089
|
}
|
|
62090
62090
|
target.userinfo = base.userinfo;
|
|
62091
62091
|
copyHost(target, base);
|
|
@@ -62093,7 +62093,7 @@ var require_fast_uri2 = __commonJS({
|
|
|
62093
62093
|
}
|
|
62094
62094
|
target.scheme = base.scheme;
|
|
62095
62095
|
}
|
|
62096
|
-
target.fragment =
|
|
62096
|
+
target.fragment = relative3.fragment;
|
|
62097
62097
|
return target;
|
|
62098
62098
|
}
|
|
62099
62099
|
function equal(uriA, uriB, options) {
|
|
@@ -65559,14 +65559,14 @@ ${contextFunctionCode}`,
|
|
|
65559
65559
|
let code3 = "";
|
|
65560
65560
|
for (let index = 0, oneOfsLength = oneOfs.length; index < oneOfsLength; index++) {
|
|
65561
65561
|
const optionLocation = oneOfsLocation.getPropertyLocation(index);
|
|
65562
|
-
const
|
|
65563
|
-
let mergedSchemaId = context.mergedSchemasIds.get(
|
|
65562
|
+
const optionSchema2 = optionLocation.schema;
|
|
65563
|
+
let mergedSchemaId = context.mergedSchemasIds.get(optionSchema2);
|
|
65564
65564
|
let mergedLocation = null;
|
|
65565
65565
|
if (mergedSchemaId) {
|
|
65566
65566
|
mergedLocation = getMergedLocation(context, mergedSchemaId);
|
|
65567
65567
|
} else {
|
|
65568
65568
|
mergedSchemaId = `__fjs_merged_${schemaIdCounter++}`;
|
|
65569
|
-
context.mergedSchemasIds.set(
|
|
65569
|
+
context.mergedSchemasIds.set(optionSchema2, mergedSchemaId);
|
|
65570
65570
|
mergedLocation = mergeLocations(context, mergedSchemaId, [
|
|
65571
65571
|
locationWithoutOneOf,
|
|
65572
65572
|
optionLocation
|
|
@@ -80247,7 +80247,7 @@ var require_send = __commonJS({
|
|
|
80247
80247
|
var { parseTokenList } = require_parseTokenList();
|
|
80248
80248
|
var { createHttpError } = require_createHttpError();
|
|
80249
80249
|
var extname = path11.extname;
|
|
80250
|
-
var
|
|
80250
|
+
var join21 = path11.join;
|
|
80251
80251
|
var normalize5 = path11.normalize;
|
|
80252
80252
|
var resolve3 = path11.resolve;
|
|
80253
80253
|
var sep3 = path11.sep;
|
|
@@ -80334,7 +80334,7 @@ var require_send = __commonJS({
|
|
|
80334
80334
|
return { statusCode: 403 };
|
|
80335
80335
|
}
|
|
80336
80336
|
parts = path12.split(sep3);
|
|
80337
|
-
path12 = normalize5(
|
|
80337
|
+
path12 = normalize5(join21(root, path12));
|
|
80338
80338
|
} else {
|
|
80339
80339
|
if (UP_PATH_REGEXP.test(path12)) {
|
|
80340
80340
|
debug('malicious path "%s"', path12);
|
|
@@ -80617,7 +80617,7 @@ var require_send = __commonJS({
|
|
|
80617
80617
|
let err;
|
|
80618
80618
|
for (let i155 = 0; i155 < options.index.length; i155++) {
|
|
80619
80619
|
const index = options.index[i155];
|
|
80620
|
-
const p15 =
|
|
80620
|
+
const p15 = join21(path12, index);
|
|
80621
80621
|
const { error: error61, stat: stat2 } = await tryStat(p15);
|
|
80622
80622
|
if (error61) {
|
|
80623
80623
|
err = error61;
|
|
@@ -82081,9 +82081,9 @@ var require_static = __commonJS({
|
|
|
82081
82081
|
});
|
|
82082
82082
|
|
|
82083
82083
|
// apps/backend/src/main.ts
|
|
82084
|
-
var
|
|
82084
|
+
var import_promises11 = require("node:fs/promises");
|
|
82085
82085
|
var import_node_os = require("node:os");
|
|
82086
|
-
var
|
|
82086
|
+
var import_node_path23 = require("node:path");
|
|
82087
82087
|
|
|
82088
82088
|
// node_modules/.pnpm/zod@4.5.4/node_modules/zod/v4/classic/external.js
|
|
82089
82089
|
var external_exports = {};
|
|
@@ -112635,23 +112635,15 @@ var appendEvents = (conversation, events) => {
|
|
|
112635
112635
|
return { conversation: { ...conversation, journal: [...conversation.journal, ...entries] }, entries };
|
|
112636
112636
|
};
|
|
112637
112637
|
var isInbound = (event) => event.kind === "reviewer-message" || event.kind === "answers" && event.origin === "agent";
|
|
112638
|
-
var isOutbound = (event) => event.kind === "agent-message" || event.kind === "question-batch" && event.origin === "agent";
|
|
112639
112638
|
var lastDeliveredSequenceOf = (journal) => journal.reduce(
|
|
112640
112639
|
(highest, { event }) => event.kind === "delivery" ? Math.max(highest, event.throughSequence) : highest,
|
|
112641
112640
|
NO_SEQUENCE
|
|
112642
112641
|
);
|
|
112643
112642
|
var inboundAfter = (journal, sequence) => journal.filter((entry) => entry.sequence > sequence && isInbound(entry.event));
|
|
112644
|
-
var pendingInboundOf = (journal) => inboundAfter(journal, lastDeliveredSequenceOf(journal));
|
|
112645
|
-
var hasOutboundAfter = (journal, sequence) => journal.some((entry) => entry.sequence > sequence && isOutbound(entry.event));
|
|
112646
112643
|
var findQuestionBatch = (journal, batchId) => journal.map(({ event }) => event).find((event) => event.kind === "question-batch" && event.id === batchId) ?? null;
|
|
112647
112644
|
var findAnswerSet = (journal, batchId) => journal.map(({ event }) => event).find((event) => event.kind === "answers" && event.batchId === batchId) ?? null;
|
|
112648
112645
|
var findWithdrawal = (journal, batchId) => journal.map(({ event }) => event).find((event) => event.kind === "questions-withdrawn" && event.batchId === batchId) ?? null;
|
|
112649
112646
|
var isBatchSettled = (journal, batchId) => findAnswerSet(journal, batchId) !== null || findWithdrawal(journal, batchId) !== null;
|
|
112650
|
-
var openQuestionBatchesOf = (journal) => journal.map(({ event }) => event).filter((event) => event.kind === "question-batch").filter((batch) => !isBatchSettled(journal, batch.id));
|
|
112651
|
-
var latestFailureOf = (journal) => journal.reduce((latest, { event }) => {
|
|
112652
|
-
if (event.kind === "agent-failure") return event;
|
|
112653
|
-
return event.kind === "delivery" ? null : latest;
|
|
112654
|
-
}, null);
|
|
112655
112647
|
var latestModelChoiceOf = (journal, agent) => journal.map(({ event }) => event).filter((event) => event.kind === "model-choice" && event.agent === agent).at(-1) ?? null;
|
|
112656
112648
|
var messageBodiesOf = (journal) => journal.flatMap(({ event }) => event.kind === "reviewer-message" || event.kind === "agent-message" ? [event.body] : []);
|
|
112657
112649
|
var reviewKeyId = (key) => `${key.repositoryName}
|
|
@@ -112663,6 +112655,7 @@ var NO_ANSWER = "(no answer)";
|
|
|
112663
112655
|
var LISTEN_PATH_SUFFIX = "live/agent";
|
|
112664
112656
|
var listenPathOf = (key) => `/api/${encodeURIComponent(key.repositoryName)}/${encodeURIComponent(key.targetId)}/${LISTEN_PATH_SUFFIX}`;
|
|
112665
112657
|
var listenCommandOf = (serverUrl, key) => `curl -sN "${serverUrl}${listenPathOf(key)}"`;
|
|
112658
|
+
var listenPermissionRuleOf = (serverUrl) => `Bash(curl -sN "${serverUrl}/api/*)`;
|
|
112666
112659
|
var formatReviewerMessage = (message) => message.reference === null ? `The reviewer wrote:
|
|
112667
112660
|
${message.body}` : `The reviewer wrote about ${message.reference}:
|
|
112668
112661
|
${message.body}`;
|
|
@@ -112685,43 +112678,54 @@ var formatInboundEntry = (entry, journal) => {
|
|
|
112685
112678
|
return null;
|
|
112686
112679
|
};
|
|
112687
112680
|
var formatInbound = (entries, journal) => entries.map((entry) => formatInboundEntry(entry, journal)).filter((text2) => text2 !== null).join(PARAGRAPH_BREAK);
|
|
112688
|
-
var
|
|
112689
|
-
${
|
|
112690
|
-
|
|
112691
|
-
|
|
112692
|
-
var
|
|
112693
|
-
var
|
|
112694
|
-
|
|
112695
|
-
|
|
112696
|
-
|
|
112697
|
-
|
|
112698
|
-
|
|
112699
|
-
|
|
112700
|
-
"Flight Plan's tools can take a few seconds to connect after this session starts or resumes, and may look unavailable or removed at first. If they do, end your turn: Flight Plan tells you when to use them.",
|
|
112701
|
-
"Never run the curl listen command that the tool descriptions mention. It is for sessions the reviewer started themselves."
|
|
112702
|
-
].join("\n");
|
|
112681
|
+
var LIVE_SKILL_COMMAND = "/flightplan:live";
|
|
112682
|
+
var liveCommandOf = (key) => `${LIVE_SKILL_COMMAND} ${key.repositoryName}/${key.targetId}`;
|
|
112683
|
+
var listenAgainOf = (nextListenCommand) => `When you have done everything above, listen again with this command, in the foreground:
|
|
112684
|
+
${nextListenCommand}`;
|
|
112685
|
+
var formatListenPacket = (text2, nextListenCommand) => [text2, listenAgainOf(nextListenCommand)].join(PARAGRAPH_BREAK);
|
|
112686
|
+
var formatIdlePacket = (nextListenCommand) => [
|
|
112687
|
+
"Nothing new from the reviewer yet.",
|
|
112688
|
+
`Listen again with this command, in the foreground:
|
|
112689
|
+
${nextListenCommand}`
|
|
112690
|
+
].join(PARAGRAPH_BREAK);
|
|
112691
|
+
var listenInstructionOf = (command) => `The reviewer's reply comes on your listening stream. If you are not listening yet, run this in the foreground. It exits when the reviewer replies, and its output holds the reply:
|
|
112692
|
+
${command}`;
|
|
112703
112693
|
var MCP_INSTRUCTIONS = [
|
|
112704
112694
|
"Flight Plan connects you with the reviewer of a pull request, who reads you in Flight Plan's web app.",
|
|
112705
112695
|
"A review target is named by repositoryName (the repository's name in Flight Plan) and targetId (pr-<number> for a pull request, branch-<name> for a branch).",
|
|
112706
|
-
"A review artifact is filled in through get-instructions, read, nodes, update-nodes and complete. Flight Plan builds its structure when the reviewer
|
|
112696
|
+
"A review artifact is filled in through get-instructions, read, nodes, update-nodes and complete. Flight Plan builds its structure when the reviewer opens the review, and these tools write the prose onto it. get-instructions says how to write each field, for the configuration the reviewer chose.",
|
|
112707
112697
|
"send-message sends the reviewer a message. ask-questions asks one question or a batch; each question either offers options (one or several picks, and the reviewer can always write their own answer) or asks for free text.",
|
|
112708
112698
|
"record-publication records the address of the Claude artifact a Flight Plan was published to. Call it only after Flight Plan asked you to publish one and your Artifact tool did.",
|
|
112709
112699
|
"record-import stores a Flight Plan you fetched from a Claude artifact. Call it only after Flight Plan asked you to fetch one and you copied the file where it said.",
|
|
112710
|
-
"
|
|
112711
|
-
"
|
|
112700
|
+
"Flight Plan shows the reviewer whether an agent is online for their review. Every call to these tools counts, and ping counts when you have nothing else to call. While you work on a review without calling Flight Plan, call ping at least every 5 seconds.",
|
|
112701
|
+
"Requests from the reviewer arrive on the review's listening stream: a curl command the tool results give you. It waits until there is something to do, prints it with the command to listen again, and exits."
|
|
112712
112702
|
].join("\n");
|
|
112713
|
-
var REPLY_REMINDER = [
|
|
112714
|
-
"You have not written to the reviewer this turn, and the reviewer reads only what you send through Flight Plan.",
|
|
112715
|
-
"If send-message or ask-questions looked unavailable, they were still connecting and are available now.",
|
|
112716
|
-
"Send your reply with send-message, or ask with ask-questions."
|
|
112717
|
-
].join(" ");
|
|
112718
112703
|
|
|
112719
|
-
// apps/backend/src/procedures/get-conversation/utils/agent-
|
|
112720
|
-
var
|
|
112721
|
-
var
|
|
112722
|
-
|
|
112723
|
-
var
|
|
112724
|
-
|
|
112704
|
+
// apps/backend/src/procedures/get-conversation/utils/agent-presence.ts
|
|
112705
|
+
var ONLINE_WINDOW_MS = 15e3;
|
|
112706
|
+
var NO_PRESENCE = { openStreamCount: 0, lastSeenAt: null, claimedThroughSequence: 0 };
|
|
112707
|
+
var isAgentOnline = (presence, now) => presence.openStreamCount > 0 || presence.lastSeenAt !== null && now.getTime() - presence.lastSeenAt.getTime() <= ONLINE_WINDOW_MS;
|
|
112708
|
+
var InMemoryAgentPresenceRegistry = class {
|
|
112709
|
+
presences = /* @__PURE__ */ new Map();
|
|
112710
|
+
presenceOf = (key) => this.presences.get(reviewKeyId(key)) ?? NO_PRESENCE;
|
|
112711
|
+
openStream = (key) => {
|
|
112712
|
+
this.change(key, (presence) => ({ ...presence, openStreamCount: presence.openStreamCount + 1 }));
|
|
112713
|
+
};
|
|
112714
|
+
closeStream = (key, closedAt) => {
|
|
112715
|
+
this.change(key, (presence) => ({ ...presence, openStreamCount: Math.max(presence.openStreamCount - 1, 0), lastSeenAt: closedAt }));
|
|
112716
|
+
};
|
|
112717
|
+
markSeen = (key, seenAt) => {
|
|
112718
|
+
this.change(key, (presence) => ({ ...presence, lastSeenAt: seenAt }));
|
|
112719
|
+
};
|
|
112720
|
+
claimThrough = (key, sequence) => {
|
|
112721
|
+
if (this.presenceOf(key).claimedThroughSequence >= sequence) return false;
|
|
112722
|
+
this.change(key, (presence) => ({ ...presence, claimedThroughSequence: sequence }));
|
|
112723
|
+
return true;
|
|
112724
|
+
};
|
|
112725
|
+
change = (key, update) => {
|
|
112726
|
+
this.presences = new Map([...this.presences, [reviewKeyId(key), update(this.presenceOf(key))]]);
|
|
112727
|
+
};
|
|
112728
|
+
};
|
|
112725
112729
|
|
|
112726
112730
|
// apps/backend/src/procedures/get-conversation/utils/review-target.ts
|
|
112727
112731
|
var TARGET_ID_PATTERN = /^(?:pr-[1-9]\d*|branch-.+)$/;
|
|
@@ -112748,29 +112752,11 @@ var appendAndPublish = async (key, events, context) => {
|
|
|
112748
112752
|
return entries;
|
|
112749
112753
|
};
|
|
112750
112754
|
var findReviewTarget = async (key, context) => lookUpReviewTarget(key, await context.repositoryStore.listRegistered());
|
|
112751
|
-
var
|
|
112752
|
-
|
|
112753
|
-
|
|
112754
|
-
|
|
112755
|
-
|
|
112756
|
-
await appendAndPublish(
|
|
112757
|
-
key,
|
|
112758
|
-
[{ kind: "agent-failure", id: context.conversationEnvironment.newId(), reason, failedAt: context.now() }],
|
|
112759
|
-
context
|
|
112760
|
-
);
|
|
112761
|
-
};
|
|
112762
|
-
var confirmAgentStart = async (sessionId, context) => {
|
|
112763
|
-
const { agents, store, hub } = context.conversationEnvironment;
|
|
112764
|
-
const agent = agents.findBySessionId(sessionId);
|
|
112765
|
-
if (agent === null) return null;
|
|
112766
|
-
const now = context.now();
|
|
112767
|
-
const confirmed = agents.update(agent.key, (current) => ({ ...current, phase: "running", lastActivityAt: now }));
|
|
112768
|
-
if (agent.phase === "starting") {
|
|
112769
|
-
const conversation = await store.read(agent.key);
|
|
112770
|
-
if (conversation.sessionId !== sessionId) await store.saveSessionId(agent.key, sessionId);
|
|
112771
|
-
hub.publish(agent.key);
|
|
112772
|
-
}
|
|
112773
|
-
return confirmed;
|
|
112755
|
+
var isAgentOnlineFor = (key, context) => isAgentOnline(context.conversationEnvironment.presence.presenceOf(key), context.now());
|
|
112756
|
+
var markAgentSeen = (key, context) => {
|
|
112757
|
+
const wasOnline = isAgentOnlineFor(key, context);
|
|
112758
|
+
context.conversationEnvironment.presence.markSeen(key, context.now());
|
|
112759
|
+
if (!wasOnline) context.conversationEnvironment.hub.publish(key);
|
|
112774
112760
|
};
|
|
112775
112761
|
|
|
112776
112762
|
// apps/backend/src/procedures/ask-reviewer/utils/plan-question-batch.ts
|
|
@@ -112797,14 +112783,13 @@ var askReviewer = async (input2, context) => {
|
|
|
112797
112783
|
const batchId = context.conversationEnvironment.newId();
|
|
112798
112784
|
const plan4 = planQuestionBatch(batchId, input2.questions);
|
|
112799
112785
|
if (plan4.kind === "rejected") return plan4;
|
|
112800
|
-
|
|
112786
|
+
markAgentSeen(key, context);
|
|
112801
112787
|
await appendAndPublish(
|
|
112802
112788
|
key,
|
|
112803
112789
|
[{ kind: "question-batch", id: batchId, origin: "agent", questions: plan4.questions, askedAt: context.now() }],
|
|
112804
112790
|
context
|
|
112805
112791
|
);
|
|
112806
|
-
|
|
112807
|
-
const command = listenCommandFor(key, context);
|
|
112792
|
+
const command = listenCommandOf(context.conversationEnvironment.serverUrl, key);
|
|
112808
112793
|
return { kind: "asked", batchId, note: askedNote(batchId, listenInstructionOf(command)) };
|
|
112809
112794
|
};
|
|
112810
112795
|
|
|
@@ -136363,19 +136348,19 @@ var ancestorsOf3 = (at) => {
|
|
|
136363
136348
|
return above === "." ? [] : [above, ...ancestorsOf3(above)];
|
|
136364
136349
|
};
|
|
136365
136350
|
var isResolverFileSystem = (fileSystem) => ["stat", "lstat", "readFile", "readJson", "readdir", "readlink"].every((method) => method in fileSystem);
|
|
136366
|
-
var inPackageFolder = (
|
|
136367
|
-
function installedPathOf(
|
|
136368
|
-
const inside = inPackageFolder(
|
|
136351
|
+
var inPackageFolder = (relative3) => relative3.startsWith(`${PACKAGE_FOLDER}/`) ? relative3.slice(PACKAGE_FOLDER.length + 1) : null;
|
|
136352
|
+
function installedPathOf(relative3, packages) {
|
|
136353
|
+
const inside = inPackageFolder(relative3);
|
|
136369
136354
|
const name = inside === null ? void 0 : [...packages.keys()].find((one) => inside === one || inside.startsWith(`${one}/`));
|
|
136370
136355
|
const directory = name === void 0 ? void 0 : packages.get(name);
|
|
136371
136356
|
if (inside === null || name === void 0 || directory === void 0) return null;
|
|
136372
136357
|
const found2 = path7.posix.join(directory, inside.slice(name.length));
|
|
136373
136358
|
return found2 === CURRENT_FOLDER ? "" : found2;
|
|
136374
136359
|
}
|
|
136375
|
-
function installedNamesIn(
|
|
136360
|
+
function installedNamesIn(relative3, packages) {
|
|
136376
136361
|
const names = [...packages.keys()];
|
|
136377
|
-
if (
|
|
136378
|
-
const scope = inPackageFolder(
|
|
136362
|
+
if (relative3 === PACKAGE_FOLDER) return [...new Set(names.map((name) => name.split("/")[0]))];
|
|
136363
|
+
const scope = inPackageFolder(relative3);
|
|
136379
136364
|
if (scope === null || !scope.startsWith(SCOPE_PREFIX) || scope.includes("/")) return null;
|
|
136380
136365
|
const scoped = names.filter((name) => name.startsWith(`${scope}/`)).map((name) => name.slice(scope.length + 1));
|
|
136381
136366
|
return scoped.length === 0 ? null : scoped;
|
|
@@ -136384,29 +136369,29 @@ function repoFileSystem(files, read2, packages) {
|
|
|
136384
136369
|
const directories = /* @__PURE__ */ new Set(["", ...[...files].flatMap(ancestorsOf3)]);
|
|
136385
136370
|
const inRepo = (at) => path7.posix.relative(ROOT, at);
|
|
136386
136371
|
const realPathOf = async (at) => {
|
|
136387
|
-
const
|
|
136388
|
-
return installedPathOf(
|
|
136372
|
+
const relative3 = inRepo(at);
|
|
136373
|
+
return installedPathOf(relative3, await packages) ?? relative3;
|
|
136389
136374
|
};
|
|
136390
136375
|
const installedNamesAt = async (at) => installedNamesIn(inRepo(at), await packages);
|
|
136391
136376
|
const stats = (isFile) => ({ isFile: () => isFile, isDirectory: () => !isFile, isSymbolicLink: () => false });
|
|
136392
136377
|
const buffers = new Memo();
|
|
136393
|
-
const textOf7 = async (
|
|
136394
|
-
if (!TSCONFIG.test(
|
|
136395
|
-
const [value, found2] = await Promise.all([read2(
|
|
136396
|
-
return value === null ? null : rootedPaths(value,
|
|
136378
|
+
const textOf7 = async (relative3) => {
|
|
136379
|
+
if (!TSCONFIG.test(relative3)) return read2(relative3);
|
|
136380
|
+
const [value, found2] = await Promise.all([read2(relative3), packages]);
|
|
136381
|
+
return value === null ? null : rootedPaths(value, relative3, (entry) => extendedConfig(entry, relative3, files, found2));
|
|
136397
136382
|
};
|
|
136398
|
-
const bufferOf = async (
|
|
136383
|
+
const bufferOf = async (relative3) => buffers.remember(relative3, async () => textOf7(relative3).then((value) => value === null ? null : Buffer.from(value)));
|
|
136399
136384
|
const manifests = new Memo();
|
|
136400
|
-
const manifestOf = async (
|
|
136401
|
-
|
|
136402
|
-
async () => bufferOf(
|
|
136385
|
+
const manifestOf = async (relative3) => manifests.remember(
|
|
136386
|
+
relative3,
|
|
136387
|
+
async () => bufferOf(relative3).then((value) => value === null ? null : JSON.parse(value.toString("utf8")))
|
|
136403
136388
|
);
|
|
136404
136389
|
const stat2 = (at, ...args) => {
|
|
136405
136390
|
const done = callbackOf(args);
|
|
136406
|
-
Promise.all([realPathOf(at), installedNamesAt(at)]).then(([
|
|
136391
|
+
Promise.all([realPathOf(at), installedNamesAt(at)]).then(([relative3, installed]) => {
|
|
136407
136392
|
if (installed !== null) done(null, stats(false));
|
|
136408
|
-
else if (files.has(
|
|
136409
|
-
else if (directories.has(
|
|
136393
|
+
else if (files.has(relative3)) done(null, stats(true));
|
|
136394
|
+
else if (directories.has(relative3)) done(null, stats(false));
|
|
136410
136395
|
else done(missing(at));
|
|
136411
136396
|
}, failWith(done));
|
|
136412
136397
|
};
|
|
@@ -136415,29 +136400,29 @@ function repoFileSystem(files, read2, packages) {
|
|
|
136415
136400
|
lstat: stat2,
|
|
136416
136401
|
readFile: (at, ...args) => {
|
|
136417
136402
|
const done = callbackOf(args);
|
|
136418
|
-
realPathOf(at).then(async (
|
|
136403
|
+
realPathOf(at).then(async (relative3) => files.has(relative3) ? await bufferOf(relative3) : null).then((value) => {
|
|
136419
136404
|
deliver(done, at, value);
|
|
136420
136405
|
}, failWith(done));
|
|
136421
136406
|
},
|
|
136422
136407
|
readJson: (at, ...args) => {
|
|
136423
136408
|
const done = callbackOf(args);
|
|
136424
|
-
realPathOf(at).then(async (
|
|
136409
|
+
realPathOf(at).then(async (relative3) => files.has(relative3) ? await manifestOf(relative3) : null).then((value) => {
|
|
136425
136410
|
deliver(done, at, value);
|
|
136426
136411
|
}, failWith(done));
|
|
136427
136412
|
},
|
|
136428
136413
|
readdir: (at, ...args) => {
|
|
136429
136414
|
const done = callbackOf(args);
|
|
136430
|
-
Promise.all([realPathOf(at), installedNamesAt(at)]).then(([
|
|
136415
|
+
Promise.all([realPathOf(at), installedNamesAt(at)]).then(([relative3, installed]) => {
|
|
136431
136416
|
if (installed !== null) {
|
|
136432
136417
|
done(null, installed);
|
|
136433
136418
|
return;
|
|
136434
136419
|
}
|
|
136435
|
-
if (!directories.has(
|
|
136420
|
+
if (!directories.has(relative3)) {
|
|
136436
136421
|
done(missing(at));
|
|
136437
136422
|
return;
|
|
136438
136423
|
}
|
|
136439
|
-
const prefix =
|
|
136440
|
-
const names = [...files, ...directories].filter((one) => one !==
|
|
136424
|
+
const prefix = relative3 === "" ? "" : `${relative3}/`;
|
|
136425
|
+
const names = [...files, ...directories].filter((one) => one !== relative3 && one.startsWith(prefix)).map((one) => one.slice(prefix.length)).filter((rest) => !rest.includes("/"));
|
|
136441
136426
|
done(null, [...new Set(names)]);
|
|
136442
136427
|
}, failWith(done));
|
|
136443
136428
|
},
|
|
@@ -136552,8 +136537,8 @@ function moduleResolver(files, read2) {
|
|
|
136552
136537
|
return nearest === null ? null : await findCoveringConfig(nearest, file2, configReader, files, /* @__PURE__ */ new Set()) ?? nearest;
|
|
136553
136538
|
});
|
|
136554
136539
|
const repoPathOf = async (found2) => {
|
|
136555
|
-
const
|
|
136556
|
-
return installedPathOf(
|
|
136540
|
+
const relative3 = path7.posix.relative(ROOT, found2);
|
|
136541
|
+
return installedPathOf(relative3, await packages) ?? relative3;
|
|
136557
136542
|
};
|
|
136558
136543
|
const resolverFor = async (config3) => resolvers.remember(
|
|
136559
136544
|
config3 ?? "",
|
|
@@ -137335,8 +137320,8 @@ var evaluationFoldersOf = (library, manifests) => {
|
|
|
137335
137320
|
var keyPathOf2 = (file2, key) => file2.under === void 0 ? key : `${file2.under}${KEY_SEPARATOR4}${key}`;
|
|
137336
137321
|
var findConfigs = (setting, folder, readerByPath) => [...readerByPath].flatMap(([filePath, reader]) => {
|
|
137337
137322
|
if (!isWithin(folder, filePath)) return [];
|
|
137338
|
-
const
|
|
137339
|
-
const file2 = setting.files.find((candidate) => fitsGlob(candidate.glob,
|
|
137323
|
+
const relative3 = relativeTo(folder, filePath);
|
|
137324
|
+
const file2 = setting.files.find((candidate) => fitsGlob(candidate.glob, relative3) && (candidate.under === void 0 || reader.holdsSection(candidate.under)));
|
|
137340
137325
|
return file2 === void 0 ? [] : [{ filePath, file: file2, reader }];
|
|
137341
137326
|
});
|
|
137342
137327
|
var baseOf = ({ filePath, file: file2 }, folder) => file2.base === "package" ? folder : levelsAbove(folderOf(filePath), file2.levelsUp ?? 0);
|
|
@@ -147401,7 +147386,7 @@ var missingArtifactRejection = (key) => ({
|
|
|
147401
147386
|
var openArtifact = async (key, context) => {
|
|
147402
147387
|
const target = await findReviewTarget(key, context);
|
|
147403
147388
|
if (target.kind === "rejected") return target;
|
|
147404
|
-
|
|
147389
|
+
markAgentSeen(key, context);
|
|
147405
147390
|
const [artifact, request, savedConfigurations] = await Promise.all([
|
|
147406
147391
|
context.reviewStore.findArtifact(key),
|
|
147407
147392
|
context.reviewStore.findRequest(key),
|
|
@@ -147996,6 +147981,37 @@ var registerNodesTool = (mcpServer, context) => {
|
|
|
147996
147981
|
);
|
|
147997
147982
|
};
|
|
147998
147983
|
|
|
147984
|
+
// apps/backend/src/procedures/record-ping/index.ts
|
|
147985
|
+
var recordedNoteOf = (listenCommand) => `Flight Plan shows the reviewer that you are online. The review's listen command:
|
|
147986
|
+
${listenCommand}`;
|
|
147987
|
+
var recordPing = async (input2, context) => {
|
|
147988
|
+
const key = { repositoryName: input2.repositoryName, targetId: input2.targetId };
|
|
147989
|
+
const target = await findReviewTarget(key, context);
|
|
147990
|
+
if (target.kind === "rejected") return target;
|
|
147991
|
+
markAgentSeen(key, context);
|
|
147992
|
+
return { kind: "recorded", note: recordedNoteOf(listenCommandOf(context.conversationEnvironment.serverUrl, key)) };
|
|
147993
|
+
};
|
|
147994
|
+
|
|
147995
|
+
// apps/backend/src/procedures/record-ping/utils/schemas.ts
|
|
147996
|
+
var recordPingInputShape = {
|
|
147997
|
+
repositoryName: external_exports.string().min(1).describe("The repository's name in Flight Plan."),
|
|
147998
|
+
targetId: external_exports.string().min(1).describe("pr-<number> for a pull request, branch-<name> for a branch.")
|
|
147999
|
+
};
|
|
148000
|
+
var recordPingInputSchema = external_exports.strictObject(recordPingInputShape);
|
|
148001
|
+
|
|
148002
|
+
// apps/backend/src/server/mcp/tools/ping/index.ts
|
|
148003
|
+
var DESCRIPTION5 = "Tell Flight Plan you are still online for a review. Call it at least every 5 seconds while you work without calling Flight Plan's other tools, which count as well.";
|
|
148004
|
+
var registerPingTool = (mcpServer, context) => {
|
|
148005
|
+
mcpServer.registerTool(
|
|
148006
|
+
"ping",
|
|
148007
|
+
{ description: DESCRIPTION5, inputSchema: recordPingInputShape },
|
|
148008
|
+
async (input2) => {
|
|
148009
|
+
const recording = await recordPing(input2, context);
|
|
148010
|
+
return recording.kind === "recorded" ? { content: [{ type: "text", text: recording.note }] } : { content: [{ type: "text", text: recording.message }], isError: true };
|
|
148011
|
+
}
|
|
148012
|
+
);
|
|
148013
|
+
};
|
|
148014
|
+
|
|
147999
148015
|
// apps/backend/src/procedures/read-artifact/index.ts
|
|
148000
148016
|
var DEFAULT_DIFF_FILE_LIMIT = 25;
|
|
148001
148017
|
var readArtifact = async (input2, context) => {
|
|
@@ -148019,7 +148035,7 @@ var readArtifact = async (input2, context) => {
|
|
|
148019
148035
|
};
|
|
148020
148036
|
|
|
148021
148037
|
// apps/backend/src/server/mcp/tools/read/index.ts
|
|
148022
|
-
var
|
|
148038
|
+
var DESCRIPTION6 = [
|
|
148023
148039
|
"Returns one part of a review artifact. Every segment and every changed file comes back with its `segmentId`, which is what a write names.",
|
|
148024
148040
|
"`overview` is the skeleton: ids, titles, the files a code link can name, and what is still unwritten, with no prose. Read it to get oriented.",
|
|
148025
148041
|
"`diff` is the whole change, per file, with the waypoint ids that cover each one. Read the change here, not from git.",
|
|
@@ -148028,7 +148044,7 @@ var DESCRIPTION5 = [
|
|
|
148028
148044
|
var registerReadTool = (mcpServer, context) => {
|
|
148029
148045
|
mcpServer.registerTool(
|
|
148030
148046
|
"read",
|
|
148031
|
-
{ description:
|
|
148047
|
+
{ description: DESCRIPTION6, inputSchema: readArtifactInputShape },
|
|
148032
148048
|
async (input2) => {
|
|
148033
148049
|
const reading = await readArtifact(input2, context);
|
|
148034
148050
|
return reading.kind === "read" ? jsonResult(reading.content) : errorResult(reading.message);
|
|
@@ -149048,6 +149064,7 @@ var completeImport = async (input2, context) => {
|
|
|
149048
149064
|
const key = { repositoryName: input2.repositoryName, targetId: input2.targetId };
|
|
149049
149065
|
const request = await context.reviewStore.readImportRequest(key);
|
|
149050
149066
|
if (request?.importedAt !== null) return rejected(NOT_REQUESTED_MESSAGE);
|
|
149067
|
+
markAgentSeen(key, context);
|
|
149051
149068
|
const path11 = context.importFiles.pathOf(key);
|
|
149052
149069
|
const text2 = await context.importFiles.read(key);
|
|
149053
149070
|
if (text2 === null) return rejected(`There is no file at ${path11} yet. Copy the Flight Plan there, then call record-import again.`);
|
|
@@ -149066,7 +149083,7 @@ var completeImportInputShape = { ...reviewTargetShape };
|
|
|
149066
149083
|
var completeImportInputSchema = external_exports.strictObject(completeImportInputShape);
|
|
149067
149084
|
|
|
149068
149085
|
// apps/backend/src/server/mcp/tools/record-import/index.ts
|
|
149069
|
-
var
|
|
149086
|
+
var DESCRIPTION7 = [
|
|
149070
149087
|
"Stores the Flight Plan you fetched from a Claude artifact as the Flight Plan of a review target.",
|
|
149071
149088
|
"Call it once, after copying the fetched file to the path Flight Plan named when it asked for the import.",
|
|
149072
149089
|
"It takes no path and no content: Flight Plan reads the file from that path."
|
|
@@ -149074,7 +149091,7 @@ var DESCRIPTION6 = [
|
|
|
149074
149091
|
var registerRecordImportTool = (mcpServer, context) => {
|
|
149075
149092
|
mcpServer.registerTool(
|
|
149076
149093
|
"record-import",
|
|
149077
|
-
{ description:
|
|
149094
|
+
{ description: DESCRIPTION7, inputSchema: completeImportInputShape },
|
|
149078
149095
|
async (input2) => {
|
|
149079
149096
|
const completion = await completeImport(input2, context);
|
|
149080
149097
|
return completion.kind === "imported" ? textResult(completion.note) : errorResult(completion.message);
|
|
@@ -149316,9 +149333,9 @@ var listLinkablePullRequests = async (repository, branchName, context) => {
|
|
|
149316
149333
|
// apps/backend/src/procedures/publish-artifact/utils/publishing-progress.ts
|
|
149317
149334
|
var LISTENER_PUBLISHING_WAIT_MS = 6e5;
|
|
149318
149335
|
var wasRecordedSince = (request, publications) => publications.some((publication) => publication.kind === "claude" && publication.publishedAt.getTime() >= request.requestedAt.getTime());
|
|
149319
|
-
var isPublishingUnderway = (request, publications,
|
|
149336
|
+
var isPublishingUnderway = (request, publications, isAgentOnline2, now) => {
|
|
149320
149337
|
if (request === null || wasRecordedSince(request, publications)) return false;
|
|
149321
|
-
return request.channel === "agent" ?
|
|
149338
|
+
return request.channel === "agent" ? isAgentOnline2 : now.getTime() - request.requestedAt.getTime() < LISTENER_PUBLISHING_WAIT_MS;
|
|
149322
149339
|
};
|
|
149323
149340
|
|
|
149324
149341
|
// packages/git-forge/src/git-adapter/base.ts
|
|
@@ -152391,14 +152408,14 @@ function toRelativePath(path11) {
|
|
|
152391
152408
|
return `${url2.pathname}${url2.search}`.replace(/^\/+/, "");
|
|
152392
152409
|
}
|
|
152393
152410
|
function buildRequestPath(path11, query) {
|
|
152394
|
-
const
|
|
152411
|
+
const relative3 = toRelativePath(path11);
|
|
152395
152412
|
const params = new URLSearchParams(
|
|
152396
152413
|
Object.entries(query ?? {}).flatMap(
|
|
152397
152414
|
([key, value]) => typeof value === "string" || typeof value === "number" ? [[key, String(value)]] : []
|
|
152398
152415
|
)
|
|
152399
152416
|
);
|
|
152400
152417
|
const suffix = params.toString();
|
|
152401
|
-
return suffix === "" ?
|
|
152418
|
+
return suffix === "" ? relative3 : `${relative3}${relative3.includes("?") ? "&" : "?"}${suffix}`;
|
|
152402
152419
|
}
|
|
152403
152420
|
function buildBodyArgs(body) {
|
|
152404
152421
|
return Object.entries(body ?? {}).flatMap(([name, value]) => typeof value === "string" ? ["-f", `${name}=${value}`] : []);
|
|
@@ -154472,43 +154489,9 @@ var AGENT_CLI_NAMES = {
|
|
|
154472
154489
|
cursor: "cursor-agent"
|
|
154473
154490
|
};
|
|
154474
154491
|
|
|
154475
|
-
// apps/backend/src/procedures/request-permission/utils/describe-permission.ts
|
|
154476
|
-
var ALLOW_LABEL = "Allow";
|
|
154477
|
-
var DENY_LABEL = "Deny";
|
|
154478
|
-
var MAX_DETAIL_LENGTH = 4e3;
|
|
154479
|
-
var JSON_INDENT2 = 2;
|
|
154480
|
-
var DETAIL_FIELDS = ["command", "file_path", "url", "pattern", "path"];
|
|
154481
|
-
var isRecord4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
154482
|
-
var leadingField = (toolInput) => {
|
|
154483
|
-
if (!isRecord4(toolInput)) return null;
|
|
154484
|
-
const field = DETAIL_FIELDS.map((name) => toolInput[name]).find((value) => typeof value === "string");
|
|
154485
|
-
return typeof field === "string" ? field : null;
|
|
154486
|
-
};
|
|
154487
|
-
var describeToolInput = (toolInput) => {
|
|
154488
|
-
const detail = leadingField(toolInput) ?? JSON.stringify(toolInput ?? null, null, JSON_INDENT2);
|
|
154489
|
-
return detail === "null" || detail === "{}" ? null : detail.slice(0, MAX_DETAIL_LENGTH);
|
|
154490
|
-
};
|
|
154491
|
-
var permissionQuestionOf = (questionId, toolName, toolInput) => ({
|
|
154492
|
-
id: questionId,
|
|
154493
|
-
prompt: `Allow the agent to use ${toolName}?`,
|
|
154494
|
-
detail: describeToolInput(toolInput),
|
|
154495
|
-
options: [
|
|
154496
|
-
{ label: ALLOW_LABEL, description: "Let the agent run it this time." },
|
|
154497
|
-
{ label: DENY_LABEL, description: "Refuse, and tell the agent why if you write an answer." }
|
|
154498
|
-
],
|
|
154499
|
-
allowsMultiple: false
|
|
154500
|
-
});
|
|
154501
|
-
|
|
154502
154492
|
// apps/backend/src/procedures/get-review/utils/build-progress.ts
|
|
154503
|
-
var NO_WRITING_ACTIVITY = { request: null,
|
|
154493
|
+
var NO_WRITING_ACTIVITY = { request: null, isAgentOnline: false, prompt: null };
|
|
154504
154494
|
var PROMPT_LABELS = { label: "Copy the line", copiedMessage: "Line copied" };
|
|
154505
|
-
var CHAT_HINT = "Send it a message in Chat to start it again.";
|
|
154506
|
-
var PERMISSION_LABELS = {
|
|
154507
|
-
description: "The agent is waiting for your answer before it goes on writing the review.",
|
|
154508
|
-
allowLabel: ALLOW_LABEL,
|
|
154509
|
-
denyLabel: DENY_LABEL,
|
|
154510
|
-
reasonLabel: "Tell the agent why, if you deny it"
|
|
154511
|
-
};
|
|
154512
154495
|
var UNATTENDED = {
|
|
154513
154496
|
state: "waiting",
|
|
154514
154497
|
label: "Still being written",
|
|
@@ -154524,37 +154507,27 @@ var WRITTEN_BY_REVIEWER_AGENT = {
|
|
|
154524
154507
|
label: "Your agent is writing the review",
|
|
154525
154508
|
message: "You can read the code meanwhile. Each part appears as it is written."
|
|
154526
154509
|
};
|
|
154527
|
-
var
|
|
154528
|
-
|
|
154529
|
-
|
|
154530
|
-
|
|
154510
|
+
var liveAgentStanding = (agentLabel, isAgentOnline2) => isAgentOnline2 ? {
|
|
154511
|
+
state: "writing",
|
|
154512
|
+
label: `${agentLabel} is writing the review`,
|
|
154513
|
+
message: "You can read the code meanwhile. Each part appears as it is written."
|
|
154514
|
+
} : {
|
|
154515
|
+
state: "waiting",
|
|
154516
|
+
label: `Waiting for ${agentLabel}`,
|
|
154517
|
+
message: `${agentLabel} writes the review once it is online. You can read the code meanwhile.`
|
|
154531
154518
|
};
|
|
154532
|
-
var
|
|
154533
|
-
state: "stopped",
|
|
154534
|
-
label: failureReason === null ? `${agentLabel} stopped before the review was finished` : `${agentLabel} could not write the review`,
|
|
154535
|
-
message: failureReason === null ? CHAT_HINT : `${failureReason} ${CHAT_HINT}`
|
|
154536
|
-
});
|
|
154537
|
-
var standingOf2 = ({ request, isAgentRunning, journal }, writtenCount) => {
|
|
154519
|
+
var standingOf2 = ({ request, isAgentOnline: isAgentOnline2 }, writtenCount) => {
|
|
154538
154520
|
if (request === null) return UNATTENDED;
|
|
154539
154521
|
if (request.writer.kind !== "agent") return writtenCount === 0 ? WAITING_FOR_REVIEWER_AGENT : WRITTEN_BY_REVIEWER_AGENT;
|
|
154540
|
-
|
|
154541
|
-
return isAgentRunning ? {
|
|
154542
|
-
state: "writing",
|
|
154543
|
-
label: `${agentLabel} is writing the review`,
|
|
154544
|
-
message: "You can read the code meanwhile. Each part appears as it is written."
|
|
154545
|
-
} : stoppedStanding(agentLabel, lastFailureReasonOf(journal));
|
|
154546
|
-
};
|
|
154547
|
-
var pendingPermissionOf = (journal) => {
|
|
154548
|
-
const batch = openQuestionBatchesOf(journal).filter((open2) => open2.origin === "permission").at(-1);
|
|
154549
|
-
const question = batch?.questions.at(0);
|
|
154550
|
-
return batch === void 0 || question === void 0 ? null : { batchId: batch.id, questionId: question.id, title: question.prompt, detail: question.detail, ...PERMISSION_LABELS };
|
|
154522
|
+
return liveAgentStanding(AGENT_LABELS[request.writer.agent], isAgentOnline2);
|
|
154551
154523
|
};
|
|
154552
154524
|
var countLabelOf2 = (writtenCount, totalCount) => `${String(writtenCount)} of ${String(totalCount)} parts written`;
|
|
154553
|
-
var isAgentWriting = ({ request,
|
|
154525
|
+
var isAgentWriting = ({ request, isAgentOnline: isAgentOnline2 }) => {
|
|
154554
154526
|
if (request?.writer.kind === "external") return true;
|
|
154555
|
-
return request?.writer.kind === "agent" &&
|
|
154527
|
+
return request?.writer.kind === "agent" && isAgentOnline2;
|
|
154556
154528
|
};
|
|
154557
154529
|
var isWritingNow = (artifact, activity) => artifact.status === "drafting" && isAgentWriting(activity);
|
|
154530
|
+
var isWaitingForLiveAgent = ({ request, isAgentOnline: isAgentOnline2 }) => request?.writer.kind === "agent" && !isAgentOnline2;
|
|
154558
154531
|
var isLeftToNoAgent = (activity) => activity.request?.writer.kind === "author" || activity.request?.writer.kind === "none";
|
|
154559
154532
|
var buildProgress = (artifact, activity) => {
|
|
154560
154533
|
if (artifact.status !== "drafting" || isLeftToNoAgent(activity)) return null;
|
|
@@ -154563,12 +154536,11 @@ var buildProgress = (artifact, activity) => {
|
|
|
154563
154536
|
const standing = standingOf2(activity, tally.complete);
|
|
154564
154537
|
return {
|
|
154565
154538
|
...standing,
|
|
154566
|
-
isWriting:
|
|
154539
|
+
isWriting: !isWaitingForLiveAgent(activity),
|
|
154567
154540
|
countLabel: countLabelOf2(tally.complete, totalCount),
|
|
154568
154541
|
writtenCount: tally.complete,
|
|
154569
154542
|
totalCount,
|
|
154570
|
-
prompt: activity.request?.writer.kind === "external" && activity.prompt !== null ? { ...PROMPT_LABELS, text: activity.prompt } : null
|
|
154571
|
-
permission: activity.isAgentRunning ? pendingPermissionOf(activity.journal) : null
|
|
154543
|
+
prompt: activity.request?.writer.kind === "external" && activity.prompt !== null ? { ...PROMPT_LABELS, text: activity.prompt } : null
|
|
154572
154544
|
};
|
|
154573
154545
|
};
|
|
154574
154546
|
var buildCompletionNotice = (artifact) => artifact.status === "complete" ? { title: "Flight Plan Review ready", body: `${artifact.title} is ready to read.` } : null;
|
|
@@ -155805,12 +155777,10 @@ var findPullRequestSubject = async (key, context) => {
|
|
|
155805
155777
|
};
|
|
155806
155778
|
var readWritingActivity = async (subject, key, context) => {
|
|
155807
155779
|
if (subject.artifact?.status !== "drafting") return NO_WRITING_ACTIVITY;
|
|
155808
|
-
const
|
|
155809
|
-
const [request, conversation] = await Promise.all([context.reviewStore.findRequest(key), store.read(key)]);
|
|
155780
|
+
const request = await context.reviewStore.findRequest(key);
|
|
155810
155781
|
return {
|
|
155811
155782
|
request,
|
|
155812
|
-
|
|
155813
|
-
journal: conversation.journal,
|
|
155783
|
+
isAgentOnline: isAgentOnlineFor(key, context),
|
|
155814
155784
|
prompt: request === null ? null : buildReviewPrompt(subject.repository, subject.target, key, request.writeUp)
|
|
155815
155785
|
};
|
|
155816
155786
|
};
|
|
@@ -155850,7 +155820,7 @@ var getReview = async (input2, context) => {
|
|
|
155850
155820
|
branchLinking,
|
|
155851
155821
|
pendingComments,
|
|
155852
155822
|
publications,
|
|
155853
|
-
isPublishing: isPublishingUnderway(publishingRequest, publications,
|
|
155823
|
+
isPublishing: isPublishingUnderway(publishingRequest, publications, isAgentOnlineFor(key, context), context.now()),
|
|
155854
155824
|
now: context.now(),
|
|
155855
155825
|
setup,
|
|
155856
155826
|
unavailableMessage: opened.unavailableMessage,
|
|
@@ -156021,6 +155991,7 @@ var recordPublication = async (input2, context) => {
|
|
|
156021
155991
|
const key = { repositoryName: input2.repositoryName, targetId: input2.targetId };
|
|
156022
155992
|
const [artifact, publications] = await Promise.all([context.reviewStore.findArtifact(key), context.reviewStore.readPublications(key)]);
|
|
156023
155993
|
if (artifact === null) return { kind: "rejected", message: NO_FLIGHT_PLAN_MESSAGE };
|
|
155994
|
+
markAgentSeen(key, context);
|
|
156024
155995
|
await context.reviewStore.writePublications(key, withPublication(publications, { kind: "claude", url: input2.url, publishedAt: context.now() }));
|
|
156025
155996
|
const isSameAddress = publications.some((publication) => publication.kind === "claude" && publication.url === input2.url);
|
|
156026
155997
|
if (isSameAddress) return { kind: "recorded", note: RECORDED_NOTE };
|
|
@@ -156036,7 +156007,7 @@ var recordPublicationInputShape = {
|
|
|
156036
156007
|
var recordPublicationInputSchema = external_exports.strictObject(recordPublicationInputShape);
|
|
156037
156008
|
|
|
156038
156009
|
// apps/backend/src/server/mcp/tools/record-publication/index.ts
|
|
156039
|
-
var
|
|
156010
|
+
var DESCRIPTION8 = [
|
|
156040
156011
|
"Records the address of the Claude artifact a Flight Plan was published to.",
|
|
156041
156012
|
"Call it once, right after the Artifact tool publishes the page Flight Plan asked you to publish.",
|
|
156042
156013
|
"Until it is called, the reviewer has no link to the artifact."
|
|
@@ -156044,7 +156015,7 @@ var DESCRIPTION7 = [
|
|
|
156044
156015
|
var registerRecordPublicationTool = (mcpServer, context) => {
|
|
156045
156016
|
mcpServer.registerTool(
|
|
156046
156017
|
"record-publication",
|
|
156047
|
-
{ description:
|
|
156018
|
+
{ description: DESCRIPTION8, inputSchema: recordPublicationInputShape },
|
|
156048
156019
|
async (input2) => {
|
|
156049
156020
|
const recording = await recordPublication(input2, context);
|
|
156050
156021
|
return recording.kind === "recorded" ? textResult(recording.note) : errorResult(recording.message);
|
|
@@ -156058,15 +156029,14 @@ var sendAgentMessage = async (input2, context) => {
|
|
|
156058
156029
|
const key = { repositoryName: input2.repositoryName, targetId: input2.targetId };
|
|
156059
156030
|
const target = await findReviewTarget(key, context);
|
|
156060
156031
|
if (target.kind === "rejected") return target;
|
|
156061
|
-
|
|
156032
|
+
markAgentSeen(key, context);
|
|
156062
156033
|
await appendAndPublish(
|
|
156063
156034
|
key,
|
|
156064
156035
|
[{ kind: "agent-message", id: context.conversationEnvironment.newId(), body: input2.body, sentAt: context.now() }],
|
|
156065
156036
|
context
|
|
156066
156037
|
);
|
|
156067
|
-
|
|
156068
|
-
|
|
156069
|
-
return { kind: "sent", note: `${SENT_NOTE} If you want the reviewer's reply: ${listenInstructionOf(command)}` };
|
|
156038
|
+
const command = listenCommandOf(context.conversationEnvironment.serverUrl, key);
|
|
156039
|
+
return { kind: "sent", note: `${SENT_NOTE} ${listenInstructionOf(command)}` };
|
|
156070
156040
|
};
|
|
156071
156041
|
|
|
156072
156042
|
// apps/backend/src/procedures/send-agent-message/utils/schemas.ts
|
|
@@ -156081,11 +156051,11 @@ var sendAgentMessageInputShape = {
|
|
|
156081
156051
|
var sendAgentMessageInputSchema = external_exports.strictObject(sendAgentMessageInputShape);
|
|
156082
156052
|
|
|
156083
156053
|
// apps/backend/src/server/mcp/tools/send-message/index.ts
|
|
156084
|
-
var
|
|
156054
|
+
var DESCRIPTION9 = "Send the reviewer a message in Flight Plan's web app. Use it for every answer, summary or result the reviewer should read.";
|
|
156085
156055
|
var registerSendMessageTool = (mcpServer, context) => {
|
|
156086
156056
|
mcpServer.registerTool(
|
|
156087
156057
|
"send-message",
|
|
156088
|
-
{ description:
|
|
156058
|
+
{ description: DESCRIPTION9, inputSchema: sendAgentMessageInputShape },
|
|
156089
156059
|
async (input2) => {
|
|
156090
156060
|
const sending = await sendAgentMessage(input2, context);
|
|
156091
156061
|
return sending.kind === "sent" ? { content: [{ type: "text", text: sending.note }] } : { content: [{ type: "text", text: sending.message }], isError: true };
|
|
@@ -156518,7 +156488,7 @@ var updateNodesInputShape = {
|
|
|
156518
156488
|
var updateNodesInputSchema = external_exports.strictObject(updateNodesInputShape);
|
|
156519
156489
|
|
|
156520
156490
|
// apps/backend/src/server/mcp/tools/update-nodes/index.ts
|
|
156521
|
-
var
|
|
156491
|
+
var DESCRIPTION10 = [
|
|
156522
156492
|
"Writes prose onto what one segment of the artifact already has, by id, in one batch.",
|
|
156523
156493
|
"`segmentId` names that segment, and every id in the call is looked up inside it.",
|
|
156524
156494
|
"The segment's own fields are written by name: `title` and `context`, and `traceDiagramDescription` for its Trace Diagram.",
|
|
@@ -156532,7 +156502,7 @@ var DESCRIPTION9 = [
|
|
|
156532
156502
|
var registerUpdateNodesTool = (mcpServer, context) => {
|
|
156533
156503
|
mcpServer.registerTool(
|
|
156534
156504
|
"update-nodes",
|
|
156535
|
-
{ description:
|
|
156505
|
+
{ description: DESCRIPTION10, inputSchema: updateNodesInputShape },
|
|
156536
156506
|
async (input2) => {
|
|
156537
156507
|
const writing = await updateNodes(input2, context);
|
|
156538
156508
|
return writing.kind === "written" ? jsonResult({ note: writing.note, nodes: writing.nodes, unwritten: writing.unwritten }) : errorResult(writing.message);
|
|
@@ -156560,6 +156530,7 @@ var createMcpServer = (context) => {
|
|
|
156560
156530
|
registerCompleteTool(mcpServer, context);
|
|
156561
156531
|
registerRecordPublicationTool(mcpServer, context);
|
|
156562
156532
|
registerRecordImportTool(mcpServer, context);
|
|
156533
|
+
registerPingTool(mcpServer, context);
|
|
156563
156534
|
return mcpServer;
|
|
156564
156535
|
};
|
|
156565
156536
|
var handleMcpRequest = (context) => async (request, reply) => {
|
|
@@ -156642,46 +156613,7 @@ var parseCommand = (commandArguments) => {
|
|
|
156642
156613
|
};
|
|
156643
156614
|
|
|
156644
156615
|
// apps/backend/src/procedures/context.ts
|
|
156645
|
-
var
|
|
156646
|
-
|
|
156647
|
-
// apps/backend/src/procedures/get-conversation/utils/agent-registry.ts
|
|
156648
|
-
var shouldRedeliverAfter = (closing) => closing === "turn-ended" || closing === "idle";
|
|
156649
|
-
var NO_LISTENER = { openCount: 0, lastClosedAt: null };
|
|
156650
|
-
var InMemoryAgentRegistry = class {
|
|
156651
|
-
agents = /* @__PURE__ */ new Map();
|
|
156652
|
-
listeners = /* @__PURE__ */ new Map();
|
|
156653
|
-
find = (key) => this.agents.get(reviewKeyId(key)) ?? null;
|
|
156654
|
-
findBySessionId = (sessionId) => [...this.agents.values()].find((agent) => agent.sessionId === sessionId) ?? null;
|
|
156655
|
-
claim = (agent) => {
|
|
156656
|
-
if (this.agents.has(reviewKeyId(agent.key))) return false;
|
|
156657
|
-
this.agents = new Map([...this.agents, [reviewKeyId(agent.key), agent]]);
|
|
156658
|
-
return true;
|
|
156659
|
-
};
|
|
156660
|
-
update = (key, change) => {
|
|
156661
|
-
const current = this.find(key);
|
|
156662
|
-
if (current === null) return null;
|
|
156663
|
-
const changed = change(current);
|
|
156664
|
-
this.agents = new Map([...this.agents, [reviewKeyId(key), changed]]);
|
|
156665
|
-
return changed;
|
|
156666
|
-
};
|
|
156667
|
-
release = (key, sessionId) => {
|
|
156668
|
-
const current = this.find(key);
|
|
156669
|
-
if (current?.sessionId !== sessionId) return null;
|
|
156670
|
-
this.agents = new Map([...this.agents].filter(([id]) => id !== reviewKeyId(key)));
|
|
156671
|
-
return current;
|
|
156672
|
-
};
|
|
156673
|
-
list = () => [...this.agents.values()];
|
|
156674
|
-
openListener = (key) => {
|
|
156675
|
-
const presence = this.listenerPresence(key);
|
|
156676
|
-
this.listeners = new Map([...this.listeners, [reviewKeyId(key), { ...presence, openCount: presence.openCount + 1 }]]);
|
|
156677
|
-
};
|
|
156678
|
-
closeListener = (key, closedAt) => {
|
|
156679
|
-
const presence = this.listenerPresence(key);
|
|
156680
|
-
const openCount = Math.max(presence.openCount - 1, 0);
|
|
156681
|
-
this.listeners = new Map([...this.listeners, [reviewKeyId(key), { openCount, lastClosedAt: closedAt }]]);
|
|
156682
|
-
};
|
|
156683
|
-
listenerPresence = (key) => this.listeners.get(reviewKeyId(key)) ?? NO_LISTENER;
|
|
156684
|
-
};
|
|
156616
|
+
var import_node_crypto5 = require("node:crypto");
|
|
156685
156617
|
|
|
156686
156618
|
// apps/backend/src/procedures/get-conversation/utils/conversation-store.ts
|
|
156687
156619
|
var InMemoryConversationStore = class {
|
|
@@ -156702,58 +156634,92 @@ var InMemoryConversationStore = class {
|
|
|
156702
156634
|
);
|
|
156703
156635
|
};
|
|
156704
156636
|
|
|
156705
|
-
// apps/backend/src/procedures/
|
|
156706
|
-
var
|
|
156707
|
-
|
|
156708
|
-
const
|
|
156709
|
-
if (
|
|
156710
|
-
|
|
156711
|
-
else closed.process.stop();
|
|
156712
|
-
hub.publish(key);
|
|
156713
|
-
return true;
|
|
156637
|
+
// apps/backend/src/procedures/get-conversation/utils/conversation-hub.ts
|
|
156638
|
+
var NO_TIME_LEFT_MS = 0;
|
|
156639
|
+
var nextChangeOf = async (subscription, options) => {
|
|
156640
|
+
const timeoutMs = options.remainingMs === null ? null : Math.max(options.remainingMs(), NO_TIME_LEFT_MS);
|
|
156641
|
+
if (timeoutMs === NO_TIME_LEFT_MS) return "timed-out";
|
|
156642
|
+
return await subscription.nextChange({ timeoutMs, signal: options.signal });
|
|
156714
156643
|
};
|
|
156644
|
+
var readsOnChange = (subscription, options, read2) => ({
|
|
156645
|
+
[Symbol.asyncIterator]: () => ({
|
|
156646
|
+
next: async () => {
|
|
156647
|
+
const wait = await nextChangeOf(subscription, options);
|
|
156648
|
+
return wait === "changed" ? { value: await read2(), done: false } : { value: void 0, done: true };
|
|
156649
|
+
}
|
|
156650
|
+
})
|
|
156651
|
+
});
|
|
156715
156652
|
|
|
156716
|
-
// apps/backend/src/procedures/
|
|
156717
|
-
var
|
|
156718
|
-
|
|
156719
|
-
|
|
156720
|
-
};
|
|
156721
|
-
|
|
156722
|
-
const pending =
|
|
156723
|
-
|
|
156724
|
-
|
|
156725
|
-
if (!
|
|
156726
|
-
return {
|
|
156727
|
-
|
|
156728
|
-
|
|
156729
|
-
|
|
156730
|
-
|
|
156731
|
-
|
|
156732
|
-
|
|
156733
|
-
|
|
156734
|
-
|
|
156735
|
-
|
|
156736
|
-
|
|
156737
|
-
|
|
156738
|
-
|
|
156739
|
-
|
|
156740
|
-
|
|
156741
|
-
|
|
156742
|
-
|
|
156743
|
-
|
|
156744
|
-
|
|
156745
|
-
|
|
156746
|
-
|
|
156747
|
-
|
|
156748
|
-
|
|
156749
|
-
|
|
156750
|
-
|
|
156751
|
-
|
|
156752
|
-
|
|
156653
|
+
// apps/backend/src/procedures/listen-for-reviewer/index.ts
|
|
156654
|
+
var LISTEN_WINDOW_MS = 54e4;
|
|
156655
|
+
var claimPacket = async (key, context) => {
|
|
156656
|
+
const { store, presence, serverUrl } = context.conversationEnvironment;
|
|
156657
|
+
const { journal } = await store.read(key);
|
|
156658
|
+
const claimed = Math.max(lastDeliveredSequenceOf(journal), presence.presenceOf(key).claimedThroughSequence);
|
|
156659
|
+
const pending = inboundAfter(journal, claimed);
|
|
156660
|
+
if (pending.length === 0) return null;
|
|
156661
|
+
const throughSequence = lastSequenceOf(pending);
|
|
156662
|
+
if (!presence.claimThrough(key, throughSequence)) return null;
|
|
156663
|
+
return {
|
|
156664
|
+
kind: "work",
|
|
156665
|
+
throughSequence,
|
|
156666
|
+
text: formatListenPacket(formatInbound(pending, journal), listenCommandOf(serverUrl, key))
|
|
156667
|
+
};
|
|
156668
|
+
};
|
|
156669
|
+
var recordDelivery = async (key, packet, context) => {
|
|
156670
|
+
await appendAndPublish(
|
|
156671
|
+
key,
|
|
156672
|
+
[
|
|
156673
|
+
{
|
|
156674
|
+
kind: "delivery",
|
|
156675
|
+
id: context.conversationEnvironment.newId(),
|
|
156676
|
+
throughSequence: packet.throughSequence,
|
|
156677
|
+
channel: "listener",
|
|
156678
|
+
deliveredAt: context.now()
|
|
156679
|
+
}
|
|
156680
|
+
],
|
|
156681
|
+
context
|
|
156682
|
+
);
|
|
156683
|
+
};
|
|
156684
|
+
var waitForPacket = async (key, subscription, context, signal) => {
|
|
156685
|
+
const waiting = await claimPacket(key, context);
|
|
156686
|
+
if (waiting !== null) return waiting;
|
|
156687
|
+
const deadlineMs = context.now().getTime() + LISTEN_WINDOW_MS;
|
|
156688
|
+
const remainingMs = () => deadlineMs - context.now().getTime();
|
|
156689
|
+
const packets = readsOnChange(subscription, { signal, remainingMs }, async () => await claimPacket(key, context));
|
|
156690
|
+
for await (const packet of packets) {
|
|
156691
|
+
if (packet !== null) return packet;
|
|
156753
156692
|
}
|
|
156754
|
-
|
|
156755
|
-
|
|
156756
|
-
|
|
156693
|
+
return null;
|
|
156694
|
+
};
|
|
156695
|
+
var idlePacketOf = (key, context) => ({
|
|
156696
|
+
kind: "idle",
|
|
156697
|
+
text: formatIdlePacket(listenCommandOf(context.conversationEnvironment.serverUrl, key))
|
|
156698
|
+
});
|
|
156699
|
+
var packetsOf = async function* (key, context, signal) {
|
|
156700
|
+
const { presence, hub } = context.conversationEnvironment;
|
|
156701
|
+
const subscription = hub.subscribe(key);
|
|
156702
|
+
presence.openStream(key);
|
|
156703
|
+
hub.publish(key);
|
|
156704
|
+
try {
|
|
156705
|
+
const packet = await waitForPacket(key, subscription, context, signal);
|
|
156706
|
+
if (packet !== null) {
|
|
156707
|
+
yield packet;
|
|
156708
|
+
await recordDelivery(key, packet, context);
|
|
156709
|
+
} else if (signal?.aborted !== true) {
|
|
156710
|
+
yield idlePacketOf(key, context);
|
|
156711
|
+
}
|
|
156712
|
+
} finally {
|
|
156713
|
+
subscription.close();
|
|
156714
|
+
presence.closeStream(key, context.now());
|
|
156715
|
+
hub.publish(key);
|
|
156716
|
+
}
|
|
156717
|
+
};
|
|
156718
|
+
var listenForReviewer = async (input2, context, signal) => {
|
|
156719
|
+
const key = { repositoryName: input2.repositoryName, targetId: input2.targetId };
|
|
156720
|
+
const target = await findReviewTarget(key, context);
|
|
156721
|
+
if (target.kind === "rejected") return target;
|
|
156722
|
+
return { kind: "listening", packets: packetsOf(key, context, signal) };
|
|
156757
156723
|
};
|
|
156758
156724
|
|
|
156759
156725
|
// apps/backend/src/procedures/get-instructions/utils/instruction-texts.ts
|
|
@@ -158423,6 +158389,7 @@ var createMockSetupEnvironment = () => ({
|
|
|
158423
158389
|
hasAgentCli: async (agent) => await Promise.resolve(agent !== AGENT_WITHOUT_CLI),
|
|
158424
158390
|
listAgentModels: async (agent) => await Promise.resolve(MOCK_AGENT_MODELS[agent] ?? []),
|
|
158425
158391
|
installAgent: async () => await Promise.resolve({ kind: "installed" }),
|
|
158392
|
+
isAgentInstallCurrent: async () => await Promise.resolve(true),
|
|
158426
158393
|
probeForgeClis: async () => await Promise.resolve([
|
|
158427
158394
|
{ cli: "gh", state: { kind: "signed-in", account: "dev-harper" } },
|
|
158428
158395
|
{ cli: "glab", state: { kind: "missing" } }
|
|
@@ -158693,25 +158660,6 @@ var writeSamplePublishedPage = async (key, texts) => await Promise.resolve({
|
|
|
158693
158660
|
]
|
|
158694
158661
|
});
|
|
158695
158662
|
|
|
158696
|
-
// apps/backend/src/procedures/request-write-up/utils/write-up-queue.ts
|
|
158697
|
-
var isSameTarget = (first, second) => JSON.stringify(first) === JSON.stringify(second);
|
|
158698
|
-
var withQueuedTarget = (queued, target) => queued.some((listed) => isSameTarget(listed, target)) ? queued : [...queued, target];
|
|
158699
|
-
var InMemoryWriteUpQueue = class {
|
|
158700
|
-
targetsByKey = /* @__PURE__ */ new Map();
|
|
158701
|
-
add = (key, target) => {
|
|
158702
|
-
const queued = this.targetsByKey.get(reviewKeyId(key)) ?? [];
|
|
158703
|
-
this.targetsByKey = new Map([...this.targetsByKey, [reviewKeyId(key), withQueuedTarget(queued, target)]]);
|
|
158704
|
-
};
|
|
158705
|
-
take = (key) => {
|
|
158706
|
-
const queued = this.targetsByKey.get(reviewKeyId(key)) ?? [];
|
|
158707
|
-
this.targetsByKey = new Map([...this.targetsByKey].filter(([id]) => id !== reviewKeyId(key)));
|
|
158708
|
-
return queued;
|
|
158709
|
-
};
|
|
158710
|
-
};
|
|
158711
|
-
|
|
158712
|
-
// apps/backend/src/procedures/save-setup-step/utils/claude-plugin.ts
|
|
158713
|
-
var import_node_path4 = require("node:path");
|
|
158714
|
-
|
|
158715
158663
|
// apps/backend/src/procedures/get-setup/utils/agent-folders.ts
|
|
158716
158664
|
var import_node_path3 = require("node:path");
|
|
158717
158665
|
var CLAUDE_FOLDER_NAME = ".claude";
|
|
@@ -158730,83 +158678,15 @@ var AGENT_ENTRY_NAMES = {
|
|
|
158730
158678
|
};
|
|
158731
158679
|
var isAgentFolder = (agent, entryNames) => AGENT_ENTRY_NAMES[agent].some((entryName) => entryNames.includes(entryName));
|
|
158732
158680
|
|
|
158733
|
-
// apps/backend/src/procedures/save-setup-step/utils/flightplan-server.ts
|
|
158734
|
-
var MCP_SERVER_NAME = "flightplan";
|
|
158735
|
-
|
|
158736
|
-
// apps/backend/src/procedures/save-setup-step/utils/claude-plugin.ts
|
|
158737
|
-
var MARKETPLACE_FOLDER_NAME = "agent-plugin";
|
|
158738
|
-
var MARKETPLACE_NAME = "flightplan";
|
|
158739
|
-
var PLUGIN_NAME = "flightplan";
|
|
158740
|
-
var MARKETPLACE_MANIFEST_PATH = [".claude-plugin", "marketplace.json"];
|
|
158741
|
-
var MCP_MANIFEST_NAME = ".mcp.json";
|
|
158742
|
-
var MARKETPLACE_OWNER = "Flight Plan";
|
|
158743
|
-
var PLUGIN_DESCRIPTION = "Write and maintain pull request walkthroughs with Flight Plan.";
|
|
158744
|
-
var MCP_TRANSPORT = "http";
|
|
158745
|
-
var buildMarketplaceManifest = () => ({
|
|
158746
|
-
name: MARKETPLACE_NAME,
|
|
158747
|
-
owner: { name: MARKETPLACE_OWNER },
|
|
158748
|
-
plugins: [{ name: PLUGIN_NAME, source: `./${PLUGIN_NAME}`, description: PLUGIN_DESCRIPTION }]
|
|
158749
|
-
});
|
|
158750
|
-
var buildMcpManifest = (mcpUrl) => ({
|
|
158751
|
-
mcpServers: { [MCP_SERVER_NAME]: { type: MCP_TRANSPORT, url: mcpUrl } }
|
|
158752
|
-
});
|
|
158753
|
-
var claudeInstallCommands = (marketplacePath) => [
|
|
158754
|
-
["plugin", "marketplace", "add", marketplacePath],
|
|
158755
|
-
["plugin", "install", `${PLUGIN_NAME}@${MARKETPLACE_NAME}`]
|
|
158756
|
-
];
|
|
158757
|
-
var usesOwnFolder = (installPath, homePath, environment) => agentFolders(homePath, environment).some((folder) => folder.agent === "claude" && folder.path === installPath);
|
|
158758
|
-
var claudeCommandEnvironment = (installPath, homePath, environment) => usesOwnFolder(installPath, homePath, environment) ? environment : { ...environment, CLAUDE_CONFIG_DIR: installPath };
|
|
158759
|
-
var SPAWN_PLUGIN_NAME = "flightplan-spawn";
|
|
158760
|
-
var PLUGIN_MANIFEST_PATH = [".claude-plugin", "plugin.json"];
|
|
158761
|
-
var HOOKS_MANIFEST_PATH = ["hooks", "hooks.json"];
|
|
158762
|
-
var AGENT_HOOK_PATHS = {
|
|
158763
|
-
promptSubmit: "/api/agent-hooks/user-prompt-submit",
|
|
158764
|
-
postToolUse: "/api/agent-hooks/post-tool-use",
|
|
158765
|
-
permissionRequest: "/api/agent-hooks/permission-request",
|
|
158766
|
-
stop: "/api/agent-hooks/stop"
|
|
158767
|
-
};
|
|
158768
|
-
var SPAWN_PLUGIN_DESCRIPTION = "Connects a Claude session that Flight Plan started to Flight Plan's web app.";
|
|
158769
|
-
var HOOK_TYPE = "http";
|
|
158770
|
-
var ALL_TOOLS_MATCHER = "*";
|
|
158771
|
-
var QUICK_HOOK_TIMEOUT_SECONDS = 10;
|
|
158772
|
-
var STOP_HOOK_TIMEOUT_SECONDS = 30;
|
|
158773
|
-
var PERMISSION_HOOK_TIMEOUT_SECONDS = 600;
|
|
158774
|
-
var spawnPluginPathOf = (dataPath) => (0, import_node_path4.join)(dataPath, MARKETPLACE_FOLDER_NAME, SPAWN_PLUGIN_NAME);
|
|
158775
|
-
var buildSpawnPluginManifest = () => ({
|
|
158776
|
-
name: SPAWN_PLUGIN_NAME,
|
|
158777
|
-
description: SPAWN_PLUGIN_DESCRIPTION
|
|
158778
|
-
});
|
|
158779
|
-
var httpHook = (serverUrl, path11, timeout) => ({
|
|
158780
|
-
type: HOOK_TYPE,
|
|
158781
|
-
url: `${serverUrl}${path11}`,
|
|
158782
|
-
timeout
|
|
158783
|
-
});
|
|
158784
|
-
var buildSpawnHooksManifest = (serverUrl) => ({
|
|
158785
|
-
description: SPAWN_PLUGIN_DESCRIPTION,
|
|
158786
|
-
hooks: {
|
|
158787
|
-
UserPromptSubmit: [{ hooks: [httpHook(serverUrl, AGENT_HOOK_PATHS.promptSubmit, QUICK_HOOK_TIMEOUT_SECONDS)] }],
|
|
158788
|
-
PostToolUse: [
|
|
158789
|
-
{ matcher: ALL_TOOLS_MATCHER, hooks: [httpHook(serverUrl, AGENT_HOOK_PATHS.postToolUse, QUICK_HOOK_TIMEOUT_SECONDS)] }
|
|
158790
|
-
],
|
|
158791
|
-
PermissionRequest: [
|
|
158792
|
-
{
|
|
158793
|
-
matcher: ALL_TOOLS_MATCHER,
|
|
158794
|
-
hooks: [httpHook(serverUrl, AGENT_HOOK_PATHS.permissionRequest, PERMISSION_HOOK_TIMEOUT_SECONDS)]
|
|
158795
|
-
}
|
|
158796
|
-
],
|
|
158797
|
-
Stop: [{ hooks: [httpHook(serverUrl, AGENT_HOOK_PATHS.stop, STOP_HOOK_TIMEOUT_SECONDS)] }]
|
|
158798
|
-
}
|
|
158799
|
-
});
|
|
158800
|
-
|
|
158801
158681
|
// apps/backend/src/utils/executable-finder/index.ts
|
|
158802
158682
|
var import_node_fs3 = require("node:fs");
|
|
158803
158683
|
var import_promises = require("node:fs/promises");
|
|
158804
158684
|
|
|
158805
158685
|
// apps/backend/src/procedures/save-setup-step/utils/executable-candidates.ts
|
|
158806
|
-
var
|
|
158686
|
+
var import_node_path4 = require("node:path");
|
|
158807
158687
|
var USER_PROGRAMS_FOLDER = [".local", "bin"];
|
|
158808
|
-
var searchFolders = (searchPath) => (searchPath ?? "").split(
|
|
158809
|
-
var executableCandidates = (name, searchPath, homePath) => [...searchFolders(searchPath), (0,
|
|
158688
|
+
var searchFolders = (searchPath) => (searchPath ?? "").split(import_node_path4.delimiter).filter((folder) => folder !== "");
|
|
158689
|
+
var executableCandidates = (name, searchPath, homePath) => [...searchFolders(searchPath), (0, import_node_path4.join)(homePath, ...USER_PROGRAMS_FOLDER)].map((folder) => (0, import_node_path4.join)(folder, name));
|
|
158810
158690
|
|
|
158811
158691
|
// apps/backend/src/utils/executable-finder/index.ts
|
|
158812
158692
|
var isExecutable = async (path11) => {
|
|
@@ -158829,7 +158709,7 @@ var createAgentCliProbe = (options) => {
|
|
|
158829
158709
|
|
|
158830
158710
|
// apps/backend/src/utils/folder-lister/index.ts
|
|
158831
158711
|
var import_promises2 = require("node:fs/promises");
|
|
158832
|
-
var
|
|
158712
|
+
var import_node_path5 = require("node:path");
|
|
158833
158713
|
var GIT_FOLDER_NAME = ".git";
|
|
158834
158714
|
var exists = async (path11) => {
|
|
158835
158715
|
try {
|
|
@@ -158861,14 +158741,14 @@ var readFolderNames = async (path11) => {
|
|
|
158861
158741
|
return null;
|
|
158862
158742
|
}
|
|
158863
158743
|
};
|
|
158864
|
-
var parentPathOf2 = (path11) => (0,
|
|
158865
|
-
var isRepositoryFolder = async (path11) => await exists((0,
|
|
158744
|
+
var parentPathOf2 = (path11) => (0, import_node_path5.dirname)(path11) === path11 ? null : (0, import_node_path5.dirname)(path11);
|
|
158745
|
+
var isRepositoryFolder = async (path11) => await exists((0, import_node_path5.join)(path11, GIT_FOLDER_NAME));
|
|
158866
158746
|
var toFolderEntry2 = async (parentPath, name) => {
|
|
158867
|
-
const path11 = (0,
|
|
158747
|
+
const path11 = (0, import_node_path5.join)(parentPath, name);
|
|
158868
158748
|
return { name, path: path11, isRepository: await isRepositoryFolder(path11) };
|
|
158869
158749
|
};
|
|
158870
158750
|
var createFolderLister = (homePath) => async (requestedPath) => {
|
|
158871
|
-
const path11 = (0,
|
|
158751
|
+
const path11 = (0, import_node_path5.resolve)(requestedPath ?? homePath);
|
|
158872
158752
|
const names = await readFolderNames(path11);
|
|
158873
158753
|
if (names === null) return null;
|
|
158874
158754
|
const folders = await Promise.all(names.map(async (name) => await toFolderEntry2(path11, name)));
|
|
@@ -158889,6 +158769,41 @@ var createAgentDetector = (options) => {
|
|
|
158889
158769
|
var import_promises4 = require("node:fs/promises");
|
|
158890
158770
|
var import_node_path8 = require("node:path");
|
|
158891
158771
|
|
|
158772
|
+
// apps/backend/src/procedures/refresh-agent-installs/utils/install-fingerprint.ts
|
|
158773
|
+
var import_node_crypto4 = require("node:crypto");
|
|
158774
|
+
var HASH_ALGORITHM = "sha256";
|
|
158775
|
+
var FIELD_SEPARATOR2 = "\0";
|
|
158776
|
+
var byPath2 = (first, second) => first.path.localeCompare(second.path);
|
|
158777
|
+
var installFingerprintOf = (files, mcpUrl) => [...files].sort(byPath2).reduce((hash2, file2) => hash2.update(file2.path).update(FIELD_SEPARATOR2).update(file2.content).update(FIELD_SEPARATOR2), (0, import_node_crypto4.createHash)(HASH_ALGORITHM).update(mcpUrl)).digest("hex");
|
|
158778
|
+
var isInstallCurrent = (install, stamp, fingerprint) => stamp?.installPath === install.installPath && stamp.fingerprint === fingerprint;
|
|
158779
|
+
|
|
158780
|
+
// apps/backend/src/procedures/save-setup-step/utils/flightplan-server.ts
|
|
158781
|
+
var MCP_SERVER_NAME = "flightplan";
|
|
158782
|
+
|
|
158783
|
+
// apps/backend/src/procedures/save-setup-step/utils/claude-plugin.ts
|
|
158784
|
+
var MARKETPLACE_FOLDER_NAME = "agent-plugin";
|
|
158785
|
+
var MARKETPLACE_NAME = "flightplan";
|
|
158786
|
+
var PLUGIN_NAME = "flightplan";
|
|
158787
|
+
var MARKETPLACE_MANIFEST_PATH = [".claude-plugin", "marketplace.json"];
|
|
158788
|
+
var MCP_MANIFEST_NAME = ".mcp.json";
|
|
158789
|
+
var MARKETPLACE_OWNER = "Flight Plan";
|
|
158790
|
+
var PLUGIN_DESCRIPTION = "Write and maintain pull request walkthroughs with Flight Plan.";
|
|
158791
|
+
var MCP_TRANSPORT = "http";
|
|
158792
|
+
var buildMarketplaceManifest = () => ({
|
|
158793
|
+
name: MARKETPLACE_NAME,
|
|
158794
|
+
owner: { name: MARKETPLACE_OWNER },
|
|
158795
|
+
plugins: [{ name: PLUGIN_NAME, source: `./${PLUGIN_NAME}`, description: PLUGIN_DESCRIPTION }]
|
|
158796
|
+
});
|
|
158797
|
+
var buildMcpManifest = (mcpUrl) => ({
|
|
158798
|
+
mcpServers: { [MCP_SERVER_NAME]: { type: MCP_TRANSPORT, url: mcpUrl } }
|
|
158799
|
+
});
|
|
158800
|
+
var claudeInstallCommands = (marketplacePath) => [
|
|
158801
|
+
["plugin", "marketplace", "add", marketplacePath],
|
|
158802
|
+
["plugin", "install", `${PLUGIN_NAME}@${MARKETPLACE_NAME}`]
|
|
158803
|
+
];
|
|
158804
|
+
var usesOwnFolder = (installPath, homePath, environment) => agentFolders(homePath, environment).some((folder) => folder.agent === "claude" && folder.path === installPath);
|
|
158805
|
+
var claudeCommandEnvironment = (installPath, homePath, environment) => usesOwnFolder(installPath, homePath, environment) ? environment : { ...environment, CLAUDE_CONFIG_DIR: installPath };
|
|
158806
|
+
|
|
158892
158807
|
// apps/backend/src/procedures/save-setup-step/utils/codex-config.ts
|
|
158893
158808
|
var SERVER_TABLE = new RegExp(String.raw`^\[mcp_servers\.${MCP_SERVER_NAME}\][^\n]*\n?(?:(?!\[)[^\n]*\n?)*`, "mu");
|
|
158894
158809
|
var serverTable = (mcpUrl) => `[mcp_servers.${MCP_SERVER_NAME}]
|
|
@@ -158912,7 +158827,7 @@ ${serverTable(mcpUrl)}`;
|
|
|
158912
158827
|
|
|
158913
158828
|
// apps/backend/src/procedures/save-setup-step/utils/cursor-config.ts
|
|
158914
158829
|
var EMPTY_CONFIG = "{}";
|
|
158915
|
-
var
|
|
158830
|
+
var JSON_INDENT2 = 2;
|
|
158916
158831
|
var isJsonObject = (parsed) => typeof parsed === "object" && parsed !== null && !Array.isArray(parsed);
|
|
158917
158832
|
var parseJsonObject = (text2) => {
|
|
158918
158833
|
try {
|
|
@@ -158927,7 +158842,7 @@ var withCursorMcpServer = (config3, mcpUrl) => {
|
|
|
158927
158842
|
const parsed = parseJsonObject(config3 === null || config3.trim() === "" ? EMPTY_CONFIG : config3);
|
|
158928
158843
|
if (parsed === null) return null;
|
|
158929
158844
|
const merged = { ...parsed, mcpServers: { ...serversOf(parsed), [MCP_SERVER_NAME]: { url: mcpUrl } } };
|
|
158930
|
-
return `${JSON.stringify(merged, null,
|
|
158845
|
+
return `${JSON.stringify(merged, null, JSON_INDENT2)}
|
|
158931
158846
|
`;
|
|
158932
158847
|
};
|
|
158933
158848
|
|
|
@@ -158935,9 +158850,12 @@ var withCursorMcpServer = (config3, mcpUrl) => {
|
|
|
158935
158850
|
var NAME_LINE = /^name:.*$/mu;
|
|
158936
158851
|
var renameSkill = (skill, name) => skill.replace(NAME_LINE, `name: ${name}`);
|
|
158937
158852
|
|
|
158853
|
+
// apps/backend/src/utils/install-stamp-file/index.ts
|
|
158854
|
+
var import_node_path7 = require("node:path");
|
|
158855
|
+
|
|
158938
158856
|
// apps/backend/src/utils/text-file/index.ts
|
|
158939
158857
|
var import_promises3 = require("node:fs/promises");
|
|
158940
|
-
var
|
|
158858
|
+
var import_node_path6 = require("node:path");
|
|
158941
158859
|
var MISSING_FILE_CODE = "ENOENT";
|
|
158942
158860
|
var DRAFT_SUFFIX = ".draft";
|
|
158943
158861
|
var isMissingFile = (error61) => error61 instanceof Error && "code" in error61 && error61.code === MISSING_FILE_CODE;
|
|
@@ -158951,7 +158869,7 @@ var readTextOrNull = async (path11) => {
|
|
|
158951
158869
|
};
|
|
158952
158870
|
var writeText = async (path11, text2) => {
|
|
158953
158871
|
const draftPath = `${path11}${DRAFT_SUFFIX}`;
|
|
158954
|
-
await (0, import_promises3.mkdir)((0,
|
|
158872
|
+
await (0, import_promises3.mkdir)((0, import_node_path6.dirname)(path11), { recursive: true });
|
|
158955
158873
|
await (0, import_promises3.writeFile)(draftPath, text2);
|
|
158956
158874
|
await (0, import_promises3.rename)(draftPath, path11);
|
|
158957
158875
|
};
|
|
@@ -158959,6 +158877,30 @@ var removeFile = async (path11) => {
|
|
|
158959
158877
|
await (0, import_promises3.rm)(path11, { force: true });
|
|
158960
158878
|
};
|
|
158961
158879
|
|
|
158880
|
+
// apps/backend/src/utils/install-stamp-file/index.ts
|
|
158881
|
+
var FOLDER_NAME = "agent-installs";
|
|
158882
|
+
var JSON_INDENT3 = 2;
|
|
158883
|
+
var installStampSchema = external_exports.object({ installPath: external_exports.string(), fingerprint: external_exports.string() });
|
|
158884
|
+
var parseInstallStamp = (text2) => {
|
|
158885
|
+
if (text2 === null) return null;
|
|
158886
|
+
try {
|
|
158887
|
+
const parsed = installStampSchema.safeParse(JSON.parse(text2));
|
|
158888
|
+
return parsed.success ? parsed.data : null;
|
|
158889
|
+
} catch {
|
|
158890
|
+
return null;
|
|
158891
|
+
}
|
|
158892
|
+
};
|
|
158893
|
+
var createInstallStampFile = (dataPath) => {
|
|
158894
|
+
const pathOf2 = (agent) => (0, import_node_path7.join)(dataPath, FOLDER_NAME, `${agent}.json`);
|
|
158895
|
+
return {
|
|
158896
|
+
read: async (agent) => parseInstallStamp(await readTextOrNull(pathOf2(agent))),
|
|
158897
|
+
write: async (agent, stamp) => {
|
|
158898
|
+
await writeText(pathOf2(agent), `${JSON.stringify(stamp, null, JSON_INDENT3)}
|
|
158899
|
+
`);
|
|
158900
|
+
}
|
|
158901
|
+
};
|
|
158902
|
+
};
|
|
158903
|
+
|
|
158962
158904
|
// apps/backend/src/utils/agent-installer/index.ts
|
|
158963
158905
|
var SKILL_SOURCE_PATH = ["skills", "review"];
|
|
158964
158906
|
var SKILL_NAME = "flightplan-review";
|
|
@@ -159001,12 +158943,6 @@ var writeMarketplace = async (marketplacePath, options) => {
|
|
|
159001
158943
|
await writeText((0, import_node_path8.join)(pluginPath, MCP_MANIFEST_NAME), formatJson(buildMcpManifest(options.mcpUrl)));
|
|
159002
158944
|
await writeText((0, import_node_path8.join)(marketplacePath, ...MARKETPLACE_MANIFEST_PATH), formatJson(buildMarketplaceManifest()));
|
|
159003
158945
|
};
|
|
159004
|
-
var writeSpawnPlugin = async (options) => {
|
|
159005
|
-
const spawnPluginPath = spawnPluginPathOf(options.dataPath);
|
|
159006
|
-
await (0, import_promises4.rm)(spawnPluginPath, { recursive: true, force: true });
|
|
159007
|
-
await writeText((0, import_node_path8.join)(spawnPluginPath, ...PLUGIN_MANIFEST_PATH), formatJson(buildSpawnPluginManifest()));
|
|
159008
|
-
await writeText((0, import_node_path8.join)(spawnPluginPath, ...HOOKS_MANIFEST_PATH), formatJson(buildSpawnHooksManifest(options.serverUrl)));
|
|
159009
|
-
};
|
|
159010
158946
|
var runUntilFailure = async (run4, commands) => {
|
|
159011
158947
|
const [command, ...laterCommands] = commands;
|
|
159012
158948
|
if (commands.length === 0) return INSTALLED;
|
|
@@ -159018,7 +158954,6 @@ var installClaudePlugin = async (install, options) => {
|
|
|
159018
158954
|
const executable = await createExecutableFinder(options)(AGENT_CLI_NAMES.claude);
|
|
159019
158955
|
if (executable === null) return failed(CLAUDE_MISSING_REASON);
|
|
159020
158956
|
await writeMarketplace(marketplacePath, options);
|
|
159021
|
-
await writeSpawnPlugin(options);
|
|
159022
158957
|
const environment = claudeCommandEnvironment(install.installPath, options.homePath, options.environment);
|
|
159023
158958
|
const run4 = async (commandArguments) => {
|
|
159024
158959
|
const outcome = await options.runCommand(executable, commandArguments, environment);
|
|
@@ -159046,72 +158981,49 @@ var INSTALLERS = {
|
|
|
159046
158981
|
codex: installFiles(CODEX_CONFIG),
|
|
159047
158982
|
cursor: installFiles(CURSOR_CONFIG)
|
|
159048
158983
|
};
|
|
159049
|
-
var
|
|
158984
|
+
var listFilePaths = async (folderPath) => {
|
|
158985
|
+
const entries = await (0, import_promises4.readdir)(folderPath, { withFileTypes: true });
|
|
158986
|
+
const nested = await Promise.all(
|
|
158987
|
+
entries.map(async (entry) => {
|
|
158988
|
+
const entryPath = (0, import_node_path8.join)(folderPath, entry.name);
|
|
158989
|
+
return entry.isDirectory() ? await listFilePaths(entryPath) : [entryPath];
|
|
158990
|
+
})
|
|
158991
|
+
);
|
|
158992
|
+
return nested.flat();
|
|
158993
|
+
};
|
|
158994
|
+
var readPluginFiles = async (pluginPath) => {
|
|
158995
|
+
const paths = await listFilePaths(pluginPath);
|
|
158996
|
+
return await Promise.all(paths.map(async (path11) => ({ path: (0, import_node_path8.relative)(pluginPath, path11), content: await (0, import_promises4.readFile)(path11, "utf8") })));
|
|
158997
|
+
};
|
|
158998
|
+
var fingerprintOf2 = async (options) => installFingerprintOf(await readPluginFiles(options.pluginPath), options.mcpUrl);
|
|
158999
|
+
var installAndStamp = async (agentInstall, options) => {
|
|
159000
|
+
const installation = await INSTALLERS[agentInstall.agent](agentInstall, options);
|
|
159001
|
+
if (installation.kind === "installed") {
|
|
159002
|
+
await createInstallStampFile(options.dataPath).write(agentInstall.agent, {
|
|
159003
|
+
installPath: agentInstall.installPath,
|
|
159004
|
+
fingerprint: await fingerprintOf2(options)
|
|
159005
|
+
});
|
|
159006
|
+
}
|
|
159007
|
+
return installation;
|
|
159008
|
+
};
|
|
159009
|
+
var createAgentInstaller = (options) => async (agentInstall) => {
|
|
159050
159010
|
try {
|
|
159051
|
-
return await
|
|
159011
|
+
return await installAndStamp(agentInstall, options);
|
|
159052
159012
|
} catch {
|
|
159053
159013
|
return failed(UNWRITABLE_REASON);
|
|
159054
159014
|
}
|
|
159055
159015
|
};
|
|
159056
|
-
|
|
159057
|
-
// apps/backend/src/utils/agent-model-lister/index.ts
|
|
159058
|
-
var import_node_child_process4 = require("node:child_process");
|
|
159059
|
-
|
|
159060
|
-
// apps/backend/src/procedures/deliver-to-agent/utils/claude-launch.ts
|
|
159061
|
-
var FLIGHT_PLAN_TOOLS_RULE = `mcp__plugin_${PLUGIN_NAME}_${MCP_SERVER_NAME}__*`;
|
|
159062
|
-
var PROJECT_MCP_FILE_NAME = ".mcp.json";
|
|
159063
|
-
var isJsonObject2 = (parsed) => typeof parsed === "object" && parsed !== null && !Array.isArray(parsed);
|
|
159064
|
-
var parseJsonObject2 = (text2) => {
|
|
159016
|
+
var createInstallChecker = (options) => async (agentInstall) => {
|
|
159065
159017
|
try {
|
|
159066
|
-
const
|
|
159067
|
-
return
|
|
159018
|
+
const [stamp, fingerprint] = await Promise.all([createInstallStampFile(options.dataPath).read(agentInstall.agent), fingerprintOf2(options)]);
|
|
159019
|
+
return isInstallCurrent(agentInstall, stamp, fingerprint);
|
|
159068
159020
|
} catch {
|
|
159069
|
-
return
|
|
159021
|
+
return false;
|
|
159070
159022
|
}
|
|
159071
159023
|
};
|
|
159072
|
-
|
|
159073
|
-
|
|
159074
|
-
|
|
159075
|
-
};
|
|
159076
|
-
var disabledProjectMcpArguments = (projectMcpServers) => projectMcpServers.length === 0 ? [] : ["--settings", JSON.stringify({ disabledMcpjsonServers: projectMcpServers })];
|
|
159077
|
-
var claudeLaunchArguments = (launch2, spawnPluginPath, projectMcpServers) => [
|
|
159078
|
-
...launch2.isResume ? ["--resume", launch2.sessionId] : ["--session-id", launch2.sessionId],
|
|
159079
|
-
"--plugin-dir",
|
|
159080
|
-
spawnPluginPath,
|
|
159081
|
-
...launch2.model === DEFAULT_MODEL ? [] : ["--model", launch2.model],
|
|
159082
|
-
"--allowedTools",
|
|
159083
|
-
FLIGHT_PLAN_TOOLS_RULE,
|
|
159084
|
-
...disabledProjectMcpArguments(projectMcpServers),
|
|
159085
|
-
"--append-system-prompt",
|
|
159086
|
-
launch2.instructions,
|
|
159087
|
-
launch2.prompt
|
|
159088
|
-
];
|
|
159089
|
-
var PARENT_SESSION_VARIABLES = /* @__PURE__ */ new Set([
|
|
159090
|
-
"CLAUDECODE",
|
|
159091
|
-
"CLAUDE_AGENT_SDK_VERSION",
|
|
159092
|
-
"CLAUDE_CODE_CHILD_SESSION",
|
|
159093
|
-
"CLAUDE_CODE_EMIT_STARTUP_TIMING",
|
|
159094
|
-
"CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING",
|
|
159095
|
-
"CLAUDE_CODE_ENABLE_TASKS",
|
|
159096
|
-
"CLAUDE_CODE_ENTRYPOINT",
|
|
159097
|
-
"CLAUDE_CODE_EXECPATH",
|
|
159098
|
-
"CLAUDE_CODE_MESSAGING_SOCKET",
|
|
159099
|
-
"CLAUDE_CODE_MESSAGING_TOKEN",
|
|
159100
|
-
"CLAUDE_CODE_QUESTION_PREVIEW_FORMAT",
|
|
159101
|
-
"CLAUDE_CODE_SESSION_ATTENDED",
|
|
159102
|
-
"CLAUDE_CODE_SESSION_ID",
|
|
159103
|
-
"CLAUDE_EFFORT",
|
|
159104
|
-
"CLAUDE_PID",
|
|
159105
|
-
"MCP_CONNECTION_NONBLOCKING"
|
|
159106
|
-
]);
|
|
159107
|
-
var FORCE_SESSION_PERSISTENCE = { CLAUDE_CODE_FORCE_SESSION_PERSISTENCE: "1" };
|
|
159108
|
-
var EFFORT_VARIABLE = "CLAUDE_CODE_EFFORT_LEVEL";
|
|
159109
|
-
var withoutParentSession = (environment) => Object.fromEntries(Object.entries(environment).filter(([name]) => !PARENT_SESSION_VARIABLES.has(name)));
|
|
159110
|
-
var spawnEnvironmentOf = (environment, effort) => ({
|
|
159111
|
-
...withoutParentSession(environment),
|
|
159112
|
-
...FORCE_SESSION_PERSISTENCE,
|
|
159113
|
-
...effort === DEFAULT_EFFORT ? {} : { [EFFORT_VARIABLE]: effort }
|
|
159114
|
-
});
|
|
159024
|
+
|
|
159025
|
+
// apps/backend/src/utils/agent-model-lister/index.ts
|
|
159026
|
+
var import_node_child_process4 = require("node:child_process");
|
|
159115
159027
|
|
|
159116
159028
|
// apps/backend/src/procedures/get-setup/utils/claude-model-query.ts
|
|
159117
159029
|
var CLAUDE_MODEL_QUERY_ARGUMENTS = [
|
|
@@ -159158,6 +159070,27 @@ var toListedModel = (reported) => ({
|
|
|
159158
159070
|
});
|
|
159159
159071
|
var parseClaudeModels = (output2) => output2.split(LINE_BREAK20).flatMap(reportedModelsOf).map(toListedModel);
|
|
159160
159072
|
|
|
159073
|
+
// apps/backend/src/utils/agent-model-lister/parent-session.ts
|
|
159074
|
+
var PARENT_SESSION_VARIABLES = /* @__PURE__ */ new Set([
|
|
159075
|
+
"CLAUDECODE",
|
|
159076
|
+
"CLAUDE_AGENT_SDK_VERSION",
|
|
159077
|
+
"CLAUDE_CODE_CHILD_SESSION",
|
|
159078
|
+
"CLAUDE_CODE_EMIT_STARTUP_TIMING",
|
|
159079
|
+
"CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING",
|
|
159080
|
+
"CLAUDE_CODE_ENABLE_TASKS",
|
|
159081
|
+
"CLAUDE_CODE_ENTRYPOINT",
|
|
159082
|
+
"CLAUDE_CODE_EXECPATH",
|
|
159083
|
+
"CLAUDE_CODE_MESSAGING_SOCKET",
|
|
159084
|
+
"CLAUDE_CODE_MESSAGING_TOKEN",
|
|
159085
|
+
"CLAUDE_CODE_QUESTION_PREVIEW_FORMAT",
|
|
159086
|
+
"CLAUDE_CODE_SESSION_ATTENDED",
|
|
159087
|
+
"CLAUDE_CODE_SESSION_ID",
|
|
159088
|
+
"CLAUDE_EFFORT",
|
|
159089
|
+
"CLAUDE_PID",
|
|
159090
|
+
"MCP_CONNECTION_NONBLOCKING"
|
|
159091
|
+
]);
|
|
159092
|
+
var withoutParentSession = (environment) => Object.fromEntries(Object.entries(environment).filter(([name]) => !PARENT_SESSION_VARIABLES.has(name)));
|
|
159093
|
+
|
|
159161
159094
|
// apps/backend/src/utils/agent-model-lister/index.ts
|
|
159162
159095
|
var DEFAULT_TIMEOUT_MS = 15e3;
|
|
159163
159096
|
var NO_MODELS = [];
|
|
@@ -159336,81 +159269,6 @@ var createBranchPuller = ({ runCommand: runCommand3, environment }) => {
|
|
|
159336
159269
|
};
|
|
159337
159270
|
};
|
|
159338
159271
|
|
|
159339
|
-
// apps/backend/src/utils/claude-spawner/index.ts
|
|
159340
|
-
var import_promises5 = require("node:fs/promises");
|
|
159341
|
-
var import_node_path9 = require("node:path");
|
|
159342
|
-
var import_node_util8 = require("node:util");
|
|
159343
|
-
var import_node_pty = require("node-pty");
|
|
159344
|
-
var TERMINAL_NAME = "xterm-256color";
|
|
159345
|
-
var TERMINAL_COLUMNS = 120;
|
|
159346
|
-
var TERMINAL_ROWS = 40;
|
|
159347
|
-
var OUTPUT_TAIL_LENGTH = 2e4;
|
|
159348
|
-
var CLAUDE_MISSING_REASON2 = "The claude command was not found on this machine.";
|
|
159349
|
-
var EXIT_COMMAND = "/exit\r";
|
|
159350
|
-
var DEFAULT_EXIT_GRACE_MS = 5e3;
|
|
159351
|
-
var failed3 = (reason) => ({ kind: "failed", reason });
|
|
159352
|
-
var definedEntries = (environment) => Object.fromEntries(
|
|
159353
|
-
Object.entries(environment).filter((entry) => entry[1] !== void 0)
|
|
159354
|
-
);
|
|
159355
|
-
var OutputTail = class {
|
|
159356
|
-
text = "";
|
|
159357
|
-
add = (chunk) => {
|
|
159358
|
-
this.text = `${this.text}${chunk}`.slice(-OUTPUT_TAIL_LENGTH);
|
|
159359
|
-
};
|
|
159360
|
-
read = () => (0, import_node_util8.stripVTControlCharacters)(this.text);
|
|
159361
|
-
};
|
|
159362
|
-
var TerminalProcess = class {
|
|
159363
|
-
terminal;
|
|
159364
|
-
output;
|
|
159365
|
-
exitGraceMs;
|
|
159366
|
-
hasExited = false;
|
|
159367
|
-
constructor(terminal, output2, exitGraceMs) {
|
|
159368
|
-
this.terminal = terminal;
|
|
159369
|
-
this.output = output2;
|
|
159370
|
-
this.exitGraceMs = exitGraceMs;
|
|
159371
|
-
terminal.onExit(() => {
|
|
159372
|
-
this.hasExited = true;
|
|
159373
|
-
});
|
|
159374
|
-
}
|
|
159375
|
-
stop = () => {
|
|
159376
|
-
if (this.hasExited) return;
|
|
159377
|
-
this.terminal.write(EXIT_COMMAND);
|
|
159378
|
-
setTimeout(() => {
|
|
159379
|
-
if (!this.hasExited) this.terminal.kill();
|
|
159380
|
-
}, this.exitGraceMs).unref();
|
|
159381
|
-
};
|
|
159382
|
-
readOutput = () => this.output.read();
|
|
159383
|
-
};
|
|
159384
|
-
var readProjectMcpFile = async (workingPath) => await (0, import_promises5.readFile)((0, import_node_path9.join)(workingPath, PROJECT_MCP_FILE_NAME), "utf8").catch(() => null);
|
|
159385
|
-
var startReason = (error61) => error61 instanceof Error ? `Claude could not be started: ${error61.message}` : "Claude could not be started.";
|
|
159386
|
-
var createClaudeSpawner = (options) => {
|
|
159387
|
-
const findExecutable = createExecutableFinder(options);
|
|
159388
|
-
return async (launch2, onExit) => {
|
|
159389
|
-
const executable = await findExecutable(AGENT_CLI_NAMES.claude);
|
|
159390
|
-
if (executable === null) return failed3(CLAUDE_MISSING_REASON2);
|
|
159391
|
-
const environment = claudeCommandEnvironment(launch2.installPath, options.homePath, spawnEnvironmentOf(options.environment, launch2.effort));
|
|
159392
|
-
const projectMcpServers = projectMcpServerNames(await readProjectMcpFile(launch2.workingPath));
|
|
159393
|
-
try {
|
|
159394
|
-
const launchArguments = claudeLaunchArguments(launch2, options.spawnPluginPath, projectMcpServers);
|
|
159395
|
-
const terminal = (0, import_node_pty.spawn)(executable, [...launchArguments], {
|
|
159396
|
-
name: TERMINAL_NAME,
|
|
159397
|
-
cols: TERMINAL_COLUMNS,
|
|
159398
|
-
rows: TERMINAL_ROWS,
|
|
159399
|
-
cwd: launch2.workingPath,
|
|
159400
|
-
env: definedEntries(environment)
|
|
159401
|
-
});
|
|
159402
|
-
const output2 = new OutputTail();
|
|
159403
|
-
terminal.onData(output2.add);
|
|
159404
|
-
terminal.onExit(({ exitCode }) => {
|
|
159405
|
-
onExit({ exitCode });
|
|
159406
|
-
});
|
|
159407
|
-
return { kind: "started", process: new TerminalProcess(terminal, output2, options.exitGraceMs ?? DEFAULT_EXIT_GRACE_MS) };
|
|
159408
|
-
} catch (error61) {
|
|
159409
|
-
return failed3(startReason(error61));
|
|
159410
|
-
}
|
|
159411
|
-
};
|
|
159412
|
-
};
|
|
159413
|
-
|
|
159414
159272
|
// node_modules/.pnpm/@code-hike+lighter@1.0.1/node_modules/@code-hike/lighter/dist/index.esm.mjs
|
|
159415
159273
|
async function A3(A4) {
|
|
159416
159274
|
return (async function(A5) {
|
|
@@ -162630,8 +162488,8 @@ var createCommitAuthorReader = (options) => async (repositoryPath) => {
|
|
|
162630
162488
|
};
|
|
162631
162489
|
|
|
162632
162490
|
// apps/backend/src/utils/configuration-file-store/index.ts
|
|
162633
|
-
var
|
|
162634
|
-
var
|
|
162491
|
+
var import_promises5 = require("node:fs/promises");
|
|
162492
|
+
var import_node_path9 = require("node:path");
|
|
162635
162493
|
|
|
162636
162494
|
// apps/backend/src/procedures/list-configurations/utils/stored-configuration.ts
|
|
162637
162495
|
var CONFIGURATION_FILE_NAME = "configuration.json";
|
|
@@ -162701,7 +162559,7 @@ var MISSING_FOLDER_CODE = "ENOENT";
|
|
|
162701
162559
|
var isMissingFolder = (error61) => error61 instanceof Error && "code" in error61 && error61.code === MISSING_FOLDER_CODE;
|
|
162702
162560
|
var readFolderNames2 = async (path11) => {
|
|
162703
162561
|
try {
|
|
162704
|
-
const entries = await (0,
|
|
162562
|
+
const entries = await (0, import_promises5.readdir)(path11, { withFileTypes: true });
|
|
162705
162563
|
return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
162706
162564
|
} catch (error61) {
|
|
162707
162565
|
if (isMissingFolder(error61)) return [];
|
|
@@ -162709,16 +162567,16 @@ var readFolderNames2 = async (path11) => {
|
|
|
162709
162567
|
}
|
|
162710
162568
|
};
|
|
162711
162569
|
var readConfigurationFiles = async (folderPath) => {
|
|
162712
|
-
const entries = await (0,
|
|
162570
|
+
const entries = await (0, import_promises5.readdir)(folderPath, { withFileTypes: true });
|
|
162713
162571
|
const fileNames = entries.filter((entry) => entry.isFile() && isStoredFileName(entry.name)).map((entry) => entry.name);
|
|
162714
162572
|
return new Map(
|
|
162715
|
-
await Promise.all(fileNames.map(async (fileName) => [fileName, await (0,
|
|
162573
|
+
await Promise.all(fileNames.map(async (fileName) => [fileName, await (0, import_promises5.readFile)((0, import_node_path9.join)(folderPath, fileName), "utf8")]))
|
|
162716
162574
|
);
|
|
162717
162575
|
};
|
|
162718
162576
|
var FileConfigurationStore = class {
|
|
162719
162577
|
rootPath;
|
|
162720
162578
|
constructor(dataPath) {
|
|
162721
|
-
this.rootPath = (0,
|
|
162579
|
+
this.rootPath = (0, import_node_path9.join)(dataPath, CONFIGURATIONS_FOLDER_NAME);
|
|
162722
162580
|
}
|
|
162723
162581
|
read = async () => storedConfigurationsOf(await this.readFolders());
|
|
162724
162582
|
write = async (configurations2) => {
|
|
@@ -162730,21 +162588,21 @@ var FileConfigurationStore = class {
|
|
|
162730
162588
|
await removeFile(this.pathOf(file2));
|
|
162731
162589
|
}));
|
|
162732
162590
|
await Promise.all(changes.removedFolders.map(async (folder) => {
|
|
162733
|
-
await (0,
|
|
162591
|
+
await (0, import_promises5.rm)((0, import_node_path9.join)(this.rootPath, folder), { recursive: true, force: true });
|
|
162734
162592
|
}));
|
|
162735
162593
|
};
|
|
162736
162594
|
readFolders = async () => {
|
|
162737
162595
|
const folders = await readFolderNames2(this.rootPath);
|
|
162738
162596
|
return new Map(
|
|
162739
|
-
await Promise.all(folders.map(async (folder) => [folder, await readConfigurationFiles((0,
|
|
162597
|
+
await Promise.all(folders.map(async (folder) => [folder, await readConfigurationFiles((0, import_node_path9.join)(this.rootPath, folder))]))
|
|
162740
162598
|
);
|
|
162741
162599
|
};
|
|
162742
|
-
pathOf = (file2) => (0,
|
|
162600
|
+
pathOf = (file2) => (0, import_node_path9.join)(this.rootPath, file2.folder, file2.fileName);
|
|
162743
162601
|
};
|
|
162744
162602
|
|
|
162745
162603
|
// apps/backend/src/utils/conversation-file-store/index.ts
|
|
162746
|
-
var
|
|
162747
|
-
var
|
|
162604
|
+
var import_promises6 = require("node:fs/promises");
|
|
162605
|
+
var import_node_path10 = require("node:path");
|
|
162748
162606
|
|
|
162749
162607
|
// apps/backend/src/procedures/get-conversation/utils/stored-conversation.ts
|
|
162750
162608
|
var JSON_INDENT6 = 2;
|
|
@@ -162841,7 +162699,7 @@ var toFileName = (name) => {
|
|
|
162841
162699
|
var fromFileName = (fileName) => decodeURIComponent(fileName);
|
|
162842
162700
|
var readFolderNames3 = async (path11) => {
|
|
162843
162701
|
try {
|
|
162844
|
-
return await (0,
|
|
162702
|
+
return await (0, import_promises6.readdir)(path11);
|
|
162845
162703
|
} catch {
|
|
162846
162704
|
return [];
|
|
162847
162705
|
}
|
|
@@ -162850,7 +162708,7 @@ var FileConversationStore = class {
|
|
|
162850
162708
|
rootPath;
|
|
162851
162709
|
writes = /* @__PURE__ */ new Map();
|
|
162852
162710
|
constructor(dataPath) {
|
|
162853
|
-
this.rootPath = (0,
|
|
162711
|
+
this.rootPath = (0, import_node_path10.join)(dataPath, CONVERSATIONS_FOLDER_NAME);
|
|
162854
162712
|
}
|
|
162855
162713
|
read = async (key) => await this.readPath(this.pathOf(key));
|
|
162856
162714
|
append = async (key, events) => await this.queue(key, async () => {
|
|
@@ -162873,7 +162731,7 @@ var FileConversationStore = class {
|
|
|
162873
162731
|
const repositoryFolders = await readFolderNames3(this.rootPath);
|
|
162874
162732
|
const nested = await Promise.all(
|
|
162875
162733
|
repositoryFolders.map(async (folder) => {
|
|
162876
|
-
const fileNames = await readFolderNames3((0,
|
|
162734
|
+
const fileNames = await readFolderNames3((0, import_node_path10.join)(this.rootPath, folder));
|
|
162877
162735
|
return fileNames.filter((fileName) => fileName.endsWith(FILE_EXTENSION)).map((fileName) => ({
|
|
162878
162736
|
repositoryName: fromFileName(folder),
|
|
162879
162737
|
targetId: fromFileName(fileName.slice(0, -FILE_EXTENSION.length))
|
|
@@ -162889,7 +162747,7 @@ var FileConversationStore = class {
|
|
|
162889
162747
|
if (conversation === null) throw new Error(UNREADABLE_MESSAGE2);
|
|
162890
162748
|
return conversation;
|
|
162891
162749
|
};
|
|
162892
|
-
pathOf = (key) => (0,
|
|
162750
|
+
pathOf = (key) => (0, import_node_path10.join)(this.rootPath, toFileName(key.repositoryName), `${toFileName(key.targetId)}${FILE_EXTENSION}`);
|
|
162893
162751
|
queue = async (key, task) => {
|
|
162894
162752
|
const id = reviewKeyId(key);
|
|
162895
162753
|
const previous = this.writes.get(id) ?? Promise.resolve();
|
|
@@ -163099,11 +162957,11 @@ var createGitIdentityReader = (options) => {
|
|
|
163099
162957
|
};
|
|
163100
162958
|
|
|
163101
162959
|
// apps/backend/src/utils/import-file-store/index.ts
|
|
163102
|
-
var
|
|
162960
|
+
var import_node_path11 = require("node:path");
|
|
163103
162961
|
var IMPORTS_FOLDER_NAME = "imports";
|
|
163104
162962
|
var FILE_EXTENSION2 = ".json";
|
|
163105
162963
|
var createImportFileStore = (dataPath) => {
|
|
163106
|
-
const pathOf2 = (key) => (0,
|
|
162964
|
+
const pathOf2 = (key) => (0, import_node_path11.join)(dataPath, IMPORTS_FOLDER_NAME, toFileName(key.repositoryName), `${toFileName(key.targetId)}${FILE_EXTENSION2}`);
|
|
163107
162965
|
return {
|
|
163108
162966
|
pathOf: pathOf2,
|
|
163109
162967
|
read: async (key) => await readTextOrNull(pathOf2(key)),
|
|
@@ -163114,30 +162972,30 @@ var createImportFileStore = (dataPath) => {
|
|
|
163114
162972
|
};
|
|
163115
162973
|
|
|
163116
162974
|
// apps/backend/src/utils/instruction-file-reader/index.ts
|
|
163117
|
-
var
|
|
163118
|
-
var
|
|
162975
|
+
var import_promises7 = require("node:fs/promises");
|
|
162976
|
+
var import_node_path12 = require("node:path");
|
|
163119
162977
|
var INSTRUCTION_FILE_EXTENSION3 = ".md";
|
|
163120
162978
|
var readFolderTexts = async (folderPath) => {
|
|
163121
|
-
const fileNames = (await (0,
|
|
162979
|
+
const fileNames = (await (0, import_promises7.readdir)(folderPath)).filter((name) => name.endsWith(INSTRUCTION_FILE_EXTENSION3));
|
|
163122
162980
|
const entries = await Promise.all(
|
|
163123
162981
|
fileNames.map(async (name) => [
|
|
163124
162982
|
name.slice(0, -INSTRUCTION_FILE_EXTENSION3.length),
|
|
163125
|
-
await (0,
|
|
162983
|
+
await (0, import_promises7.readFile)((0, import_node_path12.join)(folderPath, name), "utf8")
|
|
163126
162984
|
])
|
|
163127
162985
|
);
|
|
163128
162986
|
return new Map(entries);
|
|
163129
162987
|
};
|
|
163130
162988
|
var readPresetTexts = async (presetsPath) => {
|
|
163131
|
-
const folders = (await (0,
|
|
162989
|
+
const folders = (await (0, import_promises7.readdir)(presetsPath, { withFileTypes: true })).filter((entry) => entry.isDirectory());
|
|
163132
162990
|
const entries = await Promise.all(
|
|
163133
|
-
folders.map(async (folder) => [folder.name, await readFolderTexts((0,
|
|
162991
|
+
folders.map(async (folder) => [folder.name, await readFolderTexts((0, import_node_path12.join)(presetsPath, folder.name))])
|
|
163134
162992
|
);
|
|
163135
162993
|
return new Map(entries);
|
|
163136
162994
|
};
|
|
163137
162995
|
var readInstructionTexts = async (configurationsPath) => {
|
|
163138
162996
|
const [system, presets] = await Promise.all([
|
|
163139
|
-
readFolderTexts((0,
|
|
163140
|
-
readPresetTexts((0,
|
|
162997
|
+
readFolderTexts((0, import_node_path12.join)(configurationsPath, SYSTEM_INSTRUCTIONS_FOLDER)),
|
|
162998
|
+
readPresetTexts((0, import_node_path12.join)(configurationsPath, DEFAULT_CONFIGURATIONS_FOLDER))
|
|
163141
162999
|
]);
|
|
163142
163000
|
return { system, presets };
|
|
163143
163001
|
};
|
|
@@ -163354,21 +163212,21 @@ var RegistryReader = class {
|
|
|
163354
163212
|
var createLatestVersionReader = (request) => new RegistryReader(request).read;
|
|
163355
163213
|
|
|
163356
163214
|
// apps/backend/src/utils/published-page-writer/index.ts
|
|
163357
|
-
var
|
|
163358
|
-
var
|
|
163215
|
+
var import_promises8 = require("node:fs/promises");
|
|
163216
|
+
var import_node_path13 = require("node:path");
|
|
163359
163217
|
var PUBLICATIONS_FOLDER_NAME = "publications";
|
|
163360
163218
|
var createPublishedPageWriter = ({ bundlePath, dataPath }) => async (key, texts) => {
|
|
163361
163219
|
const bundleFileNames = await readFolderNames3(bundlePath);
|
|
163362
163220
|
if (bundleFileNames.length === 0) return null;
|
|
163363
|
-
const folderPath = (0,
|
|
163364
|
-
await (0,
|
|
163221
|
+
const folderPath = (0, import_node_path13.join)(dataPath, PUBLICATIONS_FOLDER_NAME, toFileName(key.repositoryName), toFileName(key.targetId));
|
|
163222
|
+
await (0, import_promises8.mkdir)(folderPath, { recursive: true });
|
|
163365
163223
|
await Promise.all([
|
|
163366
163224
|
...bundleFileNames.map(async (fileName) => {
|
|
163367
|
-
await (0,
|
|
163225
|
+
await (0, import_promises8.copyFile)((0, import_node_path13.join)(bundlePath, fileName), (0, import_node_path13.join)(folderPath, fileName));
|
|
163368
163226
|
}),
|
|
163369
|
-
writeText((0,
|
|
163370
|
-
writeText((0,
|
|
163371
|
-
texts.flightPlanFile === null ? removeFile((0,
|
|
163227
|
+
writeText((0, import_node_path13.join)(folderPath, PAGE_FILE_NAME), texts.html),
|
|
163228
|
+
writeText((0, import_node_path13.join)(folderPath, REVIEW_SCRIPT_FILE_NAME), texts.reviewScript),
|
|
163229
|
+
texts.flightPlanFile === null ? removeFile((0, import_node_path13.join)(folderPath, FLIGHT_PLAN_FILE_NAME)) : writeText((0, import_node_path13.join)(folderPath, FLIGHT_PLAN_FILE_NAME), texts.flightPlanFile)
|
|
163372
163230
|
]);
|
|
163373
163231
|
return {
|
|
163374
163232
|
folderPath,
|
|
@@ -163582,8 +163440,8 @@ var createRepositoryActivityReader = (options) => {
|
|
|
163582
163440
|
};
|
|
163583
163441
|
|
|
163584
163442
|
// apps/backend/src/utils/repository-folder-finder/index.ts
|
|
163585
|
-
var
|
|
163586
|
-
var
|
|
163443
|
+
var import_promises9 = require("node:fs/promises");
|
|
163444
|
+
var import_node_path14 = require("node:path");
|
|
163587
163445
|
var MAX_SCAN_DEPTH = 6;
|
|
163588
163446
|
var REPOSITORY_CACHE_MS = 6e4;
|
|
163589
163447
|
var HIDDEN_FOLDER_PREFIX = ".";
|
|
@@ -163591,7 +163449,7 @@ var SKIPPED_FOLDER_NAMES = /* @__PURE__ */ new Set(["node_modules", "Library", "
|
|
|
163591
163449
|
var isScannableFolderName = (name) => !name.startsWith(HIDDEN_FOLDER_PREFIX) && !SKIPPED_FOLDER_NAMES.has(name);
|
|
163592
163450
|
var readSubfolderNames = async (path11) => {
|
|
163593
163451
|
try {
|
|
163594
|
-
const entries = await (0,
|
|
163452
|
+
const entries = await (0, import_promises9.readdir)(path11, { withFileTypes: true });
|
|
163595
163453
|
return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
163596
163454
|
} catch {
|
|
163597
163455
|
return [];
|
|
@@ -163600,7 +163458,7 @@ var readSubfolderNames = async (path11) => {
|
|
|
163600
163458
|
var findRepositoriesBelow = async (folderPath, depthLeft) => {
|
|
163601
163459
|
if (depthLeft === 0) return [];
|
|
163602
163460
|
const subfolderNames = await readSubfolderNames(folderPath);
|
|
163603
|
-
const subfolderPaths = subfolderNames.filter(isScannableFolderName).map((name) => (0,
|
|
163461
|
+
const subfolderPaths = subfolderNames.filter(isScannableFolderName).map((name) => (0, import_node_path14.join)(folderPath, name));
|
|
163604
163462
|
const repositoryPathsBySubfolder = await Promise.all(
|
|
163605
163463
|
subfolderPaths.map(async (subfolderPath) => await isRepositoryFolder(subfolderPath) ? [subfolderPath] : await findRepositoriesBelow(subfolderPath, depthLeft - 1))
|
|
163606
163464
|
);
|
|
@@ -163751,7 +163609,7 @@ var RepositoryInspector = class {
|
|
|
163751
163609
|
};
|
|
163752
163610
|
|
|
163753
163611
|
// apps/backend/src/utils/review-file-store/index.ts
|
|
163754
|
-
var
|
|
163612
|
+
var import_node_path15 = require("node:path");
|
|
163755
163613
|
|
|
163756
163614
|
// apps/backend/src/procedures/list-repositories/utils/schemas.ts
|
|
163757
163615
|
var LABEL_SEGMENT_KINDS = ["plain", "code"];
|
|
@@ -163937,17 +163795,7 @@ var staleNoticeSchema = external_exports.strictObject({
|
|
|
163937
163795
|
prompt: external_exports.string(),
|
|
163938
163796
|
copiedMessage: external_exports.string()
|
|
163939
163797
|
});
|
|
163940
|
-
var PROGRESS_STATES = ["writing", "waiting"
|
|
163941
|
-
var permissionRequestSchema = external_exports.strictObject({
|
|
163942
|
-
batchId: external_exports.string(),
|
|
163943
|
-
questionId: external_exports.string(),
|
|
163944
|
-
title: external_exports.string(),
|
|
163945
|
-
description: external_exports.string(),
|
|
163946
|
-
detail: external_exports.string().nullable(),
|
|
163947
|
-
allowLabel: external_exports.string(),
|
|
163948
|
-
denyLabel: external_exports.string(),
|
|
163949
|
-
reasonLabel: external_exports.string()
|
|
163950
|
-
});
|
|
163798
|
+
var PROGRESS_STATES = ["writing", "waiting"];
|
|
163951
163799
|
var reviewProgressSchema = external_exports.strictObject({
|
|
163952
163800
|
state: external_exports.enum(PROGRESS_STATES),
|
|
163953
163801
|
label: external_exports.string(),
|
|
@@ -163956,8 +163804,7 @@ var reviewProgressSchema = external_exports.strictObject({
|
|
|
163956
163804
|
countLabel: external_exports.string(),
|
|
163957
163805
|
writtenCount: external_exports.number().int(),
|
|
163958
163806
|
totalCount: external_exports.number().int(),
|
|
163959
|
-
prompt: external_exports.strictObject({ label: external_exports.string(), text: external_exports.string(), copiedMessage: external_exports.string() }).nullable()
|
|
163960
|
-
permission: permissionRequestSchema.nullable()
|
|
163807
|
+
prompt: external_exports.strictObject({ label: external_exports.string(), text: external_exports.string(), copiedMessage: external_exports.string() }).nullable()
|
|
163961
163808
|
});
|
|
163962
163809
|
var completionNoticeSchema = external_exports.strictObject({ title: external_exports.string(), body: external_exports.string() });
|
|
163963
163810
|
var railSectionSchema = external_exports.strictObject({
|
|
@@ -164235,13 +164082,13 @@ var FileReviewStore = class {
|
|
|
164235
164082
|
sampleStore;
|
|
164236
164083
|
amendTurns = /* @__PURE__ */ new Map();
|
|
164237
164084
|
constructor(dataPath, sampleStore) {
|
|
164238
|
-
this.rootPath = (0,
|
|
164085
|
+
this.rootPath = (0, import_node_path15.join)(dataPath, REVIEWS_FOLDER_NAME);
|
|
164239
164086
|
this.sampleStore = sampleStore;
|
|
164240
164087
|
}
|
|
164241
164088
|
findArtifact = async (key) => (await this.readStored(key))?.artifact ?? await this.sampleStore.findArtifact(key);
|
|
164242
164089
|
listTargetIds = async (repositoryName) => {
|
|
164243
164090
|
const [fileNames, sampleTargetIds] = await Promise.all([
|
|
164244
|
-
readFolderNames3((0,
|
|
164091
|
+
readFolderNames3((0, import_node_path15.join)(this.rootPath, toFileName(repositoryName))),
|
|
164245
164092
|
this.sampleStore.listTargetIds(repositoryName)
|
|
164246
164093
|
]);
|
|
164247
164094
|
const savedTargetIds = fileNames.filter((fileName) => fileName.endsWith(FILE_EXTENSION3)).map((fileName) => fromFileName(fileName.slice(0, -FILE_EXTENSION3.length)));
|
|
@@ -164331,7 +164178,7 @@ var FileReviewStore = class {
|
|
|
164331
164178
|
await removeFile(this.filePathOf(from, extension));
|
|
164332
164179
|
};
|
|
164333
164180
|
pathOf = (key) => this.filePathOf(key, FILE_EXTENSION3);
|
|
164334
|
-
filePathOf = (key, extension) => (0,
|
|
164181
|
+
filePathOf = (key, extension) => (0, import_node_path15.join)(this.rootPath, toFileName(key.repositoryName), `${toFileName(key.targetId)}${extension}`);
|
|
164335
164182
|
};
|
|
164336
164183
|
|
|
164337
164184
|
// apps/backend/src/utils/run-command/index.ts
|
|
@@ -164350,7 +164197,7 @@ var runCommand = async (executable, commandArguments, environment) => await new
|
|
|
164350
164197
|
});
|
|
164351
164198
|
|
|
164352
164199
|
// apps/backend/src/utils/setup-file-store/index.ts
|
|
164353
|
-
var
|
|
164200
|
+
var import_node_path16 = require("node:path");
|
|
164354
164201
|
|
|
164355
164202
|
// apps/backend/src/procedures/get-review-preferences/utils/schemas.ts
|
|
164356
164203
|
var writeUpTimingSchema = external_exports.enum(WRITE_UP_TIMINGS);
|
|
@@ -164472,7 +164319,7 @@ var UNREADABLE_MESSAGE4 = "The saved settings cannot be read.";
|
|
|
164472
164319
|
var FileSetupStore = class {
|
|
164473
164320
|
settingsPath;
|
|
164474
164321
|
constructor(dataPath) {
|
|
164475
|
-
this.settingsPath = (0,
|
|
164322
|
+
this.settingsPath = (0, import_node_path16.join)(dataPath, ...SETTINGS_PATH);
|
|
164476
164323
|
}
|
|
164477
164324
|
read = async () => {
|
|
164478
164325
|
const setup = parseSettings(await readTextOrNull(this.settingsPath));
|
|
@@ -164485,7 +164332,7 @@ var FileSetupStore = class {
|
|
|
164485
164332
|
};
|
|
164486
164333
|
|
|
164487
164334
|
// apps/backend/src/utils/target-memory-file-store/index.ts
|
|
164488
|
-
var
|
|
164335
|
+
var import_node_path17 = require("node:path");
|
|
164489
164336
|
var MEMORY_FILE_NAME = "targets.json";
|
|
164490
164337
|
var UNSAFE_NAME_PATTERN = /^\.{1,2}$|[\\/\0]/;
|
|
164491
164338
|
var isSafeName = (repositoryName) => repositoryName !== "" && !UNSAFE_NAME_PATTERN.test(repositoryName);
|
|
@@ -164514,11 +164361,28 @@ var FileTargetMemoryStore = class {
|
|
|
164514
164361
|
const memory2 = await this.ensure(repositoryName, now);
|
|
164515
164362
|
await writeText(this.pathOf(repositoryName), formatTargetMemory(withAddedTarget(memory2, target)));
|
|
164516
164363
|
};
|
|
164517
|
-
pathOf = (repositoryName) => (0,
|
|
164364
|
+
pathOf = (repositoryName) => (0, import_node_path17.join)(this.dataPath, repositoryName, MEMORY_FILE_NAME);
|
|
164518
164365
|
};
|
|
164519
164366
|
|
|
164367
|
+
// apps/backend/src/utils/terminal-opener/index.ts
|
|
164368
|
+
var MAC = "darwin";
|
|
164369
|
+
var APPLE_SCRIPT_EXECUTABLE = "osascript";
|
|
164370
|
+
var SUCCESS_EXIT_CODE9 = 0;
|
|
164371
|
+
var NO_REASON = "macOS gave no reason.";
|
|
164372
|
+
var appleScriptStringOf = (text2) => `"${text2.replaceAll("\\", "\\\\").replaceAll('"', '\\"')}"`;
|
|
164373
|
+
var terminalScriptArgumentsOf = (command) => [
|
|
164374
|
+
"-e",
|
|
164375
|
+
'tell application "Terminal" to activate',
|
|
164376
|
+
"-e",
|
|
164377
|
+
`tell application "Terminal" to do script ${appleScriptStringOf(command)}`
|
|
164378
|
+
];
|
|
164379
|
+
var createTerminalOpener = (options) => options.platform === MAC ? async (command) => {
|
|
164380
|
+
const outcome = await options.runCommand(APPLE_SCRIPT_EXECUTABLE, terminalScriptArgumentsOf(command), options.environment);
|
|
164381
|
+
return outcome.exitCode === SUCCESS_EXIT_CODE9 ? { kind: "opened" } : { kind: "failed", reason: outcome.errorOutput.trim() === "" ? NO_REASON : outcome.errorOutput.trim() };
|
|
164382
|
+
} : null;
|
|
164383
|
+
|
|
164520
164384
|
// apps/backend/src/utils/update-check-file/index.ts
|
|
164521
|
-
var
|
|
164385
|
+
var import_node_path18 = require("node:path");
|
|
164522
164386
|
|
|
164523
164387
|
// apps/backend/src/procedures/get-update-notice/utils/schemas.ts
|
|
164524
164388
|
var updateCheckSchema = external_exports.strictObject({
|
|
@@ -164554,7 +164418,7 @@ var parseUpdateCheck = (text2) => {
|
|
|
164554
164418
|
var readNothing = () => null;
|
|
164555
164419
|
var ignoreFailure = () => void 0;
|
|
164556
164420
|
var createUpdateCheckFile = (dataPath) => {
|
|
164557
|
-
const filePath = (0,
|
|
164421
|
+
const filePath = (0, import_node_path18.join)(dataPath, FILE_NAME);
|
|
164558
164422
|
return {
|
|
164559
164423
|
read: async () => parseUpdateCheck(await readTextOrNull(filePath).catch(readNothing)),
|
|
164560
164424
|
write: async (check2) => {
|
|
@@ -164567,15 +164431,12 @@ var createUpdateCheckFile = (dataPath) => {
|
|
|
164567
164431
|
// apps/backend/src/procedures/context.ts
|
|
164568
164432
|
var MOCK_SERVER_URL = "http://localhost:3000";
|
|
164569
164433
|
var MOCK_APP_URL = "http://localhost:4200";
|
|
164570
|
-
var NO_SPAWNERS = {};
|
|
164571
164434
|
var createConversationEnvironment = (overrides = {}) => ({
|
|
164572
164435
|
store: new InMemoryConversationStore(),
|
|
164573
164436
|
hub: createConversationHub(),
|
|
164574
|
-
|
|
164575
|
-
writeUpQueue: new InMemoryWriteUpQueue(),
|
|
164576
|
-
spawners: NO_SPAWNERS,
|
|
164437
|
+
presence: new InMemoryAgentPresenceRegistry(),
|
|
164577
164438
|
serverUrl: MOCK_SERVER_URL,
|
|
164578
|
-
newId:
|
|
164439
|
+
newId: import_node_crypto5.randomUUID,
|
|
164579
164440
|
...overrides
|
|
164580
164441
|
});
|
|
164581
164442
|
var SAMPLE_REPOSITORY_MESSAGE = "This is a sample repository, so there is no code to read.";
|
|
@@ -164601,6 +164462,7 @@ var createMockProcedureContext = (startedAt) => ({
|
|
|
164601
164462
|
readInstructionTexts: readSampleInstructionTexts,
|
|
164602
164463
|
writePublishedPage: writeSamplePublishedPage,
|
|
164603
164464
|
importFiles: new InMemoryImportFileStore(),
|
|
164465
|
+
openTerminal: null,
|
|
164604
164466
|
appUrl: MOCK_APP_URL,
|
|
164605
164467
|
now: () => /* @__PURE__ */ new Date(),
|
|
164606
164468
|
dataNotice: SAMPLE_DATA_NOTICE
|
|
@@ -164637,13 +164499,13 @@ var createLocalProcedureContext = (startedAt, machine) => {
|
|
|
164637
164499
|
readInstructionTexts: new InstructionFileReader(machine.configurationsPath).read,
|
|
164638
164500
|
writePublishedPage: createPublishedPageWriter({ bundlePath: machine.publishedBundlePath, dataPath: machine.dataPath }),
|
|
164639
164501
|
importFiles: createImportFileStore(machine.dataPath),
|
|
164502
|
+
openTerminal: createTerminalOpener({ platform: machine.platform, runCommand, environment: machine.environment }),
|
|
164640
164503
|
appUrl: machine.appUrl,
|
|
164641
164504
|
changeReader: createGitChangeReader({ runCommand, environment: machine.environment }),
|
|
164642
164505
|
pullBranch: createBranchPuller({ runCommand, environment: machine.environment }),
|
|
164643
164506
|
openRepository,
|
|
164644
164507
|
conversationEnvironment: createConversationEnvironment({
|
|
164645
164508
|
store: new FileConversationStore(machine.dataPath),
|
|
164646
|
-
spawners: { claude: createClaudeSpawner({ ...machine, spawnPluginPath: spawnPluginPathOf(machine.dataPath) }) },
|
|
164647
164509
|
serverUrl: machine.serverUrl
|
|
164648
164510
|
}),
|
|
164649
164511
|
repositoryStore: new LiveRepositoryStore({
|
|
@@ -164659,6 +164521,7 @@ var createLocalProcedureContext = (startedAt, machine) => {
|
|
|
164659
164521
|
hasAgentCli: createAgentCliProbe(machine),
|
|
164660
164522
|
listAgentModels: createAgentModelLister(machine),
|
|
164661
164523
|
installAgent: createAgentInstaller({ ...machine, runCommand }),
|
|
164524
|
+
isAgentInstallCurrent: createInstallChecker({ ...machine, runCommand }),
|
|
164662
164525
|
probeForgeClis: createForgeCliProbe({ ...machine, runCommand }),
|
|
164663
164526
|
saveForgeCredential: createForgeCredentialSaver(saveInKeychain),
|
|
164664
164527
|
...createAuthorLookup({
|
|
@@ -164747,7 +164610,9 @@ var getUpdateNotice = async (_input, context) => {
|
|
|
164747
164610
|
// apps/backend/src/procedures/refresh-agent-installs/index.ts
|
|
164748
164611
|
var refreshAgentInstalls = async (context) => {
|
|
164749
164612
|
const setup = await context.setupStore.read();
|
|
164750
|
-
const
|
|
164613
|
+
const saved = setup.agents?.installs ?? [];
|
|
164614
|
+
const currents = await Promise.all(saved.map(async (install) => await context.setupEnvironment.isAgentInstallCurrent(install)));
|
|
164615
|
+
const installs = saved.filter((_install, position) => !currents[position]);
|
|
164751
164616
|
const attempts = await Promise.all(
|
|
164752
164617
|
installs.map(async (install) => ({ install, installation: await context.setupEnvironment.installAgent(install) }))
|
|
164753
164618
|
);
|
|
@@ -164760,314 +164625,9 @@ var refreshAgentInstalls = async (context) => {
|
|
|
164760
164625
|
var import_sensible = __toESM(require_sensible());
|
|
164761
164626
|
var import_fastify4 = __toESM(require_fastify());
|
|
164762
164627
|
|
|
164763
|
-
// apps/backend/src/procedures/close-all-agents/index.ts
|
|
164764
|
-
var closeAllAgents = (context) => context.conversationEnvironment.agents.list().filter((agent) => closeAgent(agent.key, "shutdown", context)).length;
|
|
164765
|
-
|
|
164766
|
-
// apps/backend/src/procedures/deliver-to-agent/utils/agent-problems.ts
|
|
164767
|
-
var SCREEN_EXCERPT_LENGTH = 600;
|
|
164768
|
-
var MS_PER_SECOND2 = 1e3;
|
|
164769
|
-
var WHITESPACE_PATTERN3 = /\s+/g;
|
|
164770
|
-
var screenExcerptOf = (output2) => output2.replace(WHITESPACE_PATTERN3, " ").trim().slice(-SCREEN_EXCERPT_LENGTH);
|
|
164771
|
-
var withScreen = (sentence, output2) => {
|
|
164772
|
-
const excerpt = screenExcerptOf(output2);
|
|
164773
|
-
return excerpt === "" ? sentence : `${sentence} Its terminal last showed: ${excerpt}`;
|
|
164774
|
-
};
|
|
164775
|
-
var unexpectedExitReason = (agent, exitCode, output2) => withScreen(`${AGENT_LABELS[agent]} stopped before it finished (exit code ${String(exitCode)}).`, output2);
|
|
164776
|
-
var startTimeoutReason = (agent, timeoutMs, output2) => withScreen(
|
|
164777
|
-
`${AGENT_LABELS[agent]} did not start within ${String(Math.round(timeoutMs / MS_PER_SECOND2))} seconds, so Flight Plan closed it.`,
|
|
164778
|
-
output2
|
|
164779
|
-
);
|
|
164780
|
-
|
|
164781
|
-
// apps/backend/src/procedures/close-idle-agents/utils/find-stale-agents.ts
|
|
164782
|
-
var AGENT_START_TIMEOUT_MS = 9e4;
|
|
164783
|
-
var AGENT_IDLE_MS = 6e5;
|
|
164784
|
-
var ageMs = (since, now) => now.getTime() - since.getTime();
|
|
164785
|
-
var staleReasonOf = (agent, now) => {
|
|
164786
|
-
if (agent.closing !== null || agent.isAwaitingPermission) return null;
|
|
164787
|
-
if (agent.phase === "starting") return ageMs(agent.startedAt, now) > AGENT_START_TIMEOUT_MS ? "start-timeout" : null;
|
|
164788
|
-
return ageMs(agent.lastActivityAt, now) > AGENT_IDLE_MS ? "idle" : null;
|
|
164789
|
-
};
|
|
164790
|
-
var findStaleAgents = (agents, now) => agents.flatMap((agent) => {
|
|
164791
|
-
const reason = staleReasonOf(agent, now);
|
|
164792
|
-
return reason === null ? [] : [{ agent, reason }];
|
|
164793
|
-
});
|
|
164794
|
-
|
|
164795
|
-
// apps/backend/src/procedures/close-idle-agents/index.ts
|
|
164796
|
-
var closeStaleAgent = async ({ agent, reason }, context) => {
|
|
164797
|
-
if (reason === "start-timeout") {
|
|
164798
|
-
const output2 = agent.process?.readOutput() ?? "";
|
|
164799
|
-
await recordAgentFailure(agent.key, startTimeoutReason(agent.agent, AGENT_START_TIMEOUT_MS, output2), context);
|
|
164800
|
-
}
|
|
164801
|
-
closeAgent(agent.key, reason, context);
|
|
164802
|
-
};
|
|
164803
|
-
var closeIdleAgents = async (context) => {
|
|
164804
|
-
const stale = findStaleAgents(context.conversationEnvironment.agents.list(), context.now());
|
|
164805
|
-
await Promise.all(stale.map(async (staleAgent) => {
|
|
164806
|
-
await closeStaleAgent(staleAgent, context);
|
|
164807
|
-
}));
|
|
164808
|
-
return stale.length;
|
|
164809
|
-
};
|
|
164810
|
-
|
|
164811
|
-
// apps/backend/src/server/agent-lifecycle.ts
|
|
164812
|
-
var AGENT_SWEEP_INTERVAL_MS = 15e3;
|
|
164813
|
-
var registerAgentLifecycle = (server, context) => {
|
|
164814
|
-
const sweep2 = setInterval(() => {
|
|
164815
|
-
closeIdleAgents(context).catch((error61) => {
|
|
164816
|
-
server.log.error({ err: error61 }, "closing idle agents failed");
|
|
164817
|
-
});
|
|
164818
|
-
}, AGENT_SWEEP_INTERVAL_MS);
|
|
164819
|
-
sweep2.unref();
|
|
164820
|
-
server.addHook("onClose", async () => {
|
|
164821
|
-
clearInterval(sweep2);
|
|
164822
|
-
closeAllAgents(context);
|
|
164823
|
-
await context.conversationEnvironment.hub.close();
|
|
164824
|
-
});
|
|
164825
|
-
};
|
|
164826
|
-
|
|
164827
164628
|
// apps/backend/src/server/api/plugin.ts
|
|
164828
164629
|
var import_sse = __toESM(require_sse());
|
|
164829
164630
|
|
|
164830
|
-
// apps/backend/src/procedures/get-conversation/utils/conversation-hub.ts
|
|
164831
|
-
var NO_TIME_LEFT_MS = 0;
|
|
164832
|
-
var nextChangeOf = async (subscription, options) => {
|
|
164833
|
-
const timeoutMs = options.remainingMs === null ? null : Math.max(options.remainingMs(), NO_TIME_LEFT_MS);
|
|
164834
|
-
if (timeoutMs === NO_TIME_LEFT_MS) return "timed-out";
|
|
164835
|
-
return await subscription.nextChange({ timeoutMs, signal: options.signal });
|
|
164836
|
-
};
|
|
164837
|
-
var readsOnChange = (subscription, options, read2) => ({
|
|
164838
|
-
[Symbol.asyncIterator]: () => ({
|
|
164839
|
-
next: async () => {
|
|
164840
|
-
const wait = await nextChangeOf(subscription, options);
|
|
164841
|
-
return wait === "changed" ? { value: await read2(), done: false } : { value: void 0, done: true };
|
|
164842
|
-
}
|
|
164843
|
-
})
|
|
164844
|
-
});
|
|
164845
|
-
|
|
164846
|
-
// apps/backend/src/procedures/request-permission/index.ts
|
|
164847
|
-
var PERMISSION_WAIT_MS = 59e4;
|
|
164848
|
-
var DENIED_MESSAGE = "The reviewer denied this.";
|
|
164849
|
-
var UNANSWERED_MESSAGE = "The reviewer did not answer in time, so this was refused.";
|
|
164850
|
-
var UNANSWERED_REASON = "The agent stopped waiting for an answer.";
|
|
164851
|
-
var STOPPED_REASON = "The agent stopped before you answered.";
|
|
164852
|
-
var readAnswer = async (key, batchId, context) => {
|
|
164853
|
-
const { journal } = await context.conversationEnvironment.store.read(key);
|
|
164854
|
-
const answerSet = findAnswerSet(journal, batchId);
|
|
164855
|
-
if (answerSet !== null) return { kind: "answered", answerSet };
|
|
164856
|
-
return findWithdrawal(journal, batchId) === null ? { kind: "pending" } : { kind: "withdrawn" };
|
|
164857
|
-
};
|
|
164858
|
-
var isAgentGone = (sessionId, context) => context.conversationEnvironment.agents.findBySessionId(sessionId) === null;
|
|
164859
|
-
var waitForAnswer = async (wait, context) => {
|
|
164860
|
-
const first = await readAnswer(wait.key, wait.batchId, context);
|
|
164861
|
-
if (first.kind !== "pending") return first;
|
|
164862
|
-
const remainingMs = () => wait.deadlineMs - context.now().getTime();
|
|
164863
|
-
const answers = readsOnChange(wait.subscription, { signal: null, remainingMs }, async () => await readAnswer(wait.key, wait.batchId, context));
|
|
164864
|
-
for await (const answer of answers) {
|
|
164865
|
-
if (answer.kind !== "pending" || isAgentGone(wait.sessionId, context)) return answer;
|
|
164866
|
-
}
|
|
164867
|
-
return await readAnswer(wait.key, wait.batchId, context);
|
|
164868
|
-
};
|
|
164869
|
-
var decisionOf = (answerSet) => {
|
|
164870
|
-
const answer = answerSet.answers.at(0);
|
|
164871
|
-
if (answer === void 0) return { kind: "deny", message: DENIED_MESSAGE };
|
|
164872
|
-
if (answer.pickedLabels.includes(ALLOW_LABEL)) return { kind: "allow" };
|
|
164873
|
-
return { kind: "deny", message: answer.text === null ? DENIED_MESSAGE : `${DENIED_MESSAGE} ${answer.text}` };
|
|
164874
|
-
};
|
|
164875
|
-
var withdraw = async (wait, context) => {
|
|
164876
|
-
const reason = isAgentGone(wait.sessionId, context) ? STOPPED_REASON : UNANSWERED_REASON;
|
|
164877
|
-
await appendAndPublish(
|
|
164878
|
-
wait.key,
|
|
164879
|
-
[{ kind: "questions-withdrawn", id: context.conversationEnvironment.newId(), batchId: wait.batchId, reason, withdrawnAt: context.now() }],
|
|
164880
|
-
context
|
|
164881
|
-
);
|
|
164882
|
-
};
|
|
164883
|
-
var requestPermission = async (input2, context) => {
|
|
164884
|
-
const { agents, hub, newId } = context.conversationEnvironment;
|
|
164885
|
-
const agent = await confirmAgentStart(input2.sessionId, context);
|
|
164886
|
-
if (agent === null) return { kind: "unknown-session" };
|
|
164887
|
-
const { key } = agent;
|
|
164888
|
-
const batchId = newId();
|
|
164889
|
-
const now = context.now();
|
|
164890
|
-
const subscription = hub.subscribe(key);
|
|
164891
|
-
agents.update(key, (current) => ({ ...current, isAwaitingPermission: true, lastActivityAt: now }));
|
|
164892
|
-
try {
|
|
164893
|
-
await appendAndPublish(
|
|
164894
|
-
key,
|
|
164895
|
-
[{ kind: "question-batch", id: batchId, origin: "permission", questions: [permissionQuestionOf(`${batchId}-1`, input2.toolName, input2.toolInput)], askedAt: now }],
|
|
164896
|
-
context
|
|
164897
|
-
);
|
|
164898
|
-
const wait = { key, batchId, sessionId: input2.sessionId, subscription, deadlineMs: now.getTime() + PERMISSION_WAIT_MS };
|
|
164899
|
-
const answer = await waitForAnswer(wait, context);
|
|
164900
|
-
if (answer.kind === "answered") return decisionOf(answer.answerSet);
|
|
164901
|
-
if (answer.kind === "pending") await withdraw(wait, context);
|
|
164902
|
-
return { kind: "deny", message: UNANSWERED_MESSAGE };
|
|
164903
|
-
} finally {
|
|
164904
|
-
subscription.close();
|
|
164905
|
-
agents.update(key, (current) => ({ ...current, isAwaitingPermission: false, lastActivityAt: context.now() }));
|
|
164906
|
-
hub.publish(key);
|
|
164907
|
-
}
|
|
164908
|
-
};
|
|
164909
|
-
|
|
164910
|
-
// apps/backend/src/procedures/request-permission/utils/schemas.ts
|
|
164911
|
-
var permissionHookInputSchema = external_exports.looseObject({
|
|
164912
|
-
session_id: external_exports.string().min(1),
|
|
164913
|
-
tool_name: external_exports.string().min(1),
|
|
164914
|
-
tool_input: external_exports.unknown().optional()
|
|
164915
|
-
});
|
|
164916
|
-
var permissionHookOutputSchema = external_exports.strictObject({
|
|
164917
|
-
hookSpecificOutput: external_exports.strictObject({
|
|
164918
|
-
hookEventName: external_exports.literal("PermissionRequest"),
|
|
164919
|
-
decision: external_exports.strictObject({ behavior: external_exports.enum(["allow", "deny"]), message: external_exports.string().optional() })
|
|
164920
|
-
}).optional()
|
|
164921
|
-
});
|
|
164922
|
-
|
|
164923
|
-
// apps/backend/src/server/api/route-schema.ts
|
|
164924
|
-
var JSON_SCHEMA_TARGET = "draft-7";
|
|
164925
|
-
var toRouteSchema = (schema) => external_exports.toJSONSchema(schema, { target: JSON_SCHEMA_TARGET });
|
|
164926
|
-
|
|
164927
|
-
// apps/backend/src/server/api/routes/agent-permission-request/index.ts
|
|
164928
|
-
var toHookOutput = (decision) => {
|
|
164929
|
-
if (decision.kind === "unknown-session") return {};
|
|
164930
|
-
return {
|
|
164931
|
-
hookSpecificOutput: {
|
|
164932
|
-
hookEventName: "PermissionRequest",
|
|
164933
|
-
decision: decision.kind === "allow" ? { behavior: "allow" } : { behavior: "deny", message: decision.message }
|
|
164934
|
-
}
|
|
164935
|
-
};
|
|
164936
|
-
};
|
|
164937
|
-
var registerAgentPermissionRequestRoute = (server, context) => {
|
|
164938
|
-
server.post(
|
|
164939
|
-
AGENT_HOOK_PATHS.permissionRequest,
|
|
164940
|
-
{
|
|
164941
|
-
schema: { body: toRouteSchema(permissionHookInputSchema), response: { 200: toRouteSchema(permissionHookOutputSchema) } }
|
|
164942
|
-
},
|
|
164943
|
-
async (request) => {
|
|
164944
|
-
const { session_id: sessionId, tool_name: toolName, tool_input: toolInput } = request.body;
|
|
164945
|
-
return toHookOutput(await requestPermission({ sessionId, toolName, toolInput }, context));
|
|
164946
|
-
}
|
|
164947
|
-
);
|
|
164948
|
-
};
|
|
164949
|
-
|
|
164950
|
-
// apps/backend/src/procedures/record-agent-activity/index.ts
|
|
164951
|
-
var recordAgentActivity = async (input2, context) => await confirmAgentStart(input2.sessionId, context) === null ? { kind: "unknown-session" } : { kind: "recorded" };
|
|
164952
|
-
|
|
164953
|
-
// apps/backend/src/procedures/record-agent-activity/utils/schemas.ts
|
|
164954
|
-
var agentHookInputSchema = external_exports.looseObject({ session_id: external_exports.string().min(1) });
|
|
164955
|
-
var emptyHookOutputSchema = external_exports.strictObject({});
|
|
164956
|
-
|
|
164957
|
-
// apps/backend/src/server/api/routes/agent-prompt-submit/index.ts
|
|
164958
|
-
var registerAgentPromptSubmitRoute = (server, context) => {
|
|
164959
|
-
server.post(
|
|
164960
|
-
AGENT_HOOK_PATHS.promptSubmit,
|
|
164961
|
-
{ schema: { body: toRouteSchema(agentHookInputSchema), response: { 200: toRouteSchema(emptyHookOutputSchema) } } },
|
|
164962
|
-
async (request) => {
|
|
164963
|
-
await recordAgentActivity({ sessionId: request.body.session_id }, context);
|
|
164964
|
-
return {};
|
|
164965
|
-
}
|
|
164966
|
-
);
|
|
164967
|
-
};
|
|
164968
|
-
|
|
164969
|
-
// apps/backend/src/procedures/end-agent-turn/utils/schemas.ts
|
|
164970
|
-
var stopHookInputSchema = external_exports.looseObject({
|
|
164971
|
-
session_id: external_exports.string().min(1),
|
|
164972
|
-
last_assistant_message: external_exports.string().nullable().optional()
|
|
164973
|
-
});
|
|
164974
|
-
var stopHookOutputSchema = external_exports.strictObject({
|
|
164975
|
-
decision: external_exports.literal("block").optional(),
|
|
164976
|
-
reason: external_exports.string().optional()
|
|
164977
|
-
});
|
|
164978
|
-
|
|
164979
|
-
// apps/backend/src/server/api/routes/agent-stop/index.ts
|
|
164980
|
-
var AGENT_CLOSE_DELAY_MS = 1500;
|
|
164981
|
-
var toHookOutput2 = (ending) => ending.kind === "continue" ? { decision: "block", reason: ending.reason } : {};
|
|
164982
|
-
var registerAgentStopRoute = (server, context) => {
|
|
164983
|
-
server.post(
|
|
164984
|
-
AGENT_HOOK_PATHS.stop,
|
|
164985
|
-
{ schema: { body: toRouteSchema(stopHookInputSchema), response: { 200: toRouteSchema(stopHookOutputSchema) } } },
|
|
164986
|
-
async (request) => {
|
|
164987
|
-
const ending = await endAgentTurn(
|
|
164988
|
-
{ sessionId: request.body.session_id, lastAssistantMessage: request.body.last_assistant_message ?? null },
|
|
164989
|
-
context
|
|
164990
|
-
);
|
|
164991
|
-
if (ending.kind === "close") {
|
|
164992
|
-
setTimeout(() => {
|
|
164993
|
-
closeAgent(ending.key, "turn-ended", context);
|
|
164994
|
-
}, AGENT_CLOSE_DELAY_MS).unref();
|
|
164995
|
-
}
|
|
164996
|
-
return toHookOutput2(ending);
|
|
164997
|
-
}
|
|
164998
|
-
);
|
|
164999
|
-
};
|
|
165000
|
-
|
|
165001
|
-
// apps/backend/src/server/api/routes/agent-tool-use/index.ts
|
|
165002
|
-
var registerAgentToolUseRoute = (server, context) => {
|
|
165003
|
-
server.post(
|
|
165004
|
-
AGENT_HOOK_PATHS.postToolUse,
|
|
165005
|
-
{ schema: { body: toRouteSchema(agentHookInputSchema), response: { 200: toRouteSchema(emptyHookOutputSchema) } } },
|
|
165006
|
-
async (request) => {
|
|
165007
|
-
await recordAgentActivity({ sessionId: request.body.session_id }, context);
|
|
165008
|
-
return {};
|
|
165009
|
-
}
|
|
165010
|
-
);
|
|
165011
|
-
};
|
|
165012
|
-
|
|
165013
|
-
// apps/backend/src/procedures/listen-for-reviewer/index.ts
|
|
165014
|
-
var readPacket = async (key, context) => {
|
|
165015
|
-
const { store, serverUrl } = context.conversationEnvironment;
|
|
165016
|
-
const { journal } = await store.read(key);
|
|
165017
|
-
const pending = pendingInboundOf(journal);
|
|
165018
|
-
if (pending.length === 0) return null;
|
|
165019
|
-
return {
|
|
165020
|
-
throughSequence: lastSequenceOf(pending),
|
|
165021
|
-
text: formatListenPacket(formatInbound(pending, journal), listenCommandOf(serverUrl, key))
|
|
165022
|
-
};
|
|
165023
|
-
};
|
|
165024
|
-
var recordDelivery = async (key, packet, context) => {
|
|
165025
|
-
await appendAndPublish(
|
|
165026
|
-
key,
|
|
165027
|
-
[
|
|
165028
|
-
{
|
|
165029
|
-
kind: "delivery",
|
|
165030
|
-
id: context.conversationEnvironment.newId(),
|
|
165031
|
-
throughSequence: packet.throughSequence,
|
|
165032
|
-
channel: "listener",
|
|
165033
|
-
deliveredAt: context.now()
|
|
165034
|
-
}
|
|
165035
|
-
],
|
|
165036
|
-
context
|
|
165037
|
-
);
|
|
165038
|
-
};
|
|
165039
|
-
var waitForPacket = async (key, subscription, context, signal) => {
|
|
165040
|
-
const waiting = await readPacket(key, context);
|
|
165041
|
-
if (waiting !== null) return waiting;
|
|
165042
|
-
const packets = readsOnChange(subscription, { signal, remainingMs: null }, async () => await readPacket(key, context));
|
|
165043
|
-
for await (const packet of packets) {
|
|
165044
|
-
if (packet !== null) return packet;
|
|
165045
|
-
}
|
|
165046
|
-
return null;
|
|
165047
|
-
};
|
|
165048
|
-
var packetsOf = async function* (key, context, signal) {
|
|
165049
|
-
const { agents, hub } = context.conversationEnvironment;
|
|
165050
|
-
const subscription = hub.subscribe(key);
|
|
165051
|
-
agents.openListener(key);
|
|
165052
|
-
hub.publish(key);
|
|
165053
|
-
try {
|
|
165054
|
-
const packet = await waitForPacket(key, subscription, context, signal);
|
|
165055
|
-
if (packet === null) return;
|
|
165056
|
-
yield packet;
|
|
165057
|
-
await recordDelivery(key, packet, context);
|
|
165058
|
-
} finally {
|
|
165059
|
-
subscription.close();
|
|
165060
|
-
agents.closeListener(key, context.now());
|
|
165061
|
-
hub.publish(key);
|
|
165062
|
-
}
|
|
165063
|
-
};
|
|
165064
|
-
var listenForReviewer = async (input2, context, signal) => {
|
|
165065
|
-
const key = { repositoryName: input2.repositoryName, targetId: input2.targetId };
|
|
165066
|
-
const target = await findReviewTarget(key, context);
|
|
165067
|
-
if (target.kind === "rejected") return target;
|
|
165068
|
-
return { kind: "listening", packets: packetsOf(key, context, signal) };
|
|
165069
|
-
};
|
|
165070
|
-
|
|
165071
164631
|
// apps/backend/src/procedures/listen-for-reviewer/utils/schemas.ts
|
|
165072
164632
|
var listenParamsSchema = external_exports.strictObject({
|
|
165073
164633
|
repositoryName: external_exports.string().min(1),
|
|
@@ -165075,14 +164635,17 @@ var listenParamsSchema = external_exports.strictObject({
|
|
|
165075
164635
|
});
|
|
165076
164636
|
var listenRejectionSchema = external_exports.strictObject({ message: external_exports.string() });
|
|
165077
164637
|
|
|
164638
|
+
// apps/backend/src/server/api/route-schema.ts
|
|
164639
|
+
var JSON_SCHEMA_TARGET = "draft-7";
|
|
164640
|
+
var toRouteSchema = (schema) => external_exports.toJSONSchema(schema, { target: JSON_SCHEMA_TARGET });
|
|
164641
|
+
|
|
165078
164642
|
// apps/backend/src/server/api/routes/listen-for-reviewer/index.ts
|
|
165079
164643
|
var LISTEN_ROUTE = `/api/:repositoryName/:targetId/${LISTEN_PATH_SUFFIX}`;
|
|
165080
164644
|
var HTTP_NOT_FOUND3 = 404;
|
|
165081
|
-
var REPLY_EVENT = "reply";
|
|
165082
164645
|
var passText = (data) => String(data);
|
|
165083
164646
|
var toMessages = async function* (packets) {
|
|
165084
164647
|
for await (const packet of packets) {
|
|
165085
|
-
yield { id: String(packet.throughSequence), event:
|
|
164648
|
+
yield packet.kind === "work" ? { id: String(packet.throughSequence), event: packet.kind, data: packet.text } : { event: packet.kind, data: packet.text };
|
|
165086
164649
|
}
|
|
165087
164650
|
};
|
|
165088
164651
|
var registerListenForReviewerRoute = (server, context) => {
|
|
@@ -165113,10 +164676,6 @@ var registerListenForReviewerRoute = (server, context) => {
|
|
|
165113
164676
|
var registerApi = async (server, context) => {
|
|
165114
164677
|
await server.register(import_sse.default);
|
|
165115
164678
|
registerListenForReviewerRoute(server, context);
|
|
165116
|
-
registerAgentPromptSubmitRoute(server, context);
|
|
165117
|
-
registerAgentToolUseRoute(server, context);
|
|
165118
|
-
registerAgentPermissionRequestRoute(server, context);
|
|
165119
|
-
registerAgentStopRoute(server, context);
|
|
165120
164679
|
};
|
|
165121
164680
|
|
|
165122
164681
|
// node_modules/.pnpm/@trpc+server@11.19.0_typescript@6.0.3/node_modules/@trpc/server/dist/codes-D5Ya6_Bi.mjs
|
|
@@ -168517,217 +168076,6 @@ var addSetupRepositoryRoute = publicProcedure.input(addSetupRepositoryInputSchem
|
|
|
168517
168076
|
return { name: plan4.repository.name };
|
|
168518
168077
|
});
|
|
168519
168078
|
|
|
168520
|
-
// apps/backend/src/procedures/handle-agent-exit/index.ts
|
|
168521
|
-
var handleAgentExit = async (input2, context) => {
|
|
168522
|
-
const { agents, hub } = context.conversationEnvironment;
|
|
168523
|
-
const released = agents.release(input2.key, input2.sessionId);
|
|
168524
|
-
if (released === null) return { shouldRedeliver: false };
|
|
168525
|
-
if (released.closing !== null) {
|
|
168526
|
-
hub.publish(input2.key);
|
|
168527
|
-
return { shouldRedeliver: shouldRedeliverAfter(released.closing) };
|
|
168528
|
-
}
|
|
168529
|
-
const output2 = released.process?.readOutput() ?? "";
|
|
168530
|
-
await recordAgentFailure(input2.key, unexpectedExitReason(released.agent, input2.exitCode, output2), context);
|
|
168531
|
-
return { shouldRedeliver: false };
|
|
168532
|
-
};
|
|
168533
|
-
|
|
168534
|
-
// apps/backend/src/procedures/request-write-up/utils/plan-node-write-up.ts
|
|
168535
|
-
var DRAFTING_STATUS3 = "drafting";
|
|
168536
|
-
var ALREADY_WRITTEN = { kind: "written", message: "This is already explained." };
|
|
168537
|
-
var rejected2 = (message) => ({ kind: "rejected", field: "target", message });
|
|
168538
|
-
var planned = (artifact, ask, message) => ({ kind: "planned", artifact: { ...artifact, status: DRAFTING_STATUS3 }, ask, message });
|
|
168539
|
-
var quoted6 = (text2) => `\`${text2}\``;
|
|
168540
|
-
var listWaypoints3 = (artifact) => artifact.segments.flatMap(waypointsOf).map(({ waypoint }) => waypoint);
|
|
168541
|
-
var isWaypointUnwritten = (waypoint) => waypoint.title === null || waypoint.reading.trim() === "";
|
|
168542
|
-
var waypointIdsOf = (artifact, target) => target.kind === "waypoint" ? listWaypoints3(artifact).filter((waypoint) => waypoint.id === target.waypointId).map((waypoint) => waypoint.id) : listRootBlockWaypointIds(artifact, target.rootBlockId);
|
|
168543
|
-
var waypointAskOf = (ids) => ids.length === 1 ? `The reviewer asks for the write-up of the waypoint ${quoted6(ids[0])} alone: write its title and its reading, and nothing else.` : `The reviewer asks for the write-up of the waypoints ${joinedList2(ids.map(quoted6))} alone: write their titles and readings, and nothing else.`;
|
|
168544
|
-
var planWaypoints = (artifact, target) => {
|
|
168545
|
-
const waypointIds = waypointIdsOf(artifact, target);
|
|
168546
|
-
if (waypointIds.length === 0) {
|
|
168547
|
-
return rejected2(target.kind === "waypoint" ? "This waypoint is not in the review." : "This code block has no waypoint in the review.");
|
|
168548
|
-
}
|
|
168549
|
-
const unwrittenIds = listWaypoints3(artifact).filter((waypoint) => waypointIds.includes(waypoint.id) && isWaypointUnwritten(waypoint)).map((waypoint) => waypoint.id);
|
|
168550
|
-
if (unwrittenIds.length === 0) return ALREADY_WRITTEN;
|
|
168551
|
-
return planned(withRequiredWaypoints(artifact, unwrittenIds), waypointAskOf(unwrittenIds), `Explaining ${countLabel2(unwrittenIds.length, "waypoint", "waypoints")}`);
|
|
168552
|
-
};
|
|
168553
|
-
var isTraceNodeUnwritten = (node2) => node2.label === null || node2.triggerLabels.some((trigger) => trigger.label === null) || node2.blockLabels.some((listed) => listed.label === null);
|
|
168554
|
-
var findTraceNode = (artifact, { segmentId, nodeId }) => listTraceNodes(artifact.segments.find((segment) => segment.id === segmentId)?.traceDiagram?.traceNodes ?? []).find((node2) => node2.id === nodeId);
|
|
168555
|
-
var planTraceNode = (artifact, target) => {
|
|
168556
|
-
const node2 = findTraceNode(artifact, target);
|
|
168557
|
-
if (node2 === void 0) return rejected2("This card is not in the Trace Diagram.");
|
|
168558
|
-
if (!isTraceNodeUnwritten(node2)) return ALREADY_WRITTEN;
|
|
168559
|
-
return planned(
|
|
168560
|
-
withRequiredCard(artifact, target.segmentId, target.nodeId),
|
|
168561
|
-
`The reviewer asks for the write-up of the Trace Diagram node ${quoted6(target.nodeId)} of segment ${quoted6(target.segmentId)} alone: write its label and the labels of its trigger labels and listed blocks, and nothing else.`,
|
|
168562
|
-
"Explaining the card"
|
|
168563
|
-
);
|
|
168564
|
-
};
|
|
168565
|
-
var blastFileIn = (segment, path11) => segment?.blastDiagram?.nodes.find((node2) => node2.path === path11);
|
|
168566
|
-
var findBlastFile = (artifact, { segmentId, path: path11 }) => blastFileIn(artifact.segments.find((segment) => segment.id === segmentId), path11);
|
|
168567
|
-
var blastTargetOf = (artifact, target) => {
|
|
168568
|
-
const isNamedSegment = artifact.segments.some((segment) => segment.id === target.segmentId);
|
|
168569
|
-
if (artifact.isSegmented || !isNamedSegment || findBlastFile(artifact, target) !== void 0) return target;
|
|
168570
|
-
const holder = artifact.segments.find((segment) => blastFileIn(segment, target.path) !== void 0);
|
|
168571
|
-
return holder === void 0 ? target : { ...target, segmentId: holder.id };
|
|
168572
|
-
};
|
|
168573
|
-
var planBlastFile = (artifact, requested2) => {
|
|
168574
|
-
const target = blastTargetOf(artifact, requested2);
|
|
168575
|
-
const node2 = findBlastFile(artifact, target);
|
|
168576
|
-
if (node2 === void 0) return rejected2("This file is not in the Blast Diagram.");
|
|
168577
|
-
if (node2.diffType !== null) return rejected2("This file is part of the change, so it has no impact to assess.");
|
|
168578
|
-
if (node2.impactType !== null) return ALREADY_WRITTEN;
|
|
168579
|
-
return planned(
|
|
168580
|
-
withRequiredBlastFile(artifact, target.segmentId, target.path),
|
|
168581
|
-
`The reviewer asks for the impact of the change on ${quoted6(target.path)} in the Blast Diagram of segment ${quoted6(target.segmentId)} alone: write its impact type and its reason, and nothing else.`,
|
|
168582
|
-
"Assessing the file"
|
|
168583
|
-
);
|
|
168584
|
-
};
|
|
168585
|
-
var planNodeWriteUp = (artifact, target) => {
|
|
168586
|
-
if (target.kind === "trace-node") return planTraceNode(artifact, target);
|
|
168587
|
-
if (target.kind === "blast-file") return planBlastFile(artifact, target);
|
|
168588
|
-
return planWaypoints(artifact, target);
|
|
168589
|
-
};
|
|
168590
|
-
|
|
168591
|
-
// apps/backend/src/procedures/request-queued-write-ups/utils/plan-queued-write-ups.ts
|
|
168592
|
-
var SEVERAL_ASKS_LEAD = "The reviewer asked for these write-ups while you were busy. Do each one as it asks:";
|
|
168593
|
-
var planQueuedWriteUps = (artifact, targets) => targets.reduce((queued, target) => {
|
|
168594
|
-
const planned2 = planNodeWriteUp(queued.artifact, target);
|
|
168595
|
-
return planned2.kind === "planned" ? { artifact: planned2.artifact, asks: [...queued.asks, planned2.ask] } : queued;
|
|
168596
|
-
}, { artifact, asks: [] });
|
|
168597
|
-
var queuedAmendmentOf = (queued) => ({
|
|
168598
|
-
artifact: queued.asks.length === 0 ? null : queued.artifact,
|
|
168599
|
-
outcome: queued.asks
|
|
168600
|
-
});
|
|
168601
|
-
var queuedAskOf = (asks) => asks.length === 1 ? asks[0] : [SEVERAL_ASKS_LEAD, ...asks.map((ask) => `- ${ask}`)].join("\n");
|
|
168602
|
-
|
|
168603
|
-
// apps/backend/src/procedures/request-queued-write-ups/index.ts
|
|
168604
|
-
var requestQueuedWriteUps = async (key, context) => {
|
|
168605
|
-
const { agents, writeUpQueue, newId } = context.conversationEnvironment;
|
|
168606
|
-
if (agents.find(key) !== null) return false;
|
|
168607
|
-
const targets = writeUpQueue.take(key);
|
|
168608
|
-
if (targets.length === 0) return false;
|
|
168609
|
-
const repository = (await context.repositoryStore.list()).find((candidate) => candidate.name === key.repositoryName);
|
|
168610
|
-
const target = repository === void 0 ? null : await findReviewTarget2(repository, key.targetId, context);
|
|
168611
|
-
if (repository === void 0 || target === null) return false;
|
|
168612
|
-
const asks = await context.reviewStore.amendArtifact(key, (artifact) => queuedAmendmentOf(planQueuedWriteUps(artifact, targets)));
|
|
168613
|
-
if (asks === null || asks.length === 0) return false;
|
|
168614
|
-
const body = buildWriteUpRequestPrompt(repository, target, key, queuedAskOf(asks));
|
|
168615
|
-
await appendAndPublish(key, [{ kind: "reviewer-message", id: newId(), body, reference: null, sentAt: context.now() }], context);
|
|
168616
|
-
return true;
|
|
168617
|
-
};
|
|
168618
|
-
|
|
168619
|
-
// apps/backend/src/procedures/deliver-to-agent/utils/choose-writer.ts
|
|
168620
|
-
var writerOfRequest = (install, request) => request?.writer.kind === "agent" && request.writer.agent === install.agent ? { install: { ...install, model: request.writer.model }, effort: request.writer.effort } : { install, effort: install.effort };
|
|
168621
|
-
var chooseWriter = (install, request, modelChoice) => modelChoice?.agent === install.agent ? { install: { ...install, model: modelChoice.model }, effort: modelChoice.effort } : writerOfRequest(install, request);
|
|
168622
|
-
|
|
168623
|
-
// apps/backend/src/procedures/deliver-to-agent/utils/plan-delivery.ts
|
|
168624
|
-
var LISTENER_GRACE_MS = 6e5;
|
|
168625
|
-
var NO_AGENTS_REASON = "Finish the Agents step of the setup so Flight Plan can start an agent.";
|
|
168626
|
-
var unspawnableReason = (agents) => {
|
|
168627
|
-
const labels = agents.installs.map((install) => AGENT_LABELS[install.agent]).join(" or ");
|
|
168628
|
-
return `Flight Plan can start only Claude. Start ${labels} yourself and have it listen for the reviewer.`;
|
|
168629
|
-
};
|
|
168630
|
-
var isListenerNear = (presence, now) => presence.openCount > 0 || presence.lastClosedAt !== null && now.getTime() - presence.lastClosedAt.getTime() < LISTENER_GRACE_MS;
|
|
168631
|
-
var chooseInstall = (agents, spawnableAgents) => {
|
|
168632
|
-
const candidates = agents.installs.filter((install) => spawnableAgents.includes(install.agent));
|
|
168633
|
-
return candidates.find((install) => install.agent === agents.defaultAgent) ?? candidates.at(0) ?? null;
|
|
168634
|
-
};
|
|
168635
|
-
var planDelivery = (facts) => {
|
|
168636
|
-
if (facts.pendingCount === 0) return { kind: "nothing-pending" };
|
|
168637
|
-
if (facts.runningAgent !== null) return { kind: "agent-running" };
|
|
168638
|
-
if (isListenerNear(facts.listenerPresence, facts.now)) return { kind: "listener-waiting" };
|
|
168639
|
-
if (facts.target.kind === "rejected") return { kind: "unavailable", reason: facts.target.message };
|
|
168640
|
-
if (facts.agents === null) return { kind: "unavailable", reason: NO_AGENTS_REASON };
|
|
168641
|
-
const install = chooseInstall(facts.agents, facts.spawnableAgents);
|
|
168642
|
-
return install === null ? { kind: "unavailable", reason: unspawnableReason(facts.agents) } : { kind: "spawn", install, workingPath: facts.target.workingPath };
|
|
168643
|
-
};
|
|
168644
|
-
|
|
168645
|
-
// apps/backend/src/procedures/deliver-to-agent/index.ts
|
|
168646
|
-
var spawnableAgentsOf = (context) => AGENT_NAMES.filter((agent) => context.conversationEnvironment.spawners[agent] !== void 0);
|
|
168647
|
-
var startingAgent = (key, agent, sessionId, now) => ({
|
|
168648
|
-
key,
|
|
168649
|
-
agent,
|
|
168650
|
-
sessionId,
|
|
168651
|
-
process: null,
|
|
168652
|
-
phase: "starting",
|
|
168653
|
-
startedAt: now,
|
|
168654
|
-
lastActivityAt: now,
|
|
168655
|
-
closing: null,
|
|
168656
|
-
isAwaitingPermission: false,
|
|
168657
|
-
wasReminded: false
|
|
168658
|
-
});
|
|
168659
|
-
var onExitOf = (key, sessionId, context) => (exit) => {
|
|
168660
|
-
void handleAgentExit({ key, sessionId, exitCode: exit.exitCode }, context).then(async (outcome) => {
|
|
168661
|
-
const hasQueuedWriteUps = await requestQueuedWriteUps(key, context);
|
|
168662
|
-
if (outcome.shouldRedeliver || hasQueuedWriteUps) await deliverToAgent(key, context);
|
|
168663
|
-
});
|
|
168664
|
-
};
|
|
168665
|
-
var launchAgent = async (spawning, sessionId, spawner, context) => {
|
|
168666
|
-
const { key, conversation, pending, install, effort, workingPath } = spawning;
|
|
168667
|
-
const { agents, newId } = context.conversationEnvironment;
|
|
168668
|
-
const start2 = await spawner(
|
|
168669
|
-
{
|
|
168670
|
-
agent: install.agent,
|
|
168671
|
-
installPath: install.installPath,
|
|
168672
|
-
sessionId,
|
|
168673
|
-
isResume: conversation.sessionId === sessionId,
|
|
168674
|
-
workingPath,
|
|
168675
|
-
model: install.model,
|
|
168676
|
-
effort,
|
|
168677
|
-
prompt: formatInbound(pending, conversation.journal),
|
|
168678
|
-
instructions: spawnInstructionsOf(key)
|
|
168679
|
-
},
|
|
168680
|
-
onExitOf(key, sessionId, context)
|
|
168681
|
-
);
|
|
168682
|
-
if (start2.kind === "failed") {
|
|
168683
|
-
agents.release(key, sessionId);
|
|
168684
|
-
await recordAgentFailure(key, start2.reason, context);
|
|
168685
|
-
return start2;
|
|
168686
|
-
}
|
|
168687
|
-
const started2 = agents.update(key, (agent) => ({ ...agent, process: start2.process }));
|
|
168688
|
-
if (started2?.closing !== null) start2.process.stop();
|
|
168689
|
-
await appendAndPublish(
|
|
168690
|
-
key,
|
|
168691
|
-
[{ kind: "delivery", id: newId(), throughSequence: lastSequenceOf(pending), channel: "spawn", deliveredAt: context.now() }],
|
|
168692
|
-
context
|
|
168693
|
-
);
|
|
168694
|
-
return { kind: "spawned", sessionId };
|
|
168695
|
-
};
|
|
168696
|
-
var spawnAgent = async (spawning, context) => {
|
|
168697
|
-
const { agents, spawners, newId, hub } = context.conversationEnvironment;
|
|
168698
|
-
const spawner = spawners[spawning.install.agent];
|
|
168699
|
-
if (spawner === void 0) return { kind: "unavailable", reason: `No spawner is registered for ${spawning.install.agent}.` };
|
|
168700
|
-
const sessionId = spawning.conversation.sessionId ?? newId();
|
|
168701
|
-
if (!agents.claim(startingAgent(spawning.key, spawning.install.agent, sessionId, context.now()))) {
|
|
168702
|
-
return { kind: "agent-running" };
|
|
168703
|
-
}
|
|
168704
|
-
hub.publish(spawning.key);
|
|
168705
|
-
return await launchAgent(spawning, sessionId, spawner, context);
|
|
168706
|
-
};
|
|
168707
|
-
var deliverToAgent = async (key, context) => {
|
|
168708
|
-
const { store, agents } = context.conversationEnvironment;
|
|
168709
|
-
const [conversation, setup, target, request] = await Promise.all([
|
|
168710
|
-
store.read(key),
|
|
168711
|
-
context.setupStore.read(),
|
|
168712
|
-
findReviewTarget(key, context),
|
|
168713
|
-
context.reviewStore.findRequest(key)
|
|
168714
|
-
]);
|
|
168715
|
-
const pending = pendingInboundOf(conversation.journal);
|
|
168716
|
-
const plan4 = planDelivery({
|
|
168717
|
-
pendingCount: pending.length,
|
|
168718
|
-
runningAgent: agents.find(key),
|
|
168719
|
-
listenerPresence: agents.listenerPresence(key),
|
|
168720
|
-
agents: setup.agents,
|
|
168721
|
-
spawnableAgents: spawnableAgentsOf(context),
|
|
168722
|
-
target,
|
|
168723
|
-
now: context.now()
|
|
168724
|
-
});
|
|
168725
|
-
if (plan4.kind === "unavailable") await recordAgentFailure(key, plan4.reason, context);
|
|
168726
|
-
if (plan4.kind !== "spawn") return plan4;
|
|
168727
|
-
const writer = chooseWriter(plan4.install, request, latestModelChoiceOf(conversation.journal, plan4.install.agent));
|
|
168728
|
-
return await spawnAgent({ key, conversation, pending, ...writer, workingPath: plan4.workingPath }, context);
|
|
168729
|
-
};
|
|
168730
|
-
|
|
168731
168079
|
// apps/backend/src/procedures/answer-questions/utils/plan-answers.ts
|
|
168732
168080
|
var MISSING_BATCH_MESSAGE = "The agent did not ask these questions.";
|
|
168733
168081
|
var SETTLED_MESSAGE = "These questions are closed. They were answered already, or the agent stopped waiting.";
|
|
@@ -168791,7 +168139,6 @@ var answerQuestions = async (input2, context) => {
|
|
|
168791
168139
|
],
|
|
168792
168140
|
context
|
|
168793
168141
|
);
|
|
168794
|
-
if (batch.origin === "agent") await deliverToAgent(key, context);
|
|
168795
168142
|
return { kind: "accepted" };
|
|
168796
168143
|
};
|
|
168797
168144
|
|
|
@@ -168929,8 +168276,8 @@ var buildCodeReferenceRoute = publicProcedure.input(buildCodeReferenceInputSchem
|
|
|
168929
168276
|
return reference2;
|
|
168930
168277
|
});
|
|
168931
168278
|
|
|
168932
|
-
// apps/backend/src/procedures/get-review/utils/start/
|
|
168933
|
-
var
|
|
168279
|
+
// apps/backend/src/procedures/get-review/utils/start/live-agents.ts
|
|
168280
|
+
var LIVE_AGENTS = ["claude"];
|
|
168934
168281
|
|
|
168935
168282
|
// apps/backend/src/procedures/get-setup/utils/agent-models.ts
|
|
168936
168283
|
var DEFAULT_EFFORT_OFFER = { effort: DEFAULT_EFFORT, label: "Default" };
|
|
@@ -168983,6 +168330,14 @@ var listModelsOf = async (agents, environment) => {
|
|
|
168983
168330
|
var agentsWithCli = (detections) => detections.filter((detection) => detection.hasCli).map((detection) => detection.agent);
|
|
168984
168331
|
var listOfferedModels = async (detections, choice, environment) => await listModelsOf([.../* @__PURE__ */ new Set([...agentsWithCli(detections), ...installedAgentsOf(choice)])], environment);
|
|
168985
168332
|
|
|
168333
|
+
// apps/backend/src/procedures/get-model-choice/utils/choose-writer.ts
|
|
168334
|
+
var writerOfRequest = (install, request) => request?.writer.kind === "agent" && request.writer.agent === install.agent ? { install: { ...install, model: request.writer.model }, effort: request.writer.effort } : { install, effort: install.effort };
|
|
168335
|
+
var chooseWriter = (install, request, modelChoice) => modelChoice?.agent === install.agent ? { install: { ...install, model: modelChoice.model }, effort: modelChoice.effort } : writerOfRequest(install, request);
|
|
168336
|
+
var chooseInstall = (agents, liveAgents) => {
|
|
168337
|
+
const candidates = agents.installs.filter((install) => liveAgents.includes(install.agent));
|
|
168338
|
+
return candidates.find((install) => install.agent === agents.defaultAgent) ?? candidates.at(0) ?? null;
|
|
168339
|
+
};
|
|
168340
|
+
|
|
168986
168341
|
// apps/backend/src/procedures/get-model-choice/utils/chat-writer.ts
|
|
168987
168342
|
var readChatWriter = async (key, context) => {
|
|
168988
168343
|
const [setup, conversation, request] = await Promise.all([
|
|
@@ -168990,8 +168345,7 @@ var readChatWriter = async (key, context) => {
|
|
|
168990
168345
|
context.conversationEnvironment.store.read(key),
|
|
168991
168346
|
context.reviewStore.findRequest(key)
|
|
168992
168347
|
]);
|
|
168993
|
-
const
|
|
168994
|
-
const install = setup.agents === null ? null : chooseInstall(setup.agents, startableAgents);
|
|
168348
|
+
const install = setup.agents === null ? null : chooseInstall(setup.agents, LIVE_AGENTS);
|
|
168995
168349
|
if (install === null) return null;
|
|
168996
168350
|
const writer = chooseWriter(install, request, latestModelChoiceOf(conversation.journal, install.agent));
|
|
168997
168351
|
const agentModels = await listModelsOf([install.agent], context.setupEnvironment);
|
|
@@ -169568,8 +168922,8 @@ var plan = (artifact, segments) => ({
|
|
|
169568
168922
|
kind: "planned",
|
|
169569
168923
|
artifact: { ...artifact, segments, isSegmented: artifact.isSegmented || segments.length > 1 }
|
|
169570
168924
|
});
|
|
169571
|
-
var
|
|
169572
|
-
var unchangedFilesMessage = (paths) => `${paths.length === 1 ? "This file is not a changed file" : "These files are not changed files"} of the Flight Plan: ${
|
|
168925
|
+
var quoted6 = (paths) => paths.map((path11) => `\`${path11}\``).join(", ");
|
|
168926
|
+
var unchangedFilesMessage = (paths) => `${paths.length === 1 ? "This file is not a changed file" : "These files are not changed files"} of the Flight Plan: ${quoted6(paths)}.`;
|
|
169573
168927
|
var inOrder4 = (paths) => [...new Set(paths)].sort((one, two) => one.localeCompare(two));
|
|
169574
168928
|
var normalize3 = ({ title, paths }) => ({ title: title.trim(), paths: inOrder4(paths) });
|
|
169575
168929
|
var contentProblemOf = (artifact, { title, paths }) => {
|
|
@@ -170061,7 +169415,7 @@ var editWalkthroughRoute = publicProcedure.input(editWalkthroughInputSchema).out
|
|
|
170061
169415
|
});
|
|
170062
169416
|
|
|
170063
169417
|
// apps/backend/src/procedures/get-author-form/index.ts
|
|
170064
|
-
var
|
|
169418
|
+
var import_node_path19 = require("node:path");
|
|
170065
169419
|
|
|
170066
169420
|
// apps/backend/src/procedures/get-setup/utils/build-repositories-step.ts
|
|
170067
169421
|
var COMMIT_SEARCH_PLACEHOLDER = "Type a name or email";
|
|
@@ -170123,7 +169477,7 @@ var getAuthorForm = async (input2, context) => {
|
|
|
170123
169477
|
context.setupEnvironment.findRepositoryForge(path11, setup.forges),
|
|
170124
169478
|
context.setupEnvironment.readGitIdentity(path11)
|
|
170125
169479
|
]);
|
|
170126
|
-
return buildAuthorForm(forge, identity2, (0,
|
|
169480
|
+
return buildAuthorForm(forge, identity2, (0, import_node_path19.basename)(path11));
|
|
170127
169481
|
};
|
|
170128
169482
|
|
|
170129
169483
|
// apps/backend/src/procedures/get-setup/utils/forge-catalog.ts
|
|
@@ -170579,13 +169933,9 @@ var getConfigurationCreationFormRoute = publicProcedure.output(configurationCrea
|
|
|
170579
169933
|
|
|
170580
169934
|
// apps/backend/src/procedures/get-conversation/utils/build-conversation.ts
|
|
170581
169935
|
var parseMessage = (body) => parseProse(body, new Set(codeLinkIdsIn([body])));
|
|
170582
|
-
var
|
|
170583
|
-
|
|
170584
|
-
|
|
170585
|
-
"working": "Agent working",
|
|
170586
|
-
"waiting-for-reviewer": "Agent waiting for your answers",
|
|
170587
|
-
"listening": "Agent listening",
|
|
170588
|
-
"failed": "Agent could not start"
|
|
169936
|
+
var AGENT_STATE_LABELS = {
|
|
169937
|
+
online: "Agent online",
|
|
169938
|
+
offline: "Agent offline"
|
|
170589
169939
|
};
|
|
170590
169940
|
var REVIEWER_LABEL = "You";
|
|
170591
169941
|
var AGENT_LABEL = "Agent";
|
|
@@ -170603,17 +169953,7 @@ var PANEL_LABELS = {
|
|
|
170603
169953
|
placeholder: "Ask about this review",
|
|
170604
169954
|
sendLabel: "Send"
|
|
170605
169955
|
};
|
|
170606
|
-
var EMPTY_MESSAGE = "Ask about this review.
|
|
170607
|
-
var runningStateOf = (agent) => {
|
|
170608
|
-
if (agent.phase === "starting") return "starting";
|
|
170609
|
-
return agent.isAwaitingPermission ? "waiting-for-reviewer" : "working";
|
|
170610
|
-
};
|
|
170611
|
-
var agentStateOf = ({ conversation, runningAgent, listenerPresence }) => {
|
|
170612
|
-
if (runningAgent !== null && runningAgent.closing === null) return runningStateOf(runningAgent);
|
|
170613
|
-
if (listenerPresence.openCount > 0) return "listening";
|
|
170614
|
-
if (openQuestionBatchesOf(conversation.journal).length > 0) return "waiting-for-reviewer";
|
|
170615
|
-
return latestFailureOf(conversation.journal) === null ? "not-running" : "failed";
|
|
170616
|
-
};
|
|
169956
|
+
var EMPTY_MESSAGE = "Ask about this review. Your agent answers here once it is online.";
|
|
170617
169957
|
var headingOf2 = (batch) => {
|
|
170618
169958
|
if (batch.origin === "permission") return PERMISSION_HEADING;
|
|
170619
169959
|
return batch.questions.length === 1 ? "The agent asks a question" : `The agent asks ${String(batch.questions.length)} questions`;
|
|
@@ -170687,30 +170027,25 @@ var toEntry = ({ event }, journal, now) => {
|
|
|
170687
170027
|
};
|
|
170688
170028
|
var buildConversation2 = (snapshot, now) => {
|
|
170689
170029
|
const { journal } = snapshot.conversation;
|
|
170690
|
-
const agentState =
|
|
170030
|
+
const agentState = snapshot.isAgentOnline ? "online" : "offline";
|
|
170691
170031
|
const entries = journal.map((entry) => toEntry(entry, journal, now)).filter((entry) => entry !== null);
|
|
170692
170032
|
return {
|
|
170693
170033
|
...PANEL_LABELS,
|
|
170694
170034
|
emptyMessage: entries.length === 0 ? EMPTY_MESSAGE : null,
|
|
170695
170035
|
agentState,
|
|
170696
|
-
agentStateLabel:
|
|
170697
|
-
problem: agentState === "failed" ? latestFailureOf(journal)?.reason ?? null : null,
|
|
170036
|
+
agentStateLabel: AGENT_STATE_LABELS[agentState],
|
|
170698
170037
|
entries
|
|
170699
170038
|
};
|
|
170700
170039
|
};
|
|
170701
170040
|
|
|
170702
170041
|
// apps/backend/src/procedures/get-conversation/index.ts
|
|
170703
170042
|
var getConversation = async (input2, context) => {
|
|
170704
|
-
const
|
|
170705
|
-
|
|
170706
|
-
return buildConversation2(
|
|
170707
|
-
{ conversation, runningAgent: agents.find(input2), listenerPresence: agents.listenerPresence(input2) },
|
|
170708
|
-
context.now()
|
|
170709
|
-
);
|
|
170043
|
+
const conversation = await context.conversationEnvironment.store.read(input2);
|
|
170044
|
+
return buildConversation2({ conversation, isAgentOnline: isAgentOnlineFor(input2, context) }, context.now());
|
|
170710
170045
|
};
|
|
170711
170046
|
|
|
170712
170047
|
// apps/backend/src/procedures/get-conversation/utils/schemas.ts
|
|
170713
|
-
var AGENT_STATES = ["
|
|
170048
|
+
var AGENT_STATES = ["online", "offline"];
|
|
170714
170049
|
var QUESTIONS_STATUSES = ["open", "answered", "withdrawn"];
|
|
170715
170050
|
var conversationKeySchema = external_exports.strictObject({
|
|
170716
170051
|
repositoryName: external_exports.string().min(1),
|
|
@@ -170755,7 +170090,6 @@ var conversationViewSchema = external_exports.strictObject({
|
|
|
170755
170090
|
sendLabel: external_exports.string(),
|
|
170756
170091
|
agentState: external_exports.enum(AGENT_STATES),
|
|
170757
170092
|
agentStateLabel: external_exports.string(),
|
|
170758
|
-
problem: external_exports.string().nullable(),
|
|
170759
170093
|
entries: external_exports.array(external_exports.discriminatedUnion("kind", [messageEntrySchema, questionsEntrySchema]))
|
|
170760
170094
|
});
|
|
170761
170095
|
|
|
@@ -170867,9 +170201,9 @@ var getFileCodeRoute = publicProcedure.input(getFileCodeInputSchema).output(file
|
|
|
170867
170201
|
// apps/backend/src/procedures/import-review/utils/import-request.ts
|
|
170868
170202
|
var importIdOf = (request) => request.requestedAt.toISOString();
|
|
170869
170203
|
var LISTENER_IMPORT_WAIT_MS = 6e5;
|
|
170870
|
-
var isImportUnderway = (request,
|
|
170204
|
+
var isImportUnderway = (request, isAgentOnline2, now) => {
|
|
170871
170205
|
if (request?.importedAt !== null) return false;
|
|
170872
|
-
return request.channel === "agent" ?
|
|
170206
|
+
return request.channel === "agent" ? isAgentOnline2 : now.getTime() - request.requestedAt.getTime() < LISTENER_IMPORT_WAIT_MS;
|
|
170873
170207
|
};
|
|
170874
170208
|
|
|
170875
170209
|
// apps/backend/src/procedures/get-import-form/utils/build-import-form.ts
|
|
@@ -170963,7 +170297,7 @@ var getImportForm = async (input2, context) => {
|
|
|
170963
170297
|
target,
|
|
170964
170298
|
hasFlightPlan: artifact !== null,
|
|
170965
170299
|
request,
|
|
170966
|
-
isImporting: isImportUnderway(request,
|
|
170300
|
+
isImporting: isImportUnderway(request, isAgentOnlineFor(key, context), context.now())
|
|
170967
170301
|
});
|
|
170968
170302
|
};
|
|
170969
170303
|
|
|
@@ -170994,6 +170328,85 @@ var importFormSchema = external_exports.strictObject({
|
|
|
170994
170328
|
// apps/backend/src/server/trpc/routes/get-import-form/index.ts
|
|
170995
170329
|
var getImportFormRoute = publicProcedure.input(getImportFormInputSchema).output(importFormSchema).query(async ({ ctx, input: input2 }) => await getImportForm(input2, ctx));
|
|
170996
170330
|
|
|
170331
|
+
// apps/backend/src/procedures/get-write-up-plan/utils/default-writer.ts
|
|
170332
|
+
var defaultWriterOf = (agents, startableAgents) => {
|
|
170333
|
+
const install = agents?.installs.find((candidate) => candidate.agent === agents.defaultAgent) ?? agents?.installs.at(0);
|
|
170334
|
+
if (install === void 0) return null;
|
|
170335
|
+
return {
|
|
170336
|
+
agent: install.agent,
|
|
170337
|
+
label: AGENT_LABELS[install.agent],
|
|
170338
|
+
writer: startableAgents.includes(install.agent) ? { kind: "agent", agent: install.agent, model: install.model, effort: install.effort } : { kind: "external", agent: install.agent }
|
|
170339
|
+
};
|
|
170340
|
+
};
|
|
170341
|
+
|
|
170342
|
+
// apps/backend/src/procedures/get-live-agent/utils/build-live-agent.ts
|
|
170343
|
+
var externalLivePromptOf = (key) => `Use the flightplan-review skill and Flight Plan's MCP tools on repositoryName "${key.repositoryName}" and targetId "${key.targetId}". Write what the review still needs, answer the reviewer, and keep listening with the curl command the tools give you.`;
|
|
170344
|
+
var promptOf = (facts) => facts.isLiveAgent ? liveCommandOf(facts.key) : externalLivePromptOf(facts.key);
|
|
170345
|
+
var dialogOf = (facts) => {
|
|
170346
|
+
const agentLabel = AGENT_LABELS[facts.agent];
|
|
170347
|
+
return {
|
|
170348
|
+
title: `${agentLabel} is offline`,
|
|
170349
|
+
description: `${agentLabel} writes up this review and answers you in Chat. Start it in a terminal and leave it open while you review.`,
|
|
170350
|
+
terminal: facts.isLiveAgent && facts.canOpenTerminal ? { label: "Open a terminal for me", description: `Flight Plan opens Terminal in the repository's folder and starts ${agentLabel} there.` } : null,
|
|
170351
|
+
manual: {
|
|
170352
|
+
label: "I'll start it myself",
|
|
170353
|
+
description: `Start ${agentLabel} in the repository's folder and run this.`,
|
|
170354
|
+
prompt: promptOf(facts),
|
|
170355
|
+
copyLabel: "Copy the command",
|
|
170356
|
+
copiedMessage: "Command copied"
|
|
170357
|
+
},
|
|
170358
|
+
closeLabel: "Not now"
|
|
170359
|
+
};
|
|
170360
|
+
};
|
|
170361
|
+
var buildLiveAgent = (facts) => ({
|
|
170362
|
+
kind: "live",
|
|
170363
|
+
isOnline: facts.isOnline,
|
|
170364
|
+
statusLabel: `${AGENT_LABELS[facts.agent]} ${facts.isOnline ? "online" : "offline"}`,
|
|
170365
|
+
dialog: dialogOf(facts)
|
|
170366
|
+
});
|
|
170367
|
+
|
|
170368
|
+
// apps/backend/src/procedures/get-live-agent/index.ts
|
|
170369
|
+
var UNAVAILABLE = { kind: "unavailable" };
|
|
170370
|
+
var getLiveAgent = async (input2, context) => {
|
|
170371
|
+
const key = { repositoryName: input2.repositoryName, targetId: input2.targetId };
|
|
170372
|
+
const [target, setup] = await Promise.all([findReviewTarget(key, context), context.setupStore.read()]);
|
|
170373
|
+
const writer = defaultWriterOf(setup.agents, LIVE_AGENTS);
|
|
170374
|
+
if (target.kind === "rejected" || writer === null) return UNAVAILABLE;
|
|
170375
|
+
return buildLiveAgent({
|
|
170376
|
+
key,
|
|
170377
|
+
agent: writer.agent,
|
|
170378
|
+
isLiveAgent: writer.writer.kind === "agent",
|
|
170379
|
+
canOpenTerminal: context.openTerminal !== null,
|
|
170380
|
+
isOnline: isAgentOnlineFor(key, context)
|
|
170381
|
+
});
|
|
170382
|
+
};
|
|
170383
|
+
|
|
170384
|
+
// apps/backend/src/procedures/get-live-agent/utils/schemas.ts
|
|
170385
|
+
var getLiveAgentInputSchema = external_exports.strictObject({
|
|
170386
|
+
repositoryName: external_exports.string().min(1),
|
|
170387
|
+
targetId: external_exports.string().min(1)
|
|
170388
|
+
});
|
|
170389
|
+
var optionSchema = external_exports.strictObject({ label: external_exports.string(), description: external_exports.string() });
|
|
170390
|
+
var launchAgentDialogSchema = external_exports.strictObject({
|
|
170391
|
+
title: external_exports.string(),
|
|
170392
|
+
description: external_exports.string(),
|
|
170393
|
+
terminal: optionSchema.nullable(),
|
|
170394
|
+
manual: optionSchema.extend({ prompt: external_exports.string(), copyLabel: external_exports.string(), copiedMessage: external_exports.string() }),
|
|
170395
|
+
closeLabel: external_exports.string()
|
|
170396
|
+
});
|
|
170397
|
+
var liveAgentSchema = external_exports.discriminatedUnion("kind", [
|
|
170398
|
+
external_exports.strictObject({
|
|
170399
|
+
kind: external_exports.literal("live"),
|
|
170400
|
+
isOnline: external_exports.boolean(),
|
|
170401
|
+
statusLabel: external_exports.string(),
|
|
170402
|
+
dialog: launchAgentDialogSchema
|
|
170403
|
+
}),
|
|
170404
|
+
external_exports.strictObject({ kind: external_exports.literal("unavailable") })
|
|
170405
|
+
]);
|
|
170406
|
+
|
|
170407
|
+
// apps/backend/src/server/trpc/routes/get-live-agent/index.ts
|
|
170408
|
+
var getLiveAgentRoute = publicProcedure.input(getLiveAgentInputSchema).output(liveAgentSchema).query(async ({ ctx, input: input2 }) => await getLiveAgent(input2, ctx));
|
|
170409
|
+
|
|
170997
170410
|
// apps/backend/src/procedures/get-model-choice/utils/build-model-choice.ts
|
|
170998
170411
|
var MINIMUM_OFFER_COUNT = 2;
|
|
170999
170412
|
var NEXT_TURN_HINT = "The agent uses it from its next turn.";
|
|
@@ -171619,7 +171032,7 @@ var STEP_PURPOSES = {
|
|
|
171619
171032
|
agents: "Configure how Flight Plan communicates with your agent",
|
|
171620
171033
|
configuration: "Configure how Flight Plan puts your reviews together"
|
|
171621
171034
|
};
|
|
171622
|
-
var
|
|
171035
|
+
var STATE_LABELS = {
|
|
171623
171036
|
saved: "Saved",
|
|
171624
171037
|
current: "Current step",
|
|
171625
171038
|
upcoming: "Not reached"
|
|
@@ -171663,7 +171076,7 @@ var toRouteStop = (setup, step, currentStep, agentModels) => {
|
|
|
171663
171076
|
step,
|
|
171664
171077
|
label: STEP_LABELS[step],
|
|
171665
171078
|
state,
|
|
171666
|
-
stateLabel:
|
|
171079
|
+
stateLabel: STATE_LABELS[state],
|
|
171667
171080
|
isReachable: isStepReachable(setup, step),
|
|
171668
171081
|
lines: [...SUMMARY_LINES[step](setup, agentModels) ?? [[plain5(STEP_PURPOSES[step])]]]
|
|
171669
171082
|
};
|
|
@@ -171794,11 +171207,11 @@ var listRepositories = async (input2, context) => {
|
|
|
171794
171207
|
var SEARCH_PLACEHOLDER = "Search by title or author";
|
|
171795
171208
|
var NO_TARGETS_LABEL = "No other branches are listed in this repository.";
|
|
171796
171209
|
var NO_MATCH_LABEL = "No pull request or branch matches.";
|
|
171797
|
-
var
|
|
171210
|
+
var WHITESPACE_PATTERN3 = /\s+/;
|
|
171798
171211
|
var headingOf3 = (repository) => `Branches in ${repository.name}`;
|
|
171799
171212
|
var isListed = (currentTargetId) => (target) => DEFAULT_STATUSES.includes(target.branchStatus) || targetIdOf3(target) === currentTargetId;
|
|
171800
171213
|
var searchTextOf2 = (target) => (target.kind === "pull-request" ? `${target.title} #${String(target.number)} ${target.branch} ${target.author}` : target.name).toLowerCase();
|
|
171801
|
-
var termsOf2 = (query) => query.toLowerCase().split(
|
|
171214
|
+
var termsOf2 = (query) => query.toLowerCase().split(WHITESPACE_PATTERN3).filter((term) => term !== "");
|
|
171802
171215
|
var matchesEvery2 = (terms) => (target) => {
|
|
171803
171216
|
const searchText = searchTextOf2(target);
|
|
171804
171217
|
return terms.every((term) => searchText.includes(term));
|
|
@@ -171900,17 +171313,6 @@ var buildWriteUpPlan = (source) => ({
|
|
|
171900
171313
|
isSegmented: source.isSegmented
|
|
171901
171314
|
});
|
|
171902
171315
|
|
|
171903
|
-
// apps/backend/src/procedures/get-write-up-plan/utils/default-writer.ts
|
|
171904
|
-
var defaultWriterOf = (agents, startableAgents) => {
|
|
171905
|
-
const install = agents?.installs.find((candidate) => candidate.agent === agents.defaultAgent) ?? agents?.installs.at(0);
|
|
171906
|
-
if (install === void 0) return null;
|
|
171907
|
-
return {
|
|
171908
|
-
agent: install.agent,
|
|
171909
|
-
label: AGENT_LABELS[install.agent],
|
|
171910
|
-
writer: startableAgents.includes(install.agent) ? { kind: "agent", agent: install.agent, model: install.model, effort: install.effort } : { kind: "external", agent: install.agent }
|
|
171911
|
-
};
|
|
171912
|
-
};
|
|
171913
|
-
|
|
171914
171316
|
// apps/backend/src/procedures/get-write-up-plan/utils/write-up-counts.ts
|
|
171915
171317
|
var SECTION_OF_TARGET = {
|
|
171916
171318
|
"context": "context",
|
|
@@ -171946,7 +171348,7 @@ var getWriteUpPlan = async (input2, context) => {
|
|
|
171946
171348
|
context.configurationStore.read()
|
|
171947
171349
|
]);
|
|
171948
171350
|
if (artifact === null) return null;
|
|
171949
|
-
const writer = defaultWriterOf(setup.agents,
|
|
171351
|
+
const writer = defaultWriterOf(setup.agents, LIVE_AGENTS);
|
|
171950
171352
|
if (writer === null) return { kind: "no-agent", message: NO_AGENT_MESSAGE2 };
|
|
171951
171353
|
const preferences = reviewPreferencesOf(setup.reviewPreferences);
|
|
171952
171354
|
return buildWriteUpPlan({
|
|
@@ -172023,14 +171425,8 @@ var fetchingRequestOf = (key, artifactUrl, destinationPath) => [
|
|
|
172023
171425
|
// apps/backend/src/procedures/import-review/index.ts
|
|
172024
171426
|
var NOT_AN_ARTIFACT_MESSAGE3 = "That is not the address of a Claude artifact.";
|
|
172025
171427
|
var STARTED_MESSAGE = "Asked your agent to fetch the Flight Plan.";
|
|
172026
|
-
var NO_AGENT_PREFIX = "No agent could be asked to fetch it.";
|
|
172027
|
-
var channelOf = (outcome) => {
|
|
172028
|
-
if (outcome.kind === "spawned" || outcome.kind === "agent-running") return "agent";
|
|
172029
|
-
return outcome.kind === "listener-waiting" ? "listener" : null;
|
|
172030
|
-
};
|
|
172031
171428
|
var refused2 = (message) => ({ importId: null, message });
|
|
172032
171429
|
var started = (request) => ({ importId: importIdOf(request), message: STARTED_MESSAGE });
|
|
172033
|
-
var reasonOf4 = (outcome) => outcome.kind === "unavailable" || outcome.kind === "failed" ? `${NO_AGENT_PREFIX} ${outcome.reason}` : NO_AGENT_PREFIX;
|
|
172034
171430
|
var importReview = async (input2, context) => {
|
|
172035
171431
|
if (!isClaudeArtifactUrl(input2.artifactUrl)) return refused2(NOT_AN_ARTIFACT_MESSAGE3);
|
|
172036
171432
|
const key = { repositoryName: input2.repositoryName, targetId: input2.targetId };
|
|
@@ -172038,8 +171434,7 @@ var importReview = async (input2, context) => {
|
|
|
172038
171434
|
if (target.kind === "rejected") return refused2(target.message);
|
|
172039
171435
|
const requestedAt = context.now();
|
|
172040
171436
|
const underway = await context.reviewStore.readImportRequest(key);
|
|
172041
|
-
|
|
172042
|
-
if (underway !== null && isImportUnderway(underway, isAgentRunning, requestedAt)) return started(underway);
|
|
171437
|
+
if (underway !== null && isImportUnderway(underway, isAgentOnlineFor(key, context), requestedAt)) return started(underway);
|
|
172043
171438
|
await appendAndPublish(
|
|
172044
171439
|
key,
|
|
172045
171440
|
[{
|
|
@@ -172051,10 +171446,7 @@ var importReview = async (input2, context) => {
|
|
|
172051
171446
|
}],
|
|
172052
171447
|
context
|
|
172053
171448
|
);
|
|
172054
|
-
const
|
|
172055
|
-
const channel = channelOf(outcome);
|
|
172056
|
-
if (channel === null) return refused2(reasonOf4(outcome));
|
|
172057
|
-
const request = { artifactUrl: input2.artifactUrl, channel, requestedAt, importedAt: null };
|
|
171449
|
+
const request = { artifactUrl: input2.artifactUrl, channel: "agent", requestedAt, importedAt: null };
|
|
172058
171450
|
await context.reviewStore.writeImportRequest(key, request);
|
|
172059
171451
|
return started(request);
|
|
172060
171452
|
};
|
|
@@ -172126,13 +171518,13 @@ var listCardBlocksRoute = publicProcedure.input(listCardBlocksInputSchema).outpu
|
|
|
172126
171518
|
var listConfigurationsRoute = publicProcedure.output(configurationListSchema).query(async ({ ctx }) => listConfigurations(ctx));
|
|
172127
171519
|
|
|
172128
171520
|
// apps/backend/src/procedures/list-recent-repositories/utils/build-recent-repositories.ts
|
|
172129
|
-
var
|
|
171521
|
+
var import_node_path20 = require("node:path");
|
|
172130
171522
|
var NO_RECENT_REPOSITORY_MESSAGE = "No repository in your home folder has a commit from you on main or master.";
|
|
172131
171523
|
var toRecentRepository = ({ path: path11, activity }, addedPaths) => {
|
|
172132
171524
|
const stateLabel = addedLabelOf(path11, addedPaths);
|
|
172133
171525
|
return {
|
|
172134
171526
|
path: path11,
|
|
172135
|
-
name: (0,
|
|
171527
|
+
name: (0, import_node_path20.basename)(path11),
|
|
172136
171528
|
branch: activity.branch,
|
|
172137
171529
|
latestCommitAt: activity.latestCommitAt.toISOString(),
|
|
172138
171530
|
isAdded: stateLabel !== null,
|
|
@@ -172250,19 +171642,70 @@ var markCompleteRoute = publicProcedure.input(markCompleteInputSchema).output(ma
|
|
|
172250
171642
|
return result;
|
|
172251
171643
|
});
|
|
172252
171644
|
|
|
171645
|
+
// apps/backend/src/procedures/open-agent-terminal/utils/launch-command.ts
|
|
171646
|
+
var FLIGHT_PLAN_TOOLS_RULE = `mcp__plugin_${PLUGIN_NAME}_${MCP_SERVER_NAME}__*`;
|
|
171647
|
+
var CLAUDE_EXECUTABLE = "claude";
|
|
171648
|
+
var SINGLE_QUOTE = "'";
|
|
171649
|
+
var ESCAPED_SINGLE_QUOTE = String.raw`'\''`;
|
|
171650
|
+
var quoteForShell = (text2) => `${SINGLE_QUOTE}${text2.replaceAll(SINGLE_QUOTE, ESCAPED_SINGLE_QUOTE)}${SINGLE_QUOTE}`;
|
|
171651
|
+
var claudeLiveArguments = (launch2) => [
|
|
171652
|
+
launch2.prompt,
|
|
171653
|
+
...launch2.model === DEFAULT_MODEL ? [] : ["--model", launch2.model],
|
|
171654
|
+
...launch2.effort === DEFAULT_EFFORT ? [] : ["--effort", launch2.effort],
|
|
171655
|
+
"--allowedTools",
|
|
171656
|
+
FLIGHT_PLAN_TOOLS_RULE,
|
|
171657
|
+
listenPermissionRuleOf(launch2.serverUrl)
|
|
171658
|
+
];
|
|
171659
|
+
var buildLaunchCommand = (launch2) => [
|
|
171660
|
+
`cd ${quoteForShell(launch2.workingPath)}`,
|
|
171661
|
+
[CLAUDE_EXECUTABLE, ...claudeLiveArguments(launch2).map(quoteForShell)].join(" ")
|
|
171662
|
+
].join(" && ");
|
|
171663
|
+
|
|
171664
|
+
// apps/backend/src/procedures/open-agent-terminal/index.ts
|
|
171665
|
+
var NO_TERMINAL_MESSAGE = "Flight Plan can open a terminal on macOS only. Copy the command and run it yourself.";
|
|
171666
|
+
var NO_LIVE_AGENT_MESSAGE = "Flight Plan can start only Claude in a terminal. Copy the command and run it yourself.";
|
|
171667
|
+
var rejected2 = (message) => ({ kind: "rejected", message });
|
|
171668
|
+
var failedMessageOf = (reason) => `Flight Plan could not open Terminal. ${reason}`;
|
|
171669
|
+
var openAgentTerminal = async (input2, context) => {
|
|
171670
|
+
const key = { repositoryName: input2.repositoryName, targetId: input2.targetId };
|
|
171671
|
+
const { openTerminal } = context;
|
|
171672
|
+
if (openTerminal === null) return rejected2(NO_TERMINAL_MESSAGE);
|
|
171673
|
+
const [target, setup, conversation, request] = await Promise.all([
|
|
171674
|
+
findReviewTarget(key, context),
|
|
171675
|
+
context.setupStore.read(),
|
|
171676
|
+
context.conversationEnvironment.store.read(key),
|
|
171677
|
+
context.reviewStore.findRequest(key)
|
|
171678
|
+
]);
|
|
171679
|
+
if (target.kind === "rejected") return target;
|
|
171680
|
+
const install = setup.agents === null ? null : chooseInstall(setup.agents, LIVE_AGENTS);
|
|
171681
|
+
if (install === null) return rejected2(NO_LIVE_AGENT_MESSAGE);
|
|
171682
|
+
const writer = chooseWriter(install, request, latestModelChoiceOf(conversation.journal, install.agent));
|
|
171683
|
+
const opening = await openTerminal(buildLaunchCommand({
|
|
171684
|
+
workingPath: target.workingPath,
|
|
171685
|
+
prompt: liveCommandOf(key),
|
|
171686
|
+
model: writer.install.model,
|
|
171687
|
+
effort: writer.effort,
|
|
171688
|
+
serverUrl: context.conversationEnvironment.serverUrl
|
|
171689
|
+
}));
|
|
171690
|
+
return opening.kind === "opened" ? { kind: "opened", message: `${AGENT_LABELS[install.agent]} is starting in Terminal.` } : rejected2(failedMessageOf(opening.reason));
|
|
171691
|
+
};
|
|
171692
|
+
|
|
171693
|
+
// apps/backend/src/procedures/open-agent-terminal/utils/schemas.ts
|
|
171694
|
+
var openAgentTerminalInputSchema = external_exports.strictObject({
|
|
171695
|
+
repositoryName: external_exports.string().min(1),
|
|
171696
|
+
targetId: external_exports.string().min(1)
|
|
171697
|
+
});
|
|
171698
|
+
var agentTerminalOpeningSchema = external_exports.discriminatedUnion("kind", [
|
|
171699
|
+
external_exports.strictObject({ kind: external_exports.literal("opened"), message: external_exports.string() }),
|
|
171700
|
+
external_exports.strictObject({ kind: external_exports.literal("rejected"), message: external_exports.string() })
|
|
171701
|
+
]);
|
|
171702
|
+
|
|
171703
|
+
// apps/backend/src/server/trpc/routes/open-agent-terminal/index.ts
|
|
171704
|
+
var openAgentTerminalRoute = publicProcedure.input(openAgentTerminalInputSchema).output(agentTerminalOpeningSchema).mutation(async ({ ctx, input: input2 }) => await openAgentTerminal(input2, ctx));
|
|
171705
|
+
|
|
172253
171706
|
// apps/backend/src/procedures/publish-artifact/index.ts
|
|
172254
171707
|
var REQUESTED_MESSAGE = "Asked your agent to publish it. The link shows under Share when it is done.";
|
|
172255
171708
|
var PAGE_NOT_BUILT_MESSAGE = "This build of Flight Plan has no page to publish.";
|
|
172256
|
-
var NO_AGENT_PREFIX2 = "No agent could be asked to publish it.";
|
|
172257
|
-
var reportOf = (outcome) => outcome.kind === "unavailable" || outcome.kind === "failed" ? { message: `${NO_AGENT_PREFIX2} ${outcome.reason}` } : { message: REQUESTED_MESSAGE };
|
|
172258
|
-
var channelOf2 = (outcome) => {
|
|
172259
|
-
if (outcome.kind === "spawned" || outcome.kind === "agent-running") return "agent";
|
|
172260
|
-
return outcome.kind === "listener-waiting" ? "listener" : null;
|
|
172261
|
-
};
|
|
172262
|
-
var requestOf2 = (outcome, requestedAt) => {
|
|
172263
|
-
const channel = channelOf2(outcome);
|
|
172264
|
-
return channel === null ? null : { requestedAt, channel };
|
|
172265
|
-
};
|
|
172266
171709
|
var attachToDescription = async (key, context) => {
|
|
172267
171710
|
const [artifact, detail, publications] = await Promise.all([
|
|
172268
171711
|
context.reviewStore.findArtifact(key),
|
|
@@ -172293,9 +171736,8 @@ var requestClaudeArtifact = async (key, context) => {
|
|
|
172293
171736
|
}],
|
|
172294
171737
|
context
|
|
172295
171738
|
);
|
|
172296
|
-
|
|
172297
|
-
|
|
172298
|
-
return reportOf(outcome);
|
|
171739
|
+
await context.reviewStore.writePublishingRequest(key, { requestedAt, channel: "agent" });
|
|
171740
|
+
return { message: REQUESTED_MESSAGE };
|
|
172299
171741
|
};
|
|
172300
171742
|
var publishArtifact = async (input2, context) => {
|
|
172301
171743
|
const key = { repositoryName: input2.repositoryName, targetId: input2.targetId };
|
|
@@ -172395,33 +171837,83 @@ var requestReviewer = async (input2, context) => {
|
|
|
172395
171837
|
var requestReviewerRoute = publicProcedure.input(reviewerLoginInputSchema).output(reviewActionOutputSchema).mutation(async ({ ctx, input: input2 }) => toActionOutput(await requestReviewer(input2, ctx)));
|
|
172396
171838
|
|
|
172397
171839
|
// apps/backend/src/procedures/request-review/index.ts
|
|
172398
|
-
var STARTED_MESSAGE2 = "Review started";
|
|
172399
171840
|
var CREATED_MESSAGE = "Flight Plan created";
|
|
172400
171841
|
var externalStartMessage = (agent) => `Run this line in ${AGENT_LABELS[agent]} to start explaining the review`;
|
|
172401
|
-
var
|
|
172402
|
-
var startedMessageOf = (outcome) => {
|
|
172403
|
-
if (outcome.kind === "failed" || outcome.kind === "unavailable") return unstartedMessage(outcome.reason);
|
|
172404
|
-
return STARTED_MESSAGE2;
|
|
172405
|
-
};
|
|
171842
|
+
var sentMessageOf = (agent) => `Sent to ${AGENT_LABELS[agent]}`;
|
|
172406
171843
|
var sendToAgent = async (key, prompt, context) => {
|
|
172407
171844
|
await appendAndPublish(
|
|
172408
171845
|
key,
|
|
172409
171846
|
[{ kind: "reviewer-message", id: context.conversationEnvironment.newId(), body: prompt, reference: null, sentAt: context.now() }],
|
|
172410
171847
|
context
|
|
172411
171848
|
);
|
|
172412
|
-
return await deliverToAgent(key, context);
|
|
172413
171849
|
};
|
|
172414
|
-
var startAgent = async (key, prompt, context) => startedMessageOf(await sendToAgent(key, prompt, context));
|
|
172415
171850
|
var handToWriter = async ({ key, repository, target, request }, context) => {
|
|
172416
171851
|
const { writer } = request;
|
|
172417
171852
|
if (writer.kind === "author" || writer.kind === "none") return { prompt: null, message: CREATED_MESSAGE };
|
|
172418
171853
|
const prompt = buildReviewPrompt(repository, target, key, request.writeUp);
|
|
172419
|
-
|
|
171854
|
+
if (writer.kind === "external") return { prompt: toOneLine(prompt), message: externalStartMessage(writer.agent) };
|
|
171855
|
+
await sendToAgent(key, prompt, context);
|
|
171856
|
+
return { prompt: null, message: sentMessageOf(writer.agent) };
|
|
171857
|
+
};
|
|
171858
|
+
|
|
171859
|
+
// apps/backend/src/procedures/request-write-up/utils/plan-node-write-up.ts
|
|
171860
|
+
var DRAFTING_STATUS3 = "drafting";
|
|
171861
|
+
var ALREADY_WRITTEN = { kind: "written", message: "This is already explained." };
|
|
171862
|
+
var rejected3 = (message) => ({ kind: "rejected", field: "target", message });
|
|
171863
|
+
var planned = (artifact, ask, message) => ({ kind: "planned", artifact: { ...artifact, status: DRAFTING_STATUS3 }, ask, message });
|
|
171864
|
+
var quoted7 = (text2) => `\`${text2}\``;
|
|
171865
|
+
var listWaypoints3 = (artifact) => artifact.segments.flatMap(waypointsOf).map(({ waypoint }) => waypoint);
|
|
171866
|
+
var isWaypointUnwritten = (waypoint) => waypoint.title === null || waypoint.reading.trim() === "";
|
|
171867
|
+
var waypointIdsOf = (artifact, target) => target.kind === "waypoint" ? listWaypoints3(artifact).filter((waypoint) => waypoint.id === target.waypointId).map((waypoint) => waypoint.id) : listRootBlockWaypointIds(artifact, target.rootBlockId);
|
|
171868
|
+
var waypointAskOf = (ids) => ids.length === 1 ? `The reviewer asks for the write-up of the waypoint ${quoted7(ids[0])} alone: write its title and its reading, and nothing else.` : `The reviewer asks for the write-up of the waypoints ${joinedList2(ids.map(quoted7))} alone: write their titles and readings, and nothing else.`;
|
|
171869
|
+
var planWaypoints = (artifact, target) => {
|
|
171870
|
+
const waypointIds = waypointIdsOf(artifact, target);
|
|
171871
|
+
if (waypointIds.length === 0) {
|
|
171872
|
+
return rejected3(target.kind === "waypoint" ? "This waypoint is not in the review." : "This code block has no waypoint in the review.");
|
|
171873
|
+
}
|
|
171874
|
+
const unwrittenIds = listWaypoints3(artifact).filter((waypoint) => waypointIds.includes(waypoint.id) && isWaypointUnwritten(waypoint)).map((waypoint) => waypoint.id);
|
|
171875
|
+
if (unwrittenIds.length === 0) return ALREADY_WRITTEN;
|
|
171876
|
+
return planned(withRequiredWaypoints(artifact, unwrittenIds), waypointAskOf(unwrittenIds), `Explaining ${countLabel2(unwrittenIds.length, "waypoint", "waypoints")}`);
|
|
171877
|
+
};
|
|
171878
|
+
var isTraceNodeUnwritten = (node2) => node2.label === null || node2.triggerLabels.some((trigger) => trigger.label === null) || node2.blockLabels.some((listed) => listed.label === null);
|
|
171879
|
+
var findTraceNode = (artifact, { segmentId, nodeId }) => listTraceNodes(artifact.segments.find((segment) => segment.id === segmentId)?.traceDiagram?.traceNodes ?? []).find((node2) => node2.id === nodeId);
|
|
171880
|
+
var planTraceNode = (artifact, target) => {
|
|
171881
|
+
const node2 = findTraceNode(artifact, target);
|
|
171882
|
+
if (node2 === void 0) return rejected3("This card is not in the Trace Diagram.");
|
|
171883
|
+
if (!isTraceNodeUnwritten(node2)) return ALREADY_WRITTEN;
|
|
171884
|
+
return planned(
|
|
171885
|
+
withRequiredCard(artifact, target.segmentId, target.nodeId),
|
|
171886
|
+
`The reviewer asks for the write-up of the Trace Diagram node ${quoted7(target.nodeId)} of segment ${quoted7(target.segmentId)} alone: write its label and the labels of its trigger labels and listed blocks, and nothing else.`,
|
|
171887
|
+
"Explaining the card"
|
|
171888
|
+
);
|
|
171889
|
+
};
|
|
171890
|
+
var blastFileIn = (segment, path11) => segment?.blastDiagram?.nodes.find((node2) => node2.path === path11);
|
|
171891
|
+
var findBlastFile = (artifact, { segmentId, path: path11 }) => blastFileIn(artifact.segments.find((segment) => segment.id === segmentId), path11);
|
|
171892
|
+
var blastTargetOf = (artifact, target) => {
|
|
171893
|
+
const isNamedSegment = artifact.segments.some((segment) => segment.id === target.segmentId);
|
|
171894
|
+
if (artifact.isSegmented || !isNamedSegment || findBlastFile(artifact, target) !== void 0) return target;
|
|
171895
|
+
const holder = artifact.segments.find((segment) => blastFileIn(segment, target.path) !== void 0);
|
|
171896
|
+
return holder === void 0 ? target : { ...target, segmentId: holder.id };
|
|
171897
|
+
};
|
|
171898
|
+
var planBlastFile = (artifact, requested2) => {
|
|
171899
|
+
const target = blastTargetOf(artifact, requested2);
|
|
171900
|
+
const node2 = findBlastFile(artifact, target);
|
|
171901
|
+
if (node2 === void 0) return rejected3("This file is not in the Blast Diagram.");
|
|
171902
|
+
if (node2.diffType !== null) return rejected3("This file is part of the change, so it has no impact to assess.");
|
|
171903
|
+
if (node2.impactType !== null) return ALREADY_WRITTEN;
|
|
171904
|
+
return planned(
|
|
171905
|
+
withRequiredBlastFile(artifact, target.segmentId, target.path),
|
|
171906
|
+
`The reviewer asks for the impact of the change on ${quoted7(target.path)} in the Blast Diagram of segment ${quoted7(target.segmentId)} alone: write its impact type and its reason, and nothing else.`,
|
|
171907
|
+
"Assessing the file"
|
|
171908
|
+
);
|
|
171909
|
+
};
|
|
171910
|
+
var planNodeWriteUp = (artifact, target) => {
|
|
171911
|
+
if (target.kind === "trace-node") return planTraceNode(artifact, target);
|
|
171912
|
+
if (target.kind === "blast-file") return planBlastFile(artifact, target);
|
|
171913
|
+
return planWaypoints(artifact, target);
|
|
172420
171914
|
};
|
|
172421
171915
|
|
|
172422
171916
|
// apps/backend/src/procedures/request-write-up/index.ts
|
|
172423
|
-
var QUEUED_MESSAGE = "The agent is still writing. If this is still missing when it finishes, Flight Plan asks for it next.";
|
|
172424
|
-
var unstartedMessage2 = (reason) => `The agent did not start: ${reason}`;
|
|
172425
171917
|
var amendmentOf = (planned2) => ({
|
|
172426
171918
|
artifact: planned2.kind === "planned" ? planned2.artifact : null,
|
|
172427
171919
|
outcome: planned2
|
|
@@ -172433,9 +171925,8 @@ var writeWriter = async (key, writer, context) => {
|
|
|
172433
171925
|
var handOver = async (key, writer, prompt, message, context) => {
|
|
172434
171926
|
if (writer.kind === "external") return { kind: "started", prompt: toOneLine(prompt), message: externalStartMessage(writer.agent) };
|
|
172435
171927
|
await writeWriter(key, writer, context);
|
|
172436
|
-
|
|
172437
|
-
|
|
172438
|
-
return { kind: "started", prompt: null, message: isStarted ? message : unstartedMessage2(outcome.reason) };
|
|
171928
|
+
await sendToAgent(key, prompt, context);
|
|
171929
|
+
return { kind: "started", prompt: null, message };
|
|
172439
171930
|
};
|
|
172440
171931
|
var requestWriteUp = async (input2, context) => {
|
|
172441
171932
|
const key = { repositoryName: input2.repositoryName, targetId: input2.targetId };
|
|
@@ -172448,16 +171939,11 @@ var requestWriteUp = async (input2, context) => {
|
|
|
172448
171939
|
if (repository === void 0 || scaffold === null) return null;
|
|
172449
171940
|
const target = await findReviewTarget2(repository, input2.targetId, context);
|
|
172450
171941
|
if (target === null) return null;
|
|
172451
|
-
const writer = defaultWriterOf(setup.agents,
|
|
171942
|
+
const writer = defaultWriterOf(setup.agents, LIVE_AGENTS)?.writer ?? null;
|
|
172452
171943
|
if (writer === null) return { kind: "rejected", field: "agent", message: NO_AGENT_MESSAGE2 };
|
|
172453
171944
|
const planned2 = await context.reviewStore.amendArtifact(key, (artifact) => amendmentOf(planNodeWriteUp(artifact, input2.target)));
|
|
172454
171945
|
if (planned2 === null) return null;
|
|
172455
171946
|
if (planned2.kind !== "planned") return planned2;
|
|
172456
|
-
const { agents, writeUpQueue } = context.conversationEnvironment;
|
|
172457
|
-
if (writer.kind !== "external" && agents.find(key) !== null) {
|
|
172458
|
-
writeUpQueue.add(key, input2.target);
|
|
172459
|
-
return { kind: "queued", message: QUEUED_MESSAGE };
|
|
172460
|
-
}
|
|
172461
171947
|
return await handOver(key, writer, buildWriteUpRequestPrompt(repository, target, key, planned2.ask), planned2.message, context);
|
|
172462
171948
|
};
|
|
172463
171949
|
|
|
@@ -172476,7 +171962,6 @@ var requestWriteUpInputSchema = external_exports.strictObject({
|
|
|
172476
171962
|
var WRITE_UP_REQUEST_FIELDS = ["target", "agent"];
|
|
172477
171963
|
var writeUpRequestResultSchema = external_exports.discriminatedUnion("kind", [
|
|
172478
171964
|
external_exports.strictObject({ kind: external_exports.literal("started"), prompt: external_exports.string().nullable(), message: external_exports.string() }),
|
|
172479
|
-
external_exports.strictObject({ kind: external_exports.literal("queued"), message: external_exports.string() }),
|
|
172480
171965
|
external_exports.strictObject({ kind: external_exports.literal("written"), message: external_exports.string() }),
|
|
172481
171966
|
external_exports.strictObject({ kind: external_exports.literal("rejected"), field: external_exports.enum(WRITE_UP_REQUEST_FIELDS), message: external_exports.string() })
|
|
172482
171967
|
]);
|
|
@@ -172509,14 +171994,14 @@ var resolveThreadRoute = publicProcedure.input(resolveThreadInputSchema).output(
|
|
|
172509
171994
|
var NO_FIELD_MESSAGE = "This configuration has no such field. Nothing was saved.";
|
|
172510
171995
|
var EMPTY_TEXT_MESSAGE = "An instruction cannot be empty. Write it, or reset the field.";
|
|
172511
171996
|
var PRESET_NAME_MESSAGE = "A preset keeps its name. Duplicate it to name your own.";
|
|
172512
|
-
var
|
|
171997
|
+
var rejected4 = (message) => ({ kind: "rejected", message });
|
|
172513
171998
|
var withoutKeys3 = (instructions, keys) => Object.fromEntries(Object.entries(instructions).filter(([key]) => !keys.includes(key)));
|
|
172514
171999
|
var planFieldChange = (configuration, change, texts) => {
|
|
172515
172000
|
const field = EDITABLE_FIELDS.find((editable) => editable.path === change.path);
|
|
172516
|
-
if (field === void 0) return
|
|
172001
|
+
if (field === void 0) return rejected4(NO_FIELD_MESSAGE);
|
|
172517
172002
|
const fieldKeys = presetKeysOf(field);
|
|
172518
|
-
if (change.texts.some((written) => !fieldKeys.includes(written.key))) return
|
|
172519
|
-
if (change.texts.some((written) => written.text.trim() === "")) return
|
|
172003
|
+
if (change.texts.some((written) => !fieldKeys.includes(written.key))) return rejected4(NO_FIELD_MESSAGE);
|
|
172004
|
+
if (change.texts.some((written) => written.text.trim() === "")) return rejected4(EMPTY_TEXT_MESSAGE);
|
|
172520
172005
|
const changedTexts = change.texts.filter((written) => written.text !== shippedTextOf(texts, configuration, written.key));
|
|
172521
172006
|
return {
|
|
172522
172007
|
kind: "planned",
|
|
@@ -172532,7 +172017,7 @@ var planFieldChange = (configuration, change, texts) => {
|
|
|
172532
172017
|
};
|
|
172533
172018
|
var planReset = (configuration, change) => {
|
|
172534
172019
|
const field = EDITABLE_FIELDS.find((editable) => editable.path === change.path);
|
|
172535
|
-
if (field === void 0) return
|
|
172020
|
+
if (field === void 0) return rejected4(NO_FIELD_MESSAGE);
|
|
172536
172021
|
return {
|
|
172537
172022
|
kind: "planned",
|
|
172538
172023
|
message: "This field is reset.",
|
|
@@ -172548,14 +172033,14 @@ var planSwitches = (configuration, change) => ({
|
|
|
172548
172033
|
}
|
|
172549
172034
|
});
|
|
172550
172035
|
var planRename = (configuration, change, otherConfigurations) => {
|
|
172551
|
-
if (configuration.isPreset) return
|
|
172036
|
+
if (configuration.isPreset) return rejected4(PRESET_NAME_MESSAGE);
|
|
172552
172037
|
const name = change.name.trim();
|
|
172553
172038
|
const nameProblem = nameProblemOf(name, otherConfigurations);
|
|
172554
|
-
return nameProblem === null ? { kind: "planned", message: "The name is saved.", configuration: { ...configuration, name } } :
|
|
172039
|
+
return nameProblem === null ? { kind: "planned", message: "The name is saved.", configuration: { ...configuration, name } } : rejected4(nameProblem);
|
|
172555
172040
|
};
|
|
172556
172041
|
var planChange2 = (configurations2, change, texts, missingMessage) => {
|
|
172557
172042
|
const configuration = configurations2.find((listed) => listed.id === change.id);
|
|
172558
|
-
if (configuration === void 0) return
|
|
172043
|
+
if (configuration === void 0) return rejected4(missingMessage);
|
|
172559
172044
|
if (change.change === "field") return planFieldChange(configuration, change, texts);
|
|
172560
172045
|
if (change.change === "reset") return planReset(configuration, change);
|
|
172561
172046
|
if (change.change === "switches") return planSwitches(configuration, change);
|
|
@@ -173142,7 +172627,7 @@ var searchCreationTargetsRoute = publicProcedure.input(searchCreationTargetsInpu
|
|
|
173142
172627
|
// apps/backend/src/procedures/search-files/utils/fuzzy-score.ts
|
|
173143
172628
|
var PATH_SEPARATOR18 = "/";
|
|
173144
172629
|
var WORD_START_PATTERN = /[/\\._\-\s]/;
|
|
173145
|
-
var
|
|
172630
|
+
var WHITESPACE_PATTERN4 = /\s+/g;
|
|
173146
172631
|
var MATCH_SCORE = 1;
|
|
173147
172632
|
var CONSECUTIVE_BONUS = 2;
|
|
173148
172633
|
var WORD_START_BONUS = 3;
|
|
@@ -173170,7 +172655,7 @@ var scoreSubsequence = (needle, text2) => {
|
|
|
173170
172655
|
};
|
|
173171
172656
|
var fileNameOf2 = (path11) => path11.slice(path11.lastIndexOf(PATH_SEPARATOR18) + 1);
|
|
173172
172657
|
var fuzzyScoreOf = (query, path11) => {
|
|
173173
|
-
const needle = query.replaceAll(
|
|
172658
|
+
const needle = query.replaceAll(WHITESPACE_PATTERN4, "").toLowerCase();
|
|
173174
172659
|
const fileNameScore = scoreSubsequence(needle, fileNameOf2(path11));
|
|
173175
172660
|
const score = fileNameScore === null ? scoreSubsequence(needle, path11) : fileNameScore + FILE_NAME_BONUS;
|
|
173176
172661
|
return score === null ? null : score - path11.length * LENGTH_PENALTY;
|
|
@@ -173299,15 +172784,15 @@ var ASK_FOR_MORE_CHARACTERS = {
|
|
|
173299
172784
|
var hasEnoughCharacters = (query) => query.trim().length >= MIN_QUERY_LENGTH;
|
|
173300
172785
|
|
|
173301
172786
|
// apps/backend/src/procedures/search-repository-folders/utils/rank-repository-folders.ts
|
|
173302
|
-
var
|
|
172787
|
+
var import_node_path21 = require("node:path");
|
|
173303
172788
|
var PARENT_SEGMENT2 = "..";
|
|
173304
172789
|
var pathBelowRoot = (path11, rootPath) => {
|
|
173305
|
-
const relativePath = (0,
|
|
173306
|
-
const isOutsideRoot = relativePath.startsWith(PARENT_SEGMENT2) || (0,
|
|
172790
|
+
const relativePath = (0, import_node_path21.relative)(rootPath, path11);
|
|
172791
|
+
const isOutsideRoot = relativePath.startsWith(PARENT_SEGMENT2) || (0, import_node_path21.isAbsolute)(relativePath);
|
|
173307
172792
|
return isOutsideRoot ? path11 : relativePath;
|
|
173308
172793
|
};
|
|
173309
172794
|
var matchedLettersInFolderName = (folderPath, matchedPositions) => {
|
|
173310
|
-
const folderNameStart = folderPath.lastIndexOf(
|
|
172795
|
+
const folderNameStart = folderPath.lastIndexOf(import_node_path21.sep) + 1;
|
|
173311
172796
|
return [...matchedPositions].filter((position) => position >= folderNameStart).length;
|
|
173312
172797
|
};
|
|
173313
172798
|
var byMostLettersInFolderName = (first, second, selector) => matchedLettersInFolderName(selector(second.item), second.positions) - matchedLettersInFolderName(selector(first.item), first.positions);
|
|
@@ -173403,7 +172888,6 @@ var sendReviewerMessage = async (input2, context) => {
|
|
|
173403
172888
|
[{ kind: "reviewer-message", id: messageId, body: input2.body, reference: input2.reference, sentAt: context.now() }],
|
|
173404
172889
|
context
|
|
173405
172890
|
);
|
|
173406
|
-
await deliverToAgent(key, context);
|
|
173407
172891
|
return { kind: "sent", messageId };
|
|
173408
172892
|
};
|
|
173409
172893
|
|
|
@@ -173566,8 +173050,8 @@ var watchConversationRoute = publicProcedure.input(conversationKeySchema).subscr
|
|
|
173566
173050
|
var MISSING_CONFIGURATION_MESSAGE3 = "This configuration no longer exists. Pick another one.";
|
|
173567
173051
|
var NO_SECTION_MESSAGE = "Choose at least one part for the agent to explain.";
|
|
173568
173052
|
var DRAFTING_STATUS4 = "drafting";
|
|
173569
|
-
var
|
|
173570
|
-
var
|
|
173053
|
+
var rejected5 = (field, message) => ({ kind: "rejected", field, message });
|
|
173054
|
+
var requestOf2 = (previous, input2, configuration, writer, now) => ({
|
|
173571
173055
|
...previous,
|
|
173572
173056
|
configurationId: configuration.id,
|
|
173573
173057
|
preset: configuration.preset,
|
|
@@ -173576,9 +173060,9 @@ var requestOf3 = (previous, input2, configuration, writer, now) => ({
|
|
|
173576
173060
|
writeUp: { sections: input2.sections, walkthroughOrder: input2.walkthroughOrder }
|
|
173577
173061
|
});
|
|
173578
173062
|
var planWriteUp = (input2, { scaffold, configuration, writer, noAgentMessage, now }) => {
|
|
173579
|
-
if (input2.sections.length === 0) return
|
|
173580
|
-
if (configuration === null) return
|
|
173581
|
-
if (writer === null) return
|
|
173063
|
+
if (input2.sections.length === 0) return rejected5("sections", NO_SECTION_MESSAGE);
|
|
173064
|
+
if (configuration === null) return rejected5("configuration", MISSING_CONFIGURATION_MESSAGE3);
|
|
173065
|
+
if (writer === null) return rejected5("agent", noAgentMessage);
|
|
173582
173066
|
const configured = withConfiguration({ ...scaffold.artifact, isSegmented: input2.isSegmented }, { requiredContextKinds: configuration.contextCodeBlockKinds });
|
|
173583
173067
|
const required2 = withRequiredSections(configured, input2.sections);
|
|
173584
173068
|
const hasWork = unwrittenWork(required2).length > 0 || input2.sections.includes("findings");
|
|
@@ -173587,7 +173071,7 @@ var planWriteUp = (input2, { scaffold, configuration, writer, noAgentMessage, no
|
|
|
173587
173071
|
hasWork,
|
|
173588
173072
|
scaffold: {
|
|
173589
173073
|
artifact: hasWork ? { ...required2, status: DRAFTING_STATUS4 } : required2,
|
|
173590
|
-
request:
|
|
173074
|
+
request: requestOf2(scaffold.request, input2, configuration, writer, now),
|
|
173591
173075
|
baseCommit: scaffold.baseCommit
|
|
173592
173076
|
}
|
|
173593
173077
|
};
|
|
@@ -173610,7 +173094,7 @@ var writeUpReview = async (input2, context) => {
|
|
|
173610
173094
|
const planned2 = planWriteUp(input2, {
|
|
173611
173095
|
scaffold,
|
|
173612
173096
|
configuration: findConfiguration(savedConfigurations, input2.configurationId),
|
|
173613
|
-
writer: defaultWriterOf(setup.agents,
|
|
173097
|
+
writer: defaultWriterOf(setup.agents, LIVE_AGENTS)?.writer ?? null,
|
|
173614
173098
|
noAgentMessage: NO_AGENT_MESSAGE2,
|
|
173615
173099
|
now: context.now()
|
|
173616
173100
|
});
|
|
@@ -173698,6 +173182,8 @@ var appRouter = createRouter({
|
|
|
173698
173182
|
writeUpPlan: getWriteUpPlanRoute,
|
|
173699
173183
|
writeUp: writeUpReviewRoute,
|
|
173700
173184
|
declineWriteUp: declineWriteUpRoute,
|
|
173185
|
+
liveAgent: getLiveAgentRoute,
|
|
173186
|
+
openAgentTerminal: openAgentTerminalRoute,
|
|
173701
173187
|
requestWriteUp: requestWriteUpRoute,
|
|
173702
173188
|
delete: deleteReviewRoute,
|
|
173703
173189
|
setReviewed: setReviewedRoute,
|
|
@@ -173771,7 +173257,9 @@ var buildServer = async (options = {}, context = createMockProcedureContext(/* @
|
|
|
173771
173257
|
await registerTrpc(server, context);
|
|
173772
173258
|
registerMcp(server, context);
|
|
173773
173259
|
await registerApi(server, context);
|
|
173774
|
-
|
|
173260
|
+
server.addHook("onClose", async () => {
|
|
173261
|
+
await context.conversationEnvironment.hub.close();
|
|
173262
|
+
});
|
|
173775
173263
|
if (webPath !== null) await registerWeb(server, webPath);
|
|
173776
173264
|
return server;
|
|
173777
173265
|
};
|
|
@@ -173779,10 +173267,10 @@ var buildServer = async (options = {}, context = createMockProcedureContext(/* @
|
|
|
173779
173267
|
// apps/backend/src/utils/browser-opener/index.ts
|
|
173780
173268
|
var import_node_child_process6 = require("node:child_process");
|
|
173781
173269
|
var WINDOWS = "win32";
|
|
173782
|
-
var
|
|
173270
|
+
var MAC2 = "darwin";
|
|
173783
173271
|
var EMPTY_WINDOW_TITLE = "";
|
|
173784
173272
|
var browserCommandOf = (platform, url2) => {
|
|
173785
|
-
if (platform ===
|
|
173273
|
+
if (platform === MAC2) return { executable: "open", commandArguments: [url2] };
|
|
173786
173274
|
if (platform === WINDOWS) return { executable: "cmd", commandArguments: ["/c", "start", EMPTY_WINDOW_TITLE, url2] };
|
|
173787
173275
|
return { executable: "xdg-open", commandArguments: [url2] };
|
|
173788
173276
|
};
|
|
@@ -173801,7 +173289,7 @@ var openBrowser = async (platform, url2) => {
|
|
|
173801
173289
|
};
|
|
173802
173290
|
|
|
173803
173291
|
// apps/backend/src/utils/port-probe/index.ts
|
|
173804
|
-
var
|
|
173292
|
+
var import_promises10 = require("node:dns/promises");
|
|
173805
173293
|
var import_node_net2 = require("node:net");
|
|
173806
173294
|
var ANY_PORT = 0;
|
|
173807
173295
|
var isAddressFree = async (address, port) => await new Promise((resolve3) => {
|
|
@@ -173815,7 +173303,7 @@ var isAddressFree = async (address, port) => await new Promise((resolve3) => {
|
|
|
173815
173303
|
});
|
|
173816
173304
|
});
|
|
173817
173305
|
});
|
|
173818
|
-
var addressesOf = async (host) => (await (0,
|
|
173306
|
+
var addressesOf = async (host) => (await (0, import_promises10.lookup)(host, { all: true })).map(({ address }) => address);
|
|
173819
173307
|
var isPortFree = async (host, port) => {
|
|
173820
173308
|
const addresses = await addressesOf(host);
|
|
173821
173309
|
const checks = await Promise.all(addresses.map(async (address) => await isAddressFree(address, port)));
|
|
@@ -173847,7 +173335,7 @@ var isFlightPlanRunning = async (serverUrl) => {
|
|
|
173847
173335
|
};
|
|
173848
173336
|
|
|
173849
173337
|
// apps/backend/src/utils/saved-port-file/index.ts
|
|
173850
|
-
var
|
|
173338
|
+
var import_node_path22 = require("node:path");
|
|
173851
173339
|
var FILE_NAME2 = "server.json";
|
|
173852
173340
|
var JSON_INDENT9 = 2;
|
|
173853
173341
|
var savedPortSchema = external_exports.object({ port: external_exports.number().int().positive() });
|
|
@@ -173861,7 +173349,7 @@ var parseSavedPort = (text2) => {
|
|
|
173861
173349
|
}
|
|
173862
173350
|
};
|
|
173863
173351
|
var createSavedPortFile = (dataPath) => {
|
|
173864
|
-
const filePath = (0,
|
|
173352
|
+
const filePath = (0, import_node_path22.join)(dataPath, FILE_NAME2);
|
|
173865
173353
|
return {
|
|
173866
173354
|
read: async () => parseSavedPort(await readTextOrNull(filePath)),
|
|
173867
173355
|
write: async (port) => {
|
|
@@ -173874,10 +173362,10 @@ var createSavedPortFile = (dataPath) => {
|
|
|
173874
173362
|
// apps/backend/src/main.ts
|
|
173875
173363
|
var PLUGIN_FOLDER_NAME = "plugin";
|
|
173876
173364
|
var CONFIGURATIONS_FOLDER_NAME2 = "configurations";
|
|
173877
|
-
var PUBLISHED_BUNDLE_PATH_FROM_BUILD = (0,
|
|
173878
|
-
var WEB_PATH_FROM_BUILD = (0,
|
|
173879
|
-
var PACKAGE_MANIFEST_PATH_FROM_BUILD = (0,
|
|
173880
|
-
var FIXTURE_CASES_PATH_FROM_BUILD = (0,
|
|
173365
|
+
var PUBLISHED_BUNDLE_PATH_FROM_BUILD = (0, import_node_path23.join)("..", "published-review");
|
|
173366
|
+
var WEB_PATH_FROM_BUILD = (0, import_node_path23.join)("..", "frontend");
|
|
173367
|
+
var PACKAGE_MANIFEST_PATH_FROM_BUILD = (0, import_node_path23.join)("..", "package.json");
|
|
173368
|
+
var FIXTURE_CASES_PATH_FROM_BUILD = (0, import_node_path23.join)("..", "..", "..", "tools", "playground-fixtures", "test-cases");
|
|
173881
173369
|
var PUBLISHED_LOG_LEVEL = "warn";
|
|
173882
173370
|
var ARGUMENTS_START = 2;
|
|
173883
173371
|
var FAILURE_EXIT_CODE2 = 1;
|
|
@@ -173887,13 +173375,14 @@ var openLocalContext = (serverConfig, appUrl) => {
|
|
|
173887
173375
|
const homePath = (0, import_node_os.homedir)();
|
|
173888
173376
|
return createLocalProcedureContext(/* @__PURE__ */ new Date(), {
|
|
173889
173377
|
dataPath: readDataPath(environment, homePath),
|
|
173890
|
-
pluginPath: (0,
|
|
173891
|
-
configurationsPath: (0,
|
|
173892
|
-
publishedBundlePath: (0,
|
|
173378
|
+
pluginPath: (0, import_node_path23.join)(__dirname, PLUGIN_FOLDER_NAME),
|
|
173379
|
+
configurationsPath: (0, import_node_path23.join)(__dirname, CONFIGURATIONS_FOLDER_NAME2),
|
|
173380
|
+
publishedBundlePath: (0, import_node_path23.join)(__dirname, PUBLISHED_BUNDLE_PATH_FROM_BUILD),
|
|
173893
173381
|
mcpUrl: mcpUrlOf(serverConfig),
|
|
173894
173382
|
serverUrl: serverUrlOf(serverConfig),
|
|
173895
173383
|
appUrl,
|
|
173896
173384
|
homePath,
|
|
173385
|
+
platform: process.platform,
|
|
173897
173386
|
environment
|
|
173898
173387
|
});
|
|
173899
173388
|
};
|
|
@@ -173910,7 +173399,7 @@ var choosePort = async (host, choice) => {
|
|
|
173910
173399
|
return null;
|
|
173911
173400
|
};
|
|
173912
173401
|
var readPackageVersion = async () => {
|
|
173913
|
-
const manifest = JSON.parse(await (0,
|
|
173402
|
+
const manifest = JSON.parse(await (0, import_promises11.readFile)((0, import_node_path23.join)(__dirname, PACKAGE_MANIFEST_PATH_FROM_BUILD), "utf8"));
|
|
173914
173403
|
return packageManifestSchema.parse(manifest).version;
|
|
173915
173404
|
};
|
|
173916
173405
|
var readNoVersion = () => null;
|
|
@@ -173927,7 +173416,7 @@ var printUpdateNotice = async (pendingNotice) => {
|
|
|
173927
173416
|
var refreshAgents = async (context) => {
|
|
173928
173417
|
const failures = await refreshAgentInstalls(context);
|
|
173929
173418
|
failures.forEach(({ agent, reason }) => {
|
|
173930
|
-
console.error(`${agent}
|
|
173419
|
+
console.error(`${agent} could not be brought up to date with this Flight Plan. ${reason} Save the agents again in Settings.`);
|
|
173931
173420
|
});
|
|
173932
173421
|
return failures.length === 0;
|
|
173933
173422
|
};
|
|
@@ -173954,12 +173443,13 @@ var launch = async (command) => {
|
|
|
173954
173443
|
const serverConfig = { host, port };
|
|
173955
173444
|
const serverUrl = serverUrlOf(serverConfig);
|
|
173956
173445
|
const context = { ...openLocalContext(serverConfig, serverUrl), updateChecker: await pendingChecker };
|
|
173957
|
-
const server = await buildServer({ logger: { level: PUBLISHED_LOG_LEVEL } }, context, (0,
|
|
173446
|
+
const server = await buildServer({ logger: { level: PUBLISHED_LOG_LEVEL } }, context, (0, import_node_path23.join)(__dirname, WEB_PATH_FROM_BUILD));
|
|
173958
173447
|
await server.listen(serverConfig);
|
|
173959
173448
|
console.log(`Flight Plan is running at ${serverUrl}`);
|
|
173960
173449
|
const printedNotice = printUpdateNotice(pendingNotice);
|
|
173961
173450
|
await showInBrowser(serverUrl, command);
|
|
173962
|
-
|
|
173451
|
+
const isRefreshed = await refreshAgents(context);
|
|
173452
|
+
if (port !== savedPort && isRefreshed) await savedPortFile.write(port);
|
|
173963
173453
|
await printedNotice;
|
|
173964
173454
|
};
|
|
173965
173455
|
var printVersion = async () => {
|