@runfusion/fusion 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -0
- package/dist/bin.js +1250 -522
- package/dist/client/assets/AgentDetailView-CBFUveyO.js +18 -0
- package/dist/client/assets/{AgentsView-Dvf_xUkx.js → AgentsView-DPezXQ-U.js} +4 -4
- package/dist/client/assets/ChatView-5N4-EuhD.js +1 -0
- package/dist/client/assets/{DevServerView-C2qTJch7.js → DevServerView-Daft4YFc.js} +1 -1
- package/dist/client/assets/{DirectoryPicker-DRfhg9zz.js → DirectoryPicker-rew1y6qO.js} +1 -1
- package/dist/client/assets/{DocumentsView-j8ic1xUw.js → DocumentsView-i72qJzwd.js} +1 -1
- package/dist/client/assets/{InsightsView-CpAz3o0i.js → InsightsView-BL5eZJ0a.js} +1 -1
- package/dist/client/assets/{MemoryView-BcQsi_JK.js → MemoryView-pl8Cdg_p.js} +1 -1
- package/dist/client/assets/{NodesView-Bo_Yhr4N.js → NodesView-D6eJ15zc.js} +1 -1
- package/dist/client/assets/PiExtensionsManager-ExInwXWP.js +11 -0
- package/dist/client/assets/{PluginManager-BQhBHWrB.js → PluginManager-CYhtxHun.js} +1 -1
- package/dist/client/assets/{ResearchView-CLyyqAWE.js → ResearchView-B_QPUEjB.js} +1 -1
- package/dist/client/assets/{RoadmapsView-tG7IdOoc.js → RoadmapsView-DBNLaEsK.js} +1 -1
- package/dist/client/assets/SettingsModal-1ET586M3.js +31 -0
- package/dist/client/assets/{SettingsModal-CXUGeZ0_.js → SettingsModal-CL_gWmOj.js} +1 -1
- package/dist/client/assets/SettingsModal-D_AFkDJa.css +1 -0
- package/dist/client/assets/{SetupWizardModal-BMJL6eNR.js → SetupWizardModal-CLkY9HFL.js} +1 -1
- package/dist/client/assets/{SkillMultiselect-ILMft-Kz.js → SkillMultiselect-B0qi32SQ.js} +1 -1
- package/dist/client/assets/{SkillsView-x4_YwBz6.js → SkillsView-umVjRq6o.js} +1 -1
- package/dist/client/assets/TodoView-CFifSvrD.js +6 -0
- package/dist/client/assets/TodoView-SeO9o7km.css +1 -0
- package/dist/client/assets/{folder-open-DDdJt8aE.js → folder-open-nYPrL1W3.js} +1 -1
- package/dist/client/assets/index-Bc8nfKeH.js +661 -0
- package/dist/client/assets/index-C1prPuSl.css +1 -0
- package/dist/client/assets/{list-checks-DFxQ9biT.js → list-checks-sK8xJeH_.js} +1 -1
- package/dist/client/assets/{star-BKs1bgJN.js → star-BRtXbYkB.js} +1 -1
- package/dist/client/assets/{upload-Bb5Pidne.js → upload-BP60eBwN.js} +1 -1
- package/dist/client/assets/{users-BImNn91Q.js → users-qSGAX2Pf.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/client/sw.js +6 -0
- package/dist/client/version.json +1 -1
- package/dist/droid-cli/index.ts +127 -0
- package/dist/droid-cli/package.json +37 -0
- package/dist/droid-cli/src/__tests__/control-handler.test.ts +164 -0
- package/dist/droid-cli/src/__tests__/event-bridge.test.ts +1318 -0
- package/dist/droid-cli/src/__tests__/mcp-config.test.ts +310 -0
- package/dist/droid-cli/src/__tests__/process-manager.test.ts +818 -0
- package/dist/droid-cli/src/__tests__/prompt-builder.test.ts +1206 -0
- package/dist/droid-cli/src/__tests__/provider.test.ts +1894 -0
- package/dist/droid-cli/src/__tests__/setup-test-isolation.test.ts +32 -0
- package/dist/droid-cli/src/__tests__/setup-test-isolation.ts +14 -0
- package/dist/droid-cli/src/__tests__/stream-parser.test.ts +188 -0
- package/dist/droid-cli/src/__tests__/thinking-config.test.ts +141 -0
- package/dist/droid-cli/src/__tests__/tool-mapping.test.ts +253 -0
- package/dist/droid-cli/src/control-handler.ts +82 -0
- package/dist/droid-cli/src/event-bridge.ts +397 -0
- package/dist/droid-cli/src/mcp-config.ts +144 -0
- package/dist/droid-cli/src/mcp-schema-server.cjs +49 -0
- package/dist/droid-cli/src/process-manager.ts +358 -0
- package/dist/droid-cli/src/prompt-builder.ts +629 -0
- package/dist/droid-cli/src/provider.ts +447 -0
- package/dist/droid-cli/src/stream-parser.ts +37 -0
- package/dist/droid-cli/src/thinking-config.ts +83 -0
- package/dist/droid-cli/src/tool-mapping.ts +147 -0
- package/dist/droid-cli/src/types.ts +87 -0
- package/dist/extension.js +473 -119
- package/dist/pi-claude-cli/package.json +1 -1
- package/package.json +2 -1
- package/dist/client/assets/AgentDetailView-B7j297GT.js +0 -18
- package/dist/client/assets/ChatView-BgUt38ty.js +0 -1
- package/dist/client/assets/PiExtensionsManager-DHt2zFg8.js +0 -11
- package/dist/client/assets/SettingsModal-9HS8MnmW.css +0 -1
- package/dist/client/assets/SettingsModal-UziTDnLh.js +0 -31
- package/dist/client/assets/TodoView-BBYcMbXE.js +0 -6
- package/dist/client/assets/TodoView-C1g65hJo.css +0 -1
- package/dist/client/assets/index-B15xwijw.css +0 -1
- package/dist/client/assets/index-DmSs2FGE.js +0 -661
package/dist/bin.js
CHANGED
|
@@ -1009,11 +1009,40 @@ function hasAgentIdentity(agent) {
|
|
|
1009
1009
|
if (!agent) return false;
|
|
1010
1010
|
return !!(agent.soul?.trim() || agent.instructionsText?.trim() || agent.instructionsPath?.trim() || agent.memory?.trim());
|
|
1011
1011
|
}
|
|
1012
|
-
function
|
|
1012
|
+
function slugifyAgentAssetSegment(value) {
|
|
1013
|
+
return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
1014
|
+
}
|
|
1015
|
+
function getSafeAgentAssetIdSegment(agentId) {
|
|
1016
|
+
const slug = slugifyAgentAssetSegment(agentId);
|
|
1017
|
+
return slug || "agent";
|
|
1018
|
+
}
|
|
1019
|
+
function getCanonicalAgentAssetDirectoryName(agentName, agentId) {
|
|
1020
|
+
if (!agentId || typeof agentId !== "string") {
|
|
1021
|
+
throw new Error("getCanonicalAgentAssetDirectoryName requires a non-empty agentId");
|
|
1022
|
+
}
|
|
1023
|
+
const safeId = getSafeAgentAssetIdSegment(agentId);
|
|
1024
|
+
const nameSlug = slugifyAgentAssetSegment(agentName ?? "");
|
|
1025
|
+
const prefix = nameSlug || safeId;
|
|
1026
|
+
return `${prefix}-${safeId}`;
|
|
1027
|
+
}
|
|
1028
|
+
function getLegacyAgentAssetDirectoryName(agentId) {
|
|
1029
|
+
if (!agentId || typeof agentId !== "string") {
|
|
1030
|
+
throw new Error("getLegacyAgentAssetDirectoryName requires a non-empty agentId");
|
|
1031
|
+
}
|
|
1032
|
+
return agentId;
|
|
1033
|
+
}
|
|
1034
|
+
function getCanonicalAgentInstructionsBundleDirName(agentName, agentId) {
|
|
1035
|
+
return `${getCanonicalAgentAssetDirectoryName(agentName, agentId)}-instructions`;
|
|
1036
|
+
}
|
|
1037
|
+
function getLegacyAgentInstructionsBundleDirName(agentId) {
|
|
1038
|
+
return `${getLegacyAgentAssetDirectoryName(agentId)}-instructions`;
|
|
1039
|
+
}
|
|
1040
|
+
function getDefaultHeartbeatProcedurePath(agentId, agentName) {
|
|
1013
1041
|
if (!agentId || typeof agentId !== "string") {
|
|
1014
1042
|
throw new Error("getDefaultHeartbeatProcedurePath requires a non-empty agentId");
|
|
1015
1043
|
}
|
|
1016
|
-
|
|
1044
|
+
const directory = agentName ? getCanonicalAgentAssetDirectoryName(agentName, agentId) : getLegacyAgentAssetDirectoryName(agentId);
|
|
1045
|
+
return `.fusion/agents/${directory}/HEARTBEAT.md`;
|
|
1017
1046
|
}
|
|
1018
1047
|
function agentToConfigSnapshot(agent) {
|
|
1019
1048
|
return {
|
|
@@ -2707,7 +2736,7 @@ var init_db = __esm({
|
|
|
2707
2736
|
"use strict";
|
|
2708
2737
|
init_sqlite_adapter();
|
|
2709
2738
|
init_types();
|
|
2710
|
-
SCHEMA_VERSION =
|
|
2739
|
+
SCHEMA_VERSION = 58;
|
|
2711
2740
|
SCHEMA_SQL = `
|
|
2712
2741
|
-- Tasks table with JSON columns for nested data
|
|
2713
2742
|
CREATE TABLE IF NOT EXISTS tasks (
|
|
@@ -4408,6 +4437,27 @@ CREATE INDEX IF NOT EXISTS idxTodoItemsSortOrder ON todo_items(listId, sortOrder
|
|
|
4408
4437
|
}
|
|
4409
4438
|
});
|
|
4410
4439
|
}
|
|
4440
|
+
if (version < 58) {
|
|
4441
|
+
this.applyMigration(58, () => {
|
|
4442
|
+
const newCommand = "npx runfusion.ai backup --create";
|
|
4443
|
+
if (this.hasTable("automations") && this.hasColumn("automations", "command")) {
|
|
4444
|
+
this.db.prepare(
|
|
4445
|
+
`UPDATE automations
|
|
4446
|
+
SET command = ?, updatedAt = ?
|
|
4447
|
+
WHERE name = 'Database Backup'
|
|
4448
|
+
AND (command LIKE 'fn backup%' OR command LIKE 'kb backup%' OR command LIKE 'fusion backup%')`
|
|
4449
|
+
).run(newCommand, (/* @__PURE__ */ new Date()).toISOString());
|
|
4450
|
+
}
|
|
4451
|
+
if (this.hasTable("routines") && this.hasColumn("routines", "command")) {
|
|
4452
|
+
this.db.prepare(
|
|
4453
|
+
`UPDATE routines
|
|
4454
|
+
SET command = ?, updatedAt = ?
|
|
4455
|
+
WHERE name = 'Database Backup'
|
|
4456
|
+
AND (command LIKE 'fn backup%' OR command LIKE 'kb backup%' OR command LIKE 'fusion backup%')`
|
|
4457
|
+
).run(newCommand, (/* @__PURE__ */ new Date()).toISOString());
|
|
4458
|
+
}
|
|
4459
|
+
});
|
|
4460
|
+
}
|
|
4411
4461
|
}
|
|
4412
4462
|
/**
|
|
4413
4463
|
* Run a single migration step inside a transaction and bump the version.
|
|
@@ -4671,7 +4721,7 @@ var init_agent_store = __esm({
|
|
|
4671
4721
|
if (agent.heartbeatProcedurePath !== DEFAULT_HEARTBEAT_PROCEDURE_PATH) {
|
|
4672
4722
|
continue;
|
|
4673
4723
|
}
|
|
4674
|
-
const newRelPath =
|
|
4724
|
+
const newRelPath = await this.resolveCompatibleHeartbeatProcedurePath(agent);
|
|
4675
4725
|
const newAbsPath = join3(this.rootDir, "..", newRelPath);
|
|
4676
4726
|
if (legacyContent !== null) {
|
|
4677
4727
|
try {
|
|
@@ -4832,7 +4882,7 @@ var init_agent_store = __esm({
|
|
|
4832
4882
|
const metadata = input.metadata ?? {};
|
|
4833
4883
|
const runtimeConfig = resolveCreationRuntimeConfig(input.runtimeConfig, metadata);
|
|
4834
4884
|
const ephemeral = isEphemeralAgent({ metadata, name: input.name, role: input.role, reportsTo: input.reportsTo });
|
|
4835
|
-
const resolvedHeartbeatProcedurePath = input.heartbeatProcedurePath ?? (ephemeral ? void 0 : getDefaultHeartbeatProcedurePath(agentId));
|
|
4885
|
+
const resolvedHeartbeatProcedurePath = input.heartbeatProcedurePath ?? (ephemeral ? void 0 : getDefaultHeartbeatProcedurePath(agentId, input.name));
|
|
4836
4886
|
const agent = {
|
|
4837
4887
|
id: agentId,
|
|
4838
4888
|
name: input.name.trim(),
|
|
@@ -5069,14 +5119,16 @@ var init_agent_store = __esm({
|
|
|
5069
5119
|
* Does not create the directory.
|
|
5070
5120
|
*/
|
|
5071
5121
|
getInstructionsDir(agentId) {
|
|
5072
|
-
|
|
5122
|
+
const agent = this.readAgent(agentId);
|
|
5123
|
+
const agentName = agent?.name ?? "";
|
|
5124
|
+
return join3(this.agentsDir, getCanonicalAgentInstructionsBundleDirName(agentName, agentId));
|
|
5073
5125
|
}
|
|
5074
5126
|
/**
|
|
5075
5127
|
* List markdown files in an agent's managed instructions bundle.
|
|
5076
5128
|
* Returns [] when the bundle directory does not exist.
|
|
5077
5129
|
*/
|
|
5078
5130
|
async listBundleFiles(agentId) {
|
|
5079
|
-
const bundleDir = this.
|
|
5131
|
+
const bundleDir = await this.resolveCompatibleBundleDir(agentId, false);
|
|
5080
5132
|
try {
|
|
5081
5133
|
const entries = await readdir(bundleDir, { withFileTypes: true });
|
|
5082
5134
|
return entries.filter((entry) => entry.isFile() && entry.name.endsWith(".md")).map((entry) => entry.name).sort((a, b) => a.localeCompare(b));
|
|
@@ -5092,7 +5144,8 @@ var init_agent_store = __esm({
|
|
|
5092
5144
|
*/
|
|
5093
5145
|
async readBundleFile(agentId, filePath) {
|
|
5094
5146
|
this.validateBundleFilePath(filePath);
|
|
5095
|
-
const
|
|
5147
|
+
const bundleDir = await this.resolveCompatibleBundleDir(agentId, false);
|
|
5148
|
+
const resolvedPath = join3(bundleDir, filePath);
|
|
5096
5149
|
return readFile(resolvedPath, "utf-8");
|
|
5097
5150
|
}
|
|
5098
5151
|
/**
|
|
@@ -5101,7 +5154,7 @@ var init_agent_store = __esm({
|
|
|
5101
5154
|
async writeBundleFile(agentId, filePath, content) {
|
|
5102
5155
|
return this.withLock(agentId, async () => {
|
|
5103
5156
|
this.validateBundleFilePath(filePath);
|
|
5104
|
-
const bundleDir = this.
|
|
5157
|
+
const bundleDir = await this.resolveCompatibleBundleDir(agentId, true);
|
|
5105
5158
|
await mkdir(bundleDir, { recursive: true });
|
|
5106
5159
|
const existingFiles = await this.listBundleFiles(agentId);
|
|
5107
5160
|
const isOverwrite = existingFiles.includes(filePath);
|
|
@@ -5120,7 +5173,8 @@ var init_agent_store = __esm({
|
|
|
5120
5173
|
async deleteBundleFile(agentId, filePath) {
|
|
5121
5174
|
return this.withLock(agentId, async () => {
|
|
5122
5175
|
this.validateBundleFilePath(filePath);
|
|
5123
|
-
await
|
|
5176
|
+
const bundleDir = await this.resolveCompatibleBundleDir(agentId, false);
|
|
5177
|
+
await unlink(join3(bundleDir, filePath));
|
|
5124
5178
|
});
|
|
5125
5179
|
}
|
|
5126
5180
|
/**
|
|
@@ -5142,7 +5196,7 @@ var init_agent_store = __esm({
|
|
|
5142
5196
|
};
|
|
5143
5197
|
const updated = await this.updateAgent(agentId, { bundleConfig: normalizedConfig });
|
|
5144
5198
|
if (normalizedConfig.mode === "managed") {
|
|
5145
|
-
await mkdir(this.
|
|
5199
|
+
await mkdir(await this.resolveCompatibleBundleDir(agentId, true), { recursive: true });
|
|
5146
5200
|
}
|
|
5147
5201
|
return updated;
|
|
5148
5202
|
}
|
|
@@ -5165,7 +5219,7 @@ var init_agent_store = __esm({
|
|
|
5165
5219
|
bundleConfig: { mode: "managed", entryFile, files: [] }
|
|
5166
5220
|
});
|
|
5167
5221
|
}
|
|
5168
|
-
await mkdir(this.
|
|
5222
|
+
await mkdir(await this.resolveCompatibleBundleDir(agentId, true), { recursive: true });
|
|
5169
5223
|
const files = [];
|
|
5170
5224
|
if (hasInstructionsText) {
|
|
5171
5225
|
await this.writeBundleFile(agentId, entryFile, agent.instructionsText ?? "");
|
|
@@ -6126,8 +6180,87 @@ var init_agent_store = __esm({
|
|
|
6126
6180
|
}
|
|
6127
6181
|
return null;
|
|
6128
6182
|
}
|
|
6129
|
-
|
|
6130
|
-
return join3(this.agentsDir,
|
|
6183
|
+
getCanonicalBundleDir(agent) {
|
|
6184
|
+
return join3(this.agentsDir, getCanonicalAgentInstructionsBundleDirName(agent.name, agent.id));
|
|
6185
|
+
}
|
|
6186
|
+
getLegacyBundleDir(agentId) {
|
|
6187
|
+
return join3(this.agentsDir, getLegacyAgentInstructionsBundleDirName(agentId));
|
|
6188
|
+
}
|
|
6189
|
+
async resolveCompatibleBundleDir(agentId, createIfMissing) {
|
|
6190
|
+
const agent = this.readAgent(agentId);
|
|
6191
|
+
if (!agent) {
|
|
6192
|
+
throw new Error(`Agent ${agentId} not found`);
|
|
6193
|
+
}
|
|
6194
|
+
const canonicalDir = this.getCanonicalBundleDir(agent);
|
|
6195
|
+
if (await this.pathExists(canonicalDir)) {
|
|
6196
|
+
return canonicalDir;
|
|
6197
|
+
}
|
|
6198
|
+
const compatibleDir = await this.findExistingDisplayNameBundleDir(agent);
|
|
6199
|
+
if (compatibleDir) {
|
|
6200
|
+
return compatibleDir;
|
|
6201
|
+
}
|
|
6202
|
+
const legacyDir = this.getLegacyBundleDir(agent.id);
|
|
6203
|
+
if (await this.pathExists(legacyDir)) {
|
|
6204
|
+
return legacyDir;
|
|
6205
|
+
}
|
|
6206
|
+
return createIfMissing ? canonicalDir : canonicalDir;
|
|
6207
|
+
}
|
|
6208
|
+
async findExistingDisplayNameBundleDir(agent) {
|
|
6209
|
+
const safeId = getSafeAgentAssetIdSegment(agent.id);
|
|
6210
|
+
try {
|
|
6211
|
+
const entries = await readdir(this.agentsDir, { withFileTypes: true });
|
|
6212
|
+
const candidates = entries.filter((entry) => entry.isDirectory() && entry.name.endsWith("-instructions")).map((entry) => entry.name).filter((name) => {
|
|
6213
|
+
const base = name.slice(0, -"-instructions".length);
|
|
6214
|
+
return base.endsWith(`-${safeId}`);
|
|
6215
|
+
}).sort((a, b) => a.localeCompare(b));
|
|
6216
|
+
if (candidates.length === 0) {
|
|
6217
|
+
return null;
|
|
6218
|
+
}
|
|
6219
|
+
const canonicalName = getCanonicalAgentInstructionsBundleDirName(agent.name, agent.id);
|
|
6220
|
+
const selected = candidates.find((candidate) => candidate === canonicalName) ?? candidates[0];
|
|
6221
|
+
return join3(this.agentsDir, selected);
|
|
6222
|
+
} catch (err) {
|
|
6223
|
+
if (err.code === "ENOENT") {
|
|
6224
|
+
return null;
|
|
6225
|
+
}
|
|
6226
|
+
throw err;
|
|
6227
|
+
}
|
|
6228
|
+
}
|
|
6229
|
+
async resolveCompatibleHeartbeatProcedurePath(agent) {
|
|
6230
|
+
const canonicalPath = getDefaultHeartbeatProcedurePath(agent.id, agent.name);
|
|
6231
|
+
const canonicalAbs = join3(this.rootDir, "..", canonicalPath);
|
|
6232
|
+
if (await this.pathExists(canonicalAbs)) {
|
|
6233
|
+
return canonicalPath;
|
|
6234
|
+
}
|
|
6235
|
+
const safeId = getSafeAgentAssetIdSegment(agent.id);
|
|
6236
|
+
try {
|
|
6237
|
+
const entries = await readdir(this.agentsDir, { withFileTypes: true });
|
|
6238
|
+
const compatibleDir = entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name).find((name) => name.endsWith(`-${safeId}`));
|
|
6239
|
+
if (compatibleDir) {
|
|
6240
|
+
const candidatePath = `.fusion/agents/${compatibleDir}/HEARTBEAT.md`;
|
|
6241
|
+
if (await this.pathExists(join3(this.rootDir, "..", candidatePath))) {
|
|
6242
|
+
return candidatePath;
|
|
6243
|
+
}
|
|
6244
|
+
}
|
|
6245
|
+
} catch (err) {
|
|
6246
|
+
if (err.code !== "ENOENT") {
|
|
6247
|
+
throw err;
|
|
6248
|
+
}
|
|
6249
|
+
}
|
|
6250
|
+
const legacyPath = `.fusion/agents/${getLegacyAgentAssetDirectoryName(agent.id)}/HEARTBEAT.md`;
|
|
6251
|
+
const legacyAbs = join3(this.rootDir, "..", legacyPath);
|
|
6252
|
+
if (await this.pathExists(legacyAbs)) {
|
|
6253
|
+
return legacyPath;
|
|
6254
|
+
}
|
|
6255
|
+
return canonicalPath;
|
|
6256
|
+
}
|
|
6257
|
+
async pathExists(path5) {
|
|
6258
|
+
try {
|
|
6259
|
+
await access(path5, fsConstants.F_OK);
|
|
6260
|
+
return true;
|
|
6261
|
+
} catch {
|
|
6262
|
+
return false;
|
|
6263
|
+
}
|
|
6131
6264
|
}
|
|
6132
6265
|
validateBundleFilePath(filePath) {
|
|
6133
6266
|
if (typeof filePath !== "string") {
|
|
@@ -7013,9 +7146,9 @@ var init_global_settings = __esm({
|
|
|
7013
7146
|
* Serialize operations via promise chain to prevent lost-update races.
|
|
7014
7147
|
*/
|
|
7015
7148
|
withLock(fn) {
|
|
7016
|
-
let
|
|
7149
|
+
let resolve42;
|
|
7017
7150
|
const next = new Promise((r) => {
|
|
7018
|
-
|
|
7151
|
+
resolve42 = r;
|
|
7019
7152
|
});
|
|
7020
7153
|
const prev = this.lock;
|
|
7021
7154
|
this.lock = next;
|
|
@@ -7023,7 +7156,7 @@ var init_global_settings = __esm({
|
|
|
7023
7156
|
try {
|
|
7024
7157
|
return await fn();
|
|
7025
7158
|
} finally {
|
|
7026
|
-
|
|
7159
|
+
resolve42();
|
|
7027
7160
|
}
|
|
7028
7161
|
});
|
|
7029
7162
|
}
|
|
@@ -28483,8 +28616,8 @@ var require_CronFileParser = __commonJS({
|
|
|
28483
28616
|
* @throws If file cannot be read
|
|
28484
28617
|
*/
|
|
28485
28618
|
static parseFileSync(filePath) {
|
|
28486
|
-
const { readFileSync:
|
|
28487
|
-
const data =
|
|
28619
|
+
const { readFileSync: readFileSync25 } = __require("fs");
|
|
28620
|
+
const data = readFileSync25(filePath, "utf8");
|
|
28488
28621
|
return _CronFileParser.#parseContent(data);
|
|
28489
28622
|
}
|
|
28490
28623
|
/**
|
|
@@ -28701,9 +28834,9 @@ var init_automation_store = __esm({
|
|
|
28701
28834
|
*/
|
|
28702
28835
|
withScheduleLock(id, fn) {
|
|
28703
28836
|
const prev = this.scheduleLocks.get(id) ?? Promise.resolve();
|
|
28704
|
-
let
|
|
28837
|
+
let resolve42;
|
|
28705
28838
|
const next = new Promise((r) => {
|
|
28706
|
-
|
|
28839
|
+
resolve42 = r;
|
|
28707
28840
|
});
|
|
28708
28841
|
this.scheduleLocks.set(id, next);
|
|
28709
28842
|
return prev.then(async () => {
|
|
@@ -28713,7 +28846,7 @@ var init_automation_store = __esm({
|
|
|
28713
28846
|
if (this.scheduleLocks.get(id) === next) {
|
|
28714
28847
|
this.scheduleLocks.delete(id);
|
|
28715
28848
|
}
|
|
28716
|
-
|
|
28849
|
+
resolve42();
|
|
28717
28850
|
}
|
|
28718
28851
|
});
|
|
28719
28852
|
}
|
|
@@ -30502,7 +30635,7 @@ var init_project_memory = __esm({
|
|
|
30502
30635
|
// ../core/src/run-command.ts
|
|
30503
30636
|
import { spawn } from "node:child_process";
|
|
30504
30637
|
function runCommandAsync(command, options = {}) {
|
|
30505
|
-
return new Promise((
|
|
30638
|
+
return new Promise((resolve42) => {
|
|
30506
30639
|
const maxBuffer = options.maxBuffer ?? DEFAULT_MAX_BUFFER;
|
|
30507
30640
|
let stdout = "";
|
|
30508
30641
|
let stderr = "";
|
|
@@ -30561,7 +30694,7 @@ function runCommandAsync(command, options = {}) {
|
|
|
30561
30694
|
clearTimeout(forceKillTimer);
|
|
30562
30695
|
forceKillTimer = null;
|
|
30563
30696
|
}
|
|
30564
|
-
|
|
30697
|
+
resolve42({
|
|
30565
30698
|
stdout,
|
|
30566
30699
|
stderr,
|
|
30567
30700
|
exitCode: null,
|
|
@@ -30579,7 +30712,7 @@ function runCommandAsync(command, options = {}) {
|
|
|
30579
30712
|
}
|
|
30580
30713
|
signalProcessGroup("SIGTERM");
|
|
30581
30714
|
scheduleForceKill(NORMAL_CLEANUP_FORCE_KILL_DELAY_MS);
|
|
30582
|
-
|
|
30715
|
+
resolve42({
|
|
30583
30716
|
stdout,
|
|
30584
30717
|
stderr,
|
|
30585
30718
|
exitCode: code,
|
|
@@ -31794,9 +31927,9 @@ ${outcome}`;
|
|
|
31794
31927
|
* lost-update races on the nextId counter.
|
|
31795
31928
|
*/
|
|
31796
31929
|
withConfigLock(fn) {
|
|
31797
|
-
let
|
|
31930
|
+
let resolve42;
|
|
31798
31931
|
const next = new Promise((r) => {
|
|
31799
|
-
|
|
31932
|
+
resolve42 = r;
|
|
31800
31933
|
});
|
|
31801
31934
|
const prev = this.configLock;
|
|
31802
31935
|
this.configLock = next;
|
|
@@ -31804,7 +31937,7 @@ ${outcome}`;
|
|
|
31804
31937
|
try {
|
|
31805
31938
|
return await fn();
|
|
31806
31939
|
} finally {
|
|
31807
|
-
|
|
31940
|
+
resolve42();
|
|
31808
31941
|
}
|
|
31809
31942
|
});
|
|
31810
31943
|
}
|
|
@@ -31814,9 +31947,9 @@ ${outcome}`;
|
|
|
31814
31947
|
*/
|
|
31815
31948
|
withTaskLock(id, fn) {
|
|
31816
31949
|
const prev = this.taskLocks.get(id) ?? Promise.resolve();
|
|
31817
|
-
let
|
|
31950
|
+
let resolve42;
|
|
31818
31951
|
const next = new Promise((r) => {
|
|
31819
|
-
|
|
31952
|
+
resolve42 = r;
|
|
31820
31953
|
});
|
|
31821
31954
|
this.taskLocks.set(id, next);
|
|
31822
31955
|
return prev.then(async () => {
|
|
@@ -31826,7 +31959,7 @@ ${outcome}`;
|
|
|
31826
31959
|
if (this.taskLocks.get(id) === next) {
|
|
31827
31960
|
this.taskLocks.delete(id);
|
|
31828
31961
|
}
|
|
31829
|
-
|
|
31962
|
+
resolve42();
|
|
31830
31963
|
}
|
|
31831
31964
|
});
|
|
31832
31965
|
}
|
|
@@ -34094,7 +34227,7 @@ ${task.description}
|
|
|
34094
34227
|
}
|
|
34095
34228
|
}
|
|
34096
34229
|
}
|
|
34097
|
-
await new Promise((
|
|
34230
|
+
await new Promise((resolve42) => setImmediate(resolve42));
|
|
34098
34231
|
const selectClause = this.getTaskSelectClause(true);
|
|
34099
34232
|
const changedRows = this.lastPollTime ? this.db.prepare(`SELECT ${selectClause} FROM tasks WHERE updatedAt > ? OR columnMovedAt > ?`).all(this.lastPollTime, this.lastPollTime) : this.db.prepare(`SELECT ${selectClause} FROM tasks`).all();
|
|
34100
34233
|
this.lastPollTime = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -34114,7 +34247,7 @@ ${task.description}
|
|
|
34114
34247
|
this.emit("task:updated", task);
|
|
34115
34248
|
}
|
|
34116
34249
|
if (i > 0 && i % 50 === 0) {
|
|
34117
|
-
await new Promise((
|
|
34250
|
+
await new Promise((resolve42) => setImmediate(resolve42));
|
|
34118
34251
|
}
|
|
34119
34252
|
}
|
|
34120
34253
|
const elapsed = Date.now() - startTime;
|
|
@@ -35859,6 +35992,20 @@ function reconcileClaudeCliPaths(paths, vendoredPath) {
|
|
|
35859
35992
|
}
|
|
35860
35993
|
return filtered;
|
|
35861
35994
|
}
|
|
35995
|
+
function isExternalDroidCliPath(p, vendoredPath) {
|
|
35996
|
+
if (vendoredPath && p === vendoredPath) return false;
|
|
35997
|
+
return /(^|[/\\])droid-cli([/\\]|$)/i.test(p);
|
|
35998
|
+
}
|
|
35999
|
+
function reconcileDroidCliPaths(paths, vendoredPath) {
|
|
36000
|
+
if (!vendoredPath) {
|
|
36001
|
+
return [...paths];
|
|
36002
|
+
}
|
|
36003
|
+
const filtered = paths.filter((p) => !isExternalDroidCliPath(p, vendoredPath));
|
|
36004
|
+
if (!filtered.includes(vendoredPath)) {
|
|
36005
|
+
return [vendoredPath, ...filtered];
|
|
36006
|
+
}
|
|
36007
|
+
return filtered;
|
|
36008
|
+
}
|
|
35862
36009
|
function getDisplayPathWithinRoot(root, targetPath) {
|
|
35863
36010
|
const usesWindowsPaths = /^[A-Za-z]:[\\/]/.test(root) || /^[A-Za-z]:[\\/]/.test(targetPath) || root.includes("\\") || targetPath.includes("\\");
|
|
35864
36011
|
const pathApi = usesWindowsPaths ? win32 : { relative: relative2, isAbsolute: isAbsolute5, sep: sep4 };
|
|
@@ -35970,7 +36117,7 @@ function runGh(args, cwd) {
|
|
|
35970
36117
|
}
|
|
35971
36118
|
function runGhAsync(args, cwdOrOptions) {
|
|
35972
36119
|
const { cwd, signal: externalSignal, timeoutMs = DEFAULT_GH_TIMEOUT_MS } = normalizeRunGhOptions(cwdOrOptions);
|
|
35973
|
-
return new Promise((
|
|
36120
|
+
return new Promise((resolve42, reject2) => {
|
|
35974
36121
|
if (externalSignal?.aborted) {
|
|
35975
36122
|
reject2(makeGhError(`gh command aborted: ${describeAbortReason(externalSignal.reason)}`, "ABORT_ERR"));
|
|
35976
36123
|
return;
|
|
@@ -36021,7 +36168,7 @@ function runGhAsync(args, cwdOrOptions) {
|
|
|
36021
36168
|
ghError.stderr = stderr ?? "";
|
|
36022
36169
|
reject2(ghError);
|
|
36023
36170
|
} else {
|
|
36024
|
-
|
|
36171
|
+
resolve42(stdout ?? "");
|
|
36025
36172
|
}
|
|
36026
36173
|
}
|
|
36027
36174
|
);
|
|
@@ -36116,6 +36263,85 @@ var init_gh_cli = __esm({
|
|
|
36116
36263
|
}
|
|
36117
36264
|
});
|
|
36118
36265
|
|
|
36266
|
+
// ../core/src/fn-binary.ts
|
|
36267
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
36268
|
+
import { platform as platform2 } from "node:os";
|
|
36269
|
+
function runProbe(command, args, timeoutMs) {
|
|
36270
|
+
return new Promise((resolve42) => {
|
|
36271
|
+
let stdout = "";
|
|
36272
|
+
let stderr = "";
|
|
36273
|
+
const child = spawn2(command, args, { stdio: ["ignore", "pipe", "pipe"], shell: false });
|
|
36274
|
+
const timer = setTimeout(() => {
|
|
36275
|
+
try {
|
|
36276
|
+
child.kill("SIGKILL");
|
|
36277
|
+
} catch {
|
|
36278
|
+
}
|
|
36279
|
+
}, timeoutMs);
|
|
36280
|
+
child.stdout?.on("data", (chunk) => {
|
|
36281
|
+
stdout += chunk.toString("utf8");
|
|
36282
|
+
});
|
|
36283
|
+
child.stderr?.on("data", (chunk) => {
|
|
36284
|
+
stderr += chunk.toString("utf8");
|
|
36285
|
+
});
|
|
36286
|
+
child.on("error", (err) => {
|
|
36287
|
+
clearTimeout(timer);
|
|
36288
|
+
resolve42({ exitCode: null, stdout, stderr: stderr || err.message });
|
|
36289
|
+
});
|
|
36290
|
+
child.on("close", (exitCode) => {
|
|
36291
|
+
clearTimeout(timer);
|
|
36292
|
+
resolve42({ exitCode, stdout, stderr });
|
|
36293
|
+
});
|
|
36294
|
+
});
|
|
36295
|
+
}
|
|
36296
|
+
async function whichBinary(name) {
|
|
36297
|
+
const isWindows = platform2() === "win32";
|
|
36298
|
+
const lookup = isWindows ? "where" : "which";
|
|
36299
|
+
const result = await runProbe(lookup, [name], 5e3);
|
|
36300
|
+
if (result.exitCode !== 0) return void 0;
|
|
36301
|
+
const firstLine = result.stdout.split(/\r?\n/).map((s) => s.trim()).find(Boolean);
|
|
36302
|
+
return firstLine || void 0;
|
|
36303
|
+
}
|
|
36304
|
+
async function probeVersion(binary) {
|
|
36305
|
+
const result = await runProbe(binary, ["--version"], 1e4);
|
|
36306
|
+
if (result.exitCode !== 0) return void 0;
|
|
36307
|
+
const text = (result.stdout || result.stderr).trim();
|
|
36308
|
+
if (!text) return void 0;
|
|
36309
|
+
const match = text.match(/\d+\.\d+\.\d+(?:-[\w.]+)?/);
|
|
36310
|
+
return match ? match[0] : text.split(/\s+/)[0];
|
|
36311
|
+
}
|
|
36312
|
+
async function detectFnBinary() {
|
|
36313
|
+
for (const candidate of CANDIDATES) {
|
|
36314
|
+
try {
|
|
36315
|
+
const resolvedPath = await whichBinary(candidate);
|
|
36316
|
+
if (!resolvedPath) continue;
|
|
36317
|
+
const version = await probeVersion(candidate);
|
|
36318
|
+
return {
|
|
36319
|
+
installed: true,
|
|
36320
|
+
binary: candidate,
|
|
36321
|
+
path: resolvedPath,
|
|
36322
|
+
version,
|
|
36323
|
+
invocation: candidate
|
|
36324
|
+
};
|
|
36325
|
+
} catch {
|
|
36326
|
+
}
|
|
36327
|
+
}
|
|
36328
|
+
return {
|
|
36329
|
+
installed: false,
|
|
36330
|
+
invocation: FN_NPX_INVOCATION
|
|
36331
|
+
};
|
|
36332
|
+
}
|
|
36333
|
+
var FN_NPM_PACKAGE, FN_INSTALL_CURL, FN_INSTALL_NPM, FN_NPX_INVOCATION, CANDIDATES;
|
|
36334
|
+
var init_fn_binary = __esm({
|
|
36335
|
+
"../core/src/fn-binary.ts"() {
|
|
36336
|
+
"use strict";
|
|
36337
|
+
FN_NPM_PACKAGE = "runfusion.ai";
|
|
36338
|
+
FN_INSTALL_CURL = "curl -fsSL https://runfusion.ai/install.sh | sh";
|
|
36339
|
+
FN_INSTALL_NPM = `npm install -g ${FN_NPM_PACKAGE}`;
|
|
36340
|
+
FN_NPX_INVOCATION = `npx -y ${FN_NPM_PACKAGE}`;
|
|
36341
|
+
CANDIDATES = ["fn", "fusion"];
|
|
36342
|
+
}
|
|
36343
|
+
});
|
|
36344
|
+
|
|
36119
36345
|
// ../core/src/settings-validation.ts
|
|
36120
36346
|
function validateUnavailableNodePolicy(value) {
|
|
36121
36347
|
if (value === void 0) {
|
|
@@ -36309,9 +36535,9 @@ var init_routine_store = __esm({
|
|
|
36309
36535
|
*/
|
|
36310
36536
|
withRoutineLock(id, fn) {
|
|
36311
36537
|
const prev = this.routineLocks.get(id) ?? Promise.resolve();
|
|
36312
|
-
let
|
|
36538
|
+
let resolve42;
|
|
36313
36539
|
const next = new Promise((r) => {
|
|
36314
|
-
|
|
36540
|
+
resolve42 = r;
|
|
36315
36541
|
});
|
|
36316
36542
|
this.routineLocks.set(id, next);
|
|
36317
36543
|
return prev.then(async () => {
|
|
@@ -36321,7 +36547,7 @@ var init_routine_store = __esm({
|
|
|
36321
36547
|
if (this.routineLocks.get(id) === next) {
|
|
36322
36548
|
this.routineLocks.delete(id);
|
|
36323
36549
|
}
|
|
36324
|
-
|
|
36550
|
+
resolve42();
|
|
36325
36551
|
}
|
|
36326
36552
|
});
|
|
36327
36553
|
}
|
|
@@ -36920,13 +37146,13 @@ var init_plugin_loader = __esm({
|
|
|
36920
37146
|
* Execute a promise with a timeout.
|
|
36921
37147
|
*/
|
|
36922
37148
|
withTimeout(promise, ms, timeoutMessage) {
|
|
36923
|
-
return new Promise((
|
|
37149
|
+
return new Promise((resolve42, reject2) => {
|
|
36924
37150
|
const timer = setTimeout(() => {
|
|
36925
37151
|
reject2(new Error(timeoutMessage));
|
|
36926
37152
|
}, ms);
|
|
36927
37153
|
promise.then((result) => {
|
|
36928
37154
|
clearTimeout(timer);
|
|
36929
|
-
|
|
37155
|
+
resolve42(result);
|
|
36930
37156
|
}).catch((err) => {
|
|
36931
37157
|
clearTimeout(timer);
|
|
36932
37158
|
reject2(err);
|
|
@@ -40491,7 +40717,7 @@ var require_get_stream = __commonJS({
|
|
|
40491
40717
|
};
|
|
40492
40718
|
const { maxBuffer } = options;
|
|
40493
40719
|
let stream;
|
|
40494
|
-
await new Promise((
|
|
40720
|
+
await new Promise((resolve42, reject2) => {
|
|
40495
40721
|
const rejectPromise = (error) => {
|
|
40496
40722
|
if (error && stream.getBufferedLength() <= BufferConstants.MAX_LENGTH) {
|
|
40497
40723
|
error.bufferedData = stream.getBufferedValue();
|
|
@@ -40503,7 +40729,7 @@ var require_get_stream = __commonJS({
|
|
|
40503
40729
|
rejectPromise(error);
|
|
40504
40730
|
return;
|
|
40505
40731
|
}
|
|
40506
|
-
|
|
40732
|
+
resolve42();
|
|
40507
40733
|
});
|
|
40508
40734
|
stream.on("data", () => {
|
|
40509
40735
|
if (stream.getBufferedLength() > maxBuffer) {
|
|
@@ -41797,7 +42023,7 @@ var require_extract_zip = __commonJS({
|
|
|
41797
42023
|
debug("opening", this.zipPath, "with opts", this.opts);
|
|
41798
42024
|
this.zipfile = await openZip(this.zipPath, { lazyEntries: true });
|
|
41799
42025
|
this.canceled = false;
|
|
41800
|
-
return new Promise((
|
|
42026
|
+
return new Promise((resolve42, reject2) => {
|
|
41801
42027
|
this.zipfile.on("error", (err) => {
|
|
41802
42028
|
this.canceled = true;
|
|
41803
42029
|
reject2(err);
|
|
@@ -41806,7 +42032,7 @@ var require_extract_zip = __commonJS({
|
|
|
41806
42032
|
this.zipfile.on("close", () => {
|
|
41807
42033
|
if (!this.canceled) {
|
|
41808
42034
|
debug("zip extraction complete");
|
|
41809
|
-
|
|
42035
|
+
resolve42();
|
|
41810
42036
|
}
|
|
41811
42037
|
});
|
|
41812
42038
|
this.zipfile.on("entry", async (entry) => {
|
|
@@ -50403,6 +50629,10 @@ __export(src_exports, {
|
|
|
50403
50629
|
EXECUTION_MODES: () => EXECUTION_MODES,
|
|
50404
50630
|
FEATURE_LOOP_STATES: () => FEATURE_LOOP_STATES,
|
|
50405
50631
|
FEATURE_STATUSES: () => FEATURE_STATUSES,
|
|
50632
|
+
FN_INSTALL_CURL: () => FN_INSTALL_CURL,
|
|
50633
|
+
FN_INSTALL_NPM: () => FN_INSTALL_NPM,
|
|
50634
|
+
FN_NPM_PACKAGE: () => FN_NPM_PACKAGE,
|
|
50635
|
+
FN_NPX_INVOCATION: () => FN_NPX_INVOCATION,
|
|
50406
50636
|
FileMemoryBackend: () => FileMemoryBackend,
|
|
50407
50637
|
FirstRunDetector: () => FirstRunDetector,
|
|
50408
50638
|
GLOBAL_SETTINGS_KEYS: () => GLOBAL_SETTINGS_KEYS,
|
|
@@ -50514,6 +50744,7 @@ __export(src_exports, {
|
|
|
50514
50744
|
createInsightExtractionAutomation: () => createInsightExtractionAutomation,
|
|
50515
50745
|
createMemoryDreamsAutomation: () => createMemoryDreamsAutomation,
|
|
50516
50746
|
dailyMemoryPath: () => dailyMemoryPath,
|
|
50747
|
+
detectFnBinary: () => detectFnBinary,
|
|
50517
50748
|
detectLegacyData: () => detectLegacyData,
|
|
50518
50749
|
diffConfigSnapshots: () => diffConfigSnapshots,
|
|
50519
50750
|
discoverPiExtensions: () => discoverPiExtensions,
|
|
@@ -50635,6 +50866,7 @@ __export(src_exports, {
|
|
|
50635
50866
|
readProjectMemoryWithBackend: () => readProjectMemoryWithBackend,
|
|
50636
50867
|
readWorkingMemory: () => readWorkingMemory,
|
|
50637
50868
|
reconcileClaudeCliPaths: () => reconcileClaudeCliPaths,
|
|
50869
|
+
reconcileDroidCliPaths: () => reconcileDroidCliPaths,
|
|
50638
50870
|
refreshQmdProjectMemoryIndex: () => refreshQmdProjectMemoryIndex,
|
|
50639
50871
|
registerMemoryBackend: () => registerMemoryBackend,
|
|
50640
50872
|
renderMemoryAuditMarkdown: () => renderMemoryAuditMarkdown,
|
|
@@ -50724,6 +50956,7 @@ var init_src = __esm({
|
|
|
50724
50956
|
init_automation();
|
|
50725
50957
|
init_automation_store();
|
|
50726
50958
|
init_run_command();
|
|
50959
|
+
init_fn_binary();
|
|
50727
50960
|
init_node_override_guard();
|
|
50728
50961
|
init_settings_validation();
|
|
50729
50962
|
init_routine();
|
|
@@ -51885,12 +52118,12 @@ var init_concurrency = __esm({
|
|
|
51885
52118
|
this._active++;
|
|
51886
52119
|
return Promise.resolve();
|
|
51887
52120
|
}
|
|
51888
|
-
return new Promise((
|
|
52121
|
+
return new Promise((resolve42) => {
|
|
51889
52122
|
this._waiters.push({
|
|
51890
52123
|
priority,
|
|
51891
52124
|
resolve: () => {
|
|
51892
52125
|
this._active++;
|
|
51893
|
-
|
|
52126
|
+
resolve42();
|
|
51894
52127
|
}
|
|
51895
52128
|
});
|
|
51896
52129
|
});
|
|
@@ -53454,8 +53687,23 @@ function getPackageManagerAgentDir() {
|
|
|
53454
53687
|
}
|
|
53455
53688
|
function resolveVendoredClaudeCliEntry() {
|
|
53456
53689
|
try {
|
|
53457
|
-
const
|
|
53458
|
-
const pkgJsonPath =
|
|
53690
|
+
const require_3 = createRequire2(import.meta.url);
|
|
53691
|
+
const pkgJsonPath = require_3.resolve("@fusion/pi-claude-cli/package.json");
|
|
53692
|
+
const pkgJson = JSON.parse(readFileSync9(pkgJsonPath, "utf-8"));
|
|
53693
|
+
const extensions = pkgJson.pi?.extensions;
|
|
53694
|
+
if (!Array.isArray(extensions) || extensions.length === 0) return null;
|
|
53695
|
+
const entry = extensions[0];
|
|
53696
|
+
if (typeof entry !== "string" || entry.length === 0) return null;
|
|
53697
|
+
const path5 = resolve11(dirname8(pkgJsonPath), entry);
|
|
53698
|
+
return existsSync20(path5) ? path5 : null;
|
|
53699
|
+
} catch {
|
|
53700
|
+
return null;
|
|
53701
|
+
}
|
|
53702
|
+
}
|
|
53703
|
+
function resolveVendoredDroidCliEntry() {
|
|
53704
|
+
try {
|
|
53705
|
+
const require_3 = createRequire2(import.meta.url);
|
|
53706
|
+
const pkgJsonPath = require_3.resolve("@fusion/droid-cli/package.json");
|
|
53459
53707
|
const pkgJson = JSON.parse(readFileSync9(pkgJsonPath, "utf-8"));
|
|
53460
53708
|
const extensions = pkgJson.pi?.extensions;
|
|
53461
53709
|
if (!Array.isArray(extensions) || extensions.length === 0) return null;
|
|
@@ -53482,8 +53730,13 @@ async function registerExtensionProviders(cwd, modelRegistry) {
|
|
|
53482
53730
|
[...getEnabledPiExtensionPaths(cwd), ...packageExtensionPaths],
|
|
53483
53731
|
vendoredClaudeCli
|
|
53484
53732
|
);
|
|
53485
|
-
const
|
|
53733
|
+
const vendoredDroidCli = resolveVendoredDroidCliEntry();
|
|
53734
|
+
const doubleReconciledPaths = reconcileDroidCliPaths(
|
|
53486
53735
|
reconciledPaths,
|
|
53736
|
+
vendoredDroidCli
|
|
53737
|
+
);
|
|
53738
|
+
const extensionsResult = await discoverAndLoadExtensions(
|
|
53739
|
+
doubleReconciledPaths,
|
|
53487
53740
|
cwd,
|
|
53488
53741
|
join25(resolvePiExtensionProjectRoot(cwd), ".fusion", "disabled-auto-extension-discovery")
|
|
53489
53742
|
);
|
|
@@ -54422,8 +54675,8 @@ var init_page_fetch_provider = __esm({
|
|
|
54422
54675
|
|
|
54423
54676
|
// ../engine/src/research/providers/web-search-provider.ts
|
|
54424
54677
|
async function sleep(ms, signal) {
|
|
54425
|
-
await new Promise((
|
|
54426
|
-
const timer = setTimeout(
|
|
54678
|
+
await new Promise((resolve42, reject2) => {
|
|
54679
|
+
const timer = setTimeout(resolve42, ms);
|
|
54427
54680
|
const onAbort = () => {
|
|
54428
54681
|
clearTimeout(timer);
|
|
54429
54682
|
reject2(new ResearchProviderError({ providerType: "web-search", code: "abort", message: "Search aborted" }));
|
|
@@ -55140,14 +55393,25 @@ async function getAgentMemoryWindow(rootDir, agentMemory, path5, startLine = 1,
|
|
|
55140
55393
|
backend: "agent-memory"
|
|
55141
55394
|
};
|
|
55142
55395
|
}
|
|
55143
|
-
function
|
|
55396
|
+
async function createAgentTask(store, input, options) {
|
|
55397
|
+
const settings = typeof store.getSettings === "function" ? await store.getSettings() : {};
|
|
55398
|
+
const rootDir = options?.rootDir;
|
|
55399
|
+
return store.createTask(input, {
|
|
55400
|
+
settings: { autoSummarizeTitles: settings.autoSummarizeTitles === true },
|
|
55401
|
+
onSummarize: rootDir ? async (description) => {
|
|
55402
|
+
const resolved = resolveTitleSummarizerSettingsModel(settings);
|
|
55403
|
+
return summarizeTitle(description, rootDir, resolved.provider, resolved.modelId);
|
|
55404
|
+
} : void 0
|
|
55405
|
+
});
|
|
55406
|
+
}
|
|
55407
|
+
function createTaskCreateTool(store, provenance, options) {
|
|
55144
55408
|
return {
|
|
55145
55409
|
name: "fn_task_create",
|
|
55146
55410
|
label: "Create Task",
|
|
55147
55411
|
description: "Create a new task for out-of-scope work discovered during execution. The task goes into triage where it will be specified by the AI. Optionally set dependencies (e.g., the new task depends on the current one, or the current task should wait for the new one).",
|
|
55148
55412
|
parameters: taskCreateParams,
|
|
55149
55413
|
execute: async (_id, params) => {
|
|
55150
|
-
const task = await store
|
|
55414
|
+
const task = await createAgentTask(store, {
|
|
55151
55415
|
description: params.description,
|
|
55152
55416
|
dependencies: params.dependencies,
|
|
55153
55417
|
column: "triage",
|
|
@@ -55156,7 +55420,7 @@ function createTaskCreateTool(store, provenance) {
|
|
|
55156
55420
|
sourceAgentId: provenance.sourceAgentId,
|
|
55157
55421
|
sourceRunId: provenance.sourceRunId
|
|
55158
55422
|
} : void 0
|
|
55159
|
-
});
|
|
55423
|
+
}, options);
|
|
55160
55424
|
const deps = task.dependencies.length ? ` (depends on: ${task.dependencies.join(", ")})` : "";
|
|
55161
55425
|
return {
|
|
55162
55426
|
content: [{
|
|
@@ -55509,7 +55773,7 @@ ${lines.join("\n\n")}` }],
|
|
|
55509
55773
|
}
|
|
55510
55774
|
};
|
|
55511
55775
|
}
|
|
55512
|
-
function createDelegateTaskTool(agentStore, taskStore) {
|
|
55776
|
+
function createDelegateTaskTool(agentStore, taskStore, options) {
|
|
55513
55777
|
return {
|
|
55514
55778
|
name: "fn_delegate_task",
|
|
55515
55779
|
label: "Delegate Task",
|
|
@@ -55529,13 +55793,13 @@ function createDelegateTaskTool(agentStore, taskStore) {
|
|
|
55529
55793
|
details: {}
|
|
55530
55794
|
};
|
|
55531
55795
|
}
|
|
55532
|
-
const task = await taskStore
|
|
55796
|
+
const task = await createAgentTask(taskStore, {
|
|
55533
55797
|
description: params.description,
|
|
55534
55798
|
dependencies: params.dependencies,
|
|
55535
55799
|
column: "todo",
|
|
55536
55800
|
assignedAgentId: params.agent_id,
|
|
55537
55801
|
source: { sourceType: "api" }
|
|
55538
|
-
});
|
|
55802
|
+
}, options);
|
|
55539
55803
|
const deps = task.dependencies.length ? ` (depends on: ${task.dependencies.join(", ")})` : "";
|
|
55540
55804
|
return {
|
|
55541
55805
|
content: [{
|
|
@@ -55710,9 +55974,9 @@ function createResearchTools(options) {
|
|
|
55710
55974
|
const maxWaitMs = Math.max(1e3, Math.min(params.max_wait_ms ?? 9e4, resolved.limits.maxDurationMs));
|
|
55711
55975
|
const completed = await Promise.race([
|
|
55712
55976
|
runPromise,
|
|
55713
|
-
new Promise((
|
|
55977
|
+
new Promise((resolve42) => setTimeout(() => {
|
|
55714
55978
|
const latest = options.store.getResearchStore().getRun(runId);
|
|
55715
|
-
|
|
55979
|
+
resolve42(latest ?? {
|
|
55716
55980
|
id: runId,
|
|
55717
55981
|
query: params.query,
|
|
55718
55982
|
status: "running",
|
|
@@ -57286,20 +57550,20 @@ async function withRateLimitRetry(fn, options = {}) {
|
|
|
57286
57550
|
throw lastError ?? new Error("withRateLimitRetry: unexpected state");
|
|
57287
57551
|
}
|
|
57288
57552
|
function sleep2(ms, signal) {
|
|
57289
|
-
return new Promise((
|
|
57553
|
+
return new Promise((resolve42, reject2) => {
|
|
57290
57554
|
if (signal?.aborted) {
|
|
57291
57555
|
reject2(signal.reason ?? new Error("Aborted"));
|
|
57292
57556
|
return;
|
|
57293
57557
|
}
|
|
57294
|
-
const timer = setTimeout(
|
|
57558
|
+
const timer = setTimeout(resolve42, ms);
|
|
57295
57559
|
if (signal) {
|
|
57296
57560
|
const onAbort = () => {
|
|
57297
57561
|
clearTimeout(timer);
|
|
57298
57562
|
reject2(signal.reason ?? new Error("Aborted"));
|
|
57299
57563
|
};
|
|
57300
57564
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
57301
|
-
const origResolve =
|
|
57302
|
-
|
|
57565
|
+
const origResolve = resolve42;
|
|
57566
|
+
resolve42 = () => {
|
|
57303
57567
|
signal.removeEventListener("abort", onAbort);
|
|
57304
57568
|
origResolve();
|
|
57305
57569
|
};
|
|
@@ -58362,7 +58626,7 @@ Write the PROMPT.md directly using the write tool, then call \`fn_review_spec()\
|
|
|
58362
58626
|
// Agent delegation tools — discover and delegate work to other agents.
|
|
58363
58627
|
...this.options.agentStore ? [
|
|
58364
58628
|
createListAgentsTool(this.options.agentStore),
|
|
58365
|
-
createDelegateTaskTool(this.options.agentStore, this.store)
|
|
58629
|
+
createDelegateTaskTool(this.options.agentStore, this.store, { rootDir: this.rootDir })
|
|
58366
58630
|
] : [],
|
|
58367
58631
|
this.createReviewSpecTool(
|
|
58368
58632
|
task.id,
|
|
@@ -58901,7 +59165,7 @@ Remove or replace these ids and call fn_task_create again.`
|
|
|
58901
59165
|
planLog.warn(`${options.parentTaskId}: failed to load parent task for fn_task_create inheritance: ${msg}`);
|
|
58902
59166
|
parentTask = void 0;
|
|
58903
59167
|
}
|
|
58904
|
-
const newTask = await store
|
|
59168
|
+
const newTask = await createAgentTask(store, {
|
|
58905
59169
|
title: params.title,
|
|
58906
59170
|
description: params.description,
|
|
58907
59171
|
dependencies: validDeps,
|
|
@@ -58915,7 +59179,7 @@ Remove or replace these ids and call fn_task_create again.`
|
|
|
58915
59179
|
sourceType: "agent_heartbeat",
|
|
58916
59180
|
sourceParentTaskId: options.parentTaskId
|
|
58917
59181
|
}
|
|
58918
|
-
});
|
|
59182
|
+
}, { rootDir: this.rootDir });
|
|
58919
59183
|
options.createdSubtasksRef.current.push(newTask.id);
|
|
58920
59184
|
return {
|
|
58921
59185
|
content: [
|
|
@@ -59343,13 +59607,13 @@ var init_run_audit = __esm({
|
|
|
59343
59607
|
});
|
|
59344
59608
|
|
|
59345
59609
|
// ../engine/src/merger.ts
|
|
59346
|
-
import { execSync, exec as exec2, spawn as
|
|
59610
|
+
import { execSync, exec as exec2, spawn as spawn3 } from "node:child_process";
|
|
59347
59611
|
import { promisify as promisify3 } from "node:util";
|
|
59348
59612
|
import { existsSync as existsSync22 } from "node:fs";
|
|
59349
59613
|
import { join as join29 } from "node:path";
|
|
59350
59614
|
import { Type as Type3 } from "typebox";
|
|
59351
59615
|
async function execWithProcessGroup(command, options) {
|
|
59352
|
-
return new Promise((
|
|
59616
|
+
return new Promise((resolve42, reject2) => {
|
|
59353
59617
|
if (options.signal?.aborted) {
|
|
59354
59618
|
reject2(Object.assign(
|
|
59355
59619
|
new Error(`Command aborted before start: ${command}`),
|
|
@@ -59358,7 +59622,7 @@ async function execWithProcessGroup(command, options) {
|
|
|
59358
59622
|
return;
|
|
59359
59623
|
}
|
|
59360
59624
|
const useProcessGroup = process.platform !== "win32";
|
|
59361
|
-
const child =
|
|
59625
|
+
const child = spawn3(command, {
|
|
59362
59626
|
cwd: options.cwd,
|
|
59363
59627
|
shell: true,
|
|
59364
59628
|
detached: useProcessGroup,
|
|
@@ -59442,7 +59706,7 @@ async function execWithProcessGroup(command, options) {
|
|
|
59442
59706
|
return;
|
|
59443
59707
|
}
|
|
59444
59708
|
if (code === 0) {
|
|
59445
|
-
|
|
59709
|
+
resolve42({ stdout, stderr, bufferOverflow: stdoutOverflow || stderrOverflow });
|
|
59446
59710
|
return;
|
|
59447
59711
|
}
|
|
59448
59712
|
reject2(Object.assign(
|
|
@@ -63866,7 +64130,7 @@ function resolveExecutorModelPair(taskModelProvider, taskModelId, settings) {
|
|
|
63866
64130
|
return { provider: void 0, modelId: void 0 };
|
|
63867
64131
|
}
|
|
63868
64132
|
function sleep3(ms) {
|
|
63869
|
-
return new Promise((
|
|
64133
|
+
return new Promise((resolve42) => setTimeout(resolve42, ms));
|
|
63870
64134
|
}
|
|
63871
64135
|
var execAsync4, stepExecLog, MAX_STEP_RETRIES, RETRY_DELAYS_MS, NOOP_TASK_STORE, StepSessionExecutor;
|
|
63872
64136
|
var init_step_session_executor = __esm({
|
|
@@ -64094,10 +64358,10 @@ var init_step_session_executor = __esm({
|
|
|
64094
64358
|
] : [];
|
|
64095
64359
|
const memoryTools = createMemoryTools(this.options.rootDir, settings);
|
|
64096
64360
|
const taskLogTool = this.options.store ? [createTaskLogTool(this.options.store, taskDetail.id)] : [];
|
|
64097
|
-
const taskCreateTool = this.options.store ? [createTaskCreateTool(this.options.store)] : [];
|
|
64361
|
+
const taskCreateTool = this.options.store ? [createTaskCreateTool(this.options.store, void 0, { rootDir: this.options.rootDir })] : [];
|
|
64098
64362
|
const delegationTools = this.options.agentStore ? [
|
|
64099
64363
|
createListAgentsTool(this.options.agentStore),
|
|
64100
|
-
createDelegateTaskTool(this.options.agentStore, this.options.store)
|
|
64364
|
+
createDelegateTaskTool(this.options.agentStore, this.options.store, { rootDir: this.options.rootDir })
|
|
64101
64365
|
] : [];
|
|
64102
64366
|
const messagingTools = this.options.messageStore && taskDetail.assignedAgentId ? [
|
|
64103
64367
|
createSendMessageTool(this.options.messageStore, taskDetail.assignedAgentId),
|
|
@@ -64508,7 +64772,7 @@ var init_task_completion = __esm({
|
|
|
64508
64772
|
});
|
|
64509
64773
|
|
|
64510
64774
|
// ../engine/src/run-verification-tool.ts
|
|
64511
|
-
import { spawn as
|
|
64775
|
+
import { spawn as spawn4 } from "node:child_process";
|
|
64512
64776
|
import { existsSync as existsSync26 } from "node:fs";
|
|
64513
64777
|
import { isAbsolute as isAbsolute10, join as join34 } from "node:path";
|
|
64514
64778
|
import { Type as Type4 } from "@mariozechner/pi-ai";
|
|
@@ -64540,8 +64804,8 @@ async function runVerificationCommand2(opts) {
|
|
|
64540
64804
|
const warnings = [];
|
|
64541
64805
|
const stdoutBuf = { head: "", tail: "", totalBytes: 0 };
|
|
64542
64806
|
const stderrBuf = { head: "", tail: "", totalBytes: 0 };
|
|
64543
|
-
return new Promise((
|
|
64544
|
-
const child =
|
|
64807
|
+
return new Promise((resolve42) => {
|
|
64808
|
+
const child = spawn4(command, {
|
|
64545
64809
|
cwd,
|
|
64546
64810
|
stdio: ["ignore", "pipe", "pipe"],
|
|
64547
64811
|
env: { ...process.env },
|
|
@@ -64619,7 +64883,7 @@ async function runVerificationCommand2(opts) {
|
|
|
64619
64883
|
`[fn_run_verification] command failed (exit=${exitCode}, signal=${signal ?? "none"}): ${command}`
|
|
64620
64884
|
);
|
|
64621
64885
|
}
|
|
64622
|
-
|
|
64886
|
+
resolve42({
|
|
64623
64887
|
success,
|
|
64624
64888
|
exitCode,
|
|
64625
64889
|
durationMs,
|
|
@@ -64639,7 +64903,7 @@ async function runVerificationCommand2(opts) {
|
|
|
64639
64903
|
clearTimeout(hardTimer);
|
|
64640
64904
|
const durationMs = Date.now() - startMs;
|
|
64641
64905
|
warnings.push(`Spawn error: ${err.message}`);
|
|
64642
|
-
|
|
64906
|
+
resolve42({
|
|
64643
64907
|
success: false,
|
|
64644
64908
|
exitCode: null,
|
|
64645
64909
|
durationMs,
|
|
@@ -66829,7 +67093,7 @@ The tool prevents your session from being killed by the inactivity watchdog duri
|
|
|
66829
67093
|
// Agent delegation tools — discover and delegate work to other agents.
|
|
66830
67094
|
...this.options.agentStore ? [
|
|
66831
67095
|
createListAgentsTool(this.options.agentStore),
|
|
66832
|
-
createDelegateTaskTool(this.options.agentStore, this.store)
|
|
67096
|
+
createDelegateTaskTool(this.options.agentStore, this.store, { rootDir: this.rootDir })
|
|
66833
67097
|
] : [],
|
|
66834
67098
|
// Messaging tools — allows executor agents to send and receive messages.
|
|
66835
67099
|
...this.options.messageStore && assignedAgentId ? [
|
|
@@ -67523,7 +67787,7 @@ The tool prevents your session from being killed by the inactivity watchdog duri
|
|
|
67523
67787
|
return createTaskLogTool(this.store, taskId);
|
|
67524
67788
|
}
|
|
67525
67789
|
createTaskCreateTool() {
|
|
67526
|
-
return createTaskCreateTool(this.store, { sourceType: "api" });
|
|
67790
|
+
return createTaskCreateTool(this.store, { sourceType: "api" }, { rootDir: this.rootDir });
|
|
67527
67791
|
}
|
|
67528
67792
|
createTaskDocumentWriteTool(taskId) {
|
|
67529
67793
|
return createTaskDocumentWriteTool(this.store, taskId);
|
|
@@ -68617,7 +68881,7 @@ Review the work done in this worktree and evaluate it against the criteria in yo
|
|
|
68617
68881
|
);
|
|
68618
68882
|
}
|
|
68619
68883
|
const delay2 = this.WORKTREE_RETRY_DELAYS[attempt] || 1e3;
|
|
68620
|
-
await new Promise((
|
|
68884
|
+
await new Promise((resolve42) => setTimeout(resolve42, delay2));
|
|
68621
68885
|
}
|
|
68622
68886
|
}
|
|
68623
68887
|
throw new Error("Unexpected exit from worktree creation retry loop");
|
|
@@ -72458,7 +72722,7 @@ function isTickableState(state) {
|
|
|
72458
72722
|
function isHeartbeatManaged(agent) {
|
|
72459
72723
|
return !isEphemeralAgent(agent);
|
|
72460
72724
|
}
|
|
72461
|
-
var HEARTBEAT_SYSTEM_PROMPT, HEARTBEAT_NO_TASK_SYSTEM_PROMPT, HEARTBEAT_PROCEDURE, heartbeatDoneParams, HeartbeatMonitor, OVERDUE_FIRE_JITTER_MS, HeartbeatTriggerScheduler;
|
|
72725
|
+
var HEARTBEAT_SYSTEM_PROMPT, HEARTBEAT_NO_TASK_SYSTEM_PROMPT, HEARTBEAT_PROCEDURE, HEARTBEAT_NO_TASK_PROCEDURE, heartbeatDoneParams, HeartbeatMonitor, OVERDUE_FIRE_JITTER_MS, HeartbeatTriggerScheduler;
|
|
72462
72726
|
var init_agent_heartbeat = __esm({
|
|
72463
72727
|
"../engine/src/agent-heartbeat.ts"() {
|
|
72464
72728
|
"use strict";
|
|
@@ -72648,6 +72912,32 @@ When sending messages:
|
|
|
72648
72912
|
Critical: a heartbeat without observable progress (a log, a document write, a
|
|
72649
72913
|
status change, a comment, a delegation, or an explicit "no-op with reason") is
|
|
72650
72914
|
a bug. Do not loop on the same plan across heartbeats without recording why.`;
|
|
72915
|
+
HEARTBEAT_NO_TASK_PROCEDURE = `## Heartbeat Procedure (run every tick, in order)
|
|
72916
|
+
|
|
72917
|
+
1. **Identity & context** \u2014 review the **Identity Snapshot** at the top of
|
|
72918
|
+
this prompt. Confirm your role, soul, instructions, and memory match what
|
|
72919
|
+
you expect, and surface any anomalies in your first text output before
|
|
72920
|
+
doing anything else. (If fn_identity is available in your runtime you may
|
|
72921
|
+
also call it for full structured detail; the snapshot above is the
|
|
72922
|
+
authoritative source.)
|
|
72923
|
+
2. **Inbox** \u2014 when fn_read_messages is available, call it. Process any pending
|
|
72924
|
+
messages first; reply with reply_to_message_id when answering.
|
|
72925
|
+
3. **Wake delta** \u2014 read the Wake Delta block above. The wake reason is the
|
|
72926
|
+
highest-priority change for this heartbeat. If you were woken by a comment
|
|
72927
|
+
or a message, acknowledge it before doing anything else.
|
|
72928
|
+
4. **Ambient review** \u2014 since you have no assigned task, review board/project
|
|
72929
|
+
signals and recent memory context before acting.
|
|
72930
|
+
5. **Pick the next concrete action** \u2014 exactly ONE useful action this heartbeat:
|
|
72931
|
+
create a focused task, delegate work, send/reply to a message, or append
|
|
72932
|
+
durable memory.
|
|
72933
|
+
6. **Persist progress** \u2014 use available ambient tools only:
|
|
72934
|
+
fn_task_create, fn_delegate_task, fn_send_message, fn_memory_append.
|
|
72935
|
+
7. **Exit** \u2014 call fn_heartbeat_done with a one-line summary of what changed
|
|
72936
|
+
this tick. If you took no action, say so and explain why.
|
|
72937
|
+
|
|
72938
|
+
Critical: a heartbeat without observable progress (a created task, delegation,
|
|
72939
|
+
message reply, memory append, or explicit "no-op with reason") is a bug. Do
|
|
72940
|
+
not loop on the same plan across heartbeats without recording why.`;
|
|
72651
72941
|
heartbeatDoneParams = Type6.Object({
|
|
72652
72942
|
summary: Type6.Optional(Type6.String({ description: "Summary of what was accomplished this heartbeat" }))
|
|
72653
72943
|
});
|
|
@@ -72687,13 +72977,6 @@ a bug. Do not loop on the same plan across heartbeats without recording why.`;
|
|
|
72687
72977
|
this.rootDir = options.rootDir;
|
|
72688
72978
|
this.messageStore = options.messageStore;
|
|
72689
72979
|
this.pluginRunner = options.pluginRunner;
|
|
72690
|
-
this.onRecovered = options.onRecovered;
|
|
72691
|
-
this.onTerminated = options.onTerminated;
|
|
72692
|
-
this.onRunStarted = options.onRunStarted;
|
|
72693
|
-
this.onRunCompleted = options.onRunCompleted;
|
|
72694
|
-
this.taskStore = options.taskStore;
|
|
72695
|
-
this.rootDir = options.rootDir;
|
|
72696
|
-
this.messageStore = options.messageStore;
|
|
72697
72980
|
}
|
|
72698
72981
|
/**
|
|
72699
72982
|
* Start the heartbeat monitoring loop.
|
|
@@ -73392,9 +73675,9 @@ a bug. Do not loop on the same plan across heartbeats without recording why.`;
|
|
|
73392
73675
|
sourceType: "agent_heartbeat",
|
|
73393
73676
|
sourceAgentId: agentId,
|
|
73394
73677
|
sourceRunId: runContext?.runId
|
|
73395
|
-
}));
|
|
73678
|
+
}, { rootDir: this.rootDir }));
|
|
73396
73679
|
heartbeatTools.push(createListAgentsTool(this.store));
|
|
73397
|
-
heartbeatTools.push(createDelegateTaskTool(this.store, taskStore));
|
|
73680
|
+
heartbeatTools.push(createDelegateTaskTool(this.store, taskStore, { rootDir: this.rootDir }));
|
|
73398
73681
|
if (this.messageStore) {
|
|
73399
73682
|
heartbeatTools.push(createSendMessageTool(this.messageStore, agentId));
|
|
73400
73683
|
heartbeatTools.push(createReadMessagesTool(this.messageStore, agentId));
|
|
@@ -73417,22 +73700,27 @@ a bug. Do not loop on the same plan across heartbeats without recording why.`;
|
|
|
73417
73700
|
heartbeatLog.warn(`Failed to configure heartbeat memory tools for ${agentId}: ${message}`);
|
|
73418
73701
|
}
|
|
73419
73702
|
const skillContext = buildSessionSkillContextSync2(agent, "heartbeat", rootDir);
|
|
73420
|
-
|
|
73421
|
-
const baseHeartbeatSystemPrompt = systemPrompt;
|
|
73703
|
+
const baseHeartbeatSystemPrompt = isNoTaskRun ? HEARTBEAT_NO_TASK_SYSTEM_PROMPT : HEARTBEAT_SYSTEM_PROMPT;
|
|
73422
73704
|
let resolvedInstructionsForIdentity = "";
|
|
73423
73705
|
try {
|
|
73424
|
-
|
|
73425
|
-
resolvedInstructionsForIdentity = agentInstructions;
|
|
73426
|
-
const memoryInstructions = memorySettings?.memoryEnabled === false ? "" : buildExecutionMemoryInstructions(rootDir, memorySettings);
|
|
73427
|
-
systemPrompt = buildSystemPromptWithInstructions(
|
|
73428
|
-
baseHeartbeatSystemPrompt,
|
|
73429
|
-
[agentInstructions, memoryInstructions].filter((part) => part.trim()).join("\n\n")
|
|
73430
|
-
);
|
|
73706
|
+
resolvedInstructionsForIdentity = await resolveAgentInstructionsWithRatings(agent, rootDir, this.store);
|
|
73431
73707
|
} catch (instructionError) {
|
|
73432
|
-
systemPrompt = baseHeartbeatSystemPrompt;
|
|
73433
73708
|
const message = instructionError instanceof Error ? instructionError.message : String(instructionError);
|
|
73434
|
-
heartbeatLog.warn(`Failed to
|
|
73709
|
+
heartbeatLog.warn(`Failed to resolve agent instructions for heartbeat ${agentId}: ${message}`);
|
|
73435
73710
|
}
|
|
73711
|
+
let memoryInstructions = "";
|
|
73712
|
+
if (memorySettings?.memoryEnabled !== false) {
|
|
73713
|
+
try {
|
|
73714
|
+
memoryInstructions = buildExecutionMemoryInstructions(rootDir, memorySettings);
|
|
73715
|
+
} catch (memoryInstructionErr) {
|
|
73716
|
+
const message = memoryInstructionErr instanceof Error ? memoryInstructionErr.message : String(memoryInstructionErr);
|
|
73717
|
+
heartbeatLog.warn(`Failed to resolve project memory instructions for heartbeat ${agentId}: ${message}`);
|
|
73718
|
+
}
|
|
73719
|
+
}
|
|
73720
|
+
const systemPrompt = buildSystemPromptWithInstructions(
|
|
73721
|
+
baseHeartbeatSystemPrompt,
|
|
73722
|
+
[resolvedInstructionsForIdentity, memoryInstructions].filter((part) => part.trim()).join("\n\n")
|
|
73723
|
+
);
|
|
73436
73724
|
heartbeatTools.push(createIdentityTool({ agent, resolvedInstructions: resolvedInstructionsForIdentity }));
|
|
73437
73725
|
heartbeatTools.push(heartbeatDoneTool);
|
|
73438
73726
|
if (isNoTaskRun) {
|
|
@@ -73493,7 +73781,7 @@ a bug. Do not loop on the same plan across heartbeats without recording why.`;
|
|
|
73493
73781
|
};
|
|
73494
73782
|
const wakeReason = deriveWakeReason();
|
|
73495
73783
|
const customProcedure = await resolveAgentHeartbeatProcedure(agent, rootDir);
|
|
73496
|
-
const heartbeatProcedureText = customProcedure ?? HEARTBEAT_PROCEDURE;
|
|
73784
|
+
const heartbeatProcedureText = customProcedure ?? (isNoTaskRun ? HEARTBEAT_NO_TASK_PROCEDURE : HEARTBEAT_PROCEDURE);
|
|
73497
73785
|
if (isNoTaskRun) {
|
|
73498
73786
|
if (this.messageStore) {
|
|
73499
73787
|
try {
|
|
@@ -73526,6 +73814,8 @@ a bug. Do not loop on the same plan across heartbeats without recording why.`;
|
|
|
73526
73814
|
`- pending messages: ${pendingMessages.length}`,
|
|
73527
73815
|
"",
|
|
73528
73816
|
"Treat this wake delta as the highest-priority change for this heartbeat.",
|
|
73817
|
+
"This is an autonomous heartbeat run (manual or automatic): re-anchor on",
|
|
73818
|
+
"identity, process wake context, then complete ONE concrete action.",
|
|
73529
73819
|
"Run the Heartbeat Procedure (below) before doing anything else \u2014 even a",
|
|
73530
73820
|
"timer-only wake should re-check messages, memory, and project state.",
|
|
73531
73821
|
"",
|
|
@@ -73617,6 +73907,8 @@ a bug. Do not loop on the same plan across heartbeats without recording why.`;
|
|
|
73617
73907
|
`- triggering comments: ${effectiveTriggeringCommentIds?.length ?? 0}`,
|
|
73618
73908
|
"",
|
|
73619
73909
|
"Treat this wake delta as the highest-priority change for this heartbeat.",
|
|
73910
|
+
"This is an autonomous heartbeat run (manual or automatic): re-anchor on",
|
|
73911
|
+
"identity, process wake context, then complete ONE concrete action.",
|
|
73620
73912
|
"Before resuming prior task work, run the Heartbeat Procedure (below) and",
|
|
73621
73913
|
"decide what action this delta requires. Your assigned task is one input",
|
|
73622
73914
|
"to the procedure \u2014 not the only thing to consider.",
|
|
@@ -73776,7 +74068,7 @@ ${taskDetail.prompt}` : "No PROMPT.md available.",
|
|
|
73776
74068
|
const baseCreateTool = createTaskCreateTool(taskStore, {
|
|
73777
74069
|
sourceType: "agent_heartbeat",
|
|
73778
74070
|
sourceAgentId: agentId
|
|
73779
|
-
});
|
|
74071
|
+
}, { rootDir: this.rootDir });
|
|
73780
74072
|
const trackedCreateTool = {
|
|
73781
74073
|
...baseCreateTool,
|
|
73782
74074
|
execute: async (id, params, signal, onUpdate, ctx) => {
|
|
@@ -73803,7 +74095,7 @@ ${taskDetail.prompt}` : "No PROMPT.md available.",
|
|
|
73803
74095
|
tools.push(createTaskDocumentWriteTool(taskStore, taskId));
|
|
73804
74096
|
tools.push(createTaskDocumentReadTool(taskStore, taskId));
|
|
73805
74097
|
tools.push(createListAgentsTool(this.store));
|
|
73806
|
-
tools.push(createDelegateTaskTool(this.store, taskStore));
|
|
74098
|
+
tools.push(createDelegateTaskTool(this.store, taskStore, { rootDir: this.rootDir }));
|
|
73807
74099
|
if (messageStore) {
|
|
73808
74100
|
tools.push(createSendMessageTool(messageStore, agentId));
|
|
73809
74101
|
tools.push(createReadMessagesTool(messageStore, agentId));
|
|
@@ -75387,7 +75679,7 @@ var init_shell_utils = __esm({
|
|
|
75387
75679
|
// ../engine/src/cron-runner.ts
|
|
75388
75680
|
import { exec as exec6 } from "node:child_process";
|
|
75389
75681
|
function execCommand(command, options) {
|
|
75390
|
-
return new Promise((
|
|
75682
|
+
return new Promise((resolve42, reject2) => {
|
|
75391
75683
|
exec6(command, options, (error, stdout, stderr) => {
|
|
75392
75684
|
const stdoutText = typeof stdout === "string" ? stdout : String(stdout ?? "");
|
|
75393
75685
|
const stderrText = typeof stderr === "string" ? stderr : String(stderr ?? "");
|
|
@@ -75398,7 +75690,7 @@ function execCommand(command, options) {
|
|
|
75398
75690
|
reject2(errWithOutput);
|
|
75399
75691
|
return;
|
|
75400
75692
|
}
|
|
75401
|
-
|
|
75693
|
+
resolve42({ stdout: stdoutText, stderr: stderrText });
|
|
75402
75694
|
});
|
|
75403
75695
|
});
|
|
75404
75696
|
}
|
|
@@ -78749,13 +79041,13 @@ var init_plugin_runner = __esm({
|
|
|
78749
79041
|
* Returns the result on success, throws on timeout.
|
|
78750
79042
|
*/
|
|
78751
79043
|
withTimeout(promise, ms, timeoutMessage) {
|
|
78752
|
-
return new Promise((
|
|
79044
|
+
return new Promise((resolve42, reject2) => {
|
|
78753
79045
|
const timer = setTimeout(() => {
|
|
78754
79046
|
reject2(new Error(timeoutMessage));
|
|
78755
79047
|
}, ms);
|
|
78756
79048
|
promise.then((result) => {
|
|
78757
79049
|
clearTimeout(timer);
|
|
78758
|
-
|
|
79050
|
+
resolve42(result);
|
|
78759
79051
|
}).catch((err) => {
|
|
78760
79052
|
clearTimeout(timer);
|
|
78761
79053
|
reject2(err);
|
|
@@ -79391,7 +79683,7 @@ var init_in_process_runtime = __esm({
|
|
|
79391
79683
|
runtimeLog.log(
|
|
79392
79684
|
`Waiting for ${metrics.inFlightTasks} in-flight tasks to complete...`
|
|
79393
79685
|
);
|
|
79394
|
-
await new Promise((
|
|
79686
|
+
await new Promise((resolve42) => setTimeout(resolve42, 1e3));
|
|
79395
79687
|
}
|
|
79396
79688
|
const finalMetrics = this.getMetrics();
|
|
79397
79689
|
if (finalMetrics.inFlightTasks > 0) {
|
|
@@ -79788,13 +80080,13 @@ var init_ipc_host = __esm({
|
|
|
79788
80080
|
}
|
|
79789
80081
|
const id = generateCorrelationId();
|
|
79790
80082
|
const message = { type, id, payload };
|
|
79791
|
-
return new Promise((
|
|
80083
|
+
return new Promise((resolve42, reject2) => {
|
|
79792
80084
|
const timeout2 = setTimeout(() => {
|
|
79793
80085
|
this.pendingCommands.delete(id);
|
|
79794
80086
|
reject2(new Error(`Command ${type} timed out after ${timeoutMs ?? this.commandTimeoutMs}ms`));
|
|
79795
80087
|
}, timeoutMs ?? this.commandTimeoutMs);
|
|
79796
80088
|
this.pendingCommands.set(id, {
|
|
79797
|
-
resolve:
|
|
80089
|
+
resolve: resolve42,
|
|
79798
80090
|
reject: reject2,
|
|
79799
80091
|
timeout: timeout2,
|
|
79800
80092
|
type
|
|
@@ -80603,8 +80895,8 @@ var init_remote_node_client = __esm({
|
|
|
80603
80895
|
return error instanceof TypeError;
|
|
80604
80896
|
}
|
|
80605
80897
|
async sleep(ms) {
|
|
80606
|
-
await new Promise((
|
|
80607
|
-
setTimeout(
|
|
80898
|
+
await new Promise((resolve42) => {
|
|
80899
|
+
setTimeout(resolve42, ms);
|
|
80608
80900
|
});
|
|
80609
80901
|
}
|
|
80610
80902
|
};
|
|
@@ -80868,14 +81160,14 @@ var init_remote_node_runtime = __esm({
|
|
|
80868
81160
|
return error instanceof Error ? error : new Error(String(error));
|
|
80869
81161
|
}
|
|
80870
81162
|
async sleep(ms, signal) {
|
|
80871
|
-
await new Promise((
|
|
81163
|
+
await new Promise((resolve42) => {
|
|
80872
81164
|
const timeout2 = setTimeout(() => {
|
|
80873
81165
|
cleanup();
|
|
80874
|
-
|
|
81166
|
+
resolve42();
|
|
80875
81167
|
}, ms);
|
|
80876
81168
|
const onAbort = () => {
|
|
80877
81169
|
cleanup();
|
|
80878
|
-
|
|
81170
|
+
resolve42();
|
|
80879
81171
|
};
|
|
80880
81172
|
const cleanup = () => {
|
|
80881
81173
|
clearTimeout(timeout2);
|
|
@@ -81505,7 +81797,7 @@ var init_provider_adapters = __esm({
|
|
|
81505
81797
|
|
|
81506
81798
|
// ../engine/src/remote-access/tunnel-process-manager.ts
|
|
81507
81799
|
import { EventEmitter as EventEmitter24 } from "node:events";
|
|
81508
|
-
import { exec as exec9, execFile as execFile3, spawn as
|
|
81800
|
+
import { exec as exec9, execFile as execFile3, spawn as spawn5 } from "node:child_process";
|
|
81509
81801
|
import { promisify as promisify9 } from "node:util";
|
|
81510
81802
|
function nowIso() {
|
|
81511
81803
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -81596,7 +81888,7 @@ var init_tunnel_process_manager = __esm({
|
|
|
81596
81888
|
super();
|
|
81597
81889
|
this.maxLogEntries = options.maxLogEntries ?? DEFAULT_MAX_LOG_ENTRIES;
|
|
81598
81890
|
this.defaultStopTimeoutMs = options.stopTimeoutMs ?? DEFAULT_STOP_TIMEOUT_MS2;
|
|
81599
|
-
this.spawnImpl = options.spawnImpl ??
|
|
81891
|
+
this.spawnImpl = options.spawnImpl ?? spawn5;
|
|
81600
81892
|
}
|
|
81601
81893
|
getStatus() {
|
|
81602
81894
|
return { ...this.status, lastError: this.status.lastError ? { ...this.status.lastError } : null };
|
|
@@ -81826,10 +82118,10 @@ var init_tunnel_process_manager = __esm({
|
|
|
81826
82118
|
lastError: null
|
|
81827
82119
|
});
|
|
81828
82120
|
this.emitLog("info", "manager", `Stopping ${currentHandle.provider} tunnel (pid=${currentHandle.child.pid ?? "n/a"})`);
|
|
81829
|
-
this.activeStopPromise = new Promise((
|
|
82121
|
+
this.activeStopPromise = new Promise((resolve42) => {
|
|
81830
82122
|
const onClose = () => {
|
|
81831
82123
|
currentHandle.child.removeListener("close", onClose);
|
|
81832
|
-
|
|
82124
|
+
resolve42();
|
|
81833
82125
|
};
|
|
81834
82126
|
currentHandle.child.once("close", onClose);
|
|
81835
82127
|
killManagedProcess(currentHandle.child, "SIGTERM");
|
|
@@ -81970,6 +82262,7 @@ var execFileAsync2, MERGE_HANDOFF_GRACE_MS, isRemoteActive, ProjectEngine;
|
|
|
81970
82262
|
var init_project_engine = __esm({
|
|
81971
82263
|
"../engine/src/project-engine.ts"() {
|
|
81972
82264
|
"use strict";
|
|
82265
|
+
init_src();
|
|
81973
82266
|
init_in_process_runtime();
|
|
81974
82267
|
init_pr_monitor();
|
|
81975
82268
|
init_pr_comment_handler();
|
|
@@ -82436,12 +82729,12 @@ ${detail}`
|
|
|
82436
82729
|
*/
|
|
82437
82730
|
async onMerge(taskId) {
|
|
82438
82731
|
if (this.mergeActive.has(taskId)) {
|
|
82439
|
-
return new Promise((
|
|
82440
|
-
this.manualMergeResolvers.set(taskId, { resolve:
|
|
82732
|
+
return new Promise((resolve42, reject2) => {
|
|
82733
|
+
this.manualMergeResolvers.set(taskId, { resolve: resolve42, reject: reject2 });
|
|
82441
82734
|
});
|
|
82442
82735
|
}
|
|
82443
|
-
return new Promise((
|
|
82444
|
-
this.manualMergeResolvers.set(taskId, { resolve:
|
|
82736
|
+
return new Promise((resolve42, reject2) => {
|
|
82737
|
+
this.manualMergeResolvers.set(taskId, { resolve: resolve42, reject: reject2 });
|
|
82445
82738
|
this.internalEnqueueMerge(taskId);
|
|
82446
82739
|
});
|
|
82447
82740
|
}
|
|
@@ -82664,6 +82957,48 @@ ${detail}`
|
|
|
82664
82957
|
if (task.status === "failed") return false;
|
|
82665
82958
|
return (task.mergeRetries ?? 0) < _ProjectEngine.MAX_AUTO_MERGE_RETRIES || this.hasAutoHealableVerificationBufferFailure(task) || this.isRetryCooldownElapsed(task);
|
|
82666
82959
|
}
|
|
82960
|
+
/**
|
|
82961
|
+
* Remove and return the highest-priority taskId from the merge queue.
|
|
82962
|
+
* Ordering: priority (urgent→low), then createdAt ASC, then id ASC — matching
|
|
82963
|
+
* the triage and scheduler comparators. Manual merges (onMerge resolvers) are
|
|
82964
|
+
* preferred over auto-merges so awaited callers aren't starved by a flood of
|
|
82965
|
+
* higher-priority auto-enqueues. IDs whose tasks can't be loaded fall back to
|
|
82966
|
+
* FIFO order so they still drain.
|
|
82967
|
+
*/
|
|
82968
|
+
async pickNextMergeTaskId(store) {
|
|
82969
|
+
if (this.mergeQueue.length === 0) return void 0;
|
|
82970
|
+
if (this.mergeQueue.length === 1) {
|
|
82971
|
+
return this.mergeQueue.shift();
|
|
82972
|
+
}
|
|
82973
|
+
const queueSnapshot = [...this.mergeQueue];
|
|
82974
|
+
const entries = [];
|
|
82975
|
+
for (let i = 0; i < queueSnapshot.length; i++) {
|
|
82976
|
+
const taskId = queueSnapshot[i];
|
|
82977
|
+
const task = await store.getTask(taskId).catch(() => void 0);
|
|
82978
|
+
entries.push({
|
|
82979
|
+
taskId,
|
|
82980
|
+
task,
|
|
82981
|
+
manual: this.manualMergeResolvers.has(taskId),
|
|
82982
|
+
order: i
|
|
82983
|
+
});
|
|
82984
|
+
}
|
|
82985
|
+
if (this.shuttingDown) return void 0;
|
|
82986
|
+
entries.sort((a, b) => {
|
|
82987
|
+
if (a.manual !== b.manual) return a.manual ? -1 : 1;
|
|
82988
|
+
if (a.task && b.task) return compareTasksByPriorityThenAgeAndId(a.task, b.task);
|
|
82989
|
+
if (a.task) return -1;
|
|
82990
|
+
if (b.task) return 1;
|
|
82991
|
+
return a.order - b.order;
|
|
82992
|
+
});
|
|
82993
|
+
for (const entry of entries) {
|
|
82994
|
+
const liveIndex = this.mergeQueue.indexOf(entry.taskId);
|
|
82995
|
+
if (liveIndex !== -1) {
|
|
82996
|
+
this.mergeQueue.splice(liveIndex, 1);
|
|
82997
|
+
return entry.taskId;
|
|
82998
|
+
}
|
|
82999
|
+
}
|
|
83000
|
+
return void 0;
|
|
83001
|
+
}
|
|
82667
83002
|
internalEnqueueMerge(taskId) {
|
|
82668
83003
|
if (this.shuttingDown) return;
|
|
82669
83004
|
if (this.mergeActive.has(taskId)) return;
|
|
@@ -82671,6 +83006,23 @@ ${detail}`
|
|
|
82671
83006
|
this.mergeQueue.push(taskId);
|
|
82672
83007
|
void this.drainMergeQueue();
|
|
82673
83008
|
}
|
|
83009
|
+
/**
|
|
83010
|
+
* Filter a sweep's listTasks() result to merge-eligible tasks, sort by
|
|
83011
|
+
* priority (urgent → low, then createdAt ASC, then id ASC), and enqueue.
|
|
83012
|
+
* Sorting before enqueue matters because each enqueue may immediately
|
|
83013
|
+
* trigger drainMergeQueue's single-item fast path, so the first task
|
|
83014
|
+
* pushed wins. listTasks returns createdAt ASC — without this sort an
|
|
83015
|
+
* older low-priority task would start before a later urgent one.
|
|
83016
|
+
*/
|
|
83017
|
+
enqueueEligibleInReviewTasks(tasks) {
|
|
83018
|
+
const eligible = sortTasksByPriorityThenAgeAndId(
|
|
83019
|
+
tasks.filter((t) => !t.paused && this.canMergeTask(t))
|
|
83020
|
+
);
|
|
83021
|
+
for (const t of eligible) {
|
|
83022
|
+
this.internalEnqueueMerge(t.id);
|
|
83023
|
+
}
|
|
83024
|
+
return eligible.length;
|
|
83025
|
+
}
|
|
82674
83026
|
async drainMergeQueue() {
|
|
82675
83027
|
if (this.mergeRunning) return;
|
|
82676
83028
|
this.mergeRunning = true;
|
|
@@ -82678,7 +83030,9 @@ ${detail}`
|
|
|
82678
83030
|
const store = this.runtime.getTaskStore();
|
|
82679
83031
|
const cwd = this.config.workingDirectory;
|
|
82680
83032
|
while (this.mergeQueue.length > 0 && !this.shuttingDown) {
|
|
82681
|
-
const taskId = this.
|
|
83033
|
+
const taskId = await this.pickNextMergeTaskId(store);
|
|
83034
|
+
if (!taskId) break;
|
|
83035
|
+
if (this.shuttingDown) break;
|
|
82682
83036
|
const manualResolver = this.manualMergeResolvers.get(taskId);
|
|
82683
83037
|
try {
|
|
82684
83038
|
if (!manualResolver) {
|
|
@@ -83148,12 +83502,9 @@ ${detail}`
|
|
|
83148
83502
|
}
|
|
83149
83503
|
const settings = await store.getSettings();
|
|
83150
83504
|
if (!settings.autoMerge) return;
|
|
83151
|
-
const
|
|
83152
|
-
if (
|
|
83153
|
-
runtimeLog.log(`Auto-merge startup sweep: enqueueing ${
|
|
83154
|
-
for (const t of eligible) {
|
|
83155
|
-
this.internalEnqueueMerge(t.id);
|
|
83156
|
-
}
|
|
83505
|
+
const enqueued = this.enqueueEligibleInReviewTasks(tasks);
|
|
83506
|
+
if (enqueued > 0) {
|
|
83507
|
+
runtimeLog.log(`Auto-merge startup sweep: enqueueing ${enqueued} task(s)`);
|
|
83157
83508
|
}
|
|
83158
83509
|
} catch (err) {
|
|
83159
83510
|
runtimeLog.warn(
|
|
@@ -83169,14 +83520,7 @@ ${detail}`
|
|
|
83169
83520
|
const settings = await store.getSettings();
|
|
83170
83521
|
if (!settings.globalPause && !settings.enginePaused && settings.autoMerge) {
|
|
83171
83522
|
const tasks = await store.listTasks({ column: "in-review" });
|
|
83172
|
-
|
|
83173
|
-
if (t.paused) {
|
|
83174
|
-
continue;
|
|
83175
|
-
}
|
|
83176
|
-
if (this.canMergeTask(t)) {
|
|
83177
|
-
this.internalEnqueueMerge(t.id);
|
|
83178
|
-
}
|
|
83179
|
-
}
|
|
83523
|
+
this.enqueueEligibleInReviewTasks(tasks);
|
|
83180
83524
|
}
|
|
83181
83525
|
} catch (err) {
|
|
83182
83526
|
runtimeLog.warn(
|
|
@@ -83232,14 +83576,7 @@ ${detail}`
|
|
|
83232
83576
|
if (s.autoMerge) {
|
|
83233
83577
|
try {
|
|
83234
83578
|
const tasks = await store.listTasks({ column: "in-review" });
|
|
83235
|
-
|
|
83236
|
-
if (t.paused) {
|
|
83237
|
-
continue;
|
|
83238
|
-
}
|
|
83239
|
-
if (this.canMergeTask(t)) {
|
|
83240
|
-
this.internalEnqueueMerge(t.id);
|
|
83241
|
-
}
|
|
83242
|
-
}
|
|
83579
|
+
this.enqueueEligibleInReviewTasks(tasks);
|
|
83243
83580
|
} catch (err) {
|
|
83244
83581
|
runtimeLog.warn(
|
|
83245
83582
|
`Global unpause: failed to scan in-review tasks for auto-merge: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -83269,14 +83606,7 @@ ${detail}`
|
|
|
83269
83606
|
if (s.autoMerge) {
|
|
83270
83607
|
try {
|
|
83271
83608
|
const tasks = await store.listTasks({ column: "in-review" });
|
|
83272
|
-
|
|
83273
|
-
if (t.paused) {
|
|
83274
|
-
continue;
|
|
83275
|
-
}
|
|
83276
|
-
if (this.canMergeTask(t)) {
|
|
83277
|
-
this.internalEnqueueMerge(t.id);
|
|
83278
|
-
}
|
|
83279
|
-
}
|
|
83609
|
+
this.enqueueEligibleInReviewTasks(tasks);
|
|
83280
83610
|
} catch (err) {
|
|
83281
83611
|
runtimeLog.warn(
|
|
83282
83612
|
`Engine unpause: failed to scan in-review tasks for auto-merge: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -83869,7 +84199,7 @@ var init_peer_exchange_service = __esm({
|
|
|
83869
84199
|
syncIntervalMs;
|
|
83870
84200
|
interval = null;
|
|
83871
84201
|
activeSync = null;
|
|
83872
|
-
|
|
84202
|
+
running = false;
|
|
83873
84203
|
/** Whether settings sync is enabled. Default: false. */
|
|
83874
84204
|
settingsSyncEnabled;
|
|
83875
84205
|
/** Minimum interval between settings syncs with the same node in ms. Default: 5 minutes. */
|
|
@@ -83911,10 +84241,11 @@ var init_peer_exchange_service = __esm({
|
|
|
83911
84241
|
* Begins periodic gossip with all online remote nodes.
|
|
83912
84242
|
*/
|
|
83913
84243
|
start() {
|
|
83914
|
-
if (this.
|
|
83915
|
-
peerExchangeLog.
|
|
84244
|
+
if (this.running) {
|
|
84245
|
+
peerExchangeLog.log("Peer exchange service already running");
|
|
83916
84246
|
return;
|
|
83917
84247
|
}
|
|
84248
|
+
this.running = true;
|
|
83918
84249
|
this.centralCore.listNodes().then((nodes) => {
|
|
83919
84250
|
const onlineRemoteCount = nodes.filter(
|
|
83920
84251
|
(n) => n.type === "remote" && n.status === "online" && n.url
|
|
@@ -83924,6 +84255,7 @@ var init_peer_exchange_service = __esm({
|
|
|
83924
84255
|
peerExchangeLog.warn(`Failed to get initial peer count: ${err}`);
|
|
83925
84256
|
});
|
|
83926
84257
|
this.interval = setInterval(() => {
|
|
84258
|
+
if (!this.running) return;
|
|
83927
84259
|
void this.syncWithAllPeers();
|
|
83928
84260
|
}, this.syncIntervalMs);
|
|
83929
84261
|
}
|
|
@@ -83931,12 +84263,21 @@ var init_peer_exchange_service = __esm({
|
|
|
83931
84263
|
* Stop the peer exchange service.
|
|
83932
84264
|
* Clears the sync interval and prevents further syncs.
|
|
83933
84265
|
*/
|
|
83934
|
-
stop() {
|
|
84266
|
+
async stop() {
|
|
84267
|
+
if (!this.running) {
|
|
84268
|
+
return;
|
|
84269
|
+
}
|
|
84270
|
+
this.running = false;
|
|
83935
84271
|
if (this.interval) {
|
|
83936
84272
|
clearInterval(this.interval);
|
|
83937
84273
|
this.interval = null;
|
|
83938
84274
|
}
|
|
83939
|
-
this.
|
|
84275
|
+
if (this.activeSync) {
|
|
84276
|
+
try {
|
|
84277
|
+
await this.activeSync;
|
|
84278
|
+
} catch {
|
|
84279
|
+
}
|
|
84280
|
+
}
|
|
83940
84281
|
peerExchangeLog.log("Stopped peer exchange service");
|
|
83941
84282
|
}
|
|
83942
84283
|
/**
|
|
@@ -85495,7 +85836,7 @@ For completion:
|
|
|
85495
85836
|
}`;
|
|
85496
85837
|
SESSION_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
85497
85838
|
CLEANUP_INTERVAL_MS2 = 5 * 60 * 1e3;
|
|
85498
|
-
MAX_SESSIONS_PER_IP_PER_HOUR =
|
|
85839
|
+
MAX_SESSIONS_PER_IP_PER_HOUR = 1e3;
|
|
85499
85840
|
RATE_LIMIT_WINDOW_MS2 = 60 * 60 * 1e3;
|
|
85500
85841
|
GENERATION_TIMEOUT_MS = 12e4;
|
|
85501
85842
|
sessions = /* @__PURE__ */ new Map();
|
|
@@ -88381,7 +88722,7 @@ var init_src3 = __esm({
|
|
|
88381
88722
|
});
|
|
88382
88723
|
|
|
88383
88724
|
// ../../plugins/fusion-plugin-hermes-runtime/dist/cli-spawn.js
|
|
88384
|
-
import { spawn as
|
|
88725
|
+
import { spawn as spawn6, spawnSync } from "node:child_process";
|
|
88385
88726
|
import os2 from "node:os";
|
|
88386
88727
|
import path, { sep as PATH_SEP } from "node:path";
|
|
88387
88728
|
function resolveBinaryForSpawn(binary) {
|
|
@@ -88443,9 +88784,9 @@ function hermesProfileHome(profileName) {
|
|
|
88443
88784
|
async function listHermesProfiles(opts) {
|
|
88444
88785
|
const binary = resolveBinaryForSpawn(opts?.binaryPath ?? "hermes");
|
|
88445
88786
|
const timeoutMs = opts?.timeoutMs ?? 5e3;
|
|
88446
|
-
return new Promise((
|
|
88787
|
+
return new Promise((resolve42, reject2) => {
|
|
88447
88788
|
let settled = false;
|
|
88448
|
-
const child =
|
|
88789
|
+
const child = spawn6(binary, ["profile", "list"], {
|
|
88449
88790
|
stdio: ["ignore", "pipe", "pipe"],
|
|
88450
88791
|
env: { ...process.env }
|
|
88451
88792
|
});
|
|
@@ -88486,7 +88827,7 @@ async function listHermesProfiles(opts) {
|
|
|
88486
88827
|
${combined}`));
|
|
88487
88828
|
return;
|
|
88488
88829
|
}
|
|
88489
|
-
|
|
88830
|
+
resolve42(parseProfileListOutput(stdout));
|
|
88490
88831
|
});
|
|
88491
88832
|
});
|
|
88492
88833
|
}
|
|
@@ -88563,13 +88904,13 @@ function buildHermesArgs(prompt, settings, resumeSessionId) {
|
|
|
88563
88904
|
async function invokeHermesCli(prompt, settings, resumeSessionId, signal) {
|
|
88564
88905
|
const args = buildHermesArgs(prompt, settings, resumeSessionId);
|
|
88565
88906
|
const binary = resolveBinaryForSpawn(settings.binaryPath);
|
|
88566
|
-
return new Promise((
|
|
88907
|
+
return new Promise((resolve42, reject2) => {
|
|
88567
88908
|
let settled = false;
|
|
88568
88909
|
const spawnEnv = { ...process.env, PYTHONUNBUFFERED: "1" };
|
|
88569
88910
|
if (settings.profile) {
|
|
88570
88911
|
spawnEnv.HERMES_HOME = hermesProfileHome(settings.profile);
|
|
88571
88912
|
}
|
|
88572
|
-
const child =
|
|
88913
|
+
const child = spawn6(binary, args, {
|
|
88573
88914
|
stdio: ["ignore", "pipe", "pipe"],
|
|
88574
88915
|
env: spawnEnv
|
|
88575
88916
|
});
|
|
@@ -88631,7 +88972,7 @@ ${combined}`));
|
|
|
88631
88972
|
return;
|
|
88632
88973
|
}
|
|
88633
88974
|
try {
|
|
88634
|
-
|
|
88975
|
+
resolve42(parseHermesOutput(stdout, stderr));
|
|
88635
88976
|
} catch (parseErr) {
|
|
88636
88977
|
reject2(parseErr);
|
|
88637
88978
|
}
|
|
@@ -88724,7 +89065,7 @@ var init_runtime_adapter = __esm({
|
|
|
88724
89065
|
});
|
|
88725
89066
|
|
|
88726
89067
|
// ../../plugins/fusion-plugin-hermes-runtime/dist/probe.js
|
|
88727
|
-
import { spawn as
|
|
89068
|
+
import { spawn as spawn7 } from "node:child_process";
|
|
88728
89069
|
async function probeHermesBinary(opts) {
|
|
88729
89070
|
const startedAt = Date.now();
|
|
88730
89071
|
const binary = typeof opts?.binaryPath === "string" && opts.binaryPath.trim().length > 0 ? opts.binaryPath.trim() : "hermes";
|
|
@@ -88735,7 +89076,7 @@ async function probeHermesBinary(opts) {
|
|
|
88735
89076
|
resolvePromise({ ...result, probeDurationMs: Date.now() - startedAt });
|
|
88736
89077
|
};
|
|
88737
89078
|
let settled = false;
|
|
88738
|
-
const child =
|
|
89079
|
+
const child = spawn7(resolvedPath ?? binary, ["--version"], {
|
|
88739
89080
|
stdio: ["ignore", "pipe", "pipe"]
|
|
88740
89081
|
});
|
|
88741
89082
|
const timer = setTimeout(() => {
|
|
@@ -88796,7 +89137,7 @@ async function probeHermesBinary(opts) {
|
|
|
88796
89137
|
async function tryResolveBinaryPath(binary) {
|
|
88797
89138
|
return new Promise((resolvePromise) => {
|
|
88798
89139
|
const which = process.platform === "win32" ? "where" : "which";
|
|
88799
|
-
const child =
|
|
89140
|
+
const child = spawn7(which, [binary], { stdio: ["ignore", "pipe", "ignore"] });
|
|
88800
89141
|
let out = "";
|
|
88801
89142
|
child.stdout?.on("data", (chunk) => {
|
|
88802
89143
|
out += chunk.toString("utf-8");
|
|
@@ -88874,7 +89215,7 @@ var init_dist = __esm({
|
|
|
88874
89215
|
});
|
|
88875
89216
|
|
|
88876
89217
|
// ../../plugins/fusion-plugin-openclaw-runtime/dist/pi-module.js
|
|
88877
|
-
import { spawn as
|
|
89218
|
+
import { spawn as spawn8 } from "node:child_process";
|
|
88878
89219
|
import { randomUUID as randomUUID15 } from "node:crypto";
|
|
88879
89220
|
function asString(v) {
|
|
88880
89221
|
return typeof v === "string" && v.trim() !== "" ? v.trim() : void 0;
|
|
@@ -88949,9 +89290,9 @@ async function promptCli(session, message, config, callbacks, signal) {
|
|
|
88949
89290
|
const args = buildOpenClawArgs(config, session.sessionId, message);
|
|
88950
89291
|
const cb = { ...session.callbacks, ...callbacks };
|
|
88951
89292
|
cb.onToolStart?.("openclaw.agent", { sessionId: session.sessionId });
|
|
88952
|
-
return new Promise((
|
|
89293
|
+
return new Promise((resolve42, reject2) => {
|
|
88953
89294
|
let settled = false;
|
|
88954
|
-
const child =
|
|
89295
|
+
const child = spawn8(config.binaryPath, args, {
|
|
88955
89296
|
stdio: ["ignore", "pipe", "pipe"]
|
|
88956
89297
|
});
|
|
88957
89298
|
const hardKill = setTimeout(() => {
|
|
@@ -89042,7 +89383,7 @@ async function promptCli(session, message, config, callbacks, signal) {
|
|
|
89042
89383
|
...metaError ? { error: metaError } : {},
|
|
89043
89384
|
...errorText.length > 0 ? { toolErrors: errorText } : {}
|
|
89044
89385
|
});
|
|
89045
|
-
|
|
89386
|
+
resolve42();
|
|
89046
89387
|
});
|
|
89047
89388
|
});
|
|
89048
89389
|
}
|
|
@@ -89102,7 +89443,7 @@ var init_runtime_adapter2 = __esm({
|
|
|
89102
89443
|
});
|
|
89103
89444
|
|
|
89104
89445
|
// ../../plugins/fusion-plugin-openclaw-runtime/dist/probe.js
|
|
89105
|
-
import { spawn as
|
|
89446
|
+
import { spawn as spawn9 } from "node:child_process";
|
|
89106
89447
|
async function probeOpenClawBinary(opts = {}) {
|
|
89107
89448
|
const startedAt = Date.now();
|
|
89108
89449
|
const binary = opts.binaryPath ?? "openclaw";
|
|
@@ -89113,7 +89454,7 @@ async function probeOpenClawBinary(opts = {}) {
|
|
|
89113
89454
|
resolvePromise({ ...partial, probeDurationMs: Date.now() - startedAt });
|
|
89114
89455
|
};
|
|
89115
89456
|
let settled = false;
|
|
89116
|
-
const child =
|
|
89457
|
+
const child = spawn9(resolvedPath ?? binary, ["--version"], {
|
|
89117
89458
|
stdio: ["ignore", "pipe", "pipe"]
|
|
89118
89459
|
});
|
|
89119
89460
|
const timer = setTimeout(() => {
|
|
@@ -89174,7 +89515,7 @@ async function probeOpenClawBinary(opts = {}) {
|
|
|
89174
89515
|
async function tryResolveBinaryPath2(binary) {
|
|
89175
89516
|
return new Promise((resolvePromise) => {
|
|
89176
89517
|
const which = process.platform === "win32" ? "where" : "which";
|
|
89177
|
-
const child =
|
|
89518
|
+
const child = spawn9(which, [binary], { stdio: ["ignore", "pipe", "ignore"] });
|
|
89178
89519
|
let out = "";
|
|
89179
89520
|
child.stdout?.on("data", (chunk) => {
|
|
89180
89521
|
out += chunk.toString("utf-8");
|
|
@@ -90595,7 +90936,7 @@ function registerTaskWorkflowRoutes(ctx, deps) {
|
|
|
90595
90936
|
router.patch("/tasks/:id", async (req, res) => {
|
|
90596
90937
|
try {
|
|
90597
90938
|
const { store: scopedStore } = await getProjectContext3(req);
|
|
90598
|
-
const { title, description, prompt, dependencies, enabledWorkflowSteps, modelProvider, modelId, validatorModelProvider, validatorModelId, planningModelProvider, planningModelId, thinkingLevel, assigneeUserId, reviewLevel, executionMode, sourceIssue, nodeId } = req.body;
|
|
90939
|
+
const { title, description, prompt, priority, dependencies, enabledWorkflowSteps, modelProvider, modelId, validatorModelProvider, validatorModelId, planningModelProvider, planningModelId, thinkingLevel, assigneeUserId, reviewLevel, executionMode, sourceIssue, nodeId } = req.body;
|
|
90599
90940
|
const hasBodyField = (field) => Object.prototype.hasOwnProperty.call(req.body, field);
|
|
90600
90941
|
const validateModelField = (value, name) => {
|
|
90601
90942
|
if (value === void 0) return void 0;
|
|
@@ -90625,6 +90966,9 @@ function registerTaskWorkflowRoutes(ctx, deps) {
|
|
|
90625
90966
|
if (executionMode !== void 0 && executionMode !== null && !validExecutionModes.includes(executionMode)) {
|
|
90626
90967
|
throw new Error(`executionMode must be one of: ${validExecutionModes.join(", ")}`);
|
|
90627
90968
|
}
|
|
90969
|
+
if (priority !== void 0 && priority !== null && !isTaskPriority(priority)) {
|
|
90970
|
+
throw new Error(`priority must be one of: ${TASK_PRIORITIES.join(", ")}`);
|
|
90971
|
+
}
|
|
90628
90972
|
if (enabledWorkflowSteps !== void 0) {
|
|
90629
90973
|
if (!Array.isArray(enabledWorkflowSteps) || !enabledWorkflowSteps.every((id) => typeof id === "string")) {
|
|
90630
90974
|
throw new Error("enabledWorkflowSteps must be an array of strings");
|
|
@@ -90684,6 +91028,7 @@ function registerTaskWorkflowRoutes(ctx, deps) {
|
|
|
90684
91028
|
if (title !== void 0) updates.title = title;
|
|
90685
91029
|
if (description !== void 0) updates.description = description;
|
|
90686
91030
|
if (prompt !== void 0) updates.prompt = prompt;
|
|
91031
|
+
if (hasBodyField("priority")) updates.priority = priority;
|
|
90687
91032
|
if (dependencies !== void 0) updates.dependencies = dependencies;
|
|
90688
91033
|
if (enabledWorkflowSteps !== void 0) updates.enabledWorkflowSteps = enabledWorkflowSteps;
|
|
90689
91034
|
if (hasBodyField("modelProvider")) updates.modelProvider = validatedModelProvider;
|
|
@@ -90714,7 +91059,7 @@ function registerTaskWorkflowRoutes(ctx, deps) {
|
|
|
90714
91059
|
if (err instanceof ApiError) {
|
|
90715
91060
|
throw err;
|
|
90716
91061
|
}
|
|
90717
|
-
const status = (err instanceof Error ? err.message : String(err)).includes("must be a string") || (err instanceof Error ? err.message : String(err)).includes("must be a non-empty string") || (err instanceof Error ? err.message : String(err)).includes("must be a string or null") || (err instanceof Error ? err.message : String(err)).includes("must be an array of strings") || (err instanceof Error ? err.message : String(err)).includes("thinkingLevel must be one of") || (err instanceof Error ? err.message : String(err)).includes("reviewLevel must be an integer") || (err instanceof Error ? err.message : String(err)).includes("executionMode must be one of") || (err instanceof Error ? err.message : String(err)).includes("sourceIssue") ? 400 : 500;
|
|
91062
|
+
const status = (err instanceof Error ? err.message : String(err)).includes("must be a string") || (err instanceof Error ? err.message : String(err)).includes("must be a non-empty string") || (err instanceof Error ? err.message : String(err)).includes("must be a string or null") || (err instanceof Error ? err.message : String(err)).includes("must be an array of strings") || (err instanceof Error ? err.message : String(err)).includes("thinkingLevel must be one of") || (err instanceof Error ? err.message : String(err)).includes("reviewLevel must be an integer") || (err instanceof Error ? err.message : String(err)).includes("executionMode must be one of") || (err instanceof Error ? err.message : String(err)).includes("priority must be one of") || (err instanceof Error ? err.message : String(err)).includes("sourceIssue") ? 400 : 500;
|
|
90718
91063
|
throw new ApiError(status, err instanceof Error ? err.message : String(err));
|
|
90719
91064
|
}
|
|
90720
91065
|
});
|
|
@@ -97386,10 +97731,10 @@ var require_browser3 = __commonJS({
|
|
|
97386
97731
|
text = canvas;
|
|
97387
97732
|
canvas = void 0;
|
|
97388
97733
|
}
|
|
97389
|
-
return new Promise(function(
|
|
97734
|
+
return new Promise(function(resolve42, reject2) {
|
|
97390
97735
|
try {
|
|
97391
97736
|
const data = QRCode2.create(text, opts);
|
|
97392
|
-
|
|
97737
|
+
resolve42(renderFunc(data, canvas, opts));
|
|
97393
97738
|
} catch (e) {
|
|
97394
97739
|
reject2(e);
|
|
97395
97740
|
}
|
|
@@ -97471,11 +97816,11 @@ var require_server = __commonJS({
|
|
|
97471
97816
|
}
|
|
97472
97817
|
function render(renderFunc, text, params) {
|
|
97473
97818
|
if (!params.cb) {
|
|
97474
|
-
return new Promise(function(
|
|
97819
|
+
return new Promise(function(resolve42, reject2) {
|
|
97475
97820
|
try {
|
|
97476
97821
|
const data = QRCode2.create(text, params.opts);
|
|
97477
97822
|
return renderFunc(data, params.opts, function(err, data2) {
|
|
97478
|
-
return err ? reject2(err) :
|
|
97823
|
+
return err ? reject2(err) : resolve42(data2);
|
|
97479
97824
|
});
|
|
97480
97825
|
} catch (e) {
|
|
97481
97826
|
reject2(e);
|
|
@@ -99123,9 +99468,9 @@ import * as fs2 from "node:fs";
|
|
|
99123
99468
|
import { createRequire as createRequire3 } from "node:module";
|
|
99124
99469
|
import { join as join42, dirname as dirname12 } from "node:path";
|
|
99125
99470
|
function getNativePrebuildName() {
|
|
99126
|
-
const
|
|
99471
|
+
const platform4 = process.platform === "darwin" ? "darwin" : process.platform === "linux" ? "linux" : process.platform === "win32" ? "win32" : "unknown";
|
|
99127
99472
|
const arch = process.arch === "arm64" ? "arm64" : process.arch === "x64" ? "x64" : "unknown";
|
|
99128
|
-
return `${
|
|
99473
|
+
return `${platform4}-${arch}`;
|
|
99129
99474
|
}
|
|
99130
99475
|
function findInstalledNodePtyNativeDir() {
|
|
99131
99476
|
try {
|
|
@@ -99307,8 +99652,8 @@ var init_terminal_service = __esm({
|
|
|
99307
99652
|
* Get the default allowed shells for the current platform
|
|
99308
99653
|
*/
|
|
99309
99654
|
getAllowedShells() {
|
|
99310
|
-
const
|
|
99311
|
-
return ALLOWED_SHELL_PATHS[
|
|
99655
|
+
const platform4 = os3.platform();
|
|
99656
|
+
return ALLOWED_SHELL_PATHS[platform4] || ALLOWED_SHELL_PATHS.linux;
|
|
99312
99657
|
}
|
|
99313
99658
|
/**
|
|
99314
99659
|
* Validate that a shell path is allowed
|
|
@@ -99322,7 +99667,7 @@ var init_terminal_service = __esm({
|
|
|
99322
99667
|
* Detect the best shell for the current platform
|
|
99323
99668
|
*/
|
|
99324
99669
|
detectShell() {
|
|
99325
|
-
const
|
|
99670
|
+
const platform4 = os3.platform();
|
|
99326
99671
|
const allowedShells = this.getAllowedShells();
|
|
99327
99672
|
const getBasename = (shellPath) => {
|
|
99328
99673
|
const lastSep = Math.max(shellPath.lastIndexOf("/"), shellPath.lastIndexOf("\\"));
|
|
@@ -99339,7 +99684,7 @@ var init_terminal_service = __esm({
|
|
|
99339
99684
|
return ["--login"];
|
|
99340
99685
|
};
|
|
99341
99686
|
const userShell = process.env.SHELL;
|
|
99342
|
-
if (userShell &&
|
|
99687
|
+
if (userShell && platform4 !== "win32") {
|
|
99343
99688
|
const normalizedUserShell = this.isWindows ? userShell.toLowerCase() : userShell;
|
|
99344
99689
|
for (const allowed of allowedShells) {
|
|
99345
99690
|
const normalizedAllowed = this.isWindows ? allowed.toLowerCase() : allowed;
|
|
@@ -99353,7 +99698,7 @@ var init_terminal_service = __esm({
|
|
|
99353
99698
|
return { shell, args: getShellArgs(shell) };
|
|
99354
99699
|
}
|
|
99355
99700
|
}
|
|
99356
|
-
if (
|
|
99701
|
+
if (platform4 === "win32") {
|
|
99357
99702
|
return { shell: "cmd.exe", args: [] };
|
|
99358
99703
|
}
|
|
99359
99704
|
return { shell: "/bin/sh", args: [] };
|
|
@@ -100186,7 +100531,7 @@ var init_register_messaging_scripts = __esm({
|
|
|
100186
100531
|
|
|
100187
100532
|
// ../dashboard/src/github.ts
|
|
100188
100533
|
function delay(ms) {
|
|
100189
|
-
return new Promise((
|
|
100534
|
+
return new Promise((resolve42) => setTimeout(resolve42, ms));
|
|
100190
100535
|
}
|
|
100191
100536
|
function normalizeCheckState(state) {
|
|
100192
100537
|
switch ((state ?? "").toLowerCase()) {
|
|
@@ -104580,7 +104925,7 @@ var init_register_git_github = __esm({
|
|
|
104580
104925
|
});
|
|
104581
104926
|
|
|
104582
104927
|
// ../dashboard/src/terminal.ts
|
|
104583
|
-
import { spawn as
|
|
104928
|
+
import { spawn as spawn10 } from "node:child_process";
|
|
104584
104929
|
import { randomUUID as randomUUID17 } from "node:crypto";
|
|
104585
104930
|
import { EventEmitter as EventEmitter32 } from "node:events";
|
|
104586
104931
|
function extractBaseCommand(command) {
|
|
@@ -104742,7 +105087,7 @@ var init_terminal = __esm({
|
|
|
104742
105087
|
return { sessionId: "", error: validation.error };
|
|
104743
105088
|
}
|
|
104744
105089
|
const sessionId = randomUUID17();
|
|
104745
|
-
const childProcess =
|
|
105090
|
+
const childProcess = spawn10(command, [], {
|
|
104746
105091
|
cwd,
|
|
104747
105092
|
shell: true,
|
|
104748
105093
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -106460,9 +106805,9 @@ var require_readdir_glob = __commonJS({
|
|
|
106460
106805
|
var fs3 = __require("fs");
|
|
106461
106806
|
var { EventEmitter: EventEmitter37 } = __require("events");
|
|
106462
106807
|
var { Minimatch } = require_minimatch();
|
|
106463
|
-
var { resolve:
|
|
106808
|
+
var { resolve: resolve42 } = __require("path");
|
|
106464
106809
|
function readdir12(dir2, strict) {
|
|
106465
|
-
return new Promise((
|
|
106810
|
+
return new Promise((resolve43, reject2) => {
|
|
106466
106811
|
fs3.readdir(dir2, { withFileTypes: true }, (err, files) => {
|
|
106467
106812
|
if (err) {
|
|
106468
106813
|
switch (err.code) {
|
|
@@ -106470,7 +106815,7 @@ var require_readdir_glob = __commonJS({
|
|
|
106470
106815
|
if (strict) {
|
|
106471
106816
|
reject2(err);
|
|
106472
106817
|
} else {
|
|
106473
|
-
|
|
106818
|
+
resolve43([]);
|
|
106474
106819
|
}
|
|
106475
106820
|
break;
|
|
106476
106821
|
case "ENOTSUP":
|
|
@@ -106480,7 +106825,7 @@ var require_readdir_glob = __commonJS({
|
|
|
106480
106825
|
case "ENAMETOOLONG":
|
|
106481
106826
|
// Filename too long
|
|
106482
106827
|
case "UNKNOWN":
|
|
106483
|
-
|
|
106828
|
+
resolve43([]);
|
|
106484
106829
|
break;
|
|
106485
106830
|
case "ELOOP":
|
|
106486
106831
|
// Too many levels of symbolic links
|
|
@@ -106489,30 +106834,30 @@ var require_readdir_glob = __commonJS({
|
|
|
106489
106834
|
break;
|
|
106490
106835
|
}
|
|
106491
106836
|
} else {
|
|
106492
|
-
|
|
106837
|
+
resolve43(files);
|
|
106493
106838
|
}
|
|
106494
106839
|
});
|
|
106495
106840
|
});
|
|
106496
106841
|
}
|
|
106497
106842
|
function stat12(file, followSymlinks) {
|
|
106498
|
-
return new Promise((
|
|
106843
|
+
return new Promise((resolve43, reject2) => {
|
|
106499
106844
|
const statFunc = followSymlinks ? fs3.stat : fs3.lstat;
|
|
106500
106845
|
statFunc(file, (err, stats) => {
|
|
106501
106846
|
if (err) {
|
|
106502
106847
|
switch (err.code) {
|
|
106503
106848
|
case "ENOENT":
|
|
106504
106849
|
if (followSymlinks) {
|
|
106505
|
-
|
|
106850
|
+
resolve43(stat12(file, false));
|
|
106506
106851
|
} else {
|
|
106507
|
-
|
|
106852
|
+
resolve43(null);
|
|
106508
106853
|
}
|
|
106509
106854
|
break;
|
|
106510
106855
|
default:
|
|
106511
|
-
|
|
106856
|
+
resolve43(null);
|
|
106512
106857
|
break;
|
|
106513
106858
|
}
|
|
106514
106859
|
} else {
|
|
106515
|
-
|
|
106860
|
+
resolve43(stats);
|
|
106516
106861
|
}
|
|
106517
106862
|
});
|
|
106518
106863
|
});
|
|
@@ -106602,7 +106947,7 @@ var require_readdir_glob = __commonJS({
|
|
|
106602
106947
|
(skip) => new Minimatch(skip, { dot: true })
|
|
106603
106948
|
);
|
|
106604
106949
|
}
|
|
106605
|
-
this.iterator = explore(
|
|
106950
|
+
this.iterator = explore(resolve42(cwd || "."), this.options.follow, this.options.stat, this._shouldSkipDirectory.bind(this));
|
|
106606
106951
|
this.paused = false;
|
|
106607
106952
|
this.inactive = false;
|
|
106608
106953
|
this.aborted = false;
|
|
@@ -106856,10 +107201,10 @@ function awaitify(asyncFn, arity) {
|
|
|
106856
107201
|
if (typeof args[arity - 1] === "function") {
|
|
106857
107202
|
return asyncFn.apply(this, args);
|
|
106858
107203
|
}
|
|
106859
|
-
return new Promise((
|
|
107204
|
+
return new Promise((resolve42, reject2) => {
|
|
106860
107205
|
args[arity - 1] = (err, ...cbArgs) => {
|
|
106861
107206
|
if (err) return reject2(err);
|
|
106862
|
-
|
|
107207
|
+
resolve42(cbArgs.length > 1 ? cbArgs : cbArgs[0]);
|
|
106863
107208
|
};
|
|
106864
107209
|
asyncFn.apply(this, args);
|
|
106865
107210
|
});
|
|
@@ -107041,13 +107386,13 @@ function mapSeries(coll, iteratee, callback) {
|
|
|
107041
107386
|
return _asyncMap(eachOfSeries$1, coll, iteratee, callback);
|
|
107042
107387
|
}
|
|
107043
107388
|
function promiseCallback() {
|
|
107044
|
-
let
|
|
107389
|
+
let resolve42, reject2;
|
|
107045
107390
|
function callback(err, ...args) {
|
|
107046
107391
|
if (err) return reject2(err);
|
|
107047
|
-
|
|
107392
|
+
resolve42(args.length > 1 ? args : args[0]);
|
|
107048
107393
|
}
|
|
107049
107394
|
callback[PROMISE_SYMBOL] = new Promise((res, rej) => {
|
|
107050
|
-
|
|
107395
|
+
resolve42 = res, reject2 = rej;
|
|
107051
107396
|
});
|
|
107052
107397
|
return callback;
|
|
107053
107398
|
}
|
|
@@ -107320,8 +107665,8 @@ function queue$1(worker, concurrency, payload) {
|
|
|
107320
107665
|
});
|
|
107321
107666
|
}
|
|
107322
107667
|
if (rejectOnError || !callback) {
|
|
107323
|
-
return new Promise((
|
|
107324
|
-
res =
|
|
107668
|
+
return new Promise((resolve42, reject2) => {
|
|
107669
|
+
res = resolve42;
|
|
107325
107670
|
rej = reject2;
|
|
107326
107671
|
});
|
|
107327
107672
|
}
|
|
@@ -107360,10 +107705,10 @@ function queue$1(worker, concurrency, payload) {
|
|
|
107360
107705
|
}
|
|
107361
107706
|
const eventMethod = (name) => (handler) => {
|
|
107362
107707
|
if (!handler) {
|
|
107363
|
-
return new Promise((
|
|
107708
|
+
return new Promise((resolve42, reject2) => {
|
|
107364
107709
|
once3(name, (err, data) => {
|
|
107365
107710
|
if (err) return reject2(err);
|
|
107366
|
-
|
|
107711
|
+
resolve42(data);
|
|
107367
107712
|
});
|
|
107368
107713
|
});
|
|
107369
107714
|
}
|
|
@@ -108539,7 +108884,7 @@ var require_polyfills = __commonJS({
|
|
|
108539
108884
|
var constants2 = __require("constants");
|
|
108540
108885
|
var origCwd = process.cwd;
|
|
108541
108886
|
var cwd = null;
|
|
108542
|
-
var
|
|
108887
|
+
var platform4 = process.env.GRACEFUL_FS_PLATFORM || process.platform;
|
|
108543
108888
|
process.cwd = function() {
|
|
108544
108889
|
if (!cwd)
|
|
108545
108890
|
cwd = origCwd.call(process);
|
|
@@ -108598,7 +108943,7 @@ var require_polyfills = __commonJS({
|
|
|
108598
108943
|
fs3.lchownSync = function() {
|
|
108599
108944
|
};
|
|
108600
108945
|
}
|
|
108601
|
-
if (
|
|
108946
|
+
if (platform4 === "win32") {
|
|
108602
108947
|
fs3.rename = typeof fs3.rename !== "function" ? fs3.rename : (function(fs$rename) {
|
|
108603
108948
|
function rename6(from, to, cb) {
|
|
108604
108949
|
var start = Date.now();
|
|
@@ -113369,25 +113714,25 @@ var require_util2 = __commonJS({
|
|
|
113369
113714
|
};
|
|
113370
113715
|
},
|
|
113371
113716
|
createDeferredPromise: function() {
|
|
113372
|
-
let
|
|
113717
|
+
let resolve42;
|
|
113373
113718
|
let reject2;
|
|
113374
113719
|
const promise = new Promise((res, rej) => {
|
|
113375
|
-
|
|
113720
|
+
resolve42 = res;
|
|
113376
113721
|
reject2 = rej;
|
|
113377
113722
|
});
|
|
113378
113723
|
return {
|
|
113379
113724
|
promise,
|
|
113380
|
-
resolve:
|
|
113725
|
+
resolve: resolve42,
|
|
113381
113726
|
reject: reject2
|
|
113382
113727
|
};
|
|
113383
113728
|
},
|
|
113384
113729
|
promisify(fn) {
|
|
113385
|
-
return new Promise((
|
|
113730
|
+
return new Promise((resolve42, reject2) => {
|
|
113386
113731
|
fn((err, ...args) => {
|
|
113387
113732
|
if (err) {
|
|
113388
113733
|
return reject2(err);
|
|
113389
113734
|
}
|
|
113390
|
-
return
|
|
113735
|
+
return resolve42(...args);
|
|
113391
113736
|
});
|
|
113392
113737
|
});
|
|
113393
113738
|
},
|
|
@@ -114179,7 +114524,7 @@ var require_end_of_stream2 = __commonJS({
|
|
|
114179
114524
|
validateBoolean3(opts.cleanup, "cleanup");
|
|
114180
114525
|
autoCleanup = opts.cleanup;
|
|
114181
114526
|
}
|
|
114182
|
-
return new Promise2((
|
|
114527
|
+
return new Promise2((resolve42, reject2) => {
|
|
114183
114528
|
const cleanup = eos(stream, opts, (err) => {
|
|
114184
114529
|
if (autoCleanup) {
|
|
114185
114530
|
cleanup();
|
|
@@ -114187,7 +114532,7 @@ var require_end_of_stream2 = __commonJS({
|
|
|
114187
114532
|
if (err) {
|
|
114188
114533
|
reject2(err);
|
|
114189
114534
|
} else {
|
|
114190
|
-
|
|
114535
|
+
resolve42();
|
|
114191
114536
|
}
|
|
114192
114537
|
});
|
|
114193
114538
|
});
|
|
@@ -115354,7 +115699,7 @@ var require_readable2 = __commonJS({
|
|
|
115354
115699
|
error = this.readableEnded ? null : new AbortError();
|
|
115355
115700
|
this.destroy(error);
|
|
115356
115701
|
}
|
|
115357
|
-
return new Promise2((
|
|
115702
|
+
return new Promise2((resolve42, reject2) => eos(this, (err) => err && err !== error ? reject2(err) : resolve42(null)));
|
|
115358
115703
|
};
|
|
115359
115704
|
Readable2.prototype.push = function(chunk, encoding) {
|
|
115360
115705
|
return readableAddChunk(this, chunk, encoding, false);
|
|
@@ -115898,12 +116243,12 @@ var require_readable2 = __commonJS({
|
|
|
115898
116243
|
}
|
|
115899
116244
|
async function* createAsyncIterator(stream, options) {
|
|
115900
116245
|
let callback = nop;
|
|
115901
|
-
function next(
|
|
116246
|
+
function next(resolve42) {
|
|
115902
116247
|
if (this === stream) {
|
|
115903
116248
|
callback();
|
|
115904
116249
|
callback = nop;
|
|
115905
116250
|
} else {
|
|
115906
|
-
callback =
|
|
116251
|
+
callback = resolve42;
|
|
115907
116252
|
}
|
|
115908
116253
|
}
|
|
115909
116254
|
stream.on("readable", next);
|
|
@@ -116956,7 +117301,7 @@ var require_duplexify = __commonJS({
|
|
|
116956
117301
|
);
|
|
116957
117302
|
};
|
|
116958
117303
|
function fromAsyncGen(fn) {
|
|
116959
|
-
let { promise, resolve:
|
|
117304
|
+
let { promise, resolve: resolve42 } = createDeferredPromise();
|
|
116960
117305
|
const ac = new AbortController2();
|
|
116961
117306
|
const signal = ac.signal;
|
|
116962
117307
|
const value = fn(
|
|
@@ -116971,7 +117316,7 @@ var require_duplexify = __commonJS({
|
|
|
116971
117316
|
throw new AbortError(void 0, {
|
|
116972
117317
|
cause: signal.reason
|
|
116973
117318
|
});
|
|
116974
|
-
({ promise, resolve:
|
|
117319
|
+
({ promise, resolve: resolve42 } = createDeferredPromise());
|
|
116975
117320
|
yield chunk;
|
|
116976
117321
|
}
|
|
116977
117322
|
})(),
|
|
@@ -116982,8 +117327,8 @@ var require_duplexify = __commonJS({
|
|
|
116982
117327
|
return {
|
|
116983
117328
|
value,
|
|
116984
117329
|
write(chunk, encoding, cb) {
|
|
116985
|
-
const _resolve =
|
|
116986
|
-
|
|
117330
|
+
const _resolve = resolve42;
|
|
117331
|
+
resolve42 = null;
|
|
116987
117332
|
_resolve({
|
|
116988
117333
|
chunk,
|
|
116989
117334
|
done: false,
|
|
@@ -116991,8 +117336,8 @@ var require_duplexify = __commonJS({
|
|
|
116991
117336
|
});
|
|
116992
117337
|
},
|
|
116993
117338
|
final(cb) {
|
|
116994
|
-
const _resolve =
|
|
116995
|
-
|
|
117339
|
+
const _resolve = resolve42;
|
|
117340
|
+
resolve42 = null;
|
|
116996
117341
|
_resolve({
|
|
116997
117342
|
done: true,
|
|
116998
117343
|
cb
|
|
@@ -117444,7 +117789,7 @@ var require_pipeline = __commonJS({
|
|
|
117444
117789
|
callback();
|
|
117445
117790
|
}
|
|
117446
117791
|
};
|
|
117447
|
-
const wait = () => new Promise2((
|
|
117792
|
+
const wait = () => new Promise2((resolve42, reject2) => {
|
|
117448
117793
|
if (error) {
|
|
117449
117794
|
reject2(error);
|
|
117450
117795
|
} else {
|
|
@@ -117452,7 +117797,7 @@ var require_pipeline = __commonJS({
|
|
|
117452
117797
|
if (error) {
|
|
117453
117798
|
reject2(error);
|
|
117454
117799
|
} else {
|
|
117455
|
-
|
|
117800
|
+
resolve42();
|
|
117456
117801
|
}
|
|
117457
117802
|
};
|
|
117458
117803
|
}
|
|
@@ -118096,8 +118441,8 @@ var require_operators = __commonJS({
|
|
|
118096
118441
|
next = null;
|
|
118097
118442
|
}
|
|
118098
118443
|
if (!done && (queue2.length >= highWaterMark2 || cnt >= concurrency)) {
|
|
118099
|
-
await new Promise2((
|
|
118100
|
-
resume =
|
|
118444
|
+
await new Promise2((resolve42) => {
|
|
118445
|
+
resume = resolve42;
|
|
118101
118446
|
});
|
|
118102
118447
|
}
|
|
118103
118448
|
}
|
|
@@ -118131,8 +118476,8 @@ var require_operators = __commonJS({
|
|
|
118131
118476
|
queue2.shift();
|
|
118132
118477
|
maybeResume();
|
|
118133
118478
|
}
|
|
118134
|
-
await new Promise2((
|
|
118135
|
-
next =
|
|
118479
|
+
await new Promise2((resolve42) => {
|
|
118480
|
+
next = resolve42;
|
|
118136
118481
|
});
|
|
118137
118482
|
}
|
|
118138
118483
|
} finally {
|
|
@@ -118390,7 +118735,7 @@ var require_promises = __commonJS({
|
|
|
118390
118735
|
var { finished } = require_end_of_stream2();
|
|
118391
118736
|
require_stream2();
|
|
118392
118737
|
function pipeline(...streams) {
|
|
118393
|
-
return new Promise2((
|
|
118738
|
+
return new Promise2((resolve42, reject2) => {
|
|
118394
118739
|
let signal;
|
|
118395
118740
|
let end;
|
|
118396
118741
|
const lastArg = streams[streams.length - 1];
|
|
@@ -118405,7 +118750,7 @@ var require_promises = __commonJS({
|
|
|
118405
118750
|
if (err) {
|
|
118406
118751
|
reject2(err);
|
|
118407
118752
|
} else {
|
|
118408
|
-
|
|
118753
|
+
resolve42(value);
|
|
118409
118754
|
}
|
|
118410
118755
|
},
|
|
118411
118756
|
{
|
|
@@ -123178,10 +123523,10 @@ var require_commonjs3 = __commonJS({
|
|
|
123178
123523
|
* Return a void Promise that resolves once the stream ends.
|
|
123179
123524
|
*/
|
|
123180
123525
|
async promise() {
|
|
123181
|
-
return new Promise((
|
|
123526
|
+
return new Promise((resolve42, reject2) => {
|
|
123182
123527
|
this.on(DESTROYED, () => reject2(new Error("stream destroyed")));
|
|
123183
123528
|
this.on("error", (er) => reject2(er));
|
|
123184
|
-
this.on("end", () =>
|
|
123529
|
+
this.on("end", () => resolve42());
|
|
123185
123530
|
});
|
|
123186
123531
|
}
|
|
123187
123532
|
/**
|
|
@@ -123205,7 +123550,7 @@ var require_commonjs3 = __commonJS({
|
|
|
123205
123550
|
return Promise.resolve({ done: false, value: res });
|
|
123206
123551
|
if (this[EOF])
|
|
123207
123552
|
return stop();
|
|
123208
|
-
let
|
|
123553
|
+
let resolve42;
|
|
123209
123554
|
let reject2;
|
|
123210
123555
|
const onerr = (er) => {
|
|
123211
123556
|
this.off("data", ondata);
|
|
@@ -123219,19 +123564,19 @@ var require_commonjs3 = __commonJS({
|
|
|
123219
123564
|
this.off("end", onend);
|
|
123220
123565
|
this.off(DESTROYED, ondestroy);
|
|
123221
123566
|
this.pause();
|
|
123222
|
-
|
|
123567
|
+
resolve42({ value, done: !!this[EOF] });
|
|
123223
123568
|
};
|
|
123224
123569
|
const onend = () => {
|
|
123225
123570
|
this.off("error", onerr);
|
|
123226
123571
|
this.off("data", ondata);
|
|
123227
123572
|
this.off(DESTROYED, ondestroy);
|
|
123228
123573
|
stop();
|
|
123229
|
-
|
|
123574
|
+
resolve42({ done: true, value: void 0 });
|
|
123230
123575
|
};
|
|
123231
123576
|
const ondestroy = () => onerr(new Error("stream destroyed"));
|
|
123232
123577
|
return new Promise((res2, rej) => {
|
|
123233
123578
|
reject2 = rej;
|
|
123234
|
-
|
|
123579
|
+
resolve42 = res2;
|
|
123235
123580
|
this.once(DESTROYED, ondestroy);
|
|
123236
123581
|
this.once("error", onerr);
|
|
123237
123582
|
this.once("end", onend);
|
|
@@ -124247,9 +124592,9 @@ var require_commonjs4 = __commonJS({
|
|
|
124247
124592
|
if (this.#asyncReaddirInFlight) {
|
|
124248
124593
|
await this.#asyncReaddirInFlight;
|
|
124249
124594
|
} else {
|
|
124250
|
-
let
|
|
124595
|
+
let resolve42 = () => {
|
|
124251
124596
|
};
|
|
124252
|
-
this.#asyncReaddirInFlight = new Promise((res) =>
|
|
124597
|
+
this.#asyncReaddirInFlight = new Promise((res) => resolve42 = res);
|
|
124253
124598
|
try {
|
|
124254
124599
|
for (const e of await this.#fs.promises.readdir(fullpath, {
|
|
124255
124600
|
withFileTypes: true
|
|
@@ -124262,7 +124607,7 @@ var require_commonjs4 = __commonJS({
|
|
|
124262
124607
|
children.provisional = 0;
|
|
124263
124608
|
}
|
|
124264
124609
|
this.#asyncReaddirInFlight = void 0;
|
|
124265
|
-
|
|
124610
|
+
resolve42();
|
|
124266
124611
|
}
|
|
124267
124612
|
return children.slice(0, children.provisional);
|
|
124268
124613
|
}
|
|
@@ -125129,7 +125474,7 @@ var require_pattern = __commonJS({
|
|
|
125129
125474
|
#isUNC;
|
|
125130
125475
|
#isAbsolute;
|
|
125131
125476
|
#followGlobstar = true;
|
|
125132
|
-
constructor(patternList, globList, index2,
|
|
125477
|
+
constructor(patternList, globList, index2, platform4) {
|
|
125133
125478
|
if (!isPatternList(patternList)) {
|
|
125134
125479
|
throw new TypeError("empty pattern list");
|
|
125135
125480
|
}
|
|
@@ -125146,7 +125491,7 @@ var require_pattern = __commonJS({
|
|
|
125146
125491
|
this.#patternList = patternList;
|
|
125147
125492
|
this.#globList = globList;
|
|
125148
125493
|
this.#index = index2;
|
|
125149
|
-
this.#platform =
|
|
125494
|
+
this.#platform = platform4;
|
|
125150
125495
|
if (this.#index === 0) {
|
|
125151
125496
|
if (this.isUNC()) {
|
|
125152
125497
|
const [p0, p1, p2, p3, ...prest] = this.#patternList;
|
|
@@ -125298,12 +125643,12 @@ var require_ignore = __commonJS({
|
|
|
125298
125643
|
absoluteChildren;
|
|
125299
125644
|
platform;
|
|
125300
125645
|
mmopts;
|
|
125301
|
-
constructor(ignored, { nobrace, nocase, noext, noglobstar, platform:
|
|
125646
|
+
constructor(ignored, { nobrace, nocase, noext, noglobstar, platform: platform4 = defaultPlatform }) {
|
|
125302
125647
|
this.relative = [];
|
|
125303
125648
|
this.absolute = [];
|
|
125304
125649
|
this.relativeChildren = [];
|
|
125305
125650
|
this.absoluteChildren = [];
|
|
125306
|
-
this.platform =
|
|
125651
|
+
this.platform = platform4;
|
|
125307
125652
|
this.mmopts = {
|
|
125308
125653
|
dot: true,
|
|
125309
125654
|
nobrace,
|
|
@@ -125311,7 +125656,7 @@ var require_ignore = __commonJS({
|
|
|
125311
125656
|
noext,
|
|
125312
125657
|
noglobstar,
|
|
125313
125658
|
optimizationLevel: 2,
|
|
125314
|
-
platform:
|
|
125659
|
+
platform: platform4,
|
|
125315
125660
|
nocomment: true,
|
|
125316
125661
|
nonegate: true
|
|
125317
125662
|
};
|
|
@@ -127035,11 +127380,11 @@ var require_core = __commonJS({
|
|
|
127035
127380
|
this._finalize();
|
|
127036
127381
|
}
|
|
127037
127382
|
var self2 = this;
|
|
127038
|
-
return new Promise(function(
|
|
127383
|
+
return new Promise(function(resolve42, reject2) {
|
|
127039
127384
|
var errored;
|
|
127040
127385
|
self2._module.on("end", function() {
|
|
127041
127386
|
if (!errored) {
|
|
127042
|
-
|
|
127387
|
+
resolve42();
|
|
127043
127388
|
}
|
|
127044
127389
|
});
|
|
127045
127390
|
self2._module.on("error", function(err) {
|
|
@@ -127533,8 +127878,8 @@ var require_zip_archive_entry = __commonJS({
|
|
|
127533
127878
|
}
|
|
127534
127879
|
this.name = name;
|
|
127535
127880
|
};
|
|
127536
|
-
ZipArchiveEntry.prototype.setPlatform = function(
|
|
127537
|
-
this.platform =
|
|
127881
|
+
ZipArchiveEntry.prototype.setPlatform = function(platform4) {
|
|
127882
|
+
this.platform = platform4;
|
|
127538
127883
|
};
|
|
127539
127884
|
ZipArchiveEntry.prototype.setSize = function(size) {
|
|
127540
127885
|
if (size < 0) {
|
|
@@ -129479,8 +129824,8 @@ var require_streamx = __commonJS({
|
|
|
129479
129824
|
return this;
|
|
129480
129825
|
},
|
|
129481
129826
|
next() {
|
|
129482
|
-
return new Promise(function(
|
|
129483
|
-
promiseResolve =
|
|
129827
|
+
return new Promise(function(resolve42, reject2) {
|
|
129828
|
+
promiseResolve = resolve42;
|
|
129484
129829
|
promiseReject = reject2;
|
|
129485
129830
|
const data = stream.read();
|
|
129486
129831
|
if (data !== null) ondata(data);
|
|
@@ -129510,11 +129855,11 @@ var require_streamx = __commonJS({
|
|
|
129510
129855
|
}
|
|
129511
129856
|
function destroy(err) {
|
|
129512
129857
|
stream.destroy(err);
|
|
129513
|
-
return new Promise((
|
|
129514
|
-
if (stream._duplexState & DESTROYED) return
|
|
129858
|
+
return new Promise((resolve42, reject2) => {
|
|
129859
|
+
if (stream._duplexState & DESTROYED) return resolve42({ value: void 0, done: true });
|
|
129515
129860
|
stream.once("close", function() {
|
|
129516
129861
|
if (err) reject2(err);
|
|
129517
|
-
else
|
|
129862
|
+
else resolve42({ value: void 0, done: true });
|
|
129518
129863
|
});
|
|
129519
129864
|
});
|
|
129520
129865
|
}
|
|
@@ -129558,8 +129903,8 @@ var require_streamx = __commonJS({
|
|
|
129558
129903
|
const writes = pending + (ws._duplexState & WRITE_WRITING ? 1 : 0);
|
|
129559
129904
|
if (writes === 0) return Promise.resolve(true);
|
|
129560
129905
|
if (state.drains === null) state.drains = [];
|
|
129561
|
-
return new Promise((
|
|
129562
|
-
state.drains.push({ writes, resolve:
|
|
129906
|
+
return new Promise((resolve42) => {
|
|
129907
|
+
state.drains.push({ writes, resolve: resolve42 });
|
|
129563
129908
|
});
|
|
129564
129909
|
}
|
|
129565
129910
|
write(data) {
|
|
@@ -129664,10 +130009,10 @@ var require_streamx = __commonJS({
|
|
|
129664
130009
|
cb(null);
|
|
129665
130010
|
}
|
|
129666
130011
|
function pipelinePromise(...streams) {
|
|
129667
|
-
return new Promise((
|
|
130012
|
+
return new Promise((resolve42, reject2) => {
|
|
129668
130013
|
return pipeline(...streams, (err) => {
|
|
129669
130014
|
if (err) return reject2(err);
|
|
129670
|
-
|
|
130015
|
+
resolve42();
|
|
129671
130016
|
});
|
|
129672
130017
|
});
|
|
129673
130018
|
}
|
|
@@ -130324,16 +130669,16 @@ var require_extract = __commonJS({
|
|
|
130324
130669
|
entryCallback = null;
|
|
130325
130670
|
cb(err);
|
|
130326
130671
|
}
|
|
130327
|
-
function onnext(
|
|
130672
|
+
function onnext(resolve42, reject2) {
|
|
130328
130673
|
if (error) {
|
|
130329
130674
|
return reject2(error);
|
|
130330
130675
|
}
|
|
130331
130676
|
if (entryStream) {
|
|
130332
|
-
|
|
130677
|
+
resolve42({ value: entryStream, done: false });
|
|
130333
130678
|
entryStream = null;
|
|
130334
130679
|
return;
|
|
130335
130680
|
}
|
|
130336
|
-
promiseResolve =
|
|
130681
|
+
promiseResolve = resolve42;
|
|
130337
130682
|
promiseReject = reject2;
|
|
130338
130683
|
consumeCallback(null);
|
|
130339
130684
|
if (extract._finished && promiseResolve) {
|
|
@@ -130361,11 +130706,11 @@ var require_extract = __commonJS({
|
|
|
130361
130706
|
function destroy(err) {
|
|
130362
130707
|
extract.destroy(err);
|
|
130363
130708
|
consumeCallback(err);
|
|
130364
|
-
return new Promise((
|
|
130365
|
-
if (extract.destroyed) return
|
|
130709
|
+
return new Promise((resolve42, reject2) => {
|
|
130710
|
+
if (extract.destroyed) return resolve42({ value: void 0, done: true });
|
|
130366
130711
|
extract.once("close", function() {
|
|
130367
130712
|
if (err) reject2(err);
|
|
130368
|
-
else
|
|
130713
|
+
else resolve42({ value: void 0, done: true });
|
|
130369
130714
|
});
|
|
130370
130715
|
});
|
|
130371
130716
|
}
|
|
@@ -133702,6 +134047,20 @@ var init_register_settings_sync_inbound_routes = __esm({
|
|
|
133702
134047
|
});
|
|
133703
134048
|
|
|
133704
134049
|
// ../dashboard/src/routes/register-agent-core-routes.ts
|
|
134050
|
+
function isCompatibleDefaultHeartbeatPath(path5, agent) {
|
|
134051
|
+
const trimmed = path5?.trim();
|
|
134052
|
+
if (!trimmed) {
|
|
134053
|
+
return false;
|
|
134054
|
+
}
|
|
134055
|
+
if (trimmed === getDefaultHeartbeatProcedurePath(agent.id, agent.name)) {
|
|
134056
|
+
return true;
|
|
134057
|
+
}
|
|
134058
|
+
if (trimmed === getDefaultHeartbeatProcedurePath(agent.id)) {
|
|
134059
|
+
return true;
|
|
134060
|
+
}
|
|
134061
|
+
const safeId = agent.id.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "agent";
|
|
134062
|
+
return new RegExp(`^\\.fusion/agents/[^/]+-${safeId}/HEARTBEAT\\.md$`).test(trimmed);
|
|
134063
|
+
}
|
|
133705
134064
|
function registerAgentCoreListCreateRoutes(ctx, deps) {
|
|
133706
134065
|
const { router, getProjectContext: getProjectContext3, rethrowAsApiError: rethrowAsApiError8 } = ctx;
|
|
133707
134066
|
const { sanitizeAgentTaskLinks, validateAgentInstructionsPayload } = deps;
|
|
@@ -133831,7 +134190,7 @@ function registerAgentCoreListCreateRoutes(ctx, deps) {
|
|
|
133831
134190
|
bundleConfig: bundleConfig ?? void 0,
|
|
133832
134191
|
heartbeatProcedurePath: heartbeatProcedurePath ?? void 0
|
|
133833
134192
|
});
|
|
133834
|
-
const expectedDefaultPath = getDefaultHeartbeatProcedurePath(agent.id);
|
|
134193
|
+
const expectedDefaultPath = getDefaultHeartbeatProcedurePath(agent.id, agent.name);
|
|
133835
134194
|
if (agent.heartbeatProcedurePath === expectedDefaultPath) {
|
|
133836
134195
|
try {
|
|
133837
134196
|
await ensureDefaultHeartbeatProcedureFile(scopedStore.getRootDir(), expectedDefaultPath, HEARTBEAT_PROCEDURE);
|
|
@@ -134089,7 +134448,7 @@ function registerAgentCoreRoutes(ctx, deps) {
|
|
|
134089
134448
|
if (!existing) {
|
|
134090
134449
|
throw notFound(`agent ${req.params.id} not found`);
|
|
134091
134450
|
}
|
|
134092
|
-
const targetPath = getDefaultHeartbeatProcedurePath(
|
|
134451
|
+
const targetPath = isCompatibleDefaultHeartbeatPath(existing.heartbeatProcedurePath, existing) ? existing.heartbeatProcedurePath : getDefaultHeartbeatProcedurePath(existing.id, existing.name);
|
|
134093
134452
|
const filePath = await ensureDefaultHeartbeatProcedureFile(
|
|
134094
134453
|
scopedStore.getRootDir(),
|
|
134095
134454
|
targetPath,
|
|
@@ -137349,9 +137708,9 @@ function registerProxyRoutes(router, deps) {
|
|
|
137349
137708
|
if (req.rawBody && req.rawBody.length > 0) {
|
|
137350
137709
|
body = req.rawBody;
|
|
137351
137710
|
} else {
|
|
137352
|
-
await new Promise((
|
|
137711
|
+
await new Promise((resolve42, reject2) => {
|
|
137353
137712
|
req.on("data", (chunk) => chunks.push(chunk));
|
|
137354
|
-
req.on("end",
|
|
137713
|
+
req.on("end", resolve42);
|
|
137355
137714
|
req.on("error", reject2);
|
|
137356
137715
|
});
|
|
137357
137716
|
if (chunks.length > 0) {
|
|
@@ -137482,6 +137841,7 @@ var init_register_model_routes = __esm({
|
|
|
137482
137841
|
let defaultProvider;
|
|
137483
137842
|
let defaultModelId;
|
|
137484
137843
|
let useClaudeCli = false;
|
|
137844
|
+
let useDroidCli = false;
|
|
137485
137845
|
if (store) {
|
|
137486
137846
|
try {
|
|
137487
137847
|
const globalStore = store.getGlobalSettingsStore();
|
|
@@ -137491,6 +137851,7 @@ var init_register_model_routes = __esm({
|
|
|
137491
137851
|
defaultProvider = globalSettings.defaultProvider;
|
|
137492
137852
|
defaultModelId = globalSettings.defaultModelId;
|
|
137493
137853
|
useClaudeCli = globalSettings.useClaudeCli === true;
|
|
137854
|
+
useDroidCli = globalSettings.useDroidCli === true;
|
|
137494
137855
|
} catch {
|
|
137495
137856
|
}
|
|
137496
137857
|
}
|
|
@@ -137516,6 +137877,9 @@ var init_register_model_routes = __esm({
|
|
|
137516
137877
|
if (!useClaudeCli) {
|
|
137517
137878
|
models = models.filter((m) => m.provider !== "pi-claude-cli");
|
|
137518
137879
|
}
|
|
137880
|
+
if (!useDroidCli) {
|
|
137881
|
+
models = models.filter((m) => m.provider !== "droid-cli");
|
|
137882
|
+
}
|
|
137519
137883
|
res.json({
|
|
137520
137884
|
models,
|
|
137521
137885
|
favoriteProviders,
|
|
@@ -137763,13 +138127,13 @@ function getHomeDir5() {
|
|
|
137763
138127
|
return process.env.HOME || process.env.USERPROFILE || os4.homedir();
|
|
137764
138128
|
}
|
|
137765
138129
|
function execFileAsync5(file, args, options) {
|
|
137766
|
-
return new Promise((
|
|
138130
|
+
return new Promise((resolve42, reject2) => {
|
|
137767
138131
|
child_process.execFile(file, args, options, (error, stdout, stderr) => {
|
|
137768
138132
|
if (error) {
|
|
137769
138133
|
reject2(error);
|
|
137770
138134
|
return;
|
|
137771
138135
|
}
|
|
137772
|
-
|
|
138136
|
+
resolve42({ stdout: String(stdout), stderr: String(stderr) });
|
|
137773
138137
|
});
|
|
137774
138138
|
});
|
|
137775
138139
|
}
|
|
@@ -137828,7 +138192,7 @@ function formatDuration(ms) {
|
|
|
137828
138192
|
return remHours > 0 ? `${days}d ${remHours}h` : `${days}d`;
|
|
137829
138193
|
}
|
|
137830
138194
|
function httpsRequest(url, options) {
|
|
137831
|
-
return new Promise((
|
|
138195
|
+
return new Promise((resolve42, reject2) => {
|
|
137832
138196
|
const parsed = new URL(url);
|
|
137833
138197
|
const req = https.request(
|
|
137834
138198
|
{
|
|
@@ -137848,7 +138212,7 @@ function httpsRequest(url, options) {
|
|
|
137848
138212
|
if (typeof v === "string") hdrs[k.toLowerCase()] = v;
|
|
137849
138213
|
else if (Array.isArray(v)) hdrs[k.toLowerCase()] = v.join(", ");
|
|
137850
138214
|
}
|
|
137851
|
-
|
|
138215
|
+
resolve42({
|
|
137852
138216
|
status: res.statusCode || 0,
|
|
137853
138217
|
headers: hdrs,
|
|
137854
138218
|
body: Buffer.concat(chunks).toString("utf-8")
|
|
@@ -138095,7 +138459,7 @@ async function fetchClaudeUsageViaCli() {
|
|
|
138095
138459
|
env: { ...process.env, TERM: "xterm-256color" }
|
|
138096
138460
|
};
|
|
138097
138461
|
if (isWindows) ptyOptions.useConpty = false;
|
|
138098
|
-
const output = await new Promise((
|
|
138462
|
+
const output = await new Promise((resolve42, reject2) => {
|
|
138099
138463
|
let buf = "";
|
|
138100
138464
|
let settled = false;
|
|
138101
138465
|
let sentCommand = false;
|
|
@@ -138111,7 +138475,7 @@ async function fetchClaudeUsageViaCli() {
|
|
|
138111
138475
|
}
|
|
138112
138476
|
const clean = _stripClaudeAnsi(buf);
|
|
138113
138477
|
if (clean.includes("Current session") || clean.includes("% left") || clean.includes("% used")) {
|
|
138114
|
-
|
|
138478
|
+
resolve42(buf);
|
|
138115
138479
|
} else {
|
|
138116
138480
|
reject2(new Error("Claude CLI timed out after 60s \u2014 got output but no usage data. Try running `claude /usage` manually."));
|
|
138117
138481
|
}
|
|
@@ -138162,7 +138526,7 @@ async function fetchClaudeUsageViaCli() {
|
|
|
138162
138526
|
ptyProcess.kill();
|
|
138163
138527
|
} catch {
|
|
138164
138528
|
}
|
|
138165
|
-
|
|
138529
|
+
resolve42(buf);
|
|
138166
138530
|
}
|
|
138167
138531
|
}, 2e3);
|
|
138168
138532
|
}
|
|
@@ -138173,7 +138537,7 @@ async function fetchClaudeUsageViaCli() {
|
|
|
138173
138537
|
if (settled) return;
|
|
138174
138538
|
settled = true;
|
|
138175
138539
|
clearTimeout(timeout2);
|
|
138176
|
-
|
|
138540
|
+
resolve42(buf);
|
|
138177
138541
|
});
|
|
138178
138542
|
});
|
|
138179
138543
|
const cleanOutput = _stripClaudeAnsi(output);
|
|
@@ -138841,9 +139205,9 @@ async function fetchGitHubCopilotUsage() {
|
|
|
138841
139205
|
return usage;
|
|
138842
139206
|
}
|
|
138843
139207
|
function withTimeout(providerPromise, providerName, timeoutMs = PROVIDER_FETCH_TIMEOUT_MS) {
|
|
138844
|
-
return new Promise((
|
|
139208
|
+
return new Promise((resolve42) => {
|
|
138845
139209
|
const timer = setTimeout(() => {
|
|
138846
|
-
|
|
139210
|
+
resolve42({
|
|
138847
139211
|
name: providerName,
|
|
138848
139212
|
icon: "\u23F1\uFE0F",
|
|
138849
139213
|
status: "error",
|
|
@@ -138853,10 +139217,10 @@ function withTimeout(providerPromise, providerName, timeoutMs = PROVIDER_FETCH_T
|
|
|
138853
139217
|
}, timeoutMs);
|
|
138854
139218
|
providerPromise.then((result) => {
|
|
138855
139219
|
clearTimeout(timer);
|
|
138856
|
-
|
|
139220
|
+
resolve42(result);
|
|
138857
139221
|
}).catch((err) => {
|
|
138858
139222
|
clearTimeout(timer);
|
|
138859
|
-
|
|
139223
|
+
resolve42({
|
|
138860
139224
|
name: providerName,
|
|
138861
139225
|
icon: "\u23F1\uFE0F",
|
|
138862
139226
|
status: "error",
|
|
@@ -138911,7 +139275,7 @@ var init_usage = __esm({
|
|
|
138911
139275
|
ANTHROPIC_OAUTH_CLIENT_ID = "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
|
|
138912
139276
|
ANTHROPIC_OAUTH_BETA = "oauth-2025-04-20";
|
|
138913
139277
|
CLAUDE_USAGE_USER_AGENT = "claude-code-fusion-dashboard";
|
|
138914
|
-
_sleep = (ms) => new Promise((
|
|
139278
|
+
_sleep = (ms) => new Promise((resolve42) => setTimeout(resolve42, ms));
|
|
138915
139279
|
sleepFn = _sleep;
|
|
138916
139280
|
PROVIDER_FETCH_TIMEOUT_MS = 1e4;
|
|
138917
139281
|
CLAUDE_FETCH_TIMEOUT_MS = 75e3;
|
|
@@ -138943,7 +139307,7 @@ var init_register_usage_routes = __esm({
|
|
|
138943
139307
|
});
|
|
138944
139308
|
|
|
138945
139309
|
// ../dashboard/src/claude-cli-probe.ts
|
|
138946
|
-
import { spawn as
|
|
139310
|
+
import { spawn as spawn11 } from "node:child_process";
|
|
138947
139311
|
async function probeClaudeCli(options = {}) {
|
|
138948
139312
|
const startedAt = Date.now();
|
|
138949
139313
|
const timeoutMs = options.timeoutMs ?? PROBE_TIMEOUT_MS;
|
|
@@ -138953,7 +139317,7 @@ async function probeClaudeCli(options = {}) {
|
|
|
138953
139317
|
resolvePromise({ ...result, probeDurationMs: Date.now() - startedAt });
|
|
138954
139318
|
};
|
|
138955
139319
|
let settled = false;
|
|
138956
|
-
const child =
|
|
139320
|
+
const child = spawn11(binaryPath ?? "claude", ["--version"], {
|
|
138957
139321
|
stdio: ["ignore", "pipe", "pipe"]
|
|
138958
139322
|
});
|
|
138959
139323
|
const timer = setTimeout(() => {
|
|
@@ -139011,7 +139375,7 @@ async function probeClaudeCli(options = {}) {
|
|
|
139011
139375
|
async function tryResolveBinaryPath3(binary) {
|
|
139012
139376
|
return new Promise((resolvePromise) => {
|
|
139013
139377
|
const which = process.platform === "win32" ? "where" : "which";
|
|
139014
|
-
const child =
|
|
139378
|
+
const child = spawn11(which, [binary], { stdio: ["ignore", "pipe", "ignore"] });
|
|
139015
139379
|
let out = "";
|
|
139016
139380
|
child.stdout?.on("data", (chunk) => {
|
|
139017
139381
|
out += chunk.toString("utf-8");
|
|
@@ -139036,7 +139400,7 @@ var init_claude_cli_probe = __esm({
|
|
|
139036
139400
|
});
|
|
139037
139401
|
|
|
139038
139402
|
// ../dashboard/src/droid-cli-probe.ts
|
|
139039
|
-
import { spawn as
|
|
139403
|
+
import { spawn as spawn12 } from "node:child_process";
|
|
139040
139404
|
async function probeDroidCli(options = {}) {
|
|
139041
139405
|
const startedAt = Date.now();
|
|
139042
139406
|
const timeoutMs = options.timeoutMs ?? PROBE_TIMEOUT_MS2;
|
|
@@ -139046,7 +139410,7 @@ async function probeDroidCli(options = {}) {
|
|
|
139046
139410
|
resolvePromise({ ...result, probeDurationMs: Date.now() - startedAt });
|
|
139047
139411
|
};
|
|
139048
139412
|
let settled = false;
|
|
139049
|
-
const child =
|
|
139413
|
+
const child = spawn12(binaryPath ?? "droid", ["--version"], {
|
|
139050
139414
|
stdio: ["ignore", "pipe", "pipe"]
|
|
139051
139415
|
});
|
|
139052
139416
|
const timer = setTimeout(() => {
|
|
@@ -139104,7 +139468,7 @@ async function probeDroidCli(options = {}) {
|
|
|
139104
139468
|
async function tryResolveBinaryPath4(binary) {
|
|
139105
139469
|
return new Promise((resolvePromise) => {
|
|
139106
139470
|
const which = process.platform === "win32" ? "where" : "which";
|
|
139107
|
-
const child =
|
|
139471
|
+
const child = spawn12(which, [binary], { stdio: ["ignore", "pipe", "ignore"] });
|
|
139108
139472
|
let out = "";
|
|
139109
139473
|
child.stdout?.on("data", (chunk) => {
|
|
139110
139474
|
out += chunk.toString("utf-8");
|
|
@@ -139479,8 +139843,8 @@ var init_register_auth_routes = __esm({
|
|
|
139479
139843
|
loginInProgress.set(provider, abortController);
|
|
139480
139844
|
let authResolve;
|
|
139481
139845
|
let authReject;
|
|
139482
|
-
const authUrlPromise = new Promise((
|
|
139483
|
-
authResolve =
|
|
139846
|
+
const authUrlPromise = new Promise((resolve42, reject2) => {
|
|
139847
|
+
authResolve = resolve42;
|
|
139484
139848
|
authReject = reject2;
|
|
139485
139849
|
});
|
|
139486
139850
|
const loginPromise = storage.login(provider, {
|
|
@@ -139948,7 +140312,7 @@ function stripAnsi2(str) {
|
|
|
139948
140312
|
return str.replace(/\x1B\[[0-9;]*[mGKJHFABCDSTsu]/g, "");
|
|
139949
140313
|
}
|
|
139950
140314
|
async function mintAgentApiKeyViaCli(opts) {
|
|
139951
|
-
const { spawn:
|
|
140315
|
+
const { spawn: spawn19 } = await import("node:child_process");
|
|
139952
140316
|
const bin = opts.cliBinaryPath ?? "paperclipai";
|
|
139953
140317
|
const args = [
|
|
139954
140318
|
"agent",
|
|
@@ -139969,10 +140333,10 @@ async function mintAgentApiKeyViaCli(opts) {
|
|
|
139969
140333
|
args.push("--data-dir", opts.dataDir);
|
|
139970
140334
|
}
|
|
139971
140335
|
const timeoutMs = opts.cliTimeoutMs ?? 3e4;
|
|
139972
|
-
return new Promise((
|
|
140336
|
+
return new Promise((resolve42, reject2) => {
|
|
139973
140337
|
let child;
|
|
139974
140338
|
try {
|
|
139975
|
-
child =
|
|
140339
|
+
child = spawn19(bin, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
139976
140340
|
} catch (err) {
|
|
139977
140341
|
const code = err.code;
|
|
139978
140342
|
if (code === "ENOENT") {
|
|
@@ -140043,7 +140407,7 @@ async function mintAgentApiKeyViaCli(opts) {
|
|
|
140043
140407
|
const apiBase = (typeof r.apiBase === "string" ? r.apiBase : void 0) ?? (typeof r.api_base === "string" ? r.api_base : void 0);
|
|
140044
140408
|
const agentId = (typeof r.agentId === "string" ? r.agentId : void 0) ?? (typeof r.id === "string" ? r.id : void 0);
|
|
140045
140409
|
const companyId = typeof r.companyId === "string" ? r.companyId : void 0;
|
|
140046
|
-
|
|
140410
|
+
resolve42({ apiKey, apiBase, agentId, companyId, raw: parsed });
|
|
140047
140411
|
});
|
|
140048
140412
|
});
|
|
140049
140413
|
}
|
|
@@ -140055,7 +140419,7 @@ function remapSpawnError(err, bin) {
|
|
|
140055
140419
|
return err instanceof Error ? err : new Error(String(err));
|
|
140056
140420
|
}
|
|
140057
140421
|
async function spawnPaperclipCliJson(args, opts) {
|
|
140058
|
-
const { spawn:
|
|
140422
|
+
const { spawn: spawn19 } = await import("node:child_process");
|
|
140059
140423
|
const bin = opts.cliBinaryPath ?? "paperclipai";
|
|
140060
140424
|
const fullArgs = [...args, "--json"];
|
|
140061
140425
|
if (opts.cliConfigPath) {
|
|
@@ -140063,10 +140427,10 @@ async function spawnPaperclipCliJson(args, opts) {
|
|
|
140063
140427
|
}
|
|
140064
140428
|
const timeoutMs = opts.cliTimeoutMs ?? 15e3;
|
|
140065
140429
|
const label = ["paperclipai", ...args].join(" ");
|
|
140066
|
-
return new Promise((
|
|
140430
|
+
return new Promise((resolve42, reject2) => {
|
|
140067
140431
|
let child;
|
|
140068
140432
|
try {
|
|
140069
|
-
child =
|
|
140433
|
+
child = spawn19(bin, fullArgs, { stdio: ["ignore", "pipe", "pipe"] });
|
|
140070
140434
|
} catch (err) {
|
|
140071
140435
|
reject2(remapSpawnError(err, bin));
|
|
140072
140436
|
return;
|
|
@@ -140109,7 +140473,7 @@ async function spawnPaperclipCliJson(args, opts) {
|
|
|
140109
140473
|
return;
|
|
140110
140474
|
}
|
|
140111
140475
|
try {
|
|
140112
|
-
|
|
140476
|
+
resolve42(JSON.parse(cleaned));
|
|
140113
140477
|
} catch {
|
|
140114
140478
|
reject2(new Error(`${label} returned non-JSON output: ${cleaned.slice(0, 200)}`));
|
|
140115
140479
|
}
|
|
@@ -140238,7 +140602,7 @@ var init_paperclip_client = __esm({
|
|
|
140238
140602
|
// ../../plugins/fusion-plugin-paperclip-runtime/dist/runtime-adapter.js
|
|
140239
140603
|
import { randomUUID as randomUUID20 } from "node:crypto";
|
|
140240
140604
|
function sleep4(ms) {
|
|
140241
|
-
return new Promise((
|
|
140605
|
+
return new Promise((resolve42) => setTimeout(resolve42, ms));
|
|
140242
140606
|
}
|
|
140243
140607
|
function asString2(value) {
|
|
140244
140608
|
return typeof value === "string" ? value : void 0;
|
|
@@ -140879,8 +141243,184 @@ var init_register_runtime_provider_routes = __esm({
|
|
|
140879
141243
|
}
|
|
140880
141244
|
});
|
|
140881
141245
|
|
|
141246
|
+
// ../dashboard/src/cli-package-version.ts
|
|
141247
|
+
import { existsSync as existsSync32, readFileSync as readFileSync10 } from "node:fs";
|
|
141248
|
+
import { dirname as dirname15, resolve as resolve23 } from "node:path";
|
|
141249
|
+
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
141250
|
+
function readCliPackageVersion(pkgPath) {
|
|
141251
|
+
if (!existsSync32(pkgPath)) {
|
|
141252
|
+
return null;
|
|
141253
|
+
}
|
|
141254
|
+
try {
|
|
141255
|
+
const parsed = JSON.parse(readFileSync10(pkgPath, "utf-8"));
|
|
141256
|
+
if (parsed.name === CLI_PACKAGE_NAME && typeof parsed.version === "string" && parsed.version.length > 0) {
|
|
141257
|
+
return {
|
|
141258
|
+
packageJsonPath: pkgPath,
|
|
141259
|
+
version: parsed.version
|
|
141260
|
+
};
|
|
141261
|
+
}
|
|
141262
|
+
} catch {
|
|
141263
|
+
}
|
|
141264
|
+
return null;
|
|
141265
|
+
}
|
|
141266
|
+
function resolveCliPackageVersionInfo(startDir) {
|
|
141267
|
+
let currentDir = startDir;
|
|
141268
|
+
for (let i = 0; i < 8; i += 1) {
|
|
141269
|
+
const versionInfo = readCliPackageVersion(resolve23(currentDir, "package.json"));
|
|
141270
|
+
if (versionInfo) {
|
|
141271
|
+
return versionInfo;
|
|
141272
|
+
}
|
|
141273
|
+
const parentDir = resolve23(currentDir, "..");
|
|
141274
|
+
if (parentDir === currentDir) {
|
|
141275
|
+
break;
|
|
141276
|
+
}
|
|
141277
|
+
currentDir = parentDir;
|
|
141278
|
+
}
|
|
141279
|
+
currentDir = startDir;
|
|
141280
|
+
for (let i = 0; i < 8; i += 1) {
|
|
141281
|
+
const versionInfo = readCliPackageVersion(resolve23(currentDir, "..", "cli", "package.json"));
|
|
141282
|
+
if (versionInfo) {
|
|
141283
|
+
return versionInfo;
|
|
141284
|
+
}
|
|
141285
|
+
const parentDir = resolve23(currentDir, "..");
|
|
141286
|
+
if (parentDir === currentDir) {
|
|
141287
|
+
break;
|
|
141288
|
+
}
|
|
141289
|
+
currentDir = parentDir;
|
|
141290
|
+
}
|
|
141291
|
+
return null;
|
|
141292
|
+
}
|
|
141293
|
+
function getCliPackageVersion(importMetaUrl = import.meta.url) {
|
|
141294
|
+
const startDir = dirname15(fileURLToPath4(importMetaUrl));
|
|
141295
|
+
return resolveCliPackageVersionInfo(startDir)?.version ?? process.env.npm_package_version ?? "0.0.0";
|
|
141296
|
+
}
|
|
141297
|
+
var CLI_PACKAGE_NAME;
|
|
141298
|
+
var init_cli_package_version = __esm({
|
|
141299
|
+
"../dashboard/src/cli-package-version.ts"() {
|
|
141300
|
+
"use strict";
|
|
141301
|
+
CLI_PACKAGE_NAME = "@runfusion/fusion";
|
|
141302
|
+
}
|
|
141303
|
+
});
|
|
141304
|
+
|
|
141305
|
+
// ../dashboard/src/routes/register-fn-binary-routes.ts
|
|
141306
|
+
import { spawn as spawn13 } from "node:child_process";
|
|
141307
|
+
function buildStatusPayload(binary, expectedVersion) {
|
|
141308
|
+
let state = "missing";
|
|
141309
|
+
if (binary.installed) {
|
|
141310
|
+
state = binary.version && binary.version !== expectedVersion ? "version-mismatch" : "installed";
|
|
141311
|
+
}
|
|
141312
|
+
return {
|
|
141313
|
+
binary,
|
|
141314
|
+
expectedVersion,
|
|
141315
|
+
state,
|
|
141316
|
+
install: {
|
|
141317
|
+
npm: FN_INSTALL_NPM,
|
|
141318
|
+
curl: FN_INSTALL_CURL,
|
|
141319
|
+
package: FN_NPM_PACKAGE
|
|
141320
|
+
}
|
|
141321
|
+
};
|
|
141322
|
+
}
|
|
141323
|
+
function runNpmInstall() {
|
|
141324
|
+
const startedAt = Date.now();
|
|
141325
|
+
const command = FN_INSTALL_NPM;
|
|
141326
|
+
return new Promise((resolve42) => {
|
|
141327
|
+
let stdout = "";
|
|
141328
|
+
let stderr = "";
|
|
141329
|
+
let timedOut = false;
|
|
141330
|
+
const child = spawn13("npm", ["install", "-g", FN_NPM_PACKAGE], {
|
|
141331
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
141332
|
+
shell: false
|
|
141333
|
+
});
|
|
141334
|
+
const timer = setTimeout(() => {
|
|
141335
|
+
timedOut = true;
|
|
141336
|
+
try {
|
|
141337
|
+
child.kill("SIGKILL");
|
|
141338
|
+
} catch {
|
|
141339
|
+
}
|
|
141340
|
+
}, INSTALL_TIMEOUT_MS);
|
|
141341
|
+
const append = (target, chunk) => {
|
|
141342
|
+
const text = chunk.toString("utf8");
|
|
141343
|
+
if (target === "stdout") {
|
|
141344
|
+
if (stdout.length < MAX_OUTPUT_BYTES2) {
|
|
141345
|
+
stdout += text.slice(0, MAX_OUTPUT_BYTES2 - stdout.length);
|
|
141346
|
+
}
|
|
141347
|
+
} else {
|
|
141348
|
+
if (stderr.length < MAX_OUTPUT_BYTES2) {
|
|
141349
|
+
stderr += text.slice(0, MAX_OUTPUT_BYTES2 - stderr.length);
|
|
141350
|
+
}
|
|
141351
|
+
}
|
|
141352
|
+
};
|
|
141353
|
+
child.stdout?.on("data", (c) => append("stdout", c));
|
|
141354
|
+
child.stderr?.on("data", (c) => append("stderr", c));
|
|
141355
|
+
child.on("error", (err) => {
|
|
141356
|
+
clearTimeout(timer);
|
|
141357
|
+
resolve42({
|
|
141358
|
+
success: false,
|
|
141359
|
+
exitCode: null,
|
|
141360
|
+
stdout,
|
|
141361
|
+
stderr: stderr || err.message,
|
|
141362
|
+
command,
|
|
141363
|
+
durationMs: Date.now() - startedAt
|
|
141364
|
+
});
|
|
141365
|
+
});
|
|
141366
|
+
child.on("close", (exitCode) => {
|
|
141367
|
+
clearTimeout(timer);
|
|
141368
|
+
const combined = `${stdout}
|
|
141369
|
+
${stderr}`;
|
|
141370
|
+
const eaccesHit = /EACCES|permission denied|Operation not permitted/i.test(combined);
|
|
141371
|
+
const success = exitCode === 0 && !timedOut;
|
|
141372
|
+
resolve42({
|
|
141373
|
+
success,
|
|
141374
|
+
exitCode,
|
|
141375
|
+
stdout,
|
|
141376
|
+
stderr: timedOut ? `${stderr}
|
|
141377
|
+
[install timed out after ${INSTALL_TIMEOUT_MS / 1e3}s]` : stderr,
|
|
141378
|
+
command,
|
|
141379
|
+
durationMs: Date.now() - startedAt,
|
|
141380
|
+
permissionsHint: !success && eaccesHit ? "npm reported a permissions error. On macOS/Linux this usually means npm's global prefix needs `sudo` or a fix to your npm prefix (https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally)." : void 0
|
|
141381
|
+
});
|
|
141382
|
+
});
|
|
141383
|
+
});
|
|
141384
|
+
}
|
|
141385
|
+
var INSTALL_TIMEOUT_MS, MAX_OUTPUT_BYTES2, registerFnBinaryRoutes;
|
|
141386
|
+
var init_register_fn_binary_routes = __esm({
|
|
141387
|
+
"../dashboard/src/routes/register-fn-binary-routes.ts"() {
|
|
141388
|
+
"use strict";
|
|
141389
|
+
init_src();
|
|
141390
|
+
init_api_error();
|
|
141391
|
+
init_cli_package_version();
|
|
141392
|
+
INSTALL_TIMEOUT_MS = 18e4;
|
|
141393
|
+
MAX_OUTPUT_BYTES2 = 64 * 1024;
|
|
141394
|
+
registerFnBinaryRoutes = (ctx) => {
|
|
141395
|
+
const { router, rethrowAsApiError: rethrowAsApiError8 } = ctx;
|
|
141396
|
+
router.get("/system/fn-binary/status", async (_req, res) => {
|
|
141397
|
+
try {
|
|
141398
|
+
const binary = await detectFnBinary();
|
|
141399
|
+
const expectedVersion = getCliPackageVersion();
|
|
141400
|
+
res.json(buildStatusPayload(binary, expectedVersion));
|
|
141401
|
+
} catch (err) {
|
|
141402
|
+
if (err instanceof ApiError) throw err;
|
|
141403
|
+
rethrowAsApiError8(err);
|
|
141404
|
+
}
|
|
141405
|
+
});
|
|
141406
|
+
router.post("/system/fn-binary/install", async (_req, res) => {
|
|
141407
|
+
try {
|
|
141408
|
+
const installResult = await runNpmInstall();
|
|
141409
|
+
const binary = await detectFnBinary();
|
|
141410
|
+
const expectedVersion = getCliPackageVersion();
|
|
141411
|
+
const status = buildStatusPayload(binary, expectedVersion);
|
|
141412
|
+
res.json({ ...status, installResult });
|
|
141413
|
+
} catch (err) {
|
|
141414
|
+
if (err instanceof ApiError) throw err;
|
|
141415
|
+
rethrowAsApiError8(err);
|
|
141416
|
+
}
|
|
141417
|
+
});
|
|
141418
|
+
};
|
|
141419
|
+
}
|
|
141420
|
+
});
|
|
141421
|
+
|
|
140882
141422
|
// ../dashboard/src/update-check.ts
|
|
140883
|
-
import { readFileSync as
|
|
141423
|
+
import { readFileSync as readFileSync11 } from "node:fs";
|
|
140884
141424
|
import { mkdir as mkdir17, rm as rm5, writeFile as writeFile15 } from "node:fs/promises";
|
|
140885
141425
|
import { join as join47 } from "node:path";
|
|
140886
141426
|
function ttlForFrequency(frequency) {
|
|
@@ -140920,7 +141460,7 @@ function isValidResult(value) {
|
|
|
140920
141460
|
}
|
|
140921
141461
|
function readCachedUpdateCheck(fusionDir) {
|
|
140922
141462
|
try {
|
|
140923
|
-
const raw =
|
|
141463
|
+
const raw = readFileSync11(getCachePath(fusionDir), "utf-8");
|
|
140924
141464
|
const parsed = JSON.parse(raw);
|
|
140925
141465
|
return isValidResult(parsed) ? parsed : null;
|
|
140926
141466
|
} catch {
|
|
@@ -140987,65 +141527,6 @@ var init_update_check = __esm({
|
|
|
140987
141527
|
}
|
|
140988
141528
|
});
|
|
140989
141529
|
|
|
140990
|
-
// ../dashboard/src/cli-package-version.ts
|
|
140991
|
-
import { existsSync as existsSync32, readFileSync as readFileSync11 } from "node:fs";
|
|
140992
|
-
import { dirname as dirname15, resolve as resolve23 } from "node:path";
|
|
140993
|
-
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
140994
|
-
function readCliPackageVersion(pkgPath) {
|
|
140995
|
-
if (!existsSync32(pkgPath)) {
|
|
140996
|
-
return null;
|
|
140997
|
-
}
|
|
140998
|
-
try {
|
|
140999
|
-
const parsed = JSON.parse(readFileSync11(pkgPath, "utf-8"));
|
|
141000
|
-
if (parsed.name === CLI_PACKAGE_NAME && typeof parsed.version === "string" && parsed.version.length > 0) {
|
|
141001
|
-
return {
|
|
141002
|
-
packageJsonPath: pkgPath,
|
|
141003
|
-
version: parsed.version
|
|
141004
|
-
};
|
|
141005
|
-
}
|
|
141006
|
-
} catch {
|
|
141007
|
-
}
|
|
141008
|
-
return null;
|
|
141009
|
-
}
|
|
141010
|
-
function resolveCliPackageVersionInfo(startDir) {
|
|
141011
|
-
let currentDir = startDir;
|
|
141012
|
-
for (let i = 0; i < 8; i += 1) {
|
|
141013
|
-
const versionInfo = readCliPackageVersion(resolve23(currentDir, "package.json"));
|
|
141014
|
-
if (versionInfo) {
|
|
141015
|
-
return versionInfo;
|
|
141016
|
-
}
|
|
141017
|
-
const parentDir = resolve23(currentDir, "..");
|
|
141018
|
-
if (parentDir === currentDir) {
|
|
141019
|
-
break;
|
|
141020
|
-
}
|
|
141021
|
-
currentDir = parentDir;
|
|
141022
|
-
}
|
|
141023
|
-
currentDir = startDir;
|
|
141024
|
-
for (let i = 0; i < 8; i += 1) {
|
|
141025
|
-
const versionInfo = readCliPackageVersion(resolve23(currentDir, "..", "cli", "package.json"));
|
|
141026
|
-
if (versionInfo) {
|
|
141027
|
-
return versionInfo;
|
|
141028
|
-
}
|
|
141029
|
-
const parentDir = resolve23(currentDir, "..");
|
|
141030
|
-
if (parentDir === currentDir) {
|
|
141031
|
-
break;
|
|
141032
|
-
}
|
|
141033
|
-
currentDir = parentDir;
|
|
141034
|
-
}
|
|
141035
|
-
return null;
|
|
141036
|
-
}
|
|
141037
|
-
function getCliPackageVersion(importMetaUrl = import.meta.url) {
|
|
141038
|
-
const startDir = dirname15(fileURLToPath4(importMetaUrl));
|
|
141039
|
-
return resolveCliPackageVersionInfo(startDir)?.version ?? process.env.npm_package_version ?? "0.0.0";
|
|
141040
|
-
}
|
|
141041
|
-
var CLI_PACKAGE_NAME;
|
|
141042
|
-
var init_cli_package_version = __esm({
|
|
141043
|
-
"../dashboard/src/cli-package-version.ts"() {
|
|
141044
|
-
"use strict";
|
|
141045
|
-
CLI_PACKAGE_NAME = "@runfusion/fusion";
|
|
141046
|
-
}
|
|
141047
|
-
});
|
|
141048
|
-
|
|
141049
141530
|
// ../dashboard/src/routes/register-update-check-routes.ts
|
|
141050
141531
|
var registerUpdateCheckRoutes;
|
|
141051
141532
|
var init_register_update_check_routes = __esm({
|
|
@@ -145824,7 +146305,7 @@ function detectPortFromLogLine(line) {
|
|
|
145824
146305
|
return detectViteLine(cleanLine) ?? detectNextLine(cleanLine) ?? detectStorybookLine(cleanLine) ?? detectAngularLine(cleanLine) ?? detectGenericUrl(cleanLine) ?? detectGenericPortLine(cleanLine);
|
|
145825
146306
|
}
|
|
145826
146307
|
function probePort(host, port, timeoutMs) {
|
|
145827
|
-
return new Promise((
|
|
146308
|
+
return new Promise((resolve42) => {
|
|
145828
146309
|
let settled = false;
|
|
145829
146310
|
const socket = createConnection({ host, port });
|
|
145830
146311
|
const settle = (isOpen) => {
|
|
@@ -145838,7 +146319,7 @@ function probePort(host, port, timeoutMs) {
|
|
|
145838
146319
|
} else {
|
|
145839
146320
|
socket.destroy();
|
|
145840
146321
|
}
|
|
145841
|
-
|
|
146322
|
+
resolve42(isOpen);
|
|
145842
146323
|
};
|
|
145843
146324
|
socket.setTimeout(timeoutMs);
|
|
145844
146325
|
socket.once("connect", () => settle(true));
|
|
@@ -145879,7 +146360,7 @@ var init_dev_server_port_detect = __esm({
|
|
|
145879
146360
|
|
|
145880
146361
|
// ../dashboard/src/dev-server-process.ts
|
|
145881
146362
|
import { EventEmitter as EventEmitter34 } from "node:events";
|
|
145882
|
-
import { spawn as
|
|
146363
|
+
import { spawn as spawn14 } from "node:child_process";
|
|
145883
146364
|
function killManagedProcess2(child, signal) {
|
|
145884
146365
|
if (typeof child.pid !== "number") {
|
|
145885
146366
|
return;
|
|
@@ -145958,15 +146439,15 @@ var init_dev_server_process = __esm({
|
|
|
145958
146439
|
detectedUrl: void 0,
|
|
145959
146440
|
detectedPort: void 0
|
|
145960
146441
|
});
|
|
145961
|
-
const child =
|
|
146442
|
+
const child = spawn14(safeCommand, [], {
|
|
145962
146443
|
cwd: safeCwd,
|
|
145963
146444
|
detached: process.platform !== "win32",
|
|
145964
146445
|
shell: true,
|
|
145965
146446
|
stdio: ["pipe", "pipe", "pipe"]
|
|
145966
146447
|
});
|
|
145967
146448
|
this.childProcess = child;
|
|
145968
|
-
this.closePromise = new Promise((
|
|
145969
|
-
this.resolveClosePromise =
|
|
146449
|
+
this.closePromise = new Promise((resolve42) => {
|
|
146450
|
+
this.resolveClosePromise = resolve42;
|
|
145970
146451
|
});
|
|
145971
146452
|
const runningState = await this.store.updateState({
|
|
145972
146453
|
pid: child.pid,
|
|
@@ -147592,6 +148073,7 @@ function createApiRoutes(store, options) {
|
|
|
147592
148073
|
registerCustomProviderRoutes(routeContext);
|
|
147593
148074
|
registerAuthRoutes(routeContext);
|
|
147594
148075
|
registerRuntimeProviderRoutes(routeContext);
|
|
148076
|
+
registerFnBinaryRoutes(routeContext);
|
|
147595
148077
|
router.post("/ai/refine-text", async (req, res) => {
|
|
147596
148078
|
try {
|
|
147597
148079
|
const { text, type } = req.body;
|
|
@@ -149182,15 +149664,15 @@ Description: ${step.description}`
|
|
|
149182
149664
|
return;
|
|
149183
149665
|
}
|
|
149184
149666
|
}
|
|
149185
|
-
const { resolve:
|
|
149667
|
+
const { resolve: resolve42, dirname: dirname30, join: join70 } = await import("node:path");
|
|
149186
149668
|
const { readdir: readdir12, stat: stat12 } = await import("node:fs/promises");
|
|
149187
149669
|
const rawPath = req.query.path || process.env.HOME || process.env.USERPROFILE || "/";
|
|
149188
149670
|
const showHidden = req.query.showHidden === "true";
|
|
149189
|
-
const resolvedPath =
|
|
149671
|
+
const resolvedPath = resolve42(rawPath);
|
|
149190
149672
|
if (rawPath.includes("..")) {
|
|
149191
149673
|
throw badRequest("Path must not contain '..' traversal");
|
|
149192
149674
|
}
|
|
149193
|
-
if (resolvedPath !==
|
|
149675
|
+
if (resolvedPath !== resolve42(resolvedPath)) {
|
|
149194
149676
|
throw badRequest("Path must be absolute");
|
|
149195
149677
|
}
|
|
149196
149678
|
let pathStat;
|
|
@@ -149217,7 +149699,7 @@ Description: ${step.description}`
|
|
|
149217
149699
|
entries.push({ name: entry.name, path: entryPath, hasChildren });
|
|
149218
149700
|
}
|
|
149219
149701
|
entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
149220
|
-
const parentPath =
|
|
149702
|
+
const parentPath = dirname30(resolvedPath) === resolvedPath ? null : dirname30(resolvedPath);
|
|
149221
149703
|
res.json({ currentPath: resolvedPath, parentPath, entries });
|
|
149222
149704
|
} catch (err) {
|
|
149223
149705
|
if (err instanceof ApiError) {
|
|
@@ -149727,6 +150209,7 @@ var init_routes = __esm({
|
|
|
149727
150209
|
init_register_usage_routes();
|
|
149728
150210
|
init_register_auth_routes();
|
|
149729
150211
|
init_register_runtime_provider_routes();
|
|
150212
|
+
init_register_fn_binary_routes();
|
|
149730
150213
|
init_register_update_check_routes();
|
|
149731
150214
|
init_register_integrated_routers();
|
|
149732
150215
|
init_resolve_diff_base();
|
|
@@ -156484,7 +156967,7 @@ var init_task_lifecycle = __esm({
|
|
|
156484
156967
|
// src/commands/port-prompt.ts
|
|
156485
156968
|
import { createInterface } from "node:readline";
|
|
156486
156969
|
function promptForPort(defaultPort = 4040, input = process.stdin) {
|
|
156487
|
-
return new Promise((
|
|
156970
|
+
return new Promise((resolve42, reject2) => {
|
|
156488
156971
|
const rl = createInterface({
|
|
156489
156972
|
input,
|
|
156490
156973
|
output: process.stdout
|
|
@@ -156501,7 +156984,7 @@ function promptForPort(defaultPort = 4040, input = process.stdin) {
|
|
|
156501
156984
|
if (trimmed === "") {
|
|
156502
156985
|
process.removeListener("SIGINT", sigintHandler);
|
|
156503
156986
|
rl.close();
|
|
156504
|
-
|
|
156987
|
+
resolve42(defaultPort);
|
|
156505
156988
|
return;
|
|
156506
156989
|
}
|
|
156507
156990
|
const port = parseInt(trimmed, 10);
|
|
@@ -156517,7 +157000,7 @@ function promptForPort(defaultPort = 4040, input = process.stdin) {
|
|
|
156517
157000
|
}
|
|
156518
157001
|
process.removeListener("SIGINT", sigintHandler);
|
|
156519
157002
|
rl.close();
|
|
156520
|
-
|
|
157003
|
+
resolve42(port);
|
|
156521
157004
|
});
|
|
156522
157005
|
};
|
|
156523
157006
|
ask();
|
|
@@ -157268,13 +157751,109 @@ var init_claude_cli_extension = __esm({
|
|
|
157268
157751
|
}
|
|
157269
157752
|
});
|
|
157270
157753
|
|
|
157754
|
+
// src/commands/droid-cli-extension.ts
|
|
157755
|
+
import { existsSync as existsSync40, readFileSync as readFileSync18 } from "node:fs";
|
|
157756
|
+
import { createRequire as createRequire5 } from "node:module";
|
|
157757
|
+
import { dirname as dirname24, resolve as resolve30 } from "node:path";
|
|
157758
|
+
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
157759
|
+
function resolveDroidCliExtensionFromModuleUrl(moduleUrl) {
|
|
157760
|
+
let pkgJsonPath;
|
|
157761
|
+
const here = dirname24(fileURLToPath8(moduleUrl));
|
|
157762
|
+
for (const rel of ["droid-cli", "../droid-cli", "../../droid-cli"]) {
|
|
157763
|
+
const candidate = resolve30(here, rel, "package.json");
|
|
157764
|
+
if (existsSync40(candidate)) {
|
|
157765
|
+
pkgJsonPath = candidate;
|
|
157766
|
+
break;
|
|
157767
|
+
}
|
|
157768
|
+
}
|
|
157769
|
+
if (!pkgJsonPath) {
|
|
157770
|
+
try {
|
|
157771
|
+
pkgJsonPath = require_2.resolve("@fusion/droid-cli/package.json");
|
|
157772
|
+
} catch {
|
|
157773
|
+
return { status: "not-installed" };
|
|
157774
|
+
}
|
|
157775
|
+
}
|
|
157776
|
+
let pkgJson;
|
|
157777
|
+
try {
|
|
157778
|
+
pkgJson = JSON.parse(readFileSync18(pkgJsonPath, "utf-8"));
|
|
157779
|
+
} catch (err) {
|
|
157780
|
+
return {
|
|
157781
|
+
status: "error",
|
|
157782
|
+
reason: `Failed to read @fusion/droid-cli package.json: ${err instanceof Error ? err.message : String(err)}`
|
|
157783
|
+
};
|
|
157784
|
+
}
|
|
157785
|
+
const extensions = pkgJson.pi?.extensions;
|
|
157786
|
+
if (!Array.isArray(extensions) || extensions.length === 0) {
|
|
157787
|
+
return {
|
|
157788
|
+
status: "missing-entry",
|
|
157789
|
+
reason: "@fusion/droid-cli package.json has no pi.extensions array"
|
|
157790
|
+
};
|
|
157791
|
+
}
|
|
157792
|
+
const rawEntry = extensions[0];
|
|
157793
|
+
if (typeof rawEntry !== "string" || rawEntry.length === 0) {
|
|
157794
|
+
return {
|
|
157795
|
+
status: "missing-entry",
|
|
157796
|
+
reason: "@fusion/droid-cli pi.extensions[0] is not a valid path string"
|
|
157797
|
+
};
|
|
157798
|
+
}
|
|
157799
|
+
const entryPath = resolve30(dirname24(pkgJsonPath), rawEntry);
|
|
157800
|
+
if (!existsSync40(entryPath)) {
|
|
157801
|
+
return {
|
|
157802
|
+
status: "missing-entry",
|
|
157803
|
+
reason: `@fusion/droid-cli extension file not found at ${entryPath}`
|
|
157804
|
+
};
|
|
157805
|
+
}
|
|
157806
|
+
return {
|
|
157807
|
+
status: "ok",
|
|
157808
|
+
path: entryPath,
|
|
157809
|
+
packageVersion: pkgJson.version ?? "unknown"
|
|
157810
|
+
};
|
|
157811
|
+
}
|
|
157812
|
+
function resolveDroidCliExtension() {
|
|
157813
|
+
return resolveDroidCliExtensionFromModuleUrl(import.meta.url);
|
|
157814
|
+
}
|
|
157815
|
+
function resolveDroidCliExtensionPaths(globalSettings) {
|
|
157816
|
+
const enabled = globalSettings?.useDroidCli === true;
|
|
157817
|
+
if (!enabled) {
|
|
157818
|
+
return { paths: [], resolution: null };
|
|
157819
|
+
}
|
|
157820
|
+
const resolution = resolveDroidCliExtension();
|
|
157821
|
+
switch (resolution.status) {
|
|
157822
|
+
case "ok":
|
|
157823
|
+
return { paths: [resolution.path], resolution };
|
|
157824
|
+
case "not-installed":
|
|
157825
|
+
return {
|
|
157826
|
+
paths: [],
|
|
157827
|
+
resolution,
|
|
157828
|
+
warning: "useDroidCli is on but @fusion/droid-cli is not installed in node_modules. Run `pnpm install`."
|
|
157829
|
+
};
|
|
157830
|
+
case "missing-entry":
|
|
157831
|
+
case "error":
|
|
157832
|
+
return { paths: [], resolution, warning: resolution.reason };
|
|
157833
|
+
}
|
|
157834
|
+
}
|
|
157835
|
+
function setCachedDroidCliResolution(resolution) {
|
|
157836
|
+
cachedResolution2 = resolution;
|
|
157837
|
+
}
|
|
157838
|
+
function getCachedDroidCliResolution() {
|
|
157839
|
+
return cachedResolution2;
|
|
157840
|
+
}
|
|
157841
|
+
var require_2, cachedResolution2;
|
|
157842
|
+
var init_droid_cli_extension = __esm({
|
|
157843
|
+
"src/commands/droid-cli-extension.ts"() {
|
|
157844
|
+
"use strict";
|
|
157845
|
+
require_2 = createRequire5(import.meta.url);
|
|
157846
|
+
cachedResolution2 = null;
|
|
157847
|
+
}
|
|
157848
|
+
});
|
|
157849
|
+
|
|
157271
157850
|
// src/update-cache.ts
|
|
157272
|
-
import { readFileSync as
|
|
157851
|
+
import { readFileSync as readFileSync19 } from "node:fs";
|
|
157273
157852
|
import { join as join56 } from "node:path";
|
|
157274
157853
|
function getCachedUpdateStatus(currentVersion) {
|
|
157275
157854
|
try {
|
|
157276
157855
|
const cachePath = join56(resolveGlobalDir(), "update-check.json");
|
|
157277
|
-
const raw =
|
|
157856
|
+
const raw = readFileSync19(cachePath, "utf-8");
|
|
157278
157857
|
const parsed = JSON.parse(raw);
|
|
157279
157858
|
if (parsed.updateAvailable === true && typeof parsed.latestVersion === "string" && parsed.latestVersion.length > 0 && typeof parsed.currentVersion === "string" && parsed.currentVersion.length > 0) {
|
|
157280
157859
|
if (typeof currentVersion === "string" && currentVersion.length > 0 && parsed.currentVersion !== currentVersion) {
|
|
@@ -157305,17 +157884,17 @@ var init_update_cache = __esm({
|
|
|
157305
157884
|
});
|
|
157306
157885
|
|
|
157307
157886
|
// src/commands/self-extension.ts
|
|
157308
|
-
import { existsSync as
|
|
157309
|
-
import { dirname as
|
|
157310
|
-
import { fileURLToPath as
|
|
157887
|
+
import { existsSync as existsSync41, readFileSync as readFileSync20 } from "node:fs";
|
|
157888
|
+
import { dirname as dirname25, resolve as resolve31 } from "node:path";
|
|
157889
|
+
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
157311
157890
|
function resolveSelfExtension() {
|
|
157312
|
-
const here =
|
|
157891
|
+
const here = dirname25(fileURLToPath9(import.meta.url));
|
|
157313
157892
|
let pkgDir;
|
|
157314
157893
|
let cur = here;
|
|
157315
157894
|
for (let i = 0; i < 5; i++) {
|
|
157316
|
-
if (
|
|
157895
|
+
if (existsSync41(resolve31(cur, "package.json"))) {
|
|
157317
157896
|
try {
|
|
157318
|
-
const parsed = JSON.parse(
|
|
157897
|
+
const parsed = JSON.parse(readFileSync20(resolve31(cur, "package.json"), "utf-8"));
|
|
157319
157898
|
if (parsed.name === "@runfusion/fusion") {
|
|
157320
157899
|
pkgDir = cur;
|
|
157321
157900
|
break;
|
|
@@ -157323,7 +157902,7 @@ function resolveSelfExtension() {
|
|
|
157323
157902
|
} catch {
|
|
157324
157903
|
}
|
|
157325
157904
|
}
|
|
157326
|
-
const parent2 =
|
|
157905
|
+
const parent2 = resolve31(cur, "..");
|
|
157327
157906
|
if (parent2 === cur) break;
|
|
157328
157907
|
cur = parent2;
|
|
157329
157908
|
}
|
|
@@ -157332,12 +157911,12 @@ function resolveSelfExtension() {
|
|
|
157332
157911
|
}
|
|
157333
157912
|
let pkgJson;
|
|
157334
157913
|
try {
|
|
157335
|
-
pkgJson = JSON.parse(
|
|
157914
|
+
pkgJson = JSON.parse(readFileSync20(resolve31(pkgDir, "package.json"), "utf-8"));
|
|
157336
157915
|
} catch (err) {
|
|
157337
157916
|
return { status: "missing", reason: `Failed to read @runfusion/fusion package.json: ${err instanceof Error ? err.message : String(err)}` };
|
|
157338
157917
|
}
|
|
157339
|
-
const srcEntry =
|
|
157340
|
-
if (
|
|
157918
|
+
const srcEntry = resolve31(pkgDir, "src", "extension.ts");
|
|
157919
|
+
if (existsSync41(srcEntry)) {
|
|
157341
157920
|
return { status: "ok", path: srcEntry, packageVersion: pkgJson.version ?? "unknown" };
|
|
157342
157921
|
}
|
|
157343
157922
|
const extensions = pkgJson.pi?.extensions;
|
|
@@ -157348,8 +157927,8 @@ function resolveSelfExtension() {
|
|
|
157348
157927
|
if (typeof rawEntry !== "string" || rawEntry.length === 0) {
|
|
157349
157928
|
return { status: "missing", reason: "@runfusion/fusion pi.extensions[0] is not a valid path string" };
|
|
157350
157929
|
}
|
|
157351
|
-
const entryPath =
|
|
157352
|
-
if (!
|
|
157930
|
+
const entryPath = resolve31(pkgDir, rawEntry);
|
|
157931
|
+
if (!existsSync41(entryPath)) {
|
|
157353
157932
|
return { status: "missing", reason: `@runfusion/fusion extension file not found at ${entryPath}` };
|
|
157354
157933
|
}
|
|
157355
157934
|
return { status: "ok", path: entryPath, packageVersion: pkgJson.version ?? "unknown" };
|
|
@@ -157561,7 +158140,7 @@ var init_use_projects = __esm({
|
|
|
157561
158140
|
});
|
|
157562
158141
|
|
|
157563
158142
|
// src/commands/dashboard-tui/utils.ts
|
|
157564
|
-
import { spawn as
|
|
158143
|
+
import { spawn as spawn15 } from "node:child_process";
|
|
157565
158144
|
function isTTYAvailable() {
|
|
157566
158145
|
return Boolean(process.stdout.isTTY && process.stdin.isTTY);
|
|
157567
158146
|
}
|
|
@@ -157572,14 +158151,14 @@ async function copyToClipboard(text) {
|
|
|
157572
158151
|
{ cmd: "xsel", args: ["--clipboard", "--input"] }
|
|
157573
158152
|
];
|
|
157574
158153
|
for (const { cmd, args } of candidates) {
|
|
157575
|
-
const ok = await new Promise((
|
|
158154
|
+
const ok = await new Promise((resolve42) => {
|
|
157576
158155
|
try {
|
|
157577
|
-
const child =
|
|
157578
|
-
child.once("error", () =>
|
|
157579
|
-
child.once("close", (code) =>
|
|
158156
|
+
const child = spawn15(cmd, args, { stdio: ["pipe", "ignore", "ignore"] });
|
|
158157
|
+
child.once("error", () => resolve42(false));
|
|
158158
|
+
child.once("close", (code) => resolve42(code === 0));
|
|
157580
158159
|
child.stdin.end(text);
|
|
157581
158160
|
} catch {
|
|
157582
|
-
|
|
158161
|
+
resolve42(false);
|
|
157583
158162
|
}
|
|
157584
158163
|
});
|
|
157585
158164
|
if (ok) return true;
|
|
@@ -157601,7 +158180,7 @@ import { useState as useState2, useSyncExternalStore, useCallback as useCallback
|
|
|
157601
158180
|
import { Box, Text, useInput, useApp, useStdout } from "ink";
|
|
157602
158181
|
import Spinner from "ink-spinner";
|
|
157603
158182
|
import TextInput from "ink-text-input";
|
|
157604
|
-
import { spawn as
|
|
158183
|
+
import { spawn as spawn16 } from "node:child_process";
|
|
157605
158184
|
import { appendFileSync } from "node:fs";
|
|
157606
158185
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
157607
158186
|
function tuiDebug(tag, data) {
|
|
@@ -157627,7 +158206,7 @@ function openInBrowser(url) {
|
|
|
157627
158206
|
args = [url];
|
|
157628
158207
|
}
|
|
157629
158208
|
try {
|
|
157630
|
-
const child =
|
|
158209
|
+
const child = spawn16(cmd, args, { detached: true, stdio: "ignore" });
|
|
157631
158210
|
child.unref();
|
|
157632
158211
|
} catch {
|
|
157633
158212
|
}
|
|
@@ -161640,8 +162219,8 @@ async function resolveCachedStartupUpdateStatus(importMetaUrl) {
|
|
|
161640
162219
|
try {
|
|
161641
162220
|
const updateCheckEnabled = await Promise.race([
|
|
161642
162221
|
isUpdateCheckEnabled(),
|
|
161643
|
-
new Promise((
|
|
161644
|
-
setTimeout(() =>
|
|
162222
|
+
new Promise((resolve42) => {
|
|
162223
|
+
setTimeout(() => resolve42(false), 3e3);
|
|
161645
162224
|
})
|
|
161646
162225
|
]);
|
|
161647
162226
|
if (!updateCheckEnabled) {
|
|
@@ -162361,6 +162940,23 @@ async function runDashboard(port, opts = {}) {
|
|
|
162361
162940
|
return [];
|
|
162362
162941
|
}
|
|
162363
162942
|
})();
|
|
162943
|
+
const droidCliPaths = await (async () => {
|
|
162944
|
+
try {
|
|
162945
|
+
const globalSettings = await store.getGlobalSettingsStore().getSettings();
|
|
162946
|
+
const result = resolveDroidCliExtensionPaths(globalSettings);
|
|
162947
|
+
setCachedDroidCliResolution(result.resolution);
|
|
162948
|
+
if (result.warning) {
|
|
162949
|
+
console.warn(`[extensions] droid-cli: ${result.warning}`);
|
|
162950
|
+
}
|
|
162951
|
+
return result.paths;
|
|
162952
|
+
} catch (err) {
|
|
162953
|
+
console.warn(
|
|
162954
|
+
`[extensions] Unable to evaluate useDroidCli setting: ${err instanceof Error ? err.message : String(err)}`
|
|
162955
|
+
);
|
|
162956
|
+
setCachedDroidCliResolution(null);
|
|
162957
|
+
return [];
|
|
162958
|
+
}
|
|
162959
|
+
})();
|
|
162364
162960
|
const selfExtension = resolveSelfExtension();
|
|
162365
162961
|
const selfExtensionPaths = selfExtension.status === "ok" ? [selfExtension.path] : [];
|
|
162366
162962
|
if (selfExtension.status !== "ok") {
|
|
@@ -162372,7 +162968,8 @@ async function runDashboard(port, opts = {}) {
|
|
|
162372
162968
|
...selfExtensionPaths,
|
|
162373
162969
|
...getEnabledPiExtensionPaths(cwd),
|
|
162374
162970
|
...packageExtensionPaths,
|
|
162375
|
-
...claudeCliPaths
|
|
162971
|
+
...claudeCliPaths,
|
|
162972
|
+
...droidCliPaths
|
|
162376
162973
|
],
|
|
162377
162974
|
cwd,
|
|
162378
162975
|
join57(cwd, ".fusion", "disabled-auto-extension-discovery")
|
|
@@ -162569,6 +163166,17 @@ async function runDashboard(port, opts = {}) {
|
|
|
162569
163166
|
}
|
|
162570
163167
|
return { status: r.status, reason: r.reason };
|
|
162571
163168
|
},
|
|
163169
|
+
getDroidCliExtensionStatus: () => {
|
|
163170
|
+
const r = getCachedDroidCliResolution();
|
|
163171
|
+
if (!r) return null;
|
|
163172
|
+
if (r.status === "ok") {
|
|
163173
|
+
return { status: "ok", path: r.path, packageVersion: r.packageVersion };
|
|
163174
|
+
}
|
|
163175
|
+
if (r.status === "not-installed") {
|
|
163176
|
+
return { status: "not-installed" };
|
|
163177
|
+
}
|
|
163178
|
+
return { status: r.status, reason: r.reason };
|
|
163179
|
+
},
|
|
162572
163180
|
onUseClaudeCliToggled: (_prev, next) => {
|
|
162573
163181
|
if (!next) return;
|
|
162574
163182
|
void (async () => {
|
|
@@ -162586,6 +163194,11 @@ async function runDashboard(port, opts = {}) {
|
|
|
162586
163194
|
}
|
|
162587
163195
|
})();
|
|
162588
163196
|
},
|
|
163197
|
+
onUseDroidCliToggled: (_prev, next) => {
|
|
163198
|
+
if (next) {
|
|
163199
|
+
logSink.log("Droid CLI enabled \u2014 restart required for full effect", "extensions");
|
|
163200
|
+
}
|
|
163201
|
+
},
|
|
162589
163202
|
skillsAdapter,
|
|
162590
163203
|
https: loadTlsCredentialsFromEnv(),
|
|
162591
163204
|
daemon: dashboardAuthToken ? { token: dashboardAuthToken } : void 0,
|
|
@@ -162752,6 +163365,17 @@ async function runDashboard(port, opts = {}) {
|
|
|
162752
163365
|
}
|
|
162753
163366
|
return { status: r.status, reason: r.reason };
|
|
162754
163367
|
},
|
|
163368
|
+
getDroidCliExtensionStatus: () => {
|
|
163369
|
+
const r = getCachedDroidCliResolution();
|
|
163370
|
+
if (!r) return null;
|
|
163371
|
+
if (r.status === "ok") {
|
|
163372
|
+
return { status: "ok", path: r.path, packageVersion: r.packageVersion };
|
|
163373
|
+
}
|
|
163374
|
+
if (r.status === "not-installed") {
|
|
163375
|
+
return { status: "not-installed" };
|
|
163376
|
+
}
|
|
163377
|
+
return { status: r.status, reason: r.reason };
|
|
163378
|
+
},
|
|
162755
163379
|
onUseClaudeCliToggled: (_prev, next) => {
|
|
162756
163380
|
if (!next) return;
|
|
162757
163381
|
void (async () => {
|
|
@@ -162769,6 +163393,11 @@ async function runDashboard(port, opts = {}) {
|
|
|
162769
163393
|
}
|
|
162770
163394
|
})();
|
|
162771
163395
|
},
|
|
163396
|
+
onUseDroidCliToggled: (_prev, next) => {
|
|
163397
|
+
if (next) {
|
|
163398
|
+
logSink.log("Droid CLI enabled \u2014 restart required for full effect", "extensions");
|
|
163399
|
+
}
|
|
163400
|
+
},
|
|
162772
163401
|
skillsAdapter,
|
|
162773
163402
|
https: loadTlsCredentialsFromEnv(),
|
|
162774
163403
|
daemon: dashboardAuthToken ? { token: dashboardAuthToken } : void 0,
|
|
@@ -163345,6 +163974,7 @@ var init_dashboard = __esm({
|
|
|
163345
163974
|
init_project_context();
|
|
163346
163975
|
init_claude_skills_runner();
|
|
163347
163976
|
init_claude_cli_extension();
|
|
163977
|
+
init_droid_cli_extension();
|
|
163348
163978
|
init_update_cache();
|
|
163349
163979
|
init_self_extension();
|
|
163350
163980
|
init_custom_provider_registry();
|
|
@@ -164122,6 +164752,23 @@ async function runServe(port, opts = {}) {
|
|
|
164122
164752
|
return [];
|
|
164123
164753
|
}
|
|
164124
164754
|
})();
|
|
164755
|
+
const droidCliPaths = await (async () => {
|
|
164756
|
+
try {
|
|
164757
|
+
const globalSettings = await store.getGlobalSettingsStore().getSettings();
|
|
164758
|
+
const result = resolveDroidCliExtensionPaths(globalSettings);
|
|
164759
|
+
setCachedDroidCliResolution(result.resolution);
|
|
164760
|
+
if (result.warning) {
|
|
164761
|
+
console.warn(`[extensions] droid-cli: ${result.warning}`);
|
|
164762
|
+
}
|
|
164763
|
+
return result.paths;
|
|
164764
|
+
} catch (err) {
|
|
164765
|
+
console.warn(
|
|
164766
|
+
`[extensions] Unable to evaluate useDroidCli setting: ${err instanceof Error ? err.message : String(err)}`
|
|
164767
|
+
);
|
|
164768
|
+
setCachedDroidCliResolution(null);
|
|
164769
|
+
return [];
|
|
164770
|
+
}
|
|
164771
|
+
})();
|
|
164125
164772
|
const selfExtension = resolveSelfExtension();
|
|
164126
164773
|
const selfExtensionPaths = selfExtension.status === "ok" ? [selfExtension.path] : [];
|
|
164127
164774
|
if (selfExtension.status !== "ok") {
|
|
@@ -164133,7 +164780,8 @@ async function runServe(port, opts = {}) {
|
|
|
164133
164780
|
...selfExtensionPaths,
|
|
164134
164781
|
...getEnabledPiExtensionPaths(cwd),
|
|
164135
164782
|
...packageExtensionPaths,
|
|
164136
|
-
...claudeCliPaths
|
|
164783
|
+
...claudeCliPaths,
|
|
164784
|
+
...droidCliPaths
|
|
164137
164785
|
],
|
|
164138
164786
|
cwd,
|
|
164139
164787
|
join58(cwd, ".fusion", "disabled-auto-extension-discovery")
|
|
@@ -164292,6 +164940,17 @@ async function runServe(port, opts = {}) {
|
|
|
164292
164940
|
}
|
|
164293
164941
|
return { status: r.status, reason: r.reason };
|
|
164294
164942
|
},
|
|
164943
|
+
getDroidCliExtensionStatus: () => {
|
|
164944
|
+
const r = getCachedDroidCliResolution();
|
|
164945
|
+
if (!r) return null;
|
|
164946
|
+
if (r.status === "ok") {
|
|
164947
|
+
return { status: "ok", path: r.path, packageVersion: r.packageVersion };
|
|
164948
|
+
}
|
|
164949
|
+
if (r.status === "not-installed") {
|
|
164950
|
+
return { status: "not-installed" };
|
|
164951
|
+
}
|
|
164952
|
+
return { status: r.status, reason: r.reason };
|
|
164953
|
+
},
|
|
164295
164954
|
onUseClaudeCliToggled: (_prev, next) => {
|
|
164296
164955
|
if (!next) return;
|
|
164297
164956
|
void (async () => {
|
|
@@ -164308,14 +164967,19 @@ async function runServe(port, opts = {}) {
|
|
|
164308
164967
|
}
|
|
164309
164968
|
})();
|
|
164310
164969
|
},
|
|
164970
|
+
onUseDroidCliToggled: (_prev, next) => {
|
|
164971
|
+
if (next) {
|
|
164972
|
+
console.log("[extensions] Droid CLI enabled \u2014 restart required for full effect");
|
|
164973
|
+
}
|
|
164974
|
+
},
|
|
164311
164975
|
headless: true,
|
|
164312
164976
|
skillsAdapter,
|
|
164313
164977
|
daemon: daemonToken ? { token: daemonToken } : void 0,
|
|
164314
164978
|
https: loadTlsCredentialsFromEnv()
|
|
164315
164979
|
});
|
|
164316
164980
|
const server = app.listen(selectedPort, selectedHost);
|
|
164317
|
-
await new Promise((
|
|
164318
|
-
server.once("listening",
|
|
164981
|
+
await new Promise((resolve42, reject2) => {
|
|
164982
|
+
server.once("listening", resolve42);
|
|
164319
164983
|
server.once("error", reject2);
|
|
164320
164984
|
});
|
|
164321
164985
|
const actualPort = server.address().port;
|
|
@@ -164459,6 +165123,7 @@ var init_serve = __esm({
|
|
|
164459
165123
|
init_project_context();
|
|
164460
165124
|
init_claude_skills_runner();
|
|
164461
165125
|
init_claude_cli_extension();
|
|
165126
|
+
init_droid_cli_extension();
|
|
164462
165127
|
init_self_extension();
|
|
164463
165128
|
init_custom_provider_registry();
|
|
164464
165129
|
DIAGNOSTIC_INTERVAL_MS2 = 30 * 60 * 1e3;
|
|
@@ -164730,6 +165395,23 @@ async function runDaemon(opts = {}) {
|
|
|
164730
165395
|
return [];
|
|
164731
165396
|
}
|
|
164732
165397
|
})();
|
|
165398
|
+
const droidCliPaths = await (async () => {
|
|
165399
|
+
try {
|
|
165400
|
+
const globalSettings = await store.getGlobalSettingsStore().getSettings();
|
|
165401
|
+
const result = resolveDroidCliExtensionPaths(globalSettings);
|
|
165402
|
+
setCachedDroidCliResolution(result.resolution);
|
|
165403
|
+
if (result.warning) {
|
|
165404
|
+
console.warn(`[extensions] droid-cli: ${result.warning}`);
|
|
165405
|
+
}
|
|
165406
|
+
return result.paths;
|
|
165407
|
+
} catch (err) {
|
|
165408
|
+
console.warn(
|
|
165409
|
+
`[extensions] Unable to evaluate useDroidCli setting: ${err instanceof Error ? err.message : String(err)}`
|
|
165410
|
+
);
|
|
165411
|
+
setCachedDroidCliResolution(null);
|
|
165412
|
+
return [];
|
|
165413
|
+
}
|
|
165414
|
+
})();
|
|
164733
165415
|
const selfExtension = resolveSelfExtension();
|
|
164734
165416
|
const selfExtensionPaths = selfExtension.status === "ok" ? [selfExtension.path] : [];
|
|
164735
165417
|
if (selfExtension.status !== "ok") {
|
|
@@ -164741,7 +165423,7 @@ async function runDaemon(opts = {}) {
|
|
|
164741
165423
|
claudeCliPaths[0] ?? null
|
|
164742
165424
|
);
|
|
164743
165425
|
const extensionsResult = await discoverAndLoadExtensions4(
|
|
164744
|
-
reconciledExtensionPaths,
|
|
165426
|
+
[...reconciledExtensionPaths, ...droidCliPaths],
|
|
164745
165427
|
cwd,
|
|
164746
165428
|
join59(cwd, ".fusion", "disabled-auto-extension-discovery")
|
|
164747
165429
|
);
|
|
@@ -164812,6 +165494,17 @@ async function runDaemon(opts = {}) {
|
|
|
164812
165494
|
}
|
|
164813
165495
|
return { status: r.status, reason: r.reason };
|
|
164814
165496
|
},
|
|
165497
|
+
getDroidCliExtensionStatus: () => {
|
|
165498
|
+
const r = getCachedDroidCliResolution();
|
|
165499
|
+
if (!r) return null;
|
|
165500
|
+
if (r.status === "ok") {
|
|
165501
|
+
return { status: "ok", path: r.path, packageVersion: r.packageVersion };
|
|
165502
|
+
}
|
|
165503
|
+
if (r.status === "not-installed") {
|
|
165504
|
+
return { status: "not-installed" };
|
|
165505
|
+
}
|
|
165506
|
+
return { status: r.status, reason: r.reason };
|
|
165507
|
+
},
|
|
164815
165508
|
onUseClaudeCliToggled: (_prev, next) => {
|
|
164816
165509
|
if (!next) return;
|
|
164817
165510
|
void (async () => {
|
|
@@ -164828,14 +165521,19 @@ async function runDaemon(opts = {}) {
|
|
|
164828
165521
|
}
|
|
164829
165522
|
})();
|
|
164830
165523
|
},
|
|
165524
|
+
onUseDroidCliToggled: (_prev, next) => {
|
|
165525
|
+
if (next) {
|
|
165526
|
+
console.log("[extensions] Droid CLI enabled \u2014 restart required for full effect");
|
|
165527
|
+
}
|
|
165528
|
+
},
|
|
164831
165529
|
headless: true,
|
|
164832
165530
|
daemon: { token: daemonToken },
|
|
164833
165531
|
skillsAdapter,
|
|
164834
165532
|
https: loadTlsCredentialsFromEnv()
|
|
164835
165533
|
});
|
|
164836
165534
|
const server = app.listen(selectedPort, selectedHost);
|
|
164837
|
-
await new Promise((
|
|
164838
|
-
server.once("listening",
|
|
165535
|
+
await new Promise((resolve42, reject2) => {
|
|
165536
|
+
server.once("listening", resolve42);
|
|
164839
165537
|
server.once("error", reject2);
|
|
164840
165538
|
});
|
|
164841
165539
|
const actualPort = server.address().port;
|
|
@@ -164929,6 +165627,7 @@ var init_daemon = __esm({
|
|
|
164929
165627
|
init_provider_settings();
|
|
164930
165628
|
init_claude_skills_runner();
|
|
164931
165629
|
init_claude_cli_extension();
|
|
165630
|
+
init_droid_cli_extension();
|
|
164932
165631
|
init_self_extension();
|
|
164933
165632
|
init_provider_auth();
|
|
164934
165633
|
init_auth_paths2();
|
|
@@ -164944,13 +165643,13 @@ var desktop_exports = {};
|
|
|
164944
165643
|
__export(desktop_exports, {
|
|
164945
165644
|
runDesktop: () => runDesktop
|
|
164946
165645
|
});
|
|
164947
|
-
import { spawn as
|
|
165646
|
+
import { spawn as spawn17 } from "node:child_process";
|
|
164948
165647
|
import { once as once2 } from "node:events";
|
|
164949
165648
|
import { join as join60 } from "node:path";
|
|
164950
|
-
import { createRequire as
|
|
165649
|
+
import { createRequire as createRequire6 } from "node:module";
|
|
164951
165650
|
function runCommand(command, args, cwd) {
|
|
164952
|
-
return new Promise((
|
|
164953
|
-
const child =
|
|
165651
|
+
return new Promise((resolve42, reject2) => {
|
|
165652
|
+
const child = spawn17(command, args, {
|
|
164954
165653
|
cwd,
|
|
164955
165654
|
stdio: "inherit",
|
|
164956
165655
|
env: process.env
|
|
@@ -164958,7 +165657,7 @@ function runCommand(command, args, cwd) {
|
|
|
164958
165657
|
child.on("error", (error) => reject2(error));
|
|
164959
165658
|
child.on("exit", (code) => {
|
|
164960
165659
|
if (code === 0) {
|
|
164961
|
-
|
|
165660
|
+
resolve42();
|
|
164962
165661
|
return;
|
|
164963
165662
|
}
|
|
164964
165663
|
reject2(new Error(`${command} ${args.join(" ")} exited with code ${code ?? "unknown"}`));
|
|
@@ -165001,8 +165700,8 @@ async function startDashboardRuntime(rootDir, paused) {
|
|
|
165001
165700
|
};
|
|
165002
165701
|
}
|
|
165003
165702
|
async function closeDashboardRuntime(runtime) {
|
|
165004
|
-
await new Promise((
|
|
165005
|
-
runtime.server.close(() =>
|
|
165703
|
+
await new Promise((resolve42) => {
|
|
165704
|
+
runtime.server.close(() => resolve42());
|
|
165006
165705
|
});
|
|
165007
165706
|
runtime.store.close();
|
|
165008
165707
|
}
|
|
@@ -165035,7 +165734,7 @@ async function runDesktop(options = {}) {
|
|
|
165035
165734
|
electronEnv.FUSION_DASHBOARD_URL = process.env.FUSION_DASHBOARD_URL ?? "http://localhost:5173";
|
|
165036
165735
|
electronEnv.NODE_ENV = "development";
|
|
165037
165736
|
}
|
|
165038
|
-
const electronProcess =
|
|
165737
|
+
const electronProcess = spawn17(electronBinary, electronArgs, {
|
|
165039
165738
|
cwd: rootDir,
|
|
165040
165739
|
stdio: "inherit",
|
|
165041
165740
|
env: electronEnv
|
|
@@ -165074,7 +165773,7 @@ var init_desktop = __esm({
|
|
|
165074
165773
|
"use strict";
|
|
165075
165774
|
init_src();
|
|
165076
165775
|
init_src4();
|
|
165077
|
-
require3 =
|
|
165776
|
+
require3 = createRequire6(import.meta.url);
|
|
165078
165777
|
}
|
|
165079
165778
|
});
|
|
165080
165779
|
|
|
@@ -165110,7 +165809,7 @@ __export(task_exports, {
|
|
|
165110
165809
|
runTaskUpdate: () => runTaskUpdate
|
|
165111
165810
|
});
|
|
165112
165811
|
import { createInterface as createInterface3 } from "node:readline/promises";
|
|
165113
|
-
import { watchFile, unwatchFile, statSync as statSync6, existsSync as
|
|
165812
|
+
import { watchFile, unwatchFile, statSync as statSync6, existsSync as existsSync42, readFileSync as readFileSync21 } from "node:fs";
|
|
165114
165813
|
import { basename as basename17, join as join61 } from "node:path";
|
|
165115
165814
|
function getGitHubIssueUrl(sourceMetadata) {
|
|
165116
165815
|
if (!sourceMetadata || typeof sourceMetadata !== "object") return void 0;
|
|
@@ -165275,9 +165974,9 @@ async function runTaskCreate(descriptionArg, attachFiles, depends, projectName,
|
|
|
165275
165974
|
console.log(` Path: .fusion/tasks/${task.id}/`);
|
|
165276
165975
|
if (attachFiles && attachFiles.length > 0) {
|
|
165277
165976
|
const { readFile: readFile24 } = await import("node:fs/promises");
|
|
165278
|
-
const { basename: basename22, extname: extname3, resolve:
|
|
165977
|
+
const { basename: basename22, extname: extname3, resolve: resolve42 } = await import("node:path");
|
|
165279
165978
|
for (const filePath of attachFiles) {
|
|
165280
|
-
const resolvedPath =
|
|
165979
|
+
const resolvedPath = resolve42(filePath);
|
|
165281
165980
|
const filename = basename22(resolvedPath);
|
|
165282
165981
|
const ext = extname3(filename).toLowerCase();
|
|
165283
165982
|
const mimeType = MIME_TYPES[ext];
|
|
@@ -165412,7 +166111,7 @@ async function runTaskLogs(id, options = {}, projectName) {
|
|
|
165412
166111
|
if (options.follow) {
|
|
165413
166112
|
const projectPath = projectContext?.projectPath ?? process.cwd();
|
|
165414
166113
|
const logPath = join61(projectPath, ".fusion", "tasks", id, "agent.log");
|
|
165415
|
-
if (!
|
|
166114
|
+
if (!existsSync42(logPath)) {
|
|
165416
166115
|
console.log(`
|
|
165417
166116
|
Waiting for log file to be created...`);
|
|
165418
166117
|
}
|
|
@@ -165441,7 +166140,7 @@ async function runTaskLogs(id, options = {}, projectName) {
|
|
|
165441
166140
|
lastPosition = 0;
|
|
165442
166141
|
}
|
|
165443
166142
|
if (stats.size > lastPosition) {
|
|
165444
|
-
const content =
|
|
166143
|
+
const content = readFileSync21(logPath, "utf-8");
|
|
165445
166144
|
const lines = content.slice(lastPosition).split("\n");
|
|
165446
166145
|
for (const line of lines) {
|
|
165447
166146
|
if (!line.trim()) continue;
|
|
@@ -165575,8 +166274,8 @@ async function runTaskMerge(id, projectName) {
|
|
|
165575
166274
|
async function runTaskAttach(id, filePath, projectName) {
|
|
165576
166275
|
const { readFile: readFile24 } = await import("node:fs/promises");
|
|
165577
166276
|
const { basename: basename22, extname: extname3 } = await import("node:path");
|
|
165578
|
-
const { resolve:
|
|
165579
|
-
const resolvedPath =
|
|
166277
|
+
const { resolve: resolve42 } = await import("node:path");
|
|
166278
|
+
const resolvedPath = resolve42(filePath);
|
|
165580
166279
|
const filename = basename22(resolvedPath);
|
|
165581
166280
|
const ext = extname3(filename).toLowerCase();
|
|
165582
166281
|
const mimeType = MIME_TYPES[ext];
|
|
@@ -166115,12 +166814,12 @@ async function promptText(question) {
|
|
|
166115
166814
|
console.log(" (Enter your response. Type DONE on its own line when finished):\n");
|
|
166116
166815
|
const rl = createInterface3({ input: process.stdin, output: process.stdout });
|
|
166117
166816
|
const lines = [];
|
|
166118
|
-
return new Promise((
|
|
166817
|
+
return new Promise((resolve42) => {
|
|
166119
166818
|
const askLine = () => {
|
|
166120
166819
|
rl.question(" ").then((line) => {
|
|
166121
166820
|
if (line.trim() === "DONE") {
|
|
166122
166821
|
rl.close();
|
|
166123
|
-
|
|
166822
|
+
resolve42(lines.join("\n"));
|
|
166124
166823
|
} else {
|
|
166125
166824
|
lines.push(line);
|
|
166126
166825
|
askLine();
|
|
@@ -166285,7 +166984,7 @@ async function runTaskPlan(initialPlanArg, yesFlag = false, projectName) {
|
|
|
166285
166984
|
} catch (err) {
|
|
166286
166985
|
clearThinking();
|
|
166287
166986
|
if (err instanceof RateLimitError2) {
|
|
166288
|
-
console.error("\n Rate limit exceeded. Maximum
|
|
166987
|
+
console.error("\n Rate limit exceeded. Maximum 1000 planning sessions per hour.\n");
|
|
166289
166988
|
process.exit(1);
|
|
166290
166989
|
}
|
|
166291
166990
|
console.error(`
|
|
@@ -166689,7 +167388,7 @@ __export(settings_export_exports, {
|
|
|
166689
167388
|
runSettingsExport: () => runSettingsExport
|
|
166690
167389
|
});
|
|
166691
167390
|
import { writeFile as writeFile18 } from "node:fs/promises";
|
|
166692
|
-
import { resolve as
|
|
167391
|
+
import { resolve as resolve32, join as join62 } from "node:path";
|
|
166693
167392
|
async function runSettingsExport(options = {}) {
|
|
166694
167393
|
const scope = options.scope ?? "both";
|
|
166695
167394
|
const project = options.projectName ? await resolveProject(options.projectName) : void 0;
|
|
@@ -166700,7 +167399,7 @@ async function runSettingsExport(options = {}) {
|
|
|
166700
167399
|
const exportData = await exportSettings(store, { scope });
|
|
166701
167400
|
let targetPath;
|
|
166702
167401
|
if (outputPath) {
|
|
166703
|
-
targetPath =
|
|
167402
|
+
targetPath = resolve32(outputPath);
|
|
166704
167403
|
} else {
|
|
166705
167404
|
const filename = generateExportFilename();
|
|
166706
167405
|
targetPath = join62(process.cwd(), filename);
|
|
@@ -166749,8 +167448,8 @@ var settings_import_exports = {};
|
|
|
166749
167448
|
__export(settings_import_exports, {
|
|
166750
167449
|
runSettingsImport: () => runSettingsImport
|
|
166751
167450
|
});
|
|
166752
|
-
import { existsSync as
|
|
166753
|
-
import { resolve as
|
|
167451
|
+
import { existsSync as existsSync43 } from "node:fs";
|
|
167452
|
+
import { resolve as resolve33 } from "node:path";
|
|
166754
167453
|
async function runSettingsImport(filePath, options = {}) {
|
|
166755
167454
|
const scope = options.scope ?? "both";
|
|
166756
167455
|
const project = options.projectName ? await resolveProject(options.projectName) : void 0;
|
|
@@ -166759,8 +167458,8 @@ async function runSettingsImport(filePath, options = {}) {
|
|
|
166759
167458
|
const merge = options.merge ?? true;
|
|
166760
167459
|
const skipConfirm = options.yes ?? false;
|
|
166761
167460
|
try {
|
|
166762
|
-
const resolvedPath =
|
|
166763
|
-
if (!
|
|
167461
|
+
const resolvedPath = resolve33(filePath);
|
|
167462
|
+
if (!existsSync43(resolvedPath)) {
|
|
166764
167463
|
console.error(`Error: File not found: ${filePath}`);
|
|
166765
167464
|
process.exit(1);
|
|
166766
167465
|
}
|
|
@@ -167233,8 +167932,8 @@ var init_backup2 = __esm({
|
|
|
167233
167932
|
});
|
|
167234
167933
|
|
|
167235
167934
|
// src/project-resolver.ts
|
|
167236
|
-
import { existsSync as
|
|
167237
|
-
import { basename as basename18, dirname as
|
|
167935
|
+
import { existsSync as existsSync44, statSync as statSync7 } from "node:fs";
|
|
167936
|
+
import { basename as basename18, dirname as dirname26, resolve as resolve34, normalize as normalize5 } from "node:path";
|
|
167238
167937
|
import { createInterface as createInterface5 } from "node:readline/promises";
|
|
167239
167938
|
async function getCentralCore() {
|
|
167240
167939
|
if (!centralCoreInstance) {
|
|
@@ -167251,13 +167950,13 @@ async function getProjectManager() {
|
|
|
167251
167950
|
return projectManagerInstance;
|
|
167252
167951
|
}
|
|
167253
167952
|
function findKbDir(startPath) {
|
|
167254
|
-
let current =
|
|
167953
|
+
let current = resolve34(startPath);
|
|
167255
167954
|
for (let i = 0; i < 100; i++) {
|
|
167256
|
-
const dbPath =
|
|
167955
|
+
const dbPath = resolve34(current, ".fusion", "fusion.db");
|
|
167257
167956
|
if (isValidSqliteDatabaseFile(dbPath)) {
|
|
167258
167957
|
return current;
|
|
167259
167958
|
}
|
|
167260
|
-
const parent2 =
|
|
167959
|
+
const parent2 = dirname26(current);
|
|
167261
167960
|
if (parent2 === current) {
|
|
167262
167961
|
break;
|
|
167263
167962
|
}
|
|
@@ -167309,7 +168008,7 @@ async function resolveProject2(options = {}) {
|
|
|
167309
168008
|
{ searchedName: options.project, availableProjects: projects.map((p) => p.name) }
|
|
167310
168009
|
);
|
|
167311
168010
|
}
|
|
167312
|
-
if (!
|
|
168011
|
+
if (!existsSync44(match.path)) {
|
|
167313
168012
|
throw new ProjectResolutionError(
|
|
167314
168013
|
`Project "${match.name}" is registered but the directory no longer exists: ${match.path}
|
|
167315
168014
|
|
|
@@ -167320,14 +168019,14 @@ Run \`fn project remove ` + match.name + "` to clean up the registry entry.",
|
|
|
167320
168019
|
}
|
|
167321
168020
|
return createResolvedProject(match);
|
|
167322
168021
|
}
|
|
167323
|
-
const cwd = options.cwd ?
|
|
168022
|
+
const cwd = options.cwd ? resolve34(options.cwd) : process.cwd();
|
|
167324
168023
|
const fusionDir = findKbDir(cwd);
|
|
167325
168024
|
if (fusionDir) {
|
|
167326
168025
|
const allProjects2 = await central.listProjects();
|
|
167327
168026
|
const normalizedKbDir = normalize5(fusionDir);
|
|
167328
168027
|
const match = allProjects2.find((p) => normalize5(p.path) === normalizedKbDir);
|
|
167329
168028
|
if (match) {
|
|
167330
|
-
if (!
|
|
168029
|
+
if (!existsSync44(match.path)) {
|
|
167331
168030
|
throw new ProjectResolutionError(
|
|
167332
168031
|
`Project "${match.name}" is registered but the directory no longer exists: ${match.path}
|
|
167333
168032
|
|
|
@@ -167392,7 +168091,7 @@ Run \`fn project add ` + fusionDir + "` to register it, or use --project <name>.
|
|
|
167392
168091
|
}
|
|
167393
168092
|
if (allProjects.length === 1) {
|
|
167394
168093
|
const project = allProjects[0];
|
|
167395
|
-
if (!
|
|
168094
|
+
if (!existsSync44(project.path)) {
|
|
167396
168095
|
throw new ProjectResolutionError(
|
|
167397
168096
|
`The only registered project "${project.name}" has a missing directory: ${project.path}
|
|
167398
168097
|
|
|
@@ -167832,8 +168531,8 @@ __export(project_exports, {
|
|
|
167832
168531
|
runProjectSetDefault: () => runProjectSetDefault,
|
|
167833
168532
|
runProjectShow: () => runProjectShow
|
|
167834
168533
|
});
|
|
167835
|
-
import { resolve as
|
|
167836
|
-
import { existsSync as
|
|
168534
|
+
import { resolve as resolve35, isAbsolute as isAbsolute19, relative as relative14, basename as basename19 } from "node:path";
|
|
168535
|
+
import { existsSync as existsSync45, statSync as statSync8 } from "node:fs";
|
|
167837
168536
|
import { createInterface as createInterface7 } from "node:readline/promises";
|
|
167838
168537
|
function formatDisplayPath(projectPath) {
|
|
167839
168538
|
const rel = relative14(process.cwd(), projectPath);
|
|
@@ -167961,8 +168660,8 @@ async function runProjectAdd(name, path5, options = {}) {
|
|
|
167961
168660
|
const pathInput = await rl.question(` Project path [${defaultPath}]: `);
|
|
167962
168661
|
projectPath = pathInput.trim() || defaultPath;
|
|
167963
168662
|
}
|
|
167964
|
-
const absolutePath2 = isAbsolute19(projectPath) ? projectPath :
|
|
167965
|
-
if (!
|
|
168663
|
+
const absolutePath2 = isAbsolute19(projectPath) ? projectPath : resolve35(process.cwd(), projectPath);
|
|
168664
|
+
if (!existsSync45(absolutePath2)) {
|
|
167966
168665
|
console.error(`
|
|
167967
168666
|
\u2717 Path does not exist: ${projectPath}`);
|
|
167968
168667
|
rl.close();
|
|
@@ -167974,8 +168673,8 @@ async function runProjectAdd(name, path5, options = {}) {
|
|
|
167974
168673
|
rl.close();
|
|
167975
168674
|
process.exit(1);
|
|
167976
168675
|
}
|
|
167977
|
-
const kbDbPath2 =
|
|
167978
|
-
if (!
|
|
168676
|
+
const kbDbPath2 = resolve35(absolutePath2, ".fusion", "fusion.db");
|
|
168677
|
+
if (!existsSync45(kbDbPath2) && !options.force) {
|
|
167979
168678
|
console.log(`
|
|
167980
168679
|
No fn project found at ${formatDisplayPath(absolutePath2)}`);
|
|
167981
168680
|
const init = await rl.question(" Initialize fn here first? [Y/n] ");
|
|
@@ -168006,8 +168705,8 @@ async function runProjectAdd(name, path5, options = {}) {
|
|
|
168006
168705
|
console.error(" Name must be 1-64 characters and contain only: a-z, A-Z, 0-9, _, -\n");
|
|
168007
168706
|
process.exit(1);
|
|
168008
168707
|
}
|
|
168009
|
-
const absolutePath = isAbsolute19(projectPath) ? projectPath :
|
|
168010
|
-
if (!
|
|
168708
|
+
const absolutePath = isAbsolute19(projectPath) ? projectPath : resolve35(process.cwd(), projectPath);
|
|
168709
|
+
if (!existsSync45(absolutePath)) {
|
|
168011
168710
|
console.error(`
|
|
168012
168711
|
\u2717 Path does not exist: ${projectPath}
|
|
168013
168712
|
`);
|
|
@@ -168019,8 +168718,8 @@ async function runProjectAdd(name, path5, options = {}) {
|
|
|
168019
168718
|
`);
|
|
168020
168719
|
process.exit(1);
|
|
168021
168720
|
}
|
|
168022
|
-
const kbDbPath =
|
|
168023
|
-
if (!
|
|
168721
|
+
const kbDbPath = resolve35(absolutePath, ".fusion", "fusion.db");
|
|
168722
|
+
if (!existsSync45(kbDbPath) && !options.force) {
|
|
168024
168723
|
console.error(`
|
|
168025
168724
|
\u2717 No fn project found at ${formatDisplayPath(absolutePath)}`);
|
|
168026
168725
|
console.error(" Run `fn init` first to initialize the project.\n");
|
|
@@ -168276,10 +168975,10 @@ var init_project = __esm({
|
|
|
168276
168975
|
});
|
|
168277
168976
|
|
|
168278
168977
|
// src/commands/skill-installation.ts
|
|
168279
|
-
import { cpSync as cpSync2, existsSync as
|
|
168978
|
+
import { cpSync as cpSync2, existsSync as existsSync46, mkdirSync as mkdirSync8 } from "node:fs";
|
|
168280
168979
|
import { homedir as homedir10 } from "node:os";
|
|
168281
|
-
import { dirname as
|
|
168282
|
-
import { fileURLToPath as
|
|
168980
|
+
import { dirname as dirname27, join as join63, resolve as resolve36 } from "node:path";
|
|
168981
|
+
import { fileURLToPath as fileURLToPath10 } from "node:url";
|
|
168283
168982
|
function getSupportedSkillInstallTargets(homeDir = process.env.HOME || process.env.USERPROFILE || homedir10()) {
|
|
168284
168983
|
return [
|
|
168285
168984
|
{ client: "claude", targetDir: join63(homeDir, ".claude", "skills", FUSION_SKILL_NAME2) },
|
|
@@ -168288,9 +168987,9 @@ function getSupportedSkillInstallTargets(homeDir = process.env.HOME || process.e
|
|
|
168288
168987
|
];
|
|
168289
168988
|
}
|
|
168290
168989
|
function resolveBundledFusionSkillSource() {
|
|
168291
|
-
const here =
|
|
168292
|
-
const source =
|
|
168293
|
-
return
|
|
168990
|
+
const here = fileURLToPath10(import.meta.url);
|
|
168991
|
+
const source = resolve36(dirname27(here), "..", "..", "skill", FUSION_SKILL_NAME2);
|
|
168992
|
+
return existsSync46(source) ? source : null;
|
|
168294
168993
|
}
|
|
168295
168994
|
function installBundledFusionSkill(options = {}) {
|
|
168296
168995
|
const sourceDir = options.sourceDir ?? resolveBundledFusionSkillSource();
|
|
@@ -168308,7 +169007,7 @@ function installBundledFusionSkill(options = {}) {
|
|
|
168308
169007
|
}
|
|
168309
169008
|
const results = targets.map((target) => {
|
|
168310
169009
|
try {
|
|
168311
|
-
if (
|
|
169010
|
+
if (existsSync46(target.targetDir)) {
|
|
168312
169011
|
return {
|
|
168313
169012
|
client: target.client,
|
|
168314
169013
|
targetDir: target.targetDir,
|
|
@@ -168316,7 +169015,7 @@ function installBundledFusionSkill(options = {}) {
|
|
|
168316
169015
|
reason: "existing install preserved"
|
|
168317
169016
|
};
|
|
168318
169017
|
}
|
|
168319
|
-
mkdirSync8(
|
|
169018
|
+
mkdirSync8(dirname27(target.targetDir), { recursive: true });
|
|
168320
169019
|
cpSync2(sourceDir, target.targetDir, { recursive: true });
|
|
168321
169020
|
return {
|
|
168322
169021
|
client: target.client,
|
|
@@ -168347,17 +169046,17 @@ var init_exports = {};
|
|
|
168347
169046
|
__export(init_exports, {
|
|
168348
169047
|
runInit: () => runInit
|
|
168349
169048
|
});
|
|
168350
|
-
import { existsSync as
|
|
168351
|
-
import { join as join64, resolve as
|
|
169049
|
+
import { existsSync as existsSync47, mkdirSync as mkdirSync9, writeFileSync as writeFileSync3, readFileSync as readFileSync22 } from "node:fs";
|
|
169050
|
+
import { join as join64, resolve as resolve37, basename as basename20 } from "node:path";
|
|
168352
169051
|
import { exec as exec12 } from "node:child_process";
|
|
168353
169052
|
import { promisify as promisify17 } from "node:util";
|
|
168354
169053
|
async function runInit(options = {}) {
|
|
168355
|
-
const cwd = options.path ?
|
|
169054
|
+
const cwd = options.path ? resolve37(options.path) : process.cwd();
|
|
168356
169055
|
const fusionDir = join64(cwd, ".fusion");
|
|
168357
169056
|
const dbPath = join64(fusionDir, "fusion.db");
|
|
168358
|
-
const hasDbPath =
|
|
169057
|
+
const hasDbPath = existsSync47(dbPath);
|
|
168359
169058
|
const hasValidDb = hasDbPath && isValidSqliteDatabaseFile(dbPath);
|
|
168360
|
-
if (
|
|
169059
|
+
if (existsSync47(fusionDir) && hasDbPath && hasValidDb) {
|
|
168361
169060
|
const central2 = new CentralCore();
|
|
168362
169061
|
await central2.init();
|
|
168363
169062
|
const existing = await central2.getProjectByPath(cwd);
|
|
@@ -168379,7 +169078,7 @@ async function runInit(options = {}) {
|
|
|
168379
169078
|
await central2.close();
|
|
168380
169079
|
return;
|
|
168381
169080
|
}
|
|
168382
|
-
if (
|
|
169081
|
+
if (existsSync47(fusionDir) && hasDbPath && !hasValidDb) {
|
|
168383
169082
|
throw new Error(
|
|
168384
169083
|
`Existing database at ${dbPath} is not a valid SQLite database. Restore it from .fusion/backups or move it aside before re-running fn init.`
|
|
168385
169084
|
);
|
|
@@ -168387,7 +169086,7 @@ async function runInit(options = {}) {
|
|
|
168387
169086
|
const projectName = options.name ?? await detectProjectName(cwd);
|
|
168388
169087
|
console.log(`Initializing fn project: "${projectName}"`);
|
|
168389
169088
|
console.log(` Path: ${cwd}`);
|
|
168390
|
-
if (!
|
|
169089
|
+
if (!existsSync47(fusionDir)) {
|
|
168391
169090
|
mkdirSync9(fusionDir, { recursive: true });
|
|
168392
169091
|
console.log(` \u2713 Created .fusion/ directory`);
|
|
168393
169092
|
}
|
|
@@ -168400,7 +169099,7 @@ async function runInit(options = {}) {
|
|
|
168400
169099
|
}
|
|
168401
169100
|
await addLocalStorageToGitignore(cwd);
|
|
168402
169101
|
await warnIfQmdMissing();
|
|
168403
|
-
if (!
|
|
169102
|
+
if (!existsSync47(dbPath)) {
|
|
168404
169103
|
writeFileSync3(dbPath, "");
|
|
168405
169104
|
console.log(` \u2713 Created fusion.db`);
|
|
168406
169105
|
}
|
|
@@ -168450,7 +169149,7 @@ async function runInit(options = {}) {
|
|
|
168450
169149
|
}
|
|
168451
169150
|
}
|
|
168452
169151
|
async function detectProjectName(dir2) {
|
|
168453
|
-
if (!
|
|
169152
|
+
if (!existsSync47(join64(dir2, ".git"))) {
|
|
168454
169153
|
return basename20(dir2) || "my-project";
|
|
168455
169154
|
}
|
|
168456
169155
|
try {
|
|
@@ -168472,9 +169171,9 @@ async function detectProjectName(dir2) {
|
|
|
168472
169171
|
async function addLocalStorageToGitignore(cwd) {
|
|
168473
169172
|
const gitignorePath = join64(cwd, ".gitignore");
|
|
168474
169173
|
let content = "";
|
|
168475
|
-
if (
|
|
169174
|
+
if (existsSync47(gitignorePath)) {
|
|
168476
169175
|
try {
|
|
168477
|
-
content =
|
|
169176
|
+
content = readFileSync22(gitignorePath, "utf-8");
|
|
168478
169177
|
} catch {
|
|
168479
169178
|
}
|
|
168480
169179
|
}
|
|
@@ -168514,7 +169213,7 @@ async function initializeGitRepo(cwd) {
|
|
|
168514
169213
|
await ensureGitConfig(cwd, "user.name", "Fusion");
|
|
168515
169214
|
await ensureGitConfig(cwd, "user.email", "noreply@runfusion.ai");
|
|
168516
169215
|
const gitkeepPath = join64(cwd, ".gitkeep");
|
|
168517
|
-
if (!
|
|
169216
|
+
if (!existsSync47(gitkeepPath)) {
|
|
168518
169217
|
writeFileSync3(gitkeepPath, "\n");
|
|
168519
169218
|
}
|
|
168520
169219
|
await execAsync11("git add .gitkeep", { cwd, timeout: 1e4 });
|
|
@@ -168652,8 +169351,8 @@ var agent_import_exports = {};
|
|
|
168652
169351
|
__export(agent_import_exports, {
|
|
168653
169352
|
runAgentImport: () => runAgentImport
|
|
168654
169353
|
});
|
|
168655
|
-
import { existsSync as
|
|
168656
|
-
import { resolve as
|
|
169354
|
+
import { existsSync as existsSync48, mkdirSync as mkdirSync10, readFileSync as readFileSync23, statSync as statSync9, writeFileSync as writeFileSync4 } from "node:fs";
|
|
169355
|
+
import { resolve as resolve38 } from "node:path";
|
|
168657
169356
|
function slugifyPathSegment(input) {
|
|
168658
169357
|
if (!input || typeof input !== "string") {
|
|
168659
169358
|
return "unnamed";
|
|
@@ -168702,16 +169401,16 @@ async function importSkillsToProject(projectPath, skills, companySlug, dryRun) {
|
|
|
168702
169401
|
errors: []
|
|
168703
169402
|
};
|
|
168704
169403
|
const companyDir = slugifyPathSegment(companySlug ?? "unknown-company");
|
|
168705
|
-
const baseSkillsDir =
|
|
169404
|
+
const baseSkillsDir = resolve38(projectPath, "skills", "imported", companyDir);
|
|
168706
169405
|
for (const skill of skills) {
|
|
168707
169406
|
if (!skill.name || typeof skill.name !== "string" || skill.name.trim().length === 0) {
|
|
168708
169407
|
result.errors.push({ name: "(unnamed)", error: "Skill is missing required 'name' field" });
|
|
168709
169408
|
continue;
|
|
168710
169409
|
}
|
|
168711
169410
|
const skillSlug = slugifyPathSegment(skill.name);
|
|
168712
|
-
const skillDir =
|
|
168713
|
-
const skillPath =
|
|
168714
|
-
if (
|
|
169411
|
+
const skillDir = resolve38(baseSkillsDir, skillSlug);
|
|
169412
|
+
const skillPath = resolve38(skillDir, "SKILL.md");
|
|
169413
|
+
if (existsSync48(skillPath)) {
|
|
168715
169414
|
result.skipped.push(skill.name);
|
|
168716
169415
|
continue;
|
|
168717
169416
|
}
|
|
@@ -168783,8 +169482,8 @@ function isArchivePath(path5) {
|
|
|
168783
169482
|
async function runAgentImport(source, options) {
|
|
168784
169483
|
const dryRun = options?.dryRun ?? false;
|
|
168785
169484
|
const skipExisting = options?.skipExisting ?? false;
|
|
168786
|
-
const sourcePath =
|
|
168787
|
-
if (!
|
|
169485
|
+
const sourcePath = resolve38(source);
|
|
169486
|
+
if (!existsSync48(sourcePath)) {
|
|
168788
169487
|
console.error(`Path not found: ${sourcePath}`);
|
|
168789
169488
|
process.exit(1);
|
|
168790
169489
|
}
|
|
@@ -168830,7 +169529,7 @@ async function runAgentImport(source, options) {
|
|
|
168830
169529
|
isPackageImport = true;
|
|
168831
169530
|
({ items: importItems, result } = prepareAgentCompaniesImport(pkg, conversionOptions));
|
|
168832
169531
|
} else if (sourcePath.endsWith(".md")) {
|
|
168833
|
-
const content =
|
|
169532
|
+
const content = readFileSync23(sourcePath, "utf-8");
|
|
168834
169533
|
const { manifest } = parseSingleAgentManifest(content);
|
|
168835
169534
|
const pkg = {
|
|
168836
169535
|
company: void 0,
|
|
@@ -168922,7 +169621,7 @@ var agent_export_exports = {};
|
|
|
168922
169621
|
__export(agent_export_exports, {
|
|
168923
169622
|
runAgentExport: () => runAgentExport
|
|
168924
169623
|
});
|
|
168925
|
-
import { resolve as
|
|
169624
|
+
import { resolve as resolve39 } from "node:path";
|
|
168926
169625
|
async function getProjectPath4(projectName) {
|
|
168927
169626
|
if (projectName) {
|
|
168928
169627
|
const context = await resolveProject(projectName);
|
|
@@ -168960,7 +169659,7 @@ async function runAgentExport(outputDir, options) {
|
|
|
168960
169659
|
console.error("No agents found to export");
|
|
168961
169660
|
process.exit(1);
|
|
168962
169661
|
}
|
|
168963
|
-
const result = await exportAgentsToDirectory(agents,
|
|
169662
|
+
const result = await exportAgentsToDirectory(agents, resolve39(outputDir), {
|
|
168964
169663
|
companyName: options?.companyName,
|
|
168965
169664
|
companySlug: options?.companySlug
|
|
168966
169665
|
});
|
|
@@ -169179,7 +169878,7 @@ __export(plugin_exports, {
|
|
|
169179
169878
|
runPluginList: () => runPluginList,
|
|
169180
169879
|
runPluginUninstall: () => runPluginUninstall
|
|
169181
169880
|
});
|
|
169182
|
-
import { existsSync as
|
|
169881
|
+
import { existsSync as existsSync49 } from "node:fs";
|
|
169183
169882
|
import { join as join65 } from "node:path";
|
|
169184
169883
|
import { readFile as readFile23 } from "node:fs/promises";
|
|
169185
169884
|
import * as readline from "node:readline";
|
|
@@ -169219,7 +169918,7 @@ async function createPluginLoader(pluginStore, projectName) {
|
|
|
169219
169918
|
}
|
|
169220
169919
|
async function loadManifestFromPath(pluginPath) {
|
|
169221
169920
|
const manifestPath = join65(pluginPath, "manifest.json");
|
|
169222
|
-
if (!
|
|
169921
|
+
if (!existsSync49(manifestPath)) {
|
|
169223
169922
|
throw new Error(`Plugin manifest not found at: ${manifestPath}`);
|
|
169224
169923
|
}
|
|
169225
169924
|
const content = await readFile23(manifestPath, "utf-8");
|
|
@@ -169277,7 +169976,7 @@ async function runPluginInstall(source, options) {
|
|
|
169277
169976
|
console.error("Please provide a local path to the plugin directory.");
|
|
169278
169977
|
process.exit(1);
|
|
169279
169978
|
}
|
|
169280
|
-
if (!
|
|
169979
|
+
if (!existsSync49(source)) {
|
|
169281
169980
|
console.error(`Plugin path does not exist: ${source}`);
|
|
169282
169981
|
process.exit(1);
|
|
169283
169982
|
}
|
|
@@ -169322,14 +170021,14 @@ async function runPluginUninstall(id, options) {
|
|
|
169322
170021
|
console.log(` Uninstall "${plugin4.name}"?`);
|
|
169323
170022
|
console.log(` This will stop and remove the plugin.`);
|
|
169324
170023
|
console.log();
|
|
169325
|
-
const response = await new Promise((
|
|
170024
|
+
const response = await new Promise((resolve42) => {
|
|
169326
170025
|
const rl = readline.createInterface({
|
|
169327
170026
|
input: process.stdin,
|
|
169328
170027
|
output: process.stdout
|
|
169329
170028
|
});
|
|
169330
170029
|
rl.question(" Continue? [y/N] ", (answer) => {
|
|
169331
170030
|
rl.close();
|
|
169332
|
-
|
|
170031
|
+
resolve42(answer.toLowerCase());
|
|
169333
170032
|
});
|
|
169334
170033
|
});
|
|
169335
170034
|
if (response !== "y" && response !== "yes") {
|
|
@@ -169409,7 +170108,7 @@ var plugin_scaffold_exports = {};
|
|
|
169409
170108
|
__export(plugin_scaffold_exports, {
|
|
169410
170109
|
runPluginCreate: () => runPluginCreate
|
|
169411
170110
|
});
|
|
169412
|
-
import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync5, existsSync as
|
|
170111
|
+
import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync5, existsSync as existsSync50 } from "node:fs";
|
|
169413
170112
|
import { join as join66 } from "node:path";
|
|
169414
170113
|
function toTitleCase(str) {
|
|
169415
170114
|
return str.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
@@ -169544,7 +170243,7 @@ async function runPluginCreate(name, options) {
|
|
|
169544
170243
|
}
|
|
169545
170244
|
const targetDir = options?.output ?? name;
|
|
169546
170245
|
const targetPath = join66(process.cwd(), targetDir);
|
|
169547
|
-
if (
|
|
170246
|
+
if (existsSync50(targetPath)) {
|
|
169548
170247
|
console.error(`Error: Directory '${targetDir}' already exists.`);
|
|
169549
170248
|
console.error("Please choose a different name or remove the existing directory.");
|
|
169550
170249
|
process.exit(1);
|
|
@@ -169594,7 +170293,7 @@ __export(skills_exports, {
|
|
|
169594
170293
|
runSkillsSearch: () => runSkillsSearch,
|
|
169595
170294
|
searchSkills: () => searchSkills
|
|
169596
170295
|
});
|
|
169597
|
-
import { spawn as
|
|
170296
|
+
import { spawn as spawn18 } from "node:child_process";
|
|
169598
170297
|
async function searchSkills(query, limit = 10) {
|
|
169599
170298
|
const url = `${SKILLS_API_BASE}/api/search?q=${encodeURIComponent(query)}&limit=${limit}`;
|
|
169600
170299
|
try {
|
|
@@ -169672,14 +170371,14 @@ async function runSkillsInstall(args, options) {
|
|
|
169672
170371
|
npxArgs.push("--skill", options.skill);
|
|
169673
170372
|
}
|
|
169674
170373
|
npxArgs.push("-y", "-a", "pi");
|
|
169675
|
-
const child =
|
|
170374
|
+
const child = spawn18("npx", npxArgs, {
|
|
169676
170375
|
cwd: process.cwd(),
|
|
169677
170376
|
stdio: "inherit",
|
|
169678
170377
|
shell: true
|
|
169679
170378
|
});
|
|
169680
|
-
const exitCode = await new Promise((
|
|
170379
|
+
const exitCode = await new Promise((resolve42, reject2) => {
|
|
169681
170380
|
child.on("exit", (code) => {
|
|
169682
|
-
|
|
170381
|
+
resolve42(code ?? 1);
|
|
169683
170382
|
});
|
|
169684
170383
|
child.on("error", (err) => {
|
|
169685
170384
|
reject2(err);
|
|
@@ -169712,7 +170411,7 @@ __export(research_exports, {
|
|
|
169712
170411
|
runResearchShow: () => runResearchShow
|
|
169713
170412
|
});
|
|
169714
170413
|
import { writeFile as writeFile19 } from "node:fs/promises";
|
|
169715
|
-
import { join as join67, resolve as
|
|
170414
|
+
import { join as join67, resolve as resolve40 } from "node:path";
|
|
169716
170415
|
async function getStore3(projectName) {
|
|
169717
170416
|
const project = projectName ? await resolveProject(projectName) : void 0;
|
|
169718
170417
|
const store = new TaskStore(project?.projectPath ?? process.cwd());
|
|
@@ -169868,7 +170567,7 @@ async function runResearchExport(options) {
|
|
|
169868
170567
|
}
|
|
169869
170568
|
const content = format === "json" ? JSON.stringify(run, null, 2) : renderMarkdown(run);
|
|
169870
170569
|
const ext = format === "json" ? "json" : "md";
|
|
169871
|
-
const outputPath = options.output ?
|
|
170570
|
+
const outputPath = options.output ? resolve40(options.output) : join67(process.cwd(), `research-${run.id.toLowerCase()}.${ext}`);
|
|
169872
170571
|
await writeFile19(outputPath, content, "utf8");
|
|
169873
170572
|
store.getResearchStore().createExport(run.id, format, content);
|
|
169874
170573
|
if (options.json) {
|
|
@@ -169933,21 +170632,21 @@ __export(native_patch_exports, {
|
|
|
169933
170632
|
isTerminalAvailable: () => isTerminalAvailable,
|
|
169934
170633
|
setupNativeResolution: () => setupNativeResolution
|
|
169935
170634
|
});
|
|
169936
|
-
import { join as join68, basename as basename21, dirname as
|
|
169937
|
-
import { existsSync as
|
|
170635
|
+
import { join as join68, basename as basename21, dirname as dirname28 } from "node:path";
|
|
170636
|
+
import { existsSync as existsSync51, copyFileSync, mkdirSync as mkdirSync12, symlinkSync as symlinkSync2, rmSync as rmSync5, lstatSync as lstatSync3, readlinkSync as readlinkSync2 } from "node:fs";
|
|
169938
170637
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
169939
170638
|
function findStagedNativeDir2() {
|
|
169940
|
-
const
|
|
170639
|
+
const platform4 = process.platform === "darwin" ? "darwin" : process.platform === "linux" ? "linux" : process.platform === "win32" ? "win32" : "unknown";
|
|
169941
170640
|
const arch = process.arch === "arm64" ? "arm64" : process.arch === "x64" ? "x64" : "unknown";
|
|
169942
|
-
const prebuildName = `${
|
|
169943
|
-
const execDir =
|
|
170641
|
+
const prebuildName = `${platform4}-${arch}`;
|
|
170642
|
+
const execDir = dirname28(process.execPath);
|
|
169944
170643
|
const nextToBinary = join68(execDir, "runtime", prebuildName);
|
|
169945
|
-
if (
|
|
170644
|
+
if (existsSync51(join68(nextToBinary, "pty.node"))) {
|
|
169946
170645
|
return nextToBinary;
|
|
169947
170646
|
}
|
|
169948
170647
|
if (process.env.FUSION_RUNTIME_DIR) {
|
|
169949
170648
|
const envPath = join68(process.env.FUSION_RUNTIME_DIR, prebuildName);
|
|
169950
|
-
if (
|
|
170649
|
+
if (existsSync51(join68(envPath, "pty.node"))) {
|
|
169951
170650
|
return envPath;
|
|
169952
170651
|
}
|
|
169953
170652
|
}
|
|
@@ -169957,11 +170656,11 @@ function cleanupStaleBunfsLinks() {
|
|
|
169957
170656
|
if (process.platform === "win32") return;
|
|
169958
170657
|
const bunfsRoot = "/$bunfs/root";
|
|
169959
170658
|
try {
|
|
169960
|
-
if (
|
|
170659
|
+
if (existsSync51(bunfsRoot)) {
|
|
169961
170660
|
const stats = lstatSync3(bunfsRoot);
|
|
169962
170661
|
if (stats.isSymbolicLink()) {
|
|
169963
170662
|
const target = readlinkSync2(bunfsRoot);
|
|
169964
|
-
if (target.includes("fn-bunfs-") && !
|
|
170663
|
+
if (target.includes("fn-bunfs-") && !existsSync51(target)) {
|
|
169965
170664
|
rmSync5(bunfsRoot);
|
|
169966
170665
|
console.log("[fn-native-patch] Cleaned up stale /$bunfs/root symlink");
|
|
169967
170666
|
}
|
|
@@ -169989,14 +170688,14 @@ function setupNativeResolution() {
|
|
|
169989
170688
|
mkdirSync12(platformDir, { recursive: true });
|
|
169990
170689
|
const ptyNodeDest = join68(platformDir, "pty.node");
|
|
169991
170690
|
copyFileSync(join68(nativeDir, "pty.node"), ptyNodeDest);
|
|
169992
|
-
if (
|
|
170691
|
+
if (existsSync51(join68(nativeDir, "spawn-helper"))) {
|
|
169993
170692
|
copyFileSync(join68(nativeDir, "spawn-helper"), join68(platformDir, "spawn-helper"));
|
|
169994
170693
|
}
|
|
169995
170694
|
process.env.FUSION_FAKE_BUNFS_ROOT = tmpRoot;
|
|
169996
170695
|
if (process.platform !== "win32") {
|
|
169997
170696
|
const bunfsRoot = "/$bunfs/root";
|
|
169998
170697
|
try {
|
|
169999
|
-
if (
|
|
170698
|
+
if (existsSync51(bunfsRoot)) {
|
|
170000
170699
|
const stats = lstatSync3(bunfsRoot);
|
|
170001
170700
|
if (stats.isSymbolicLink()) {
|
|
170002
170701
|
rmSync5(bunfsRoot);
|
|
@@ -170019,7 +170718,7 @@ function setupNativeResolution() {
|
|
|
170019
170718
|
function cleanupNativeResolution() {
|
|
170020
170719
|
if (bunfsSymlinkPath && process.platform !== "win32") {
|
|
170021
170720
|
try {
|
|
170022
|
-
if (
|
|
170721
|
+
if (existsSync51(bunfsSymlinkPath)) {
|
|
170023
170722
|
const stats = lstatSync3(bunfsSymlinkPath);
|
|
170024
170723
|
if (stats.isSymbolicLink()) {
|
|
170025
170724
|
rmSync5(bunfsSymlinkPath);
|
|
@@ -170065,11 +170764,12 @@ var init_native_patch = __esm({
|
|
|
170065
170764
|
});
|
|
170066
170765
|
|
|
170067
170766
|
// src/bin.ts
|
|
170068
|
-
import { existsSync as
|
|
170069
|
-
import { createRequire as
|
|
170070
|
-
import { join as join69, dirname as
|
|
170767
|
+
import { existsSync as existsSync52, mkdtempSync as mkdtempSync2, readFileSync as readFileSync24, symlinkSync as symlinkSync3, writeFileSync as writeFileSync6 } from "node:fs";
|
|
170768
|
+
import { createRequire as createRequire7 } from "node:module";
|
|
170769
|
+
import { join as join69, dirname as dirname29, resolve as resolve41 } from "node:path";
|
|
170071
170770
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
170072
170771
|
import { performance as performance3 } from "node:perf_hooks";
|
|
170772
|
+
import { fileURLToPath as fileURLToPath11 } from "node:url";
|
|
170073
170773
|
var isBunBinary3 = typeof Bun !== "undefined" && !!Bun.embeddedFiles;
|
|
170074
170774
|
function configurePiPackage() {
|
|
170075
170775
|
if (process.env.PI_PACKAGE_DIR) {
|
|
@@ -170082,13 +170782,13 @@ function configurePiPackage() {
|
|
|
170082
170782
|
type: "module"
|
|
170083
170783
|
};
|
|
170084
170784
|
try {
|
|
170085
|
-
const require4 =
|
|
170785
|
+
const require4 = createRequire7(import.meta.url);
|
|
170086
170786
|
const piPackagePath = require4.resolve("@mariozechner/pi-coding-agent/package.json");
|
|
170087
|
-
const piPackageDir =
|
|
170088
|
-
packageJson = JSON.parse(
|
|
170787
|
+
const piPackageDir = dirname29(piPackagePath);
|
|
170788
|
+
packageJson = JSON.parse(readFileSync24(piPackagePath, "utf-8"));
|
|
170089
170789
|
for (const entry of ["dist", "docs", "examples", "README.md", "CHANGELOG.md"]) {
|
|
170090
170790
|
const source = join69(piPackageDir, entry);
|
|
170091
|
-
if (
|
|
170791
|
+
if (existsSync52(source)) {
|
|
170092
170792
|
symlinkSync3(source, join69(tmp, entry));
|
|
170093
170793
|
}
|
|
170094
170794
|
}
|
|
@@ -170107,8 +170807,8 @@ setInterval(() => {
|
|
|
170107
170807
|
performance3.clearMarks();
|
|
170108
170808
|
}, 3e4).unref();
|
|
170109
170809
|
function loadEnvFile(path5) {
|
|
170110
|
-
if (!
|
|
170111
|
-
const contents =
|
|
170810
|
+
if (!existsSync52(path5)) return;
|
|
170811
|
+
const contents = readFileSync24(path5, "utf-8");
|
|
170112
170812
|
for (const rawLine of contents.split(/\r?\n/)) {
|
|
170113
170813
|
const line = rawLine.trim();
|
|
170114
170814
|
if (!line || line.startsWith("#")) continue;
|
|
@@ -170419,8 +171119,36 @@ function getFlagValueNumber(args, flag) {
|
|
|
170419
171119
|
const parsed = Number(value);
|
|
170420
171120
|
return Number.isFinite(parsed) ? parsed : void 0;
|
|
170421
171121
|
}
|
|
171122
|
+
function readOwnCliVersion() {
|
|
171123
|
+
let currentDir;
|
|
171124
|
+
try {
|
|
171125
|
+
currentDir = dirname29(fileURLToPath11(import.meta.url));
|
|
171126
|
+
} catch {
|
|
171127
|
+
return void 0;
|
|
171128
|
+
}
|
|
171129
|
+
for (let i = 0; i < 8; i += 1) {
|
|
171130
|
+
const pkgPath = resolve41(currentDir, "package.json");
|
|
171131
|
+
if (existsSync52(pkgPath)) {
|
|
171132
|
+
try {
|
|
171133
|
+
const parsed = JSON.parse(readFileSync24(pkgPath, "utf-8"));
|
|
171134
|
+
if (parsed.name === "@runfusion/fusion" && typeof parsed.version === "string") {
|
|
171135
|
+
return parsed.version;
|
|
171136
|
+
}
|
|
171137
|
+
} catch {
|
|
171138
|
+
}
|
|
171139
|
+
}
|
|
171140
|
+
const parentDir = resolve41(currentDir, "..");
|
|
171141
|
+
if (parentDir === currentDir) break;
|
|
171142
|
+
currentDir = parentDir;
|
|
171143
|
+
}
|
|
171144
|
+
return void 0;
|
|
171145
|
+
}
|
|
170422
171146
|
async function main() {
|
|
170423
171147
|
const { cleanedArgs: args, projectName } = extractGlobalProjectFlag(process.argv.slice(2));
|
|
171148
|
+
if (args.includes("--version") || args.includes("-v")) {
|
|
171149
|
+
console.log(readOwnCliVersion() ?? "unknown");
|
|
171150
|
+
process.exit(0);
|
|
171151
|
+
}
|
|
170424
171152
|
if (args.includes("--help") || args.includes("-h")) {
|
|
170425
171153
|
console.log(HELP);
|
|
170426
171154
|
process.exit(0);
|