repoburg 1.3.198 → 1.3.201
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/agent-pane/backend/data.db +0 -0
- package/agent-pane/backend/data.db-shm +0 -0
- package/agent-pane/backend/data.db-wal +0 -0
- package/agent-pane/backend/dist/index.js +1425 -272
- package/agent-pane/backend/src/claude/claude-provider.test.ts +393 -3
- package/agent-pane/backend/src/claude/claude-provider.ts +53 -50
- package/agent-pane/backend/src/db/index.ts +6 -0
- package/agent-pane/backend/src/index.ts +5 -2
- package/agent-pane/backend/src/integration/threads-claude-fork.test.ts +241 -0
- package/agent-pane/backend/src/providers/index.ts +3 -1
- package/agent-pane/backend/src/repoburg/action-mapping.ts +216 -0
- package/agent-pane/backend/src/repoburg/agent-runtime-client.test.ts +271 -0
- package/agent-pane/backend/src/repoburg/agent-runtime-client.ts +262 -0
- package/agent-pane/backend/src/repoburg/backend-resolver.test.ts +271 -0
- package/agent-pane/backend/src/repoburg/backend-resolver.ts +246 -0
- package/agent-pane/backend/src/repoburg/repoburg-client.test.ts +159 -0
- package/agent-pane/backend/src/repoburg/repoburg-client.ts +181 -0
- package/agent-pane/backend/src/repoburg/repoburg-provider.test.ts +723 -0
- package/agent-pane/backend/src/repoburg/repoburg-provider.ts +422 -0
- package/agent-pane/backend/src/repoburg/turn-projector.test.ts +475 -0
- package/agent-pane/backend/src/repoburg/turn-projector.ts +537 -0
- package/agent-pane/backend/src/routes/providers.test.ts +18 -1
- package/agent-pane/backend/src/routes/providers.ts +19 -1
- package/agent-pane/backend/src/routes/sessions.ts +12 -0
- package/agent-pane/backend/src/routes/threads.ts +21 -6
- package/agent-pane/backend/src/routes/turns.test.ts +45 -1
- package/agent-pane/frontend/dist/assets/{index-Dwwhx7YN.css → index-34WaZYsW.css} +1 -1
- package/agent-pane/frontend/dist/assets/index-y7xlT86e.js +362 -0
- package/agent-pane/frontend/dist/index.html +2 -2
- package/agent-pane/frontend/src/components/CommentableText.test.tsx +196 -0
- package/agent-pane/frontend/src/components/CommentableText.tsx +109 -21
- package/agent-pane/frontend/src/components/IdeWorkspace.test.tsx +39 -0
- package/agent-pane/frontend/src/components/IdeWorkspace.tsx +28 -2
- package/agent-pane/frontend/src/components/ResizeHandle.tsx +29 -0
- package/agent-pane/frontend/src/components/panels/ThreadsPanel.tsx +35 -3
- package/agent-pane/frontend/src/constants/models.ts +37 -0
- package/agent-pane/frontend/src/hooks/useResizable.test.ts +97 -0
- package/agent-pane/frontend/src/hooks/useResizable.ts +75 -0
- package/agent-pane/frontend/src/store/store.test.ts +35 -0
- package/agent-pane/frontend/src/store/uiSlice.ts +50 -0
- package/agent-pane/frontend/src/styles/app.css +10 -1
- package/agent-pane/frontend/src/test/component-helpers.ts +2 -0
- package/agent-pane-bug-repro-no-agent-reply.png +0 -0
- package/backend/dist/src/agent-runtime/agent-runtime-event-emitter.d.ts +20 -0
- package/backend/dist/src/agent-runtime/agent-runtime-event-emitter.js +112 -0
- package/backend/dist/src/agent-runtime/agent-runtime-event-emitter.js.map +1 -0
- package/backend/dist/src/agent-runtime/agent-runtime.controller.d.ts +11 -0
- package/backend/dist/src/agent-runtime/agent-runtime.controller.js +91 -0
- package/backend/dist/src/agent-runtime/agent-runtime.controller.js.map +1 -0
- package/backend/dist/src/agent-runtime/agent-runtime.module.d.ts +2 -0
- package/backend/dist/src/agent-runtime/agent-runtime.module.js +26 -0
- package/backend/dist/src/agent-runtime/agent-runtime.module.js.map +1 -0
- package/backend/dist/src/agent-runtime/agent-runtime.types.d.ts +77 -0
- package/backend/dist/src/agent-runtime/agent-runtime.types.js +3 -0
- package/backend/dist/src/agent-runtime/agent-runtime.types.js.map +1 -0
- package/backend/dist/src/app.module.js +4 -0
- package/backend/dist/src/app.module.js.map +1 -1
- package/backend/dist/src/interactive-chat/chat.module.js +4 -0
- package/backend/dist/src/interactive-chat/chat.module.js.map +1 -1
- package/backend/dist/src/interactive-chat/chat.service.d.ts +3 -1
- package/backend/dist/src/interactive-chat/chat.service.js +33 -6
- package/backend/dist/src/interactive-chat/chat.service.js.map +1 -1
- package/backend/dist/src/llm-orchestration/hooks/frontend-notification.hook.d.ts +3 -1
- package/backend/dist/src/llm-orchestration/hooks/frontend-notification.hook.js +20 -2
- package/backend/dist/src/llm-orchestration/hooks/frontend-notification.hook.js.map +1 -1
- package/backend/dist/src/llm-orchestration/llm-orchestration.module.js +2 -0
- package/backend/dist/src/llm-orchestration/llm-orchestration.module.js.map +1 -1
- package/backend/dist/src/llm-orchestration/llm-turn-processor.service.d.ts +4 -1
- package/backend/dist/src/llm-orchestration/llm-turn-processor.service.js +35 -2
- package/backend/dist/src/llm-orchestration/llm-turn-processor.service.js.map +1 -1
- package/backend/dist/src/llm-provider/ollama-llm.provider.d.ts +1 -0
- package/backend/dist/src/llm-provider/ollama-llm.provider.js +20 -1
- package/backend/dist/src/llm-provider/ollama-llm.provider.js.map +1 -1
- package/backend/dist/src/llm-responses/llm-responses.module.js +4 -0
- package/backend/dist/src/llm-responses/llm-responses.module.js.map +1 -1
- package/backend/dist/src/llm-responses/llm-responses.service.d.ts +4 -1
- package/backend/dist/src/llm-responses/llm-responses.service.js +52 -2
- package/backend/dist/src/llm-responses/llm-responses.service.js.map +1 -1
- package/backend/dist/tsconfig.build.tsbuildinfo +1 -1
- package/daemon/dist/index.js +0 -0
- package/package.json +1 -1
- package/agent-pane/frontend/dist/assets/index-BYo-lnxm.js +0 -362
|
@@ -75,7 +75,7 @@ var require_queue = __commonJS({
|
|
|
75
75
|
if (!(_concurrency >= 1)) {
|
|
76
76
|
throw new Error("fastqueue concurrency must be equal to or greater than 1");
|
|
77
77
|
}
|
|
78
|
-
var
|
|
78
|
+
var cache2 = reusify(Task);
|
|
79
79
|
var queueHead = null;
|
|
80
80
|
var queueTail = null;
|
|
81
81
|
var _running = 0;
|
|
@@ -154,7 +154,7 @@ var require_queue = __commonJS({
|
|
|
154
154
|
return _running === 0 && self2.length() === 0;
|
|
155
155
|
}
|
|
156
156
|
function push(value, done) {
|
|
157
|
-
var current =
|
|
157
|
+
var current = cache2.get();
|
|
158
158
|
current.context = context;
|
|
159
159
|
current.release = release;
|
|
160
160
|
current.value = value;
|
|
@@ -175,7 +175,7 @@ var require_queue = __commonJS({
|
|
|
175
175
|
}
|
|
176
176
|
}
|
|
177
177
|
function unshift(value, done) {
|
|
178
|
-
var current =
|
|
178
|
+
var current = cache2.get();
|
|
179
179
|
current.context = context;
|
|
180
180
|
current.release = release;
|
|
181
181
|
current.value = value;
|
|
@@ -197,7 +197,7 @@ var require_queue = __commonJS({
|
|
|
197
197
|
}
|
|
198
198
|
function release(holder) {
|
|
199
199
|
if (holder) {
|
|
200
|
-
|
|
200
|
+
cache2.release(holder);
|
|
201
201
|
}
|
|
202
202
|
var next = queueHead;
|
|
203
203
|
if (next && _running <= _concurrency) {
|
|
@@ -3984,7 +3984,7 @@ var require_content_type = __commonJS({
|
|
|
3984
3984
|
var quotedPairReg = /\\([\t\u0020-\u00ff])/gu;
|
|
3985
3985
|
var typeNameReg = /^[\w!#$%&'*+.^`|~-]+$/;
|
|
3986
3986
|
var subtypeNameReg = /^[\w!#$%&'*+.^`|~-]+\s*$/;
|
|
3987
|
-
var
|
|
3987
|
+
var cache2 = new Lru(100);
|
|
3988
3988
|
var ContentType = class _ContentType {
|
|
3989
3989
|
#valid = false;
|
|
3990
3990
|
#empty = true;
|
|
@@ -3998,7 +3998,7 @@ var require_content_type = __commonJS({
|
|
|
3998
3998
|
* @type {Lru<ContentType>}
|
|
3999
3999
|
*/
|
|
4000
4000
|
static get cache() {
|
|
4001
|
-
return
|
|
4001
|
+
return cache2;
|
|
4002
4002
|
}
|
|
4003
4003
|
/**
|
|
4004
4004
|
* Create a ContentType instance from a header value. If the value has been
|
|
@@ -4007,10 +4007,10 @@ var require_content_type = __commonJS({
|
|
|
4007
4007
|
* @returns {ContentType | undefined}
|
|
4008
4008
|
*/
|
|
4009
4009
|
static from(headerValue) {
|
|
4010
|
-
let contentType =
|
|
4010
|
+
let contentType = cache2.get(headerValue);
|
|
4011
4011
|
if (contentType !== void 0) return contentType;
|
|
4012
4012
|
contentType = new _ContentType(headerValue);
|
|
4013
|
-
|
|
4013
|
+
cache2.set(headerValue, contentType);
|
|
4014
4014
|
return contentType;
|
|
4015
4015
|
}
|
|
4016
4016
|
constructor(headerValue) {
|
|
@@ -6123,8 +6123,8 @@ var require_req = __commonJS({
|
|
|
6123
6123
|
if (req.originalUrl) {
|
|
6124
6124
|
_req.url = req.originalUrl;
|
|
6125
6125
|
} else {
|
|
6126
|
-
const
|
|
6127
|
-
_req.url = typeof
|
|
6126
|
+
const path2 = req.path;
|
|
6127
|
+
_req.url = typeof path2 === "string" ? path2 : req.url ? req.url.path || req.url : void 0;
|
|
6128
6128
|
}
|
|
6129
6129
|
if (req.query) {
|
|
6130
6130
|
_req.query = req.query;
|
|
@@ -6289,14 +6289,14 @@ var require_redact = __commonJS({
|
|
|
6289
6289
|
}
|
|
6290
6290
|
return obj;
|
|
6291
6291
|
}
|
|
6292
|
-
function parsePath(
|
|
6292
|
+
function parsePath(path2) {
|
|
6293
6293
|
const parts = [];
|
|
6294
6294
|
let current = "";
|
|
6295
6295
|
let inBrackets = false;
|
|
6296
6296
|
let inQuotes = false;
|
|
6297
6297
|
let quoteChar = "";
|
|
6298
|
-
for (let i = 0; i <
|
|
6299
|
-
const char =
|
|
6298
|
+
for (let i = 0; i < path2.length; i++) {
|
|
6299
|
+
const char = path2[i];
|
|
6300
6300
|
if (!inBrackets && char === ".") {
|
|
6301
6301
|
if (current) {
|
|
6302
6302
|
parts.push(current);
|
|
@@ -6427,10 +6427,10 @@ var require_redact = __commonJS({
|
|
|
6427
6427
|
return current;
|
|
6428
6428
|
}
|
|
6429
6429
|
function redactPaths(obj, paths, censor, remove = false) {
|
|
6430
|
-
for (const
|
|
6431
|
-
const parts = parsePath(
|
|
6430
|
+
for (const path2 of paths) {
|
|
6431
|
+
const parts = parsePath(path2);
|
|
6432
6432
|
if (parts.includes("*")) {
|
|
6433
|
-
redactWildcardPath(obj, parts, censor,
|
|
6433
|
+
redactWildcardPath(obj, parts, censor, path2, remove);
|
|
6434
6434
|
} else {
|
|
6435
6435
|
if (remove) {
|
|
6436
6436
|
removeKey(obj, parts);
|
|
@@ -6515,8 +6515,8 @@ var require_redact = __commonJS({
|
|
|
6515
6515
|
}
|
|
6516
6516
|
} else {
|
|
6517
6517
|
if (afterWildcard.includes("*")) {
|
|
6518
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
6519
|
-
const fullPath = [...pathArray.slice(0, pathLength), ...
|
|
6518
|
+
const wrappedCensor = typeof censor === "function" ? (value, path2) => {
|
|
6519
|
+
const fullPath = [...pathArray.slice(0, pathLength), ...path2];
|
|
6520
6520
|
return censor(value, fullPath);
|
|
6521
6521
|
} : censor;
|
|
6522
6522
|
redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
|
|
@@ -6551,8 +6551,8 @@ var require_redact = __commonJS({
|
|
|
6551
6551
|
return null;
|
|
6552
6552
|
}
|
|
6553
6553
|
const pathStructure = /* @__PURE__ */ new Map();
|
|
6554
|
-
for (const
|
|
6555
|
-
const parts = parsePath(
|
|
6554
|
+
for (const path2 of pathsToClone) {
|
|
6555
|
+
const parts = parsePath(path2);
|
|
6556
6556
|
let current = pathStructure;
|
|
6557
6557
|
for (let i = 0; i < parts.length; i++) {
|
|
6558
6558
|
const part = parts[i];
|
|
@@ -6604,24 +6604,24 @@ var require_redact = __commonJS({
|
|
|
6604
6604
|
}
|
|
6605
6605
|
return cloneSelectively(obj, pathStructure);
|
|
6606
6606
|
}
|
|
6607
|
-
function validatePath(
|
|
6608
|
-
if (typeof
|
|
6607
|
+
function validatePath(path2) {
|
|
6608
|
+
if (typeof path2 !== "string") {
|
|
6609
6609
|
throw new Error("Paths must be (non-empty) strings");
|
|
6610
6610
|
}
|
|
6611
|
-
if (
|
|
6611
|
+
if (path2 === "") {
|
|
6612
6612
|
throw new Error("Invalid redaction path ()");
|
|
6613
6613
|
}
|
|
6614
|
-
if (
|
|
6615
|
-
throw new Error(`Invalid redaction path (${
|
|
6614
|
+
if (path2.includes("..")) {
|
|
6615
|
+
throw new Error(`Invalid redaction path (${path2})`);
|
|
6616
6616
|
}
|
|
6617
|
-
if (
|
|
6618
|
-
throw new Error(`Invalid redaction path (${
|
|
6617
|
+
if (path2.includes(",")) {
|
|
6618
|
+
throw new Error(`Invalid redaction path (${path2})`);
|
|
6619
6619
|
}
|
|
6620
6620
|
let bracketCount = 0;
|
|
6621
6621
|
let inQuotes = false;
|
|
6622
6622
|
let quoteChar = "";
|
|
6623
|
-
for (let i = 0; i <
|
|
6624
|
-
const char =
|
|
6623
|
+
for (let i = 0; i < path2.length; i++) {
|
|
6624
|
+
const char = path2[i];
|
|
6625
6625
|
if ((char === '"' || char === "'") && bracketCount > 0) {
|
|
6626
6626
|
if (!inQuotes) {
|
|
6627
6627
|
inQuotes = true;
|
|
@@ -6635,20 +6635,20 @@ var require_redact = __commonJS({
|
|
|
6635
6635
|
} else if (char === "]" && !inQuotes) {
|
|
6636
6636
|
bracketCount--;
|
|
6637
6637
|
if (bracketCount < 0) {
|
|
6638
|
-
throw new Error(`Invalid redaction path (${
|
|
6638
|
+
throw new Error(`Invalid redaction path (${path2})`);
|
|
6639
6639
|
}
|
|
6640
6640
|
}
|
|
6641
6641
|
}
|
|
6642
6642
|
if (bracketCount !== 0) {
|
|
6643
|
-
throw new Error(`Invalid redaction path (${
|
|
6643
|
+
throw new Error(`Invalid redaction path (${path2})`);
|
|
6644
6644
|
}
|
|
6645
6645
|
}
|
|
6646
6646
|
function validatePaths(paths) {
|
|
6647
6647
|
if (!Array.isArray(paths)) {
|
|
6648
6648
|
throw new TypeError("paths must be an array");
|
|
6649
6649
|
}
|
|
6650
|
-
for (const
|
|
6651
|
-
validatePath(
|
|
6650
|
+
for (const path2 of paths) {
|
|
6651
|
+
validatePath(path2);
|
|
6652
6652
|
}
|
|
6653
6653
|
}
|
|
6654
6654
|
function slowRedact(options = {}) {
|
|
@@ -6816,8 +6816,8 @@ var require_redaction = __commonJS({
|
|
|
6816
6816
|
if (shape[k2] === null) {
|
|
6817
6817
|
o[k2] = (value) => topCensor(value, [k2]);
|
|
6818
6818
|
} else {
|
|
6819
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
6820
|
-
return censor(value, [k2, ...
|
|
6819
|
+
const wrappedCensor = typeof censor === "function" ? (value, path2) => {
|
|
6820
|
+
return censor(value, [k2, ...path2]);
|
|
6821
6821
|
} : censor;
|
|
6822
6822
|
o[k2] = Redact({
|
|
6823
6823
|
paths: shape[k2],
|
|
@@ -7038,7 +7038,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7038
7038
|
var fs = __require("fs");
|
|
7039
7039
|
var EventEmitter2 = __require("events");
|
|
7040
7040
|
var inherits = __require("util").inherits;
|
|
7041
|
-
var
|
|
7041
|
+
var path2 = __require("path");
|
|
7042
7042
|
var sleep = require_atomic_sleep();
|
|
7043
7043
|
var assert = __require("assert");
|
|
7044
7044
|
var BUSY_WRITE_TIMEOUT = 100;
|
|
@@ -7092,7 +7092,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7092
7092
|
const mode = sonic.mode;
|
|
7093
7093
|
if (sonic.sync) {
|
|
7094
7094
|
try {
|
|
7095
|
-
if (sonic.mkdir) fs.mkdirSync(
|
|
7095
|
+
if (sonic.mkdir) fs.mkdirSync(path2.dirname(file), { recursive: true });
|
|
7096
7096
|
const fd2 = fs.openSync(file, flags, mode);
|
|
7097
7097
|
fileOpened(null, fd2);
|
|
7098
7098
|
} catch (err) {
|
|
@@ -7100,7 +7100,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7100
7100
|
throw err;
|
|
7101
7101
|
}
|
|
7102
7102
|
} else if (sonic.mkdir) {
|
|
7103
|
-
fs.mkdir(
|
|
7103
|
+
fs.mkdir(path2.dirname(file), { recursive: true }, (err) => {
|
|
7104
7104
|
if (err) return fileOpened(err);
|
|
7105
7105
|
fs.open(file, flags, mode, fileOpened);
|
|
7106
7106
|
});
|
|
@@ -8432,15 +8432,15 @@ var require_transport = __commonJS({
|
|
|
8432
8432
|
if (!unquoted) {
|
|
8433
8433
|
return false;
|
|
8434
8434
|
}
|
|
8435
|
-
let
|
|
8436
|
-
if (
|
|
8435
|
+
let path2 = unquoted;
|
|
8436
|
+
if (path2.startsWith("file://")) {
|
|
8437
8437
|
try {
|
|
8438
|
-
|
|
8438
|
+
path2 = fileURLToPath(path2);
|
|
8439
8439
|
} catch {
|
|
8440
8440
|
return false;
|
|
8441
8441
|
}
|
|
8442
8442
|
}
|
|
8443
|
-
return isAbsolute4(
|
|
8443
|
+
return isAbsolute4(path2) && !existsSync2(path2);
|
|
8444
8444
|
}
|
|
8445
8445
|
function stripQuotes(value) {
|
|
8446
8446
|
const first = value[0];
|
|
@@ -8981,12 +8981,12 @@ var require_levels = __commonJS({
|
|
|
8981
8981
|
function genLsCache(instance) {
|
|
8982
8982
|
const formatter = instance[formattersSym].level;
|
|
8983
8983
|
const { labels } = instance.levels;
|
|
8984
|
-
const
|
|
8984
|
+
const cache2 = {};
|
|
8985
8985
|
for (const label in labels) {
|
|
8986
8986
|
const level = formatter(labels[label], Number(label));
|
|
8987
|
-
|
|
8987
|
+
cache2[label] = JSON.stringify(level).slice(0, -1);
|
|
8988
8988
|
}
|
|
8989
|
-
instance[lsCacheSym] =
|
|
8989
|
+
instance[lsCacheSym] = cache2;
|
|
8990
8990
|
return instance;
|
|
8991
8991
|
}
|
|
8992
8992
|
function isStandardLevel(level, useOnlyCustomLevels) {
|
|
@@ -17116,8 +17116,8 @@ var require_utils = __commonJS({
|
|
|
17116
17116
|
}
|
|
17117
17117
|
return ind;
|
|
17118
17118
|
}
|
|
17119
|
-
function removeDotSegments(
|
|
17120
|
-
let input =
|
|
17119
|
+
function removeDotSegments(path2) {
|
|
17120
|
+
let input = path2;
|
|
17121
17121
|
const output = [];
|
|
17122
17122
|
let nextSlash = -1;
|
|
17123
17123
|
let len = 0;
|
|
@@ -17369,8 +17369,8 @@ var require_schemes = __commonJS({
|
|
|
17369
17369
|
wsComponent.secure = void 0;
|
|
17370
17370
|
}
|
|
17371
17371
|
if (wsComponent.resourceName) {
|
|
17372
|
-
const [
|
|
17373
|
-
wsComponent.path =
|
|
17372
|
+
const [path2, query] = wsComponent.resourceName.split("?");
|
|
17373
|
+
wsComponent.path = path2 && path2 !== "/" ? path2 : void 0;
|
|
17374
17374
|
wsComponent.query = query;
|
|
17375
17375
|
wsComponent.resourceName = void 0;
|
|
17376
17376
|
}
|
|
@@ -22307,8 +22307,8 @@ var require_utils2 = __commonJS({
|
|
|
22307
22307
|
}
|
|
22308
22308
|
return ind;
|
|
22309
22309
|
}
|
|
22310
|
-
function removeDotSegments(
|
|
22311
|
-
let input =
|
|
22310
|
+
function removeDotSegments(path2) {
|
|
22311
|
+
let input = path2;
|
|
22312
22312
|
const output = [];
|
|
22313
22313
|
let nextSlash = -1;
|
|
22314
22314
|
let len = 0;
|
|
@@ -22653,8 +22653,8 @@ var require_schemes2 = __commonJS({
|
|
|
22653
22653
|
wsComponent.secure = void 0;
|
|
22654
22654
|
}
|
|
22655
22655
|
if (wsComponent.resourceName) {
|
|
22656
|
-
const [
|
|
22657
|
-
wsComponent.path =
|
|
22656
|
+
const [path2, query] = wsComponent.resourceName.split("?");
|
|
22657
|
+
wsComponent.path = path2 && path2 !== "/" ? path2 : void 0;
|
|
22658
22658
|
wsComponent.query = query;
|
|
22659
22659
|
wsComponent.resourceName = void 0;
|
|
22660
22660
|
}
|
|
@@ -24138,8 +24138,8 @@ var require_utils3 = __commonJS({
|
|
|
24138
24138
|
}
|
|
24139
24139
|
return ind;
|
|
24140
24140
|
}
|
|
24141
|
-
function removeDotSegments(
|
|
24142
|
-
let input =
|
|
24141
|
+
function removeDotSegments(path2) {
|
|
24142
|
+
let input = path2;
|
|
24143
24143
|
const output = [];
|
|
24144
24144
|
let nextSlash = -1;
|
|
24145
24145
|
let len = 0;
|
|
@@ -24484,8 +24484,8 @@ var require_schemes3 = __commonJS({
|
|
|
24484
24484
|
wsComponent.secure = void 0;
|
|
24485
24485
|
}
|
|
24486
24486
|
if (wsComponent.resourceName) {
|
|
24487
|
-
const [
|
|
24488
|
-
wsComponent.path =
|
|
24487
|
+
const [path2, query] = wsComponent.resourceName.split("?");
|
|
24488
|
+
wsComponent.path = path2 && path2 !== "/" ? path2 : void 0;
|
|
24489
24489
|
wsComponent.query = query;
|
|
24490
24490
|
wsComponent.resourceName = void 0;
|
|
24491
24491
|
}
|
|
@@ -28884,7 +28884,7 @@ var require_range = __commonJS({
|
|
|
28884
28884
|
range = range.replace(BUILDSTRIPRE, "");
|
|
28885
28885
|
const memoOpts = (this.options.includePrerelease && FLAG_INCLUDE_PRERELEASE) | (this.options.loose && FLAG_LOOSE);
|
|
28886
28886
|
const memoKey = memoOpts + ":" + range;
|
|
28887
|
-
const cached =
|
|
28887
|
+
const cached = cache2.get(memoKey);
|
|
28888
28888
|
if (cached) {
|
|
28889
28889
|
return cached;
|
|
28890
28890
|
}
|
|
@@ -28918,7 +28918,7 @@ var require_range = __commonJS({
|
|
|
28918
28918
|
rangeMap.delete("");
|
|
28919
28919
|
}
|
|
28920
28920
|
const result = [...rangeMap.values()];
|
|
28921
|
-
|
|
28921
|
+
cache2.set(memoKey, result);
|
|
28922
28922
|
return result;
|
|
28923
28923
|
}
|
|
28924
28924
|
intersects(range, options) {
|
|
@@ -28957,7 +28957,7 @@ var require_range = __commonJS({
|
|
|
28957
28957
|
};
|
|
28958
28958
|
module.exports = Range;
|
|
28959
28959
|
var LRU = require_lrucache();
|
|
28960
|
-
var
|
|
28960
|
+
var cache2 = new LRU();
|
|
28961
28961
|
var parseOptions = require_parse_options();
|
|
28962
28962
|
var Comparator = require_comparator();
|
|
28963
28963
|
var debug = require_debug2();
|
|
@@ -29907,12 +29907,12 @@ var require_plugin_utils = __commonJS({
|
|
|
29907
29907
|
if (display) {
|
|
29908
29908
|
return display;
|
|
29909
29909
|
}
|
|
29910
|
-
const
|
|
29911
|
-
if (
|
|
29912
|
-
const keys = Object.keys(
|
|
29910
|
+
const cache2 = __require.cache;
|
|
29911
|
+
if (cache2) {
|
|
29912
|
+
const keys = Object.keys(cache2);
|
|
29913
29913
|
for (let i = 0; i < keys.length; i++) {
|
|
29914
29914
|
const key = keys[i];
|
|
29915
|
-
if (
|
|
29915
|
+
if (cache2[key].exports === func) {
|
|
29916
29916
|
return key;
|
|
29917
29917
|
}
|
|
29918
29918
|
}
|
|
@@ -32002,13 +32002,13 @@ var require_node = __commonJS({
|
|
|
32002
32002
|
this.staticChildrenNodes[index] = node;
|
|
32003
32003
|
}
|
|
32004
32004
|
}
|
|
32005
|
-
findStaticMatchingChild(
|
|
32006
|
-
const charCode =
|
|
32005
|
+
findStaticMatchingChild(path2, pathIndex) {
|
|
32006
|
+
const charCode = path2.charCodeAt(pathIndex);
|
|
32007
32007
|
const charCodes = this.staticChildrenCharCodes;
|
|
32008
32008
|
for (let i = 0; i < charCodes.length; i++) {
|
|
32009
32009
|
if (charCodes[i] === charCode) {
|
|
32010
32010
|
const staticChild = this.staticChildrenNodes[i];
|
|
32011
|
-
if (staticChild.matchPrefix(
|
|
32011
|
+
if (staticChild.matchPrefix(path2, pathIndex)) {
|
|
32012
32012
|
return staticChild;
|
|
32013
32013
|
}
|
|
32014
32014
|
return null;
|
|
@@ -32016,34 +32016,34 @@ var require_node = __commonJS({
|
|
|
32016
32016
|
}
|
|
32017
32017
|
return null;
|
|
32018
32018
|
}
|
|
32019
|
-
getStaticChild(
|
|
32020
|
-
if (
|
|
32019
|
+
getStaticChild(path2, pathIndex = 0) {
|
|
32020
|
+
if (path2.length === pathIndex) {
|
|
32021
32021
|
return this;
|
|
32022
32022
|
}
|
|
32023
|
-
const staticChild = this.findStaticMatchingChild(
|
|
32023
|
+
const staticChild = this.findStaticMatchingChild(path2, pathIndex);
|
|
32024
32024
|
if (staticChild) {
|
|
32025
|
-
return staticChild.getStaticChild(
|
|
32025
|
+
return staticChild.getStaticChild(path2, pathIndex + staticChild.prefix.length);
|
|
32026
32026
|
}
|
|
32027
32027
|
return null;
|
|
32028
32028
|
}
|
|
32029
|
-
createStaticChild(
|
|
32030
|
-
if (
|
|
32029
|
+
createStaticChild(path2) {
|
|
32030
|
+
if (path2.length === 0) {
|
|
32031
32031
|
return this;
|
|
32032
32032
|
}
|
|
32033
|
-
const childIndex = this.staticChildrenCharCodes.indexOf(
|
|
32033
|
+
const childIndex = this.staticChildrenCharCodes.indexOf(path2.charCodeAt(0));
|
|
32034
32034
|
let staticChild = childIndex === -1 ? void 0 : this.staticChildrenNodes[childIndex];
|
|
32035
32035
|
if (staticChild) {
|
|
32036
32036
|
let i = 1;
|
|
32037
32037
|
for (; i < staticChild.prefix.length; i++) {
|
|
32038
|
-
if (
|
|
32038
|
+
if (path2.charCodeAt(i) !== staticChild.prefix.charCodeAt(i)) {
|
|
32039
32039
|
staticChild = staticChild.split(this, i);
|
|
32040
32040
|
break;
|
|
32041
32041
|
}
|
|
32042
32042
|
}
|
|
32043
|
-
return staticChild.createStaticChild(
|
|
32043
|
+
return staticChild.createStaticChild(path2.slice(i));
|
|
32044
32044
|
}
|
|
32045
|
-
const node = new StaticNode(
|
|
32046
|
-
this.setStaticChild(
|
|
32045
|
+
const node = new StaticNode(path2);
|
|
32046
|
+
this.setStaticChild(path2.charAt(0), node);
|
|
32047
32047
|
return node;
|
|
32048
32048
|
}
|
|
32049
32049
|
};
|
|
@@ -32103,8 +32103,8 @@ var require_node = __commonJS({
|
|
|
32103
32103
|
parentNode.setStaticChild(parentPrefix.charAt(0), staticNode);
|
|
32104
32104
|
return staticNode;
|
|
32105
32105
|
}
|
|
32106
|
-
getNextNode(
|
|
32107
|
-
let node = this.findStaticMatchingChild(
|
|
32106
|
+
getNextNode(path2, pathIndex, nodeStack, paramsCount) {
|
|
32107
|
+
let node = this.findStaticMatchingChild(path2, pathIndex);
|
|
32108
32108
|
let parametricBrotherNodeIndex = 0;
|
|
32109
32109
|
if (node === null) {
|
|
32110
32110
|
if (this.parametricChildren.length === 0) {
|
|
@@ -32151,8 +32151,8 @@ var require_node = __commonJS({
|
|
|
32151
32151
|
this.kind = NODE_TYPES.PARAMETRIC;
|
|
32152
32152
|
this.nodePaths = /* @__PURE__ */ new Set([nodePath]);
|
|
32153
32153
|
}
|
|
32154
|
-
getNextNode(
|
|
32155
|
-
return this.findStaticMatchingChild(
|
|
32154
|
+
getNextNode(path2, pathIndex) {
|
|
32155
|
+
return this.findStaticMatchingChild(path2, pathIndex);
|
|
32156
32156
|
}
|
|
32157
32157
|
};
|
|
32158
32158
|
var WildcardNode = class extends Node {
|
|
@@ -32508,81 +32508,81 @@ var require_url_sanitizer = __commonJS({
|
|
|
32508
32508
|
return String.fromCharCode(charCode);
|
|
32509
32509
|
}
|
|
32510
32510
|
var MIN_NATIVE_SCAN_LENGTH = 12;
|
|
32511
|
-
function safeDecodeURI(
|
|
32512
|
-
if (
|
|
32513
|
-
return safeDecodeURINativeScan(
|
|
32511
|
+
function safeDecodeURI(path2, useSemicolonDelimiter) {
|
|
32512
|
+
if (path2.length >= MIN_NATIVE_SCAN_LENGTH) {
|
|
32513
|
+
return safeDecodeURINativeScan(path2, useSemicolonDelimiter);
|
|
32514
32514
|
}
|
|
32515
|
-
return safeDecodeURICharScan(
|
|
32515
|
+
return safeDecodeURICharScan(path2, useSemicolonDelimiter, 1);
|
|
32516
32516
|
}
|
|
32517
|
-
function safeDecodeURINativeScan(
|
|
32518
|
-
const percentIndex =
|
|
32519
|
-
let delimIndex =
|
|
32520
|
-
const hashIndex =
|
|
32517
|
+
function safeDecodeURINativeScan(path2, useSemicolonDelimiter) {
|
|
32518
|
+
const percentIndex = path2.indexOf("%", 1);
|
|
32519
|
+
let delimIndex = path2.indexOf("?", 1);
|
|
32520
|
+
const hashIndex = path2.indexOf("#", 1);
|
|
32521
32521
|
if (hashIndex !== -1 && (delimIndex === -1 || hashIndex < delimIndex)) {
|
|
32522
32522
|
delimIndex = hashIndex;
|
|
32523
32523
|
}
|
|
32524
32524
|
if (useSemicolonDelimiter) {
|
|
32525
|
-
const semicolonIndex =
|
|
32525
|
+
const semicolonIndex = path2.indexOf(";", 1);
|
|
32526
32526
|
if (semicolonIndex !== -1 && (delimIndex === -1 || semicolonIndex < delimIndex)) {
|
|
32527
32527
|
delimIndex = semicolonIndex;
|
|
32528
32528
|
}
|
|
32529
32529
|
}
|
|
32530
32530
|
if (percentIndex === -1 || delimIndex !== -1 && percentIndex > delimIndex) {
|
|
32531
32531
|
if (delimIndex === -1) {
|
|
32532
|
-
return { path, querystring: "", shouldDecodeParam: false };
|
|
32532
|
+
return { path: path2, querystring: "", shouldDecodeParam: false };
|
|
32533
32533
|
}
|
|
32534
32534
|
return {
|
|
32535
|
-
path:
|
|
32536
|
-
querystring:
|
|
32535
|
+
path: path2.slice(0, delimIndex),
|
|
32536
|
+
querystring: path2.slice(delimIndex + 1),
|
|
32537
32537
|
shouldDecodeParam: false
|
|
32538
32538
|
};
|
|
32539
32539
|
}
|
|
32540
|
-
return safeDecodeURIPercentScan(
|
|
32540
|
+
return safeDecodeURIPercentScan(path2, useSemicolonDelimiter, percentIndex);
|
|
32541
32541
|
}
|
|
32542
|
-
function safeDecodeURICharScan(
|
|
32543
|
-
for (let i = startIndex; i <
|
|
32544
|
-
const charCode =
|
|
32542
|
+
function safeDecodeURICharScan(path2, useSemicolonDelimiter, startIndex) {
|
|
32543
|
+
for (let i = startIndex; i < path2.length; i++) {
|
|
32544
|
+
const charCode = path2.charCodeAt(i);
|
|
32545
32545
|
if (charCode === 37) {
|
|
32546
|
-
return safeDecodeURIPercentScan(
|
|
32546
|
+
return safeDecodeURIPercentScan(path2, useSemicolonDelimiter, i);
|
|
32547
32547
|
} else if (charCode === 63 || charCode === 35 || charCode === 59 && useSemicolonDelimiter) {
|
|
32548
32548
|
return {
|
|
32549
|
-
path:
|
|
32550
|
-
querystring:
|
|
32549
|
+
path: path2.slice(0, i),
|
|
32550
|
+
querystring: path2.slice(i + 1),
|
|
32551
32551
|
shouldDecodeParam: false
|
|
32552
32552
|
};
|
|
32553
32553
|
}
|
|
32554
32554
|
}
|
|
32555
|
-
return { path, querystring: "", shouldDecodeParam: false };
|
|
32555
|
+
return { path: path2, querystring: "", shouldDecodeParam: false };
|
|
32556
32556
|
}
|
|
32557
|
-
function reencodePercentChar(
|
|
32558
|
-
return
|
|
32557
|
+
function reencodePercentChar(path2, index) {
|
|
32558
|
+
return path2.slice(0, index + 1) + "25" + path2.slice(index + 1);
|
|
32559
32559
|
}
|
|
32560
|
-
function safeDecodeURIPercentScan(
|
|
32560
|
+
function safeDecodeURIPercentScan(path2, useSemicolonDelimiter, startIndex) {
|
|
32561
32561
|
let shouldDecode = false;
|
|
32562
32562
|
let shouldDecodeParam = false;
|
|
32563
32563
|
let querystring = "";
|
|
32564
|
-
for (let i = startIndex; i <
|
|
32565
|
-
const charCode =
|
|
32564
|
+
for (let i = startIndex; i < path2.length; i++) {
|
|
32565
|
+
const charCode = path2.charCodeAt(i);
|
|
32566
32566
|
if (charCode === 37) {
|
|
32567
|
-
const componentCharCode = decodeComponentCharCode(
|
|
32567
|
+
const componentCharCode = decodeComponentCharCode(path2.charCodeAt(i + 1), path2.charCodeAt(i + 2));
|
|
32568
32568
|
if (componentCharCode === 0) {
|
|
32569
32569
|
shouldDecode = true;
|
|
32570
32570
|
} else {
|
|
32571
32571
|
shouldDecodeParam = true;
|
|
32572
32572
|
if (componentCharCode === 37) {
|
|
32573
32573
|
shouldDecode = true;
|
|
32574
|
-
|
|
32574
|
+
path2 = reencodePercentChar(path2, i);
|
|
32575
32575
|
i += 2;
|
|
32576
32576
|
}
|
|
32577
32577
|
i += 2;
|
|
32578
32578
|
}
|
|
32579
32579
|
} else if (charCode === 63 || charCode === 35 || charCode === 59 && useSemicolonDelimiter) {
|
|
32580
|
-
querystring =
|
|
32581
|
-
|
|
32580
|
+
querystring = path2.slice(i + 1);
|
|
32581
|
+
path2 = path2.slice(0, i);
|
|
32582
32582
|
break;
|
|
32583
32583
|
}
|
|
32584
32584
|
}
|
|
32585
|
-
const decodedPath = shouldDecode ? decodeURI(
|
|
32585
|
+
const decodedPath = shouldDecode ? decodeURI(path2) : path2;
|
|
32586
32586
|
return { path: decodedPath, querystring, shouldDecodeParam };
|
|
32587
32587
|
}
|
|
32588
32588
|
function safeDecodeURIComponent(uriComponent) {
|
|
@@ -32677,7 +32677,7 @@ var require_find_my_way = __commonJS({
|
|
|
32677
32677
|
this.trees = /* @__PURE__ */ Object.create(null);
|
|
32678
32678
|
this._treeGET = null;
|
|
32679
32679
|
}
|
|
32680
|
-
Router.prototype.on = function on2(method,
|
|
32680
|
+
Router.prototype.on = function on2(method, path2, opts, handler, store) {
|
|
32681
32681
|
if (typeof opts === "function") {
|
|
32682
32682
|
if (handler !== void 0) {
|
|
32683
32683
|
store = handler;
|
|
@@ -32685,34 +32685,34 @@ var require_find_my_way = __commonJS({
|
|
|
32685
32685
|
handler = opts;
|
|
32686
32686
|
opts = {};
|
|
32687
32687
|
}
|
|
32688
|
-
assert(typeof
|
|
32689
|
-
assert(
|
|
32690
|
-
assert(
|
|
32688
|
+
assert(typeof path2 === "string", "Path should be a string");
|
|
32689
|
+
assert(path2.length > 0, "The path could not be empty");
|
|
32690
|
+
assert(path2[0] === "/" || path2[0] === "*", "The first character of a path should be `/` or `*`");
|
|
32691
32691
|
assert(typeof handler === "function", "Handler should be a function");
|
|
32692
|
-
const optionalParamMatch =
|
|
32692
|
+
const optionalParamMatch = path2.match(OPTIONAL_PARAM_REGEXP);
|
|
32693
32693
|
if (optionalParamMatch) {
|
|
32694
|
-
assert(
|
|
32695
|
-
const pathFull =
|
|
32696
|
-
const pathOptional =
|
|
32694
|
+
assert(path2.length === optionalParamMatch.index + optionalParamMatch[0].length, "Optional Parameter needs to be the last parameter of the path");
|
|
32695
|
+
const pathFull = path2.replace(OPTIONAL_PARAM_REGEXP, "$1$2");
|
|
32696
|
+
const pathOptional = path2.replace(OPTIONAL_PARAM_REGEXP, "$2") || "/";
|
|
32697
32697
|
this.on(method, pathFull, opts, handler, store);
|
|
32698
32698
|
this.on(method, pathOptional, opts, handler, store);
|
|
32699
32699
|
return;
|
|
32700
32700
|
}
|
|
32701
|
-
const route =
|
|
32701
|
+
const route = path2;
|
|
32702
32702
|
if (this.ignoreDuplicateSlashes) {
|
|
32703
|
-
|
|
32703
|
+
path2 = removeDuplicateSlashes(path2);
|
|
32704
32704
|
}
|
|
32705
32705
|
if (this.ignoreTrailingSlash) {
|
|
32706
|
-
|
|
32706
|
+
path2 = trimLastSlash(path2);
|
|
32707
32707
|
}
|
|
32708
32708
|
const methods = Array.isArray(method) ? method : [method];
|
|
32709
32709
|
for (const method2 of methods) {
|
|
32710
32710
|
assert(typeof method2 === "string", "Method should be a string");
|
|
32711
32711
|
assert(httpMethods.includes(method2), `Method '${method2}' is not an http method.`);
|
|
32712
|
-
this._on(method2,
|
|
32712
|
+
this._on(method2, path2, opts, handler, store, route);
|
|
32713
32713
|
}
|
|
32714
32714
|
};
|
|
32715
|
-
Router.prototype._on = function _on(method,
|
|
32715
|
+
Router.prototype._on = function _on(method, path2, opts, handler, store) {
|
|
32716
32716
|
let constraints = {};
|
|
32717
32717
|
if (opts.constraints !== void 0) {
|
|
32718
32718
|
assert(typeof opts.constraints === "object" && opts.constraints !== null, "Constraints should be an object");
|
|
@@ -32725,7 +32725,7 @@ var require_find_my_way = __commonJS({
|
|
|
32725
32725
|
if (this.trees[method] === void 0) {
|
|
32726
32726
|
this.trees[method] = new StaticNode("/");
|
|
32727
32727
|
}
|
|
32728
|
-
let pattern =
|
|
32728
|
+
let pattern = path2;
|
|
32729
32729
|
if (pattern === "*" && this.trees[method].prefix.length !== 0) {
|
|
32730
32730
|
const currentRoot = this.trees[method];
|
|
32731
32731
|
this.trees[method] = new StaticNode("");
|
|
@@ -32833,19 +32833,19 @@ var require_find_my_way = __commonJS({
|
|
|
32833
32833
|
throw new Error(`Method '${method}' already declared for route '${pattern}' with constraints '${JSON.stringify(constraints)}'`);
|
|
32834
32834
|
}
|
|
32835
32835
|
}
|
|
32836
|
-
const route = { method, path, pattern, params, opts, handler, store };
|
|
32836
|
+
const route = { method, path: path2, pattern, params, opts, handler, store };
|
|
32837
32837
|
this.routes.push(route);
|
|
32838
32838
|
currentNode.addRoute(route, this.constrainer);
|
|
32839
32839
|
};
|
|
32840
|
-
Router.prototype.hasRoute = function hasRoute(method,
|
|
32841
|
-
const route = this.findRoute(method,
|
|
32840
|
+
Router.prototype.hasRoute = function hasRoute(method, path2, constraints) {
|
|
32841
|
+
const route = this.findRoute(method, path2, constraints);
|
|
32842
32842
|
return route !== null;
|
|
32843
32843
|
};
|
|
32844
|
-
Router.prototype.findRoute = function findNode(method,
|
|
32844
|
+
Router.prototype.findRoute = function findNode(method, path2, constraints = {}) {
|
|
32845
32845
|
if (this.trees[method] === void 0) {
|
|
32846
32846
|
return null;
|
|
32847
32847
|
}
|
|
32848
|
-
let pattern =
|
|
32848
|
+
let pattern = path2;
|
|
32849
32849
|
let currentNode = this.trees[method];
|
|
32850
32850
|
let parentNodePathIndex = currentNode.prefix.length;
|
|
32851
32851
|
const params = [];
|
|
@@ -32966,39 +32966,39 @@ var require_find_my_way = __commonJS({
|
|
|
32966
32966
|
this._treeGET = null;
|
|
32967
32967
|
this.routes = [];
|
|
32968
32968
|
};
|
|
32969
|
-
Router.prototype.off = function off(method,
|
|
32970
|
-
assert(typeof
|
|
32971
|
-
assert(
|
|
32972
|
-
assert(
|
|
32969
|
+
Router.prototype.off = function off(method, path2, constraints) {
|
|
32970
|
+
assert(typeof path2 === "string", "Path should be a string");
|
|
32971
|
+
assert(path2.length > 0, "The path could not be empty");
|
|
32972
|
+
assert(path2[0] === "/" || path2[0] === "*", "The first character of a path should be `/` or `*`");
|
|
32973
32973
|
assert(
|
|
32974
32974
|
typeof constraints === "undefined" || typeof constraints === "object" && !Array.isArray(constraints) && constraints !== null,
|
|
32975
32975
|
"Constraints should be an object or undefined."
|
|
32976
32976
|
);
|
|
32977
|
-
const optionalParamMatch =
|
|
32977
|
+
const optionalParamMatch = path2.match(OPTIONAL_PARAM_REGEXP);
|
|
32978
32978
|
if (optionalParamMatch) {
|
|
32979
|
-
assert(
|
|
32980
|
-
const pathFull =
|
|
32981
|
-
const pathOptional =
|
|
32979
|
+
assert(path2.length === optionalParamMatch.index + optionalParamMatch[0].length, "Optional Parameter needs to be the last parameter of the path");
|
|
32980
|
+
const pathFull = path2.replace(OPTIONAL_PARAM_REGEXP, "$1$2");
|
|
32981
|
+
const pathOptional = path2.replace(OPTIONAL_PARAM_REGEXP, "$2") || "/";
|
|
32982
32982
|
this.off(method, pathFull, constraints);
|
|
32983
32983
|
this.off(method, pathOptional, constraints);
|
|
32984
32984
|
return;
|
|
32985
32985
|
}
|
|
32986
32986
|
if (this.ignoreDuplicateSlashes) {
|
|
32987
|
-
|
|
32987
|
+
path2 = removeDuplicateSlashes(path2);
|
|
32988
32988
|
}
|
|
32989
32989
|
if (this.ignoreTrailingSlash) {
|
|
32990
|
-
|
|
32990
|
+
path2 = trimLastSlash(path2);
|
|
32991
32991
|
}
|
|
32992
32992
|
const methods = Array.isArray(method) ? method : [method];
|
|
32993
32993
|
for (const method2 of methods) {
|
|
32994
|
-
this._off(method2,
|
|
32994
|
+
this._off(method2, path2, constraints);
|
|
32995
32995
|
}
|
|
32996
32996
|
};
|
|
32997
|
-
Router.prototype._off = function _off(method,
|
|
32997
|
+
Router.prototype._off = function _off(method, path2, constraints) {
|
|
32998
32998
|
assert(typeof method === "string", "Method should be a string");
|
|
32999
32999
|
assert(httpMethods.includes(method), `Method '${method}' is not an http method.`);
|
|
33000
33000
|
function matcherWithoutConstraints(route) {
|
|
33001
|
-
return method !== route.method ||
|
|
33001
|
+
return method !== route.method || path2 !== route.path;
|
|
33002
33002
|
}
|
|
33003
33003
|
function matcherWithConstraints(route) {
|
|
33004
33004
|
return matcherWithoutConstraints(route) || !deepEqual(constraints, route.opts.constraints || {});
|
|
@@ -33035,37 +33035,37 @@ var require_find_my_way = __commonJS({
|
|
|
33035
33035
|
if (handle === null) return this._defaultRoute(req, res, ctx);
|
|
33036
33036
|
return ctx === void 0 ? handle.handler(req, res, handle.params, handle.store, handle.searchParams) : handle.handler.call(ctx, req, res, handle.params, handle.store, handle.searchParams);
|
|
33037
33037
|
};
|
|
33038
|
-
Router.prototype.find = function find(method,
|
|
33038
|
+
Router.prototype.find = function find(method, path2, derivedConstraints) {
|
|
33039
33039
|
let currentNode = method === "GET" ? this._treeGET : this.trees[method];
|
|
33040
33040
|
if (currentNode == null) return null;
|
|
33041
|
-
if (
|
|
33042
|
-
|
|
33041
|
+
if (path2.charCodeAt(0) !== 47) {
|
|
33042
|
+
path2 = path2.replace(FULL_PATH_REGEXP, "/");
|
|
33043
33043
|
}
|
|
33044
33044
|
if (this.ignoreDuplicateSlashes) {
|
|
33045
|
-
|
|
33045
|
+
path2 = removeDuplicateSlashes(path2);
|
|
33046
33046
|
}
|
|
33047
33047
|
let sanitizedUrl;
|
|
33048
33048
|
let querystring2;
|
|
33049
33049
|
let shouldDecodeParam;
|
|
33050
33050
|
try {
|
|
33051
|
-
sanitizedUrl =
|
|
33052
|
-
|
|
33051
|
+
sanitizedUrl = path2.length >= MIN_NATIVE_SCAN_LENGTH ? safeDecodeURINativeScan(path2, this.useSemicolonDelimiter) : safeDecodeURICharScan(path2, this.useSemicolonDelimiter, 1);
|
|
33052
|
+
path2 = sanitizedUrl.path;
|
|
33053
33053
|
querystring2 = sanitizedUrl.querystring;
|
|
33054
33054
|
shouldDecodeParam = sanitizedUrl.shouldDecodeParam;
|
|
33055
33055
|
} catch (error) {
|
|
33056
|
-
return this._onBadUrl(
|
|
33056
|
+
return this._onBadUrl(path2);
|
|
33057
33057
|
}
|
|
33058
33058
|
if (this.ignoreTrailingSlash) {
|
|
33059
|
-
|
|
33059
|
+
path2 = trimLastSlash(path2);
|
|
33060
33060
|
}
|
|
33061
|
-
const originPath =
|
|
33061
|
+
const originPath = path2;
|
|
33062
33062
|
if (this.caseSensitive === false) {
|
|
33063
|
-
|
|
33063
|
+
path2 = path2.toLowerCase();
|
|
33064
33064
|
}
|
|
33065
33065
|
const maxParamLength = this.maxParamLength;
|
|
33066
33066
|
let pathIndex = currentNode.prefix.length;
|
|
33067
33067
|
const params = [];
|
|
33068
|
-
const pathLen =
|
|
33068
|
+
const pathLen = path2.length;
|
|
33069
33069
|
const brothersNodesStack = [];
|
|
33070
33070
|
let maxParamLengthExceeded = false;
|
|
33071
33071
|
while (true) {
|
|
@@ -33080,7 +33080,7 @@ var require_find_my_way = __commonJS({
|
|
|
33080
33080
|
};
|
|
33081
33081
|
}
|
|
33082
33082
|
}
|
|
33083
|
-
let node = currentNode.getNextNode(
|
|
33083
|
+
let node = currentNode.getNextNode(path2, pathIndex, brothersNodesStack, params.length);
|
|
33084
33084
|
if (node === null) {
|
|
33085
33085
|
if (brothersNodesStack.length === 0) {
|
|
33086
33086
|
if (maxParamLengthExceeded && this.onMaxParamLength) {
|
|
@@ -33181,8 +33181,8 @@ var require_find_my_way = __commonJS({
|
|
|
33181
33181
|
Router.prototype._rebuild = function(routes) {
|
|
33182
33182
|
this.reset();
|
|
33183
33183
|
for (const route of routes) {
|
|
33184
|
-
const { method, path, opts, handler, store } = route;
|
|
33185
|
-
this._on(method,
|
|
33184
|
+
const { method, path: path2, opts, handler, store } = route;
|
|
33185
|
+
this._on(method, path2, opts, handler, store);
|
|
33186
33186
|
}
|
|
33187
33187
|
};
|
|
33188
33188
|
Router.prototype._defaultRoute = function(req, res, ctx) {
|
|
@@ -33193,24 +33193,24 @@ var require_find_my_way = __commonJS({
|
|
|
33193
33193
|
res.end();
|
|
33194
33194
|
}
|
|
33195
33195
|
};
|
|
33196
|
-
Router.prototype._onBadUrl = function(
|
|
33196
|
+
Router.prototype._onBadUrl = function(path2) {
|
|
33197
33197
|
if (this.onBadUrl === null) {
|
|
33198
33198
|
return null;
|
|
33199
33199
|
}
|
|
33200
33200
|
const onBadUrl = this.onBadUrl;
|
|
33201
33201
|
return {
|
|
33202
|
-
handler: (req, res, ctx) => onBadUrl(
|
|
33202
|
+
handler: (req, res, ctx) => onBadUrl(path2, req, res),
|
|
33203
33203
|
params: {},
|
|
33204
33204
|
store: null
|
|
33205
33205
|
};
|
|
33206
33206
|
};
|
|
33207
|
-
Router.prototype._onMaxParamLength = function(
|
|
33207
|
+
Router.prototype._onMaxParamLength = function(path2) {
|
|
33208
33208
|
if (this.onMaxParamLength === null) {
|
|
33209
33209
|
return null;
|
|
33210
33210
|
}
|
|
33211
33211
|
const onMaxParamLength = this.onMaxParamLength;
|
|
33212
33212
|
return {
|
|
33213
|
-
handler: (req, res, ctx) => onMaxParamLength(
|
|
33213
|
+
handler: (req, res, ctx) => onMaxParamLength(path2, req, res),
|
|
33214
33214
|
params: {},
|
|
33215
33215
|
store: null
|
|
33216
33216
|
};
|
|
@@ -33242,12 +33242,12 @@ var require_find_my_way = __commonJS({
|
|
|
33242
33242
|
if (!httpMethods.hasOwnProperty(i)) continue;
|
|
33243
33243
|
const m = httpMethods[i];
|
|
33244
33244
|
const methodName = m.toLowerCase();
|
|
33245
|
-
Router.prototype[methodName] = function(
|
|
33246
|
-
return this.on(m,
|
|
33245
|
+
Router.prototype[methodName] = function(path2, handler, store) {
|
|
33246
|
+
return this.on(m, path2, handler, store);
|
|
33247
33247
|
};
|
|
33248
33248
|
}
|
|
33249
|
-
Router.prototype.all = function(
|
|
33250
|
-
this.on(httpMethods,
|
|
33249
|
+
Router.prototype.all = function(path2, handler, store) {
|
|
33250
|
+
this.on(httpMethods, path2, handler, store);
|
|
33251
33251
|
};
|
|
33252
33252
|
Router.sanitizeUrlPath = function sanitizeUrlPath(url, useSemicolonDelimiter) {
|
|
33253
33253
|
const decoded = safeDecodeURI(url, useSemicolonDelimiter);
|
|
@@ -33262,14 +33262,14 @@ var require_find_my_way = __commonJS({
|
|
|
33262
33262
|
function escapeRegExp(string) {
|
|
33263
33263
|
return string.replace(ESCAPE_REGEXP, "\\$&");
|
|
33264
33264
|
}
|
|
33265
|
-
function removeDuplicateSlashes(
|
|
33266
|
-
return
|
|
33265
|
+
function removeDuplicateSlashes(path2) {
|
|
33266
|
+
return path2.indexOf("//") !== -1 ? path2.replace(REMOVE_DUPLICATE_SLASHES_REGEXP, "/") : path2;
|
|
33267
33267
|
}
|
|
33268
|
-
function trimLastSlash(
|
|
33269
|
-
if (
|
|
33270
|
-
return
|
|
33268
|
+
function trimLastSlash(path2) {
|
|
33269
|
+
if (path2.length > 1 && path2.charCodeAt(path2.length - 1) === 47) {
|
|
33270
|
+
return path2.slice(0, -1);
|
|
33271
33271
|
}
|
|
33272
|
-
return
|
|
33272
|
+
return path2;
|
|
33273
33273
|
}
|
|
33274
33274
|
function trimRegExpStartAndEnd(regexString) {
|
|
33275
33275
|
if (regexString.charCodeAt(1) === 94) {
|
|
@@ -33280,22 +33280,22 @@ var require_find_my_way = __commonJS({
|
|
|
33280
33280
|
}
|
|
33281
33281
|
return regexString;
|
|
33282
33282
|
}
|
|
33283
|
-
function getClosingParenthensePosition(
|
|
33283
|
+
function getClosingParenthensePosition(path2, idx) {
|
|
33284
33284
|
let parentheses = 1;
|
|
33285
|
-
while (idx <
|
|
33285
|
+
while (idx < path2.length) {
|
|
33286
33286
|
idx++;
|
|
33287
|
-
if (
|
|
33287
|
+
if (path2.charCodeAt(idx) === 92) {
|
|
33288
33288
|
idx++;
|
|
33289
33289
|
continue;
|
|
33290
33290
|
}
|
|
33291
|
-
if (
|
|
33291
|
+
if (path2.charCodeAt(idx) === 41) {
|
|
33292
33292
|
parentheses--;
|
|
33293
|
-
} else if (
|
|
33293
|
+
} else if (path2.charCodeAt(idx) === 40) {
|
|
33294
33294
|
parentheses++;
|
|
33295
33295
|
}
|
|
33296
33296
|
if (!parentheses) return idx;
|
|
33297
33297
|
}
|
|
33298
|
-
throw new TypeError('Invalid regexp expression in "' +
|
|
33298
|
+
throw new TypeError('Invalid regexp expression in "' + path2 + '"');
|
|
33299
33299
|
}
|
|
33300
33300
|
function defaultBuildPrettyMeta(route) {
|
|
33301
33301
|
if (!route) return {};
|
|
@@ -33528,12 +33528,12 @@ var require_route = __commonJS({
|
|
|
33528
33528
|
function route({ options: options2, isFastify }) {
|
|
33529
33529
|
throwIfAlreadyStarted("Cannot add route!");
|
|
33530
33530
|
const opts = { ...options2 };
|
|
33531
|
-
const
|
|
33531
|
+
const path2 = opts.url || opts.path || "";
|
|
33532
33532
|
if (!opts.handler) {
|
|
33533
|
-
throw new FST_ERR_ROUTE_MISSING_HANDLER(opts.method,
|
|
33533
|
+
throw new FST_ERR_ROUTE_MISSING_HANDLER(opts.method, path2);
|
|
33534
33534
|
}
|
|
33535
33535
|
if (opts.errorHandler !== void 0 && typeof opts.errorHandler !== "function") {
|
|
33536
|
-
throw new FST_ERR_ROUTE_HANDLER_NOT_FN(opts.method,
|
|
33536
|
+
throw new FST_ERR_ROUTE_HANDLER_NOT_FN(opts.method, path2);
|
|
33537
33537
|
}
|
|
33538
33538
|
validateBodyLimitOption(opts.bodyLimit);
|
|
33539
33539
|
validateHandlerTimeoutOption(opts.handlerTimeout);
|
|
@@ -33543,22 +33543,22 @@ var require_route = __commonJS({
|
|
|
33543
33543
|
if (Array.isArray(opts.method)) {
|
|
33544
33544
|
for (let i = 0; i < opts.method.length; ++i) {
|
|
33545
33545
|
opts.method[i] = normalizeAndValidateMethod.call(this, opts.method[i]);
|
|
33546
|
-
validateSchemaBodyOption.call(this, opts.method[i],
|
|
33546
|
+
validateSchemaBodyOption.call(this, opts.method[i], path2, opts.schema);
|
|
33547
33547
|
isGetRoute = opts.method.includes("GET");
|
|
33548
33548
|
isHeadRoute = opts.method.includes("HEAD");
|
|
33549
33549
|
}
|
|
33550
33550
|
} else {
|
|
33551
33551
|
opts.method = normalizeAndValidateMethod.call(this, opts.method);
|
|
33552
|
-
validateSchemaBodyOption.call(this, opts.method,
|
|
33552
|
+
validateSchemaBodyOption.call(this, opts.method, path2, opts.schema);
|
|
33553
33553
|
isGetRoute = opts.method === "GET";
|
|
33554
33554
|
isHeadRoute = opts.method === "HEAD";
|
|
33555
33555
|
}
|
|
33556
33556
|
const headOpts = shouldExposeHead && isGetRoute ? { ...options2 } : null;
|
|
33557
33557
|
const prefix = this[kRoutePrefix];
|
|
33558
|
-
if (
|
|
33558
|
+
if (path2 === "/" && prefix.length > 0 && opts.method !== "HEAD") {
|
|
33559
33559
|
switch (opts.prefixTrailingSlash) {
|
|
33560
33560
|
case "slash":
|
|
33561
|
-
addNewRoute.call(this, { path, isFastify });
|
|
33561
|
+
addNewRoute.call(this, { path: path2, isFastify });
|
|
33562
33562
|
break;
|
|
33563
33563
|
case "no-slash":
|
|
33564
33564
|
addNewRoute.call(this, { path: "", isFastify });
|
|
@@ -33567,20 +33567,20 @@ var require_route = __commonJS({
|
|
|
33567
33567
|
default:
|
|
33568
33568
|
addNewRoute.call(this, { path: "", isFastify });
|
|
33569
33569
|
if (ignoreTrailingSlash !== true && (ignoreDuplicateSlashes !== true || !prefix.endsWith("/"))) {
|
|
33570
|
-
addNewRoute.call(this, { path, prefixing: true, isFastify });
|
|
33570
|
+
addNewRoute.call(this, { path: path2, prefixing: true, isFastify });
|
|
33571
33571
|
}
|
|
33572
33572
|
}
|
|
33573
|
-
} else if (
|
|
33574
|
-
addNewRoute.call(this, { path:
|
|
33573
|
+
} else if (path2[0] === "/" && prefix.endsWith("/")) {
|
|
33574
|
+
addNewRoute.call(this, { path: path2.slice(1), isFastify });
|
|
33575
33575
|
} else {
|
|
33576
|
-
addNewRoute.call(this, { path, isFastify });
|
|
33576
|
+
addNewRoute.call(this, { path: path2, isFastify });
|
|
33577
33577
|
}
|
|
33578
33578
|
return this;
|
|
33579
|
-
function addNewRoute({ path:
|
|
33580
|
-
const url = prefix +
|
|
33579
|
+
function addNewRoute({ path: path3, prefixing = false, isFastify: isFastify2 = false }) {
|
|
33580
|
+
const url = prefix + path3;
|
|
33581
33581
|
opts.url = url;
|
|
33582
33582
|
opts.path = url;
|
|
33583
|
-
opts.routePath =
|
|
33583
|
+
opts.routePath = path3;
|
|
33584
33584
|
opts.prefix = prefix;
|
|
33585
33585
|
opts.logLevel = opts.logLevel || this[kLogLevel];
|
|
33586
33586
|
validateLogLevelOption(opts.logLevel, opts.method, opts.url, logger);
|
|
@@ -33712,7 +33712,7 @@ var require_route = __commonJS({
|
|
|
33712
33712
|
});
|
|
33713
33713
|
if (shouldExposeHead && isGetRoute && !isHeadRoute && !hasHEADHandler) {
|
|
33714
33714
|
const onSendHandlers = parseHeadOnSendHandlers(headOpts.onSend);
|
|
33715
|
-
prepareRoute.call(this, { method: "HEAD", url:
|
|
33715
|
+
prepareRoute.call(this, { method: "HEAD", url: path3, options: { ...headOpts, onSend: onSendHandlers }, isFastify: true });
|
|
33716
33716
|
}
|
|
33717
33717
|
}
|
|
33718
33718
|
}
|
|
@@ -33836,9 +33836,9 @@ var require_route = __commonJS({
|
|
|
33836
33836
|
}
|
|
33837
33837
|
return method;
|
|
33838
33838
|
}
|
|
33839
|
-
function validateSchemaBodyOption(method,
|
|
33839
|
+
function validateSchemaBodyOption(method, path2, schema) {
|
|
33840
33840
|
if (this[kSupportedHTTPMethods].bodyless.has(method) && schema?.body) {
|
|
33841
|
-
throw new FST_ERR_ROUTE_BODY_VALIDATION_SCHEMA_NOT_SUPPORTED(method,
|
|
33841
|
+
throw new FST_ERR_ROUTE_BODY_VALIDATION_SCHEMA_NOT_SUPPORTED(method, path2);
|
|
33842
33842
|
}
|
|
33843
33843
|
}
|
|
33844
33844
|
function validateBodyLimitOption(bodyLimit) {
|
|
@@ -33853,11 +33853,11 @@ var require_route = __commonJS({
|
|
|
33853
33853
|
throw new FST_ERR_ROUTE_HANDLER_TIMEOUT_OPTION_NOT_INT(handlerTimeout);
|
|
33854
33854
|
}
|
|
33855
33855
|
}
|
|
33856
|
-
function validateLogLevelOption(logLevel, method,
|
|
33856
|
+
function validateLogLevelOption(logLevel, method, path2, logger) {
|
|
33857
33857
|
if (logLevel == null || logLevel === "") return;
|
|
33858
33858
|
if (logger?.levels?.values == null) return;
|
|
33859
33859
|
if (typeof logLevel !== "string" || logger.levels.values[logLevel] === void 0) {
|
|
33860
|
-
throw new FST_ERR_ROUTE_LOG_LEVEL_INVALID(method,
|
|
33860
|
+
throw new FST_ERR_ROUTE_LOG_LEVEL_INVALID(method, path2, logLevel);
|
|
33861
33861
|
}
|
|
33862
33862
|
}
|
|
33863
33863
|
function runPreParsing(err, request, reply) {
|
|
@@ -33946,7 +33946,7 @@ var require_four_oh_four = __commonJS({
|
|
|
33946
33946
|
});
|
|
33947
33947
|
}
|
|
33948
33948
|
function createRouteEventHandler() {
|
|
33949
|
-
return function onRouteEvent(
|
|
33949
|
+
return function onRouteEvent(path2, req, res) {
|
|
33950
33950
|
const fourOhFourContext = this[kFourOhFourLevelInstance][kFourOhFourContext];
|
|
33951
33951
|
const id2 = getGenReqId(fourOhFourContext.server, req);
|
|
33952
33952
|
const childLogger = createChildLogger(fourOhFourContext, logger, req, id2);
|
|
@@ -36617,19 +36617,19 @@ var require_fastify = __commonJS({
|
|
|
36617
36617
|
}
|
|
36618
36618
|
fourOhFour.router.lookup(req, res);
|
|
36619
36619
|
}
|
|
36620
|
-
function onBadUrl(
|
|
36620
|
+
function onBadUrl(path2, req, res) {
|
|
36621
36621
|
if (options.frameworkErrors) {
|
|
36622
36622
|
const id2 = getGenReqId(routeEventContext.server, req);
|
|
36623
36623
|
const childLogger = createChildLogger(routeEventContext, options.logger, req, id2);
|
|
36624
36624
|
const request = new Request(id2, null, req, null, childLogger, routeEventContext);
|
|
36625
36625
|
const reply = new Reply(res, request, childLogger);
|
|
36626
36626
|
routeEventContext.server[kLogController].incomingRequest(request, reply);
|
|
36627
|
-
return options.frameworkErrors(new FST_ERR_BAD_URL(
|
|
36627
|
+
return options.frameworkErrors(new FST_ERR_BAD_URL(path2), request, reply);
|
|
36628
36628
|
}
|
|
36629
36629
|
const body = JSON.stringify({
|
|
36630
36630
|
error: "Bad Request",
|
|
36631
36631
|
code: "FST_ERR_BAD_URL",
|
|
36632
|
-
message: `'${
|
|
36632
|
+
message: `'${path2}' is not a valid url component`,
|
|
36633
36633
|
statusCode: 400
|
|
36634
36634
|
});
|
|
36635
36635
|
res.writeHead(400, {
|
|
@@ -36638,19 +36638,19 @@ var require_fastify = __commonJS({
|
|
|
36638
36638
|
});
|
|
36639
36639
|
res.end(body);
|
|
36640
36640
|
}
|
|
36641
|
-
function onMaxParamLength(
|
|
36641
|
+
function onMaxParamLength(path2, req, res) {
|
|
36642
36642
|
if (options.frameworkErrors) {
|
|
36643
36643
|
const id2 = getGenReqId(routeEventContext.server, req);
|
|
36644
36644
|
const childLogger = createChildLogger(routeEventContext, options.logger, req, id2);
|
|
36645
36645
|
const request = new Request(id2, null, req, null, childLogger, routeEventContext);
|
|
36646
36646
|
const reply = new Reply(res, request, childLogger);
|
|
36647
36647
|
routeEventContext.server[kLogController].incomingRequest(request, reply);
|
|
36648
|
-
return options.frameworkErrors(new FST_ERR_MAX_PARAM_LENGTH(
|
|
36648
|
+
return options.frameworkErrors(new FST_ERR_MAX_PARAM_LENGTH(path2), request, reply);
|
|
36649
36649
|
}
|
|
36650
36650
|
const body = JSON.stringify({
|
|
36651
36651
|
error: "Bad Request",
|
|
36652
36652
|
code: "FST_ERR_MAX_PARAM_LENGTH",
|
|
36653
|
-
message: `'${
|
|
36653
|
+
message: `'${path2}' is exceeding the max param length`,
|
|
36654
36654
|
statusCode: 414
|
|
36655
36655
|
});
|
|
36656
36656
|
res.writeHead(414, {
|
|
@@ -37376,20 +37376,20 @@ var require_file_uri_to_path = __commonJS({
|
|
|
37376
37376
|
var rest = decodeURI(uri.substring(7));
|
|
37377
37377
|
var firstSlash = rest.indexOf("/");
|
|
37378
37378
|
var host = rest.substring(0, firstSlash);
|
|
37379
|
-
var
|
|
37379
|
+
var path2 = rest.substring(firstSlash + 1);
|
|
37380
37380
|
if ("localhost" == host) host = "";
|
|
37381
37381
|
if (host) {
|
|
37382
37382
|
host = sep5 + sep5 + host;
|
|
37383
37383
|
}
|
|
37384
|
-
|
|
37384
|
+
path2 = path2.replace(/^(.+)\|/, "$1:");
|
|
37385
37385
|
if (sep5 == "\\") {
|
|
37386
|
-
|
|
37386
|
+
path2 = path2.replace(/\//g, "\\");
|
|
37387
37387
|
}
|
|
37388
|
-
if (/^.+\:/.test(
|
|
37388
|
+
if (/^.+\:/.test(path2)) {
|
|
37389
37389
|
} else {
|
|
37390
|
-
|
|
37390
|
+
path2 = sep5 + path2;
|
|
37391
37391
|
}
|
|
37392
|
-
return host +
|
|
37392
|
+
return host + path2;
|
|
37393
37393
|
}
|
|
37394
37394
|
}
|
|
37395
37395
|
});
|
|
@@ -37398,18 +37398,18 @@ var require_file_uri_to_path = __commonJS({
|
|
|
37398
37398
|
var require_bindings = __commonJS({
|
|
37399
37399
|
"node_modules/bindings/bindings.js"(exports, module) {
|
|
37400
37400
|
var fs = __require("fs");
|
|
37401
|
-
var
|
|
37401
|
+
var path2 = __require("path");
|
|
37402
37402
|
var fileURLToPath = require_file_uri_to_path();
|
|
37403
|
-
var join6 =
|
|
37404
|
-
var dirname4 =
|
|
37405
|
-
var exists = fs.accessSync && function(
|
|
37403
|
+
var join6 = path2.join;
|
|
37404
|
+
var dirname4 = path2.dirname;
|
|
37405
|
+
var exists = fs.accessSync && function(path3) {
|
|
37406
37406
|
try {
|
|
37407
|
-
fs.accessSync(
|
|
37407
|
+
fs.accessSync(path3);
|
|
37408
37408
|
} catch (e) {
|
|
37409
37409
|
return false;
|
|
37410
37410
|
}
|
|
37411
37411
|
return true;
|
|
37412
|
-
} || fs.existsSync ||
|
|
37412
|
+
} || fs.existsSync || path2.existsSync;
|
|
37413
37413
|
var defaults = {
|
|
37414
37414
|
arrow: process.env.NODE_BINDINGS_ARROW || " \u2192 ",
|
|
37415
37415
|
compiled: process.env.NODE_BINDINGS_COMPILED_DIR || "compiled",
|
|
@@ -37454,7 +37454,7 @@ var require_bindings = __commonJS({
|
|
|
37454
37454
|
if (!opts.module_root) {
|
|
37455
37455
|
opts.module_root = exports.getRoot(exports.getFileName());
|
|
37456
37456
|
}
|
|
37457
|
-
if (
|
|
37457
|
+
if (path2.extname(opts.bindings) != ".node") {
|
|
37458
37458
|
opts.bindings += ".node";
|
|
37459
37459
|
}
|
|
37460
37460
|
var requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
|
|
@@ -37693,7 +37693,7 @@ var require_backup = __commonJS({
|
|
|
37693
37693
|
"node_modules/better-sqlite3/lib/methods/backup.js"(exports, module) {
|
|
37694
37694
|
"use strict";
|
|
37695
37695
|
var fs = __require("fs");
|
|
37696
|
-
var
|
|
37696
|
+
var path2 = __require("path");
|
|
37697
37697
|
var { promisify: promisify2 } = __require("util");
|
|
37698
37698
|
var { cppdb } = require_util3();
|
|
37699
37699
|
var fsAccess = promisify2(fs.access);
|
|
@@ -37709,7 +37709,7 @@ var require_backup = __commonJS({
|
|
|
37709
37709
|
if (typeof attachedName !== "string") throw new TypeError('Expected the "attached" option to be a string');
|
|
37710
37710
|
if (!attachedName) throw new TypeError('The "attached" option cannot be an empty string');
|
|
37711
37711
|
if (handler != null && typeof handler !== "function") throw new TypeError('Expected the "progress" option to be a function');
|
|
37712
|
-
await fsAccess(
|
|
37712
|
+
await fsAccess(path2.dirname(filename)).catch(() => {
|
|
37713
37713
|
throw new TypeError("Cannot save backup because the directory does not exist");
|
|
37714
37714
|
});
|
|
37715
37715
|
const isNewFile = await fsAccess(filename).then(() => false, () => true);
|
|
@@ -38015,7 +38015,7 @@ var require_database = __commonJS({
|
|
|
38015
38015
|
"node_modules/better-sqlite3/lib/database.js"(exports, module) {
|
|
38016
38016
|
"use strict";
|
|
38017
38017
|
var fs = __require("fs");
|
|
38018
|
-
var
|
|
38018
|
+
var path2 = __require("path");
|
|
38019
38019
|
var util = require_util3();
|
|
38020
38020
|
var SqliteError = require_sqlite_error();
|
|
38021
38021
|
var DEFAULT_ADDON;
|
|
@@ -38051,7 +38051,7 @@ var require_database = __commonJS({
|
|
|
38051
38051
|
addon = DEFAULT_ADDON || (DEFAULT_ADDON = require_bindings()("better_sqlite3.node"));
|
|
38052
38052
|
} else if (typeof nativeBinding === "string") {
|
|
38053
38053
|
const requireFunc = typeof __non_webpack_require__ === "function" ? __non_webpack_require__ : __require;
|
|
38054
|
-
addon = requireFunc(
|
|
38054
|
+
addon = requireFunc(path2.resolve(nativeBinding).replace(/(\.node)?$/, ".node"));
|
|
38055
38055
|
} else {
|
|
38056
38056
|
addon = nativeBinding;
|
|
38057
38057
|
}
|
|
@@ -38059,7 +38059,7 @@ var require_database = __commonJS({
|
|
|
38059
38059
|
addon.setErrorConstructor(SqliteError);
|
|
38060
38060
|
addon.isInitialized = true;
|
|
38061
38061
|
}
|
|
38062
|
-
if (!anonymous && !fs.existsSync(
|
|
38062
|
+
if (!anonymous && !fs.existsSync(path2.dirname(filename))) {
|
|
38063
38063
|
throw new TypeError("Cannot open database because the directory does not exist");
|
|
38064
38064
|
}
|
|
38065
38065
|
Object.defineProperties(this, {
|
|
@@ -41772,8 +41772,8 @@ var import_cors = __toESM(require_cors(), 1);
|
|
|
41772
41772
|
// src/db/index.ts
|
|
41773
41773
|
var import_better_sqlite3 = __toESM(require_lib2(), 1);
|
|
41774
41774
|
var db;
|
|
41775
|
-
function initDb(
|
|
41776
|
-
db = new import_better_sqlite3.default(
|
|
41775
|
+
function initDb(path2 = "data.db") {
|
|
41776
|
+
db = new import_better_sqlite3.default(path2);
|
|
41777
41777
|
db.pragma("journal_mode = WAL");
|
|
41778
41778
|
db.pragma("foreign_keys = ON");
|
|
41779
41779
|
createTables(db);
|
|
@@ -41891,6 +41891,9 @@ function createTables(database) {
|
|
|
41891
41891
|
if (!sessColumns.some((c) => c.name === "pre_rewind_thread_id")) {
|
|
41892
41892
|
database.exec("ALTER TABLE sessions ADD COLUMN pre_rewind_thread_id TEXT");
|
|
41893
41893
|
}
|
|
41894
|
+
if (!sessColumns.some((c) => c.name === "context_usage")) {
|
|
41895
|
+
database.exec("ALTER TABLE sessions ADD COLUMN context_usage TEXT");
|
|
41896
|
+
}
|
|
41894
41897
|
const turnColumns = database.prepare("PRAGMA table_info(turns)").all();
|
|
41895
41898
|
if (!turnColumns.some((c) => c.name === "thread_id")) {
|
|
41896
41899
|
database.exec("ALTER TABLE turns ADD COLUMN thread_id TEXT");
|
|
@@ -42082,6 +42085,13 @@ async function registerSessionRoutes(fastify) {
|
|
|
42082
42085
|
turns: detail.turns.filter((t) => t.thread_id === tr.id)
|
|
42083
42086
|
}));
|
|
42084
42087
|
}
|
|
42088
|
+
const cuRow = db3.prepare("SELECT context_usage FROM sessions WHERE id = ?").get(id2);
|
|
42089
|
+
if (cuRow?.context_usage) {
|
|
42090
|
+
try {
|
|
42091
|
+
detail.contextUsage = JSON.parse(cuRow.context_usage);
|
|
42092
|
+
} catch {
|
|
42093
|
+
}
|
|
42094
|
+
}
|
|
42085
42095
|
return detail;
|
|
42086
42096
|
});
|
|
42087
42097
|
fastify.post("/api/sessions", {
|
|
@@ -42504,11 +42514,20 @@ async function registerThreadRoutes(fastify) {
|
|
|
42504
42514
|
const provider = getProvider(session.runtime_type);
|
|
42505
42515
|
if (provider.forkSession) {
|
|
42506
42516
|
try {
|
|
42507
|
-
|
|
42508
|
-
|
|
42509
|
-
|
|
42510
|
-
|
|
42511
|
-
|
|
42517
|
+
if (!session.external_thread_id) {
|
|
42518
|
+
console.warn(`[threads] cannot fork for thread ${threadId}: session ${sessionId} has no external_thread_id \u2014 thread will start a fresh isolated session`);
|
|
42519
|
+
} else {
|
|
42520
|
+
const anchorTurn = db3.prepare("SELECT * FROM turns WHERE id = ?").get(turnId);
|
|
42521
|
+
if (anchorTurn) {
|
|
42522
|
+
const forkedSessionId = await provider.forkSession(session, anchorTurn);
|
|
42523
|
+
if (forkedSessionId) {
|
|
42524
|
+
db3.prepare("UPDATE discussion_threads SET external_thread_id = ? WHERE id = ?").run(forkedSessionId, threadId);
|
|
42525
|
+
console.log(`[threads] forked to ${forkedSessionId} for thread ${threadId} (session ${sessionId})`);
|
|
42526
|
+
} else {
|
|
42527
|
+
console.warn(`[threads] forkSession returned null for thread ${threadId} (external_thread_id=${session.external_thread_id}, upToMessageId=${anchorTurn.external_turn_id}) \u2014 thread will start a fresh isolated session`);
|
|
42528
|
+
}
|
|
42529
|
+
} else {
|
|
42530
|
+
console.warn(`[threads] anchor turn ${turnId} not found for thread ${threadId} \u2014 cannot fork`);
|
|
42512
42531
|
}
|
|
42513
42532
|
}
|
|
42514
42533
|
} catch (err) {
|
|
@@ -42690,11 +42709,11 @@ async function registerWorkspaceRoutes(fastify) {
|
|
|
42690
42709
|
}
|
|
42691
42710
|
}
|
|
42692
42711
|
}, async (request, reply) => {
|
|
42693
|
-
const { path, label = null } = request.body || {};
|
|
42694
|
-
if (!
|
|
42712
|
+
const { path: path2, label = null } = request.body || {};
|
|
42713
|
+
if (!path2 || !path2.trim()) {
|
|
42695
42714
|
return reply.code(400).send({ error: "Path is required" });
|
|
42696
42715
|
}
|
|
42697
|
-
const trimmedPath =
|
|
42716
|
+
const trimmedPath = path2.trim();
|
|
42698
42717
|
const db3 = getDb();
|
|
42699
42718
|
const existing = db3.prepare("SELECT * FROM workspaces WHERE path = ?").get(trimmedPath);
|
|
42700
42719
|
if (existing) {
|
|
@@ -42722,8 +42741,8 @@ async function registerWorkspaceRoutes(fastify) {
|
|
|
42722
42741
|
"-e",
|
|
42723
42742
|
'POSIX path of (choose folder with prompt "Select a workspace directory")'
|
|
42724
42743
|
]);
|
|
42725
|
-
const
|
|
42726
|
-
return { path };
|
|
42744
|
+
const path2 = stdout.trim().replace(/\/$/, "");
|
|
42745
|
+
return { path: path2 };
|
|
42727
42746
|
} catch {
|
|
42728
42747
|
return reply.code(204).send({ cancelled: true });
|
|
42729
42748
|
}
|
|
@@ -42739,11 +42758,11 @@ async function registerWorkspaceRoutes(fastify) {
|
|
|
42739
42758
|
}
|
|
42740
42759
|
}
|
|
42741
42760
|
}, async (request, reply) => {
|
|
42742
|
-
const { path } = request.body || {};
|
|
42743
|
-
if (!
|
|
42761
|
+
const { path: path2 } = request.body || {};
|
|
42762
|
+
if (!path2 || !path2.trim()) {
|
|
42744
42763
|
return reply.code(400).send({ error: "Path is required" });
|
|
42745
42764
|
}
|
|
42746
|
-
const trimmedPath =
|
|
42765
|
+
const trimmedPath = path2.trim();
|
|
42747
42766
|
const db3 = getDb();
|
|
42748
42767
|
const existing = db3.prepare("SELECT * FROM workspaces WHERE path = ?").get(trimmedPath);
|
|
42749
42768
|
if (existing) {
|
|
@@ -42804,7 +42823,23 @@ var CLAUDE_PROVIDER = {
|
|
|
42804
42823
|
fileReferences: true
|
|
42805
42824
|
}
|
|
42806
42825
|
};
|
|
42807
|
-
var
|
|
42826
|
+
var REPOBURG_PROVIDER = {
|
|
42827
|
+
id: "repoburg",
|
|
42828
|
+
label: "Repoburg",
|
|
42829
|
+
available: true,
|
|
42830
|
+
capabilities: {
|
|
42831
|
+
dynamicModels: true,
|
|
42832
|
+
skills: false,
|
|
42833
|
+
plugins: false,
|
|
42834
|
+
mcpServers: false,
|
|
42835
|
+
imageAttachments: false,
|
|
42836
|
+
sandbox: false,
|
|
42837
|
+
webSearch: false,
|
|
42838
|
+
networkAccess: false,
|
|
42839
|
+
fileReferences: false
|
|
42840
|
+
}
|
|
42841
|
+
};
|
|
42842
|
+
var PROVIDERS = [CODEX_PROVIDER, CLAUDE_PROVIDER, REPOBURG_PROVIDER];
|
|
42808
42843
|
async function registerProviderRoutes(fastify) {
|
|
42809
42844
|
fastify.get("/api/providers", async () => {
|
|
42810
42845
|
return PROVIDERS;
|
|
@@ -72905,9 +72940,9 @@ function mapToolUse(block) {
|
|
|
72905
72940
|
};
|
|
72906
72941
|
}
|
|
72907
72942
|
function deriveFileChangeData(input, toolName) {
|
|
72908
|
-
const
|
|
72943
|
+
const path2 = input.file_path ?? input.notebook_path ?? "";
|
|
72909
72944
|
const kind = toolName === "Write" ? "add" : "modify";
|
|
72910
|
-
return { changes: [{ path, kind }], status: "in_progress" };
|
|
72945
|
+
return { changes: [{ path: path2, kind }], status: "in_progress" };
|
|
72911
72946
|
}
|
|
72912
72947
|
function extractToolResultText(content) {
|
|
72913
72948
|
if (!content) return "";
|
|
@@ -73052,7 +73087,7 @@ function setSessionStatus2(db3, sessionId, isRunning, status, now, hasUnreviewed
|
|
|
73052
73087
|
async function ensureSessionStarted(session, mapKey, resumeSessionId) {
|
|
73053
73088
|
const db3 = getDb();
|
|
73054
73089
|
const key = mapKey ?? session.id;
|
|
73055
|
-
const resumeId = resumeSessionId ?? session.external_thread_id ?? void 0;
|
|
73090
|
+
const resumeId = mapKey !== void 0 ? resumeSessionId : resumeSessionId ?? session.external_thread_id ?? void 0;
|
|
73056
73091
|
const options = {
|
|
73057
73092
|
cwd: session.cwd ?? process.cwd(),
|
|
73058
73093
|
model: session.model ?? void 0,
|
|
@@ -73140,8 +73175,7 @@ async function startTurn2(session, turn) {
|
|
|
73140
73175
|
try {
|
|
73141
73176
|
if (turn.thread_id) {
|
|
73142
73177
|
const thread = db3.prepare("SELECT external_thread_id FROM discussion_threads WHERE id = ?").get(turn.thread_id);
|
|
73143
|
-
|
|
73144
|
-
entry = await ensureSessionStarted(session, mapKey, resumeId);
|
|
73178
|
+
entry = await ensureSessionStarted(session, mapKey, thread?.external_thread_id ?? void 0);
|
|
73145
73179
|
} else {
|
|
73146
73180
|
entry = await ensureSessionStarted(session);
|
|
73147
73181
|
}
|
|
@@ -73154,6 +73188,7 @@ async function startTurn2(session, turn) {
|
|
|
73154
73188
|
return;
|
|
73155
73189
|
}
|
|
73156
73190
|
}
|
|
73191
|
+
entry.threadId = turn.thread_id ?? null;
|
|
73157
73192
|
if (entry.turnId) {
|
|
73158
73193
|
const prevTurn = db3.prepare("SELECT status, token_usage FROM turns WHERE id = ?").get(entry.turnId);
|
|
73159
73194
|
if (prevTurn && prevTurn.status === "running") {
|
|
@@ -73215,12 +73250,14 @@ async function handleMessage(message, sessionId, turnId, entry, db3) {
|
|
|
73215
73250
|
const sub = message.subtype;
|
|
73216
73251
|
if (sub === "init") {
|
|
73217
73252
|
entry.sessionId = message.session_id;
|
|
73218
|
-
|
|
73219
|
-
|
|
73220
|
-
|
|
73221
|
-
|
|
73222
|
-
|
|
73223
|
-
|
|
73253
|
+
if (!entry.threadId) {
|
|
73254
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
73255
|
+
db3.prepare("UPDATE sessions SET external_thread_id = ?, updated_at = ? WHERE id = ?").run(
|
|
73256
|
+
message.session_id,
|
|
73257
|
+
now,
|
|
73258
|
+
sessionId
|
|
73259
|
+
);
|
|
73260
|
+
}
|
|
73224
73261
|
} else if (sub === "compact_boundary") {
|
|
73225
73262
|
handleCompactBoundary(message, sessionId, turnId, db3);
|
|
73226
73263
|
} else if (sub === "task_started") {
|
|
@@ -73250,7 +73287,7 @@ async function handleMessage(message, sessionId, turnId, entry, db3) {
|
|
|
73250
73287
|
break;
|
|
73251
73288
|
}
|
|
73252
73289
|
case "result": {
|
|
73253
|
-
handleResultMessage(message, sessionId, turnId, db3);
|
|
73290
|
+
handleResultMessage(message, sessionId, turnId, entry, db3);
|
|
73254
73291
|
break;
|
|
73255
73292
|
}
|
|
73256
73293
|
default:
|
|
@@ -73500,7 +73537,7 @@ function handleBackgroundTasksChanged(message, sessionId) {
|
|
|
73500
73537
|
const m = message;
|
|
73501
73538
|
broadcast("background_tasks", { sessionId, tasks: m.tasks ?? [] });
|
|
73502
73539
|
}
|
|
73503
|
-
function handleResultMessage(message, sessionId, turnId, db3) {
|
|
73540
|
+
async function handleResultMessage(message, sessionId, turnId, entry, db3) {
|
|
73504
73541
|
const parentToolUseId = message.parent_tool_use_id ?? null;
|
|
73505
73542
|
if (parentToolUseId) return;
|
|
73506
73543
|
if (message.subtype === "success") {
|
|
@@ -73512,30 +73549,23 @@ function handleResultMessage(message, sessionId, turnId, db3) {
|
|
|
73512
73549
|
turnId
|
|
73513
73550
|
);
|
|
73514
73551
|
broadcast("turn:tokenUsage", { sessionId, turnId, usage });
|
|
73515
|
-
|
|
73516
|
-
|
|
73517
|
-
|
|
73518
|
-
const sessionModel = session?.model ?? null;
|
|
73519
|
-
let modelEntry = void 0;
|
|
73520
|
-
if (modelUsage) {
|
|
73521
|
-
if (sessionModel && modelUsage[sessionModel]) {
|
|
73522
|
-
modelEntry = modelUsage[sessionModel];
|
|
73523
|
-
} else {
|
|
73524
|
-
modelEntry = Object.values(modelUsage).find(
|
|
73525
|
-
(e) => sessionModel && e.canonicalModel === sessionModel
|
|
73526
|
-
) ?? Object.values(modelUsage)[0];
|
|
73527
|
-
}
|
|
73528
|
-
}
|
|
73529
|
-
if (modelEntry && modelEntry.contextWindow > 0) {
|
|
73530
|
-
const totalTokens = result.usage.input_tokens + (result.usage.cache_read_input_tokens ?? 0) + (result.usage.cache_creation_input_tokens ?? 0);
|
|
73531
|
-
if (totalTokens > 0) {
|
|
73552
|
+
try {
|
|
73553
|
+
const ctx = await entry.query.getContextUsage();
|
|
73554
|
+
if (ctx.totalTokens > 0 && ctx.maxTokens > 0) {
|
|
73532
73555
|
const contextUsage = {
|
|
73533
|
-
totalTokens,
|
|
73534
|
-
contextWindow:
|
|
73535
|
-
percentage: Math.round(
|
|
73556
|
+
totalTokens: ctx.totalTokens,
|
|
73557
|
+
contextWindow: ctx.maxTokens,
|
|
73558
|
+
percentage: Math.round(ctx.percentage)
|
|
73536
73559
|
};
|
|
73537
73560
|
broadcast("turn:contextUsage", { sessionId, ...contextUsage });
|
|
73561
|
+
const cuNow = (/* @__PURE__ */ new Date()).toISOString();
|
|
73562
|
+
db3.prepare("UPDATE sessions SET context_usage = ?, updated_at = ? WHERE id = ?").run(
|
|
73563
|
+
JSON.stringify(contextUsage),
|
|
73564
|
+
cuNow,
|
|
73565
|
+
sessionId
|
|
73566
|
+
);
|
|
73538
73567
|
}
|
|
73568
|
+
} catch {
|
|
73539
73569
|
}
|
|
73540
73570
|
completeTurn(db3, sessionId, turnId, usage);
|
|
73541
73571
|
} else {
|
|
@@ -73793,15 +73823,1138 @@ var claudeProvider = {
|
|
|
73793
73823
|
shutdown: shutdown2
|
|
73794
73824
|
};
|
|
73795
73825
|
|
|
73826
|
+
// src/repoburg/repoburg-client.ts
|
|
73827
|
+
function defaultRepoburgBaseUrl() {
|
|
73828
|
+
return process.env.REPOBURG_BACKEND_URL || "http://localhost:3000";
|
|
73829
|
+
}
|
|
73830
|
+
function isHtml(text) {
|
|
73831
|
+
return /^\s*<(?:!doctype|html)/i.test(text);
|
|
73832
|
+
}
|
|
73833
|
+
var RepoburgHttpClient = class {
|
|
73834
|
+
baseUrl;
|
|
73835
|
+
constructor(baseUrl = defaultRepoburgBaseUrl()) {
|
|
73836
|
+
this.baseUrl = baseUrl.replace(/\/+$/, "");
|
|
73837
|
+
}
|
|
73838
|
+
/** Perform a JSON request. Throws a concise error on non-OK/non-JSON responses. */
|
|
73839
|
+
async request(method, path2, body) {
|
|
73840
|
+
const response = await fetch(`${this.baseUrl}${path2}`, {
|
|
73841
|
+
method,
|
|
73842
|
+
headers: { "Content-Type": "application/json" },
|
|
73843
|
+
body: body === void 0 ? void 0 : JSON.stringify(body)
|
|
73844
|
+
});
|
|
73845
|
+
const text = await response.text();
|
|
73846
|
+
if (!response.ok) {
|
|
73847
|
+
if (isHtml(text)) {
|
|
73848
|
+
throw new Error(
|
|
73849
|
+
`${method} ${path2} failed: ${response.status} HTML response from ${this.baseUrl} \u2014 the URL points to the wrong server`
|
|
73850
|
+
);
|
|
73851
|
+
}
|
|
73852
|
+
throw new Error(`${method} ${path2} failed: ${response.status} ${text}`);
|
|
73853
|
+
}
|
|
73854
|
+
try {
|
|
73855
|
+
return JSON.parse(text);
|
|
73856
|
+
} catch {
|
|
73857
|
+
throw new Error(
|
|
73858
|
+
`${method} ${path2} failed: non-JSON response from ${this.baseUrl} \u2014 the URL points to the wrong server`
|
|
73859
|
+
);
|
|
73860
|
+
}
|
|
73861
|
+
}
|
|
73862
|
+
async createSession(dto) {
|
|
73863
|
+
return this.request("POST", "/sessions", dto);
|
|
73864
|
+
}
|
|
73865
|
+
async patchSession(id2, dto) {
|
|
73866
|
+
return this.request("PATCH", `/sessions/${id2}`, dto);
|
|
73867
|
+
}
|
|
73868
|
+
async getSession(id2) {
|
|
73869
|
+
return this.request("GET", `/sessions/${id2}`);
|
|
73870
|
+
}
|
|
73871
|
+
async createInput(sessionId, dto) {
|
|
73872
|
+
return this.request("POST", `/sessions/${sessionId}/inputs`, dto);
|
|
73873
|
+
}
|
|
73874
|
+
async getInputWithActions(sessionId, inputId) {
|
|
73875
|
+
return this.request(
|
|
73876
|
+
"GET",
|
|
73877
|
+
`/sessions/${sessionId}/inputs/${inputId}/actions-with-logs`
|
|
73878
|
+
);
|
|
73879
|
+
}
|
|
73880
|
+
async getSessionInputs(sessionId) {
|
|
73881
|
+
return this.request("GET", `/sessions/${sessionId}/inputs`);
|
|
73882
|
+
}
|
|
73883
|
+
async cancel(sessionId) {
|
|
73884
|
+
return this.request(
|
|
73885
|
+
"POST",
|
|
73886
|
+
`/streaming/${sessionId}/cancel`
|
|
73887
|
+
);
|
|
73888
|
+
}
|
|
73889
|
+
async getModels() {
|
|
73890
|
+
const result = await this.request("GET", "/llm-provider/models");
|
|
73891
|
+
return result.models ?? [];
|
|
73892
|
+
}
|
|
73893
|
+
};
|
|
73894
|
+
|
|
73895
|
+
// src/repoburg/backend-resolver.ts
|
|
73896
|
+
import path from "node:path";
|
|
73897
|
+
var HEALTH_POLL_INTERVAL_MS = 1e3;
|
|
73898
|
+
var HEALTH_TIMEOUT_MS = 3e4;
|
|
73899
|
+
function daemonBaseUrl() {
|
|
73900
|
+
return (process.env.REPOBURG_DAEMON_URL || "http://localhost:9998").replace(/\/+$/, "");
|
|
73901
|
+
}
|
|
73902
|
+
var HttpError = class extends Error {
|
|
73903
|
+
constructor(status, body, url) {
|
|
73904
|
+
super(`${url} failed: ${status} ${body}`);
|
|
73905
|
+
this.status = status;
|
|
73906
|
+
this.body = body;
|
|
73907
|
+
this.url = url;
|
|
73908
|
+
}
|
|
73909
|
+
};
|
|
73910
|
+
async function fetchJson(url, init, timeoutMs = 5e3) {
|
|
73911
|
+
const controller = new AbortController();
|
|
73912
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
73913
|
+
let response;
|
|
73914
|
+
try {
|
|
73915
|
+
response = await fetch(url, { ...init, signal: controller.signal });
|
|
73916
|
+
} finally {
|
|
73917
|
+
clearTimeout(timer);
|
|
73918
|
+
}
|
|
73919
|
+
const text = await response.text();
|
|
73920
|
+
if (!response.ok) {
|
|
73921
|
+
throw new HttpError(response.status, text, url);
|
|
73922
|
+
}
|
|
73923
|
+
try {
|
|
73924
|
+
return JSON.parse(text);
|
|
73925
|
+
} catch {
|
|
73926
|
+
throw new Error(`Unexpected non-JSON response from ${url}`);
|
|
73927
|
+
}
|
|
73928
|
+
}
|
|
73929
|
+
function daemonErrorMessage(err) {
|
|
73930
|
+
if (err instanceof HttpError) {
|
|
73931
|
+
try {
|
|
73932
|
+
const parsed = JSON.parse(err.body);
|
|
73933
|
+
return parsed.message || parsed.error || err.body;
|
|
73934
|
+
} catch {
|
|
73935
|
+
return err.body;
|
|
73936
|
+
}
|
|
73937
|
+
}
|
|
73938
|
+
return err.message;
|
|
73939
|
+
}
|
|
73940
|
+
var resolvedCache = /* @__PURE__ */ new Map();
|
|
73941
|
+
function invalidateBackend(baseUrl) {
|
|
73942
|
+
for (const [key, value] of resolvedCache) {
|
|
73943
|
+
if (value.baseUrl === baseUrl) resolvedCache.delete(key);
|
|
73944
|
+
}
|
|
73945
|
+
}
|
|
73946
|
+
async function backendHealthy(baseUrl) {
|
|
73947
|
+
try {
|
|
73948
|
+
await fetchJson(`${baseUrl}/health`, void 0, 2e3);
|
|
73949
|
+
return true;
|
|
73950
|
+
} catch {
|
|
73951
|
+
return false;
|
|
73952
|
+
}
|
|
73953
|
+
}
|
|
73954
|
+
async function waitForHealthy(baseUrl, name) {
|
|
73955
|
+
const deadline = Date.now() + HEALTH_TIMEOUT_MS;
|
|
73956
|
+
while (Date.now() < deadline) {
|
|
73957
|
+
if (await backendHealthy(baseUrl)) return;
|
|
73958
|
+
await new Promise((resolve5) => setTimeout(resolve5, HEALTH_POLL_INTERVAL_MS));
|
|
73959
|
+
}
|
|
73960
|
+
throw new Error(
|
|
73961
|
+
`Backend '${name}' on ${baseUrl} did not become healthy within ${HEALTH_TIMEOUT_MS / 1e3}s. Check daemon logs: repoburg logs ${name}`
|
|
73962
|
+
);
|
|
73963
|
+
}
|
|
73964
|
+
function serviceBaseUrl(service) {
|
|
73965
|
+
return `http://localhost:${service.port}`;
|
|
73966
|
+
}
|
|
73967
|
+
async function restartService(daemon, name) {
|
|
73968
|
+
try {
|
|
73969
|
+
await fetchJson(`${daemon}/services/${name}/restart`, { method: "POST" });
|
|
73970
|
+
} catch (err) {
|
|
73971
|
+
throw new Error(`Daemon failed to restart backend '${name}': ${daemonErrorMessage(err)}`);
|
|
73972
|
+
}
|
|
73973
|
+
}
|
|
73974
|
+
async function startService(daemon, projectPath) {
|
|
73975
|
+
try {
|
|
73976
|
+
return await fetchJson(`${daemon}/services/start`, {
|
|
73977
|
+
method: "POST",
|
|
73978
|
+
headers: { "Content-Type": "application/json" },
|
|
73979
|
+
body: JSON.stringify({ path: projectPath })
|
|
73980
|
+
});
|
|
73981
|
+
} catch (err) {
|
|
73982
|
+
throw new Error(`Daemon failed to start backend for ${projectPath}: ${daemonErrorMessage(err)}`);
|
|
73983
|
+
}
|
|
73984
|
+
}
|
|
73985
|
+
function cache(absPath, service) {
|
|
73986
|
+
const resolved = {
|
|
73987
|
+
baseUrl: serviceBaseUrl(service),
|
|
73988
|
+
port: service.port,
|
|
73989
|
+
name: service.name
|
|
73990
|
+
};
|
|
73991
|
+
resolvedCache.set(absPath, resolved);
|
|
73992
|
+
return resolved;
|
|
73993
|
+
}
|
|
73994
|
+
async function resolveBackendUrl(projectPath, opts = {}) {
|
|
73995
|
+
const autoStart = opts.autoStart !== false;
|
|
73996
|
+
const envUrl = process.env.REPOBURG_BACKEND_URL;
|
|
73997
|
+
if (envUrl) {
|
|
73998
|
+
return { baseUrl: envUrl.replace(/\/+$/, ""), port: 0, name: "REPOBURG_BACKEND_URL" };
|
|
73999
|
+
}
|
|
74000
|
+
const absPath = path.resolve(projectPath);
|
|
74001
|
+
const daemon = daemonBaseUrl();
|
|
74002
|
+
const cached = resolvedCache.get(absPath);
|
|
74003
|
+
if (cached && await backendHealthy(cached.baseUrl)) {
|
|
74004
|
+
return cached;
|
|
74005
|
+
}
|
|
74006
|
+
try {
|
|
74007
|
+
await fetchJson(`${daemon}/health`, void 0, 3e3);
|
|
74008
|
+
} catch {
|
|
74009
|
+
throw new Error(
|
|
74010
|
+
`Repoburg daemon not reachable at ${daemon}. Start it with 'repoburg-daemon', or set REPOBURG_BACKEND_URL to a running backend.`
|
|
74011
|
+
);
|
|
74012
|
+
}
|
|
74013
|
+
const services = await fetchJson(`${daemon}/services`);
|
|
74014
|
+
const match = services.find((s) => s.path === absPath);
|
|
74015
|
+
if (match && match.status === "running") {
|
|
74016
|
+
if (await backendHealthy(serviceBaseUrl(match))) {
|
|
74017
|
+
return cache(absPath, match);
|
|
74018
|
+
}
|
|
74019
|
+
if (!autoStart) return null;
|
|
74020
|
+
await restartService(daemon, match.name);
|
|
74021
|
+
await waitForHealthy(serviceBaseUrl(match), match.name);
|
|
74022
|
+
return cache(absPath, match);
|
|
74023
|
+
}
|
|
74024
|
+
if (!autoStart) return null;
|
|
74025
|
+
if (match) {
|
|
74026
|
+
await restartService(daemon, match.name);
|
|
74027
|
+
await waitForHealthy(serviceBaseUrl(match), match.name);
|
|
74028
|
+
return cache(absPath, match);
|
|
74029
|
+
}
|
|
74030
|
+
const service = await startService(daemon, absPath);
|
|
74031
|
+
await waitForHealthy(serviceBaseUrl(service), service.name);
|
|
74032
|
+
return cache(absPath, service);
|
|
74033
|
+
}
|
|
74034
|
+
|
|
74035
|
+
// src/repoburg/action-mapping.ts
|
|
74036
|
+
function parseJsonArgs(raw) {
|
|
74037
|
+
if (!raw) return null;
|
|
74038
|
+
try {
|
|
74039
|
+
const parsed = JSON.parse(raw);
|
|
74040
|
+
return typeof parsed === "object" && parsed !== null ? parsed : null;
|
|
74041
|
+
} catch {
|
|
74042
|
+
return null;
|
|
74043
|
+
}
|
|
74044
|
+
}
|
|
74045
|
+
function mapActionToItem(action) {
|
|
74046
|
+
const failed = action.status === "EXECUTION_FAILED";
|
|
74047
|
+
const status = failed ? "failed" : "completed";
|
|
74048
|
+
const log = action.executionLogs?.[0];
|
|
74049
|
+
const output = log?.output ?? "";
|
|
74050
|
+
const errorMsg = log?.error_message ?? "";
|
|
74051
|
+
switch (action.action_type) {
|
|
74052
|
+
case "create_file":
|
|
74053
|
+
case "overwrite_file":
|
|
74054
|
+
case "patch":
|
|
74055
|
+
case "quick_edit":
|
|
74056
|
+
case "apply_diff":
|
|
74057
|
+
case "write_todo":
|
|
74058
|
+
case "delete_file": {
|
|
74059
|
+
const kind = action.action_type === "create_file" ? "add" : action.action_type === "delete_file" ? "delete" : "modify";
|
|
74060
|
+
return {
|
|
74061
|
+
type: "file_change",
|
|
74062
|
+
data: { changes: [{ path: action.file_path ?? "", kind }], status },
|
|
74063
|
+
status
|
|
74064
|
+
};
|
|
74065
|
+
}
|
|
74066
|
+
case "run_command":
|
|
74067
|
+
case "execute_code":
|
|
74068
|
+
return {
|
|
74069
|
+
type: "command_execution",
|
|
74070
|
+
data: {
|
|
74071
|
+
command: action.command_string ?? action.action_type,
|
|
74072
|
+
aggregated_output: output,
|
|
74073
|
+
exit_code: failed ? 1 : 0,
|
|
74074
|
+
status
|
|
74075
|
+
},
|
|
74076
|
+
status
|
|
74077
|
+
};
|
|
74078
|
+
case "invoke_subagent": {
|
|
74079
|
+
const args = parseJsonArgs(action.arguments);
|
|
74080
|
+
return {
|
|
74081
|
+
type: "mcp_tool_call",
|
|
74082
|
+
data: {
|
|
74083
|
+
server: null,
|
|
74084
|
+
tool: "Agent",
|
|
74085
|
+
arguments: {
|
|
74086
|
+
description: args?.agent_name ?? args?.agentName ?? "Subagent",
|
|
74087
|
+
prompt: args?.prompt ?? ""
|
|
74088
|
+
},
|
|
74089
|
+
result: output ? [{ type: "text", text: output }] : null,
|
|
74090
|
+
error: failed ? errorMsg || "Sub-agent failed" : null,
|
|
74091
|
+
status
|
|
74092
|
+
},
|
|
74093
|
+
status
|
|
74094
|
+
};
|
|
74095
|
+
}
|
|
74096
|
+
case "web_search": {
|
|
74097
|
+
const args = parseJsonArgs(action.arguments);
|
|
74098
|
+
return { type: "web_search", data: { query: args?.query ?? "" }, status };
|
|
74099
|
+
}
|
|
74100
|
+
case "final":
|
|
74101
|
+
case "html_final":
|
|
74102
|
+
case "ask_user":
|
|
74103
|
+
return null;
|
|
74104
|
+
default: {
|
|
74105
|
+
const isMcp = !!(action.server_name && action.tool_name);
|
|
74106
|
+
return {
|
|
74107
|
+
type: "mcp_tool_call",
|
|
74108
|
+
data: {
|
|
74109
|
+
server: isMcp ? action.server_name : null,
|
|
74110
|
+
tool: isMcp ? action.tool_name : action.action_type,
|
|
74111
|
+
arguments: parseJsonArgs(action.arguments),
|
|
74112
|
+
result: output ? [{ type: "text", text: output }] : null,
|
|
74113
|
+
error: failed ? errorMsg || "Action failed" : null,
|
|
74114
|
+
status
|
|
74115
|
+
},
|
|
74116
|
+
status
|
|
74117
|
+
};
|
|
74118
|
+
}
|
|
74119
|
+
}
|
|
74120
|
+
}
|
|
74121
|
+
function mapUsage2(u) {
|
|
74122
|
+
return {
|
|
74123
|
+
input_tokens: u.input,
|
|
74124
|
+
cached_input_tokens: u.cached,
|
|
74125
|
+
cache_write_input_tokens: 0,
|
|
74126
|
+
output_tokens: u.output,
|
|
74127
|
+
reasoning_output_tokens: 0
|
|
74128
|
+
};
|
|
74129
|
+
}
|
|
74130
|
+
function setSessionStatus3(db3, sessionId, isRunning, status, now, hasUnreviewed = false) {
|
|
74131
|
+
if (hasUnreviewed) {
|
|
74132
|
+
db3.prepare("UPDATE sessions SET is_running = ?, status = ?, has_unreviewed = 1, updated_at = ? WHERE id = ?").run(
|
|
74133
|
+
isRunning,
|
|
74134
|
+
status,
|
|
74135
|
+
now,
|
|
74136
|
+
sessionId
|
|
74137
|
+
);
|
|
74138
|
+
} else {
|
|
74139
|
+
db3.prepare("UPDATE sessions SET is_running = ?, status = ?, updated_at = ? WHERE id = ?").run(
|
|
74140
|
+
isRunning,
|
|
74141
|
+
status,
|
|
74142
|
+
now,
|
|
74143
|
+
sessionId
|
|
74144
|
+
);
|
|
74145
|
+
}
|
|
74146
|
+
}
|
|
74147
|
+
function insertItem(db3, sessionId, turnId, externalId, type, data, status, broadcastEvent) {
|
|
74148
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
74149
|
+
const itemId = v4_default();
|
|
74150
|
+
db3.prepare(
|
|
74151
|
+
"INSERT INTO items (id, turn_id, external_item_id, type, data, status, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"
|
|
74152
|
+
).run(itemId, turnId, externalId, type, JSON.stringify(data), status, now, now);
|
|
74153
|
+
const item = {
|
|
74154
|
+
id: itemId,
|
|
74155
|
+
turn_id: turnId,
|
|
74156
|
+
external_item_id: externalId,
|
|
74157
|
+
type,
|
|
74158
|
+
data,
|
|
74159
|
+
status,
|
|
74160
|
+
created_at: now,
|
|
74161
|
+
updated_at: now
|
|
74162
|
+
};
|
|
74163
|
+
broadcast(broadcastEvent, { sessionId, turnId, item });
|
|
74164
|
+
return item;
|
|
74165
|
+
}
|
|
74166
|
+
function completeItem(db3, sessionId, turnId, item, data, status) {
|
|
74167
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
74168
|
+
db3.prepare("UPDATE items SET data = ?, status = ?, updated_at = ? WHERE id = ?").run(
|
|
74169
|
+
JSON.stringify(data),
|
|
74170
|
+
status,
|
|
74171
|
+
now,
|
|
74172
|
+
item.id
|
|
74173
|
+
);
|
|
74174
|
+
const updated = { ...item, data, status, updated_at: now };
|
|
74175
|
+
broadcast("item:completed", { sessionId, turnId, item: updated });
|
|
74176
|
+
}
|
|
74177
|
+
|
|
74178
|
+
// src/repoburg/turn-projector.ts
|
|
74179
|
+
var RESULT_TIMEOUT_MS = 15 * 6e4;
|
|
74180
|
+
var MAX_RESULT_EXTENSIONS = 3;
|
|
74181
|
+
var TurnProjector = class {
|
|
74182
|
+
constructor(deps) {
|
|
74183
|
+
this.deps = deps;
|
|
74184
|
+
this.armResultWatchdog();
|
|
74185
|
+
}
|
|
74186
|
+
rounds = /* @__PURE__ */ new Map();
|
|
74187
|
+
done = false;
|
|
74188
|
+
resultTimer = null;
|
|
74189
|
+
extensions = 0;
|
|
74190
|
+
get isDone() {
|
|
74191
|
+
return this.done;
|
|
74192
|
+
}
|
|
74193
|
+
/** Main entry — dispatch one agent-runtime message. */
|
|
74194
|
+
handle(message) {
|
|
74195
|
+
if (this.done) return;
|
|
74196
|
+
switch (message.type) {
|
|
74197
|
+
case "system":
|
|
74198
|
+
break;
|
|
74199
|
+
// init — connection marker only
|
|
74200
|
+
case "stream_event":
|
|
74201
|
+
this.handleStreamEvent(message);
|
|
74202
|
+
break;
|
|
74203
|
+
case "assistant":
|
|
74204
|
+
this.handleAssistant(message);
|
|
74205
|
+
break;
|
|
74206
|
+
case "user":
|
|
74207
|
+
this.handleUser(message);
|
|
74208
|
+
break;
|
|
74209
|
+
case "result":
|
|
74210
|
+
this.handleResult(message);
|
|
74211
|
+
break;
|
|
74212
|
+
}
|
|
74213
|
+
}
|
|
74214
|
+
/** Reset the result watchdog (any MESSAGE resets it; heartbeats do not). */
|
|
74215
|
+
touch() {
|
|
74216
|
+
if (this.done) return;
|
|
74217
|
+
this.armResultWatchdog();
|
|
74218
|
+
}
|
|
74219
|
+
/** Stop the projector (turn finalized externally). Clears timers. */
|
|
74220
|
+
close() {
|
|
74221
|
+
this.clearWatchdog();
|
|
74222
|
+
this.done = true;
|
|
74223
|
+
}
|
|
74224
|
+
// -------------------------------------------------------------------------
|
|
74225
|
+
// Message handlers
|
|
74226
|
+
// -------------------------------------------------------------------------
|
|
74227
|
+
round(inputId) {
|
|
74228
|
+
let info = this.rounds.get(inputId);
|
|
74229
|
+
if (!info) {
|
|
74230
|
+
info = {
|
|
74231
|
+
messageItemId: null,
|
|
74232
|
+
reasoningItemId: null,
|
|
74233
|
+
messageExternalId: `${inputId}-text`,
|
|
74234
|
+
reasoningExternalId: `${inputId}-thoughts`,
|
|
74235
|
+
text: "",
|
|
74236
|
+
thoughts: "",
|
|
74237
|
+
finalPlain: null
|
|
74238
|
+
};
|
|
74239
|
+
this.rounds.set(inputId, info);
|
|
74240
|
+
}
|
|
74241
|
+
return info;
|
|
74242
|
+
}
|
|
74243
|
+
handleStreamEvent(msg) {
|
|
74244
|
+
const db3 = getDb();
|
|
74245
|
+
const info = this.round(msg.inputId);
|
|
74246
|
+
const kind = msg.delta.type === "thinking" ? "thoughts" : "text";
|
|
74247
|
+
if (kind === "text") info.text += msg.delta.text;
|
|
74248
|
+
else info.thoughts += msg.delta.text;
|
|
74249
|
+
const externalId = kind === "text" ? info.messageExternalId : info.reasoningExternalId;
|
|
74250
|
+
const type = kind === "text" ? "agent_message" : "reasoning";
|
|
74251
|
+
const itemId = kind === "text" ? info.messageItemId : info.reasoningItemId;
|
|
74252
|
+
if (!itemId) {
|
|
74253
|
+
const item = insertItem(
|
|
74254
|
+
db3,
|
|
74255
|
+
this.deps.agentPaneSessionId,
|
|
74256
|
+
this.deps.turnId,
|
|
74257
|
+
externalId,
|
|
74258
|
+
type,
|
|
74259
|
+
{ text: kind === "text" ? info.text : info.thoughts },
|
|
74260
|
+
"in_progress",
|
|
74261
|
+
"item:started"
|
|
74262
|
+
);
|
|
74263
|
+
if (kind === "text") info.messageItemId = item.id;
|
|
74264
|
+
else info.reasoningItemId = item.id;
|
|
74265
|
+
} else {
|
|
74266
|
+
broadcast("item:delta", {
|
|
74267
|
+
sessionId: this.deps.agentPaneSessionId,
|
|
74268
|
+
turnId: this.deps.turnId,
|
|
74269
|
+
itemId: externalId,
|
|
74270
|
+
delta: msg.delta.text
|
|
74271
|
+
});
|
|
74272
|
+
}
|
|
74273
|
+
this.touch();
|
|
74274
|
+
}
|
|
74275
|
+
handleAssistant(msg) {
|
|
74276
|
+
const info = this.round(msg.inputId);
|
|
74277
|
+
const text = msg.content.filter((b) => b.type === "text").map((b) => b.text).join("");
|
|
74278
|
+
const thinking = msg.content.filter((b) => b.type === "thinking").map((b) => b.thinking).join("");
|
|
74279
|
+
if (text) info.text = text;
|
|
74280
|
+
if (thinking) info.thoughts = thinking;
|
|
74281
|
+
this.upsertCompletedTextItem(info, "message", info.text);
|
|
74282
|
+
this.upsertCompletedTextItem(info, "reasoning", info.thoughts);
|
|
74283
|
+
this.touch();
|
|
74284
|
+
}
|
|
74285
|
+
/** Complete a round's text/thoughts item — creates it when deltas were
|
|
74286
|
+
* off or missed, otherwise completes the streamed in_progress item. */
|
|
74287
|
+
upsertCompletedTextItem(info, kind, text) {
|
|
74288
|
+
if (!text) return;
|
|
74289
|
+
const db3 = getDb();
|
|
74290
|
+
const externalId = kind === "message" ? info.messageExternalId : info.reasoningExternalId;
|
|
74291
|
+
const itemId = kind === "message" ? info.messageItemId : info.reasoningItemId;
|
|
74292
|
+
const type = kind === "message" ? "agent_message" : "reasoning";
|
|
74293
|
+
if (itemId) {
|
|
74294
|
+
const itemRow = db3.prepare("SELECT * FROM items WHERE id = ?").get(itemId);
|
|
74295
|
+
if (itemRow) {
|
|
74296
|
+
completeItem(db3, this.deps.agentPaneSessionId, this.deps.turnId, itemRow, { text }, "completed");
|
|
74297
|
+
return;
|
|
74298
|
+
}
|
|
74299
|
+
}
|
|
74300
|
+
const existing = db3.prepare("SELECT id FROM items WHERE turn_id = ? AND external_item_id = ?").get(this.deps.turnId, externalId);
|
|
74301
|
+
if (existing) return;
|
|
74302
|
+
const item = insertItem(
|
|
74303
|
+
db3,
|
|
74304
|
+
this.deps.agentPaneSessionId,
|
|
74305
|
+
this.deps.turnId,
|
|
74306
|
+
externalId,
|
|
74307
|
+
type,
|
|
74308
|
+
{ text },
|
|
74309
|
+
"completed",
|
|
74310
|
+
"item:completed"
|
|
74311
|
+
);
|
|
74312
|
+
if (kind === "message") info.messageItemId = item.id;
|
|
74313
|
+
else info.reasoningItemId = item.id;
|
|
74314
|
+
}
|
|
74315
|
+
handleUser(msg) {
|
|
74316
|
+
const db3 = getDb();
|
|
74317
|
+
for (const block of msg.content) {
|
|
74318
|
+
const info = this.round(msg.inputId);
|
|
74319
|
+
const action = {
|
|
74320
|
+
...block.action,
|
|
74321
|
+
executionLogs: [
|
|
74322
|
+
{
|
|
74323
|
+
output: block.is_error ? "" : block.content,
|
|
74324
|
+
error_message: block.is_error ? block.content : null
|
|
74325
|
+
}
|
|
74326
|
+
]
|
|
74327
|
+
};
|
|
74328
|
+
if (action.action_type === "final") info.finalPlain = action.plain ?? null;
|
|
74329
|
+
const externalId = `${msg.inputId}-action-${action.id}`;
|
|
74330
|
+
const mapped = mapActionToItem(action);
|
|
74331
|
+
if (!mapped) continue;
|
|
74332
|
+
const existing = db3.prepare("SELECT id FROM items WHERE turn_id = ? AND external_item_id = ?").get(this.deps.turnId, externalId);
|
|
74333
|
+
if (existing) continue;
|
|
74334
|
+
insertItem(
|
|
74335
|
+
db3,
|
|
74336
|
+
this.deps.agentPaneSessionId,
|
|
74337
|
+
this.deps.turnId,
|
|
74338
|
+
externalId,
|
|
74339
|
+
mapped.type,
|
|
74340
|
+
mapped.data,
|
|
74341
|
+
mapped.status,
|
|
74342
|
+
"item:completed"
|
|
74343
|
+
);
|
|
74344
|
+
}
|
|
74345
|
+
this.touch();
|
|
74346
|
+
}
|
|
74347
|
+
handleResult(msg) {
|
|
74348
|
+
switch (msg.subtype) {
|
|
74349
|
+
case "success":
|
|
74350
|
+
this.finishSuccess(msg);
|
|
74351
|
+
break;
|
|
74352
|
+
case "aborted":
|
|
74353
|
+
this.finishAborted();
|
|
74354
|
+
break;
|
|
74355
|
+
case "error_during_execution":
|
|
74356
|
+
default:
|
|
74357
|
+
this.finishFailed((msg.errors ?? []).join("; ") || "Agent turn failed.");
|
|
74358
|
+
break;
|
|
74359
|
+
}
|
|
74360
|
+
}
|
|
74361
|
+
// -------------------------------------------------------------------------
|
|
74362
|
+
// Terminal states
|
|
74363
|
+
// -------------------------------------------------------------------------
|
|
74364
|
+
finishSuccess(msg) {
|
|
74365
|
+
const db3 = getDb();
|
|
74366
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
74367
|
+
const lastRound = [...this.rounds.values()].pop();
|
|
74368
|
+
const responseText = msg.result || lastRound?.text || lastRound?.finalPlain || "";
|
|
74369
|
+
const usage = msg.usage ? mapUsage2({
|
|
74370
|
+
input: msg.usage.input_tokens,
|
|
74371
|
+
cached: msg.usage.cache_read_input_tokens,
|
|
74372
|
+
output: msg.usage.output_tokens
|
|
74373
|
+
}) : null;
|
|
74374
|
+
this.closeOpenItems("completed");
|
|
74375
|
+
db3.prepare(
|
|
74376
|
+
"UPDATE turns SET status = ?, agent_response = ?, token_usage = ?, updated_at = ? WHERE id = ?"
|
|
74377
|
+
).run("completed", responseText || null, usage ? JSON.stringify(usage) : null, now, this.deps.turnId);
|
|
74378
|
+
setSessionStatus3(db3, this.deps.agentPaneSessionId, 0, "active", now, true);
|
|
74379
|
+
broadcast("turn:completed", {
|
|
74380
|
+
sessionId: this.deps.agentPaneSessionId,
|
|
74381
|
+
turnId: this.deps.turnId,
|
|
74382
|
+
...usage ? { usage } : {},
|
|
74383
|
+
hasUnreviewed: true
|
|
74384
|
+
});
|
|
74385
|
+
void this.syncTitle();
|
|
74386
|
+
this.finalize();
|
|
74387
|
+
}
|
|
74388
|
+
/** Fire-and-forget: copy the runtime session title once (new sessions). */
|
|
74389
|
+
async syncTitle() {
|
|
74390
|
+
try {
|
|
74391
|
+
const db3 = getDb();
|
|
74392
|
+
const session = db3.prepare("SELECT title FROM sessions WHERE id = ?").get(
|
|
74393
|
+
this.deps.agentPaneSessionId
|
|
74394
|
+
);
|
|
74395
|
+
if (!session || session.title) return;
|
|
74396
|
+
const runtimeSession = await this.deps.client.getSession(this.deps.repoburgSessionId);
|
|
74397
|
+
const title = (runtimeSession.session_title || "").trim();
|
|
74398
|
+
if (!title) return;
|
|
74399
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
74400
|
+
db3.prepare("UPDATE sessions SET title = ?, updated_at = ? WHERE id = ?").run(
|
|
74401
|
+
title,
|
|
74402
|
+
now,
|
|
74403
|
+
this.deps.agentPaneSessionId
|
|
74404
|
+
);
|
|
74405
|
+
broadcast("session:title", { sessionId: this.deps.agentPaneSessionId, title });
|
|
74406
|
+
} catch {
|
|
74407
|
+
}
|
|
74408
|
+
}
|
|
74409
|
+
finishFailed(error) {
|
|
74410
|
+
const db3 = getDb();
|
|
74411
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
74412
|
+
this.closeOpenItems("failed");
|
|
74413
|
+
db3.prepare("UPDATE turns SET status = ?, error = ?, updated_at = ? WHERE id = ?").run(
|
|
74414
|
+
"failed",
|
|
74415
|
+
error,
|
|
74416
|
+
now,
|
|
74417
|
+
this.deps.turnId
|
|
74418
|
+
);
|
|
74419
|
+
setSessionStatus3(db3, this.deps.agentPaneSessionId, 0, "failed", now);
|
|
74420
|
+
broadcast("turn:failed", {
|
|
74421
|
+
sessionId: this.deps.agentPaneSessionId,
|
|
74422
|
+
turnId: this.deps.turnId,
|
|
74423
|
+
error
|
|
74424
|
+
});
|
|
74425
|
+
this.finalize();
|
|
74426
|
+
}
|
|
74427
|
+
finishAborted() {
|
|
74428
|
+
const db3 = getDb();
|
|
74429
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
74430
|
+
this.closeOpenItems("completed");
|
|
74431
|
+
db3.prepare("UPDATE turns SET status = ?, updated_at = ? WHERE id = ?").run(
|
|
74432
|
+
"aborted",
|
|
74433
|
+
now,
|
|
74434
|
+
this.deps.turnId
|
|
74435
|
+
);
|
|
74436
|
+
setSessionStatus3(db3, this.deps.agentPaneSessionId, 0, "active", now);
|
|
74437
|
+
broadcast("turn:cancelled", {
|
|
74438
|
+
sessionId: this.deps.agentPaneSessionId,
|
|
74439
|
+
turnId: this.deps.turnId
|
|
74440
|
+
});
|
|
74441
|
+
this.finalize();
|
|
74442
|
+
}
|
|
74443
|
+
finalize() {
|
|
74444
|
+
this.clearWatchdog();
|
|
74445
|
+
this.done = true;
|
|
74446
|
+
this.deps.onFinished?.();
|
|
74447
|
+
}
|
|
74448
|
+
/** Close every still in_progress item of this turn with the given status. */
|
|
74449
|
+
closeOpenItems(status) {
|
|
74450
|
+
const db3 = getDb();
|
|
74451
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
74452
|
+
db3.prepare("UPDATE items SET status = ?, updated_at = ? WHERE turn_id = ? AND status = ?").run(
|
|
74453
|
+
status,
|
|
74454
|
+
now,
|
|
74455
|
+
this.deps.turnId,
|
|
74456
|
+
"in_progress"
|
|
74457
|
+
);
|
|
74458
|
+
}
|
|
74459
|
+
// -------------------------------------------------------------------------
|
|
74460
|
+
// Watch-dog + snapshot reconcile
|
|
74461
|
+
// -------------------------------------------------------------------------
|
|
74462
|
+
armResultWatchdog() {
|
|
74463
|
+
if (this.done) return;
|
|
74464
|
+
this.clearWatchdog();
|
|
74465
|
+
this.resultTimer = setTimeout(() => {
|
|
74466
|
+
void this.reconcileFromSnapshot();
|
|
74467
|
+
}, RESULT_TIMEOUT_MS);
|
|
74468
|
+
}
|
|
74469
|
+
clearWatchdog() {
|
|
74470
|
+
if (this.resultTimer) {
|
|
74471
|
+
clearTimeout(this.resultTimer);
|
|
74472
|
+
this.resultTimer = null;
|
|
74473
|
+
}
|
|
74474
|
+
}
|
|
74475
|
+
/** Snapshot reconcile: project missing rounds from the runtime's HTTP
|
|
74476
|
+
* snapshot, then complete the turn when the session stopped running. */
|
|
74477
|
+
async reconcileFromSnapshot() {
|
|
74478
|
+
if (this.done) return;
|
|
74479
|
+
const { client, repoburgSessionId } = this.deps;
|
|
74480
|
+
try {
|
|
74481
|
+
const [inputs, session] = await Promise.all([
|
|
74482
|
+
client.getSessionInputs(repoburgSessionId),
|
|
74483
|
+
client.getSession(repoburgSessionId)
|
|
74484
|
+
]);
|
|
74485
|
+
if (this.done) return;
|
|
74486
|
+
for (const input of inputs) {
|
|
74487
|
+
if (input.role === "model") this.projectSnapshotRound(input);
|
|
74488
|
+
}
|
|
74489
|
+
if (!session.is_running) {
|
|
74490
|
+
const modelInputs = inputs.filter((i) => i.role === "model");
|
|
74491
|
+
const last = modelInputs[modelInputs.length - 1];
|
|
74492
|
+
const lastRound = [...this.rounds.values()].pop();
|
|
74493
|
+
const responseText = lastRound?.text || lastRound?.finalPlain || extractFinalPlain(last) || last?.raw_llm_response || "";
|
|
74494
|
+
const usage = last ? mapUsage2({
|
|
74495
|
+
input: last.input_token_count ?? 0,
|
|
74496
|
+
cached: last.cached_token_count ?? 0,
|
|
74497
|
+
output: last.output_token_count ?? 0
|
|
74498
|
+
}) : null;
|
|
74499
|
+
const db3 = getDb();
|
|
74500
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
74501
|
+
this.closeOpenItems("completed");
|
|
74502
|
+
db3.prepare(
|
|
74503
|
+
"UPDATE turns SET status = ?, agent_response = ?, token_usage = ?, updated_at = ? WHERE id = ?"
|
|
74504
|
+
).run("completed", responseText || null, usage ? JSON.stringify(usage) : null, now, this.deps.turnId);
|
|
74505
|
+
setSessionStatus3(db3, this.deps.agentPaneSessionId, 0, "active", now, true);
|
|
74506
|
+
broadcast("turn:completed", {
|
|
74507
|
+
sessionId: this.deps.agentPaneSessionId,
|
|
74508
|
+
turnId: this.deps.turnId,
|
|
74509
|
+
...usage ? { usage } : {},
|
|
74510
|
+
hasUnreviewed: true
|
|
74511
|
+
});
|
|
74512
|
+
void this.syncTitle();
|
|
74513
|
+
this.finalize();
|
|
74514
|
+
return;
|
|
74515
|
+
}
|
|
74516
|
+
if (this.extensions < MAX_RESULT_EXTENSIONS) {
|
|
74517
|
+
this.extensions += 1;
|
|
74518
|
+
this.armResultWatchdog();
|
|
74519
|
+
} else {
|
|
74520
|
+
this.finishFailed(
|
|
74521
|
+
`No result within ${RESULT_TIMEOUT_MS / 6e4 * (MAX_RESULT_EXTENSIONS + 1)} minutes \u2014 the runtime session is still running. Check repoburg logs.`
|
|
74522
|
+
);
|
|
74523
|
+
}
|
|
74524
|
+
} catch (err) {
|
|
74525
|
+
console.error("[repoburg] snapshot reconcile failed:", err);
|
|
74526
|
+
if (this.extensions < MAX_RESULT_EXTENSIONS) {
|
|
74527
|
+
this.extensions += 1;
|
|
74528
|
+
this.armResultWatchdog();
|
|
74529
|
+
} else {
|
|
74530
|
+
this.finishFailed(`Snapshot reconcile failed: ${err.message}`);
|
|
74531
|
+
}
|
|
74532
|
+
}
|
|
74533
|
+
}
|
|
74534
|
+
/** Project one round from the snapshot (idempotent — live-projected
|
|
74535
|
+
* rounds already exist and are skipped). */
|
|
74536
|
+
projectSnapshotRound(input) {
|
|
74537
|
+
if (!input.raw_llm_response && !input.thoughts && !input.aiActions?.length) return;
|
|
74538
|
+
const info = this.round(input.id);
|
|
74539
|
+
info.text = info.text || (input.raw_llm_response ?? "");
|
|
74540
|
+
info.thoughts = info.thoughts || (input.thoughts ?? "");
|
|
74541
|
+
this.upsertCompletedTextItem(info, "message", info.text);
|
|
74542
|
+
this.upsertCompletedTextItem(info, "reasoning", info.thoughts);
|
|
74543
|
+
const actions = [...input.aiActions ?? []].sort(
|
|
74544
|
+
(a, b) => (a.order_of_execution ?? 0) - (b.order_of_execution ?? 0)
|
|
74545
|
+
);
|
|
74546
|
+
const db3 = getDb();
|
|
74547
|
+
for (const action of actions) {
|
|
74548
|
+
if (action.action_type === "final") info.finalPlain = action.plain ?? null;
|
|
74549
|
+
const mapped = mapActionToItem(action);
|
|
74550
|
+
if (!mapped) continue;
|
|
74551
|
+
const externalId = `${input.id}-action-${action.id}`;
|
|
74552
|
+
const existing = db3.prepare("SELECT id FROM items WHERE turn_id = ? AND external_item_id = ?").get(this.deps.turnId, externalId);
|
|
74553
|
+
if (existing) continue;
|
|
74554
|
+
insertItem(
|
|
74555
|
+
db3,
|
|
74556
|
+
this.deps.agentPaneSessionId,
|
|
74557
|
+
this.deps.turnId,
|
|
74558
|
+
externalId,
|
|
74559
|
+
mapped.type,
|
|
74560
|
+
mapped.data,
|
|
74561
|
+
mapped.status,
|
|
74562
|
+
"item:completed"
|
|
74563
|
+
);
|
|
74564
|
+
}
|
|
74565
|
+
}
|
|
74566
|
+
};
|
|
74567
|
+
function extractFinalPlain(input) {
|
|
74568
|
+
const action = input?.aiActions?.find(
|
|
74569
|
+
(a) => a.action_type === "final" || a.action_type === "html_final"
|
|
74570
|
+
);
|
|
74571
|
+
return action?.plain ?? null;
|
|
74572
|
+
}
|
|
74573
|
+
|
|
74574
|
+
// src/repoburg/agent-runtime-client.ts
|
|
74575
|
+
function parseSseFrame(frame) {
|
|
74576
|
+
const dataLines = [];
|
|
74577
|
+
for (const line of frame.split("\n")) {
|
|
74578
|
+
const trimmed = line.replace(/\r$/, "");
|
|
74579
|
+
if (trimmed.startsWith(":")) continue;
|
|
74580
|
+
if (trimmed.startsWith("data:")) {
|
|
74581
|
+
dataLines.push(trimmed.slice(5).replace(/^ /, ""));
|
|
74582
|
+
}
|
|
74583
|
+
}
|
|
74584
|
+
if (dataLines.length === 0) return null;
|
|
74585
|
+
return dataLines.join("\n");
|
|
74586
|
+
}
|
|
74587
|
+
function createSseParser() {
|
|
74588
|
+
let buffer = "";
|
|
74589
|
+
return (chunk) => {
|
|
74590
|
+
buffer += chunk.replace(/\r\n/g, "\n");
|
|
74591
|
+
const payloads = [];
|
|
74592
|
+
let boundary;
|
|
74593
|
+
while ((boundary = buffer.indexOf("\n\n")) !== -1) {
|
|
74594
|
+
const frame = buffer.slice(0, boundary);
|
|
74595
|
+
buffer = buffer.slice(boundary + 2);
|
|
74596
|
+
const data = parseSseFrame(frame);
|
|
74597
|
+
if (data !== null) payloads.push(data);
|
|
74598
|
+
}
|
|
74599
|
+
return payloads;
|
|
74600
|
+
};
|
|
74601
|
+
}
|
|
74602
|
+
async function streamAgentRuntimeMessages(baseUrl, sessionId, onMessage, opts = {}) {
|
|
74603
|
+
const deltas = opts.deltas !== false;
|
|
74604
|
+
const delayMs = opts.reconnectDelayMs ?? 2e3;
|
|
74605
|
+
const url = `${baseUrl.replace(/\/+$/, "")}/agent-runtime/sessions/${sessionId}/messages?stream=${deltas ? 1 : 0}`;
|
|
74606
|
+
for (; ; ) {
|
|
74607
|
+
if (opts.signal?.aborted) return "aborted";
|
|
74608
|
+
let response;
|
|
74609
|
+
try {
|
|
74610
|
+
response = await fetch(url, { method: "GET", signal: opts.signal });
|
|
74611
|
+
} catch (err) {
|
|
74612
|
+
if (opts.signal?.aborted || err.name === "AbortError") {
|
|
74613
|
+
return "aborted";
|
|
74614
|
+
}
|
|
74615
|
+
await reconnectDelay(delayMs, opts.signal);
|
|
74616
|
+
continue;
|
|
74617
|
+
}
|
|
74618
|
+
if (response.status === 404) return "session-not-found";
|
|
74619
|
+
if (!response.ok || !response.body) {
|
|
74620
|
+
await reconnectDelay(delayMs, opts.signal);
|
|
74621
|
+
continue;
|
|
74622
|
+
}
|
|
74623
|
+
const reason = await readBody(
|
|
74624
|
+
response.body,
|
|
74625
|
+
onMessage,
|
|
74626
|
+
opts
|
|
74627
|
+
);
|
|
74628
|
+
if (reason !== null) {
|
|
74629
|
+
await response.body.cancel().catch(() => {
|
|
74630
|
+
});
|
|
74631
|
+
return reason;
|
|
74632
|
+
}
|
|
74633
|
+
await reconnectDelay(delayMs, opts.signal);
|
|
74634
|
+
}
|
|
74635
|
+
}
|
|
74636
|
+
async function readBody(body, onMessage, opts) {
|
|
74637
|
+
const parse3 = createSseParser();
|
|
74638
|
+
const decoder = new TextDecoder();
|
|
74639
|
+
const reader = body.getReader();
|
|
74640
|
+
try {
|
|
74641
|
+
for (; ; ) {
|
|
74642
|
+
const { done, value } = await reader.read();
|
|
74643
|
+
if (done) return null;
|
|
74644
|
+
opts.onActivity?.();
|
|
74645
|
+
for (const payload of parse3(decoder.decode(value, { stream: true }))) {
|
|
74646
|
+
let message = null;
|
|
74647
|
+
try {
|
|
74648
|
+
message = JSON.parse(payload);
|
|
74649
|
+
} catch {
|
|
74650
|
+
continue;
|
|
74651
|
+
}
|
|
74652
|
+
if (!message || typeof message.type !== "string") continue;
|
|
74653
|
+
onMessage(message);
|
|
74654
|
+
if (message.type === "result") return "result";
|
|
74655
|
+
}
|
|
74656
|
+
}
|
|
74657
|
+
} catch (err) {
|
|
74658
|
+
if (opts.signal?.aborted || err.name === "AbortError") {
|
|
74659
|
+
return "aborted";
|
|
74660
|
+
}
|
|
74661
|
+
return null;
|
|
74662
|
+
} finally {
|
|
74663
|
+
try {
|
|
74664
|
+
reader.releaseLock();
|
|
74665
|
+
} catch {
|
|
74666
|
+
}
|
|
74667
|
+
}
|
|
74668
|
+
}
|
|
74669
|
+
function reconnectDelay(delayMs, signal) {
|
|
74670
|
+
return new Promise((resolve5) => {
|
|
74671
|
+
if (signal?.aborted) return resolve5();
|
|
74672
|
+
const timer = setTimeout(resolve5, delayMs);
|
|
74673
|
+
signal?.addEventListener(
|
|
74674
|
+
"abort",
|
|
74675
|
+
() => {
|
|
74676
|
+
clearTimeout(timer);
|
|
74677
|
+
resolve5();
|
|
74678
|
+
},
|
|
74679
|
+
{ once: true }
|
|
74680
|
+
);
|
|
74681
|
+
});
|
|
74682
|
+
}
|
|
74683
|
+
|
|
74684
|
+
// src/repoburg/repoburg-provider.ts
|
|
74685
|
+
var REASONING_LEVELS = [
|
|
74686
|
+
{ effort: "low", label: "Low" },
|
|
74687
|
+
{ effort: "medium", label: "Medium" },
|
|
74688
|
+
{ effort: "high", label: "High" },
|
|
74689
|
+
{ effort: "xhigh", label: "Extra High" }
|
|
74690
|
+
];
|
|
74691
|
+
var OLLAMA_REASONING_LEVELS = REASONING_LEVELS.filter((l) => l.effort !== "xhigh");
|
|
74692
|
+
function mapReasoningEffort(modelId, effort) {
|
|
74693
|
+
if (!effort) return void 0;
|
|
74694
|
+
if (!["xhigh", "high", "medium", "low", "minimal", "none"].includes(effort)) return void 0;
|
|
74695
|
+
if (modelId?.startsWith("ollama/")) {
|
|
74696
|
+
if (effort === "xhigh") return "high";
|
|
74697
|
+
if (effort === "low" || effort === "medium" || effort === "high") return effort;
|
|
74698
|
+
return void 0;
|
|
74699
|
+
}
|
|
74700
|
+
return effort;
|
|
74701
|
+
}
|
|
74702
|
+
var sessionMap3 = /* @__PURE__ */ new Map();
|
|
74703
|
+
var STALLED_STREAM_MS = 6e4;
|
|
74704
|
+
function isConnectionError(err) {
|
|
74705
|
+
const message = String(err?.message ?? "");
|
|
74706
|
+
return /fetch failed|ECONNREFUSED|ENOTFOUND|ECONNRESET|ETIMEDOUT|EHOSTUNREACH|socket hang up/i.test(
|
|
74707
|
+
message
|
|
74708
|
+
);
|
|
74709
|
+
}
|
|
74710
|
+
async function ensureSession(session, client, baseUrl) {
|
|
74711
|
+
const existing = sessionMap3.get(session.id);
|
|
74712
|
+
if (existing) return existing;
|
|
74713
|
+
if (session.external_thread_id) {
|
|
74714
|
+
const entry2 = {
|
|
74715
|
+
agentPaneSessionId: session.id,
|
|
74716
|
+
repoburgSessionId: session.external_thread_id,
|
|
74717
|
+
client,
|
|
74718
|
+
baseUrl,
|
|
74719
|
+
modelId: session.model ?? null,
|
|
74720
|
+
// undefined forces a re-push on the next turn — heals sessions created
|
|
74721
|
+
// before unsafe effort values (e.g. ollama xhigh) were clamped.
|
|
74722
|
+
reasoningEffort: void 0,
|
|
74723
|
+
activeTurn: null
|
|
74724
|
+
};
|
|
74725
|
+
sessionMap3.set(session.id, entry2);
|
|
74726
|
+
return entry2;
|
|
74727
|
+
}
|
|
74728
|
+
const mappedEffort = mapReasoningEffort(session.model, session.model_reasoning_effort);
|
|
74729
|
+
const created = await client.createSession({
|
|
74730
|
+
session_title: session.title ?? void 0,
|
|
74731
|
+
model_id: session.model ?? void 0,
|
|
74732
|
+
reasoning_effort: mappedEffort
|
|
74733
|
+
});
|
|
74734
|
+
const db3 = getDb();
|
|
74735
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
74736
|
+
db3.prepare("UPDATE sessions SET external_thread_id = ?, updated_at = ? WHERE id = ?").run(
|
|
74737
|
+
created.id,
|
|
74738
|
+
now,
|
|
74739
|
+
session.id
|
|
74740
|
+
);
|
|
74741
|
+
const entry = {
|
|
74742
|
+
agentPaneSessionId: session.id,
|
|
74743
|
+
repoburgSessionId: created.id,
|
|
74744
|
+
client,
|
|
74745
|
+
baseUrl,
|
|
74746
|
+
modelId: session.model ?? null,
|
|
74747
|
+
reasoningEffort: mappedEffort,
|
|
74748
|
+
activeTurn: null
|
|
74749
|
+
};
|
|
74750
|
+
sessionMap3.set(session.id, entry);
|
|
74751
|
+
return entry;
|
|
74752
|
+
}
|
|
74753
|
+
function failTurnBeforeStart(db3, sessionId, turnId, error) {
|
|
74754
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
74755
|
+
db3.prepare("UPDATE turns SET status = ?, error = ?, updated_at = ? WHERE id = ?").run(
|
|
74756
|
+
"failed",
|
|
74757
|
+
error,
|
|
74758
|
+
now,
|
|
74759
|
+
turnId
|
|
74760
|
+
);
|
|
74761
|
+
setSessionStatus3(db3, sessionId, 0, "failed", now);
|
|
74762
|
+
broadcast("turn:failed", { sessionId, turnId, error });
|
|
74763
|
+
}
|
|
74764
|
+
function failTurn(entry, error) {
|
|
74765
|
+
const active = entry.activeTurn;
|
|
74766
|
+
if (!active) return;
|
|
74767
|
+
entry.activeTurn = null;
|
|
74768
|
+
active.projector.close();
|
|
74769
|
+
active.sseAbort.abort();
|
|
74770
|
+
const db3 = getDb();
|
|
74771
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
74772
|
+
db3.prepare("UPDATE turns SET status = ?, error = ?, updated_at = ? WHERE id = ?").run(
|
|
74773
|
+
"failed",
|
|
74774
|
+
error,
|
|
74775
|
+
now,
|
|
74776
|
+
active.turnId
|
|
74777
|
+
);
|
|
74778
|
+
db3.prepare("UPDATE items SET status = ?, updated_at = ? WHERE turn_id = ? AND status = ?").run(
|
|
74779
|
+
"failed",
|
|
74780
|
+
now,
|
|
74781
|
+
active.turnId,
|
|
74782
|
+
"in_progress"
|
|
74783
|
+
);
|
|
74784
|
+
setSessionStatus3(db3, entry.agentPaneSessionId, 0, "failed", now);
|
|
74785
|
+
broadcast("turn:failed", { sessionId: entry.agentPaneSessionId, turnId: active.turnId, error });
|
|
74786
|
+
}
|
|
74787
|
+
async function runStreamLoop(entry, projector) {
|
|
74788
|
+
while (entry.activeTurn?.projector === projector && !projector.isDone) {
|
|
74789
|
+
const active = entry.activeTurn;
|
|
74790
|
+
const controller = new AbortController();
|
|
74791
|
+
active.sseAbort = controller;
|
|
74792
|
+
let stallTimer = null;
|
|
74793
|
+
const resetStall = () => {
|
|
74794
|
+
if (stallTimer) clearTimeout(stallTimer);
|
|
74795
|
+
stallTimer = setTimeout(() => controller.abort(), STALLED_STREAM_MS);
|
|
74796
|
+
};
|
|
74797
|
+
resetStall();
|
|
74798
|
+
const reason = await streamAgentRuntimeMessages(
|
|
74799
|
+
entry.baseUrl,
|
|
74800
|
+
entry.repoburgSessionId,
|
|
74801
|
+
(message) => projector.handle(message),
|
|
74802
|
+
{ signal: controller.signal, onActivity: resetStall }
|
|
74803
|
+
);
|
|
74804
|
+
if (stallTimer) clearTimeout(stallTimer);
|
|
74805
|
+
if (projector.isDone || entry.activeTurn?.projector !== projector) return;
|
|
74806
|
+
if (reason === "session-not-found") {
|
|
74807
|
+
failTurn(entry, "Repoburg session no longer exists on the backend.");
|
|
74808
|
+
return;
|
|
74809
|
+
}
|
|
74810
|
+
if (reason === "aborted") {
|
|
74811
|
+
if (active.cancelled) return;
|
|
74812
|
+
continue;
|
|
74813
|
+
}
|
|
74814
|
+
}
|
|
74815
|
+
}
|
|
74816
|
+
async function startTurn3(session, turn) {
|
|
74817
|
+
const db3 = getDb();
|
|
74818
|
+
let client;
|
|
74819
|
+
let baseUrl;
|
|
74820
|
+
try {
|
|
74821
|
+
const resolved = await resolveBackendUrl(session.cwd ?? process.cwd());
|
|
74822
|
+
if (!resolved) throw new Error("No repoburg backend resolved.");
|
|
74823
|
+
baseUrl = resolved.baseUrl;
|
|
74824
|
+
client = new RepoburgHttpClient(baseUrl);
|
|
74825
|
+
} catch (err) {
|
|
74826
|
+
failTurnBeforeStart(db3, session.id, turn.id, `Failed to resolve repoburg backend: ${err.message}`);
|
|
74827
|
+
return;
|
|
74828
|
+
}
|
|
74829
|
+
let entry;
|
|
74830
|
+
try {
|
|
74831
|
+
entry = await ensureSession(session, client, baseUrl);
|
|
74832
|
+
} catch (err) {
|
|
74833
|
+
if (isConnectionError(err)) invalidateBackend(baseUrl);
|
|
74834
|
+
failTurnBeforeStart(db3, session.id, turn.id, `Failed to create repoburg session: ${err.message}`);
|
|
74835
|
+
return;
|
|
74836
|
+
}
|
|
74837
|
+
const wantedModel = session.model ?? null;
|
|
74838
|
+
const wantedEffort = mapReasoningEffort(session.model, session.model_reasoning_effort);
|
|
74839
|
+
if (wantedModel !== entry.modelId || wantedEffort !== entry.reasoningEffort) {
|
|
74840
|
+
try {
|
|
74841
|
+
await entry.client.patchSession(entry.repoburgSessionId, {
|
|
74842
|
+
model_id: wantedModel ?? void 0,
|
|
74843
|
+
reasoning_effort: wantedEffort
|
|
74844
|
+
});
|
|
74845
|
+
entry.modelId = wantedModel;
|
|
74846
|
+
entry.reasoningEffort = wantedEffort;
|
|
74847
|
+
} catch (err) {
|
|
74848
|
+
console.error(`[repoburg] patchSession failed for ${entry.repoburgSessionId}:`, err);
|
|
74849
|
+
}
|
|
74850
|
+
}
|
|
74851
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
74852
|
+
db3.prepare("UPDATE turns SET status = ?, updated_at = ? WHERE id = ?").run("running", now, turn.id);
|
|
74853
|
+
setSessionStatus3(db3, session.id, 1, "running", now);
|
|
74854
|
+
broadcast("turn:started", { sessionId: session.id, turnId: turn.id });
|
|
74855
|
+
const projector = new TurnProjector({
|
|
74856
|
+
agentPaneSessionId: session.id,
|
|
74857
|
+
turnId: turn.id,
|
|
74858
|
+
repoburgSessionId: entry.repoburgSessionId,
|
|
74859
|
+
client: entry.client
|
|
74860
|
+
});
|
|
74861
|
+
entry.activeTurn = { turnId: turn.id, projector, sseAbort: new AbortController(), cancelled: false };
|
|
74862
|
+
runStreamLoop(entry, projector).catch((err) => {
|
|
74863
|
+
console.error("[repoburg] stream loop crashed:", err);
|
|
74864
|
+
failTurn(entry, `Stream loop failed: ${err.message}`);
|
|
74865
|
+
});
|
|
74866
|
+
try {
|
|
74867
|
+
await entry.client.createInput(entry.repoburgSessionId, {
|
|
74868
|
+
user_prompt: turn.user_prompt,
|
|
74869
|
+
execution_strategy: "auto_apply"
|
|
74870
|
+
});
|
|
74871
|
+
} catch (err) {
|
|
74872
|
+
if (isConnectionError(err)) invalidateBackend(entry.baseUrl);
|
|
74873
|
+
failTurn(entry, err.message);
|
|
74874
|
+
}
|
|
74875
|
+
}
|
|
74876
|
+
async function interruptTurn3(sessionId) {
|
|
74877
|
+
const entry = sessionMap3.get(sessionId);
|
|
74878
|
+
const active = entry?.activeTurn;
|
|
74879
|
+
if (!entry || !active) return false;
|
|
74880
|
+
active.cancelled = true;
|
|
74881
|
+
entry.activeTurn = null;
|
|
74882
|
+
active.projector.close();
|
|
74883
|
+
active.sseAbort.abort();
|
|
74884
|
+
entry.client.cancel(entry.repoburgSessionId).catch((err) => console.error("[repoburg] cancel failed:", err));
|
|
74885
|
+
const db3 = getDb();
|
|
74886
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
74887
|
+
db3.prepare("UPDATE turns SET status = ?, updated_at = ? WHERE id = ?").run("aborted", now, active.turnId);
|
|
74888
|
+
db3.prepare("UPDATE items SET status = ?, updated_at = ? WHERE turn_id = ? AND status = ?").run(
|
|
74889
|
+
"completed",
|
|
74890
|
+
now,
|
|
74891
|
+
active.turnId,
|
|
74892
|
+
"in_progress"
|
|
74893
|
+
);
|
|
74894
|
+
setSessionStatus3(db3, sessionId, 0, "active", now);
|
|
74895
|
+
broadcast("turn:cancelled", { sessionId, turnId: active.turnId });
|
|
74896
|
+
return true;
|
|
74897
|
+
}
|
|
74898
|
+
function clearThread3(sessionId) {
|
|
74899
|
+
const entry = sessionMap3.get(sessionId);
|
|
74900
|
+
if (entry?.activeTurn) {
|
|
74901
|
+
const active = entry.activeTurn;
|
|
74902
|
+
entry.activeTurn = null;
|
|
74903
|
+
active.projector.close();
|
|
74904
|
+
active.sseAbort.abort();
|
|
74905
|
+
}
|
|
74906
|
+
sessionMap3.delete(sessionId);
|
|
74907
|
+
}
|
|
74908
|
+
function clearAllThreads3() {
|
|
74909
|
+
for (const entry of sessionMap3.values()) {
|
|
74910
|
+
if (entry.activeTurn) {
|
|
74911
|
+
const active = entry.activeTurn;
|
|
74912
|
+
entry.activeTurn = null;
|
|
74913
|
+
active.projector.close();
|
|
74914
|
+
active.sseAbort.abort();
|
|
74915
|
+
}
|
|
74916
|
+
}
|
|
74917
|
+
sessionMap3.clear();
|
|
74918
|
+
}
|
|
74919
|
+
async function getModels3() {
|
|
74920
|
+
try {
|
|
74921
|
+
const resolved = await resolveBackendUrl(process.cwd(), { autoStart: false });
|
|
74922
|
+
if (!resolved) return [];
|
|
74923
|
+
const models = await new RepoburgHttpClient(resolved.baseUrl).getModels();
|
|
74924
|
+
return models.map((m) => ({
|
|
74925
|
+
slug: m.id,
|
|
74926
|
+
displayName: m.name,
|
|
74927
|
+
description: "Repoburg backend",
|
|
74928
|
+
defaultReasoning: "medium",
|
|
74929
|
+
// Ollama rejects xhigh/minimal/none as `think` — offer only valid levels.
|
|
74930
|
+
reasoningLevels: m.id.startsWith("ollama/") ? OLLAMA_REASONING_LEVELS : REASONING_LEVELS
|
|
74931
|
+
}));
|
|
74932
|
+
} catch {
|
|
74933
|
+
return [];
|
|
74934
|
+
}
|
|
74935
|
+
}
|
|
74936
|
+
async function shutdown3() {
|
|
74937
|
+
clearAllThreads3();
|
|
74938
|
+
}
|
|
74939
|
+
var repoburgProvider = {
|
|
74940
|
+
startTurn: startTurn3,
|
|
74941
|
+
interruptTurn: interruptTurn3,
|
|
74942
|
+
clearThread: clearThread3,
|
|
74943
|
+
clearAllThreads: clearAllThreads3,
|
|
74944
|
+
getModels: getModels3,
|
|
74945
|
+
shutdown: shutdown3
|
|
74946
|
+
};
|
|
74947
|
+
|
|
73796
74948
|
// src/providers/index.ts
|
|
73797
74949
|
registerProvider("codex", codexProvider);
|
|
73798
74950
|
registerProvider("claude", claudeProvider);
|
|
74951
|
+
registerProvider("repoburg", repoburgProvider);
|
|
73799
74952
|
|
|
73800
74953
|
// src/index.ts
|
|
73801
74954
|
var PORT = 3003;
|
|
73802
74955
|
async function main() {
|
|
73803
74956
|
initDb("data.db");
|
|
73804
|
-
const fastify = (0, import_fastify.default)({ logger: true });
|
|
74957
|
+
const fastify = (0, import_fastify.default)({ logger: true, bodyLimit: 50 * 1024 * 1024 });
|
|
73805
74958
|
await fastify.register(import_cors.default, { origin: true });
|
|
73806
74959
|
await registerSessionRoutes(fastify);
|
|
73807
74960
|
await registerTurnRoutes(fastify);
|