@runfusion/fusion 0.7.0 → 0.7.1
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/dist/bin.js +2058 -1709
- package/dist/client/assets/{AgentDetailView-Du65-jDo.js → AgentDetailView-DyzuiJas.js} +1 -1
- package/dist/client/assets/AgentsView-C2f7esMv.css +1 -0
- package/dist/client/assets/{AgentsView-BkgNEbNs.js → AgentsView-CgweOTe6.js} +46 -46
- package/dist/client/assets/{ChatView-LDte0TdV.js → ChatView-DrY8FMIt.js} +1 -1
- package/dist/client/assets/{DevServerView-AXznq3jv.js → DevServerView-fvjo36sF.js} +1 -1
- package/dist/client/assets/{DirectoryPicker-CSp3G115.js → DirectoryPicker-D5KQ-im_.js} +1 -1
- package/dist/client/assets/{DocumentsView-DOe0E1WQ.js → DocumentsView-D2wK7FYJ.js} +1 -1
- package/dist/client/assets/{InsightsView-DWZbS6z-.js → InsightsView-DfY3sa1j.js} +1 -1
- package/dist/client/assets/{MemoryView-BxnlhBoa.js → MemoryView-CyAQgXwO.js} +1 -1
- package/dist/client/assets/{NodesView-DO9jxhM4.js → NodesView-g26-j7rg.js} +4 -4
- package/dist/client/assets/{PiExtensionsManager-CfXZaWl7.js → PiExtensionsManager-DfMr3Gls.js} +3 -3
- package/dist/client/assets/{PluginManager-r6CWD9u-.js → PluginManager-DiMOD-Kj.js} +1 -1
- package/dist/client/assets/{RoadmapsView-CgAM3YfN.js → RoadmapsView-DJC4F4CD.js} +1 -1
- package/dist/client/assets/SettingsModal-BnekMOV2.css +1 -0
- package/dist/client/assets/{SettingsModal-fmRtzH8z.js → SettingsModal-Cx3iMWDs.js} +1 -1
- package/dist/client/assets/SettingsModal-DjVE27r5.js +31 -0
- package/dist/client/assets/{SetupWizardModal-oRNpImWR.js → SetupWizardModal-Cow6woq6.js} +1 -1
- package/dist/client/assets/{SkillsView-BhwtL-0_.js → SkillsView-DTB2cmXQ.js} +1 -1
- package/dist/client/assets/{TodoView-CmhUBFNV.js → TodoView-CyxdHUdz.js} +1 -1
- package/dist/client/assets/{folder-open-CrTagHrr.js → folder-open-C3zB1vmh.js} +1 -1
- package/dist/client/assets/{index-S9oR77v2.css → index-Belw0PQt.css} +1 -1
- package/dist/client/assets/{index-BTeSa6vk.js → index-DJDWSrju.js} +14 -14
- package/dist/client/assets/{list-checks-DR26h_Io.js → list-checks-CK3_6p5e.js} +1 -1
- package/dist/client/assets/{star-CO_D42zy.js → star-BQhDgM9V.js} +1 -1
- package/dist/client/assets/{upload-BcrgS-iu.js → upload-DDdZveEJ.js} +1 -1
- package/dist/client/assets/{users-4d8al5Sp.js → users-DWWgd19M.js} +1 -1
- package/dist/client/brands/hermes-logo.svg +1 -1
- package/dist/client/index.html +2 -2
- package/dist/client/version.json +1 -1
- package/dist/extension.js +1340 -1126
- package/dist/pi-claude-cli/package.json +1 -1
- package/package.json +7 -6
- package/dist/client/assets/AgentsView-D12CuIFc.css +0 -1
- package/dist/client/assets/SettingsModal-DPDQyWim.css +0 -1
- package/dist/client/assets/SettingsModal-GZdRt8fX.js +0 -31
package/dist/extension.js
CHANGED
|
@@ -114,6 +114,7 @@ var init_settings_schema = __esm({
|
|
|
114
114
|
mergeStrategy: "direct",
|
|
115
115
|
pushAfterMerge: false,
|
|
116
116
|
pushRemote: "origin",
|
|
117
|
+
unavailableNodePolicy: "block",
|
|
117
118
|
worktreeInitCommand: void 0,
|
|
118
119
|
testCommand: void 0,
|
|
119
120
|
buildCommand: void 0,
|
|
@@ -2176,9 +2177,9 @@ var init_sqlite_adapter = __esm({
|
|
|
2176
2177
|
cachedCtor = null;
|
|
2177
2178
|
DatabaseSync = class {
|
|
2178
2179
|
impl;
|
|
2179
|
-
constructor(
|
|
2180
|
+
constructor(path2) {
|
|
2180
2181
|
const Ctor = loadDatabaseCtor();
|
|
2181
|
-
this.impl = new Ctor(
|
|
2182
|
+
this.impl = new Ctor(path2);
|
|
2182
2183
|
}
|
|
2183
2184
|
exec(sql) {
|
|
2184
2185
|
this.impl.exec(sql);
|
|
@@ -2288,7 +2289,7 @@ var init_db = __esm({
|
|
|
2288
2289
|
"use strict";
|
|
2289
2290
|
init_sqlite_adapter();
|
|
2290
2291
|
init_types();
|
|
2291
|
-
SCHEMA_VERSION =
|
|
2292
|
+
SCHEMA_VERSION = 49;
|
|
2292
2293
|
SCHEMA_SQL = `
|
|
2293
2294
|
-- Tasks table with JSON columns for nested data
|
|
2294
2295
|
CREATE TABLE IF NOT EXISTS tasks (
|
|
@@ -3742,6 +3743,11 @@ CREATE INDEX IF NOT EXISTS idxTodoItemsSortOrder ON todo_items(listId, sortOrder
|
|
|
3742
3743
|
this.addColumnIfMissing("tasks", "verificationFailureCount", "INTEGER DEFAULT 0");
|
|
3743
3744
|
});
|
|
3744
3745
|
}
|
|
3746
|
+
if (version < 49) {
|
|
3747
|
+
this.applyMigration(49, () => {
|
|
3748
|
+
this.addColumnIfMissing("tasks", "nodeId", "TEXT");
|
|
3749
|
+
});
|
|
3750
|
+
}
|
|
3745
3751
|
}
|
|
3746
3752
|
/**
|
|
3747
3753
|
* Run a single migration step inside a transaction and bump the version.
|
|
@@ -9658,12 +9664,12 @@ var init_plugin_store = __esm({
|
|
|
9658
9664
|
* Register a new plugin.
|
|
9659
9665
|
*/
|
|
9660
9666
|
async registerPlugin(input) {
|
|
9661
|
-
const { manifest, path, settings = {} } = input;
|
|
9667
|
+
const { manifest, path: path2, settings = {} } = input;
|
|
9662
9668
|
const manifestValidation = validatePluginManifest(manifest);
|
|
9663
9669
|
if (!manifestValidation.valid) {
|
|
9664
9670
|
throw new Error(`Invalid plugin manifest: ${manifestValidation.errors.join(", ")}`);
|
|
9665
9671
|
}
|
|
9666
|
-
if (!
|
|
9672
|
+
if (!path2?.trim()) {
|
|
9667
9673
|
throw new Error("Plugin path is required and cannot be empty");
|
|
9668
9674
|
}
|
|
9669
9675
|
if (!this.validateIdFormat(manifest.id)) {
|
|
@@ -9694,7 +9700,7 @@ var init_plugin_store = __esm({
|
|
|
9694
9700
|
description: manifest.description,
|
|
9695
9701
|
author: manifest.author,
|
|
9696
9702
|
homepage: manifest.homepage,
|
|
9697
|
-
path:
|
|
9703
|
+
path: path2.trim(),
|
|
9698
9704
|
enabled: true,
|
|
9699
9705
|
state: "installed",
|
|
9700
9706
|
settings: mergedSettings,
|
|
@@ -14682,7 +14688,7 @@ var require_multicast_dns = __commonJS({
|
|
|
14682
14688
|
var dgram = __require("dgram");
|
|
14683
14689
|
var thunky = require_thunky();
|
|
14684
14690
|
var events = __require("events");
|
|
14685
|
-
var
|
|
14691
|
+
var os3 = __require("os");
|
|
14686
14692
|
var noop = function() {
|
|
14687
14693
|
};
|
|
14688
14694
|
module.exports = function(opts) {
|
|
@@ -14812,14 +14818,14 @@ var require_multicast_dns = __commonJS({
|
|
|
14812
14818
|
return that;
|
|
14813
14819
|
};
|
|
14814
14820
|
function defaultInterface() {
|
|
14815
|
-
var networks =
|
|
14821
|
+
var networks = os3.networkInterfaces();
|
|
14816
14822
|
var names = Object.keys(networks);
|
|
14817
14823
|
for (var i = 0; i < names.length; i++) {
|
|
14818
14824
|
var net = networks[names[i]];
|
|
14819
14825
|
for (var j = 0; j < net.length; j++) {
|
|
14820
14826
|
var iface = net[j];
|
|
14821
14827
|
if (isIPv4(iface.family) && !iface.internal) {
|
|
14822
|
-
if (
|
|
14828
|
+
if (os3.platform() === "darwin" && names[i] === "en0") return iface.address;
|
|
14823
14829
|
return "0.0.0.0";
|
|
14824
14830
|
}
|
|
14825
14831
|
}
|
|
@@ -14827,7 +14833,7 @@ var require_multicast_dns = __commonJS({
|
|
|
14827
14833
|
return "127.0.0.1";
|
|
14828
14834
|
}
|
|
14829
14835
|
function allInterfaces() {
|
|
14830
|
-
var networks =
|
|
14836
|
+
var networks = os3.networkInterfaces();
|
|
14831
14837
|
var names = Object.keys(networks);
|
|
14832
14838
|
var res = [];
|
|
14833
14839
|
for (var i = 0; i < names.length; i++) {
|
|
@@ -15959,9 +15965,9 @@ var init_central_core = __esm({
|
|
|
15959
15965
|
* @param path — Absolute project path
|
|
15960
15966
|
* @returns The project or undefined if not found
|
|
15961
15967
|
*/
|
|
15962
|
-
async getProjectByPath(
|
|
15968
|
+
async getProjectByPath(path2) {
|
|
15963
15969
|
this.ensureInitialized();
|
|
15964
|
-
const row = this.db.prepare("SELECT * FROM projects WHERE path = ?").get(
|
|
15970
|
+
const row = this.db.prepare("SELECT * FROM projects WHERE path = ?").get(path2);
|
|
15965
15971
|
if (!row) return void 0;
|
|
15966
15972
|
return this.rowToProject(row);
|
|
15967
15973
|
}
|
|
@@ -27886,11 +27892,11 @@ function extractDreamProcessorResult(output) {
|
|
|
27886
27892
|
longTermUpdates: updatesMatch?.[1]?.trim() ?? ""
|
|
27887
27893
|
};
|
|
27888
27894
|
}
|
|
27889
|
-
async function readIfExists(
|
|
27890
|
-
if (!existsSync9(
|
|
27895
|
+
async function readIfExists(path2) {
|
|
27896
|
+
if (!existsSync9(path2)) {
|
|
27891
27897
|
return "";
|
|
27892
27898
|
}
|
|
27893
|
-
return readFile5(
|
|
27899
|
+
return readFile5(path2, "utf-8");
|
|
27894
27900
|
}
|
|
27895
27901
|
async function processMemoryDreams(rootDir, executePrompt, date = /* @__PURE__ */ new Date()) {
|
|
27896
27902
|
await ensureOpenClawMemoryFiles(rootDir, date);
|
|
@@ -28271,20 +28277,20 @@ async function listProjectMemoryFiles(rootDir, date = /* @__PURE__ */ new Date()
|
|
|
28271
28277
|
async function readProjectMemoryFile(rootDir, options) {
|
|
28272
28278
|
return getMemoryFile(rootDir, options, "file");
|
|
28273
28279
|
}
|
|
28274
|
-
async function readProjectMemoryFileContent(rootDir,
|
|
28275
|
-
const { absPath, displayPath } = resolveMemoryFilePath(rootDir,
|
|
28280
|
+
async function readProjectMemoryFileContent(rootDir, path2) {
|
|
28281
|
+
const { absPath, displayPath } = resolveMemoryFilePath(rootDir, path2);
|
|
28276
28282
|
try {
|
|
28277
28283
|
const content = await readFile6(absPath, "utf-8");
|
|
28278
28284
|
return { path: displayPath, content };
|
|
28279
28285
|
} catch (err) {
|
|
28280
28286
|
if (err.code === "ENOENT") {
|
|
28281
|
-
throw new MemoryBackendError("NOT_FOUND", `Memory path '${
|
|
28287
|
+
throw new MemoryBackendError("NOT_FOUND", `Memory path '${path2}' not found`, "file");
|
|
28282
28288
|
}
|
|
28283
|
-
throw new MemoryBackendError("READ_FAILED", `Failed to read memory path '${
|
|
28289
|
+
throw new MemoryBackendError("READ_FAILED", `Failed to read memory path '${path2}': ${err.message}`, "file");
|
|
28284
28290
|
}
|
|
28285
28291
|
}
|
|
28286
|
-
async function writeProjectMemoryFile(rootDir,
|
|
28287
|
-
const { absPath } = resolveMemoryFilePath(rootDir,
|
|
28292
|
+
async function writeProjectMemoryFile(rootDir, path2, content) {
|
|
28293
|
+
const { absPath } = resolveMemoryFilePath(rootDir, path2);
|
|
28288
28294
|
await mkdir6(dirname4(absPath), { recursive: true });
|
|
28289
28295
|
const tmpPath = `${absPath}.tmp`;
|
|
28290
28296
|
await writeFile5(tmpPath, content, "utf-8");
|
|
@@ -28390,20 +28396,20 @@ async function resolveAgentMemoryFilePath(rootDir, agentId, requestedPath) {
|
|
|
28390
28396
|
}
|
|
28391
28397
|
return { absPath, displayPath };
|
|
28392
28398
|
}
|
|
28393
|
-
async function readAgentMemoryFile(rootDir, agentId,
|
|
28394
|
-
const { absPath, displayPath } = await resolveAgentMemoryFilePath(rootDir, agentId,
|
|
28399
|
+
async function readAgentMemoryFile(rootDir, agentId, path2) {
|
|
28400
|
+
const { absPath, displayPath } = await resolveAgentMemoryFilePath(rootDir, agentId, path2);
|
|
28395
28401
|
try {
|
|
28396
28402
|
const content = await readFile6(absPath, "utf-8");
|
|
28397
28403
|
return { path: displayPath, content };
|
|
28398
28404
|
} catch (err) {
|
|
28399
28405
|
if (err.code === "ENOENT") {
|
|
28400
|
-
throw new MemoryBackendError("NOT_FOUND", `Memory path '${
|
|
28406
|
+
throw new MemoryBackendError("NOT_FOUND", `Memory path '${path2}' not found`, "file");
|
|
28401
28407
|
}
|
|
28402
|
-
throw new MemoryBackendError("READ_FAILED", `Failed to read memory path '${
|
|
28408
|
+
throw new MemoryBackendError("READ_FAILED", `Failed to read memory path '${path2}': ${err.message}`, "file");
|
|
28403
28409
|
}
|
|
28404
28410
|
}
|
|
28405
|
-
async function writeAgentMemoryFile(rootDir, agentId,
|
|
28406
|
-
const { absPath } = await resolveAgentMemoryFilePath(rootDir, agentId,
|
|
28411
|
+
async function writeAgentMemoryFile(rootDir, agentId, path2, content) {
|
|
28412
|
+
const { absPath } = await resolveAgentMemoryFilePath(rootDir, agentId, path2);
|
|
28407
28413
|
await mkdir6(dirname4(absPath), { recursive: true });
|
|
28408
28414
|
const tmpPath = `${absPath}.tmp`;
|
|
28409
28415
|
await writeFile5(tmpPath, content, "utf-8");
|
|
@@ -28411,8 +28417,8 @@ async function writeAgentMemoryFile(rootDir, agentId, path, content) {
|
|
|
28411
28417
|
await rename6(tmpPath, absPath);
|
|
28412
28418
|
return { success: true };
|
|
28413
28419
|
}
|
|
28414
|
-
function isPathTraversal(
|
|
28415
|
-
return
|
|
28420
|
+
function isPathTraversal(path2) {
|
|
28421
|
+
return path2.split(/[\\/]+/).includes("..");
|
|
28416
28422
|
}
|
|
28417
28423
|
function normalizeMemoryRequestPath(rawPath) {
|
|
28418
28424
|
const trimmed = rawPath.trim();
|
|
@@ -29467,14 +29473,14 @@ function assertSafeGitBranchName(name) {
|
|
|
29467
29473
|
throw new Error(`Unsafe git branch name: ${JSON.stringify(name)}`);
|
|
29468
29474
|
}
|
|
29469
29475
|
}
|
|
29470
|
-
function assertSafeAbsolutePath(
|
|
29471
|
-
const isAbsolute12 =
|
|
29472
|
-
if (!
|
|
29476
|
+
function assertSafeAbsolutePath(path2) {
|
|
29477
|
+
const isAbsolute12 = path2.startsWith("/") || /^[A-Za-z]:[\\/]/.test(path2);
|
|
29478
|
+
if (!path2 || path2.length > 4096 || !isAbsolute12 || path2.startsWith("-") || // Reject shell metacharacters, quotes, control chars, and NULs.
|
|
29473
29479
|
/["'`$\n\r\t;&|<>()*?[\]{}\\\0]/.test(
|
|
29474
|
-
|
|
29480
|
+
path2.replace(/^[A-Za-z]:/, "")
|
|
29475
29481
|
// ignore the drive-letter colon on Windows
|
|
29476
29482
|
)) {
|
|
29477
|
-
throw new Error(`Unsafe path: ${JSON.stringify(
|
|
29483
|
+
throw new Error(`Unsafe path: ${JSON.stringify(path2)}`);
|
|
29478
29484
|
}
|
|
29479
29485
|
}
|
|
29480
29486
|
function truncateTaskLogOutcome(outcome) {
|
|
@@ -29828,6 +29834,7 @@ var init_store = __esm({
|
|
|
29828
29834
|
sliceId: row.sliceId || void 0,
|
|
29829
29835
|
assignedAgentId: row.assignedAgentId || void 0,
|
|
29830
29836
|
assigneeUserId: row.assigneeUserId || void 0,
|
|
29837
|
+
nodeId: row.nodeId || void 0,
|
|
29831
29838
|
checkedOutBy: row.checkedOutBy || void 0,
|
|
29832
29839
|
checkedOutAt: row.checkedOutAt || void 0
|
|
29833
29840
|
};
|
|
@@ -30075,6 +30082,7 @@ ${recentText}` : void 0
|
|
|
30075
30082
|
"sliceId",
|
|
30076
30083
|
"assignedAgentId",
|
|
30077
30084
|
"assigneeUserId",
|
|
30085
|
+
"nodeId",
|
|
30078
30086
|
"checkedOutBy",
|
|
30079
30087
|
"checkedOutAt",
|
|
30080
30088
|
// `log` is fetched in slim mode so the server can aggregate
|
|
@@ -30174,6 +30182,7 @@ ${outcome}`;
|
|
|
30174
30182
|
"sliceId",
|
|
30175
30183
|
"assignedAgentId",
|
|
30176
30184
|
"assigneeUserId",
|
|
30185
|
+
"nodeId",
|
|
30177
30186
|
"checkedOutBy",
|
|
30178
30187
|
"checkedOutAt"
|
|
30179
30188
|
];
|
|
@@ -30212,9 +30221,9 @@ ${outcome}`;
|
|
|
30212
30221
|
dependencies, steps, log, attachments, steeringComments,
|
|
30213
30222
|
comments, workflowStepResults, prInfo, issueInfo,
|
|
30214
30223
|
sourceIssueProvider, sourceIssueRepository, sourceIssueExternalIssueId, sourceIssueNumber, sourceIssueUrl,
|
|
30215
|
-
mergeDetails, breakIntoSubtasks, enabledWorkflowSteps, modifiedFiles, missionId, sliceId, assignedAgentId, assigneeUserId, checkedOutBy, checkedOutAt
|
|
30224
|
+
mergeDetails, breakIntoSubtasks, enabledWorkflowSteps, modifiedFiles, missionId, sliceId, assignedAgentId, assigneeUserId, nodeId, checkedOutBy, checkedOutAt
|
|
30216
30225
|
) VALUES (
|
|
30217
|
-
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
|
|
30226
|
+
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
|
|
30218
30227
|
)
|
|
30219
30228
|
ON CONFLICT(id) DO UPDATE SET
|
|
30220
30229
|
title = excluded.title,
|
|
@@ -30281,6 +30290,7 @@ ${outcome}`;
|
|
|
30281
30290
|
sliceId = excluded.sliceId,
|
|
30282
30291
|
assignedAgentId = excluded.assignedAgentId,
|
|
30283
30292
|
assigneeUserId = excluded.assigneeUserId,
|
|
30293
|
+
nodeId = excluded.nodeId,
|
|
30284
30294
|
checkedOutBy = excluded.checkedOutBy,
|
|
30285
30295
|
checkedOutAt = excluded.checkedOutAt
|
|
30286
30296
|
`).run(
|
|
@@ -30349,6 +30359,7 @@ ${outcome}`;
|
|
|
30349
30359
|
task.sliceId ?? null,
|
|
30350
30360
|
task.assignedAgentId ?? null,
|
|
30351
30361
|
task.assigneeUserId ?? null,
|
|
30362
|
+
task.nodeId ?? null,
|
|
30352
30363
|
task.checkedOutBy ?? null,
|
|
30353
30364
|
task.checkedOutAt ?? null
|
|
30354
30365
|
);
|
|
@@ -31111,6 +31122,7 @@ ${outcome}`;
|
|
|
31111
31122
|
modelPresetId: input.modelPresetId,
|
|
31112
31123
|
assignedAgentId: input.assignedAgentId,
|
|
31113
31124
|
assigneeUserId: input.assigneeUserId,
|
|
31125
|
+
nodeId: input.nodeId,
|
|
31114
31126
|
modelProvider: input.modelProvider,
|
|
31115
31127
|
modelId: input.modelId,
|
|
31116
31128
|
validatorModelProvider: input.validatorModelProvider,
|
|
@@ -31602,6 +31614,11 @@ ${newTask.description}
|
|
|
31602
31614
|
} else if (updates.assigneeUserId !== void 0) {
|
|
31603
31615
|
task.assigneeUserId = updates.assigneeUserId;
|
|
31604
31616
|
}
|
|
31617
|
+
if (updates.nodeId === null) {
|
|
31618
|
+
task.nodeId = void 0;
|
|
31619
|
+
} else if (updates.nodeId !== void 0) {
|
|
31620
|
+
task.nodeId = updates.nodeId;
|
|
31621
|
+
}
|
|
31605
31622
|
if (updates.checkedOutBy === null) {
|
|
31606
31623
|
task.checkedOutBy = void 0;
|
|
31607
31624
|
task.checkedOutAt = void 0;
|
|
@@ -34594,6 +34611,24 @@ var init_gh_cli = __esm({
|
|
|
34594
34611
|
}
|
|
34595
34612
|
});
|
|
34596
34613
|
|
|
34614
|
+
// ../core/src/settings-validation.ts
|
|
34615
|
+
function validateUnavailableNodePolicy(value) {
|
|
34616
|
+
if (value === void 0) {
|
|
34617
|
+
return void 0;
|
|
34618
|
+
}
|
|
34619
|
+
if (typeof value !== "string") {
|
|
34620
|
+
return void 0;
|
|
34621
|
+
}
|
|
34622
|
+
return UNAVAILABLE_NODE_POLICIES.includes(value) ? value : void 0;
|
|
34623
|
+
}
|
|
34624
|
+
var UNAVAILABLE_NODE_POLICIES;
|
|
34625
|
+
var init_settings_validation = __esm({
|
|
34626
|
+
"../core/src/settings-validation.ts"() {
|
|
34627
|
+
"use strict";
|
|
34628
|
+
UNAVAILABLE_NODE_POLICIES = ["block", "fallback-local"];
|
|
34629
|
+
}
|
|
34630
|
+
});
|
|
34631
|
+
|
|
34597
34632
|
// ../core/src/routine.ts
|
|
34598
34633
|
function isCronTrigger(trigger) {
|
|
34599
34634
|
return trigger.type === "cron";
|
|
@@ -35175,27 +35210,27 @@ var init_plugin_loader = __esm({
|
|
|
35175
35210
|
throw err;
|
|
35176
35211
|
}
|
|
35177
35212
|
}
|
|
35178
|
-
resolvePluginPath(
|
|
35179
|
-
if (isAbsolute5(
|
|
35180
|
-
return
|
|
35213
|
+
resolvePluginPath(path2) {
|
|
35214
|
+
if (isAbsolute5(path2)) {
|
|
35215
|
+
return path2;
|
|
35181
35216
|
}
|
|
35182
|
-
if (
|
|
35183
|
-
return resolve7(this.getProjectRoot(),
|
|
35217
|
+
if (path2.startsWith("@") || path2.includes("/")) {
|
|
35218
|
+
return resolve7(this.getProjectRoot(), path2);
|
|
35184
35219
|
}
|
|
35185
|
-
return resolve7(this.getProjectRoot(),
|
|
35220
|
+
return resolve7(this.getProjectRoot(), path2);
|
|
35186
35221
|
}
|
|
35187
|
-
async importPluginModule(
|
|
35188
|
-
if (!bypassCache && this.loadedModules.has(
|
|
35189
|
-
return this.loadedModules.get(
|
|
35222
|
+
async importPluginModule(path2, bypassCache = false) {
|
|
35223
|
+
if (!bypassCache && this.loadedModules.has(path2)) {
|
|
35224
|
+
return this.loadedModules.get(path2);
|
|
35190
35225
|
}
|
|
35191
|
-
const moduleUrl = pathToFileURL(
|
|
35226
|
+
const moduleUrl = pathToFileURL(path2).href;
|
|
35192
35227
|
let mod;
|
|
35193
35228
|
if (bypassCache) {
|
|
35194
35229
|
moduleImportVersion += 1;
|
|
35195
|
-
const ext = extname(
|
|
35196
|
-
const baseName = basename6(
|
|
35197
|
-
const reloadedPath = resolve7(dirname5(
|
|
35198
|
-
await copyFile(
|
|
35230
|
+
const ext = extname(path2);
|
|
35231
|
+
const baseName = basename6(path2, ext);
|
|
35232
|
+
const reloadedPath = resolve7(dirname5(path2), `.${baseName}.reload-${moduleImportVersion}${ext}`);
|
|
35233
|
+
await copyFile(path2, reloadedPath);
|
|
35199
35234
|
try {
|
|
35200
35235
|
mod = await import(pathToFileURL(reloadedPath).href);
|
|
35201
35236
|
} finally {
|
|
@@ -35204,16 +35239,16 @@ var init_plugin_loader = __esm({
|
|
|
35204
35239
|
} else {
|
|
35205
35240
|
mod = await import(moduleUrl);
|
|
35206
35241
|
}
|
|
35207
|
-
this.loadedModules.set(
|
|
35242
|
+
this.loadedModules.set(path2, mod);
|
|
35208
35243
|
return mod;
|
|
35209
35244
|
}
|
|
35210
35245
|
/**
|
|
35211
35246
|
* Invalidate the module cache for a plugin path.
|
|
35212
35247
|
* This ensures a fresh import when the plugin is loaded again.
|
|
35213
35248
|
*/
|
|
35214
|
-
invalidateModuleCache(
|
|
35215
|
-
this.loadedModules.delete(
|
|
35216
|
-
log.log(`Module cache invalidated for: ${
|
|
35249
|
+
invalidateModuleCache(path2) {
|
|
35250
|
+
this.loadedModules.delete(path2);
|
|
35251
|
+
log.log(`Module cache invalidated for: ${path2}`);
|
|
35217
35252
|
}
|
|
35218
35253
|
/**
|
|
35219
35254
|
* Reload a plugin: stop the old instance, re-import, and start the new one.
|
|
@@ -37927,7 +37962,7 @@ var require_has_flag = __commonJS({
|
|
|
37927
37962
|
var require_supports_color = __commonJS({
|
|
37928
37963
|
"../../node_modules/.pnpm/supports-color@7.2.0/node_modules/supports-color/index.js"(exports, module) {
|
|
37929
37964
|
"use strict";
|
|
37930
|
-
var
|
|
37965
|
+
var os3 = __require("os");
|
|
37931
37966
|
var tty = __require("tty");
|
|
37932
37967
|
var hasFlag = require_has_flag();
|
|
37933
37968
|
var { env } = process;
|
|
@@ -37975,7 +38010,7 @@ var require_supports_color = __commonJS({
|
|
|
37975
38010
|
return min;
|
|
37976
38011
|
}
|
|
37977
38012
|
if (process.platform === "win32") {
|
|
37978
|
-
const osRelease =
|
|
38013
|
+
const osRelease = os3.release().split(".");
|
|
37979
38014
|
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
37980
38015
|
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
37981
38016
|
}
|
|
@@ -39192,7 +39227,7 @@ var require_yauzl = __commonJS({
|
|
|
39192
39227
|
exports.ZipFile = ZipFile;
|
|
39193
39228
|
exports.Entry = Entry;
|
|
39194
39229
|
exports.RandomAccessReader = RandomAccessReader;
|
|
39195
|
-
function open(
|
|
39230
|
+
function open(path2, options, callback) {
|
|
39196
39231
|
if (typeof options === "function") {
|
|
39197
39232
|
callback = options;
|
|
39198
39233
|
options = null;
|
|
@@ -39204,7 +39239,7 @@ var require_yauzl = __commonJS({
|
|
|
39204
39239
|
if (options.validateEntrySizes == null) options.validateEntrySizes = true;
|
|
39205
39240
|
if (options.strictFileNames == null) options.strictFileNames = false;
|
|
39206
39241
|
if (callback == null) callback = defaultCallback;
|
|
39207
|
-
fs.open(
|
|
39242
|
+
fs.open(path2, "r", function(err, fd) {
|
|
39208
39243
|
if (err) return callback(err);
|
|
39209
39244
|
fromFd(fd, options, function(err2, zipfile) {
|
|
39210
39245
|
if (err2) fs.close(fd, defaultCallback);
|
|
@@ -39807,7 +39842,7 @@ var require_extract_zip = __commonJS({
|
|
|
39807
39842
|
var debug = require_src()("extract-zip");
|
|
39808
39843
|
var { createWriteStream, promises: fs } = __require("fs");
|
|
39809
39844
|
var getStream = require_get_stream();
|
|
39810
|
-
var
|
|
39845
|
+
var path2 = __require("path");
|
|
39811
39846
|
var { promisify: promisify13 } = __require("util");
|
|
39812
39847
|
var stream = __require("stream");
|
|
39813
39848
|
var yauzl = require_yauzl();
|
|
@@ -39844,12 +39879,12 @@ var require_extract_zip = __commonJS({
|
|
|
39844
39879
|
this.zipfile.readEntry();
|
|
39845
39880
|
return;
|
|
39846
39881
|
}
|
|
39847
|
-
const destDir =
|
|
39882
|
+
const destDir = path2.dirname(path2.join(this.opts.dir, entry.fileName));
|
|
39848
39883
|
try {
|
|
39849
39884
|
await fs.mkdir(destDir, { recursive: true });
|
|
39850
39885
|
const canonicalDestDir = await fs.realpath(destDir);
|
|
39851
|
-
const relativeDestDir =
|
|
39852
|
-
if (relativeDestDir.split(
|
|
39886
|
+
const relativeDestDir = path2.relative(this.opts.dir, canonicalDestDir);
|
|
39887
|
+
if (relativeDestDir.split(path2.sep).includes("..")) {
|
|
39853
39888
|
throw new Error(`Out of bound path "${canonicalDestDir}" found while processing file ${entry.fileName}`);
|
|
39854
39889
|
}
|
|
39855
39890
|
await this.extractEntry(entry);
|
|
@@ -39871,7 +39906,7 @@ var require_extract_zip = __commonJS({
|
|
|
39871
39906
|
if (this.opts.onEntry) {
|
|
39872
39907
|
this.opts.onEntry(entry, this.zipfile);
|
|
39873
39908
|
}
|
|
39874
|
-
const dest =
|
|
39909
|
+
const dest = path2.join(this.opts.dir, entry.fileName);
|
|
39875
39910
|
const mode = entry.externalFileAttributes >> 16 & 65535;
|
|
39876
39911
|
const IFMT = 61440;
|
|
39877
39912
|
const IFDIR = 16384;
|
|
@@ -39885,7 +39920,7 @@ var require_extract_zip = __commonJS({
|
|
|
39885
39920
|
if (!isDir) isDir = madeBy === 0 && entry.externalFileAttributes === 16;
|
|
39886
39921
|
debug("extracting entry", { filename: entry.fileName, isDir, isSymlink: symlink });
|
|
39887
39922
|
const procMode = this.getExtractedMode(mode, isDir) & 511;
|
|
39888
|
-
const destDir = isDir ? dest :
|
|
39923
|
+
const destDir = isDir ? dest : path2.dirname(dest);
|
|
39889
39924
|
const mkdirOptions = { recursive: true };
|
|
39890
39925
|
if (isDir) {
|
|
39891
39926
|
mkdirOptions.mode = procMode;
|
|
@@ -39927,7 +39962,7 @@ var require_extract_zip = __commonJS({
|
|
|
39927
39962
|
};
|
|
39928
39963
|
module.exports = async function(zipPath, opts) {
|
|
39929
39964
|
debug("creating target directory", opts.dir);
|
|
39930
|
-
if (!
|
|
39965
|
+
if (!path2.isAbsolute(opts.dir)) {
|
|
39931
39966
|
throw new Error("Target directory is expected to be absolute");
|
|
39932
39967
|
}
|
|
39933
39968
|
await fs.mkdir(opts.dir, { recursive: true });
|
|
@@ -40014,17 +40049,17 @@ var require_visit = __commonJS({
|
|
|
40014
40049
|
visit.BREAK = BREAK;
|
|
40015
40050
|
visit.SKIP = SKIP;
|
|
40016
40051
|
visit.REMOVE = REMOVE;
|
|
40017
|
-
function visit_(key, node, visitor,
|
|
40018
|
-
const ctrl = callVisitor(key, node, visitor,
|
|
40052
|
+
function visit_(key, node, visitor, path2) {
|
|
40053
|
+
const ctrl = callVisitor(key, node, visitor, path2);
|
|
40019
40054
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
40020
|
-
replaceNode(key,
|
|
40021
|
-
return visit_(key, ctrl, visitor,
|
|
40055
|
+
replaceNode(key, path2, ctrl);
|
|
40056
|
+
return visit_(key, ctrl, visitor, path2);
|
|
40022
40057
|
}
|
|
40023
40058
|
if (typeof ctrl !== "symbol") {
|
|
40024
40059
|
if (identity.isCollection(node)) {
|
|
40025
|
-
|
|
40060
|
+
path2 = Object.freeze(path2.concat(node));
|
|
40026
40061
|
for (let i = 0; i < node.items.length; ++i) {
|
|
40027
|
-
const ci = visit_(i, node.items[i], visitor,
|
|
40062
|
+
const ci = visit_(i, node.items[i], visitor, path2);
|
|
40028
40063
|
if (typeof ci === "number")
|
|
40029
40064
|
i = ci - 1;
|
|
40030
40065
|
else if (ci === BREAK)
|
|
@@ -40035,13 +40070,13 @@ var require_visit = __commonJS({
|
|
|
40035
40070
|
}
|
|
40036
40071
|
}
|
|
40037
40072
|
} else if (identity.isPair(node)) {
|
|
40038
|
-
|
|
40039
|
-
const ck = visit_("key", node.key, visitor,
|
|
40073
|
+
path2 = Object.freeze(path2.concat(node));
|
|
40074
|
+
const ck = visit_("key", node.key, visitor, path2);
|
|
40040
40075
|
if (ck === BREAK)
|
|
40041
40076
|
return BREAK;
|
|
40042
40077
|
else if (ck === REMOVE)
|
|
40043
40078
|
node.key = null;
|
|
40044
|
-
const cv = visit_("value", node.value, visitor,
|
|
40079
|
+
const cv = visit_("value", node.value, visitor, path2);
|
|
40045
40080
|
if (cv === BREAK)
|
|
40046
40081
|
return BREAK;
|
|
40047
40082
|
else if (cv === REMOVE)
|
|
@@ -40062,17 +40097,17 @@ var require_visit = __commonJS({
|
|
|
40062
40097
|
visitAsync.BREAK = BREAK;
|
|
40063
40098
|
visitAsync.SKIP = SKIP;
|
|
40064
40099
|
visitAsync.REMOVE = REMOVE;
|
|
40065
|
-
async function visitAsync_(key, node, visitor,
|
|
40066
|
-
const ctrl = await callVisitor(key, node, visitor,
|
|
40100
|
+
async function visitAsync_(key, node, visitor, path2) {
|
|
40101
|
+
const ctrl = await callVisitor(key, node, visitor, path2);
|
|
40067
40102
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
40068
|
-
replaceNode(key,
|
|
40069
|
-
return visitAsync_(key, ctrl, visitor,
|
|
40103
|
+
replaceNode(key, path2, ctrl);
|
|
40104
|
+
return visitAsync_(key, ctrl, visitor, path2);
|
|
40070
40105
|
}
|
|
40071
40106
|
if (typeof ctrl !== "symbol") {
|
|
40072
40107
|
if (identity.isCollection(node)) {
|
|
40073
|
-
|
|
40108
|
+
path2 = Object.freeze(path2.concat(node));
|
|
40074
40109
|
for (let i = 0; i < node.items.length; ++i) {
|
|
40075
|
-
const ci = await visitAsync_(i, node.items[i], visitor,
|
|
40110
|
+
const ci = await visitAsync_(i, node.items[i], visitor, path2);
|
|
40076
40111
|
if (typeof ci === "number")
|
|
40077
40112
|
i = ci - 1;
|
|
40078
40113
|
else if (ci === BREAK)
|
|
@@ -40083,13 +40118,13 @@ var require_visit = __commonJS({
|
|
|
40083
40118
|
}
|
|
40084
40119
|
}
|
|
40085
40120
|
} else if (identity.isPair(node)) {
|
|
40086
|
-
|
|
40087
|
-
const ck = await visitAsync_("key", node.key, visitor,
|
|
40121
|
+
path2 = Object.freeze(path2.concat(node));
|
|
40122
|
+
const ck = await visitAsync_("key", node.key, visitor, path2);
|
|
40088
40123
|
if (ck === BREAK)
|
|
40089
40124
|
return BREAK;
|
|
40090
40125
|
else if (ck === REMOVE)
|
|
40091
40126
|
node.key = null;
|
|
40092
|
-
const cv = await visitAsync_("value", node.value, visitor,
|
|
40127
|
+
const cv = await visitAsync_("value", node.value, visitor, path2);
|
|
40093
40128
|
if (cv === BREAK)
|
|
40094
40129
|
return BREAK;
|
|
40095
40130
|
else if (cv === REMOVE)
|
|
@@ -40116,23 +40151,23 @@ var require_visit = __commonJS({
|
|
|
40116
40151
|
}
|
|
40117
40152
|
return visitor;
|
|
40118
40153
|
}
|
|
40119
|
-
function callVisitor(key, node, visitor,
|
|
40154
|
+
function callVisitor(key, node, visitor, path2) {
|
|
40120
40155
|
if (typeof visitor === "function")
|
|
40121
|
-
return visitor(key, node,
|
|
40156
|
+
return visitor(key, node, path2);
|
|
40122
40157
|
if (identity.isMap(node))
|
|
40123
|
-
return visitor.Map?.(key, node,
|
|
40158
|
+
return visitor.Map?.(key, node, path2);
|
|
40124
40159
|
if (identity.isSeq(node))
|
|
40125
|
-
return visitor.Seq?.(key, node,
|
|
40160
|
+
return visitor.Seq?.(key, node, path2);
|
|
40126
40161
|
if (identity.isPair(node))
|
|
40127
|
-
return visitor.Pair?.(key, node,
|
|
40162
|
+
return visitor.Pair?.(key, node, path2);
|
|
40128
40163
|
if (identity.isScalar(node))
|
|
40129
|
-
return visitor.Scalar?.(key, node,
|
|
40164
|
+
return visitor.Scalar?.(key, node, path2);
|
|
40130
40165
|
if (identity.isAlias(node))
|
|
40131
|
-
return visitor.Alias?.(key, node,
|
|
40166
|
+
return visitor.Alias?.(key, node, path2);
|
|
40132
40167
|
return void 0;
|
|
40133
40168
|
}
|
|
40134
|
-
function replaceNode(key,
|
|
40135
|
-
const parent =
|
|
40169
|
+
function replaceNode(key, path2, node) {
|
|
40170
|
+
const parent = path2[path2.length - 1];
|
|
40136
40171
|
if (identity.isCollection(parent)) {
|
|
40137
40172
|
parent.items[key] = node;
|
|
40138
40173
|
} else if (identity.isPair(parent)) {
|
|
@@ -40740,10 +40775,10 @@ var require_Collection = __commonJS({
|
|
|
40740
40775
|
var createNode = require_createNode();
|
|
40741
40776
|
var identity = require_identity();
|
|
40742
40777
|
var Node = require_Node();
|
|
40743
|
-
function collectionFromPath(schema,
|
|
40778
|
+
function collectionFromPath(schema, path2, value) {
|
|
40744
40779
|
let v = value;
|
|
40745
|
-
for (let i =
|
|
40746
|
-
const k =
|
|
40780
|
+
for (let i = path2.length - 1; i >= 0; --i) {
|
|
40781
|
+
const k = path2[i];
|
|
40747
40782
|
if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
|
|
40748
40783
|
const a = [];
|
|
40749
40784
|
a[k] = v;
|
|
@@ -40762,7 +40797,7 @@ var require_Collection = __commonJS({
|
|
|
40762
40797
|
sourceObjects: /* @__PURE__ */ new Map()
|
|
40763
40798
|
});
|
|
40764
40799
|
}
|
|
40765
|
-
var isEmptyPath = (
|
|
40800
|
+
var isEmptyPath = (path2) => path2 == null || typeof path2 === "object" && !!path2[Symbol.iterator]().next().done;
|
|
40766
40801
|
var Collection = class extends Node.NodeBase {
|
|
40767
40802
|
constructor(type, schema) {
|
|
40768
40803
|
super(type);
|
|
@@ -40792,11 +40827,11 @@ var require_Collection = __commonJS({
|
|
|
40792
40827
|
* be a Pair instance or a `{ key, value }` object, which may not have a key
|
|
40793
40828
|
* that already exists in the map.
|
|
40794
40829
|
*/
|
|
40795
|
-
addIn(
|
|
40796
|
-
if (isEmptyPath(
|
|
40830
|
+
addIn(path2, value) {
|
|
40831
|
+
if (isEmptyPath(path2))
|
|
40797
40832
|
this.add(value);
|
|
40798
40833
|
else {
|
|
40799
|
-
const [key, ...rest] =
|
|
40834
|
+
const [key, ...rest] = path2;
|
|
40800
40835
|
const node = this.get(key, true);
|
|
40801
40836
|
if (identity.isCollection(node))
|
|
40802
40837
|
node.addIn(rest, value);
|
|
@@ -40810,8 +40845,8 @@ var require_Collection = __commonJS({
|
|
|
40810
40845
|
* Removes a value from the collection.
|
|
40811
40846
|
* @returns `true` if the item was found and removed.
|
|
40812
40847
|
*/
|
|
40813
|
-
deleteIn(
|
|
40814
|
-
const [key, ...rest] =
|
|
40848
|
+
deleteIn(path2) {
|
|
40849
|
+
const [key, ...rest] = path2;
|
|
40815
40850
|
if (rest.length === 0)
|
|
40816
40851
|
return this.delete(key);
|
|
40817
40852
|
const node = this.get(key, true);
|
|
@@ -40825,8 +40860,8 @@ var require_Collection = __commonJS({
|
|
|
40825
40860
|
* scalar values from their surrounding node; to disable set `keepScalar` to
|
|
40826
40861
|
* `true` (collections are always returned intact).
|
|
40827
40862
|
*/
|
|
40828
|
-
getIn(
|
|
40829
|
-
const [key, ...rest] =
|
|
40863
|
+
getIn(path2, keepScalar) {
|
|
40864
|
+
const [key, ...rest] = path2;
|
|
40830
40865
|
const node = this.get(key, true);
|
|
40831
40866
|
if (rest.length === 0)
|
|
40832
40867
|
return !keepScalar && identity.isScalar(node) ? node.value : node;
|
|
@@ -40844,8 +40879,8 @@ var require_Collection = __commonJS({
|
|
|
40844
40879
|
/**
|
|
40845
40880
|
* Checks if the collection includes a value with the key `key`.
|
|
40846
40881
|
*/
|
|
40847
|
-
hasIn(
|
|
40848
|
-
const [key, ...rest] =
|
|
40882
|
+
hasIn(path2) {
|
|
40883
|
+
const [key, ...rest] = path2;
|
|
40849
40884
|
if (rest.length === 0)
|
|
40850
40885
|
return this.has(key);
|
|
40851
40886
|
const node = this.get(key, true);
|
|
@@ -40855,8 +40890,8 @@ var require_Collection = __commonJS({
|
|
|
40855
40890
|
* Sets a value in this collection. For `!!set`, `value` needs to be a
|
|
40856
40891
|
* boolean to add/remove the item from the set.
|
|
40857
40892
|
*/
|
|
40858
|
-
setIn(
|
|
40859
|
-
const [key, ...rest] =
|
|
40893
|
+
setIn(path2, value) {
|
|
40894
|
+
const [key, ...rest] = path2;
|
|
40860
40895
|
if (rest.length === 0) {
|
|
40861
40896
|
this.set(key, value);
|
|
40862
40897
|
} else {
|
|
@@ -43368,9 +43403,9 @@ var require_Document = __commonJS({
|
|
|
43368
43403
|
this.contents.add(value);
|
|
43369
43404
|
}
|
|
43370
43405
|
/** Adds a value to the document. */
|
|
43371
|
-
addIn(
|
|
43406
|
+
addIn(path2, value) {
|
|
43372
43407
|
if (assertCollection(this.contents))
|
|
43373
|
-
this.contents.addIn(
|
|
43408
|
+
this.contents.addIn(path2, value);
|
|
43374
43409
|
}
|
|
43375
43410
|
/**
|
|
43376
43411
|
* Create a new `Alias` node, ensuring that the target `node` has the required anchor.
|
|
@@ -43445,14 +43480,14 @@ var require_Document = __commonJS({
|
|
|
43445
43480
|
* Removes a value from the document.
|
|
43446
43481
|
* @returns `true` if the item was found and removed.
|
|
43447
43482
|
*/
|
|
43448
|
-
deleteIn(
|
|
43449
|
-
if (Collection.isEmptyPath(
|
|
43483
|
+
deleteIn(path2) {
|
|
43484
|
+
if (Collection.isEmptyPath(path2)) {
|
|
43450
43485
|
if (this.contents == null)
|
|
43451
43486
|
return false;
|
|
43452
43487
|
this.contents = null;
|
|
43453
43488
|
return true;
|
|
43454
43489
|
}
|
|
43455
|
-
return assertCollection(this.contents) ? this.contents.deleteIn(
|
|
43490
|
+
return assertCollection(this.contents) ? this.contents.deleteIn(path2) : false;
|
|
43456
43491
|
}
|
|
43457
43492
|
/**
|
|
43458
43493
|
* Returns item at `key`, or `undefined` if not found. By default unwraps
|
|
@@ -43467,10 +43502,10 @@ var require_Document = __commonJS({
|
|
|
43467
43502
|
* scalar values from their surrounding node; to disable set `keepScalar` to
|
|
43468
43503
|
* `true` (collections are always returned intact).
|
|
43469
43504
|
*/
|
|
43470
|
-
getIn(
|
|
43471
|
-
if (Collection.isEmptyPath(
|
|
43505
|
+
getIn(path2, keepScalar) {
|
|
43506
|
+
if (Collection.isEmptyPath(path2))
|
|
43472
43507
|
return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
|
|
43473
|
-
return identity.isCollection(this.contents) ? this.contents.getIn(
|
|
43508
|
+
return identity.isCollection(this.contents) ? this.contents.getIn(path2, keepScalar) : void 0;
|
|
43474
43509
|
}
|
|
43475
43510
|
/**
|
|
43476
43511
|
* Checks if the document includes a value with the key `key`.
|
|
@@ -43481,10 +43516,10 @@ var require_Document = __commonJS({
|
|
|
43481
43516
|
/**
|
|
43482
43517
|
* Checks if the document includes a value at `path`.
|
|
43483
43518
|
*/
|
|
43484
|
-
hasIn(
|
|
43485
|
-
if (Collection.isEmptyPath(
|
|
43519
|
+
hasIn(path2) {
|
|
43520
|
+
if (Collection.isEmptyPath(path2))
|
|
43486
43521
|
return this.contents !== void 0;
|
|
43487
|
-
return identity.isCollection(this.contents) ? this.contents.hasIn(
|
|
43522
|
+
return identity.isCollection(this.contents) ? this.contents.hasIn(path2) : false;
|
|
43488
43523
|
}
|
|
43489
43524
|
/**
|
|
43490
43525
|
* Sets a value in this document. For `!!set`, `value` needs to be a
|
|
@@ -43501,13 +43536,13 @@ var require_Document = __commonJS({
|
|
|
43501
43536
|
* Sets a value in this document. For `!!set`, `value` needs to be a
|
|
43502
43537
|
* boolean to add/remove the item from the set.
|
|
43503
43538
|
*/
|
|
43504
|
-
setIn(
|
|
43505
|
-
if (Collection.isEmptyPath(
|
|
43539
|
+
setIn(path2, value) {
|
|
43540
|
+
if (Collection.isEmptyPath(path2)) {
|
|
43506
43541
|
this.contents = value;
|
|
43507
43542
|
} else if (this.contents == null) {
|
|
43508
|
-
this.contents = Collection.collectionFromPath(this.schema, Array.from(
|
|
43543
|
+
this.contents = Collection.collectionFromPath(this.schema, Array.from(path2), value);
|
|
43509
43544
|
} else if (assertCollection(this.contents)) {
|
|
43510
|
-
this.contents.setIn(
|
|
43545
|
+
this.contents.setIn(path2, value);
|
|
43511
43546
|
}
|
|
43512
43547
|
}
|
|
43513
43548
|
/**
|
|
@@ -45464,9 +45499,9 @@ var require_cst_visit = __commonJS({
|
|
|
45464
45499
|
visit.BREAK = BREAK;
|
|
45465
45500
|
visit.SKIP = SKIP;
|
|
45466
45501
|
visit.REMOVE = REMOVE;
|
|
45467
|
-
visit.itemAtPath = (cst,
|
|
45502
|
+
visit.itemAtPath = (cst, path2) => {
|
|
45468
45503
|
let item = cst;
|
|
45469
|
-
for (const [field, index] of
|
|
45504
|
+
for (const [field, index] of path2) {
|
|
45470
45505
|
const tok = item?.[field];
|
|
45471
45506
|
if (tok && "items" in tok) {
|
|
45472
45507
|
item = tok.items[index];
|
|
@@ -45475,23 +45510,23 @@ var require_cst_visit = __commonJS({
|
|
|
45475
45510
|
}
|
|
45476
45511
|
return item;
|
|
45477
45512
|
};
|
|
45478
|
-
visit.parentCollection = (cst,
|
|
45479
|
-
const parent = visit.itemAtPath(cst,
|
|
45480
|
-
const field =
|
|
45513
|
+
visit.parentCollection = (cst, path2) => {
|
|
45514
|
+
const parent = visit.itemAtPath(cst, path2.slice(0, -1));
|
|
45515
|
+
const field = path2[path2.length - 1][0];
|
|
45481
45516
|
const coll = parent?.[field];
|
|
45482
45517
|
if (coll && "items" in coll)
|
|
45483
45518
|
return coll;
|
|
45484
45519
|
throw new Error("Parent collection not found");
|
|
45485
45520
|
};
|
|
45486
|
-
function _visit(
|
|
45487
|
-
let ctrl = visitor(item,
|
|
45521
|
+
function _visit(path2, item, visitor) {
|
|
45522
|
+
let ctrl = visitor(item, path2);
|
|
45488
45523
|
if (typeof ctrl === "symbol")
|
|
45489
45524
|
return ctrl;
|
|
45490
45525
|
for (const field of ["key", "value"]) {
|
|
45491
45526
|
const token = item[field];
|
|
45492
45527
|
if (token && "items" in token) {
|
|
45493
45528
|
for (let i = 0; i < token.items.length; ++i) {
|
|
45494
|
-
const ci = _visit(Object.freeze(
|
|
45529
|
+
const ci = _visit(Object.freeze(path2.concat([[field, i]])), token.items[i], visitor);
|
|
45495
45530
|
if (typeof ci === "number")
|
|
45496
45531
|
i = ci - 1;
|
|
45497
45532
|
else if (ci === BREAK)
|
|
@@ -45502,10 +45537,10 @@ var require_cst_visit = __commonJS({
|
|
|
45502
45537
|
}
|
|
45503
45538
|
}
|
|
45504
45539
|
if (typeof ctrl === "function" && field === "key")
|
|
45505
|
-
ctrl = ctrl(item,
|
|
45540
|
+
ctrl = ctrl(item, path2);
|
|
45506
45541
|
}
|
|
45507
45542
|
}
|
|
45508
|
-
return typeof ctrl === "function" ? ctrl(item,
|
|
45543
|
+
return typeof ctrl === "function" ? ctrl(item, path2) : ctrl;
|
|
45509
45544
|
}
|
|
45510
45545
|
exports.visit = visit;
|
|
45511
45546
|
}
|
|
@@ -48636,6 +48671,7 @@ __export(src_exports, {
|
|
|
48636
48671
|
validateImportData: () => validateImportData,
|
|
48637
48672
|
validateMessageMetadata: () => validateMessageMetadata,
|
|
48638
48673
|
validatePluginManifest: () => validatePluginManifest,
|
|
48674
|
+
validateUnavailableNodePolicy: () => validateUnavailableNodePolicy,
|
|
48639
48675
|
writeAgentMemoryFile: () => writeAgentMemoryFile,
|
|
48640
48676
|
writeExportFile: () => writeExportFile,
|
|
48641
48677
|
writeInsightsMemory: () => writeInsightsMemory,
|
|
@@ -48668,6 +48704,7 @@ var init_src = __esm({
|
|
|
48668
48704
|
init_automation();
|
|
48669
48705
|
init_automation_store();
|
|
48670
48706
|
init_run_command();
|
|
48707
|
+
init_settings_validation();
|
|
48671
48708
|
init_routine();
|
|
48672
48709
|
init_routine_store();
|
|
48673
48710
|
init_plugin_types();
|
|
@@ -49166,13 +49203,13 @@ async function searchAgentMemoryWithQmd(rootDir, agentMemory, query, limit) {
|
|
|
49166
49203
|
return searchAgentMemoryFile(rootDir, agentMemory, query, limit);
|
|
49167
49204
|
}
|
|
49168
49205
|
}
|
|
49169
|
-
function resolveAgentMemoryPath(rootDir, agentId,
|
|
49206
|
+
function resolveAgentMemoryPath(rootDir, agentId, path2) {
|
|
49170
49207
|
const safeAgentId = sanitizeAgentMemoryId(agentId);
|
|
49171
49208
|
const prefix = `${AGENT_MEMORY_ROOT2}/${safeAgentId}/`;
|
|
49172
|
-
if (!
|
|
49209
|
+
if (!path2.startsWith(prefix)) {
|
|
49173
49210
|
return null;
|
|
49174
49211
|
}
|
|
49175
|
-
const filename =
|
|
49212
|
+
const filename = path2.slice(prefix.length);
|
|
49176
49213
|
if (filename !== AGENT_MEMORY_FILENAME2 && filename !== AGENT_DREAMS_FILENAME2 && !DAILY_AGENT_MEMORY_RE2.test(filename)) {
|
|
49177
49214
|
return null;
|
|
49178
49215
|
}
|
|
@@ -49181,8 +49218,8 @@ function resolveAgentMemoryPath(rootDir, agentId, path) {
|
|
|
49181
49218
|
displayPath: `${prefix}${filename}`
|
|
49182
49219
|
};
|
|
49183
49220
|
}
|
|
49184
|
-
async function getAgentMemoryWindow(rootDir, agentMemory,
|
|
49185
|
-
const resolved = resolveAgentMemoryPath(rootDir, agentMemory.agentId,
|
|
49221
|
+
async function getAgentMemoryWindow(rootDir, agentMemory, path2, startLine = 1, lineCount = 40) {
|
|
49222
|
+
const resolved = resolveAgentMemoryPath(rootDir, agentMemory.agentId, path2);
|
|
49186
49223
|
if (!resolved) {
|
|
49187
49224
|
return null;
|
|
49188
49225
|
}
|
|
@@ -49908,12 +49945,12 @@ var init_concurrency = __esm({
|
|
|
49908
49945
|
// ../engine/src/skill-resolver.ts
|
|
49909
49946
|
import { existsSync as existsSync18, readFileSync as readFileSync4 } from "node:fs";
|
|
49910
49947
|
import { join as join22 } from "node:path";
|
|
49911
|
-
function readJsonObject(
|
|
49912
|
-
if (!existsSync18(
|
|
49948
|
+
function readJsonObject(path2) {
|
|
49949
|
+
if (!existsSync18(path2)) {
|
|
49913
49950
|
return {};
|
|
49914
49951
|
}
|
|
49915
49952
|
try {
|
|
49916
|
-
const parsed = JSON.parse(readFileSync4(
|
|
49953
|
+
const parsed = JSON.parse(readFileSync4(path2, "utf-8"));
|
|
49917
49954
|
return parsed && typeof parsed === "object" ? parsed : {};
|
|
49918
49955
|
} catch {
|
|
49919
49956
|
return {};
|
|
@@ -49973,17 +50010,17 @@ function resolveSessionSkills(context) {
|
|
|
49973
50010
|
}
|
|
49974
50011
|
const finalDecisions = /* @__PURE__ */ new Map();
|
|
49975
50012
|
for (const pattern of skillPatterns) {
|
|
49976
|
-
const
|
|
50013
|
+
const path2 = normalizePattern(pattern);
|
|
49977
50014
|
const isExclusion = isExclusionPattern(pattern);
|
|
49978
|
-
finalDecisions.set(
|
|
50015
|
+
finalDecisions.set(path2, !isExclusion);
|
|
49979
50016
|
}
|
|
49980
50017
|
const allowedSet = /* @__PURE__ */ new Set();
|
|
49981
50018
|
const excludedSet = /* @__PURE__ */ new Set();
|
|
49982
|
-
for (const [
|
|
50019
|
+
for (const [path2, allowed] of finalDecisions) {
|
|
49983
50020
|
if (allowed) {
|
|
49984
|
-
allowedSet.add(
|
|
50021
|
+
allowedSet.add(path2);
|
|
49985
50022
|
} else {
|
|
49986
|
-
excludedSet.add(
|
|
50023
|
+
excludedSet.add(path2);
|
|
49987
50024
|
}
|
|
49988
50025
|
}
|
|
49989
50026
|
const filterActive = hasPatterns || hasRequestedNames;
|
|
@@ -49991,11 +50028,11 @@ function resolveSessionSkills(context) {
|
|
|
49991
50028
|
if (hasPatterns) {
|
|
49992
50029
|
for (const pattern of skillPatterns) {
|
|
49993
50030
|
if (!isExclusionPattern(pattern)) {
|
|
49994
|
-
const
|
|
50031
|
+
const path2 = normalizePattern(pattern);
|
|
49995
50032
|
diagnostics8.push({
|
|
49996
50033
|
type: "info",
|
|
49997
50034
|
message: `Configured skill pattern: ${pattern}`,
|
|
49998
|
-
skillPath:
|
|
50035
|
+
skillPath: path2
|
|
49999
50036
|
});
|
|
50000
50037
|
}
|
|
50001
50038
|
}
|
|
@@ -50522,12 +50559,12 @@ function isRetryableModelSelectionError(message) {
|
|
|
50522
50559
|
const normalized = message.toLowerCase();
|
|
50523
50560
|
return normalized.includes("rate limit") || normalized.includes("too many requests") || normalized.includes("429") || normalized.includes("401") || normalized.includes("403") || normalized.includes("unauthorized") || normalized.includes("forbidden") || normalized.includes("authentication") || normalized.includes("invalid api key") || normalized.includes("invalid key") || normalized.includes("api key") || normalized.includes("overloaded") || normalized.includes("quota") || normalized.includes("capacity") || normalized.includes("temporarily unavailable") || normalized.includes("invalid temperature");
|
|
50524
50561
|
}
|
|
50525
|
-
function readJsonObject2(
|
|
50526
|
-
if (!existsSync20(
|
|
50562
|
+
function readJsonObject2(path2) {
|
|
50563
|
+
if (!existsSync20(path2)) {
|
|
50527
50564
|
return {};
|
|
50528
50565
|
}
|
|
50529
50566
|
try {
|
|
50530
|
-
const parsed = JSON.parse(readFileSync6(
|
|
50567
|
+
const parsed = JSON.parse(readFileSync6(path2, "utf-8"));
|
|
50531
50568
|
return parsed && typeof parsed === "object" ? parsed : {};
|
|
50532
50569
|
} catch {
|
|
50533
50570
|
return {};
|
|
@@ -50704,8 +50741,8 @@ function resolveVendoredClaudeCliEntry() {
|
|
|
50704
50741
|
if (!Array.isArray(extensions) || extensions.length === 0) return null;
|
|
50705
50742
|
const entry = extensions[0];
|
|
50706
50743
|
if (typeof entry !== "string" || entry.length === 0) return null;
|
|
50707
|
-
const
|
|
50708
|
-
return existsSync20(
|
|
50744
|
+
const path2 = resolve10(dirname7(pkgJsonPath), entry);
|
|
50745
|
+
return existsSync20(path2) ? path2 : null;
|
|
50709
50746
|
} catch {
|
|
50710
50747
|
return null;
|
|
50711
50748
|
}
|
|
@@ -50730,8 +50767,8 @@ async function registerExtensionProviders(cwd, modelRegistry) {
|
|
|
50730
50767
|
cwd,
|
|
50731
50768
|
join24(resolvePiExtensionProjectRoot(cwd), ".fusion", "disabled-auto-extension-discovery")
|
|
50732
50769
|
);
|
|
50733
|
-
for (const { path, error } of extensionsResult.errors) {
|
|
50734
|
-
extensionsLog.warn(`Failed to load ${
|
|
50770
|
+
for (const { path: path2, error } of extensionsResult.errors) {
|
|
50771
|
+
extensionsLog.warn(`Failed to load ${path2}: ${error}`);
|
|
50735
50772
|
}
|
|
50736
50773
|
for (const { name, config, extensionPath } of extensionsResult.runtime.pendingProviderRegistrations) {
|
|
50737
50774
|
try {
|
|
@@ -51560,8 +51597,8 @@ function trimAndClamp(value, maxLength, label, agentId) {
|
|
|
51560
51597
|
log4.warn(`${label} exceeded max length for agent ${agentId}; truncating to ${maxLength} chars`);
|
|
51561
51598
|
return trimmed.slice(0, maxLength);
|
|
51562
51599
|
}
|
|
51563
|
-
function isPathTraversal2(
|
|
51564
|
-
return
|
|
51600
|
+
function isPathTraversal2(path2) {
|
|
51601
|
+
return path2.split(/[\\/]+/).includes("..");
|
|
51565
51602
|
}
|
|
51566
51603
|
function resolveValidatedInstructionsPath(rawPath, rootDir, agentId) {
|
|
51567
51604
|
const trimmed = rawPath.trim();
|
|
@@ -54282,10 +54319,11 @@ async function execWithProcessGroup(command, options) {
|
|
|
54282
54319
|
));
|
|
54283
54320
|
return;
|
|
54284
54321
|
}
|
|
54322
|
+
const useProcessGroup = process.platform !== "win32";
|
|
54285
54323
|
const child = spawn2(command, {
|
|
54286
54324
|
cwd: options.cwd,
|
|
54287
54325
|
shell: true,
|
|
54288
|
-
detached:
|
|
54326
|
+
detached: useProcessGroup,
|
|
54289
54327
|
stdio: ["ignore", "pipe", "pipe"]
|
|
54290
54328
|
});
|
|
54291
54329
|
let stdout = "";
|
|
@@ -54298,7 +54336,11 @@ async function execWithProcessGroup(command, options) {
|
|
|
54298
54336
|
const killTree = (sig) => {
|
|
54299
54337
|
if (child.pid === void 0) return;
|
|
54300
54338
|
try {
|
|
54301
|
-
|
|
54339
|
+
if (useProcessGroup) {
|
|
54340
|
+
process.kill(-child.pid, sig);
|
|
54341
|
+
} else {
|
|
54342
|
+
child.kill(sig);
|
|
54343
|
+
}
|
|
54302
54344
|
} catch {
|
|
54303
54345
|
}
|
|
54304
54346
|
};
|
|
@@ -54489,18 +54531,18 @@ function truncateWorkflowScriptOutput(output) {
|
|
|
54489
54531
|
return `... output truncated to last ${WORKFLOW_SCRIPT_OUTPUT_MAX_CHARS} characters ...
|
|
54490
54532
|
${output.slice(-WORKFLOW_SCRIPT_OUTPUT_MAX_CHARS)}`;
|
|
54491
54533
|
}
|
|
54492
|
-
function matchGlob(
|
|
54534
|
+
function matchGlob(path2, pattern) {
|
|
54493
54535
|
if (pattern.includes("**")) {
|
|
54494
54536
|
const regexPattern2 = pattern.replace(/\./g, "\\.").replace(/\*\*/g, "<<<DOUBLESTAR>>>").replace(/\*/g, "[^/]*").replace(/<<<DOUBLESTAR>>>/g, ".*");
|
|
54495
54537
|
const regex2 = new RegExp(`^${regexPattern2}$`);
|
|
54496
|
-
return regex2.test(
|
|
54538
|
+
return regex2.test(path2);
|
|
54497
54539
|
}
|
|
54498
54540
|
const lastSlash = pattern.lastIndexOf("/");
|
|
54499
54541
|
if (lastSlash !== -1) {
|
|
54500
54542
|
const patternDir = pattern.slice(0, lastSlash);
|
|
54501
54543
|
const patternFile = pattern.slice(lastSlash + 1);
|
|
54502
|
-
const pathDir =
|
|
54503
|
-
const pathFile =
|
|
54544
|
+
const pathDir = path2.lastIndexOf("/") !== -1 ? path2.slice(0, path2.lastIndexOf("/")) : "";
|
|
54545
|
+
const pathFile = path2.lastIndexOf("/") !== -1 ? path2.slice(path2.lastIndexOf("/")) : path2;
|
|
54504
54546
|
if (patternDir.includes("*")) {
|
|
54505
54547
|
const dirRegex = new RegExp(`^${patternDir.replace(/\./g, "\\.").replace(/\*/g, "[^/]*")}$`);
|
|
54506
54548
|
if (!dirRegex.test(pathDir)) return false;
|
|
@@ -54509,10 +54551,10 @@ function matchGlob(path, pattern) {
|
|
|
54509
54551
|
}
|
|
54510
54552
|
return matchGlob(pathFile, patternFile);
|
|
54511
54553
|
}
|
|
54512
|
-
const fileName =
|
|
54554
|
+
const fileName = path2.lastIndexOf("/") !== -1 ? path2.slice(path2.lastIndexOf("/") + 1) : path2;
|
|
54513
54555
|
const regexPattern = pattern.replace(/\./g, "\\.").replace(/\*/g, "[^/]*");
|
|
54514
54556
|
const regex = new RegExp(`^${regexPattern}$`);
|
|
54515
|
-
return regex.test(fileName) || regex.test(
|
|
54557
|
+
return regex.test(fileName) || regex.test(path2);
|
|
54516
54558
|
}
|
|
54517
54559
|
async function getStagedFiles(cwd) {
|
|
54518
54560
|
try {
|
|
@@ -54952,13 +54994,13 @@ async function amendMergeCommitWithFixes(rootDir, taskId, authorArg) {
|
|
|
54952
54994
|
const match = line.match(/^:\d{6} 160000 [^\t]+\t(.+)$/);
|
|
54953
54995
|
if (match) gitlinkPaths.push(match[1]);
|
|
54954
54996
|
}
|
|
54955
|
-
for (const
|
|
54956
|
-
mergerLog.warn(`${taskId}: refusing to stage gitlink "${
|
|
54997
|
+
for (const path2 of gitlinkPaths) {
|
|
54998
|
+
mergerLog.warn(`${taskId}: refusing to stage gitlink "${path2}" (project uses no submodules \u2014 likely a nested worktree). Unstaging.`);
|
|
54957
54999
|
try {
|
|
54958
|
-
await execAsync2(`git reset HEAD -- "${
|
|
55000
|
+
await execAsync2(`git reset HEAD -- "${path2}"`, { cwd: rootDir });
|
|
54959
55001
|
} catch (err) {
|
|
54960
55002
|
const msg = err instanceof Error ? err.message : String(err);
|
|
54961
|
-
mergerLog.warn(`${taskId}: failed to unstage gitlink "${
|
|
55003
|
+
mergerLog.warn(`${taskId}: failed to unstage gitlink "${path2}": ${msg}`);
|
|
54962
55004
|
}
|
|
54963
55005
|
}
|
|
54964
55006
|
const { stdout: finalStaged } = await execAsync2("git diff --cached --name-only", {
|
|
@@ -57508,12 +57550,12 @@ var init_worktree_pool = __esm({
|
|
|
57508
57550
|
* and prunes any stale entries.
|
|
57509
57551
|
*/
|
|
57510
57552
|
acquire() {
|
|
57511
|
-
for (const
|
|
57512
|
-
this.idle.delete(
|
|
57513
|
-
if (existsSync23(
|
|
57514
|
-
return
|
|
57553
|
+
for (const path2 of this.idle) {
|
|
57554
|
+
this.idle.delete(path2);
|
|
57555
|
+
if (existsSync23(path2)) {
|
|
57556
|
+
return path2;
|
|
57515
57557
|
}
|
|
57516
|
-
worktreePoolLog.log(`Pruned stale entry: ${
|
|
57558
|
+
worktreePoolLog.log(`Pruned stale entry: ${path2}`);
|
|
57517
57559
|
}
|
|
57518
57560
|
return null;
|
|
57519
57561
|
}
|
|
@@ -57533,8 +57575,8 @@ var init_worktree_pool = __esm({
|
|
|
57533
57575
|
return this.idle.size;
|
|
57534
57576
|
}
|
|
57535
57577
|
/** Check whether a specific path is in the idle pool. */
|
|
57536
|
-
has(
|
|
57537
|
-
return this.idle.has(
|
|
57578
|
+
has(path2) {
|
|
57579
|
+
return this.idle.has(path2);
|
|
57538
57580
|
}
|
|
57539
57581
|
/**
|
|
57540
57582
|
* Remove and return all idle worktree paths.
|
|
@@ -57556,11 +57598,11 @@ var init_worktree_pool = __esm({
|
|
|
57556
57598
|
* @param idlePaths — Absolute paths to idle worktree directories
|
|
57557
57599
|
*/
|
|
57558
57600
|
rehydrate(idlePaths) {
|
|
57559
|
-
for (const
|
|
57560
|
-
if (existsSync23(
|
|
57561
|
-
this.idle.add(
|
|
57601
|
+
for (const path2 of idlePaths) {
|
|
57602
|
+
if (existsSync23(path2)) {
|
|
57603
|
+
this.idle.add(path2);
|
|
57562
57604
|
} else {
|
|
57563
|
-
worktreePoolLog.log(`Rehydrate skipped (not on disk): ${
|
|
57605
|
+
worktreePoolLog.log(`Rehydrate skipped (not on disk): ${path2}`);
|
|
57564
57606
|
}
|
|
57565
57607
|
}
|
|
57566
57608
|
}
|
|
@@ -57725,14 +57767,14 @@ function extractPathsFromSection(section) {
|
|
|
57725
57767
|
return paths;
|
|
57726
57768
|
}
|
|
57727
57769
|
function normalizePath(raw) {
|
|
57728
|
-
let
|
|
57729
|
-
if (
|
|
57730
|
-
|
|
57770
|
+
let path2 = raw.trim();
|
|
57771
|
+
if (path2.endsWith("/*")) {
|
|
57772
|
+
path2 = path2.slice(0, -2);
|
|
57731
57773
|
}
|
|
57732
|
-
if (
|
|
57733
|
-
|
|
57774
|
+
if (path2.endsWith("/")) {
|
|
57775
|
+
path2 = path2.slice(0, -1);
|
|
57734
57776
|
}
|
|
57735
|
-
return
|
|
57777
|
+
return path2;
|
|
57736
57778
|
}
|
|
57737
57779
|
function buildConflictMatrix(stepScopes) {
|
|
57738
57780
|
const indices = [...stepScopes.keys()].sort((a, b) => a - b);
|
|
@@ -58362,8 +58404,8 @@ var init_step_session_executor = __esm({
|
|
|
58362
58404
|
const failedWorktreeSteps = /* @__PURE__ */ new Set();
|
|
58363
58405
|
for (const stepIdx of wave.indices) {
|
|
58364
58406
|
try {
|
|
58365
|
-
const
|
|
58366
|
-
worktreePaths.set(stepIdx,
|
|
58407
|
+
const path2 = await this.createStepWorktree(stepIdx);
|
|
58408
|
+
worktreePaths.set(stepIdx, path2);
|
|
58367
58409
|
} catch (err) {
|
|
58368
58410
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
58369
58411
|
stepExecLog.error(
|
|
@@ -58382,8 +58424,8 @@ var init_step_session_executor = __esm({
|
|
|
58382
58424
|
const parallelResults = [];
|
|
58383
58425
|
if (parallelSteps.length > 0) {
|
|
58384
58426
|
const promises = parallelSteps.map((stepIdx) => {
|
|
58385
|
-
const
|
|
58386
|
-
return this.executeStep(stepIdx,
|
|
58427
|
+
const path2 = worktreePaths.get(stepIdx) ?? this.options.worktreePath;
|
|
58428
|
+
return this.executeStep(stepIdx, path2);
|
|
58387
58429
|
});
|
|
58388
58430
|
const settled = await Promise.allSettled(promises);
|
|
58389
58431
|
parallelResults.push(...settled.map((outcome, i) => {
|
|
@@ -61824,8 +61866,8 @@ Review the work done in this worktree and evaluate it against the criteria in yo
|
|
|
61824
61866
|
* @param startPoint - Optional base branch/commit for new branch
|
|
61825
61867
|
* @returns The actual worktree path (may differ if recovery generated new name)
|
|
61826
61868
|
*/
|
|
61827
|
-
async createWorktree(branch,
|
|
61828
|
-
const currentPath =
|
|
61869
|
+
async createWorktree(branch, path2, taskId, startPoint) {
|
|
61870
|
+
const currentPath = path2;
|
|
61829
61871
|
let resolvedStartPoint;
|
|
61830
61872
|
if (startPoint) {
|
|
61831
61873
|
const resolved = await this.resolveWorktreeStartPoint(startPoint, taskId);
|
|
@@ -61885,58 +61927,58 @@ Review the work done in this worktree and evaluate it against the criteria in yo
|
|
|
61885
61927
|
* Single attempt to create a worktree with conflict detection and recovery.
|
|
61886
61928
|
* Returns the actual worktree path used (may differ from input if recovery generated new name).
|
|
61887
61929
|
*/
|
|
61888
|
-
async tryCreateWorktree(branch,
|
|
61889
|
-
await this.assertWorktreePathNotNested(
|
|
61890
|
-
if (existsSync25(
|
|
61891
|
-
const isRegistered = await this.isRegisteredWorktree(
|
|
61930
|
+
async tryCreateWorktree(branch, path2, taskId, startPoint, attemptNumber = 0, recoveryDepth = 0) {
|
|
61931
|
+
await this.assertWorktreePathNotNested(path2, taskId);
|
|
61932
|
+
if (existsSync25(path2)) {
|
|
61933
|
+
const isRegistered = await this.isRegisteredWorktree(path2);
|
|
61892
61934
|
if (!isRegistered) {
|
|
61893
61935
|
await this.store.logEntry(
|
|
61894
61936
|
taskId,
|
|
61895
|
-
`Removing existing directory (not a registered worktree): ${
|
|
61937
|
+
`Removing existing directory (not a registered worktree): ${path2}`
|
|
61896
61938
|
);
|
|
61897
61939
|
try {
|
|
61898
|
-
await execAsync5(`rm -rf "${
|
|
61940
|
+
await execAsync5(`rm -rf "${path2}"`, { cwd: this.rootDir });
|
|
61899
61941
|
} catch (e) {
|
|
61900
61942
|
const eMessage = e instanceof Error ? e.message : String(e);
|
|
61901
|
-
throw new Error(`Failed to remove existing directory ${
|
|
61943
|
+
throw new Error(`Failed to remove existing directory ${path2}: ${eMessage}`);
|
|
61902
61944
|
}
|
|
61903
61945
|
} else {
|
|
61904
|
-
executorLog.log(`Worktree already exists: ${
|
|
61905
|
-
return { path, branch };
|
|
61946
|
+
executorLog.log(`Worktree already exists: ${path2}`);
|
|
61947
|
+
return { path: path2, branch };
|
|
61906
61948
|
}
|
|
61907
61949
|
}
|
|
61908
61950
|
const createWithBranch = async (branchToCreate) => {
|
|
61909
|
-
const cmd = startPoint ? `git worktree add -b "${branchToCreate}" "${
|
|
61951
|
+
const cmd = startPoint ? `git worktree add -b "${branchToCreate}" "${path2}" "${startPoint}"` : `git worktree add -b "${branchToCreate}" "${path2}"`;
|
|
61910
61952
|
try {
|
|
61911
61953
|
await execAsync5(cmd, { cwd: this.rootDir });
|
|
61912
61954
|
} catch (err) {
|
|
61913
61955
|
try {
|
|
61914
|
-
await execAsync5(`rm -rf "${
|
|
61956
|
+
await execAsync5(`rm -rf "${path2}"`, { cwd: this.rootDir });
|
|
61915
61957
|
} catch {
|
|
61916
|
-
executorLog.log(`Warning: failed to remove partial worktree directory after creation failure: ${
|
|
61958
|
+
executorLog.log(`Warning: failed to remove partial worktree directory after creation failure: ${path2}`);
|
|
61917
61959
|
}
|
|
61918
61960
|
throw err;
|
|
61919
61961
|
}
|
|
61920
61962
|
};
|
|
61921
61963
|
const createFromExistingBranch = async () => {
|
|
61922
61964
|
try {
|
|
61923
|
-
await execAsync5(`git worktree add "${
|
|
61965
|
+
await execAsync5(`git worktree add "${path2}" "${branch}"`, { cwd: this.rootDir });
|
|
61924
61966
|
} catch (err) {
|
|
61925
61967
|
try {
|
|
61926
|
-
await execAsync5(`rm -rf "${
|
|
61968
|
+
await execAsync5(`rm -rf "${path2}"`, { cwd: this.rootDir });
|
|
61927
61969
|
} catch {
|
|
61928
|
-
executorLog.log(`Warning: failed to remove partial worktree directory after creation failure: ${
|
|
61970
|
+
executorLog.log(`Warning: failed to remove partial worktree directory after creation failure: ${path2}`);
|
|
61929
61971
|
}
|
|
61930
61972
|
throw err;
|
|
61931
61973
|
}
|
|
61932
61974
|
};
|
|
61933
61975
|
try {
|
|
61934
61976
|
await createWithBranch(branch);
|
|
61935
|
-
executorLog.log(`Worktree created: ${
|
|
61977
|
+
executorLog.log(`Worktree created: ${path2}${startPoint ? ` (from ${startPoint})` : ""}`);
|
|
61936
61978
|
if (attemptNumber > 0) {
|
|
61937
|
-
await this.store.logEntry(taskId, `Worktree created on attempt ${attemptNumber + 1}`,
|
|
61979
|
+
await this.store.logEntry(taskId, `Worktree created on attempt ${attemptNumber + 1}`, path2);
|
|
61938
61980
|
}
|
|
61939
|
-
return { path, branch };
|
|
61981
|
+
return { path: path2, branch };
|
|
61940
61982
|
} catch (initialError) {
|
|
61941
61983
|
const conflictInfo = this.extractWorktreeConflictInfo(initialError);
|
|
61942
61984
|
if (conflictInfo.type === "not-git-repo") {
|
|
@@ -61948,7 +61990,7 @@ Review the work done in this worktree and evaluate it against the criteria in yo
|
|
|
61948
61990
|
const result = await this.handleWorktreeConflict(
|
|
61949
61991
|
conflictInfo.path,
|
|
61950
61992
|
branch,
|
|
61951
|
-
|
|
61993
|
+
path2,
|
|
61952
61994
|
taskId,
|
|
61953
61995
|
startPoint,
|
|
61954
61996
|
attemptNumber
|
|
@@ -61969,7 +62011,7 @@ Review the work done in this worktree and evaluate it against the criteria in yo
|
|
|
61969
62011
|
const branchCleaned = await this.cleanupStaleBranch(branch, taskId);
|
|
61970
62012
|
if (branchCleaned) {
|
|
61971
62013
|
await this.store.logEntry(taskId, `Removed stale branch reference, retrying`);
|
|
61972
|
-
return this.tryCreateWorktree(branch,
|
|
62014
|
+
return this.tryCreateWorktree(branch, path2, taskId, startPoint, attemptNumber, recoveryDepth + 1);
|
|
61973
62015
|
}
|
|
61974
62016
|
throw new Error(
|
|
61975
62017
|
`Invalid reference for branch ${branch}: unable to clean up stale reference`
|
|
@@ -61977,13 +62019,13 @@ Review the work done in this worktree and evaluate it against the criteria in yo
|
|
|
61977
62019
|
}
|
|
61978
62020
|
if (conflictInfo.type === "leading-directories") {
|
|
61979
62021
|
throw new Error(
|
|
61980
|
-
`Cannot create worktree at ${
|
|
62022
|
+
`Cannot create worktree at ${path2}: permission or path issue. Check that parent directories are writable.`
|
|
61981
62023
|
);
|
|
61982
62024
|
}
|
|
61983
62025
|
try {
|
|
61984
62026
|
await createFromExistingBranch();
|
|
61985
|
-
executorLog.log(`Worktree created from existing branch: ${
|
|
61986
|
-
return { path, branch };
|
|
62027
|
+
executorLog.log(`Worktree created from existing branch: ${path2}`);
|
|
62028
|
+
return { path: path2, branch };
|
|
61987
62029
|
} catch (fallbackError) {
|
|
61988
62030
|
const fallbackErrorMessage = fallbackError instanceof Error ? fallbackError.message : String(fallbackError);
|
|
61989
62031
|
const fallbackConflictInfo = this.extractWorktreeConflictInfo(fallbackError);
|
|
@@ -61996,7 +62038,7 @@ Review the work done in this worktree and evaluate it against the criteria in yo
|
|
|
61996
62038
|
const result = await this.handleWorktreeConflict(
|
|
61997
62039
|
fallbackConflictInfo.path,
|
|
61998
62040
|
branch,
|
|
61999
|
-
|
|
62041
|
+
path2,
|
|
62000
62042
|
taskId,
|
|
62001
62043
|
startPoint,
|
|
62002
62044
|
attemptNumber
|
|
@@ -62017,7 +62059,7 @@ Review the work done in this worktree and evaluate it against the criteria in yo
|
|
|
62017
62059
|
const branchCleaned = await this.cleanupStaleBranch(branch, taskId);
|
|
62018
62060
|
if (branchCleaned) {
|
|
62019
62061
|
await this.store.logEntry(taskId, `Cleaned up stale reference in fallback, retrying`);
|
|
62020
|
-
return this.tryCreateWorktree(branch,
|
|
62062
|
+
return this.tryCreateWorktree(branch, path2, taskId, startPoint, attemptNumber, recoveryDepth + 1);
|
|
62021
62063
|
}
|
|
62022
62064
|
}
|
|
62023
62065
|
throw new Error(`Failed to create worktree: ${fallbackErrorMessage}`);
|
|
@@ -62031,7 +62073,7 @@ Review the work done in this worktree and evaluate it against the criteria in yo
|
|
|
62031
62073
|
*
|
|
62032
62074
|
* @returns The worktree path if recovery succeeded, null if recovery failed
|
|
62033
62075
|
*/
|
|
62034
|
-
async handleWorktreeConflict(conflictPath, branch,
|
|
62076
|
+
async handleWorktreeConflict(conflictPath, branch, path2, taskId, startPoint, attemptNumber) {
|
|
62035
62077
|
const shouldGenerateNewName = await this.shouldGenerateNewWorktreeName(
|
|
62036
62078
|
conflictPath,
|
|
62037
62079
|
taskId
|
|
@@ -62061,24 +62103,24 @@ Review the work done in this worktree and evaluate it against the criteria in yo
|
|
|
62061
62103
|
}
|
|
62062
62104
|
const cleanupSuccess = await this.cleanupConflictingWorktree(conflictPath, branch, taskId);
|
|
62063
62105
|
if (cleanupSuccess) {
|
|
62064
|
-
await this.store.logEntry(taskId, `Cleaned up conflicting worktree, retrying`,
|
|
62065
|
-
return this.tryCreateWorktree(branch,
|
|
62106
|
+
await this.store.logEntry(taskId, `Cleaned up conflicting worktree, retrying`, path2);
|
|
62107
|
+
return this.tryCreateWorktree(branch, path2, taskId, startPoint, attemptNumber);
|
|
62066
62108
|
}
|
|
62067
62109
|
return null;
|
|
62068
62110
|
}
|
|
62069
62111
|
/**
|
|
62070
62112
|
* Check if a path is registered as a git worktree.
|
|
62071
62113
|
*/
|
|
62072
|
-
async isRegisteredWorktree(
|
|
62073
|
-
return isRegisteredGitWorktree2(this.rootDir,
|
|
62114
|
+
async isRegisteredWorktree(path2) {
|
|
62115
|
+
return isRegisteredGitWorktree2(this.rootDir, path2);
|
|
62074
62116
|
}
|
|
62075
62117
|
/**
|
|
62076
62118
|
* Throw if `path` lies inside an existing registered worktree other than the
|
|
62077
62119
|
* repo root. The repo root itself is a worktree (main branch) and must be
|
|
62078
62120
|
* allowed — we only reject paths strictly *inside* a non-root worktree.
|
|
62079
62121
|
*/
|
|
62080
|
-
async assertWorktreePathNotNested(
|
|
62081
|
-
const target = resolvePath(
|
|
62122
|
+
async assertWorktreePathNotNested(path2, taskId) {
|
|
62123
|
+
const target = resolvePath(path2);
|
|
62082
62124
|
const rootResolved = resolvePath(this.rootDir);
|
|
62083
62125
|
const registered = await getRegisteredWorktreePaths(this.rootDir);
|
|
62084
62126
|
for (const wt of registered) {
|
|
@@ -62716,11 +62758,11 @@ function pathsOverlap2(a, b) {
|
|
|
62716
62758
|
}
|
|
62717
62759
|
return false;
|
|
62718
62760
|
}
|
|
62719
|
-
function normalizeOverlapPath(
|
|
62720
|
-
return
|
|
62761
|
+
function normalizeOverlapPath(path2) {
|
|
62762
|
+
return path2.trim().replaceAll("\\", "/").replace(/^\.\//, "");
|
|
62721
62763
|
}
|
|
62722
|
-
function isIgnoredOverlapPath(
|
|
62723
|
-
const normalizedPath = normalizeOverlapPath(
|
|
62764
|
+
function isIgnoredOverlapPath(path2, ignorePath) {
|
|
62765
|
+
const normalizedPath = normalizeOverlapPath(path2);
|
|
62724
62766
|
const normalizedIgnore = normalizeOverlapPath(ignorePath);
|
|
62725
62767
|
if (normalizedIgnore.endsWith("/*")) {
|
|
62726
62768
|
const directory = normalizedIgnore.slice(0, -2);
|
|
@@ -62740,7 +62782,7 @@ function filterPathsByIgnoreList(paths, ignorePaths) {
|
|
|
62740
62782
|
if (normalizedIgnorePaths.length === 0) {
|
|
62741
62783
|
return paths;
|
|
62742
62784
|
}
|
|
62743
|
-
return paths.filter((
|
|
62785
|
+
return paths.filter((path2) => !normalizedIgnorePaths.some((ignore) => isIgnoredOverlapPath(path2, ignore)));
|
|
62744
62786
|
}
|
|
62745
62787
|
var Scheduler;
|
|
62746
62788
|
var init_scheduler = __esm({
|
|
@@ -70041,18 +70083,18 @@ var init_self_healing = __esm({
|
|
|
70041
70083
|
const registered = await getRegisteredWorktreePaths(this.options.rootDir);
|
|
70042
70084
|
const unregistered = dirs.filter((d) => !registered.has(resolve14(d)));
|
|
70043
70085
|
let cleaned = 0;
|
|
70044
|
-
for (const
|
|
70045
|
-
const rel = relative7(worktreesDir,
|
|
70086
|
+
for (const path2 of unregistered) {
|
|
70087
|
+
const rel = relative7(worktreesDir, path2);
|
|
70046
70088
|
if (rel === "" || rel.startsWith("..") || isAbsolute11(rel)) {
|
|
70047
|
-
log8.warn(`Refusing to remove path outside .worktrees: ${
|
|
70089
|
+
log8.warn(`Refusing to remove path outside .worktrees: ${path2}`);
|
|
70048
70090
|
continue;
|
|
70049
70091
|
}
|
|
70050
70092
|
try {
|
|
70051
|
-
rmSync3(
|
|
70052
|
-
log8.log(`Cleaned unregistered worktree dir: ${
|
|
70093
|
+
rmSync3(path2, { recursive: true, force: true });
|
|
70094
|
+
log8.log(`Cleaned unregistered worktree dir: ${path2}`);
|
|
70053
70095
|
cleaned++;
|
|
70054
70096
|
} catch (err) {
|
|
70055
|
-
log8.warn(`Failed to remove unregistered worktree dir ${
|
|
70097
|
+
log8.warn(`Failed to remove unregistered worktree dir ${path2}: ${err instanceof Error ? err.message : String(err)}`);
|
|
70056
70098
|
}
|
|
70057
70099
|
}
|
|
70058
70100
|
if (cleaned > 0) {
|
|
@@ -72266,9 +72308,9 @@ var init_remote_node_client = __esm({
|
|
|
72266
72308
|
}
|
|
72267
72309
|
}
|
|
72268
72310
|
}
|
|
72269
|
-
const
|
|
72311
|
+
const path2 = query.toString().length > 0 ? `/api/tasks?${query.toString()}` : "/api/tasks";
|
|
72270
72312
|
return this.withRetry(
|
|
72271
|
-
() => this.requestJson(
|
|
72313
|
+
() => this.requestJson(path2, {
|
|
72272
72314
|
method: "GET"
|
|
72273
72315
|
})
|
|
72274
72316
|
);
|
|
@@ -72309,8 +72351,8 @@ var init_remote_node_client = __esm({
|
|
|
72309
72351
|
}
|
|
72310
72352
|
yield* this.parseJsonLines(response.body, options?.signal);
|
|
72311
72353
|
}
|
|
72312
|
-
async requestJson(
|
|
72313
|
-
const response = await this.fetchWithTimeout(
|
|
72354
|
+
async requestJson(path2, init) {
|
|
72355
|
+
const response = await this.fetchWithTimeout(path2, {
|
|
72314
72356
|
...init,
|
|
72315
72357
|
headers: {
|
|
72316
72358
|
...this.getAuthHeaders(),
|
|
@@ -72320,20 +72362,20 @@ var init_remote_node_client = __esm({
|
|
|
72320
72362
|
}
|
|
72321
72363
|
});
|
|
72322
72364
|
if (!response.ok) {
|
|
72323
|
-
await this.throwHttpError(
|
|
72365
|
+
await this.throwHttpError(path2, response);
|
|
72324
72366
|
}
|
|
72325
72367
|
try {
|
|
72326
72368
|
return await response.json();
|
|
72327
72369
|
} catch (error) {
|
|
72328
72370
|
throw new RemoteNodeRequestError(
|
|
72329
|
-
`Failed to parse JSON response for ${
|
|
72371
|
+
`Failed to parse JSON response for ${path2}: ${error instanceof Error ? error.message : String(error)}`,
|
|
72330
72372
|
false
|
|
72331
72373
|
);
|
|
72332
72374
|
}
|
|
72333
72375
|
}
|
|
72334
|
-
async openStream(
|
|
72376
|
+
async openStream(path2, signal) {
|
|
72335
72377
|
const response = await this.fetchWithTimeout(
|
|
72336
|
-
|
|
72378
|
+
path2,
|
|
72337
72379
|
{
|
|
72338
72380
|
method: "GET",
|
|
72339
72381
|
headers: {
|
|
@@ -72344,16 +72386,16 @@ var init_remote_node_client = __esm({
|
|
|
72344
72386
|
signal
|
|
72345
72387
|
);
|
|
72346
72388
|
if (!response.ok) {
|
|
72347
|
-
await this.throwHttpError(
|
|
72389
|
+
await this.throwHttpError(path2, response);
|
|
72348
72390
|
}
|
|
72349
72391
|
return response;
|
|
72350
72392
|
}
|
|
72351
|
-
async throwHttpError(
|
|
72393
|
+
async throwHttpError(path2, response) {
|
|
72352
72394
|
const responseBody = (await response.text()).trim();
|
|
72353
72395
|
const snippet = responseBody.length > 0 ? ` \u2014 ${responseBody.slice(0, 300)}` : "";
|
|
72354
72396
|
const retryable = response.status >= 500;
|
|
72355
72397
|
throw new RemoteNodeRequestError(
|
|
72356
|
-
`Remote node request failed (${response.status} ${response.statusText}) for ${
|
|
72398
|
+
`Remote node request failed (${response.status} ${response.statusText}) for ${path2}${snippet}`,
|
|
72357
72399
|
retryable,
|
|
72358
72400
|
response.status
|
|
72359
72401
|
);
|
|
@@ -72363,7 +72405,7 @@ var init_remote_node_client = __esm({
|
|
|
72363
72405
|
Authorization: `Bearer ${this.apiKey}`
|
|
72364
72406
|
};
|
|
72365
72407
|
}
|
|
72366
|
-
async fetchWithTimeout(
|
|
72408
|
+
async fetchWithTimeout(path2, init, externalSignal) {
|
|
72367
72409
|
const controller = new AbortController();
|
|
72368
72410
|
let timedOut = false;
|
|
72369
72411
|
const timeout = setTimeout(() => {
|
|
@@ -72379,7 +72421,7 @@ var init_remote_node_client = __esm({
|
|
|
72379
72421
|
externalSignal.addEventListener("abort", onAbort, { once: true });
|
|
72380
72422
|
}
|
|
72381
72423
|
try {
|
|
72382
|
-
return await fetch(`${this.baseUrl}${
|
|
72424
|
+
return await fetch(`${this.baseUrl}${path2}`, {
|
|
72383
72425
|
...init,
|
|
72384
72426
|
signal: controller.signal
|
|
72385
72427
|
});
|
|
@@ -72389,15 +72431,15 @@ var init_remote_node_client = __esm({
|
|
|
72389
72431
|
}
|
|
72390
72432
|
if (timedOut) {
|
|
72391
72433
|
throw new RemoteNodeRequestError(
|
|
72392
|
-
`Remote node request timed out after ${this.timeoutMs}ms (${
|
|
72434
|
+
`Remote node request timed out after ${this.timeoutMs}ms (${path2})`,
|
|
72393
72435
|
true
|
|
72394
72436
|
);
|
|
72395
72437
|
}
|
|
72396
72438
|
if (error instanceof Error && error.name === "AbortError") {
|
|
72397
|
-
throw new RemoteNodeRequestError(`Remote node request aborted (${
|
|
72439
|
+
throw new RemoteNodeRequestError(`Remote node request aborted (${path2})`, false);
|
|
72398
72440
|
}
|
|
72399
72441
|
throw new RemoteNodeRequestError(
|
|
72400
|
-
`Remote node network error (${
|
|
72442
|
+
`Remote node network error (${path2}): ${error instanceof Error ? error.message : String(error)}`,
|
|
72401
72443
|
true
|
|
72402
72444
|
);
|
|
72403
72445
|
} finally {
|
|
@@ -77350,166 +77392,882 @@ var init_plugin_routes = __esm({
|
|
|
77350
77392
|
}
|
|
77351
77393
|
});
|
|
77352
77394
|
|
|
77353
|
-
// ../
|
|
77354
|
-
|
|
77355
|
-
|
|
77395
|
+
// ../plugin-sdk/src/index.ts
|
|
77396
|
+
function definePlugin(plugin4) {
|
|
77397
|
+
return plugin4;
|
|
77398
|
+
}
|
|
77399
|
+
var init_src3 = __esm({
|
|
77400
|
+
"../plugin-sdk/src/index.ts"() {
|
|
77356
77401
|
"use strict";
|
|
77402
|
+
init_src();
|
|
77357
77403
|
}
|
|
77358
77404
|
});
|
|
77359
77405
|
|
|
77360
|
-
//
|
|
77361
|
-
import {
|
|
77362
|
-
|
|
77363
|
-
|
|
77364
|
-
|
|
77365
|
-
|
|
77366
|
-
|
|
77367
|
-
|
|
77406
|
+
// ../../plugins/fusion-plugin-hermes-runtime/dist/cli-spawn.js
|
|
77407
|
+
import { spawn as spawn4, spawnSync } from "node:child_process";
|
|
77408
|
+
import os2 from "node:os";
|
|
77409
|
+
import path, { sep as PATH_SEP } from "node:path";
|
|
77410
|
+
function resolveBinaryForSpawn(binary) {
|
|
77411
|
+
if (process.platform !== "win32")
|
|
77412
|
+
return binary;
|
|
77413
|
+
if (binary.includes(PATH_SEP) || binary.includes("/") || /\.[a-z]{2,4}$/i.test(binary)) {
|
|
77414
|
+
return binary;
|
|
77368
77415
|
}
|
|
77369
|
-
|
|
77370
|
-
|
|
77371
|
-
|
|
77372
|
-
|
|
77373
|
-
|
|
77374
|
-
|
|
77375
|
-
|
|
77376
|
-
|
|
77416
|
+
const cached = resolvedBinaryCache.get(binary);
|
|
77417
|
+
if (cached)
|
|
77418
|
+
return cached;
|
|
77419
|
+
try {
|
|
77420
|
+
const result = spawnSync("where", [binary], { encoding: "utf-8" });
|
|
77421
|
+
if (result.status === 0) {
|
|
77422
|
+
const first = (result.stdout ?? "").trim().split(/\r?\n/)[0];
|
|
77423
|
+
if (first?.length) {
|
|
77424
|
+
resolvedBinaryCache.set(binary, first);
|
|
77425
|
+
return first;
|
|
77426
|
+
}
|
|
77427
|
+
}
|
|
77428
|
+
} catch {
|
|
77377
77429
|
}
|
|
77378
|
-
|
|
77379
|
-
|
|
77380
|
-
|
|
77381
|
-
|
|
77382
|
-
"
|
|
77383
|
-
|
|
77384
|
-
|
|
77385
|
-
|
|
77430
|
+
return binary;
|
|
77431
|
+
}
|
|
77432
|
+
function hermesProfileHome(profileName) {
|
|
77433
|
+
const base = process.env.HERMES_HOME ?? path.join(os2.homedir(), ".hermes");
|
|
77434
|
+
if (profileName === "default" || profileName === "")
|
|
77435
|
+
return base;
|
|
77436
|
+
return path.join(base, "profiles", profileName);
|
|
77437
|
+
}
|
|
77438
|
+
function resolveCliSettings(settings) {
|
|
77439
|
+
const str = (v) => typeof v === "string" && v.trim().length > 0 ? v.trim() : void 0;
|
|
77440
|
+
const num = (v, envKey, fallback) => {
|
|
77441
|
+
if (typeof v === "number" && Number.isFinite(v) && v > 0)
|
|
77442
|
+
return v;
|
|
77443
|
+
const raw = str(v) ?? str(process.env[envKey]);
|
|
77444
|
+
if (raw !== void 0) {
|
|
77445
|
+
const parsed = Number(raw);
|
|
77446
|
+
if (Number.isFinite(parsed) && parsed > 0)
|
|
77447
|
+
return parsed;
|
|
77448
|
+
}
|
|
77449
|
+
return fallback;
|
|
77450
|
+
};
|
|
77451
|
+
const bool = (v, envKey, fallback) => {
|
|
77452
|
+
if (typeof v === "boolean")
|
|
77453
|
+
return v;
|
|
77454
|
+
const raw = str(v) ?? str(process.env[envKey]);
|
|
77455
|
+
if (raw !== void 0)
|
|
77456
|
+
return raw === "1" || raw.toLowerCase() === "true";
|
|
77457
|
+
return fallback;
|
|
77458
|
+
};
|
|
77459
|
+
return {
|
|
77460
|
+
binaryPath: str(settings?.binaryPath) ?? str(process.env.HERMES_BIN) ?? "hermes",
|
|
77461
|
+
model: str(settings?.model) ?? str(process.env.HERMES_MODEL_ID),
|
|
77462
|
+
provider: str(settings?.provider) ?? str(process.env.HERMES_PROVIDER),
|
|
77463
|
+
maxTurns: num(settings?.maxTurns, "HERMES_MAX_TURNS", 12),
|
|
77464
|
+
yolo: bool(settings?.yolo, "HERMES_YOLO", false),
|
|
77465
|
+
cliTimeoutMs: num(settings?.cliTimeoutMs, "HERMES_CLI_TIMEOUT_MS", 3e5),
|
|
77466
|
+
profile: str(settings?.profile) ?? str(process.env.HERMES_PROFILE)
|
|
77467
|
+
};
|
|
77468
|
+
}
|
|
77469
|
+
function cleanText(raw) {
|
|
77470
|
+
return raw.replace(ANSI_RE, "").replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
77471
|
+
}
|
|
77472
|
+
function stripChrome(text) {
|
|
77473
|
+
const lines = text.split("\n");
|
|
77474
|
+
const filtered = lines.filter((line) => !CHROME_LINE_RES.some((re) => re.test(line)));
|
|
77475
|
+
return filtered.join("\n").trim();
|
|
77476
|
+
}
|
|
77477
|
+
function parseHermesOutput(rawStdout, rawStderr) {
|
|
77478
|
+
const cleaned = cleanText(rawStdout);
|
|
77479
|
+
const match = SESSION_ID_RE.exec(cleaned);
|
|
77480
|
+
if (!match) {
|
|
77481
|
+
const combined = [rawStdout, rawStderr].filter(Boolean).join("\n");
|
|
77482
|
+
throw new Error(`hermes: missing session_id in output.
|
|
77483
|
+
${combined}`);
|
|
77386
77484
|
}
|
|
77387
|
-
|
|
77388
|
-
|
|
77389
|
-
|
|
77390
|
-
|
|
77391
|
-
|
|
77392
|
-
|
|
77393
|
-
|
|
77485
|
+
const sessionId = match[1];
|
|
77486
|
+
const sessionIdLineStart = cleaned.lastIndexOf("\nsession_id:");
|
|
77487
|
+
const bodyRaw = sessionIdLineStart >= 0 ? cleaned.slice(0, sessionIdLineStart) : cleaned;
|
|
77488
|
+
const body = stripChrome(bodyRaw);
|
|
77489
|
+
return { body, sessionId };
|
|
77490
|
+
}
|
|
77491
|
+
function buildHermesArgs(prompt, settings, resumeSessionId) {
|
|
77492
|
+
const args = ["chat", "-q", prompt, "-Q", "--source", "tool"];
|
|
77493
|
+
if (resumeSessionId) {
|
|
77494
|
+
args.push("--resume", resumeSessionId);
|
|
77394
77495
|
}
|
|
77395
|
-
|
|
77396
|
-
|
|
77397
|
-
// ../dashboard/src/routes/register-chat-routes.ts
|
|
77398
|
-
var init_register_chat_routes = __esm({
|
|
77399
|
-
"../dashboard/src/routes/register-chat-routes.ts"() {
|
|
77400
|
-
"use strict";
|
|
77401
|
-
init_api_error();
|
|
77402
|
-
init_rate_limit();
|
|
77403
|
-
init_sse_buffer();
|
|
77496
|
+
if (settings.model) {
|
|
77497
|
+
args.push("-m", settings.model);
|
|
77404
77498
|
}
|
|
77405
|
-
|
|
77406
|
-
|
|
77407
|
-
|
|
77408
|
-
|
|
77409
|
-
|
|
77499
|
+
if (settings.provider) {
|
|
77500
|
+
args.push("--provider", settings.provider);
|
|
77501
|
+
}
|
|
77502
|
+
args.push("--max-turns", String(settings.maxTurns));
|
|
77503
|
+
if (settings.yolo) {
|
|
77504
|
+
args.push("--yolo");
|
|
77505
|
+
}
|
|
77506
|
+
return args;
|
|
77507
|
+
}
|
|
77508
|
+
async function invokeHermesCli(prompt, settings, resumeSessionId, signal) {
|
|
77509
|
+
const args = buildHermesArgs(prompt, settings, resumeSessionId);
|
|
77510
|
+
const binary = resolveBinaryForSpawn(settings.binaryPath);
|
|
77511
|
+
return new Promise((resolve17, reject) => {
|
|
77512
|
+
let settled = false;
|
|
77513
|
+
const spawnEnv = { ...process.env, PYTHONUNBUFFERED: "1" };
|
|
77514
|
+
if (settings.profile) {
|
|
77515
|
+
spawnEnv.HERMES_HOME = hermesProfileHome(settings.profile);
|
|
77516
|
+
}
|
|
77517
|
+
const child = spawn4(binary, args, {
|
|
77518
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
77519
|
+
env: spawnEnv
|
|
77520
|
+
});
|
|
77521
|
+
const hardKillTimer = setTimeout(() => {
|
|
77522
|
+
if (settled)
|
|
77523
|
+
return;
|
|
77524
|
+
settled = true;
|
|
77525
|
+
try {
|
|
77526
|
+
child.kill("SIGKILL");
|
|
77527
|
+
} catch {
|
|
77528
|
+
}
|
|
77529
|
+
reject(new Error(`hermes: process timed out after ${settings.cliTimeoutMs}ms`));
|
|
77530
|
+
}, settings.cliTimeoutMs);
|
|
77531
|
+
const onAbort = () => {
|
|
77532
|
+
if (settled)
|
|
77533
|
+
return;
|
|
77534
|
+
settled = true;
|
|
77535
|
+
clearTimeout(hardKillTimer);
|
|
77536
|
+
try {
|
|
77537
|
+
child.kill("SIGTERM");
|
|
77538
|
+
} catch {
|
|
77539
|
+
}
|
|
77540
|
+
reject(new Error("hermes: invocation aborted"));
|
|
77541
|
+
};
|
|
77542
|
+
if (signal) {
|
|
77543
|
+
if (signal.aborted) {
|
|
77544
|
+
onAbort();
|
|
77545
|
+
return;
|
|
77546
|
+
}
|
|
77547
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
77548
|
+
}
|
|
77549
|
+
let stdout = "";
|
|
77550
|
+
let stderr = "";
|
|
77551
|
+
child.stdout?.on("data", (chunk) => {
|
|
77552
|
+
stdout += chunk.toString("utf-8");
|
|
77553
|
+
});
|
|
77554
|
+
child.stderr?.on("data", (chunk) => {
|
|
77555
|
+
stderr += chunk.toString("utf-8");
|
|
77556
|
+
});
|
|
77557
|
+
child.on("error", (err) => {
|
|
77558
|
+
if (settled)
|
|
77559
|
+
return;
|
|
77560
|
+
settled = true;
|
|
77561
|
+
clearTimeout(hardKillTimer);
|
|
77562
|
+
signal?.removeEventListener("abort", onAbort);
|
|
77563
|
+
const isNotFound = err.code === "ENOENT";
|
|
77564
|
+
reject(new Error(isNotFound ? `hermes: binary not found at "${settings.binaryPath}". Install hermes or set binaryPath/HERMES_BIN.` : `hermes: spawn error \u2014 ${err.message}`));
|
|
77565
|
+
});
|
|
77566
|
+
child.on("close", (code) => {
|
|
77567
|
+
if (settled)
|
|
77568
|
+
return;
|
|
77569
|
+
settled = true;
|
|
77570
|
+
clearTimeout(hardKillTimer);
|
|
77571
|
+
signal?.removeEventListener("abort", onAbort);
|
|
77572
|
+
if (code !== 0) {
|
|
77573
|
+
const combined = [stdout, stderr].filter(Boolean).join("\n");
|
|
77574
|
+
reject(new Error(`hermes: process exited with code ${String(code)}.
|
|
77575
|
+
${combined}`));
|
|
77576
|
+
return;
|
|
77577
|
+
}
|
|
77578
|
+
try {
|
|
77579
|
+
resolve17(parseHermesOutput(stdout, stderr));
|
|
77580
|
+
} catch (parseErr) {
|
|
77581
|
+
reject(parseErr);
|
|
77582
|
+
}
|
|
77583
|
+
});
|
|
77584
|
+
});
|
|
77585
|
+
}
|
|
77586
|
+
var resolvedBinaryCache, ANSI_RE, SESSION_ID_RE, CHROME_LINE_RES;
|
|
77587
|
+
var init_cli_spawn = __esm({
|
|
77588
|
+
"../../plugins/fusion-plugin-hermes-runtime/dist/cli-spawn.js"() {
|
|
77410
77589
|
"use strict";
|
|
77590
|
+
resolvedBinaryCache = /* @__PURE__ */ new Map();
|
|
77591
|
+
ANSI_RE = /\x1b\[[0-9;]*[A-Za-z]/g;
|
|
77592
|
+
SESSION_ID_RE = /^session_id:\s+([0-9]{8}_[0-9]{6}_[0-9a-f]{6})\s*$/m;
|
|
77593
|
+
CHROME_LINE_RES = [
|
|
77594
|
+
/^\s*┊\s/,
|
|
77595
|
+
// memory/status sidebar lines
|
|
77596
|
+
/^↻ Resumed session /,
|
|
77597
|
+
// resume banner
|
|
77598
|
+
/^╭─.*╮\s*$/,
|
|
77599
|
+
// top box border
|
|
77600
|
+
/^╰─.*╯\s*$/,
|
|
77601
|
+
// bottom box border
|
|
77602
|
+
/^Query:\s*/
|
|
77603
|
+
// query echo line
|
|
77604
|
+
];
|
|
77411
77605
|
}
|
|
77412
77606
|
});
|
|
77413
77607
|
|
|
77414
|
-
//
|
|
77415
|
-
var
|
|
77416
|
-
|
|
77608
|
+
// ../../plugins/fusion-plugin-hermes-runtime/dist/runtime-adapter.js
|
|
77609
|
+
var HermesRuntimeAdapter;
|
|
77610
|
+
var init_runtime_adapter = __esm({
|
|
77611
|
+
"../../plugins/fusion-plugin-hermes-runtime/dist/runtime-adapter.js"() {
|
|
77417
77612
|
"use strict";
|
|
77418
|
-
|
|
77419
|
-
|
|
77420
|
-
|
|
77421
|
-
|
|
77613
|
+
init_cli_spawn();
|
|
77614
|
+
HermesRuntimeAdapter = class {
|
|
77615
|
+
id = "hermes";
|
|
77616
|
+
name = "Hermes Runtime";
|
|
77617
|
+
settings;
|
|
77618
|
+
constructor(settings) {
|
|
77619
|
+
this.settings = resolveCliSettings(settings);
|
|
77620
|
+
}
|
|
77621
|
+
async createSession(options) {
|
|
77622
|
+
const session = {
|
|
77623
|
+
model: void 0,
|
|
77624
|
+
systemPrompt: options.systemPrompt,
|
|
77625
|
+
messages: [],
|
|
77626
|
+
apiKey: void 0,
|
|
77627
|
+
thinkingLevel: void 0,
|
|
77628
|
+
sessionId: "",
|
|
77629
|
+
lastModelDescription: this.describeFromSettings(),
|
|
77630
|
+
callbacks: {
|
|
77631
|
+
onText: options.onText,
|
|
77632
|
+
onThinking: options.onThinking,
|
|
77633
|
+
onToolStart: options.onToolStart,
|
|
77634
|
+
onToolEnd: options.onToolEnd
|
|
77635
|
+
},
|
|
77636
|
+
dispose: () => void 0
|
|
77637
|
+
};
|
|
77638
|
+
return { session, sessionFile: void 0 };
|
|
77639
|
+
}
|
|
77640
|
+
async promptWithFallback(session, prompt, _options) {
|
|
77641
|
+
const resumeId = session.sessionId || void 0;
|
|
77642
|
+
const result = await invokeHermesCli(prompt, this.settings, resumeId);
|
|
77643
|
+
session.sessionId = result.sessionId;
|
|
77644
|
+
session.lastModelDescription = this.describeFromSettings();
|
|
77645
|
+
if (result.body) {
|
|
77646
|
+
session.callbacks.onText?.(result.body);
|
|
77647
|
+
}
|
|
77648
|
+
}
|
|
77649
|
+
describeModel(session) {
|
|
77650
|
+
return session.lastModelDescription || this.describeFromSettings();
|
|
77651
|
+
}
|
|
77652
|
+
async dispose(_session) {
|
|
77653
|
+
}
|
|
77654
|
+
describeFromSettings() {
|
|
77655
|
+
const provider = this.settings.provider;
|
|
77656
|
+
const model = this.settings.model;
|
|
77657
|
+
if (provider && model)
|
|
77658
|
+
return `hermes/${provider}/${model}`;
|
|
77659
|
+
if (model)
|
|
77660
|
+
return `hermes/${model}`;
|
|
77661
|
+
if (provider)
|
|
77662
|
+
return `hermes/${provider}`;
|
|
77663
|
+
return "hermes";
|
|
77664
|
+
}
|
|
77665
|
+
};
|
|
77422
77666
|
}
|
|
77423
77667
|
});
|
|
77424
77668
|
|
|
77425
|
-
//
|
|
77426
|
-
|
|
77427
|
-
|
|
77428
|
-
var init_terminal_service = __esm({
|
|
77429
|
-
"../dashboard/src/terminal-service.ts"() {
|
|
77669
|
+
// ../../plugins/fusion-plugin-hermes-runtime/dist/probe.js
|
|
77670
|
+
var init_probe = __esm({
|
|
77671
|
+
"../../plugins/fusion-plugin-hermes-runtime/dist/probe.js"() {
|
|
77430
77672
|
"use strict";
|
|
77431
|
-
isBunBinary = typeof Bun !== "undefined" && !!Bun.embeddedFiles;
|
|
77432
|
-
require2 = createRequire3(import.meta.url);
|
|
77433
77673
|
}
|
|
77434
77674
|
});
|
|
77435
77675
|
|
|
77436
|
-
//
|
|
77437
|
-
var
|
|
77438
|
-
|
|
77676
|
+
// ../../plugins/fusion-plugin-hermes-runtime/dist/index.js
|
|
77677
|
+
var HERMES_RUNTIME_ID, HERMES_RUNTIME_VERSION, hermesRuntimeMetadata, hermesRuntimeFactory, plugin;
|
|
77678
|
+
var init_dist = __esm({
|
|
77679
|
+
"../../plugins/fusion-plugin-hermes-runtime/dist/index.js"() {
|
|
77439
77680
|
"use strict";
|
|
77440
|
-
|
|
77441
|
-
|
|
77442
|
-
|
|
77681
|
+
init_src3();
|
|
77682
|
+
init_cli_spawn();
|
|
77683
|
+
init_runtime_adapter();
|
|
77684
|
+
init_runtime_adapter();
|
|
77685
|
+
init_cli_spawn();
|
|
77686
|
+
init_probe();
|
|
77687
|
+
HERMES_RUNTIME_ID = "hermes";
|
|
77688
|
+
HERMES_RUNTIME_VERSION = "0.2.0";
|
|
77689
|
+
hermesRuntimeMetadata = {
|
|
77690
|
+
runtimeId: HERMES_RUNTIME_ID,
|
|
77691
|
+
name: "Hermes Runtime",
|
|
77692
|
+
description: "Drives the local `hermes` CLI (NousResearch/hermes-agent)",
|
|
77693
|
+
version: HERMES_RUNTIME_VERSION
|
|
77694
|
+
};
|
|
77695
|
+
hermesRuntimeFactory = async (ctx) => {
|
|
77696
|
+
return new HermesRuntimeAdapter(ctx.settings);
|
|
77697
|
+
};
|
|
77698
|
+
plugin = definePlugin({
|
|
77699
|
+
manifest: {
|
|
77700
|
+
id: "fusion-plugin-hermes-runtime",
|
|
77701
|
+
name: "Hermes Runtime Plugin",
|
|
77702
|
+
version: HERMES_RUNTIME_VERSION,
|
|
77703
|
+
description: "Drives the local `hermes` CLI for Fusion agents \u2014 captures session ids and resumes via --resume.",
|
|
77704
|
+
author: "Fusion Team",
|
|
77705
|
+
homepage: "https://github.com/NousResearch/hermes-agent",
|
|
77706
|
+
runtime: hermesRuntimeMetadata
|
|
77707
|
+
},
|
|
77708
|
+
state: "installed",
|
|
77709
|
+
hooks: {
|
|
77710
|
+
onLoad: (ctx) => {
|
|
77711
|
+
const settings = resolveCliSettings(ctx.settings);
|
|
77712
|
+
ctx.logger.info(`Hermes Runtime Plugin loaded \u2014 binary=${settings.binaryPath} model=${settings.model ?? "(default)"}`);
|
|
77713
|
+
ctx.emitEvent("hermes-runtime:loaded", {
|
|
77714
|
+
runtimeId: HERMES_RUNTIME_ID,
|
|
77715
|
+
version: HERMES_RUNTIME_VERSION
|
|
77716
|
+
});
|
|
77717
|
+
},
|
|
77718
|
+
onUnload: () => {
|
|
77719
|
+
}
|
|
77720
|
+
},
|
|
77721
|
+
runtime: {
|
|
77722
|
+
metadata: hermesRuntimeMetadata,
|
|
77723
|
+
factory: hermesRuntimeFactory
|
|
77724
|
+
}
|
|
77725
|
+
});
|
|
77443
77726
|
}
|
|
77444
77727
|
});
|
|
77445
77728
|
|
|
77446
|
-
//
|
|
77447
|
-
|
|
77448
|
-
|
|
77729
|
+
// ../../plugins/fusion-plugin-openclaw-runtime/dist/pi-module.js
|
|
77730
|
+
import { spawn as spawn5 } from "node:child_process";
|
|
77731
|
+
import { randomUUID as randomUUID11 } from "node:crypto";
|
|
77732
|
+
function asString(v) {
|
|
77733
|
+
return typeof v === "string" && v.trim() !== "" ? v.trim() : void 0;
|
|
77449
77734
|
}
|
|
77450
|
-
function
|
|
77451
|
-
|
|
77452
|
-
|
|
77453
|
-
|
|
77454
|
-
|
|
77455
|
-
|
|
77456
|
-
|
|
77457
|
-
|
|
77458
|
-
return "pending";
|
|
77459
|
-
case "failure":
|
|
77460
|
-
case "failed":
|
|
77461
|
-
case "error":
|
|
77462
|
-
return "failure";
|
|
77463
|
-
case "cancelled":
|
|
77464
|
-
return "cancelled";
|
|
77465
|
-
case "timed_out":
|
|
77466
|
-
return "timed_out";
|
|
77467
|
-
case "action_required":
|
|
77468
|
-
return "action_required";
|
|
77469
|
-
case "neutral":
|
|
77470
|
-
return "neutral";
|
|
77471
|
-
case "skipped":
|
|
77472
|
-
return "skipped";
|
|
77473
|
-
case "stale":
|
|
77474
|
-
return "stale";
|
|
77475
|
-
case "startup_failure":
|
|
77476
|
-
return "startup_failure";
|
|
77477
|
-
default:
|
|
77478
|
-
return "failure";
|
|
77479
|
-
}
|
|
77735
|
+
function asNumber(v) {
|
|
77736
|
+
if (typeof v === "number" && Number.isFinite(v))
|
|
77737
|
+
return v;
|
|
77738
|
+
const s = asString(v);
|
|
77739
|
+
if (s === void 0)
|
|
77740
|
+
return void 0;
|
|
77741
|
+
const n = Number(s);
|
|
77742
|
+
return Number.isFinite(n) ? n : void 0;
|
|
77480
77743
|
}
|
|
77481
|
-
function
|
|
77744
|
+
function asBool(v) {
|
|
77745
|
+
if (typeof v === "boolean")
|
|
77746
|
+
return v;
|
|
77747
|
+
const s = asString(v);
|
|
77748
|
+
if (s === void 0)
|
|
77749
|
+
return void 0;
|
|
77750
|
+
return s === "1" || s.toLowerCase() === "true";
|
|
77751
|
+
}
|
|
77752
|
+
function stripAnsi(text) {
|
|
77753
|
+
return text.replace(ANSI_RE2, "");
|
|
77754
|
+
}
|
|
77755
|
+
function resolveCliConfig(settings) {
|
|
77482
77756
|
return {
|
|
77483
|
-
|
|
77484
|
-
|
|
77485
|
-
|
|
77486
|
-
|
|
77487
|
-
|
|
77488
|
-
|
|
77489
|
-
|
|
77490
|
-
lastCommentAt: input.lastCommentAt,
|
|
77491
|
-
lastCheckedAt: input.lastCheckedAt
|
|
77757
|
+
binaryPath: asString(settings?.binaryPath) ?? asString(process.env.OPENCLAW_BIN) ?? DEFAULT_BINARY,
|
|
77758
|
+
agentId: asString(settings?.agentId) ?? asString(process.env.OPENCLAW_AGENT_ID) ?? DEFAULT_AGENT_ID,
|
|
77759
|
+
model: asString(settings?.model) ?? asString(process.env.OPENCLAW_MODEL),
|
|
77760
|
+
thinking: asString(settings?.thinking) ?? asString(process.env.OPENCLAW_THINKING) ?? DEFAULT_THINKING,
|
|
77761
|
+
cliTimeoutSec: asNumber(settings?.cliTimeoutSec) ?? asNumber(process.env.OPENCLAW_TIMEOUT_SEC) ?? DEFAULT_TIMEOUT_SEC,
|
|
77762
|
+
cliTimeoutMs: asNumber(settings?.cliTimeoutMs) ?? asNumber(process.env.OPENCLAW_CLI_TIMEOUT_MS) ?? DEFAULT_CLI_TIMEOUT_MS,
|
|
77763
|
+
useGateway: asBool(settings?.useGateway) ?? asBool(process.env.OPENCLAW_USE_GATEWAY) ?? false
|
|
77492
77764
|
};
|
|
77493
77765
|
}
|
|
77494
|
-
function
|
|
77495
|
-
const
|
|
77496
|
-
if (
|
|
77497
|
-
|
|
77498
|
-
|
|
77499
|
-
|
|
77500
|
-
|
|
77501
|
-
|
|
77502
|
-
|
|
77503
|
-
(
|
|
77504
|
-
);
|
|
77505
|
-
if (blockingChecks.length > 0) {
|
|
77506
|
-
blockingReasons.push(
|
|
77507
|
-
`required checks not successful: ${blockingChecks.map((check) => `${check.name} (${check.state})`).join(", ")}`
|
|
77508
|
-
);
|
|
77766
|
+
function buildOpenClawArgs(config, sessionId, message) {
|
|
77767
|
+
const args = ["--no-color", "agent"];
|
|
77768
|
+
if (!config.useGateway)
|
|
77769
|
+
args.push("--local");
|
|
77770
|
+
args.push("--json");
|
|
77771
|
+
args.push("--session-id", sessionId);
|
|
77772
|
+
args.push("--message", message);
|
|
77773
|
+
args.push("--agent", config.agentId);
|
|
77774
|
+
if (config.model) {
|
|
77775
|
+
args.push("--model", config.model);
|
|
77509
77776
|
}
|
|
77777
|
+
args.push("--thinking", config.thinking);
|
|
77778
|
+
args.push("--timeout", String(config.cliTimeoutSec));
|
|
77779
|
+
return args;
|
|
77780
|
+
}
|
|
77781
|
+
function extractStderrError(stderr, stdout) {
|
|
77782
|
+
const tryExtract = (raw) => {
|
|
77783
|
+
if (!raw)
|
|
77784
|
+
return void 0;
|
|
77785
|
+
const lines = stripAnsi(raw).split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
|
|
77786
|
+
return lines.length > 0 ? lines[lines.length - 1] : void 0;
|
|
77787
|
+
};
|
|
77788
|
+
return tryExtract(stderr) ?? tryExtract(stdout ?? "") ?? "openclaw exited with non-zero status (no stderr)";
|
|
77789
|
+
}
|
|
77790
|
+
function createCliSession(opts) {
|
|
77510
77791
|
return {
|
|
77511
|
-
|
|
77512
|
-
|
|
77792
|
+
sessionId: randomUUID11(),
|
|
77793
|
+
agentId: opts.agentId ?? DEFAULT_AGENT_ID,
|
|
77794
|
+
systemPrompt: opts.systemPrompt,
|
|
77795
|
+
messages: [{ role: "developer", content: opts.systemPrompt }],
|
|
77796
|
+
lastModelDescription: `openclaw/${opts.agentId ?? DEFAULT_AGENT_ID}`,
|
|
77797
|
+
lastUsage: void 0,
|
|
77798
|
+
callbacks: opts.callbacks
|
|
77799
|
+
};
|
|
77800
|
+
}
|
|
77801
|
+
async function promptCli(session, message, config, callbacks, signal) {
|
|
77802
|
+
const args = buildOpenClawArgs(config, session.sessionId, message);
|
|
77803
|
+
const cb = { ...session.callbacks, ...callbacks };
|
|
77804
|
+
cb.onToolStart?.("openclaw.agent", { sessionId: session.sessionId });
|
|
77805
|
+
return new Promise((resolve17, reject) => {
|
|
77806
|
+
let settled = false;
|
|
77807
|
+
const child = spawn5(config.binaryPath, args, {
|
|
77808
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
77809
|
+
});
|
|
77810
|
+
const hardKill = setTimeout(() => {
|
|
77811
|
+
if (settled)
|
|
77812
|
+
return;
|
|
77813
|
+
settled = true;
|
|
77814
|
+
try {
|
|
77815
|
+
child.kill("SIGKILL");
|
|
77816
|
+
} catch {
|
|
77817
|
+
}
|
|
77818
|
+
reject(new Error(`openclaw: process timed out after ${config.cliTimeoutMs}ms`));
|
|
77819
|
+
}, config.cliTimeoutMs);
|
|
77820
|
+
const onAbort = () => {
|
|
77821
|
+
if (settled)
|
|
77822
|
+
return;
|
|
77823
|
+
try {
|
|
77824
|
+
child.kill("SIGTERM");
|
|
77825
|
+
} catch {
|
|
77826
|
+
}
|
|
77827
|
+
};
|
|
77828
|
+
if (signal) {
|
|
77829
|
+
if (signal.aborted) {
|
|
77830
|
+
onAbort();
|
|
77831
|
+
} else {
|
|
77832
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
77833
|
+
}
|
|
77834
|
+
}
|
|
77835
|
+
let stdout = "";
|
|
77836
|
+
let stderr = "";
|
|
77837
|
+
child.stdout?.on("data", (chunk) => {
|
|
77838
|
+
stdout += chunk.toString("utf-8");
|
|
77839
|
+
});
|
|
77840
|
+
child.stderr?.on("data", (chunk) => {
|
|
77841
|
+
stderr += chunk.toString("utf-8");
|
|
77842
|
+
});
|
|
77843
|
+
child.on("error", (err) => {
|
|
77844
|
+
if (settled)
|
|
77845
|
+
return;
|
|
77846
|
+
settled = true;
|
|
77847
|
+
clearTimeout(hardKill);
|
|
77848
|
+
signal?.removeEventListener("abort", onAbort);
|
|
77849
|
+
const isNotFound = err.code === "ENOENT";
|
|
77850
|
+
reject(new Error(isNotFound ? `openclaw: binary not found at "${config.binaryPath}". Install OpenClaw (npm i -g openclaw) or set binaryPath/OPENCLAW_BIN.` : `openclaw: spawn error \u2014 ${err.message}`));
|
|
77851
|
+
});
|
|
77852
|
+
child.on("close", (code) => {
|
|
77853
|
+
if (settled)
|
|
77854
|
+
return;
|
|
77855
|
+
settled = true;
|
|
77856
|
+
clearTimeout(hardKill);
|
|
77857
|
+
signal?.removeEventListener("abort", onAbort);
|
|
77858
|
+
if (code !== 0) {
|
|
77859
|
+
const err = stderr.trim() || stdout.trim() ? extractStderrError(stderr, stdout) : `openclaw: exited with code ${String(code)}`;
|
|
77860
|
+
reject(new Error(err));
|
|
77861
|
+
return;
|
|
77862
|
+
}
|
|
77863
|
+
let parsed;
|
|
77864
|
+
try {
|
|
77865
|
+
parsed = JSON.parse(stdout);
|
|
77866
|
+
} catch {
|
|
77867
|
+
reject(new Error(`openclaw: failed to parse JSON output (stdout=${stdout.slice(0, 200)})`));
|
|
77868
|
+
return;
|
|
77869
|
+
}
|
|
77870
|
+
const payloads = parsed.payloads ?? [];
|
|
77871
|
+
const visibleText = payloads.filter((p) => !p.isError && !p.isReasoning).map((p) => p.text ?? "").filter((t) => t.length > 0).join("");
|
|
77872
|
+
const reasoningText = payloads.filter((p) => p.isReasoning).map((p) => p.text ?? "").filter((t) => t.length > 0).join("\n");
|
|
77873
|
+
const errorText = payloads.filter((p) => p.isError).map((p) => p.text ?? "").filter((t) => t.length > 0);
|
|
77874
|
+
const finalText = visibleText || parsed.meta?.finalAssistantVisibleText || "";
|
|
77875
|
+
if (finalText)
|
|
77876
|
+
cb.onText?.(finalText);
|
|
77877
|
+
if (reasoningText)
|
|
77878
|
+
cb.onThinking?.(reasoningText);
|
|
77879
|
+
session.messages.push({ role: "user", content: message });
|
|
77880
|
+
if (finalText) {
|
|
77881
|
+
session.messages.push({ role: "assistant", content: finalText });
|
|
77882
|
+
}
|
|
77883
|
+
const agentMeta = parsed.meta?.agentMeta;
|
|
77884
|
+
if (agentMeta?.usage)
|
|
77885
|
+
session.lastUsage = agentMeta.usage;
|
|
77886
|
+
if (agentMeta?.provider && agentMeta.model) {
|
|
77887
|
+
session.lastModelDescription = `openclaw/${session.agentId}/${agentMeta.provider}/${agentMeta.model}`;
|
|
77888
|
+
}
|
|
77889
|
+
const metaError = parsed.meta?.error;
|
|
77890
|
+
const isError = !!metaError;
|
|
77891
|
+
cb.onToolEnd?.("openclaw.agent", isError, {
|
|
77892
|
+
usage: agentMeta?.usage,
|
|
77893
|
+
provider: agentMeta?.provider,
|
|
77894
|
+
model: agentMeta?.model,
|
|
77895
|
+
...metaError ? { error: metaError } : {},
|
|
77896
|
+
...errorText.length > 0 ? { toolErrors: errorText } : {}
|
|
77897
|
+
});
|
|
77898
|
+
resolve17();
|
|
77899
|
+
});
|
|
77900
|
+
});
|
|
77901
|
+
}
|
|
77902
|
+
function describeCliModel(session) {
|
|
77903
|
+
return session.lastModelDescription || `openclaw/${session.agentId}`;
|
|
77904
|
+
}
|
|
77905
|
+
var DEFAULT_BINARY, DEFAULT_AGENT_ID, DEFAULT_THINKING, DEFAULT_TIMEOUT_SEC, DEFAULT_CLI_TIMEOUT_MS, ANSI_RE2;
|
|
77906
|
+
var init_pi_module = __esm({
|
|
77907
|
+
"../../plugins/fusion-plugin-openclaw-runtime/dist/pi-module.js"() {
|
|
77908
|
+
"use strict";
|
|
77909
|
+
DEFAULT_BINARY = "openclaw";
|
|
77910
|
+
DEFAULT_AGENT_ID = "main";
|
|
77911
|
+
DEFAULT_THINKING = "off";
|
|
77912
|
+
DEFAULT_TIMEOUT_SEC = 0;
|
|
77913
|
+
DEFAULT_CLI_TIMEOUT_MS = 3e5;
|
|
77914
|
+
ANSI_RE2 = /\x1b\[[0-9;]*[A-Za-z]/g;
|
|
77915
|
+
}
|
|
77916
|
+
});
|
|
77917
|
+
|
|
77918
|
+
// ../../plugins/fusion-plugin-openclaw-runtime/dist/runtime-adapter.js
|
|
77919
|
+
var OpenClawRuntimeAdapter;
|
|
77920
|
+
var init_runtime_adapter2 = __esm({
|
|
77921
|
+
"../../plugins/fusion-plugin-openclaw-runtime/dist/runtime-adapter.js"() {
|
|
77922
|
+
"use strict";
|
|
77923
|
+
init_pi_module();
|
|
77924
|
+
OpenClawRuntimeAdapter = class {
|
|
77925
|
+
id = "openclaw";
|
|
77926
|
+
name = "OpenClaw Runtime";
|
|
77927
|
+
config;
|
|
77928
|
+
constructor(settings) {
|
|
77929
|
+
this.config = resolveCliConfig(settings);
|
|
77930
|
+
}
|
|
77931
|
+
async createSession(options) {
|
|
77932
|
+
const session = createCliSession({
|
|
77933
|
+
systemPrompt: options.systemPrompt,
|
|
77934
|
+
agentId: this.config.agentId,
|
|
77935
|
+
callbacks: {
|
|
77936
|
+
onText: options.onText,
|
|
77937
|
+
onThinking: options.onThinking,
|
|
77938
|
+
onToolStart: options.onToolStart,
|
|
77939
|
+
onToolEnd: options.onToolEnd
|
|
77940
|
+
}
|
|
77941
|
+
});
|
|
77942
|
+
return { session, sessionFile: void 0 };
|
|
77943
|
+
}
|
|
77944
|
+
async promptWithFallback(session, prompt, options) {
|
|
77945
|
+
const overrideCallbacks = options ?? void 0;
|
|
77946
|
+
await promptCli(session, prompt, this.config, overrideCallbacks);
|
|
77947
|
+
}
|
|
77948
|
+
describeModel(session) {
|
|
77949
|
+
return describeCliModel(session);
|
|
77950
|
+
}
|
|
77951
|
+
async dispose(_session) {
|
|
77952
|
+
}
|
|
77953
|
+
};
|
|
77954
|
+
}
|
|
77955
|
+
});
|
|
77956
|
+
|
|
77957
|
+
// ../../plugins/fusion-plugin-openclaw-runtime/dist/probe.js
|
|
77958
|
+
import { spawn as spawn6 } from "node:child_process";
|
|
77959
|
+
async function probeOpenClawBinary(opts = {}) {
|
|
77960
|
+
const startedAt = Date.now();
|
|
77961
|
+
const binary = opts.binaryPath ?? "openclaw";
|
|
77962
|
+
const timeoutMs = opts.timeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
|
|
77963
|
+
const resolvedPath = await tryResolveBinaryPath(binary);
|
|
77964
|
+
return new Promise((resolvePromise) => {
|
|
77965
|
+
const finish = (partial) => {
|
|
77966
|
+
resolvePromise({ ...partial, probeDurationMs: Date.now() - startedAt });
|
|
77967
|
+
};
|
|
77968
|
+
let settled = false;
|
|
77969
|
+
const child = spawn6(resolvedPath ?? binary, ["--version"], {
|
|
77970
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
77971
|
+
});
|
|
77972
|
+
const timer = setTimeout(() => {
|
|
77973
|
+
if (settled)
|
|
77974
|
+
return;
|
|
77975
|
+
settled = true;
|
|
77976
|
+
try {
|
|
77977
|
+
child.kill("SIGKILL");
|
|
77978
|
+
} catch {
|
|
77979
|
+
}
|
|
77980
|
+
finish({
|
|
77981
|
+
available: false,
|
|
77982
|
+
binaryPath: resolvedPath,
|
|
77983
|
+
reason: `Probe timed out after ${timeoutMs}ms`
|
|
77984
|
+
});
|
|
77985
|
+
}, timeoutMs);
|
|
77986
|
+
let stdout = "";
|
|
77987
|
+
let stderr = "";
|
|
77988
|
+
child.stdout?.on("data", (chunk) => {
|
|
77989
|
+
stdout += chunk.toString("utf-8");
|
|
77990
|
+
});
|
|
77991
|
+
child.stderr?.on("data", (chunk) => {
|
|
77992
|
+
stderr += chunk.toString("utf-8");
|
|
77993
|
+
});
|
|
77994
|
+
child.on("error", (err) => {
|
|
77995
|
+
if (settled)
|
|
77996
|
+
return;
|
|
77997
|
+
settled = true;
|
|
77998
|
+
clearTimeout(timer);
|
|
77999
|
+
const isNotFound = err.code === "ENOENT";
|
|
78000
|
+
finish({
|
|
78001
|
+
available: false,
|
|
78002
|
+
binaryPath: resolvedPath,
|
|
78003
|
+
reason: isNotFound ? `\`${binary}\` not found on PATH \u2014 install via: npm install -g openclaw` : err.message
|
|
78004
|
+
});
|
|
78005
|
+
});
|
|
78006
|
+
child.on("close", (code) => {
|
|
78007
|
+
if (settled)
|
|
78008
|
+
return;
|
|
78009
|
+
settled = true;
|
|
78010
|
+
clearTimeout(timer);
|
|
78011
|
+
if (code === 0) {
|
|
78012
|
+
finish({
|
|
78013
|
+
available: true,
|
|
78014
|
+
binaryPath: resolvedPath,
|
|
78015
|
+
version: stdout.trim() || void 0
|
|
78016
|
+
});
|
|
78017
|
+
} else {
|
|
78018
|
+
finish({
|
|
78019
|
+
available: false,
|
|
78020
|
+
binaryPath: resolvedPath,
|
|
78021
|
+
reason: stderr.trim() || `openclaw --version exited with code ${String(code)}`
|
|
78022
|
+
});
|
|
78023
|
+
}
|
|
78024
|
+
});
|
|
78025
|
+
});
|
|
78026
|
+
}
|
|
78027
|
+
async function tryResolveBinaryPath(binary) {
|
|
78028
|
+
return new Promise((resolvePromise) => {
|
|
78029
|
+
const which = process.platform === "win32" ? "where" : "which";
|
|
78030
|
+
const child = spawn6(which, [binary], { stdio: ["ignore", "pipe", "ignore"] });
|
|
78031
|
+
let out = "";
|
|
78032
|
+
child.stdout?.on("data", (chunk) => {
|
|
78033
|
+
out += chunk.toString("utf-8");
|
|
78034
|
+
});
|
|
78035
|
+
child.on("error", () => resolvePromise(void 0));
|
|
78036
|
+
child.on("close", (code) => {
|
|
78037
|
+
if (code === 0) {
|
|
78038
|
+
const first = out.trim().split(/\r?\n/)[0];
|
|
78039
|
+
resolvePromise(first?.length ? first : void 0);
|
|
78040
|
+
} else {
|
|
78041
|
+
resolvePromise(void 0);
|
|
78042
|
+
}
|
|
78043
|
+
});
|
|
78044
|
+
});
|
|
78045
|
+
}
|
|
78046
|
+
var DEFAULT_PROBE_TIMEOUT_MS;
|
|
78047
|
+
var init_probe2 = __esm({
|
|
78048
|
+
"../../plugins/fusion-plugin-openclaw-runtime/dist/probe.js"() {
|
|
78049
|
+
"use strict";
|
|
78050
|
+
DEFAULT_PROBE_TIMEOUT_MS = 2e3;
|
|
78051
|
+
}
|
|
78052
|
+
});
|
|
78053
|
+
|
|
78054
|
+
// ../../plugins/fusion-plugin-openclaw-runtime/dist/index.js
|
|
78055
|
+
var OPENCLAW_RUNTIME_ID, OPENCLAW_RUNTIME_VERSION, openclawRuntimeMetadata, openclawRuntimeFactory, plugin2;
|
|
78056
|
+
var init_dist2 = __esm({
|
|
78057
|
+
"../../plugins/fusion-plugin-openclaw-runtime/dist/index.js"() {
|
|
78058
|
+
"use strict";
|
|
78059
|
+
init_src3();
|
|
78060
|
+
init_runtime_adapter2();
|
|
78061
|
+
init_pi_module();
|
|
78062
|
+
init_probe2();
|
|
78063
|
+
init_runtime_adapter2();
|
|
78064
|
+
init_pi_module();
|
|
78065
|
+
init_probe2();
|
|
78066
|
+
OPENCLAW_RUNTIME_ID = "openclaw";
|
|
78067
|
+
OPENCLAW_RUNTIME_VERSION = "0.2.0";
|
|
78068
|
+
openclawRuntimeMetadata = {
|
|
78069
|
+
runtimeId: OPENCLAW_RUNTIME_ID,
|
|
78070
|
+
name: "OpenClaw Runtime",
|
|
78071
|
+
description: "Drives the local `openclaw` CLI (openclaw/openclaw)",
|
|
78072
|
+
version: OPENCLAW_RUNTIME_VERSION
|
|
78073
|
+
};
|
|
78074
|
+
openclawRuntimeFactory = async (ctx) => {
|
|
78075
|
+
return new OpenClawRuntimeAdapter(ctx?.settings);
|
|
78076
|
+
};
|
|
78077
|
+
plugin2 = definePlugin({
|
|
78078
|
+
manifest: {
|
|
78079
|
+
id: "fusion-plugin-openclaw-runtime",
|
|
78080
|
+
name: "OpenClaw Runtime Plugin",
|
|
78081
|
+
version: OPENCLAW_RUNTIME_VERSION,
|
|
78082
|
+
description: "Drives the local `openclaw` CLI for Fusion agents \u2014 embedded `--local` mode by default; gateway optional.",
|
|
78083
|
+
author: "Fusion Team",
|
|
78084
|
+
homepage: "https://docs.openclaw.ai/",
|
|
78085
|
+
runtime: openclawRuntimeMetadata
|
|
78086
|
+
},
|
|
78087
|
+
state: "installed",
|
|
78088
|
+
hooks: {
|
|
78089
|
+
onLoad: async (ctx) => {
|
|
78090
|
+
const config = resolveCliConfig(ctx.settings);
|
|
78091
|
+
const probe = await probeOpenClawBinary({ binaryPath: config.binaryPath });
|
|
78092
|
+
ctx.logger.info(probe.available ? `OpenClaw Runtime Plugin loaded \u2014 binary=${config.binaryPath}${probe.version ? ` (${probe.version})` : ""}` : `OpenClaw Runtime Plugin loaded but binary not detected: ${probe.reason ?? "unknown"}`);
|
|
78093
|
+
ctx.emitEvent("openclaw-runtime:loaded", {
|
|
78094
|
+
runtimeId: OPENCLAW_RUNTIME_ID,
|
|
78095
|
+
version: OPENCLAW_RUNTIME_VERSION,
|
|
78096
|
+
binaryAvailable: probe.available,
|
|
78097
|
+
binaryPath: probe.binaryPath ?? config.binaryPath
|
|
78098
|
+
});
|
|
78099
|
+
},
|
|
78100
|
+
onUnload: () => {
|
|
78101
|
+
}
|
|
78102
|
+
},
|
|
78103
|
+
runtime: {
|
|
78104
|
+
metadata: openclawRuntimeMetadata,
|
|
78105
|
+
factory: openclawRuntimeFactory
|
|
78106
|
+
}
|
|
78107
|
+
});
|
|
78108
|
+
}
|
|
78109
|
+
});
|
|
78110
|
+
|
|
78111
|
+
// ../dashboard/src/project-store-resolver.ts
|
|
78112
|
+
var init_project_store_resolver = __esm({
|
|
78113
|
+
"../dashboard/src/project-store-resolver.ts"() {
|
|
78114
|
+
"use strict";
|
|
78115
|
+
}
|
|
78116
|
+
});
|
|
78117
|
+
|
|
78118
|
+
// ../dashboard/src/routes/context.ts
|
|
78119
|
+
import { Router as Router2 } from "express";
|
|
78120
|
+
var init_context = __esm({
|
|
78121
|
+
"../dashboard/src/routes/context.ts"() {
|
|
78122
|
+
"use strict";
|
|
78123
|
+
init_api_error();
|
|
78124
|
+
init_project_store_resolver();
|
|
78125
|
+
init_runtime_logger();
|
|
78126
|
+
}
|
|
78127
|
+
});
|
|
78128
|
+
|
|
78129
|
+
// ../dashboard/src/routes/register-task-workflow-routes.ts
|
|
78130
|
+
var init_register_task_workflow_routes = __esm({
|
|
78131
|
+
"../dashboard/src/routes/register-task-workflow-routes.ts"() {
|
|
78132
|
+
"use strict";
|
|
78133
|
+
init_src();
|
|
78134
|
+
init_api_error();
|
|
78135
|
+
}
|
|
78136
|
+
});
|
|
78137
|
+
|
|
78138
|
+
// ../dashboard/src/routes/register-planning-subtask-routes.ts
|
|
78139
|
+
var init_register_planning_subtask_routes = __esm({
|
|
78140
|
+
"../dashboard/src/routes/register-planning-subtask-routes.ts"() {
|
|
78141
|
+
"use strict";
|
|
78142
|
+
init_api_error();
|
|
78143
|
+
init_sse_buffer();
|
|
78144
|
+
}
|
|
78145
|
+
});
|
|
78146
|
+
|
|
78147
|
+
// ../dashboard/src/rate-limit.ts
|
|
78148
|
+
var init_rate_limit = __esm({
|
|
78149
|
+
"../dashboard/src/rate-limit.ts"() {
|
|
78150
|
+
"use strict";
|
|
78151
|
+
init_api_error();
|
|
78152
|
+
}
|
|
78153
|
+
});
|
|
78154
|
+
|
|
78155
|
+
// ../dashboard/src/routes/register-chat-routes.ts
|
|
78156
|
+
var init_register_chat_routes = __esm({
|
|
78157
|
+
"../dashboard/src/routes/register-chat-routes.ts"() {
|
|
78158
|
+
"use strict";
|
|
78159
|
+
init_api_error();
|
|
78160
|
+
init_rate_limit();
|
|
78161
|
+
init_sse_buffer();
|
|
78162
|
+
}
|
|
78163
|
+
});
|
|
78164
|
+
|
|
78165
|
+
// ../dashboard/src/remote-auth.ts
|
|
78166
|
+
var init_remote_auth = __esm({
|
|
78167
|
+
"../dashboard/src/remote-auth.ts"() {
|
|
78168
|
+
"use strict";
|
|
78169
|
+
}
|
|
78170
|
+
});
|
|
78171
|
+
|
|
78172
|
+
// ../dashboard/src/routes/register-settings-memory-routes.ts
|
|
78173
|
+
var init_register_settings_memory_routes = __esm({
|
|
78174
|
+
"../dashboard/src/routes/register-settings-memory-routes.ts"() {
|
|
78175
|
+
"use strict";
|
|
78176
|
+
init_src();
|
|
78177
|
+
init_api_error();
|
|
78178
|
+
init_remote_auth();
|
|
78179
|
+
init_project_store_resolver();
|
|
78180
|
+
}
|
|
78181
|
+
});
|
|
78182
|
+
|
|
78183
|
+
// ../dashboard/src/terminal-service.ts
|
|
78184
|
+
import { createRequire as createRequire3 } from "node:module";
|
|
78185
|
+
var isBunBinary, require2;
|
|
78186
|
+
var init_terminal_service = __esm({
|
|
78187
|
+
"../dashboard/src/terminal-service.ts"() {
|
|
78188
|
+
"use strict";
|
|
78189
|
+
isBunBinary = typeof Bun !== "undefined" && !!Bun.embeddedFiles;
|
|
78190
|
+
require2 = createRequire3(import.meta.url);
|
|
78191
|
+
}
|
|
78192
|
+
});
|
|
78193
|
+
|
|
78194
|
+
// ../dashboard/src/routes/register-messaging-scripts.ts
|
|
78195
|
+
var init_register_messaging_scripts = __esm({
|
|
78196
|
+
"../dashboard/src/routes/register-messaging-scripts.ts"() {
|
|
78197
|
+
"use strict";
|
|
78198
|
+
init_src();
|
|
78199
|
+
init_api_error();
|
|
78200
|
+
init_terminal_service();
|
|
78201
|
+
}
|
|
78202
|
+
});
|
|
78203
|
+
|
|
78204
|
+
// ../dashboard/src/github.ts
|
|
78205
|
+
function delay(ms) {
|
|
78206
|
+
return new Promise((resolve17) => setTimeout(resolve17, ms));
|
|
78207
|
+
}
|
|
78208
|
+
function normalizeCheckState(state) {
|
|
78209
|
+
switch ((state ?? "").toLowerCase()) {
|
|
78210
|
+
case "success":
|
|
78211
|
+
return "success";
|
|
78212
|
+
case "pending":
|
|
78213
|
+
case "queued":
|
|
78214
|
+
case "in_progress":
|
|
78215
|
+
case "expected":
|
|
78216
|
+
return "pending";
|
|
78217
|
+
case "failure":
|
|
78218
|
+
case "failed":
|
|
78219
|
+
case "error":
|
|
78220
|
+
return "failure";
|
|
78221
|
+
case "cancelled":
|
|
78222
|
+
return "cancelled";
|
|
78223
|
+
case "timed_out":
|
|
78224
|
+
return "timed_out";
|
|
78225
|
+
case "action_required":
|
|
78226
|
+
return "action_required";
|
|
78227
|
+
case "neutral":
|
|
78228
|
+
return "neutral";
|
|
78229
|
+
case "skipped":
|
|
78230
|
+
return "skipped";
|
|
78231
|
+
case "stale":
|
|
78232
|
+
return "stale";
|
|
78233
|
+
case "startup_failure":
|
|
78234
|
+
return "startup_failure";
|
|
78235
|
+
default:
|
|
78236
|
+
return "failure";
|
|
78237
|
+
}
|
|
78238
|
+
}
|
|
78239
|
+
function toPrInfo(input) {
|
|
78240
|
+
return {
|
|
78241
|
+
url: input.url,
|
|
78242
|
+
number: input.number,
|
|
78243
|
+
status: input.status,
|
|
78244
|
+
title: input.title,
|
|
78245
|
+
headBranch: input.headBranch,
|
|
78246
|
+
baseBranch: input.baseBranch,
|
|
78247
|
+
commentCount: input.commentCount ?? 0,
|
|
78248
|
+
lastCommentAt: input.lastCommentAt,
|
|
78249
|
+
lastCheckedAt: input.lastCheckedAt
|
|
78250
|
+
};
|
|
78251
|
+
}
|
|
78252
|
+
function isPrMergeReady(input) {
|
|
78253
|
+
const blockingReasons = [];
|
|
78254
|
+
if (input.status !== "open") {
|
|
78255
|
+
blockingReasons.push(`PR is ${input.status}`);
|
|
78256
|
+
}
|
|
78257
|
+
if (input.reviewDecision === "CHANGES_REQUESTED") {
|
|
78258
|
+
blockingReasons.push("changes requested review is active");
|
|
78259
|
+
}
|
|
78260
|
+
const blockingChecks = input.checks.filter(
|
|
78261
|
+
(check) => check.required && check.state !== "success"
|
|
78262
|
+
);
|
|
78263
|
+
if (blockingChecks.length > 0) {
|
|
78264
|
+
blockingReasons.push(
|
|
78265
|
+
`required checks not successful: ${blockingChecks.map((check) => `${check.name} (${check.state})`).join(", ")}`
|
|
78266
|
+
);
|
|
78267
|
+
}
|
|
78268
|
+
return {
|
|
78269
|
+
ready: blockingReasons.length === 0,
|
|
78270
|
+
blockingReasons
|
|
77513
78271
|
};
|
|
77514
78272
|
}
|
|
77515
78273
|
function uniqueBatchNumbers(numbers) {
|
|
@@ -78329,10 +79087,10 @@ var init_github = __esm({
|
|
|
78329
79087
|
return issues;
|
|
78330
79088
|
}
|
|
78331
79089
|
async listRecentIssueStatusPage(owner, repo) {
|
|
78332
|
-
const
|
|
79090
|
+
const path2 = `repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues?state=all&per_page=${MAX_BADGE_BATCH_SIZE}`;
|
|
78333
79091
|
if (this.hasGhAuth()) {
|
|
78334
79092
|
try {
|
|
78335
|
-
return await runGhJsonAsync(["api",
|
|
79093
|
+
return await runGhJsonAsync(["api", path2]);
|
|
78336
79094
|
} catch (err) {
|
|
78337
79095
|
if (this.token) {
|
|
78338
79096
|
return this.listRecentIssueStatusPageWithApi(owner, repo);
|
|
@@ -78374,10 +79132,10 @@ var init_github = __esm({
|
|
|
78374
79132
|
return prs;
|
|
78375
79133
|
}
|
|
78376
79134
|
async listRecentPrStatusPage(owner, repo) {
|
|
78377
|
-
const
|
|
79135
|
+
const path2 = `repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls?state=all&per_page=${MAX_BADGE_BATCH_SIZE}`;
|
|
78378
79136
|
if (this.hasGhAuth()) {
|
|
78379
79137
|
try {
|
|
78380
|
-
return await runGhJsonAsync(["api",
|
|
79138
|
+
return await runGhJsonAsync(["api", path2]);
|
|
78381
79139
|
} catch (err) {
|
|
78382
79140
|
if (this.token) {
|
|
78383
79141
|
return this.listRecentPrStatusPageWithApi(owner, repo);
|
|
@@ -79284,8 +80042,8 @@ var init_register_git_github = __esm({
|
|
|
79284
80042
|
});
|
|
79285
80043
|
|
|
79286
80044
|
// ../dashboard/src/terminal.ts
|
|
79287
|
-
import { spawn as
|
|
79288
|
-
import { randomUUID as
|
|
80045
|
+
import { spawn as spawn7 } from "node:child_process";
|
|
80046
|
+
import { randomUUID as randomUUID12 } from "node:crypto";
|
|
79289
80047
|
import { EventEmitter as EventEmitter28 } from "node:events";
|
|
79290
80048
|
function extractBaseCommand(command) {
|
|
79291
80049
|
let trimmed = command.trim();
|
|
@@ -79445,8 +80203,8 @@ var init_terminal = __esm({
|
|
|
79445
80203
|
if (!validation.valid) {
|
|
79446
80204
|
return { sessionId: "", error: validation.error };
|
|
79447
80205
|
}
|
|
79448
|
-
const sessionId =
|
|
79449
|
-
const childProcess =
|
|
80206
|
+
const sessionId = randomUUID12();
|
|
80207
|
+
const childProcess = spawn7(command, [], {
|
|
79450
80208
|
cwd,
|
|
79451
80209
|
shell: true,
|
|
79452
80210
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -79871,728 +80629,13 @@ var init_register_auth_routes = __esm({
|
|
|
79871
80629
|
}
|
|
79872
80630
|
});
|
|
79873
80631
|
|
|
79874
|
-
// ../plugin-sdk/src/index.ts
|
|
79875
|
-
function definePlugin(plugin4) {
|
|
79876
|
-
return plugin4;
|
|
79877
|
-
}
|
|
79878
|
-
var init_src3 = __esm({
|
|
79879
|
-
"../plugin-sdk/src/index.ts"() {
|
|
79880
|
-
"use strict";
|
|
79881
|
-
init_src();
|
|
79882
|
-
}
|
|
79883
|
-
});
|
|
79884
|
-
|
|
79885
|
-
// ../../plugins/fusion-plugin-hermes-runtime/dist/cli-spawn.js
|
|
79886
|
-
import { spawn as spawn5, spawnSync } from "node:child_process";
|
|
79887
|
-
import { sep as PATH_SEP } from "node:path";
|
|
79888
|
-
function resolveBinaryForSpawn(binary) {
|
|
79889
|
-
if (process.platform !== "win32")
|
|
79890
|
-
return binary;
|
|
79891
|
-
if (binary.includes(PATH_SEP) || binary.includes("/") || /\.[a-z]{2,4}$/i.test(binary)) {
|
|
79892
|
-
return binary;
|
|
79893
|
-
}
|
|
79894
|
-
const cached = resolvedBinaryCache.get(binary);
|
|
79895
|
-
if (cached)
|
|
79896
|
-
return cached;
|
|
79897
|
-
try {
|
|
79898
|
-
const result = spawnSync("where", [binary], { encoding: "utf-8" });
|
|
79899
|
-
if (result.status === 0) {
|
|
79900
|
-
const first = (result.stdout ?? "").trim().split(/\r?\n/)[0];
|
|
79901
|
-
if (first?.length) {
|
|
79902
|
-
resolvedBinaryCache.set(binary, first);
|
|
79903
|
-
return first;
|
|
79904
|
-
}
|
|
79905
|
-
}
|
|
79906
|
-
} catch {
|
|
79907
|
-
}
|
|
79908
|
-
return binary;
|
|
79909
|
-
}
|
|
79910
|
-
function hermesProfileHome(profileName) {
|
|
79911
|
-
const base = process.env.HERMES_HOME ?? `${process.env.HOME ?? "~"}/.hermes`;
|
|
79912
|
-
if (profileName === "default" || profileName === "")
|
|
79913
|
-
return base;
|
|
79914
|
-
return `${base}/profiles/${profileName}`;
|
|
79915
|
-
}
|
|
79916
|
-
function resolveCliSettings(settings) {
|
|
79917
|
-
const str = (v) => typeof v === "string" && v.trim().length > 0 ? v.trim() : void 0;
|
|
79918
|
-
const num = (v, envKey, fallback) => {
|
|
79919
|
-
if (typeof v === "number" && Number.isFinite(v) && v > 0)
|
|
79920
|
-
return v;
|
|
79921
|
-
const raw = str(v) ?? str(process.env[envKey]);
|
|
79922
|
-
if (raw !== void 0) {
|
|
79923
|
-
const parsed = Number(raw);
|
|
79924
|
-
if (Number.isFinite(parsed) && parsed > 0)
|
|
79925
|
-
return parsed;
|
|
79926
|
-
}
|
|
79927
|
-
return fallback;
|
|
79928
|
-
};
|
|
79929
|
-
const bool = (v, envKey, fallback) => {
|
|
79930
|
-
if (typeof v === "boolean")
|
|
79931
|
-
return v;
|
|
79932
|
-
const raw = str(v) ?? str(process.env[envKey]);
|
|
79933
|
-
if (raw !== void 0)
|
|
79934
|
-
return raw === "1" || raw.toLowerCase() === "true";
|
|
79935
|
-
return fallback;
|
|
79936
|
-
};
|
|
79937
|
-
return {
|
|
79938
|
-
binaryPath: str(settings?.binaryPath) ?? str(process.env.HERMES_BIN) ?? "hermes",
|
|
79939
|
-
model: str(settings?.model) ?? str(process.env.HERMES_MODEL_ID),
|
|
79940
|
-
provider: str(settings?.provider) ?? str(process.env.HERMES_PROVIDER),
|
|
79941
|
-
maxTurns: num(settings?.maxTurns, "HERMES_MAX_TURNS", 12),
|
|
79942
|
-
yolo: bool(settings?.yolo, "HERMES_YOLO", false),
|
|
79943
|
-
cliTimeoutMs: num(settings?.cliTimeoutMs, "HERMES_CLI_TIMEOUT_MS", 3e5),
|
|
79944
|
-
profile: str(settings?.profile) ?? str(process.env.HERMES_PROFILE)
|
|
79945
|
-
};
|
|
79946
|
-
}
|
|
79947
|
-
function cleanText(raw) {
|
|
79948
|
-
return raw.replace(ANSI_RE, "").replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
79949
|
-
}
|
|
79950
|
-
function stripChrome(text) {
|
|
79951
|
-
const lines = text.split("\n");
|
|
79952
|
-
const filtered = lines.filter((line) => !CHROME_LINE_RES.some((re) => re.test(line)));
|
|
79953
|
-
return filtered.join("\n").trim();
|
|
79954
|
-
}
|
|
79955
|
-
function parseHermesOutput(rawStdout, rawStderr) {
|
|
79956
|
-
const cleaned = cleanText(rawStdout);
|
|
79957
|
-
const match = SESSION_ID_RE.exec(cleaned);
|
|
79958
|
-
if (!match) {
|
|
79959
|
-
const combined = [rawStdout, rawStderr].filter(Boolean).join("\n");
|
|
79960
|
-
throw new Error(`hermes: missing session_id in output.
|
|
79961
|
-
${combined}`);
|
|
79962
|
-
}
|
|
79963
|
-
const sessionId = match[1];
|
|
79964
|
-
const sessionIdLineStart = cleaned.lastIndexOf("\nsession_id:");
|
|
79965
|
-
const bodyRaw = sessionIdLineStart >= 0 ? cleaned.slice(0, sessionIdLineStart) : cleaned;
|
|
79966
|
-
const body = stripChrome(bodyRaw);
|
|
79967
|
-
return { body, sessionId };
|
|
79968
|
-
}
|
|
79969
|
-
function buildHermesArgs(prompt, settings, resumeSessionId) {
|
|
79970
|
-
const args = ["chat", "-q", prompt, "-Q", "--source", "tool"];
|
|
79971
|
-
if (resumeSessionId) {
|
|
79972
|
-
args.push("--resume", resumeSessionId);
|
|
79973
|
-
}
|
|
79974
|
-
if (settings.model) {
|
|
79975
|
-
args.push("-m", settings.model);
|
|
79976
|
-
}
|
|
79977
|
-
if (settings.provider) {
|
|
79978
|
-
args.push("--provider", settings.provider);
|
|
79979
|
-
}
|
|
79980
|
-
args.push("--max-turns", String(settings.maxTurns));
|
|
79981
|
-
if (settings.yolo) {
|
|
79982
|
-
args.push("--yolo");
|
|
79983
|
-
}
|
|
79984
|
-
return args;
|
|
79985
|
-
}
|
|
79986
|
-
async function invokeHermesCli(prompt, settings, resumeSessionId, signal) {
|
|
79987
|
-
const args = buildHermesArgs(prompt, settings, resumeSessionId);
|
|
79988
|
-
const binary = resolveBinaryForSpawn(settings.binaryPath);
|
|
79989
|
-
return new Promise((resolve17, reject) => {
|
|
79990
|
-
let settled = false;
|
|
79991
|
-
const spawnEnv = { ...process.env, PYTHONUNBUFFERED: "1" };
|
|
79992
|
-
if (settings.profile) {
|
|
79993
|
-
spawnEnv.HERMES_HOME = hermesProfileHome(settings.profile);
|
|
79994
|
-
}
|
|
79995
|
-
const child = spawn5(binary, args, {
|
|
79996
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
79997
|
-
env: spawnEnv
|
|
79998
|
-
});
|
|
79999
|
-
const hardKillTimer = setTimeout(() => {
|
|
80000
|
-
if (settled)
|
|
80001
|
-
return;
|
|
80002
|
-
settled = true;
|
|
80003
|
-
try {
|
|
80004
|
-
child.kill("SIGKILL");
|
|
80005
|
-
} catch {
|
|
80006
|
-
}
|
|
80007
|
-
reject(new Error(`hermes: process timed out after ${settings.cliTimeoutMs}ms`));
|
|
80008
|
-
}, settings.cliTimeoutMs);
|
|
80009
|
-
const onAbort = () => {
|
|
80010
|
-
if (settled)
|
|
80011
|
-
return;
|
|
80012
|
-
settled = true;
|
|
80013
|
-
clearTimeout(hardKillTimer);
|
|
80014
|
-
try {
|
|
80015
|
-
child.kill("SIGTERM");
|
|
80016
|
-
} catch {
|
|
80017
|
-
}
|
|
80018
|
-
reject(new Error("hermes: invocation aborted"));
|
|
80019
|
-
};
|
|
80020
|
-
if (signal) {
|
|
80021
|
-
if (signal.aborted) {
|
|
80022
|
-
onAbort();
|
|
80023
|
-
return;
|
|
80024
|
-
}
|
|
80025
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
80026
|
-
}
|
|
80027
|
-
let stdout = "";
|
|
80028
|
-
let stderr = "";
|
|
80029
|
-
child.stdout?.on("data", (chunk) => {
|
|
80030
|
-
stdout += chunk.toString("utf-8");
|
|
80031
|
-
});
|
|
80032
|
-
child.stderr?.on("data", (chunk) => {
|
|
80033
|
-
stderr += chunk.toString("utf-8");
|
|
80034
|
-
});
|
|
80035
|
-
child.on("error", (err) => {
|
|
80036
|
-
if (settled)
|
|
80037
|
-
return;
|
|
80038
|
-
settled = true;
|
|
80039
|
-
clearTimeout(hardKillTimer);
|
|
80040
|
-
signal?.removeEventListener("abort", onAbort);
|
|
80041
|
-
const isNotFound = err.code === "ENOENT";
|
|
80042
|
-
reject(new Error(isNotFound ? `hermes: binary not found at "${settings.binaryPath}". Install hermes or set binaryPath/HERMES_BIN.` : `hermes: spawn error \u2014 ${err.message}`));
|
|
80043
|
-
});
|
|
80044
|
-
child.on("close", (code) => {
|
|
80045
|
-
if (settled)
|
|
80046
|
-
return;
|
|
80047
|
-
settled = true;
|
|
80048
|
-
clearTimeout(hardKillTimer);
|
|
80049
|
-
signal?.removeEventListener("abort", onAbort);
|
|
80050
|
-
if (code !== 0) {
|
|
80051
|
-
const combined = [stdout, stderr].filter(Boolean).join("\n");
|
|
80052
|
-
reject(new Error(`hermes: process exited with code ${String(code)}.
|
|
80053
|
-
${combined}`));
|
|
80054
|
-
return;
|
|
80055
|
-
}
|
|
80056
|
-
try {
|
|
80057
|
-
resolve17(parseHermesOutput(stdout, stderr));
|
|
80058
|
-
} catch (parseErr) {
|
|
80059
|
-
reject(parseErr);
|
|
80060
|
-
}
|
|
80061
|
-
});
|
|
80062
|
-
});
|
|
80063
|
-
}
|
|
80064
|
-
var resolvedBinaryCache, ANSI_RE, SESSION_ID_RE, CHROME_LINE_RES;
|
|
80065
|
-
var init_cli_spawn = __esm({
|
|
80066
|
-
"../../plugins/fusion-plugin-hermes-runtime/dist/cli-spawn.js"() {
|
|
80067
|
-
"use strict";
|
|
80068
|
-
resolvedBinaryCache = /* @__PURE__ */ new Map();
|
|
80069
|
-
ANSI_RE = /\x1b\[[0-9;]*[A-Za-z]/g;
|
|
80070
|
-
SESSION_ID_RE = /^session_id:\s+([0-9]{8}_[0-9]{6}_[0-9a-f]{6})\s*$/m;
|
|
80071
|
-
CHROME_LINE_RES = [
|
|
80072
|
-
/^\s*┊\s/,
|
|
80073
|
-
// memory/status sidebar lines
|
|
80074
|
-
/^↻ Resumed session /,
|
|
80075
|
-
// resume banner
|
|
80076
|
-
/^╭─.*╮\s*$/,
|
|
80077
|
-
// top box border
|
|
80078
|
-
/^╰─.*╯\s*$/,
|
|
80079
|
-
// bottom box border
|
|
80080
|
-
/^Query:\s*/
|
|
80081
|
-
// query echo line
|
|
80082
|
-
];
|
|
80083
|
-
}
|
|
80084
|
-
});
|
|
80085
|
-
|
|
80086
|
-
// ../../plugins/fusion-plugin-hermes-runtime/dist/runtime-adapter.js
|
|
80087
|
-
var HermesRuntimeAdapter;
|
|
80088
|
-
var init_runtime_adapter = __esm({
|
|
80089
|
-
"../../plugins/fusion-plugin-hermes-runtime/dist/runtime-adapter.js"() {
|
|
80090
|
-
"use strict";
|
|
80091
|
-
init_cli_spawn();
|
|
80092
|
-
HermesRuntimeAdapter = class {
|
|
80093
|
-
id = "hermes";
|
|
80094
|
-
name = "Hermes Runtime";
|
|
80095
|
-
settings;
|
|
80096
|
-
constructor(settings) {
|
|
80097
|
-
this.settings = resolveCliSettings(settings);
|
|
80098
|
-
}
|
|
80099
|
-
async createSession(options) {
|
|
80100
|
-
const session = {
|
|
80101
|
-
model: void 0,
|
|
80102
|
-
systemPrompt: options.systemPrompt,
|
|
80103
|
-
messages: [],
|
|
80104
|
-
apiKey: void 0,
|
|
80105
|
-
thinkingLevel: void 0,
|
|
80106
|
-
sessionId: "",
|
|
80107
|
-
lastModelDescription: this.describeFromSettings(),
|
|
80108
|
-
callbacks: {
|
|
80109
|
-
onText: options.onText,
|
|
80110
|
-
onThinking: options.onThinking,
|
|
80111
|
-
onToolStart: options.onToolStart,
|
|
80112
|
-
onToolEnd: options.onToolEnd
|
|
80113
|
-
},
|
|
80114
|
-
dispose: () => void 0
|
|
80115
|
-
};
|
|
80116
|
-
return { session, sessionFile: void 0 };
|
|
80117
|
-
}
|
|
80118
|
-
async promptWithFallback(session, prompt, _options) {
|
|
80119
|
-
const resumeId = session.sessionId || void 0;
|
|
80120
|
-
const result = await invokeHermesCli(prompt, this.settings, resumeId);
|
|
80121
|
-
session.sessionId = result.sessionId;
|
|
80122
|
-
session.lastModelDescription = this.describeFromSettings();
|
|
80123
|
-
if (result.body) {
|
|
80124
|
-
session.callbacks.onText?.(result.body);
|
|
80125
|
-
}
|
|
80126
|
-
}
|
|
80127
|
-
describeModel(session) {
|
|
80128
|
-
return session.lastModelDescription || this.describeFromSettings();
|
|
80129
|
-
}
|
|
80130
|
-
async dispose(_session) {
|
|
80131
|
-
}
|
|
80132
|
-
describeFromSettings() {
|
|
80133
|
-
const provider = this.settings.provider;
|
|
80134
|
-
const model = this.settings.model;
|
|
80135
|
-
if (provider && model)
|
|
80136
|
-
return `hermes/${provider}/${model}`;
|
|
80137
|
-
if (model)
|
|
80138
|
-
return `hermes/${model}`;
|
|
80139
|
-
if (provider)
|
|
80140
|
-
return `hermes/${provider}`;
|
|
80141
|
-
return "hermes";
|
|
80142
|
-
}
|
|
80143
|
-
};
|
|
80144
|
-
}
|
|
80145
|
-
});
|
|
80146
|
-
|
|
80147
|
-
// ../../plugins/fusion-plugin-hermes-runtime/dist/probe.js
|
|
80148
|
-
var init_probe = __esm({
|
|
80149
|
-
"../../plugins/fusion-plugin-hermes-runtime/dist/probe.js"() {
|
|
80150
|
-
"use strict";
|
|
80151
|
-
}
|
|
80152
|
-
});
|
|
80153
|
-
|
|
80154
|
-
// ../../plugins/fusion-plugin-hermes-runtime/dist/index.js
|
|
80155
|
-
var HERMES_RUNTIME_ID, HERMES_RUNTIME_VERSION, hermesRuntimeMetadata, hermesRuntimeFactory, plugin;
|
|
80156
|
-
var init_dist = __esm({
|
|
80157
|
-
"../../plugins/fusion-plugin-hermes-runtime/dist/index.js"() {
|
|
80158
|
-
"use strict";
|
|
80159
|
-
init_src3();
|
|
80160
|
-
init_cli_spawn();
|
|
80161
|
-
init_runtime_adapter();
|
|
80162
|
-
init_runtime_adapter();
|
|
80163
|
-
init_cli_spawn();
|
|
80164
|
-
init_probe();
|
|
80165
|
-
HERMES_RUNTIME_ID = "hermes";
|
|
80166
|
-
HERMES_RUNTIME_VERSION = "0.2.0";
|
|
80167
|
-
hermesRuntimeMetadata = {
|
|
80168
|
-
runtimeId: HERMES_RUNTIME_ID,
|
|
80169
|
-
name: "Hermes Runtime",
|
|
80170
|
-
description: "Drives the local `hermes` CLI (NousResearch/hermes-agent)",
|
|
80171
|
-
version: HERMES_RUNTIME_VERSION
|
|
80172
|
-
};
|
|
80173
|
-
hermesRuntimeFactory = async (ctx) => {
|
|
80174
|
-
return new HermesRuntimeAdapter(ctx.settings);
|
|
80175
|
-
};
|
|
80176
|
-
plugin = definePlugin({
|
|
80177
|
-
manifest: {
|
|
80178
|
-
id: "fusion-plugin-hermes-runtime",
|
|
80179
|
-
name: "Hermes Runtime Plugin",
|
|
80180
|
-
version: HERMES_RUNTIME_VERSION,
|
|
80181
|
-
description: "Drives the local `hermes` CLI for Fusion agents \u2014 captures session ids and resumes via --resume.",
|
|
80182
|
-
author: "Fusion Team",
|
|
80183
|
-
homepage: "https://github.com/NousResearch/hermes-agent",
|
|
80184
|
-
runtime: hermesRuntimeMetadata
|
|
80185
|
-
},
|
|
80186
|
-
state: "installed",
|
|
80187
|
-
hooks: {
|
|
80188
|
-
onLoad: (ctx) => {
|
|
80189
|
-
const settings = resolveCliSettings(ctx.settings);
|
|
80190
|
-
ctx.logger.info(`Hermes Runtime Plugin loaded \u2014 binary=${settings.binaryPath} model=${settings.model ?? "(default)"}`);
|
|
80191
|
-
ctx.emitEvent("hermes-runtime:loaded", {
|
|
80192
|
-
runtimeId: HERMES_RUNTIME_ID,
|
|
80193
|
-
version: HERMES_RUNTIME_VERSION
|
|
80194
|
-
});
|
|
80195
|
-
},
|
|
80196
|
-
onUnload: () => {
|
|
80197
|
-
}
|
|
80198
|
-
},
|
|
80199
|
-
runtime: {
|
|
80200
|
-
metadata: hermesRuntimeMetadata,
|
|
80201
|
-
factory: hermesRuntimeFactory
|
|
80202
|
-
}
|
|
80203
|
-
});
|
|
80204
|
-
}
|
|
80205
|
-
});
|
|
80206
|
-
|
|
80207
|
-
// ../../plugins/fusion-plugin-openclaw-runtime/dist/pi-module.js
|
|
80208
|
-
import { spawn as spawn6 } from "node:child_process";
|
|
80209
|
-
import { randomUUID as randomUUID12 } from "node:crypto";
|
|
80210
|
-
function asString(v) {
|
|
80211
|
-
return typeof v === "string" && v.trim() !== "" ? v.trim() : void 0;
|
|
80212
|
-
}
|
|
80213
|
-
function asNumber(v) {
|
|
80214
|
-
if (typeof v === "number" && Number.isFinite(v))
|
|
80215
|
-
return v;
|
|
80216
|
-
const s = asString(v);
|
|
80217
|
-
if (s === void 0)
|
|
80218
|
-
return void 0;
|
|
80219
|
-
const n = Number(s);
|
|
80220
|
-
return Number.isFinite(n) ? n : void 0;
|
|
80221
|
-
}
|
|
80222
|
-
function asBool(v) {
|
|
80223
|
-
if (typeof v === "boolean")
|
|
80224
|
-
return v;
|
|
80225
|
-
const s = asString(v);
|
|
80226
|
-
if (s === void 0)
|
|
80227
|
-
return void 0;
|
|
80228
|
-
return s === "1" || s.toLowerCase() === "true";
|
|
80229
|
-
}
|
|
80230
|
-
function stripAnsi(text) {
|
|
80231
|
-
return text.replace(ANSI_RE2, "");
|
|
80232
|
-
}
|
|
80233
|
-
function resolveCliConfig(settings) {
|
|
80234
|
-
return {
|
|
80235
|
-
binaryPath: asString(settings?.binaryPath) ?? asString(process.env.OPENCLAW_BIN) ?? DEFAULT_BINARY,
|
|
80236
|
-
agentId: asString(settings?.agentId) ?? asString(process.env.OPENCLAW_AGENT_ID) ?? DEFAULT_AGENT_ID,
|
|
80237
|
-
model: asString(settings?.model) ?? asString(process.env.OPENCLAW_MODEL),
|
|
80238
|
-
thinking: asString(settings?.thinking) ?? asString(process.env.OPENCLAW_THINKING) ?? DEFAULT_THINKING,
|
|
80239
|
-
cliTimeoutSec: asNumber(settings?.cliTimeoutSec) ?? asNumber(process.env.OPENCLAW_TIMEOUT_SEC) ?? DEFAULT_TIMEOUT_SEC,
|
|
80240
|
-
cliTimeoutMs: asNumber(settings?.cliTimeoutMs) ?? asNumber(process.env.OPENCLAW_CLI_TIMEOUT_MS) ?? DEFAULT_CLI_TIMEOUT_MS,
|
|
80241
|
-
useGateway: asBool(settings?.useGateway) ?? asBool(process.env.OPENCLAW_USE_GATEWAY) ?? false
|
|
80242
|
-
};
|
|
80243
|
-
}
|
|
80244
|
-
function buildOpenClawArgs(config, sessionId, message) {
|
|
80245
|
-
const args = ["--no-color", "agent"];
|
|
80246
|
-
if (!config.useGateway)
|
|
80247
|
-
args.push("--local");
|
|
80248
|
-
args.push("--json");
|
|
80249
|
-
args.push("--session-id", sessionId);
|
|
80250
|
-
args.push("--message", message);
|
|
80251
|
-
args.push("--agent", config.agentId);
|
|
80252
|
-
if (config.model) {
|
|
80253
|
-
args.push("--model", config.model);
|
|
80254
|
-
}
|
|
80255
|
-
args.push("--thinking", config.thinking);
|
|
80256
|
-
args.push("--timeout", String(config.cliTimeoutSec));
|
|
80257
|
-
return args;
|
|
80258
|
-
}
|
|
80259
|
-
function extractStderrError(stderr, stdout) {
|
|
80260
|
-
const tryExtract = (raw) => {
|
|
80261
|
-
if (!raw)
|
|
80262
|
-
return void 0;
|
|
80263
|
-
const lines = stripAnsi(raw).split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
|
|
80264
|
-
return lines.length > 0 ? lines[lines.length - 1] : void 0;
|
|
80265
|
-
};
|
|
80266
|
-
return tryExtract(stderr) ?? tryExtract(stdout ?? "") ?? "openclaw exited with non-zero status (no stderr)";
|
|
80267
|
-
}
|
|
80268
|
-
function createCliSession(opts) {
|
|
80269
|
-
return {
|
|
80270
|
-
sessionId: randomUUID12(),
|
|
80271
|
-
agentId: opts.agentId ?? DEFAULT_AGENT_ID,
|
|
80272
|
-
systemPrompt: opts.systemPrompt,
|
|
80273
|
-
messages: [{ role: "developer", content: opts.systemPrompt }],
|
|
80274
|
-
lastModelDescription: `openclaw/${opts.agentId ?? DEFAULT_AGENT_ID}`,
|
|
80275
|
-
lastUsage: void 0,
|
|
80276
|
-
callbacks: opts.callbacks
|
|
80277
|
-
};
|
|
80278
|
-
}
|
|
80279
|
-
async function promptCli(session, message, config, callbacks, signal) {
|
|
80280
|
-
const args = buildOpenClawArgs(config, session.sessionId, message);
|
|
80281
|
-
const cb = { ...session.callbacks, ...callbacks };
|
|
80282
|
-
cb.onToolStart?.("openclaw.agent", { sessionId: session.sessionId });
|
|
80283
|
-
return new Promise((resolve17, reject) => {
|
|
80284
|
-
let settled = false;
|
|
80285
|
-
const child = spawn6(config.binaryPath, args, {
|
|
80286
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
80287
|
-
});
|
|
80288
|
-
const hardKill = setTimeout(() => {
|
|
80289
|
-
if (settled)
|
|
80290
|
-
return;
|
|
80291
|
-
settled = true;
|
|
80292
|
-
try {
|
|
80293
|
-
child.kill("SIGKILL");
|
|
80294
|
-
} catch {
|
|
80295
|
-
}
|
|
80296
|
-
reject(new Error(`openclaw: process timed out after ${config.cliTimeoutMs}ms`));
|
|
80297
|
-
}, config.cliTimeoutMs);
|
|
80298
|
-
const onAbort = () => {
|
|
80299
|
-
if (settled)
|
|
80300
|
-
return;
|
|
80301
|
-
try {
|
|
80302
|
-
child.kill("SIGTERM");
|
|
80303
|
-
} catch {
|
|
80304
|
-
}
|
|
80305
|
-
};
|
|
80306
|
-
if (signal) {
|
|
80307
|
-
if (signal.aborted) {
|
|
80308
|
-
onAbort();
|
|
80309
|
-
} else {
|
|
80310
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
80311
|
-
}
|
|
80312
|
-
}
|
|
80313
|
-
let stdout = "";
|
|
80314
|
-
let stderr = "";
|
|
80315
|
-
child.stdout?.on("data", (chunk) => {
|
|
80316
|
-
stdout += chunk.toString("utf-8");
|
|
80317
|
-
});
|
|
80318
|
-
child.stderr?.on("data", (chunk) => {
|
|
80319
|
-
stderr += chunk.toString("utf-8");
|
|
80320
|
-
});
|
|
80321
|
-
child.on("error", (err) => {
|
|
80322
|
-
if (settled)
|
|
80323
|
-
return;
|
|
80324
|
-
settled = true;
|
|
80325
|
-
clearTimeout(hardKill);
|
|
80326
|
-
signal?.removeEventListener("abort", onAbort);
|
|
80327
|
-
const isNotFound = err.code === "ENOENT";
|
|
80328
|
-
reject(new Error(isNotFound ? `openclaw: binary not found at "${config.binaryPath}". Install OpenClaw (npm i -g openclaw) or set binaryPath/OPENCLAW_BIN.` : `openclaw: spawn error \u2014 ${err.message}`));
|
|
80329
|
-
});
|
|
80330
|
-
child.on("close", (code) => {
|
|
80331
|
-
if (settled)
|
|
80332
|
-
return;
|
|
80333
|
-
settled = true;
|
|
80334
|
-
clearTimeout(hardKill);
|
|
80335
|
-
signal?.removeEventListener("abort", onAbort);
|
|
80336
|
-
if (code !== 0) {
|
|
80337
|
-
const err = stderr.trim() || stdout.trim() ? extractStderrError(stderr, stdout) : `openclaw: exited with code ${String(code)}`;
|
|
80338
|
-
reject(new Error(err));
|
|
80339
|
-
return;
|
|
80340
|
-
}
|
|
80341
|
-
let parsed;
|
|
80342
|
-
try {
|
|
80343
|
-
parsed = JSON.parse(stdout);
|
|
80344
|
-
} catch {
|
|
80345
|
-
reject(new Error(`openclaw: failed to parse JSON output (stdout=${stdout.slice(0, 200)})`));
|
|
80346
|
-
return;
|
|
80347
|
-
}
|
|
80348
|
-
const payloads = parsed.payloads ?? [];
|
|
80349
|
-
const visibleText = payloads.filter((p) => !p.isError && !p.isReasoning).map((p) => p.text ?? "").filter((t) => t.length > 0).join("");
|
|
80350
|
-
const reasoningText = payloads.filter((p) => p.isReasoning).map((p) => p.text ?? "").filter((t) => t.length > 0).join("\n");
|
|
80351
|
-
const errorText = payloads.filter((p) => p.isError).map((p) => p.text ?? "").filter((t) => t.length > 0);
|
|
80352
|
-
const finalText = visibleText || parsed.meta?.finalAssistantVisibleText || "";
|
|
80353
|
-
if (finalText)
|
|
80354
|
-
cb.onText?.(finalText);
|
|
80355
|
-
if (reasoningText)
|
|
80356
|
-
cb.onThinking?.(reasoningText);
|
|
80357
|
-
session.messages.push({ role: "user", content: message });
|
|
80358
|
-
if (finalText) {
|
|
80359
|
-
session.messages.push({ role: "assistant", content: finalText });
|
|
80360
|
-
}
|
|
80361
|
-
const agentMeta = parsed.meta?.agentMeta;
|
|
80362
|
-
if (agentMeta?.usage)
|
|
80363
|
-
session.lastUsage = agentMeta.usage;
|
|
80364
|
-
if (agentMeta?.provider && agentMeta.model) {
|
|
80365
|
-
session.lastModelDescription = `openclaw/${session.agentId}/${agentMeta.provider}/${agentMeta.model}`;
|
|
80366
|
-
}
|
|
80367
|
-
const metaError = parsed.meta?.error;
|
|
80368
|
-
const isError = !!metaError;
|
|
80369
|
-
cb.onToolEnd?.("openclaw.agent", isError, {
|
|
80370
|
-
usage: agentMeta?.usage,
|
|
80371
|
-
provider: agentMeta?.provider,
|
|
80372
|
-
model: agentMeta?.model,
|
|
80373
|
-
...metaError ? { error: metaError } : {},
|
|
80374
|
-
...errorText.length > 0 ? { toolErrors: errorText } : {}
|
|
80375
|
-
});
|
|
80376
|
-
resolve17();
|
|
80377
|
-
});
|
|
80378
|
-
});
|
|
80379
|
-
}
|
|
80380
|
-
function describeCliModel(session) {
|
|
80381
|
-
return session.lastModelDescription || `openclaw/${session.agentId}`;
|
|
80382
|
-
}
|
|
80383
|
-
var DEFAULT_BINARY, DEFAULT_AGENT_ID, DEFAULT_THINKING, DEFAULT_TIMEOUT_SEC, DEFAULT_CLI_TIMEOUT_MS, ANSI_RE2;
|
|
80384
|
-
var init_pi_module = __esm({
|
|
80385
|
-
"../../plugins/fusion-plugin-openclaw-runtime/dist/pi-module.js"() {
|
|
80386
|
-
"use strict";
|
|
80387
|
-
DEFAULT_BINARY = "openclaw";
|
|
80388
|
-
DEFAULT_AGENT_ID = "main";
|
|
80389
|
-
DEFAULT_THINKING = "off";
|
|
80390
|
-
DEFAULT_TIMEOUT_SEC = 0;
|
|
80391
|
-
DEFAULT_CLI_TIMEOUT_MS = 3e5;
|
|
80392
|
-
ANSI_RE2 = /\x1b\[[0-9;]*[A-Za-z]/g;
|
|
80393
|
-
}
|
|
80394
|
-
});
|
|
80395
|
-
|
|
80396
|
-
// ../../plugins/fusion-plugin-openclaw-runtime/dist/runtime-adapter.js
|
|
80397
|
-
var OpenClawRuntimeAdapter;
|
|
80398
|
-
var init_runtime_adapter2 = __esm({
|
|
80399
|
-
"../../plugins/fusion-plugin-openclaw-runtime/dist/runtime-adapter.js"() {
|
|
80400
|
-
"use strict";
|
|
80401
|
-
init_pi_module();
|
|
80402
|
-
OpenClawRuntimeAdapter = class {
|
|
80403
|
-
id = "openclaw";
|
|
80404
|
-
name = "OpenClaw Runtime";
|
|
80405
|
-
config;
|
|
80406
|
-
constructor(settings) {
|
|
80407
|
-
this.config = resolveCliConfig(settings);
|
|
80408
|
-
}
|
|
80409
|
-
async createSession(options) {
|
|
80410
|
-
const session = createCliSession({
|
|
80411
|
-
systemPrompt: options.systemPrompt,
|
|
80412
|
-
agentId: this.config.agentId,
|
|
80413
|
-
callbacks: {
|
|
80414
|
-
onText: options.onText,
|
|
80415
|
-
onThinking: options.onThinking,
|
|
80416
|
-
onToolStart: options.onToolStart,
|
|
80417
|
-
onToolEnd: options.onToolEnd
|
|
80418
|
-
}
|
|
80419
|
-
});
|
|
80420
|
-
return { session, sessionFile: void 0 };
|
|
80421
|
-
}
|
|
80422
|
-
async promptWithFallback(session, prompt, options) {
|
|
80423
|
-
const overrideCallbacks = options ?? void 0;
|
|
80424
|
-
await promptCli(session, prompt, this.config, overrideCallbacks);
|
|
80425
|
-
}
|
|
80426
|
-
describeModel(session) {
|
|
80427
|
-
return describeCliModel(session);
|
|
80428
|
-
}
|
|
80429
|
-
async dispose(_session) {
|
|
80430
|
-
}
|
|
80431
|
-
};
|
|
80432
|
-
}
|
|
80433
|
-
});
|
|
80434
|
-
|
|
80435
|
-
// ../../plugins/fusion-plugin-openclaw-runtime/dist/probe.js
|
|
80436
|
-
import { spawn as spawn7 } from "node:child_process";
|
|
80437
|
-
async function probeOpenClawBinary(opts = {}) {
|
|
80438
|
-
const startedAt = Date.now();
|
|
80439
|
-
const binary = opts.binaryPath ?? "openclaw";
|
|
80440
|
-
const timeoutMs = opts.timeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
|
|
80441
|
-
const resolvedPath = await tryResolveBinaryPath(binary);
|
|
80442
|
-
return new Promise((resolvePromise) => {
|
|
80443
|
-
const finish = (partial) => {
|
|
80444
|
-
resolvePromise({ ...partial, probeDurationMs: Date.now() - startedAt });
|
|
80445
|
-
};
|
|
80446
|
-
let settled = false;
|
|
80447
|
-
const child = spawn7(resolvedPath ?? binary, ["--version"], {
|
|
80448
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
80449
|
-
});
|
|
80450
|
-
const timer = setTimeout(() => {
|
|
80451
|
-
if (settled)
|
|
80452
|
-
return;
|
|
80453
|
-
settled = true;
|
|
80454
|
-
try {
|
|
80455
|
-
child.kill("SIGKILL");
|
|
80456
|
-
} catch {
|
|
80457
|
-
}
|
|
80458
|
-
finish({
|
|
80459
|
-
available: false,
|
|
80460
|
-
binaryPath: resolvedPath,
|
|
80461
|
-
reason: `Probe timed out after ${timeoutMs}ms`
|
|
80462
|
-
});
|
|
80463
|
-
}, timeoutMs);
|
|
80464
|
-
let stdout = "";
|
|
80465
|
-
let stderr = "";
|
|
80466
|
-
child.stdout?.on("data", (chunk) => {
|
|
80467
|
-
stdout += chunk.toString("utf-8");
|
|
80468
|
-
});
|
|
80469
|
-
child.stderr?.on("data", (chunk) => {
|
|
80470
|
-
stderr += chunk.toString("utf-8");
|
|
80471
|
-
});
|
|
80472
|
-
child.on("error", (err) => {
|
|
80473
|
-
if (settled)
|
|
80474
|
-
return;
|
|
80475
|
-
settled = true;
|
|
80476
|
-
clearTimeout(timer);
|
|
80477
|
-
const isNotFound = err.code === "ENOENT";
|
|
80478
|
-
finish({
|
|
80479
|
-
available: false,
|
|
80480
|
-
binaryPath: resolvedPath,
|
|
80481
|
-
reason: isNotFound ? `\`${binary}\` not found on PATH \u2014 install via: npm install -g openclaw` : err.message
|
|
80482
|
-
});
|
|
80483
|
-
});
|
|
80484
|
-
child.on("close", (code) => {
|
|
80485
|
-
if (settled)
|
|
80486
|
-
return;
|
|
80487
|
-
settled = true;
|
|
80488
|
-
clearTimeout(timer);
|
|
80489
|
-
if (code === 0) {
|
|
80490
|
-
finish({
|
|
80491
|
-
available: true,
|
|
80492
|
-
binaryPath: resolvedPath,
|
|
80493
|
-
version: stdout.trim() || void 0
|
|
80494
|
-
});
|
|
80495
|
-
} else {
|
|
80496
|
-
finish({
|
|
80497
|
-
available: false,
|
|
80498
|
-
binaryPath: resolvedPath,
|
|
80499
|
-
reason: stderr.trim() || `openclaw --version exited with code ${String(code)}`
|
|
80500
|
-
});
|
|
80501
|
-
}
|
|
80502
|
-
});
|
|
80503
|
-
});
|
|
80504
|
-
}
|
|
80505
|
-
async function tryResolveBinaryPath(binary) {
|
|
80506
|
-
return new Promise((resolvePromise) => {
|
|
80507
|
-
const which = process.platform === "win32" ? "where" : "which";
|
|
80508
|
-
const child = spawn7(which, [binary], { stdio: ["ignore", "pipe", "ignore"] });
|
|
80509
|
-
let out = "";
|
|
80510
|
-
child.stdout?.on("data", (chunk) => {
|
|
80511
|
-
out += chunk.toString("utf-8");
|
|
80512
|
-
});
|
|
80513
|
-
child.on("error", () => resolvePromise(void 0));
|
|
80514
|
-
child.on("close", (code) => {
|
|
80515
|
-
if (code === 0) {
|
|
80516
|
-
const first = out.trim().split(/\r?\n/)[0];
|
|
80517
|
-
resolvePromise(first?.length ? first : void 0);
|
|
80518
|
-
} else {
|
|
80519
|
-
resolvePromise(void 0);
|
|
80520
|
-
}
|
|
80521
|
-
});
|
|
80522
|
-
});
|
|
80523
|
-
}
|
|
80524
|
-
var DEFAULT_PROBE_TIMEOUT_MS;
|
|
80525
|
-
var init_probe2 = __esm({
|
|
80526
|
-
"../../plugins/fusion-plugin-openclaw-runtime/dist/probe.js"() {
|
|
80527
|
-
"use strict";
|
|
80528
|
-
DEFAULT_PROBE_TIMEOUT_MS = 2e3;
|
|
80529
|
-
}
|
|
80530
|
-
});
|
|
80531
|
-
|
|
80532
|
-
// ../../plugins/fusion-plugin-openclaw-runtime/dist/index.js
|
|
80533
|
-
var OPENCLAW_RUNTIME_ID, OPENCLAW_RUNTIME_VERSION, openclawRuntimeMetadata, openclawRuntimeFactory, plugin2;
|
|
80534
|
-
var init_dist2 = __esm({
|
|
80535
|
-
"../../plugins/fusion-plugin-openclaw-runtime/dist/index.js"() {
|
|
80536
|
-
"use strict";
|
|
80537
|
-
init_src3();
|
|
80538
|
-
init_runtime_adapter2();
|
|
80539
|
-
init_pi_module();
|
|
80540
|
-
init_probe2();
|
|
80541
|
-
init_runtime_adapter2();
|
|
80542
|
-
init_pi_module();
|
|
80543
|
-
init_probe2();
|
|
80544
|
-
OPENCLAW_RUNTIME_ID = "openclaw";
|
|
80545
|
-
OPENCLAW_RUNTIME_VERSION = "0.2.0";
|
|
80546
|
-
openclawRuntimeMetadata = {
|
|
80547
|
-
runtimeId: OPENCLAW_RUNTIME_ID,
|
|
80548
|
-
name: "OpenClaw Runtime",
|
|
80549
|
-
description: "Drives the local `openclaw` CLI (openclaw/openclaw)",
|
|
80550
|
-
version: OPENCLAW_RUNTIME_VERSION
|
|
80551
|
-
};
|
|
80552
|
-
openclawRuntimeFactory = async (ctx) => {
|
|
80553
|
-
return new OpenClawRuntimeAdapter(ctx?.settings);
|
|
80554
|
-
};
|
|
80555
|
-
plugin2 = definePlugin({
|
|
80556
|
-
manifest: {
|
|
80557
|
-
id: "fusion-plugin-openclaw-runtime",
|
|
80558
|
-
name: "OpenClaw Runtime Plugin",
|
|
80559
|
-
version: OPENCLAW_RUNTIME_VERSION,
|
|
80560
|
-
description: "Drives the local `openclaw` CLI for Fusion agents \u2014 embedded `--local` mode by default; gateway optional.",
|
|
80561
|
-
author: "Fusion Team",
|
|
80562
|
-
homepage: "https://docs.openclaw.ai/",
|
|
80563
|
-
runtime: openclawRuntimeMetadata
|
|
80564
|
-
},
|
|
80565
|
-
state: "installed",
|
|
80566
|
-
hooks: {
|
|
80567
|
-
onLoad: async (ctx) => {
|
|
80568
|
-
const config = resolveCliConfig(ctx.settings);
|
|
80569
|
-
const probe = await probeOpenClawBinary({ binaryPath: config.binaryPath });
|
|
80570
|
-
ctx.logger.info(probe.available ? `OpenClaw Runtime Plugin loaded \u2014 binary=${config.binaryPath}${probe.version ? ` (${probe.version})` : ""}` : `OpenClaw Runtime Plugin loaded but binary not detected: ${probe.reason ?? "unknown"}`);
|
|
80571
|
-
ctx.emitEvent("openclaw-runtime:loaded", {
|
|
80572
|
-
runtimeId: OPENCLAW_RUNTIME_ID,
|
|
80573
|
-
version: OPENCLAW_RUNTIME_VERSION,
|
|
80574
|
-
binaryAvailable: probe.available,
|
|
80575
|
-
binaryPath: probe.binaryPath ?? config.binaryPath
|
|
80576
|
-
});
|
|
80577
|
-
},
|
|
80578
|
-
onUnload: () => {
|
|
80579
|
-
}
|
|
80580
|
-
},
|
|
80581
|
-
runtime: {
|
|
80582
|
-
metadata: openclawRuntimeMetadata,
|
|
80583
|
-
factory: openclawRuntimeFactory
|
|
80584
|
-
}
|
|
80585
|
-
});
|
|
80586
|
-
}
|
|
80587
|
-
});
|
|
80588
|
-
|
|
80589
80632
|
// ../../plugins/fusion-plugin-paperclip-runtime/dist/paperclip-client.js
|
|
80590
80633
|
function normalizeApiUrl(url) {
|
|
80591
80634
|
return url.replace(/\/+$/, "");
|
|
80592
80635
|
}
|
|
80593
|
-
function buildUrl(apiUrl,
|
|
80636
|
+
function buildUrl(apiUrl, path2, query) {
|
|
80594
80637
|
const base = normalizeApiUrl(apiUrl);
|
|
80595
|
-
const normalizedPath =
|
|
80638
|
+
const normalizedPath = path2.startsWith("/") ? path2 : `/${path2}`;
|
|
80596
80639
|
const qs = query && query.size > 0 ? `?${query.toString()}` : "";
|
|
80597
80640
|
return `${base}/api${normalizedPath}${qs}`;
|
|
80598
80641
|
}
|
|
@@ -80629,9 +80672,9 @@ function toErrorMessage(status, statusText, body, raw) {
|
|
|
80629
80672
|
return raw.slice(0, 200).trim();
|
|
80630
80673
|
return `${status} ${statusText}`.trim();
|
|
80631
80674
|
}
|
|
80632
|
-
async function request(apiUrl,
|
|
80675
|
+
async function request(apiUrl, path2, options) {
|
|
80633
80676
|
const method = options?.method ?? "GET";
|
|
80634
|
-
const url = buildUrl(apiUrl,
|
|
80677
|
+
const url = buildUrl(apiUrl, path2, options?.query);
|
|
80635
80678
|
const headers = buildHeaders(options?.apiKey);
|
|
80636
80679
|
let bodyStr;
|
|
80637
80680
|
if (options && "body" in options && options.body !== void 0) {
|
|
@@ -80648,7 +80691,7 @@ async function request(apiUrl, path, options) {
|
|
|
80648
80691
|
const { value, raw } = await parseJsonBody(response);
|
|
80649
80692
|
if (!response.ok) {
|
|
80650
80693
|
const msg = toErrorMessage(response.status, response.statusText, value, raw);
|
|
80651
|
-
const full = `Paperclip API ${response.status} (${method} ${
|
|
80694
|
+
const full = `Paperclip API ${response.status} (${method} ${path2}): ${msg}`;
|
|
80652
80695
|
if (response.status === 409)
|
|
80653
80696
|
throw new ConflictError(full);
|
|
80654
80697
|
throw new Error(full);
|
|
@@ -80694,9 +80737,9 @@ function resolvePaperclipConfig(settings) {
|
|
|
80694
80737
|
}
|
|
80695
80738
|
async function discoverPaperclipCliConfig(opts = {}) {
|
|
80696
80739
|
const fs = await import("node:fs/promises");
|
|
80697
|
-
const
|
|
80698
|
-
const
|
|
80699
|
-
const configPath = opts.configPath ??
|
|
80740
|
+
const path2 = await import("node:path");
|
|
80741
|
+
const os3 = await import("node:os");
|
|
80742
|
+
const configPath = opts.configPath ?? path2.join(os3.homedir(), ".paperclip", "instances", "default", "config.json");
|
|
80700
80743
|
let raw;
|
|
80701
80744
|
try {
|
|
80702
80745
|
raw = await fs.readFile(configPath, "utf-8");
|
|
@@ -80843,6 +80886,124 @@ async function probePaperclipConnection(opts) {
|
|
|
80843
80886
|
}
|
|
80844
80887
|
return { available: true, apiUrl, identity, probeDurationMs };
|
|
80845
80888
|
}
|
|
80889
|
+
function stripAnsi2(str) {
|
|
80890
|
+
return str.replace(/\x1B\[[0-9;]*[mGKJHFABCDSTsu]/g, "");
|
|
80891
|
+
}
|
|
80892
|
+
function remapSpawnError(err, bin) {
|
|
80893
|
+
const code = err?.code;
|
|
80894
|
+
if (code === "ENOENT") {
|
|
80895
|
+
return new Error(`paperclipai binary not found at ${bin}; install via \`npm i -g paperclipai\``);
|
|
80896
|
+
}
|
|
80897
|
+
return err instanceof Error ? err : new Error(String(err));
|
|
80898
|
+
}
|
|
80899
|
+
async function spawnPaperclipCliJson(args, opts) {
|
|
80900
|
+
const { spawn: spawn10 } = await import("node:child_process");
|
|
80901
|
+
const bin = opts.cliBinaryPath ?? "paperclipai";
|
|
80902
|
+
const fullArgs = [...args, "--json"];
|
|
80903
|
+
if (opts.cliConfigPath) {
|
|
80904
|
+
fullArgs.push("--config", opts.cliConfigPath);
|
|
80905
|
+
}
|
|
80906
|
+
const timeoutMs = opts.cliTimeoutMs ?? 15e3;
|
|
80907
|
+
const label = ["paperclipai", ...args].join(" ");
|
|
80908
|
+
return new Promise((resolve17, reject) => {
|
|
80909
|
+
let child;
|
|
80910
|
+
try {
|
|
80911
|
+
child = spawn10(bin, fullArgs, { stdio: ["ignore", "pipe", "pipe"] });
|
|
80912
|
+
} catch (err) {
|
|
80913
|
+
reject(remapSpawnError(err, bin));
|
|
80914
|
+
return;
|
|
80915
|
+
}
|
|
80916
|
+
const stdoutChunks = [];
|
|
80917
|
+
const stderrLines = [];
|
|
80918
|
+
let killed = false;
|
|
80919
|
+
const timer = setTimeout(() => {
|
|
80920
|
+
killed = true;
|
|
80921
|
+
child.kill("SIGKILL");
|
|
80922
|
+
reject(new Error(`${label} timed out after ${timeoutMs}ms`));
|
|
80923
|
+
}, timeoutMs);
|
|
80924
|
+
child.stdout?.on("data", (chunk) => {
|
|
80925
|
+
stdoutChunks.push(chunk);
|
|
80926
|
+
});
|
|
80927
|
+
child.stderr?.on("data", (chunk) => {
|
|
80928
|
+
const lines = chunk.toString("utf-8").split("\n");
|
|
80929
|
+
for (const line of lines) {
|
|
80930
|
+
const stripped = stripAnsi2(line).trim();
|
|
80931
|
+
if (stripped)
|
|
80932
|
+
stderrLines.push(stripped);
|
|
80933
|
+
}
|
|
80934
|
+
});
|
|
80935
|
+
child.on("error", (err) => {
|
|
80936
|
+
clearTimeout(timer);
|
|
80937
|
+
reject(remapSpawnError(err, bin));
|
|
80938
|
+
});
|
|
80939
|
+
child.on("close", (code) => {
|
|
80940
|
+
clearTimeout(timer);
|
|
80941
|
+
if (killed)
|
|
80942
|
+
return;
|
|
80943
|
+
const cleaned = stripAnsi2(Buffer.concat(stdoutChunks).toString("utf-8")).trim();
|
|
80944
|
+
if (code !== 0) {
|
|
80945
|
+
const lastErr = stderrLines.filter(Boolean).pop() ?? "";
|
|
80946
|
+
reject(new Error(lastErr ? `${label} exited ${code}: ${lastErr}` : `${label} exited ${code}`));
|
|
80947
|
+
return;
|
|
80948
|
+
}
|
|
80949
|
+
if (!cleaned) {
|
|
80950
|
+
reject(new Error(`${label} produced no output`));
|
|
80951
|
+
return;
|
|
80952
|
+
}
|
|
80953
|
+
try {
|
|
80954
|
+
resolve17(JSON.parse(cleaned));
|
|
80955
|
+
} catch {
|
|
80956
|
+
reject(new Error(`${label} returned non-JSON output: ${cleaned.slice(0, 200)}`));
|
|
80957
|
+
}
|
|
80958
|
+
});
|
|
80959
|
+
});
|
|
80960
|
+
}
|
|
80961
|
+
async function createIssueViaCli(opts) {
|
|
80962
|
+
const args = ["issue", "create", "--company-id", opts.companyId];
|
|
80963
|
+
args.push("--title", opts.body.title);
|
|
80964
|
+
if (opts.body.description)
|
|
80965
|
+
args.push("--description", opts.body.description);
|
|
80966
|
+
if (opts.body.status)
|
|
80967
|
+
args.push("--status", opts.body.status);
|
|
80968
|
+
if (opts.body.assigneeAgentId)
|
|
80969
|
+
args.push("--assignee-agent-id", opts.body.assigneeAgentId);
|
|
80970
|
+
if (opts.body.parentId)
|
|
80971
|
+
args.push("--parent-id", opts.body.parentId);
|
|
80972
|
+
if (opts.body.projectId)
|
|
80973
|
+
args.push("--project-id", opts.body.projectId);
|
|
80974
|
+
if (opts.body.goalId)
|
|
80975
|
+
args.push("--goal-id", opts.body.goalId);
|
|
80976
|
+
const raw = await spawnPaperclipCliJson(args, opts);
|
|
80977
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
80978
|
+
throw new Error(`paperclipai issue create returned unexpected payload: ${JSON.stringify(raw).slice(0, 200)}`);
|
|
80979
|
+
}
|
|
80980
|
+
return raw;
|
|
80981
|
+
}
|
|
80982
|
+
async function getIssueViaCli(opts) {
|
|
80983
|
+
const raw = await spawnPaperclipCliJson(["issue", "get", opts.issueId], opts);
|
|
80984
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
80985
|
+
throw new Error(`paperclipai issue get returned unexpected payload: ${JSON.stringify(raw).slice(0, 200)}`);
|
|
80986
|
+
}
|
|
80987
|
+
return raw;
|
|
80988
|
+
}
|
|
80989
|
+
async function agentsMeViaCli(opts) {
|
|
80990
|
+
const raw = await spawnPaperclipCliJson(["agent", "get", opts.agentId], opts);
|
|
80991
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
80992
|
+
throw new Error(`paperclipai agent get returned unexpected payload: ${JSON.stringify(raw).slice(0, 200)}`);
|
|
80993
|
+
}
|
|
80994
|
+
const id = typeof raw.id === "string" ? raw.id : void 0;
|
|
80995
|
+
const cId = typeof raw.companyId === "string" ? raw.companyId : void 0;
|
|
80996
|
+
if (!id || !cId) {
|
|
80997
|
+
throw new Error("paperclipai agent get returned a response missing `id` or `companyId`");
|
|
80998
|
+
}
|
|
80999
|
+
return {
|
|
81000
|
+
agentId: id,
|
|
81001
|
+
agentName: typeof raw.name === "string" ? raw.name : id,
|
|
81002
|
+
role: typeof raw.role === "string" ? raw.role : void 0,
|
|
81003
|
+
companyId: cId,
|
|
81004
|
+
companyName: typeof raw.companyName === "string" ? raw.companyName : void 0
|
|
81005
|
+
};
|
|
81006
|
+
}
|
|
80846
81007
|
var ConflictError;
|
|
80847
81008
|
var init_paperclip_client = __esm({
|
|
80848
81009
|
"../../plugins/fusion-plugin-paperclip-runtime/dist/paperclip-client.js"() {
|
|
@@ -80949,12 +81110,24 @@ var init_runtime_adapter3 = __esm({
|
|
|
80949
81110
|
let companyId = this.config.companyId;
|
|
80950
81111
|
if (!agentId || !companyId) {
|
|
80951
81112
|
try {
|
|
80952
|
-
|
|
80953
|
-
|
|
80954
|
-
|
|
81113
|
+
if (this.config.transport === "cli") {
|
|
81114
|
+
if (!agentId) {
|
|
81115
|
+
throw new Error("agentId is required in Local CLI mode (paperclipai has no `agents/me` equivalent \u2014 pick an agent in settings)");
|
|
81116
|
+
}
|
|
81117
|
+
const me = await agentsMeViaCli({
|
|
81118
|
+
agentId,
|
|
81119
|
+
cliBinaryPath: this.config.cliBinaryPath,
|
|
81120
|
+
cliConfigPath: this.config.cliConfigPath
|
|
81121
|
+
});
|
|
81122
|
+
companyId = companyId ?? me.companyId;
|
|
81123
|
+
} else {
|
|
81124
|
+
const me = await agentsMe(effectiveApiUrl, effectiveApiKey);
|
|
81125
|
+
agentId = agentId ?? me.agentId;
|
|
81126
|
+
companyId = companyId ?? me.companyId;
|
|
81127
|
+
}
|
|
80955
81128
|
} catch (error) {
|
|
80956
81129
|
const reason = error instanceof Error ? error.message : String(error);
|
|
80957
|
-
throw new Error(`Paperclip runtime could not derive agentId/companyId
|
|
81130
|
+
throw new Error(`Paperclip runtime could not derive agentId/companyId. Configure them explicitly or check the API key / CLI auth. Underlying error: ${reason}`);
|
|
80958
81131
|
}
|
|
80959
81132
|
}
|
|
80960
81133
|
if (!agentId || !companyId) {
|
|
@@ -80973,6 +81146,9 @@ var init_runtime_adapter3 = __esm({
|
|
|
80973
81146
|
projectId: this.config.projectId,
|
|
80974
81147
|
goalId: this.config.goalId,
|
|
80975
81148
|
issueId: void 0,
|
|
81149
|
+
transport: this.config.transport ?? "api",
|
|
81150
|
+
cliBinaryPath: this.config.cliBinaryPath,
|
|
81151
|
+
cliConfigPath: this.config.cliConfigPath,
|
|
80976
81152
|
turnIndex: 0,
|
|
80977
81153
|
runTimeoutMs: this.config.runTimeoutMs ?? 6e5,
|
|
80978
81154
|
pollIntervalMs: this.config.pollIntervalMs ?? 500,
|
|
@@ -81043,7 +81219,11 @@ var init_runtime_adapter3 = __esm({
|
|
|
81043
81219
|
let finalText = stream.text;
|
|
81044
81220
|
if (issueId) {
|
|
81045
81221
|
try {
|
|
81046
|
-
const issue =
|
|
81222
|
+
const issue = session.transport === "cli" ? await getIssueViaCli({
|
|
81223
|
+
issueId,
|
|
81224
|
+
cliBinaryPath: session.cliBinaryPath,
|
|
81225
|
+
cliConfigPath: session.cliConfigPath
|
|
81226
|
+
}) : await getIssue(session.apiUrl, session.apiKey, issueId);
|
|
81047
81227
|
issueStatus = asString2(issue.status) ?? void 0;
|
|
81048
81228
|
if (!finalText) {
|
|
81049
81229
|
const comments = await getIssueComments(session.apiUrl, session.apiKey, issueId);
|
|
@@ -81079,7 +81259,7 @@ var init_runtime_adapter3 = __esm({
|
|
|
81079
81259
|
// Internals
|
|
81080
81260
|
// ---------------------------------------------------------------------
|
|
81081
81261
|
async createIssueForPrompt(session, prompt) {
|
|
81082
|
-
const
|
|
81262
|
+
const body = {
|
|
81083
81263
|
title: deriveIssueTitle(prompt),
|
|
81084
81264
|
description: buildIssueDescription(session, prompt),
|
|
81085
81265
|
status: "todo",
|
|
@@ -81087,7 +81267,13 @@ var init_runtime_adapter3 = __esm({
|
|
|
81087
81267
|
...session.parentIssueId ? { parentId: session.parentIssueId } : {},
|
|
81088
81268
|
...session.projectId ? { projectId: session.projectId } : {},
|
|
81089
81269
|
...session.goalId ? { goalId: session.goalId } : {}
|
|
81090
|
-
}
|
|
81270
|
+
};
|
|
81271
|
+
const created = session.transport === "cli" ? await createIssueViaCli({
|
|
81272
|
+
companyId: session.companyId,
|
|
81273
|
+
body,
|
|
81274
|
+
cliBinaryPath: session.cliBinaryPath,
|
|
81275
|
+
cliConfigPath: session.cliConfigPath
|
|
81276
|
+
}) : await createIssue(session.apiUrl, session.apiKey, session.companyId, body);
|
|
81091
81277
|
return pickIssueId(created);
|
|
81092
81278
|
}
|
|
81093
81279
|
async streamRunEvents(session, runId) {
|
|
@@ -81387,7 +81573,7 @@ async function initPromptOverrides() {
|
|
|
81387
81573
|
promptOverridesReady = true;
|
|
81388
81574
|
}
|
|
81389
81575
|
}
|
|
81390
|
-
var upload, resolveWorkflowStepRefinePrompt, promptOverridesReady, DEFAULT_WORKFLOW_STEP_REFINE_PROMPT, DEFAULT_AUTOMATION_TIMEOUT_MS, AUTOMATION_MAX_BUFFER, MANUAL_RUN_AI_SYSTEM_PROMPT;
|
|
81576
|
+
var BUNDLED_PLUGIN_RUNTIMES, upload, resolveWorkflowStepRefinePrompt, promptOverridesReady, DEFAULT_WORKFLOW_STEP_REFINE_PROMPT, DEFAULT_AUTOMATION_TIMEOUT_MS, AUTOMATION_MAX_BUFFER, MANUAL_RUN_AI_SYSTEM_PROMPT;
|
|
81391
81577
|
var init_routes = __esm({
|
|
81392
81578
|
"../dashboard/src/routes.ts"() {
|
|
81393
81579
|
"use strict";
|
|
@@ -81401,6 +81587,8 @@ var init_routes = __esm({
|
|
|
81401
81587
|
init_sse_buffer();
|
|
81402
81588
|
init_api_error();
|
|
81403
81589
|
init_plugin_routes();
|
|
81590
|
+
init_dist();
|
|
81591
|
+
init_dist2();
|
|
81404
81592
|
init_ai_session_diagnostics();
|
|
81405
81593
|
init_context();
|
|
81406
81594
|
init_register_task_workflow_routes();
|
|
@@ -81434,6 +81622,29 @@ var init_routes = __esm({
|
|
|
81434
81622
|
init_register_git_github();
|
|
81435
81623
|
init_src2();
|
|
81436
81624
|
init_resolve_diff_base();
|
|
81625
|
+
BUNDLED_PLUGIN_RUNTIMES = [
|
|
81626
|
+
{
|
|
81627
|
+
pluginId: "fusion-plugin-hermes-runtime",
|
|
81628
|
+
runtimeId: hermesRuntimeMetadata.runtimeId,
|
|
81629
|
+
name: hermesRuntimeMetadata.name,
|
|
81630
|
+
...hermesRuntimeMetadata.description ? { description: hermesRuntimeMetadata.description } : {},
|
|
81631
|
+
version: hermesRuntimeMetadata.version ?? "0.0.0"
|
|
81632
|
+
},
|
|
81633
|
+
{
|
|
81634
|
+
pluginId: "fusion-plugin-openclaw-runtime",
|
|
81635
|
+
runtimeId: openclawRuntimeMetadata.runtimeId,
|
|
81636
|
+
name: openclawRuntimeMetadata.name,
|
|
81637
|
+
...openclawRuntimeMetadata.description ? { description: openclawRuntimeMetadata.description } : {},
|
|
81638
|
+
version: openclawRuntimeMetadata.version ?? "0.0.0"
|
|
81639
|
+
},
|
|
81640
|
+
{
|
|
81641
|
+
pluginId: "fusion-plugin-paperclip-runtime",
|
|
81642
|
+
runtimeId: "paperclip",
|
|
81643
|
+
name: "Paperclip Runtime",
|
|
81644
|
+
description: "Drives a Paperclip agent via the wakeup + heartbeat-run REST API",
|
|
81645
|
+
version: "1.0.0"
|
|
81646
|
+
}
|
|
81647
|
+
];
|
|
81437
81648
|
upload = multer({
|
|
81438
81649
|
storage: multer.memoryStorage(),
|
|
81439
81650
|
limits: { fileSize: 5 * 1024 * 1024 }
|
|
@@ -86172,9 +86383,9 @@ async function fetchGitHubIssues(owner, repo, options = {}) {
|
|
|
86172
86383
|
if (since) {
|
|
86173
86384
|
params.append("since", since);
|
|
86174
86385
|
}
|
|
86175
|
-
const
|
|
86386
|
+
const path2 = `repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues?${params.toString()}`;
|
|
86176
86387
|
try {
|
|
86177
|
-
const issues = await runGhJsonAsync(["api",
|
|
86388
|
+
const issues = await runGhJsonAsync(["api", path2]);
|
|
86178
86389
|
return issues.filter((issue) => !issue.pull_request).slice(0, limit);
|
|
86179
86390
|
} catch (error) {
|
|
86180
86391
|
throw new Error(getGhErrorMessage(error));
|
|
@@ -86834,7 +87045,8 @@ async function runSkillsInstall(args, options) {
|
|
|
86834
87045
|
npxArgs.push("-y", "-a", "pi");
|
|
86835
87046
|
const child = spawn8("npx", npxArgs, {
|
|
86836
87047
|
cwd: process.cwd(),
|
|
86837
|
-
stdio: "inherit"
|
|
87048
|
+
stdio: "inherit",
|
|
87049
|
+
shell: true
|
|
86838
87050
|
});
|
|
86839
87051
|
const exitCode = await new Promise((resolve17, reject) => {
|
|
86840
87052
|
child.on("exit", (code) => {
|
|
@@ -86929,9 +87141,9 @@ async function fetchGitHubIssuesViaGh(owner, repo, options = {}) {
|
|
|
86929
87141
|
if (options.labels && options.labels.length > 0) {
|
|
86930
87142
|
queryParams.append("labels", options.labels.join(","));
|
|
86931
87143
|
}
|
|
86932
|
-
const
|
|
87144
|
+
const path2 = `repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues?${queryParams.toString()}`;
|
|
86933
87145
|
try {
|
|
86934
|
-
const issues = await runGhJsonAsync(["api",
|
|
87146
|
+
const issues = await runGhJsonAsync(["api", path2]);
|
|
86935
87147
|
return issues.filter((issue) => !issue.pull_request);
|
|
86936
87148
|
} catch (error) {
|
|
86937
87149
|
throw new Error(getGhErrorMessage(error));
|
|
@@ -86939,9 +87151,9 @@ async function fetchGitHubIssuesViaGh(owner, repo, options = {}) {
|
|
|
86939
87151
|
}
|
|
86940
87152
|
async function fetchGitHubIssueViaGh(owner, repo, issueNumber) {
|
|
86941
87153
|
ensureGhCliAuth();
|
|
86942
|
-
const
|
|
87154
|
+
const path2 = `repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues/${issueNumber}`;
|
|
86943
87155
|
try {
|
|
86944
|
-
return await runGhJsonAsync(["api",
|
|
87156
|
+
return await runGhJsonAsync(["api", path2]);
|
|
86945
87157
|
} catch (error) {
|
|
86946
87158
|
throw new Error(getGhErrorMessage(error));
|
|
86947
87159
|
}
|
|
@@ -88285,7 +88497,8 @@ Status: ${updated.status}`
|
|
|
88285
88497
|
npxArgs.push("-y", "-a", "pi");
|
|
88286
88498
|
const child = spawn9("npx", npxArgs, {
|
|
88287
88499
|
cwd: resolveProjectRoot(ctx.cwd),
|
|
88288
|
-
stdio: "pipe"
|
|
88500
|
+
stdio: "pipe",
|
|
88501
|
+
shell: true
|
|
88289
88502
|
});
|
|
88290
88503
|
let stderr = "";
|
|
88291
88504
|
child.stdout?.on("data", () => {
|
|
@@ -88368,7 +88581,8 @@ Status: ${updated.status}`
|
|
|
88368
88581
|
cwd: resolveProjectRoot(ctx.cwd),
|
|
88369
88582
|
stdio: ["ignore", "pipe", "pipe"],
|
|
88370
88583
|
detached: false,
|
|
88371
|
-
env: { ...process.env }
|
|
88584
|
+
env: { ...process.env },
|
|
88585
|
+
shell: true
|
|
88372
88586
|
});
|
|
88373
88587
|
dashboardProcess = child;
|
|
88374
88588
|
dashboardPort = port;
|