@n1creator/openacp-cli 2026.712.3 → 2026.712.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cli.js +776 -565
- package/dist/cli.js.map +1 -1
- package/dist/index.js +302 -215
- package/dist/index.js.map +1 -1
- package/dist/speech/transcribe_audio.sh +118 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -199,11 +199,11 @@ async function shutdownLogger() {
|
|
|
199
199
|
logDir = void 0;
|
|
200
200
|
initialized = false;
|
|
201
201
|
if (transport) {
|
|
202
|
-
await new Promise((
|
|
203
|
-
const timeout = setTimeout(
|
|
202
|
+
await new Promise((resolve8) => {
|
|
203
|
+
const timeout = setTimeout(resolve8, 3e3);
|
|
204
204
|
transport.on("close", () => {
|
|
205
205
|
clearTimeout(timeout);
|
|
206
|
-
|
|
206
|
+
resolve8();
|
|
207
207
|
});
|
|
208
208
|
transport.end();
|
|
209
209
|
});
|
|
@@ -345,21 +345,21 @@ function compareVersions(current, latest) {
|
|
|
345
345
|
}
|
|
346
346
|
async function runUpdate() {
|
|
347
347
|
const { spawn: spawn9 } = await import("child_process");
|
|
348
|
-
return new Promise((
|
|
348
|
+
return new Promise((resolve8) => {
|
|
349
349
|
const child = spawn9("npm", ["install", "-g", `${NPM_PACKAGE}@latest`], {
|
|
350
350
|
stdio: "inherit",
|
|
351
351
|
shell: false
|
|
352
352
|
});
|
|
353
353
|
const onSignal = () => {
|
|
354
354
|
child.kill("SIGTERM");
|
|
355
|
-
|
|
355
|
+
resolve8(false);
|
|
356
356
|
};
|
|
357
357
|
process.on("SIGINT", onSignal);
|
|
358
358
|
process.on("SIGTERM", onSignal);
|
|
359
359
|
child.on("close", (code) => {
|
|
360
360
|
process.off("SIGINT", onSignal);
|
|
361
361
|
process.off("SIGTERM", onSignal);
|
|
362
|
-
|
|
362
|
+
resolve8(code === 0);
|
|
363
363
|
});
|
|
364
364
|
});
|
|
365
365
|
}
|
|
@@ -4996,12 +4996,203 @@ var init_groq = __esm({
|
|
|
4996
4996
|
}
|
|
4997
4997
|
});
|
|
4998
4998
|
|
|
4999
|
+
// src/plugins/speech/providers/local-whisper.ts
|
|
5000
|
+
import { execFile } from "child_process";
|
|
5001
|
+
import { existsSync as existsSync2 } from "fs";
|
|
5002
|
+
import { mkdtemp, rm, writeFile } from "fs/promises";
|
|
5003
|
+
import { tmpdir } from "os";
|
|
5004
|
+
import path9 from "path";
|
|
5005
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
5006
|
+
import { promisify } from "util";
|
|
5007
|
+
function resolveLocalWhisperScriptPath() {
|
|
5008
|
+
const moduleDir = path9.dirname(fileURLToPath2(import.meta.url));
|
|
5009
|
+
const candidates = [
|
|
5010
|
+
path9.resolve(moduleDir, "../scripts/transcribe_audio.sh"),
|
|
5011
|
+
path9.resolve(moduleDir, "speech/transcribe_audio.sh")
|
|
5012
|
+
];
|
|
5013
|
+
return candidates.find(existsSync2) ?? candidates[0];
|
|
5014
|
+
}
|
|
5015
|
+
function mimeToExt2(mimeType) {
|
|
5016
|
+
const normalized = mimeType.split(";", 1)[0]?.trim().toLowerCase();
|
|
5017
|
+
const extensions = {
|
|
5018
|
+
"audio/ogg": ".ogg",
|
|
5019
|
+
"audio/opus": ".ogg",
|
|
5020
|
+
"audio/wav": ".wav",
|
|
5021
|
+
"audio/x-wav": ".wav",
|
|
5022
|
+
"audio/mpeg": ".mp3",
|
|
5023
|
+
"audio/mp3": ".mp3",
|
|
5024
|
+
"audio/mp4": ".m4a",
|
|
5025
|
+
"audio/aac": ".aac",
|
|
5026
|
+
"audio/webm": ".webm",
|
|
5027
|
+
"audio/flac": ".flac"
|
|
5028
|
+
};
|
|
5029
|
+
return normalized && extensions[normalized] || ".bin";
|
|
5030
|
+
}
|
|
5031
|
+
function parseMetadata(stderr) {
|
|
5032
|
+
const language = /\blanguage=([^\s]+)/.exec(stderr)?.[1];
|
|
5033
|
+
const durationRaw = /\bduration=([0-9.]+)s\b/.exec(stderr)?.[1];
|
|
5034
|
+
const duration = durationRaw ? Number(durationRaw) : void 0;
|
|
5035
|
+
return { language, duration: Number.isFinite(duration) ? duration : void 0 };
|
|
5036
|
+
}
|
|
5037
|
+
function formatExecError(error) {
|
|
5038
|
+
if (!(error instanceof Error)) return String(error);
|
|
5039
|
+
const execError = error;
|
|
5040
|
+
const details = [execError.stderr, execError.stdout].filter(Boolean).join("\n").trim();
|
|
5041
|
+
const code = execError.code === void 0 ? "" : ` (exit ${execError.code})`;
|
|
5042
|
+
return details ? `${error.message}${code}: ${details}` : `${error.message}${code}`;
|
|
5043
|
+
}
|
|
5044
|
+
var execFileAsync, LOCAL_WHISPER_PROVIDER, LOCAL_WHISPER_DEFAULTS, LocalWhisperSTT;
|
|
5045
|
+
var init_local_whisper = __esm({
|
|
5046
|
+
"src/plugins/speech/providers/local-whisper.ts"() {
|
|
5047
|
+
"use strict";
|
|
5048
|
+
execFileAsync = promisify(execFile);
|
|
5049
|
+
LOCAL_WHISPER_PROVIDER = "local-whisper";
|
|
5050
|
+
LOCAL_WHISPER_DEFAULTS = {
|
|
5051
|
+
language: "ru",
|
|
5052
|
+
model: "base",
|
|
5053
|
+
beamSize: 5,
|
|
5054
|
+
vadFilter: false,
|
|
5055
|
+
device: "cpu",
|
|
5056
|
+
computeType: "int8",
|
|
5057
|
+
timeoutMs: 12e4
|
|
5058
|
+
};
|
|
5059
|
+
LocalWhisperSTT = class {
|
|
5060
|
+
name = LOCAL_WHISPER_PROVIDER;
|
|
5061
|
+
config;
|
|
5062
|
+
constructor(options = {}) {
|
|
5063
|
+
this.config = {
|
|
5064
|
+
scriptPath: options.scriptPath ?? resolveLocalWhisperScriptPath(),
|
|
5065
|
+
language: options.language ?? LOCAL_WHISPER_DEFAULTS.language,
|
|
5066
|
+
model: options.model ?? LOCAL_WHISPER_DEFAULTS.model,
|
|
5067
|
+
beamSize: options.beamSize ?? LOCAL_WHISPER_DEFAULTS.beamSize,
|
|
5068
|
+
vadFilter: options.vadFilter ?? LOCAL_WHISPER_DEFAULTS.vadFilter,
|
|
5069
|
+
device: options.device ?? LOCAL_WHISPER_DEFAULTS.device,
|
|
5070
|
+
computeType: options.computeType ?? LOCAL_WHISPER_DEFAULTS.computeType,
|
|
5071
|
+
timeoutMs: options.timeoutMs ?? LOCAL_WHISPER_DEFAULTS.timeoutMs,
|
|
5072
|
+
tempRoot: options.tempRoot
|
|
5073
|
+
};
|
|
5074
|
+
}
|
|
5075
|
+
async transcribe(audioBuffer, mimeType, options) {
|
|
5076
|
+
const tempDir = await mkdtemp(path9.join(this.config.tempRoot ?? tmpdir(), "openacp-local-whisper-"));
|
|
5077
|
+
const audioPath = path9.join(tempDir, `input${mimeToExt2(mimeType)}`);
|
|
5078
|
+
try {
|
|
5079
|
+
await writeFile(audioPath, audioBuffer);
|
|
5080
|
+
const { stdout, stderr } = await execFileAsync(this.config.scriptPath, this.buildArgs(audioPath, options), {
|
|
5081
|
+
timeout: this.config.timeoutMs,
|
|
5082
|
+
maxBuffer: 10 * 1024 * 1024
|
|
5083
|
+
});
|
|
5084
|
+
const text5 = stdout.trim();
|
|
5085
|
+
if (!text5) throw new Error("Local Whisper returned an empty transcript");
|
|
5086
|
+
return { text: text5, ...parseMetadata(stderr) };
|
|
5087
|
+
} catch (error) {
|
|
5088
|
+
throw new Error(`Local Whisper STT failed: ${formatExecError(error)}`);
|
|
5089
|
+
} finally {
|
|
5090
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
5091
|
+
}
|
|
5092
|
+
}
|
|
5093
|
+
buildArgs(audioPath, options) {
|
|
5094
|
+
return [
|
|
5095
|
+
"--model",
|
|
5096
|
+
options?.model ?? this.config.model,
|
|
5097
|
+
"--language",
|
|
5098
|
+
options?.language ?? this.config.language,
|
|
5099
|
+
"--beam-size",
|
|
5100
|
+
String(this.config.beamSize),
|
|
5101
|
+
"--device",
|
|
5102
|
+
this.config.device,
|
|
5103
|
+
"--compute-type",
|
|
5104
|
+
this.config.computeType,
|
|
5105
|
+
this.config.vadFilter ? "--vad-filter" : "--no-vad-filter",
|
|
5106
|
+
audioPath
|
|
5107
|
+
];
|
|
5108
|
+
}
|
|
5109
|
+
};
|
|
5110
|
+
}
|
|
5111
|
+
});
|
|
5112
|
+
|
|
4999
5113
|
// src/plugins/speech/exports.ts
|
|
5000
5114
|
var init_exports = __esm({
|
|
5001
5115
|
"src/plugins/speech/exports.ts"() {
|
|
5002
5116
|
"use strict";
|
|
5003
5117
|
init_speech_service();
|
|
5004
5118
|
init_groq();
|
|
5119
|
+
init_local_whisper();
|
|
5120
|
+
}
|
|
5121
|
+
});
|
|
5122
|
+
|
|
5123
|
+
// src/plugins/speech/native-stt.ts
|
|
5124
|
+
function readLocalWhisperSettings(raw) {
|
|
5125
|
+
return {
|
|
5126
|
+
scriptPath: readString(raw.localWhisperScriptPath, resolveLocalWhisperScriptPath()),
|
|
5127
|
+
language: readString(raw.localWhisperLanguage, LOCAL_WHISPER_DEFAULTS.language),
|
|
5128
|
+
model: readString(raw.localWhisperModel, LOCAL_WHISPER_DEFAULTS.model),
|
|
5129
|
+
beamSize: readNumber(raw.localWhisperBeamSize, LOCAL_WHISPER_DEFAULTS.beamSize),
|
|
5130
|
+
vadFilter: readBoolean(raw.localWhisperVadFilter, LOCAL_WHISPER_DEFAULTS.vadFilter),
|
|
5131
|
+
device: readString(raw.localWhisperDevice, LOCAL_WHISPER_DEFAULTS.device),
|
|
5132
|
+
computeType: readString(raw.localWhisperComputeType, LOCAL_WHISPER_DEFAULTS.computeType),
|
|
5133
|
+
timeoutMs: readNumber(raw.localWhisperTimeoutMs, LOCAL_WHISPER_DEFAULTS.timeoutMs)
|
|
5134
|
+
};
|
|
5135
|
+
}
|
|
5136
|
+
function buildSpeechServiceConfig(raw) {
|
|
5137
|
+
const groqApiKey = readOptionalString(raw.groqApiKey);
|
|
5138
|
+
const requestedProvider = readOptionalString(raw.sttProvider);
|
|
5139
|
+
const provider = requestedProvider === LOCAL_WHISPER_PROVIDER ? LOCAL_WHISPER_PROVIDER : groqApiKey ? "groq" : null;
|
|
5140
|
+
const providers = {};
|
|
5141
|
+
if (groqApiKey) providers.groq = { apiKey: groqApiKey };
|
|
5142
|
+
if (provider === LOCAL_WHISPER_PROVIDER) {
|
|
5143
|
+
providers[LOCAL_WHISPER_PROVIDER] = {
|
|
5144
|
+
apiKey: "local",
|
|
5145
|
+
...readLocalWhisperSettings(raw)
|
|
5146
|
+
};
|
|
5147
|
+
}
|
|
5148
|
+
return {
|
|
5149
|
+
stt: { provider, providers },
|
|
5150
|
+
tts: {
|
|
5151
|
+
provider: readOptionalString(raw.ttsProvider) ?? "edge-tts",
|
|
5152
|
+
providers: {}
|
|
5153
|
+
}
|
|
5154
|
+
};
|
|
5155
|
+
}
|
|
5156
|
+
function createNativeSTTProviders(config) {
|
|
5157
|
+
const providers = /* @__PURE__ */ new Map();
|
|
5158
|
+
const groq = config.stt.providers.groq;
|
|
5159
|
+
if (groq?.apiKey) providers.set("groq", new GroqSTT(groq.apiKey, groq.model));
|
|
5160
|
+
const local = config.stt.providers[LOCAL_WHISPER_PROVIDER];
|
|
5161
|
+
if (local?.apiKey !== void 0) {
|
|
5162
|
+
providers.set(LOCAL_WHISPER_PROVIDER, new LocalWhisperSTT({
|
|
5163
|
+
scriptPath: readOptionalString(local.scriptPath),
|
|
5164
|
+
language: readOptionalString(local.language),
|
|
5165
|
+
model: readOptionalString(local.model),
|
|
5166
|
+
beamSize: readOptionalNumber(local.beamSize),
|
|
5167
|
+
vadFilter: typeof local.vadFilter === "boolean" ? local.vadFilter : void 0,
|
|
5168
|
+
device: readOptionalString(local.device),
|
|
5169
|
+
computeType: readOptionalString(local.computeType),
|
|
5170
|
+
timeoutMs: readOptionalNumber(local.timeoutMs)
|
|
5171
|
+
}));
|
|
5172
|
+
}
|
|
5173
|
+
return providers;
|
|
5174
|
+
}
|
|
5175
|
+
function readString(value, fallback) {
|
|
5176
|
+
return readOptionalString(value) ?? fallback;
|
|
5177
|
+
}
|
|
5178
|
+
function readOptionalString(value) {
|
|
5179
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
5180
|
+
}
|
|
5181
|
+
function readNumber(value, fallback) {
|
|
5182
|
+
return readOptionalNumber(value) ?? fallback;
|
|
5183
|
+
}
|
|
5184
|
+
function readOptionalNumber(value) {
|
|
5185
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
5186
|
+
}
|
|
5187
|
+
function readBoolean(value, fallback) {
|
|
5188
|
+
return typeof value === "boolean" ? value : fallback;
|
|
5189
|
+
}
|
|
5190
|
+
var init_native_stt = __esm({
|
|
5191
|
+
"src/plugins/speech/native-stt.ts"() {
|
|
5192
|
+
"use strict";
|
|
5193
|
+
init_groq();
|
|
5194
|
+
init_local_whisper();
|
|
5195
|
+
init_local_whisper();
|
|
5005
5196
|
}
|
|
5006
5197
|
});
|
|
5007
5198
|
|
|
@@ -5011,14 +5202,14 @@ __export(plugin_installer_exports, {
|
|
|
5011
5202
|
importFromDir: () => importFromDir,
|
|
5012
5203
|
installNpmPlugin: () => installNpmPlugin
|
|
5013
5204
|
});
|
|
5014
|
-
import { execFile } from "child_process";
|
|
5015
|
-
import { promisify } from "util";
|
|
5205
|
+
import { execFile as execFile2 } from "child_process";
|
|
5206
|
+
import { promisify as promisify2 } from "util";
|
|
5016
5207
|
import * as fs8 from "fs/promises";
|
|
5017
|
-
import * as
|
|
5208
|
+
import * as path10 from "path";
|
|
5018
5209
|
import { pathToFileURL } from "url";
|
|
5019
5210
|
async function importFromDir(packageName, dir) {
|
|
5020
|
-
const pkgDir =
|
|
5021
|
-
const pkgJsonPath =
|
|
5211
|
+
const pkgDir = path10.join(dir, "node_modules", ...packageName.split("/"));
|
|
5212
|
+
const pkgJsonPath = path10.join(pkgDir, "package.json");
|
|
5022
5213
|
let pkgJson;
|
|
5023
5214
|
try {
|
|
5024
5215
|
pkgJson = JSON.parse(await fs8.readFile(pkgJsonPath, "utf-8"));
|
|
@@ -5034,7 +5225,7 @@ async function importFromDir(packageName, dir) {
|
|
|
5034
5225
|
} else {
|
|
5035
5226
|
entry = pkgJson.main ?? "index.js";
|
|
5036
5227
|
}
|
|
5037
|
-
const entryPath =
|
|
5228
|
+
const entryPath = path10.join(pkgDir, entry);
|
|
5038
5229
|
try {
|
|
5039
5230
|
await fs8.access(entryPath);
|
|
5040
5231
|
} catch {
|
|
@@ -5051,16 +5242,16 @@ async function installNpmPlugin(packageName, pluginsDir) {
|
|
|
5051
5242
|
return await importFromDir(packageName, dir);
|
|
5052
5243
|
} catch {
|
|
5053
5244
|
}
|
|
5054
|
-
await
|
|
5245
|
+
await execFileAsync2("npm", ["install", packageName, "--prefix", dir, "--save", "--ignore-scripts"], {
|
|
5055
5246
|
timeout: 6e4
|
|
5056
5247
|
});
|
|
5057
5248
|
return await importFromDir(packageName, dir);
|
|
5058
5249
|
}
|
|
5059
|
-
var
|
|
5250
|
+
var execFileAsync2, VALID_NPM_NAME;
|
|
5060
5251
|
var init_plugin_installer = __esm({
|
|
5061
5252
|
"src/core/plugin/plugin-installer.ts"() {
|
|
5062
5253
|
"use strict";
|
|
5063
|
-
|
|
5254
|
+
execFileAsync2 = promisify2(execFile2);
|
|
5064
5255
|
VALID_NPM_NAME = /^(@[a-z0-9][\w.-]*\/)?[a-z0-9][\w.-]*(@[\w.^~>=<|-]+)?$/i;
|
|
5065
5256
|
}
|
|
5066
5257
|
});
|
|
@@ -5070,12 +5261,13 @@ var speech_exports = {};
|
|
|
5070
5261
|
__export(speech_exports, {
|
|
5071
5262
|
default: () => speech_default
|
|
5072
5263
|
});
|
|
5073
|
-
import
|
|
5264
|
+
import path11 from "path";
|
|
5074
5265
|
var EDGE_TTS_PLUGIN, speechPlugin, speech_default;
|
|
5075
5266
|
var init_speech = __esm({
|
|
5076
5267
|
"src/plugins/speech/index.ts"() {
|
|
5077
5268
|
"use strict";
|
|
5078
5269
|
init_exports();
|
|
5270
|
+
init_native_stt();
|
|
5079
5271
|
init_plugin_installer();
|
|
5080
5272
|
EDGE_TTS_PLUGIN = "@openacp/msedge-tts-plugin";
|
|
5081
5273
|
speechPlugin = {
|
|
@@ -5089,17 +5281,22 @@ var init_speech = __esm({
|
|
|
5089
5281
|
inheritableKeys: ["ttsProvider", "ttsVoice"],
|
|
5090
5282
|
async install(ctx) {
|
|
5091
5283
|
const { terminal, settings } = ctx;
|
|
5092
|
-
const pluginsDir = ctx.instanceRoot ?
|
|
5284
|
+
const pluginsDir = ctx.instanceRoot ? path11.join(ctx.instanceRoot, "plugins") : void 0;
|
|
5093
5285
|
const enableStt = await terminal.confirm({
|
|
5094
5286
|
message: "Enable speech-to-text (STT)?",
|
|
5095
5287
|
initialValue: false
|
|
5096
5288
|
});
|
|
5097
5289
|
let sttProvider = null;
|
|
5098
5290
|
let groqApiKey = "";
|
|
5291
|
+
let localWhisperLanguage = LOCAL_WHISPER_DEFAULTS.language;
|
|
5292
|
+
let localWhisperModel = LOCAL_WHISPER_DEFAULTS.model;
|
|
5099
5293
|
if (enableStt) {
|
|
5100
5294
|
sttProvider = await terminal.select({
|
|
5101
5295
|
message: "STT provider:",
|
|
5102
|
-
options: [
|
|
5296
|
+
options: [
|
|
5297
|
+
{ value: LOCAL_WHISPER_PROVIDER, label: "Local faster-whisper", hint: "Private and offline after the first model download" },
|
|
5298
|
+
{ value: "groq", label: "Groq (Whisper)", hint: "Hosted API, requires an API key" }
|
|
5299
|
+
]
|
|
5103
5300
|
});
|
|
5104
5301
|
if (sttProvider === "groq") {
|
|
5105
5302
|
groqApiKey = await terminal.text({
|
|
@@ -5107,6 +5304,15 @@ var init_speech = __esm({
|
|
|
5107
5304
|
validate: (v) => !v.trim() ? "API key cannot be empty" : void 0
|
|
5108
5305
|
});
|
|
5109
5306
|
groqApiKey = groqApiKey.trim();
|
|
5307
|
+
} else {
|
|
5308
|
+
localWhisperLanguage = (await terminal.text({
|
|
5309
|
+
message: "Local Whisper language:",
|
|
5310
|
+
defaultValue: LOCAL_WHISPER_DEFAULTS.language
|
|
5311
|
+
})).trim() || LOCAL_WHISPER_DEFAULTS.language;
|
|
5312
|
+
localWhisperModel = (await terminal.text({
|
|
5313
|
+
message: "Local Whisper model:",
|
|
5314
|
+
defaultValue: LOCAL_WHISPER_DEFAULTS.model
|
|
5315
|
+
})).trim() || LOCAL_WHISPER_DEFAULTS.model;
|
|
5110
5316
|
}
|
|
5111
5317
|
}
|
|
5112
5318
|
const ttsProvider = await terminal.select({
|
|
@@ -5134,6 +5340,13 @@ var init_speech = __esm({
|
|
|
5134
5340
|
await settings.setAll({
|
|
5135
5341
|
sttProvider,
|
|
5136
5342
|
groqApiKey,
|
|
5343
|
+
localWhisperLanguage,
|
|
5344
|
+
localWhisperModel,
|
|
5345
|
+
localWhisperBeamSize: LOCAL_WHISPER_DEFAULTS.beamSize,
|
|
5346
|
+
localWhisperVadFilter: LOCAL_WHISPER_DEFAULTS.vadFilter,
|
|
5347
|
+
localWhisperDevice: LOCAL_WHISPER_DEFAULTS.device,
|
|
5348
|
+
localWhisperComputeType: LOCAL_WHISPER_DEFAULTS.computeType,
|
|
5349
|
+
localWhisperTimeoutMs: LOCAL_WHISPER_DEFAULTS.timeoutMs,
|
|
5137
5350
|
ttsProvider: ttsProvider === "none" ? null : ttsProvider,
|
|
5138
5351
|
ttsVoice
|
|
5139
5352
|
});
|
|
@@ -5151,13 +5364,34 @@ var init_speech = __esm({
|
|
|
5151
5364
|
]
|
|
5152
5365
|
});
|
|
5153
5366
|
if (choice === "stt") {
|
|
5154
|
-
const
|
|
5155
|
-
message: "
|
|
5156
|
-
|
|
5367
|
+
const provider = await terminal.select({
|
|
5368
|
+
message: "STT provider:",
|
|
5369
|
+
options: [
|
|
5370
|
+
{ value: LOCAL_WHISPER_PROVIDER, label: "Local faster-whisper", hint: "Private and offline after the first model download" },
|
|
5371
|
+
{ value: "groq", label: "Groq (Whisper)", hint: "Hosted API, requires an API key" },
|
|
5372
|
+
{ value: "none", label: "None (disable STT)" }
|
|
5373
|
+
]
|
|
5157
5374
|
});
|
|
5158
|
-
|
|
5159
|
-
|
|
5160
|
-
|
|
5375
|
+
await settings.set("sttProvider", provider === "none" ? null : provider);
|
|
5376
|
+
if (provider === "groq") {
|
|
5377
|
+
const key = await terminal.text({
|
|
5378
|
+
message: "Groq API key:",
|
|
5379
|
+
defaultValue: current.groqApiKey ?? "",
|
|
5380
|
+
validate: (v) => !v.trim() ? "API key cannot be empty" : void 0
|
|
5381
|
+
});
|
|
5382
|
+
await settings.set("groqApiKey", key.trim());
|
|
5383
|
+
} else if (provider === LOCAL_WHISPER_PROVIDER) {
|
|
5384
|
+
const language = await terminal.text({
|
|
5385
|
+
message: "Local Whisper language:",
|
|
5386
|
+
defaultValue: current.localWhisperLanguage ?? LOCAL_WHISPER_DEFAULTS.language
|
|
5387
|
+
});
|
|
5388
|
+
const model = await terminal.text({
|
|
5389
|
+
message: "Local Whisper model:",
|
|
5390
|
+
defaultValue: current.localWhisperModel ?? LOCAL_WHISPER_DEFAULTS.model
|
|
5391
|
+
});
|
|
5392
|
+
await settings.set("localWhisperLanguage", language.trim() || LOCAL_WHISPER_DEFAULTS.language);
|
|
5393
|
+
await settings.set("localWhisperModel", model.trim() || LOCAL_WHISPER_DEFAULTS.model);
|
|
5394
|
+
}
|
|
5161
5395
|
terminal.log.success("STT settings updated");
|
|
5162
5396
|
} else if (choice === "tts") {
|
|
5163
5397
|
const voice = await terminal.text({
|
|
@@ -5176,37 +5410,26 @@ var init_speech = __esm({
|
|
|
5176
5410
|
},
|
|
5177
5411
|
async setup(ctx) {
|
|
5178
5412
|
ctx.registerEditableFields([
|
|
5179
|
-
{ key: "sttProvider", displayName: "Speech to Text", type: "select", scope: "safe", hotReload: true, options: ["groq"] },
|
|
5180
|
-
{ key: "groqApiKey", displayName: "STT API Key", type: "string", scope: "sensitive", hotReload: true },
|
|
5413
|
+
{ key: "sttProvider", displayName: "Speech to Text", type: "select", scope: "safe", hotReload: true, options: [LOCAL_WHISPER_PROVIDER, "groq"] },
|
|
5414
|
+
{ key: "groqApiKey", displayName: "Groq STT API Key", type: "string", scope: "sensitive", hotReload: true },
|
|
5415
|
+
{ key: "localWhisperLanguage", displayName: "Local Whisper Language", type: "string", scope: "safe", hotReload: true },
|
|
5416
|
+
{ key: "localWhisperModel", displayName: "Local Whisper Model", type: "string", scope: "safe", hotReload: true },
|
|
5417
|
+
{ key: "localWhisperBeamSize", displayName: "Local Whisper Beam Size", type: "number", scope: "safe", hotReload: true },
|
|
5418
|
+
{ key: "localWhisperVadFilter", displayName: "Local Whisper VAD Filter", type: "toggle", scope: "safe", hotReload: true },
|
|
5419
|
+
{ key: "localWhisperDevice", displayName: "Local Whisper Device", type: "select", scope: "safe", hotReload: true, options: ["cpu", "cuda", "auto"] },
|
|
5420
|
+
{ key: "localWhisperComputeType", displayName: "Local Whisper Compute Type", type: "string", scope: "safe", hotReload: true },
|
|
5421
|
+
{ key: "localWhisperTimeoutMs", displayName: "Local Whisper Timeout (ms)", type: "number", scope: "safe", hotReload: true },
|
|
5422
|
+
{ key: "localWhisperScriptPath", displayName: "Local Whisper Script Path", type: "string", scope: "safe", hotReload: true },
|
|
5181
5423
|
{ key: "ttsProvider", displayName: "Text to Speech", type: "select", scope: "safe", hotReload: true, options: ["edge-tts"] }
|
|
5182
5424
|
]);
|
|
5183
|
-
const pluginsDir = ctx.instanceRoot ?
|
|
5425
|
+
const pluginsDir = ctx.instanceRoot ? path11.join(ctx.instanceRoot, "plugins") : void 0;
|
|
5184
5426
|
const config = ctx.pluginConfig;
|
|
5185
|
-
const
|
|
5186
|
-
const sttProvider = groqApiKey ? "groq" : null;
|
|
5187
|
-
const speechConfig = {
|
|
5188
|
-
stt: {
|
|
5189
|
-
provider: sttProvider,
|
|
5190
|
-
providers: groqApiKey ? { groq: { apiKey: groqApiKey } } : {}
|
|
5191
|
-
},
|
|
5192
|
-
tts: {
|
|
5193
|
-
provider: config.ttsProvider ?? "edge-tts",
|
|
5194
|
-
providers: {}
|
|
5195
|
-
}
|
|
5196
|
-
};
|
|
5427
|
+
const speechConfig = buildSpeechServiceConfig(config);
|
|
5197
5428
|
const service = new SpeechService(speechConfig);
|
|
5198
|
-
|
|
5199
|
-
service.registerSTTProvider(
|
|
5429
|
+
for (const [name, provider] of createNativeSTTProviders(speechConfig)) {
|
|
5430
|
+
service.registerSTTProvider(name, provider);
|
|
5200
5431
|
}
|
|
5201
|
-
service.setProviderFactory((cfg) => {
|
|
5202
|
-
const sttMap = /* @__PURE__ */ new Map();
|
|
5203
|
-
const ttsMap = /* @__PURE__ */ new Map();
|
|
5204
|
-
const groqCfg = cfg.stt?.providers?.groq;
|
|
5205
|
-
if (groqCfg?.apiKey) {
|
|
5206
|
-
sttMap.set("groq", new GroqSTT(groqCfg.apiKey, groqCfg.model));
|
|
5207
|
-
}
|
|
5208
|
-
return { stt: sttMap, tts: ttsMap };
|
|
5209
|
-
});
|
|
5432
|
+
service.setProviderFactory((cfg) => ({ stt: createNativeSTTProviders(cfg), tts: /* @__PURE__ */ new Map() }));
|
|
5210
5433
|
ctx.registerService("speech", service);
|
|
5211
5434
|
const setSessionVoiceMode = (pluginCtx, sessionId, voiceMode) => {
|
|
5212
5435
|
if (!sessionId) return;
|
|
@@ -5534,7 +5757,7 @@ __export(agent_dependencies_exports, {
|
|
|
5534
5757
|
});
|
|
5535
5758
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
5536
5759
|
import * as fs9 from "fs";
|
|
5537
|
-
import * as
|
|
5760
|
+
import * as path12 from "path";
|
|
5538
5761
|
function getAgentSetup(registryId) {
|
|
5539
5762
|
return AGENT_SETUP[registryId];
|
|
5540
5763
|
}
|
|
@@ -5558,9 +5781,9 @@ function commandExists(cmd) {
|
|
|
5558
5781
|
}
|
|
5559
5782
|
let dir = process.cwd();
|
|
5560
5783
|
while (true) {
|
|
5561
|
-
const binPath =
|
|
5784
|
+
const binPath = path12.join(dir, "node_modules", ".bin", cmd);
|
|
5562
5785
|
if (fs9.existsSync(binPath)) return true;
|
|
5563
|
-
const parent =
|
|
5786
|
+
const parent = path12.dirname(dir);
|
|
5564
5787
|
if (parent === dir) break;
|
|
5565
5788
|
dir = parent;
|
|
5566
5789
|
}
|
|
@@ -5826,7 +6049,7 @@ var init_agent_dependencies = __esm({
|
|
|
5826
6049
|
|
|
5827
6050
|
// src/core/agents/agent-installer.ts
|
|
5828
6051
|
import * as fs10 from "fs";
|
|
5829
|
-
import * as
|
|
6052
|
+
import * as path13 from "path";
|
|
5830
6053
|
import * as os2 from "os";
|
|
5831
6054
|
import crypto2 from "crypto";
|
|
5832
6055
|
function validateArchiveContents(entries, destDir) {
|
|
@@ -5841,9 +6064,9 @@ function validateArchiveContents(entries, destDir) {
|
|
|
5841
6064
|
}
|
|
5842
6065
|
}
|
|
5843
6066
|
function validateUninstallPath(binaryPath, agentsDir) {
|
|
5844
|
-
const realPath =
|
|
5845
|
-
const realAgentsDir =
|
|
5846
|
-
if (!realPath.startsWith(realAgentsDir +
|
|
6067
|
+
const realPath = path13.resolve(binaryPath);
|
|
6068
|
+
const realAgentsDir = path13.resolve(agentsDir);
|
|
6069
|
+
if (!realPath.startsWith(realAgentsDir + path13.sep) && realPath !== realAgentsDir) {
|
|
5847
6070
|
throw new Error(`Refusing to delete path outside agents directory: ${realPath}`);
|
|
5848
6071
|
}
|
|
5849
6072
|
}
|
|
@@ -5897,7 +6120,7 @@ function buildInstalledAgent(registryId, name, version, dist, binaryPath) {
|
|
|
5897
6120
|
binaryPath: null
|
|
5898
6121
|
};
|
|
5899
6122
|
}
|
|
5900
|
-
const absCmd =
|
|
6123
|
+
const absCmd = path13.resolve(binaryPath, dist.cmd);
|
|
5901
6124
|
return {
|
|
5902
6125
|
registryId,
|
|
5903
6126
|
name,
|
|
@@ -5963,7 +6186,7 @@ Install it with: pip install uv`;
|
|
|
5963
6186
|
return { ok: true, agentKey, setupSteps: setupSteps.length > 0 ? setupSteps : void 0 };
|
|
5964
6187
|
}
|
|
5965
6188
|
async function downloadAndExtract(agentId, archiveUrl, progress, agentsDir) {
|
|
5966
|
-
const destDir =
|
|
6189
|
+
const destDir = path13.join(agentsDir ?? DEFAULT_AGENTS_DIR, agentId);
|
|
5967
6190
|
fs10.mkdirSync(destDir, { recursive: true });
|
|
5968
6191
|
await progress?.onStep("Downloading...");
|
|
5969
6192
|
log2.info({ agentId, url: archiveUrl }, "Downloading agent binary");
|
|
@@ -6010,15 +6233,15 @@ function validateExtractedPaths(destDir) {
|
|
|
6010
6233
|
for (const entry of entries) {
|
|
6011
6234
|
const dirent = entry;
|
|
6012
6235
|
const parentPath = dirent.parentPath ?? dirent.path ?? destDir;
|
|
6013
|
-
const fullPath =
|
|
6236
|
+
const fullPath = path13.join(parentPath, entry.name);
|
|
6014
6237
|
let realPath;
|
|
6015
6238
|
try {
|
|
6016
6239
|
realPath = fs10.realpathSync(fullPath);
|
|
6017
6240
|
} catch {
|
|
6018
6241
|
const linkTarget = fs10.readlinkSync(fullPath);
|
|
6019
|
-
realPath =
|
|
6242
|
+
realPath = path13.resolve(path13.dirname(fullPath), linkTarget);
|
|
6020
6243
|
}
|
|
6021
|
-
if (!realPath.startsWith(realDest +
|
|
6244
|
+
if (!realPath.startsWith(realDest + path13.sep) && realPath !== realDest) {
|
|
6022
6245
|
fs10.rmSync(destDir, { recursive: true, force: true });
|
|
6023
6246
|
throw new Error(`Archive contains unsafe path: ${entry.name}`);
|
|
6024
6247
|
}
|
|
@@ -6026,7 +6249,7 @@ function validateExtractedPaths(destDir) {
|
|
|
6026
6249
|
}
|
|
6027
6250
|
async function extractTarGz(buffer, destDir) {
|
|
6028
6251
|
const { execFileSync: execFileSync9 } = await import("child_process");
|
|
6029
|
-
const tmpFile =
|
|
6252
|
+
const tmpFile = path13.join(destDir, "_archive.tar.gz");
|
|
6030
6253
|
fs10.writeFileSync(tmpFile, buffer);
|
|
6031
6254
|
try {
|
|
6032
6255
|
const listing = execFileSync9("tar", ["tf", tmpFile], { stdio: "pipe" }).toString().trim().split("\n").filter(Boolean);
|
|
@@ -6039,7 +6262,7 @@ async function extractTarGz(buffer, destDir) {
|
|
|
6039
6262
|
}
|
|
6040
6263
|
async function extractZip(buffer, destDir) {
|
|
6041
6264
|
const { execFileSync: execFileSync9 } = await import("child_process");
|
|
6042
|
-
const tmpFile =
|
|
6265
|
+
const tmpFile = path13.join(destDir, "_archive.zip");
|
|
6043
6266
|
fs10.writeFileSync(tmpFile, buffer);
|
|
6044
6267
|
try {
|
|
6045
6268
|
const listing = execFileSync9("unzip", ["-l", tmpFile], { stdio: "pipe" }).toString().trim().split("\n").filter(Boolean);
|
|
@@ -6068,7 +6291,7 @@ var init_agent_installer = __esm({
|
|
|
6068
6291
|
init_log();
|
|
6069
6292
|
init_agent_dependencies();
|
|
6070
6293
|
log2 = createChildLogger({ module: "agent-installer" });
|
|
6071
|
-
DEFAULT_AGENTS_DIR =
|
|
6294
|
+
DEFAULT_AGENTS_DIR = path13.join(os2.homedir(), ".openacp", "agents");
|
|
6072
6295
|
MAX_DOWNLOAD_SIZE = 500 * 1024 * 1024;
|
|
6073
6296
|
validateTarContents = validateArchiveContents;
|
|
6074
6297
|
ARCH_MAP = {
|
|
@@ -6085,12 +6308,12 @@ var init_agent_installer = __esm({
|
|
|
6085
6308
|
|
|
6086
6309
|
// src/core/utils/install-binary.ts
|
|
6087
6310
|
import fs11 from "fs";
|
|
6088
|
-
import
|
|
6311
|
+
import path14 from "path";
|
|
6089
6312
|
import https from "https";
|
|
6090
6313
|
import os3 from "os";
|
|
6091
6314
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
6092
6315
|
function downloadFile(url, dest, maxRedirects = 10) {
|
|
6093
|
-
return new Promise((
|
|
6316
|
+
return new Promise((resolve8, reject) => {
|
|
6094
6317
|
const file = fs11.createWriteStream(dest);
|
|
6095
6318
|
const cleanup = () => {
|
|
6096
6319
|
try {
|
|
@@ -6109,7 +6332,7 @@ function downloadFile(url, dest, maxRedirects = 10) {
|
|
|
6109
6332
|
}
|
|
6110
6333
|
file.close(() => {
|
|
6111
6334
|
cleanup();
|
|
6112
|
-
downloadFile(response.headers.location, dest, maxRedirects - 1).then(
|
|
6335
|
+
downloadFile(response.headers.location, dest, maxRedirects - 1).then(resolve8).catch(reject);
|
|
6113
6336
|
});
|
|
6114
6337
|
return;
|
|
6115
6338
|
}
|
|
@@ -6133,7 +6356,7 @@ function downloadFile(url, dest, maxRedirects = 10) {
|
|
|
6133
6356
|
}
|
|
6134
6357
|
});
|
|
6135
6358
|
response.pipe(file);
|
|
6136
|
-
file.on("finish", () => file.close(() =>
|
|
6359
|
+
file.on("finish", () => file.close(() => resolve8(dest)));
|
|
6137
6360
|
file.on("error", (err) => {
|
|
6138
6361
|
file.close(() => {
|
|
6139
6362
|
cleanup();
|
|
@@ -6160,7 +6383,7 @@ function getDownloadUrl(spec) {
|
|
|
6160
6383
|
async function ensureBinary(spec, binDir) {
|
|
6161
6384
|
const resolvedBinDir = binDir ?? DEFAULT_BIN_DIR;
|
|
6162
6385
|
const binName = IS_WINDOWS ? `${spec.name}.exe` : spec.name;
|
|
6163
|
-
const binPath =
|
|
6386
|
+
const binPath = path14.join(resolvedBinDir, binName);
|
|
6164
6387
|
if (commandExists(spec.name)) {
|
|
6165
6388
|
log3.debug({ name: spec.name }, "Found in PATH");
|
|
6166
6389
|
return spec.name;
|
|
@@ -6174,7 +6397,7 @@ async function ensureBinary(spec, binDir) {
|
|
|
6174
6397
|
fs11.mkdirSync(resolvedBinDir, { recursive: true });
|
|
6175
6398
|
const url = getDownloadUrl(spec);
|
|
6176
6399
|
const isArchive = spec.isArchive?.(url) ?? false;
|
|
6177
|
-
const downloadDest = isArchive ?
|
|
6400
|
+
const downloadDest = isArchive ? path14.join(resolvedBinDir, `${spec.name}.tgz`) : binPath;
|
|
6178
6401
|
await downloadFile(url, downloadDest);
|
|
6179
6402
|
if (isArchive) {
|
|
6180
6403
|
const listing = execFileSync3("tar", ["-tf", downloadDest], { stdio: "pipe" }).toString().trim().split("\n").filter(Boolean);
|
|
@@ -6202,7 +6425,7 @@ var init_install_binary = __esm({
|
|
|
6202
6425
|
init_agent_dependencies();
|
|
6203
6426
|
init_agent_installer();
|
|
6204
6427
|
log3 = createChildLogger({ module: "binary-installer" });
|
|
6205
|
-
DEFAULT_BIN_DIR =
|
|
6428
|
+
DEFAULT_BIN_DIR = path14.join(os3.homedir(), ".openacp", "bin");
|
|
6206
6429
|
IS_WINDOWS = os3.platform() === "win32";
|
|
6207
6430
|
}
|
|
6208
6431
|
});
|
|
@@ -6245,7 +6468,7 @@ var init_install_cloudflared = __esm({
|
|
|
6245
6468
|
// src/plugins/tunnel/providers/cloudflare.ts
|
|
6246
6469
|
import { spawn } from "child_process";
|
|
6247
6470
|
import fs12 from "fs";
|
|
6248
|
-
import
|
|
6471
|
+
import path15 from "path";
|
|
6249
6472
|
var log4, SIGKILL_TIMEOUT_MS, CloudflareTunnelProvider;
|
|
6250
6473
|
var init_cloudflare = __esm({
|
|
6251
6474
|
"src/plugins/tunnel/providers/cloudflare.ts"() {
|
|
@@ -6282,7 +6505,7 @@ var init_cloudflare = __esm({
|
|
|
6282
6505
|
if (this.options.domain) {
|
|
6283
6506
|
args2.push("--hostname", String(this.options.domain));
|
|
6284
6507
|
}
|
|
6285
|
-
return new Promise((
|
|
6508
|
+
return new Promise((resolve8, reject) => {
|
|
6286
6509
|
let settled = false;
|
|
6287
6510
|
const settle = (fn) => {
|
|
6288
6511
|
if (!settled) {
|
|
@@ -6310,7 +6533,7 @@ var init_cloudflare = __esm({
|
|
|
6310
6533
|
clearTimeout(timeout);
|
|
6311
6534
|
this.publicUrl = match[0];
|
|
6312
6535
|
log4.info({ url: this.publicUrl }, "Cloudflare tunnel ready");
|
|
6313
|
-
settle(() =>
|
|
6536
|
+
settle(() => resolve8(this.publicUrl));
|
|
6314
6537
|
}
|
|
6315
6538
|
};
|
|
6316
6539
|
this.child.stdout?.on("data", onData);
|
|
@@ -6343,8 +6566,8 @@ var init_cloudflare = __esm({
|
|
|
6343
6566
|
}
|
|
6344
6567
|
child.kill("SIGTERM");
|
|
6345
6568
|
const exited = await Promise.race([
|
|
6346
|
-
new Promise((
|
|
6347
|
-
new Promise((
|
|
6569
|
+
new Promise((resolve8) => child.on("exit", () => resolve8(true))),
|
|
6570
|
+
new Promise((resolve8) => setTimeout(() => resolve8(false), SIGKILL_TIMEOUT_MS))
|
|
6348
6571
|
]);
|
|
6349
6572
|
if (!exited) {
|
|
6350
6573
|
log4.warn("cloudflared did not exit after SIGTERM, sending SIGKILL");
|
|
@@ -6357,7 +6580,7 @@ var init_cloudflare = __esm({
|
|
|
6357
6580
|
}
|
|
6358
6581
|
findBinary() {
|
|
6359
6582
|
if (commandExists("cloudflared")) return "cloudflared";
|
|
6360
|
-
const binPath =
|
|
6583
|
+
const binPath = path15.join(this.binDir, "cloudflared");
|
|
6361
6584
|
if (fs12.existsSync(binPath)) return binPath;
|
|
6362
6585
|
return null;
|
|
6363
6586
|
}
|
|
@@ -6397,7 +6620,7 @@ var init_ngrok = __esm({
|
|
|
6397
6620
|
if (this.options.region) {
|
|
6398
6621
|
args2.push("--region", String(this.options.region));
|
|
6399
6622
|
}
|
|
6400
|
-
return new Promise((
|
|
6623
|
+
return new Promise((resolve8, reject) => {
|
|
6401
6624
|
let settled = false;
|
|
6402
6625
|
const settle = (fn) => {
|
|
6403
6626
|
if (!settled) {
|
|
@@ -6427,7 +6650,7 @@ var init_ngrok = __esm({
|
|
|
6427
6650
|
clearTimeout(timeout);
|
|
6428
6651
|
this.publicUrl = match[0];
|
|
6429
6652
|
log5.info({ url: this.publicUrl }, "ngrok tunnel ready");
|
|
6430
|
-
settle(() =>
|
|
6653
|
+
settle(() => resolve8(this.publicUrl));
|
|
6431
6654
|
}
|
|
6432
6655
|
};
|
|
6433
6656
|
this.child.stdout?.on("data", onData);
|
|
@@ -6462,8 +6685,8 @@ var init_ngrok = __esm({
|
|
|
6462
6685
|
}
|
|
6463
6686
|
child.kill("SIGTERM");
|
|
6464
6687
|
const exited = await Promise.race([
|
|
6465
|
-
new Promise((
|
|
6466
|
-
new Promise((
|
|
6688
|
+
new Promise((resolve8) => child.on("exit", () => resolve8(true))),
|
|
6689
|
+
new Promise((resolve8) => setTimeout(() => resolve8(false), SIGKILL_TIMEOUT_MS2))
|
|
6467
6690
|
]);
|
|
6468
6691
|
if (!exited) {
|
|
6469
6692
|
log5.warn("ngrok did not exit after SIGTERM, sending SIGKILL");
|
|
@@ -6507,7 +6730,7 @@ var init_bore = __esm({
|
|
|
6507
6730
|
if (this.options.secret) {
|
|
6508
6731
|
args2.push("--secret", String(this.options.secret));
|
|
6509
6732
|
}
|
|
6510
|
-
return new Promise((
|
|
6733
|
+
return new Promise((resolve8, reject) => {
|
|
6511
6734
|
let settled = false;
|
|
6512
6735
|
const settle = (fn) => {
|
|
6513
6736
|
if (!settled) {
|
|
@@ -6537,7 +6760,7 @@ var init_bore = __esm({
|
|
|
6537
6760
|
clearTimeout(timeout);
|
|
6538
6761
|
this.publicUrl = `http://${match[1]}:${match[2]}`;
|
|
6539
6762
|
log6.info({ url: this.publicUrl }, "Bore tunnel ready");
|
|
6540
|
-
settle(() =>
|
|
6763
|
+
settle(() => resolve8(this.publicUrl));
|
|
6541
6764
|
}
|
|
6542
6765
|
};
|
|
6543
6766
|
this.child.stdout?.on("data", onData);
|
|
@@ -6572,8 +6795,8 @@ var init_bore = __esm({
|
|
|
6572
6795
|
}
|
|
6573
6796
|
child.kill("SIGTERM");
|
|
6574
6797
|
const exited = await Promise.race([
|
|
6575
|
-
new Promise((
|
|
6576
|
-
new Promise((
|
|
6798
|
+
new Promise((resolve8) => child.on("exit", () => resolve8(true))),
|
|
6799
|
+
new Promise((resolve8) => setTimeout(() => resolve8(false), SIGKILL_TIMEOUT_MS3))
|
|
6577
6800
|
]);
|
|
6578
6801
|
if (!exited) {
|
|
6579
6802
|
log6.warn("bore did not exit after SIGTERM, sending SIGKILL");
|
|
@@ -6622,7 +6845,7 @@ var init_tailscale = __esm({
|
|
|
6622
6845
|
if (this.options.bg) {
|
|
6623
6846
|
args2.push("--bg");
|
|
6624
6847
|
}
|
|
6625
|
-
return new Promise((
|
|
6848
|
+
return new Promise((resolve8, reject) => {
|
|
6626
6849
|
let settled = false;
|
|
6627
6850
|
const settle = (fn) => {
|
|
6628
6851
|
if (!settled) {
|
|
@@ -6652,7 +6875,7 @@ var init_tailscale = __esm({
|
|
|
6652
6875
|
clearTimeout(timeout);
|
|
6653
6876
|
this.publicUrl = match[0];
|
|
6654
6877
|
log7.info({ url: this.publicUrl }, "Tailscale funnel ready");
|
|
6655
|
-
settle(() =>
|
|
6878
|
+
settle(() => resolve8(this.publicUrl));
|
|
6656
6879
|
}
|
|
6657
6880
|
};
|
|
6658
6881
|
this.child.stdout?.on("data", onData);
|
|
@@ -6670,7 +6893,7 @@ var init_tailscale = __esm({
|
|
|
6670
6893
|
this.publicUrl = `https://${hostname}:${localPort}`;
|
|
6671
6894
|
this.child = null;
|
|
6672
6895
|
log7.info({ url: this.publicUrl }, "Tailscale funnel ready (constructed from hostname)");
|
|
6673
|
-
settle(() =>
|
|
6896
|
+
settle(() => resolve8(this.publicUrl));
|
|
6674
6897
|
} else {
|
|
6675
6898
|
settle(() => reject(new Error(`tailscale exited with code ${code} before establishing funnel`)));
|
|
6676
6899
|
}
|
|
@@ -6694,8 +6917,8 @@ var init_tailscale = __esm({
|
|
|
6694
6917
|
}
|
|
6695
6918
|
child.kill("SIGTERM");
|
|
6696
6919
|
const exited = await Promise.race([
|
|
6697
|
-
new Promise((
|
|
6698
|
-
new Promise((
|
|
6920
|
+
new Promise((resolve8) => child.on("exit", () => resolve8(true))),
|
|
6921
|
+
new Promise((resolve8) => setTimeout(() => resolve8(false), SIGKILL_TIMEOUT_MS4))
|
|
6699
6922
|
]);
|
|
6700
6923
|
if (!exited) {
|
|
6701
6924
|
log7.warn("tailscale did not exit after SIGTERM, sending SIGKILL");
|
|
@@ -6713,7 +6936,7 @@ var init_tailscale = __esm({
|
|
|
6713
6936
|
// src/plugins/tunnel/providers/openacp.ts
|
|
6714
6937
|
import { spawn as spawn5 } from "child_process";
|
|
6715
6938
|
import fs13 from "fs";
|
|
6716
|
-
import
|
|
6939
|
+
import path16 from "path";
|
|
6717
6940
|
var log8, DEFAULT_WORKER_URL, DEFAULT_API_KEY, HEARTBEAT_INTERVAL_MS, STARTUP_TIMEOUT_MS, SIGKILL_TIMEOUT_MS5, STORAGE_KEY, OpenACPTunnelProvider;
|
|
6718
6941
|
var init_openacp = __esm({
|
|
6719
6942
|
"src/plugins/tunnel/providers/openacp.ts"() {
|
|
@@ -6813,7 +7036,7 @@ var init_openacp = __esm({
|
|
|
6813
7036
|
}
|
|
6814
7037
|
async spawnCloudflared(binaryPath, token, port) {
|
|
6815
7038
|
const args2 = ["tunnel", "run", "--url", `http://localhost:${port}`, "--token", token];
|
|
6816
|
-
return new Promise((
|
|
7039
|
+
return new Promise((resolve8, reject) => {
|
|
6817
7040
|
let settled = false;
|
|
6818
7041
|
const settle = (fn) => {
|
|
6819
7042
|
if (!settled) {
|
|
@@ -6823,7 +7046,7 @@ var init_openacp = __esm({
|
|
|
6823
7046
|
};
|
|
6824
7047
|
const timeout = setTimeout(() => {
|
|
6825
7048
|
log8.info({ port }, "cloudflared still running after startup window \u2014 assuming tunnel active");
|
|
6826
|
-
settle(
|
|
7049
|
+
settle(resolve8);
|
|
6827
7050
|
}, STARTUP_TIMEOUT_MS);
|
|
6828
7051
|
let child;
|
|
6829
7052
|
try {
|
|
@@ -6839,7 +7062,7 @@ var init_openacp = __esm({
|
|
|
6839
7062
|
if (/Registered tunnel connection/.test(line)) {
|
|
6840
7063
|
clearTimeout(timeout);
|
|
6841
7064
|
log8.info({ port }, "cloudflared connection registered");
|
|
6842
|
-
settle(
|
|
7065
|
+
settle(resolve8);
|
|
6843
7066
|
}
|
|
6844
7067
|
};
|
|
6845
7068
|
child.stdout?.on("data", onData);
|
|
@@ -6915,7 +7138,7 @@ var init_openacp = __esm({
|
|
|
6915
7138
|
}
|
|
6916
7139
|
async resolveBinary() {
|
|
6917
7140
|
if (commandExists("cloudflared")) return "cloudflared";
|
|
6918
|
-
const binPath =
|
|
7141
|
+
const binPath = path16.join(this.binDir, "cloudflared");
|
|
6919
7142
|
if (fs13.existsSync(binPath)) return binPath;
|
|
6920
7143
|
log8.warn("cloudflared not found, attempting auto-install...");
|
|
6921
7144
|
const { ensureCloudflared: ensureCloudflared2 } = await Promise.resolve().then(() => (init_install_cloudflared(), install_cloudflared_exports));
|
|
@@ -6927,7 +7150,7 @@ var init_openacp = __esm({
|
|
|
6927
7150
|
|
|
6928
7151
|
// src/plugins/tunnel/tunnel-registry.ts
|
|
6929
7152
|
import fs14 from "fs";
|
|
6930
|
-
import
|
|
7153
|
+
import path17 from "path";
|
|
6931
7154
|
var log9, MAX_RETRIES, BASE_RETRY_DELAY_MS, TunnelRegistry;
|
|
6932
7155
|
var init_tunnel_registry = __esm({
|
|
6933
7156
|
"src/plugins/tunnel/tunnel-registry.ts"() {
|
|
@@ -7252,7 +7475,7 @@ var init_tunnel_registry = __esm({
|
|
|
7252
7475
|
createdAt: l.entry.createdAt
|
|
7253
7476
|
}));
|
|
7254
7477
|
try {
|
|
7255
|
-
const dir =
|
|
7478
|
+
const dir = path17.dirname(this.registryPath);
|
|
7256
7479
|
fs14.mkdirSync(dir, { recursive: true });
|
|
7257
7480
|
fs14.writeFileSync(this.registryPath, JSON.stringify(data, null, 2));
|
|
7258
7481
|
} catch (err) {
|
|
@@ -7687,7 +7910,7 @@ var init_output_viewer = __esm({
|
|
|
7687
7910
|
});
|
|
7688
7911
|
|
|
7689
7912
|
// src/plugins/tunnel/viewer-routes.ts
|
|
7690
|
-
import
|
|
7913
|
+
import path18 from "path";
|
|
7691
7914
|
function createViewerRoutes(store) {
|
|
7692
7915
|
return async (app) => {
|
|
7693
7916
|
app.get("/view/:id", async (request, reply) => {
|
|
@@ -7717,7 +7940,7 @@ function createViewerRoutes(store) {
|
|
|
7717
7940
|
return reply.status(404).send({ error: "not found" });
|
|
7718
7941
|
}
|
|
7719
7942
|
return reply.send({
|
|
7720
|
-
filePath: entry.filePath ?
|
|
7943
|
+
filePath: entry.filePath ? path18.basename(entry.filePath) : null,
|
|
7721
7944
|
content: entry.content,
|
|
7722
7945
|
language: entry.language
|
|
7723
7946
|
});
|
|
@@ -7728,7 +7951,7 @@ function createViewerRoutes(store) {
|
|
|
7728
7951
|
return reply.status(404).send({ error: "not found" });
|
|
7729
7952
|
}
|
|
7730
7953
|
return reply.send({
|
|
7731
|
-
filePath: entry.filePath ?
|
|
7954
|
+
filePath: entry.filePath ? path18.basename(entry.filePath) : null,
|
|
7732
7955
|
oldContent: entry.oldContent,
|
|
7733
7956
|
newContent: entry.content,
|
|
7734
7957
|
language: entry.language
|
|
@@ -7753,7 +7976,7 @@ var init_viewer_routes = __esm({
|
|
|
7753
7976
|
|
|
7754
7977
|
// src/plugins/tunnel/viewer-store.ts
|
|
7755
7978
|
import * as fs15 from "fs";
|
|
7756
|
-
import * as
|
|
7979
|
+
import * as path19 from "path";
|
|
7757
7980
|
import { nanoid as nanoid2 } from "nanoid";
|
|
7758
7981
|
var log10, MAX_CONTENT_SIZE, EXTENSION_LANGUAGE, ViewerStore;
|
|
7759
7982
|
var init_viewer_store = __esm({
|
|
@@ -7909,24 +8132,24 @@ var init_viewer_store = __esm({
|
|
|
7909
8132
|
let resolved;
|
|
7910
8133
|
let workspace;
|
|
7911
8134
|
try {
|
|
7912
|
-
resolved = fs15.realpathSync(
|
|
8135
|
+
resolved = fs15.realpathSync(path19.resolve(workingDirectory, filePath));
|
|
7913
8136
|
} catch {
|
|
7914
|
-
resolved =
|
|
8137
|
+
resolved = path19.resolve(workingDirectory, filePath);
|
|
7915
8138
|
}
|
|
7916
8139
|
try {
|
|
7917
|
-
workspace = fs15.realpathSync(
|
|
8140
|
+
workspace = fs15.realpathSync(path19.resolve(workingDirectory));
|
|
7918
8141
|
} catch {
|
|
7919
|
-
workspace =
|
|
8142
|
+
workspace = path19.resolve(workingDirectory);
|
|
7920
8143
|
}
|
|
7921
8144
|
if (caseInsensitive) {
|
|
7922
8145
|
const rLower = resolved.toLowerCase();
|
|
7923
8146
|
const wLower = workspace.toLowerCase();
|
|
7924
|
-
return rLower.startsWith(wLower +
|
|
8147
|
+
return rLower.startsWith(wLower + path19.sep) || rLower === wLower;
|
|
7925
8148
|
}
|
|
7926
|
-
return resolved.startsWith(workspace +
|
|
8149
|
+
return resolved.startsWith(workspace + path19.sep) || resolved === workspace;
|
|
7927
8150
|
}
|
|
7928
8151
|
detectLanguage(filePath) {
|
|
7929
|
-
const ext =
|
|
8152
|
+
const ext = path19.extname(filePath).toLowerCase();
|
|
7930
8153
|
return EXTENSION_LANGUAGE[ext];
|
|
7931
8154
|
}
|
|
7932
8155
|
destroy() {
|
|
@@ -8073,7 +8296,7 @@ var tunnel_exports = {};
|
|
|
8073
8296
|
__export(tunnel_exports, {
|
|
8074
8297
|
default: () => tunnel_default
|
|
8075
8298
|
});
|
|
8076
|
-
import
|
|
8299
|
+
import path20 from "path";
|
|
8077
8300
|
function createTunnelPlugin() {
|
|
8078
8301
|
let service = null;
|
|
8079
8302
|
return {
|
|
@@ -8179,10 +8402,10 @@ function createTunnelPlugin() {
|
|
|
8179
8402
|
{ key: "provider", displayName: "Provider", type: "select", scope: "safe", hotReload: false, options: ["openacp", "cloudflare", "ngrok", "bore", "tailscale"] }
|
|
8180
8403
|
]);
|
|
8181
8404
|
const { default: fs57 } = await import("fs");
|
|
8182
|
-
const settingsPath =
|
|
8405
|
+
const settingsPath = path20.join(ctx.instanceRoot, "plugins", "data", ctx.pluginName, "settings.json");
|
|
8183
8406
|
if (!fs57.existsSync(settingsPath)) {
|
|
8184
8407
|
const defaults = { enabled: true, provider: "openacp", maxUserTunnels: 5, auth: { enabled: false } };
|
|
8185
|
-
fs57.mkdirSync(
|
|
8408
|
+
fs57.mkdirSync(path20.dirname(settingsPath), { recursive: true });
|
|
8186
8409
|
fs57.writeFileSync(settingsPath, JSON.stringify(defaults, null, 2));
|
|
8187
8410
|
Object.assign(ctx.pluginConfig, defaults);
|
|
8188
8411
|
ctx.log.info("Initialized tunnel settings with defaults (openacp provider)");
|
|
@@ -8218,8 +8441,8 @@ function createTunnelPlugin() {
|
|
|
8218
8441
|
const instanceRoot = ctx.instanceRoot;
|
|
8219
8442
|
const tunnelSvc = new TunnelService2(
|
|
8220
8443
|
config,
|
|
8221
|
-
|
|
8222
|
-
|
|
8444
|
+
path20.join(instanceRoot, "tunnels.json"),
|
|
8445
|
+
path20.join(instanceRoot, "bin"),
|
|
8223
8446
|
ctx.storage,
|
|
8224
8447
|
(event, data) => ctx.emit(event, data)
|
|
8225
8448
|
);
|
|
@@ -8318,7 +8541,7 @@ __export(token_store_exports, {
|
|
|
8318
8541
|
TokenStore: () => TokenStore,
|
|
8319
8542
|
parseDuration: () => parseDuration
|
|
8320
8543
|
});
|
|
8321
|
-
import { readFile as readFile2, writeFile } from "fs/promises";
|
|
8544
|
+
import { readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
8322
8545
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
8323
8546
|
function generateTokenId() {
|
|
8324
8547
|
return `tok_${randomBytes2(12).toString("hex")}`;
|
|
@@ -8387,7 +8610,7 @@ var init_token_store = __esm({
|
|
|
8387
8610
|
tokens: Array.from(this.tokens.values()),
|
|
8388
8611
|
codes: Array.from(this.codes.values())
|
|
8389
8612
|
};
|
|
8390
|
-
await
|
|
8613
|
+
await writeFile2(this.filePath, JSON.stringify(data, null, 2), "utf-8");
|
|
8391
8614
|
}
|
|
8392
8615
|
/**
|
|
8393
8616
|
* Coalesces concurrent writes: if a save is in-flight, sets a pending flag
|
|
@@ -8595,22 +8818,22 @@ __export(config_registry_exports, {
|
|
|
8595
8818
|
resolveOptions: () => resolveOptions,
|
|
8596
8819
|
setFieldValueAsync: () => setFieldValueAsync
|
|
8597
8820
|
});
|
|
8598
|
-
function getFieldDef(
|
|
8599
|
-
return CONFIG_REGISTRY.find((f) => f.path ===
|
|
8821
|
+
function getFieldDef(path72) {
|
|
8822
|
+
return CONFIG_REGISTRY.find((f) => f.path === path72);
|
|
8600
8823
|
}
|
|
8601
8824
|
function getSafeFields() {
|
|
8602
8825
|
return CONFIG_REGISTRY.filter((f) => f.scope === "safe");
|
|
8603
8826
|
}
|
|
8604
|
-
function isHotReloadable(
|
|
8605
|
-
const def = getFieldDef(
|
|
8827
|
+
function isHotReloadable(path72) {
|
|
8828
|
+
const def = getFieldDef(path72);
|
|
8606
8829
|
return def?.hotReload ?? false;
|
|
8607
8830
|
}
|
|
8608
8831
|
function resolveOptions(def, config) {
|
|
8609
8832
|
if (!def.options) return void 0;
|
|
8610
8833
|
return typeof def.options === "function" ? def.options(config) : def.options;
|
|
8611
8834
|
}
|
|
8612
|
-
function getConfigValue(config,
|
|
8613
|
-
const parts =
|
|
8835
|
+
function getConfigValue(config, path72) {
|
|
8836
|
+
const parts = path72.split(".");
|
|
8614
8837
|
let current = config;
|
|
8615
8838
|
for (const part of parts) {
|
|
8616
8839
|
if (current && typeof current === "object" && part in current) {
|
|
@@ -9270,8 +9493,8 @@ __export(static_server_exports, {
|
|
|
9270
9493
|
StaticServer: () => StaticServer
|
|
9271
9494
|
});
|
|
9272
9495
|
import * as fs16 from "fs";
|
|
9273
|
-
import * as
|
|
9274
|
-
import { fileURLToPath as
|
|
9496
|
+
import * as path21 from "path";
|
|
9497
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
9275
9498
|
var MIME_TYPES, StaticServer;
|
|
9276
9499
|
var init_static_server = __esm({
|
|
9277
9500
|
"src/plugins/api-server/static-server.ts"() {
|
|
@@ -9293,17 +9516,17 @@ var init_static_server = __esm({
|
|
|
9293
9516
|
constructor(uiDir) {
|
|
9294
9517
|
this.uiDir = uiDir;
|
|
9295
9518
|
if (!this.uiDir) {
|
|
9296
|
-
const __filename =
|
|
9297
|
-
const candidate =
|
|
9298
|
-
if (fs16.existsSync(
|
|
9519
|
+
const __filename = fileURLToPath3(import.meta.url);
|
|
9520
|
+
const candidate = path21.resolve(path21.dirname(__filename), "../../ui/dist");
|
|
9521
|
+
if (fs16.existsSync(path21.join(candidate, "index.html"))) {
|
|
9299
9522
|
this.uiDir = candidate;
|
|
9300
9523
|
}
|
|
9301
9524
|
if (!this.uiDir) {
|
|
9302
|
-
const publishCandidate =
|
|
9303
|
-
|
|
9525
|
+
const publishCandidate = path21.resolve(
|
|
9526
|
+
path21.dirname(__filename),
|
|
9304
9527
|
"../ui"
|
|
9305
9528
|
);
|
|
9306
|
-
if (fs16.existsSync(
|
|
9529
|
+
if (fs16.existsSync(path21.join(publishCandidate, "index.html"))) {
|
|
9307
9530
|
this.uiDir = publishCandidate;
|
|
9308
9531
|
}
|
|
9309
9532
|
}
|
|
@@ -9321,9 +9544,9 @@ var init_static_server = __esm({
|
|
|
9321
9544
|
serve(req, res) {
|
|
9322
9545
|
if (!this.uiDir) return false;
|
|
9323
9546
|
const urlPath = (req.url || "/").split("?")[0];
|
|
9324
|
-
const safePath =
|
|
9325
|
-
const filePath =
|
|
9326
|
-
if (!filePath.startsWith(this.uiDir +
|
|
9547
|
+
const safePath = path21.normalize(urlPath);
|
|
9548
|
+
const filePath = path21.join(this.uiDir, safePath);
|
|
9549
|
+
if (!filePath.startsWith(this.uiDir + path21.sep) && filePath !== this.uiDir)
|
|
9327
9550
|
return false;
|
|
9328
9551
|
let realFilePath;
|
|
9329
9552
|
try {
|
|
@@ -9333,11 +9556,11 @@ var init_static_server = __esm({
|
|
|
9333
9556
|
}
|
|
9334
9557
|
if (realFilePath !== null) {
|
|
9335
9558
|
const realUiDir = fs16.realpathSync(this.uiDir);
|
|
9336
|
-
if (!realFilePath.startsWith(realUiDir +
|
|
9559
|
+
if (!realFilePath.startsWith(realUiDir + path21.sep) && realFilePath !== realUiDir)
|
|
9337
9560
|
return false;
|
|
9338
9561
|
}
|
|
9339
9562
|
if (realFilePath !== null && fs16.existsSync(realFilePath) && fs16.statSync(realFilePath).isFile()) {
|
|
9340
|
-
const ext =
|
|
9563
|
+
const ext = path21.extname(filePath);
|
|
9341
9564
|
const contentType = MIME_TYPES[ext] ?? "application/octet-stream";
|
|
9342
9565
|
const isHashed = /\.[a-zA-Z0-9]{8,}\.(js|css)$/.test(filePath);
|
|
9343
9566
|
const cacheControl = isHashed ? "public, max-age=31536000, immutable" : "no-cache";
|
|
@@ -9348,7 +9571,7 @@ var init_static_server = __esm({
|
|
|
9348
9571
|
fs16.createReadStream(realFilePath).pipe(res);
|
|
9349
9572
|
return true;
|
|
9350
9573
|
}
|
|
9351
|
-
const indexPath =
|
|
9574
|
+
const indexPath = path21.join(this.uiDir, "index.html");
|
|
9352
9575
|
if (fs16.existsSync(indexPath)) {
|
|
9353
9576
|
res.writeHead(200, {
|
|
9354
9577
|
"Content-Type": "text/html; charset=utf-8",
|
|
@@ -10100,7 +10323,7 @@ var init_config = __esm({
|
|
|
10100
10323
|
|
|
10101
10324
|
// src/core/config/config-migrations.ts
|
|
10102
10325
|
import fs18 from "fs";
|
|
10103
|
-
import
|
|
10326
|
+
import path22 from "path";
|
|
10104
10327
|
import os4 from "os";
|
|
10105
10328
|
function applyMigrations(raw, migrationList = migrations, ctx) {
|
|
10106
10329
|
let changed = false;
|
|
@@ -10150,7 +10373,7 @@ var init_config_migrations = __esm({
|
|
|
10150
10373
|
if (!ctx?.configDir) return false;
|
|
10151
10374
|
const instanceRoot = ctx.configDir;
|
|
10152
10375
|
try {
|
|
10153
|
-
const registryPath =
|
|
10376
|
+
const registryPath = path22.join(os4.homedir(), ".openacp", "instances.json");
|
|
10154
10377
|
const data = JSON.parse(fs18.readFileSync(registryPath, "utf-8"));
|
|
10155
10378
|
const instances = data?.instances ?? {};
|
|
10156
10379
|
const entry = Object.values(instances).find(
|
|
@@ -10179,13 +10402,13 @@ __export(config_exports, {
|
|
|
10179
10402
|
});
|
|
10180
10403
|
import { z as z4 } from "zod";
|
|
10181
10404
|
import * as fs19 from "fs";
|
|
10182
|
-
import * as
|
|
10405
|
+
import * as path23 from "path";
|
|
10183
10406
|
import * as os5 from "os";
|
|
10184
10407
|
import { randomBytes as randomBytes3 } from "crypto";
|
|
10185
10408
|
import { EventEmitter } from "events";
|
|
10186
10409
|
function expandHome2(p2) {
|
|
10187
10410
|
if (p2.startsWith("~")) {
|
|
10188
|
-
return
|
|
10411
|
+
return path23.join(os5.homedir(), p2.slice(1));
|
|
10189
10412
|
}
|
|
10190
10413
|
return p2;
|
|
10191
10414
|
}
|
|
@@ -10259,7 +10482,7 @@ var init_config2 = __esm({
|
|
|
10259
10482
|
* 4. Validate against Zod schema — exits on failure
|
|
10260
10483
|
*/
|
|
10261
10484
|
async load() {
|
|
10262
|
-
const dir =
|
|
10485
|
+
const dir = path23.dirname(this.configPath);
|
|
10263
10486
|
fs19.mkdirSync(dir, { recursive: true });
|
|
10264
10487
|
if (!fs19.existsSync(this.configPath)) {
|
|
10265
10488
|
fs19.writeFileSync(
|
|
@@ -10273,7 +10496,7 @@ var init_config2 = __esm({
|
|
|
10273
10496
|
process.exit(1);
|
|
10274
10497
|
}
|
|
10275
10498
|
const raw = JSON.parse(fs19.readFileSync(this.configPath, "utf-8"));
|
|
10276
|
-
const { changed: configUpdated } = applyMigrations(raw, void 0, { configDir:
|
|
10499
|
+
const { changed: configUpdated } = applyMigrations(raw, void 0, { configDir: path23.dirname(this.configPath) });
|
|
10277
10500
|
if (configUpdated) {
|
|
10278
10501
|
fs19.writeFileSync(this.configPath, JSON.stringify(raw, null, 2));
|
|
10279
10502
|
}
|
|
@@ -10353,16 +10576,16 @@ var init_config2 = __esm({
|
|
|
10353
10576
|
* (alphanumeric subdirectories under the base).
|
|
10354
10577
|
*/
|
|
10355
10578
|
resolveWorkspace(input2) {
|
|
10356
|
-
const workspaceBase =
|
|
10579
|
+
const workspaceBase = path23.dirname(path23.dirname(this.configPath));
|
|
10357
10580
|
if (!input2) {
|
|
10358
10581
|
fs19.mkdirSync(workspaceBase, { recursive: true });
|
|
10359
10582
|
return workspaceBase;
|
|
10360
10583
|
}
|
|
10361
10584
|
const expanded = input2.startsWith("~") ? expandHome2(input2) : input2;
|
|
10362
|
-
if (
|
|
10363
|
-
const resolved =
|
|
10364
|
-
const base =
|
|
10365
|
-
const isInternal = resolved === base || resolved.startsWith(base +
|
|
10585
|
+
if (path23.isAbsolute(expanded)) {
|
|
10586
|
+
const resolved = path23.resolve(expanded);
|
|
10587
|
+
const base = path23.resolve(workspaceBase);
|
|
10588
|
+
const isInternal = resolved === base || resolved.startsWith(base + path23.sep);
|
|
10366
10589
|
if (!isInternal) {
|
|
10367
10590
|
if (!this.config.workspace.allowExternalWorkspaces) {
|
|
10368
10591
|
throw new Error(
|
|
@@ -10382,7 +10605,7 @@ var init_config2 = __esm({
|
|
|
10382
10605
|
`Invalid workspace name: "${input2}". Only alphanumeric characters, hyphens, and underscores are allowed.`
|
|
10383
10606
|
);
|
|
10384
10607
|
}
|
|
10385
|
-
const namedPath =
|
|
10608
|
+
const namedPath = path23.join(workspaceBase, input2.toLowerCase());
|
|
10386
10609
|
fs19.mkdirSync(namedPath, { recursive: true });
|
|
10387
10610
|
return namedPath;
|
|
10388
10611
|
}
|
|
@@ -10396,7 +10619,7 @@ var init_config2 = __esm({
|
|
|
10396
10619
|
}
|
|
10397
10620
|
/** Writes a complete config object to disk, creating the directory if needed. Used during initial setup. */
|
|
10398
10621
|
async writeNew(config) {
|
|
10399
|
-
const dir =
|
|
10622
|
+
const dir = path23.dirname(this.configPath);
|
|
10400
10623
|
fs19.mkdirSync(dir, { recursive: true });
|
|
10401
10624
|
fs19.writeFileSync(this.configPath, JSON.stringify(config, null, 2));
|
|
10402
10625
|
}
|
|
@@ -10414,6 +10637,14 @@ var init_config2 = __esm({
|
|
|
10414
10637
|
{ envVar: "OPENACP_API_PORT", pluginName: "@openacp/api-server", key: "port", transform: (v) => Number(v) },
|
|
10415
10638
|
{ envVar: "OPENACP_SPEECH_STT_PROVIDER", pluginName: "@openacp/speech", key: "sttProvider" },
|
|
10416
10639
|
{ envVar: "OPENACP_SPEECH_GROQ_API_KEY", pluginName: "@openacp/speech", key: "groqApiKey" },
|
|
10640
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_LANGUAGE", pluginName: "@openacp/speech", key: "localWhisperLanguage" },
|
|
10641
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_MODEL", pluginName: "@openacp/speech", key: "localWhisperModel" },
|
|
10642
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_BEAM_SIZE", pluginName: "@openacp/speech", key: "localWhisperBeamSize", transform: (v) => Number(v) },
|
|
10643
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_VAD_FILTER", pluginName: "@openacp/speech", key: "localWhisperVadFilter", transform: (v) => v === "true" },
|
|
10644
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_DEVICE", pluginName: "@openacp/speech", key: "localWhisperDevice" },
|
|
10645
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_COMPUTE_TYPE", pluginName: "@openacp/speech", key: "localWhisperComputeType" },
|
|
10646
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_TIMEOUT_MS", pluginName: "@openacp/speech", key: "localWhisperTimeoutMs", transform: (v) => Number(v) },
|
|
10647
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_SCRIPT_PATH", pluginName: "@openacp/speech", key: "localWhisperScriptPath" },
|
|
10417
10648
|
{ envVar: "OPENACP_TELEGRAM_BOT_TOKEN", pluginName: "@openacp/telegram", key: "botToken" },
|
|
10418
10649
|
{ envVar: "OPENACP_TELEGRAM_CHAT_ID", pluginName: "@openacp/telegram", key: "chatId", transform: (v) => Number(v) },
|
|
10419
10650
|
// Future adapters — no-ops if plugin settings don't exist
|
|
@@ -11131,7 +11362,7 @@ var plugins_exports = {};
|
|
|
11131
11362
|
__export(plugins_exports, {
|
|
11132
11363
|
pluginRoutes: () => pluginRoutes
|
|
11133
11364
|
});
|
|
11134
|
-
import
|
|
11365
|
+
import path24 from "path";
|
|
11135
11366
|
async function pluginRoutes(app, deps) {
|
|
11136
11367
|
const { lifecycleManager } = deps;
|
|
11137
11368
|
const admin = [requireScopes("system:admin")];
|
|
@@ -11196,7 +11427,7 @@ async function pluginRoutes(app, deps) {
|
|
|
11196
11427
|
} else {
|
|
11197
11428
|
const { importFromDir: importFromDir2 } = await Promise.resolve().then(() => (init_plugin_installer(), plugin_installer_exports));
|
|
11198
11429
|
const instanceRoot = lifecycleManager.instanceRoot;
|
|
11199
|
-
const pluginsDir =
|
|
11430
|
+
const pluginsDir = path24.join(instanceRoot, "plugins");
|
|
11200
11431
|
try {
|
|
11201
11432
|
const mod = await importFromDir2(name, pluginsDir);
|
|
11202
11433
|
pluginDef = mod.default ?? mod;
|
|
@@ -11272,11 +11503,11 @@ __export(instance_registry_exports, {
|
|
|
11272
11503
|
readIdFromConfig: () => readIdFromConfig
|
|
11273
11504
|
});
|
|
11274
11505
|
import fs20 from "fs";
|
|
11275
|
-
import
|
|
11506
|
+
import path25 from "path";
|
|
11276
11507
|
import { randomUUID } from "crypto";
|
|
11277
11508
|
function readIdFromConfig(instanceRoot) {
|
|
11278
11509
|
try {
|
|
11279
|
-
const raw = JSON.parse(fs20.readFileSync(
|
|
11510
|
+
const raw = JSON.parse(fs20.readFileSync(path25.join(instanceRoot, "config.json"), "utf-8"));
|
|
11280
11511
|
return typeof raw.id === "string" && raw.id ? raw.id : null;
|
|
11281
11512
|
} catch {
|
|
11282
11513
|
return null;
|
|
@@ -11322,7 +11553,7 @@ var init_instance_registry = __esm({
|
|
|
11322
11553
|
}
|
|
11323
11554
|
/** Persist the registry to disk, creating parent directories if needed. */
|
|
11324
11555
|
save() {
|
|
11325
|
-
const dir =
|
|
11556
|
+
const dir = path25.dirname(this.registryPath);
|
|
11326
11557
|
fs20.mkdirSync(dir, { recursive: true });
|
|
11327
11558
|
fs20.writeFileSync(this.registryPath, JSON.stringify(this.data, null, 2));
|
|
11328
11559
|
}
|
|
@@ -11392,7 +11623,7 @@ __export(instance_context_exports, {
|
|
|
11392
11623
|
resolveInstanceRoot: () => resolveInstanceRoot,
|
|
11393
11624
|
resolveRunningInstance: () => resolveRunningInstance
|
|
11394
11625
|
});
|
|
11395
|
-
import
|
|
11626
|
+
import path26 from "path";
|
|
11396
11627
|
import fs21 from "fs";
|
|
11397
11628
|
import os6 from "os";
|
|
11398
11629
|
function createInstanceContext(opts) {
|
|
@@ -11402,22 +11633,22 @@ function createInstanceContext(opts) {
|
|
|
11402
11633
|
id,
|
|
11403
11634
|
root,
|
|
11404
11635
|
paths: {
|
|
11405
|
-
config:
|
|
11406
|
-
sessions:
|
|
11407
|
-
agents:
|
|
11408
|
-
registryCache:
|
|
11409
|
-
plugins:
|
|
11410
|
-
pluginsData:
|
|
11411
|
-
pluginRegistry:
|
|
11412
|
-
logs:
|
|
11413
|
-
pid:
|
|
11414
|
-
running:
|
|
11415
|
-
apiPort:
|
|
11416
|
-
apiSecret:
|
|
11417
|
-
bin:
|
|
11418
|
-
cache:
|
|
11419
|
-
tunnels:
|
|
11420
|
-
agentsDir:
|
|
11636
|
+
config: path26.join(root, "config.json"),
|
|
11637
|
+
sessions: path26.join(root, "sessions.json"),
|
|
11638
|
+
agents: path26.join(root, "agents.json"),
|
|
11639
|
+
registryCache: path26.join(globalRoot, "cache", "registry-cache.json"),
|
|
11640
|
+
plugins: path26.join(root, "plugins"),
|
|
11641
|
+
pluginsData: path26.join(root, "plugins", "data"),
|
|
11642
|
+
pluginRegistry: path26.join(root, "plugins.json"),
|
|
11643
|
+
logs: path26.join(root, "logs"),
|
|
11644
|
+
pid: path26.join(root, "openacp.pid"),
|
|
11645
|
+
running: path26.join(root, "running"),
|
|
11646
|
+
apiPort: path26.join(root, "api.port"),
|
|
11647
|
+
apiSecret: path26.join(root, "api-secret"),
|
|
11648
|
+
bin: path26.join(globalRoot, "bin"),
|
|
11649
|
+
cache: path26.join(root, "cache"),
|
|
11650
|
+
tunnels: path26.join(root, "tunnels.json"),
|
|
11651
|
+
agentsDir: path26.join(globalRoot, "agents")
|
|
11421
11652
|
}
|
|
11422
11653
|
};
|
|
11423
11654
|
}
|
|
@@ -11426,50 +11657,50 @@ function generateSlug(name) {
|
|
|
11426
11657
|
return slug || "openacp";
|
|
11427
11658
|
}
|
|
11428
11659
|
function expandHome3(p2) {
|
|
11429
|
-
if (p2.startsWith("~")) return
|
|
11660
|
+
if (p2.startsWith("~")) return path26.join(os6.homedir(), p2.slice(1));
|
|
11430
11661
|
return p2;
|
|
11431
11662
|
}
|
|
11432
11663
|
function resolveInstanceRoot(opts) {
|
|
11433
11664
|
const cwd = opts.cwd ?? process.cwd();
|
|
11434
11665
|
const home = os6.homedir();
|
|
11435
11666
|
const globalRoot = getGlobalRoot();
|
|
11436
|
-
if (opts.dir) return
|
|
11437
|
-
if (opts.local) return
|
|
11438
|
-
const cwdRoot =
|
|
11439
|
-
if (fs21.existsSync(
|
|
11440
|
-
let dir =
|
|
11667
|
+
if (opts.dir) return path26.join(expandHome3(opts.dir), ".openacp");
|
|
11668
|
+
if (opts.local) return path26.join(cwd, ".openacp");
|
|
11669
|
+
const cwdRoot = path26.join(cwd, ".openacp");
|
|
11670
|
+
if (fs21.existsSync(path26.join(cwdRoot, "config.json"))) return cwdRoot;
|
|
11671
|
+
let dir = path26.resolve(cwd);
|
|
11441
11672
|
while (true) {
|
|
11442
|
-
const parent =
|
|
11673
|
+
const parent = path26.dirname(dir);
|
|
11443
11674
|
if (parent === dir) break;
|
|
11444
11675
|
dir = parent;
|
|
11445
|
-
const candidate =
|
|
11676
|
+
const candidate = path26.join(dir, ".openacp");
|
|
11446
11677
|
if (candidate === globalRoot) {
|
|
11447
11678
|
if (dir === home) break;
|
|
11448
11679
|
continue;
|
|
11449
11680
|
}
|
|
11450
|
-
if (fs21.existsSync(
|
|
11681
|
+
if (fs21.existsSync(path26.join(candidate, "config.json"))) return candidate;
|
|
11451
11682
|
if (dir === home) break;
|
|
11452
11683
|
}
|
|
11453
|
-
if (
|
|
11454
|
-
const defaultWs =
|
|
11455
|
-
if (fs21.existsSync(
|
|
11684
|
+
if (path26.resolve(cwd) === path26.resolve(home)) {
|
|
11685
|
+
const defaultWs = path26.join(home, "openacp-workspace", ".openacp");
|
|
11686
|
+
if (fs21.existsSync(path26.join(defaultWs, "config.json"))) return defaultWs;
|
|
11456
11687
|
}
|
|
11457
11688
|
if (process.env.OPENACP_INSTANCE_ROOT) return process.env.OPENACP_INSTANCE_ROOT;
|
|
11458
11689
|
return null;
|
|
11459
11690
|
}
|
|
11460
11691
|
function getGlobalRoot() {
|
|
11461
|
-
return
|
|
11692
|
+
return path26.join(os6.homedir(), ".openacp");
|
|
11462
11693
|
}
|
|
11463
11694
|
async function resolveRunningInstance(cwd) {
|
|
11464
11695
|
const globalRoot = getGlobalRoot();
|
|
11465
11696
|
const home = os6.homedir();
|
|
11466
|
-
let dir =
|
|
11697
|
+
let dir = path26.resolve(cwd);
|
|
11467
11698
|
while (true) {
|
|
11468
|
-
const candidate =
|
|
11699
|
+
const candidate = path26.join(dir, ".openacp");
|
|
11469
11700
|
if (candidate !== globalRoot && fs21.existsSync(candidate)) {
|
|
11470
11701
|
if (await isInstanceRunning(candidate)) return candidate;
|
|
11471
11702
|
}
|
|
11472
|
-
const parent =
|
|
11703
|
+
const parent = path26.dirname(dir);
|
|
11473
11704
|
if (parent === dir) break;
|
|
11474
11705
|
if (dir === home) break;
|
|
11475
11706
|
dir = parent;
|
|
@@ -11477,7 +11708,7 @@ async function resolveRunningInstance(cwd) {
|
|
|
11477
11708
|
return null;
|
|
11478
11709
|
}
|
|
11479
11710
|
async function isInstanceRunning(instanceRoot) {
|
|
11480
|
-
const portFile =
|
|
11711
|
+
const portFile = path26.join(instanceRoot, "api.port");
|
|
11481
11712
|
try {
|
|
11482
11713
|
const content = fs21.readFileSync(portFile, "utf-8").trim();
|
|
11483
11714
|
const port = parseInt(content, 10);
|
|
@@ -11506,22 +11737,14 @@ __export(api_server_exports, {
|
|
|
11506
11737
|
});
|
|
11507
11738
|
import * as fs22 from "fs";
|
|
11508
11739
|
import * as crypto3 from "crypto";
|
|
11509
|
-
import * as
|
|
11510
|
-
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
11740
|
+
import * as path27 from "path";
|
|
11511
11741
|
function getVersion() {
|
|
11512
11742
|
if (cachedVersion) return cachedVersion;
|
|
11513
|
-
|
|
11514
|
-
const __filename = fileURLToPath3(import.meta.url);
|
|
11515
|
-
const pkgPath = path26.resolve(path26.dirname(__filename), "../../../package.json");
|
|
11516
|
-
const pkg = JSON.parse(fs22.readFileSync(pkgPath, "utf-8"));
|
|
11517
|
-
cachedVersion = pkg.version ?? "0.0.0-dev";
|
|
11518
|
-
} catch {
|
|
11519
|
-
cachedVersion = "0.0.0-dev";
|
|
11520
|
-
}
|
|
11743
|
+
cachedVersion = getCurrentVersion();
|
|
11521
11744
|
return cachedVersion;
|
|
11522
11745
|
}
|
|
11523
11746
|
function loadOrCreateSecret(secretFilePath) {
|
|
11524
|
-
const dir =
|
|
11747
|
+
const dir = path27.dirname(secretFilePath);
|
|
11525
11748
|
fs22.mkdirSync(dir, { recursive: true });
|
|
11526
11749
|
try {
|
|
11527
11750
|
const existing = fs22.readFileSync(secretFilePath, "utf-8").trim();
|
|
@@ -11547,7 +11770,7 @@ function loadOrCreateSecret(secretFilePath) {
|
|
|
11547
11770
|
return secret;
|
|
11548
11771
|
}
|
|
11549
11772
|
function writePortFile(portFilePath, port) {
|
|
11550
|
-
const dir =
|
|
11773
|
+
const dir = path27.dirname(portFilePath);
|
|
11551
11774
|
fs22.mkdirSync(dir, { recursive: true });
|
|
11552
11775
|
fs22.writeFileSync(portFilePath, String(port));
|
|
11553
11776
|
}
|
|
@@ -11632,10 +11855,10 @@ function createApiServerPlugin() {
|
|
|
11632
11855
|
{ port: apiConfig.port, host: apiConfig.host, instanceRoot },
|
|
11633
11856
|
"API server plugin setup \u2014 config loaded"
|
|
11634
11857
|
);
|
|
11635
|
-
portFilePath =
|
|
11636
|
-
const secretFilePath =
|
|
11637
|
-
const jwtSecretFilePath =
|
|
11638
|
-
const tokensFilePath =
|
|
11858
|
+
portFilePath = path27.join(instanceRoot, "api.port");
|
|
11859
|
+
const secretFilePath = path27.join(instanceRoot, "api-secret");
|
|
11860
|
+
const jwtSecretFilePath = path27.join(instanceRoot, "jwt-secret");
|
|
11861
|
+
const tokensFilePath = path27.join(instanceRoot, "tokens.json");
|
|
11639
11862
|
const startedAt = Date.now();
|
|
11640
11863
|
const secret = loadOrCreateSecret(secretFilePath);
|
|
11641
11864
|
const jwtSecret = loadOrCreateSecret(jwtSecretFilePath);
|
|
@@ -11674,7 +11897,7 @@ function createApiServerPlugin() {
|
|
|
11674
11897
|
const { InstanceRegistry: InstanceRegistry2 } = await Promise.resolve().then(() => (init_instance_registry(), instance_registry_exports));
|
|
11675
11898
|
const { getGlobalRoot: getGlobalRoot2 } = await Promise.resolve().then(() => (init_instance_context(), instance_context_exports));
|
|
11676
11899
|
const globalRoot = getGlobalRoot2();
|
|
11677
|
-
const instanceReg = new InstanceRegistry2(
|
|
11900
|
+
const instanceReg = new InstanceRegistry2(path27.join(globalRoot, "instances.json"));
|
|
11678
11901
|
instanceReg.load();
|
|
11679
11902
|
const instanceEntry = instanceReg.getByRoot(instanceRoot);
|
|
11680
11903
|
const workspaceId = instanceEntry?.id ?? "main";
|
|
@@ -11706,7 +11929,7 @@ function createApiServerPlugin() {
|
|
|
11706
11929
|
server.registerPlugin("/api/v1/plugins", async (app) => pluginRoutes2(app, deps));
|
|
11707
11930
|
const appConfig = core.configManager.get();
|
|
11708
11931
|
const workspaceName = appConfig.instanceName ?? "Main";
|
|
11709
|
-
const workspaceDir =
|
|
11932
|
+
const workspaceDir = path27.dirname(instanceRoot);
|
|
11710
11933
|
server.registerPlugin("/api/v1", async (app) => {
|
|
11711
11934
|
await app.register(workspaceRoute2, {
|
|
11712
11935
|
id: workspaceId,
|
|
@@ -11846,6 +12069,7 @@ var init_api_server = __esm({
|
|
|
11846
12069
|
"use strict";
|
|
11847
12070
|
init_events();
|
|
11848
12071
|
init_log();
|
|
12072
|
+
init_version();
|
|
11849
12073
|
log15 = createChildLogger({ module: "api-server" });
|
|
11850
12074
|
api_server_default = createApiServerPlugin();
|
|
11851
12075
|
}
|
|
@@ -12799,8 +13023,8 @@ function formatToolSummary(name, rawInput, displaySummary) {
|
|
|
12799
13023
|
}
|
|
12800
13024
|
if (lowerName === "grep") {
|
|
12801
13025
|
const pattern = args2.pattern ?? "";
|
|
12802
|
-
const
|
|
12803
|
-
return pattern ? `\u{1F50D} Grep "${pattern}"${
|
|
13026
|
+
const path72 = args2.path ?? "";
|
|
13027
|
+
return pattern ? `\u{1F50D} Grep "${pattern}"${path72 ? ` in ${path72}` : ""}` : `\u{1F527} ${name}`;
|
|
12804
13028
|
}
|
|
12805
13029
|
if (lowerName === "glob") {
|
|
12806
13030
|
const pattern = args2.pattern ?? "";
|
|
@@ -12836,8 +13060,8 @@ function formatToolTitle(name, rawInput, displayTitle) {
|
|
|
12836
13060
|
}
|
|
12837
13061
|
if (lowerName === "grep") {
|
|
12838
13062
|
const pattern = args2.pattern ?? "";
|
|
12839
|
-
const
|
|
12840
|
-
return pattern ? `"${pattern}"${
|
|
13063
|
+
const path72 = args2.path ?? "";
|
|
13064
|
+
return pattern ? `"${pattern}"${path72 ? ` in ${path72}` : ""}` : name;
|
|
12841
13065
|
}
|
|
12842
13066
|
if (lowerName === "glob") {
|
|
12843
13067
|
return String(args2.pattern ?? name);
|
|
@@ -13980,7 +14204,7 @@ __export(integrate_exports, {
|
|
|
13980
14204
|
listIntegrations: () => listIntegrations,
|
|
13981
14205
|
uninstallIntegration: () => uninstallIntegration
|
|
13982
14206
|
});
|
|
13983
|
-
import { existsSync as
|
|
14207
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync5, unlinkSync as unlinkSync4, chmodSync, rmdirSync } from "fs";
|
|
13984
14208
|
import { join as join10, dirname as dirname7 } from "path";
|
|
13985
14209
|
import { homedir as homedir3 } from "os";
|
|
13986
14210
|
function isHooksIntegrationSpec(spec) {
|
|
@@ -14142,7 +14366,7 @@ function generateOpencodePlugin(spec) {
|
|
|
14142
14366
|
function mergeSettingsJson(settingsPath, hookEvent, hookScriptPath) {
|
|
14143
14367
|
const fullPath = expandPath(settingsPath);
|
|
14144
14368
|
let settings = {};
|
|
14145
|
-
if (
|
|
14369
|
+
if (existsSync7(fullPath)) {
|
|
14146
14370
|
const raw = readFileSync5(fullPath, "utf-8");
|
|
14147
14371
|
writeFileSync5(`${fullPath}.bak`, raw);
|
|
14148
14372
|
settings = JSON.parse(raw);
|
|
@@ -14165,7 +14389,7 @@ function mergeSettingsJson(settingsPath, hookEvent, hookScriptPath) {
|
|
|
14165
14389
|
function mergeHooksJson(settingsPath, hookEvent, hookScriptPath) {
|
|
14166
14390
|
const fullPath = expandPath(settingsPath);
|
|
14167
14391
|
let config = { version: 1 };
|
|
14168
|
-
if (
|
|
14392
|
+
if (existsSync7(fullPath)) {
|
|
14169
14393
|
const raw = readFileSync5(fullPath, "utf-8");
|
|
14170
14394
|
writeFileSync5(`${fullPath}.bak`, raw);
|
|
14171
14395
|
config = JSON.parse(raw);
|
|
@@ -14183,7 +14407,7 @@ function mergeHooksJson(settingsPath, hookEvent, hookScriptPath) {
|
|
|
14183
14407
|
}
|
|
14184
14408
|
function removeFromSettingsJson(settingsPath, hookEvent) {
|
|
14185
14409
|
const fullPath = expandPath(settingsPath);
|
|
14186
|
-
if (!
|
|
14410
|
+
if (!existsSync7(fullPath)) return;
|
|
14187
14411
|
const raw = readFileSync5(fullPath, "utf-8");
|
|
14188
14412
|
const settings = JSON.parse(raw);
|
|
14189
14413
|
const hooks = settings.hooks;
|
|
@@ -14198,7 +14422,7 @@ function removeFromSettingsJson(settingsPath, hookEvent) {
|
|
|
14198
14422
|
}
|
|
14199
14423
|
function removeFromHooksJson(settingsPath, hookEvent) {
|
|
14200
14424
|
const fullPath = expandPath(settingsPath);
|
|
14201
|
-
if (!
|
|
14425
|
+
if (!existsSync7(fullPath)) return;
|
|
14202
14426
|
const raw = readFileSync5(fullPath, "utf-8");
|
|
14203
14427
|
const config = JSON.parse(raw);
|
|
14204
14428
|
const hooks = config.hooks;
|
|
@@ -14264,7 +14488,7 @@ async function uninstallHooksIntegration(agentKey, spec) {
|
|
|
14264
14488
|
const hooksDir = expandPath(spec.hooksDirPath);
|
|
14265
14489
|
for (const filename of ["openacp-inject-session.sh", "openacp-handoff.sh"]) {
|
|
14266
14490
|
const filePath = join10(hooksDir, filename);
|
|
14267
|
-
if (
|
|
14491
|
+
if (existsSync7(filePath)) {
|
|
14268
14492
|
unlinkSync4(filePath);
|
|
14269
14493
|
logs.push(`Removed ${filePath}`);
|
|
14270
14494
|
}
|
|
@@ -14273,7 +14497,7 @@ async function uninstallHooksIntegration(agentKey, spec) {
|
|
|
14273
14497
|
if (spec.commandFormat === "skill") {
|
|
14274
14498
|
const skillDir = expandPath(join10(spec.commandsPath, spec.handoffCommandName));
|
|
14275
14499
|
const skillPath = join10(skillDir, "SKILL.md");
|
|
14276
|
-
if (
|
|
14500
|
+
if (existsSync7(skillPath)) {
|
|
14277
14501
|
unlinkSync4(skillPath);
|
|
14278
14502
|
try {
|
|
14279
14503
|
rmdirSync(skillDir);
|
|
@@ -14283,7 +14507,7 @@ async function uninstallHooksIntegration(agentKey, spec) {
|
|
|
14283
14507
|
}
|
|
14284
14508
|
} else {
|
|
14285
14509
|
const cmdPath = expandPath(join10(spec.commandsPath, `${spec.handoffCommandName}.md`));
|
|
14286
|
-
if (
|
|
14510
|
+
if (existsSync7(cmdPath)) {
|
|
14287
14511
|
unlinkSync4(cmdPath);
|
|
14288
14512
|
logs.push(`Removed ${cmdPath}`);
|
|
14289
14513
|
}
|
|
@@ -14310,11 +14534,11 @@ async function installPluginIntegration(_agentKey, spec) {
|
|
|
14310
14534
|
const pluginsDir = expandPath(spec.pluginsPath);
|
|
14311
14535
|
mkdirSync5(pluginsDir, { recursive: true });
|
|
14312
14536
|
const pluginPath = join10(pluginsDir, spec.pluginFileName);
|
|
14313
|
-
if (
|
|
14537
|
+
if (existsSync7(commandPath) && existsSync7(pluginPath)) {
|
|
14314
14538
|
logs.push("Already installed, skipping.");
|
|
14315
14539
|
return { success: true, logs };
|
|
14316
14540
|
}
|
|
14317
|
-
if (
|
|
14541
|
+
if (existsSync7(commandPath) || existsSync7(pluginPath)) {
|
|
14318
14542
|
logs.push("Overwriting existing files.");
|
|
14319
14543
|
}
|
|
14320
14544
|
writeFileSync5(commandPath, generateOpencodeHandoffCommand(spec));
|
|
@@ -14332,13 +14556,13 @@ async function uninstallPluginIntegration(_agentKey, spec) {
|
|
|
14332
14556
|
try {
|
|
14333
14557
|
const commandPath = join10(expandPath(spec.commandsPath), spec.handoffCommandFile);
|
|
14334
14558
|
let removedCount = 0;
|
|
14335
|
-
if (
|
|
14559
|
+
if (existsSync7(commandPath)) {
|
|
14336
14560
|
unlinkSync4(commandPath);
|
|
14337
14561
|
logs.push(`Removed ${commandPath}`);
|
|
14338
14562
|
removedCount += 1;
|
|
14339
14563
|
}
|
|
14340
14564
|
const pluginPath = join10(expandPath(spec.pluginsPath), spec.pluginFileName);
|
|
14341
|
-
if (
|
|
14565
|
+
if (existsSync7(pluginPath)) {
|
|
14342
14566
|
unlinkSync4(pluginPath);
|
|
14343
14567
|
logs.push(`Removed ${pluginPath}`);
|
|
14344
14568
|
removedCount += 1;
|
|
@@ -14372,11 +14596,11 @@ function buildHandoffItem(agentKey, spec) {
|
|
|
14372
14596
|
isInstalled() {
|
|
14373
14597
|
if (isHooksIntegrationSpec(spec)) {
|
|
14374
14598
|
const hooksDir = expandPath(spec.hooksDirPath);
|
|
14375
|
-
return
|
|
14599
|
+
return existsSync7(join10(hooksDir, "openacp-inject-session.sh")) && existsSync7(join10(hooksDir, "openacp-handoff.sh"));
|
|
14376
14600
|
}
|
|
14377
14601
|
const commandPath = join10(expandPath(spec.commandsPath), spec.handoffCommandFile);
|
|
14378
14602
|
const pluginPath = join10(expandPath(spec.pluginsPath), spec.pluginFileName);
|
|
14379
|
-
return
|
|
14603
|
+
return existsSync7(commandPath) && existsSync7(pluginPath);
|
|
14380
14604
|
},
|
|
14381
14605
|
install: () => installIntegration(agentKey, spec),
|
|
14382
14606
|
uninstall: () => uninstallIntegration(agentKey, spec)
|
|
@@ -14398,7 +14622,7 @@ function buildTunnelItem(spec) {
|
|
|
14398
14622
|
name: "Tunnel",
|
|
14399
14623
|
description: "Expose local ports to the internet via OpenACP tunnel",
|
|
14400
14624
|
isInstalled() {
|
|
14401
|
-
return
|
|
14625
|
+
return existsSync7(getTunnelPath());
|
|
14402
14626
|
},
|
|
14403
14627
|
async install() {
|
|
14404
14628
|
const logs = [];
|
|
@@ -14417,7 +14641,7 @@ function buildTunnelItem(spec) {
|
|
|
14417
14641
|
const logs = [];
|
|
14418
14642
|
try {
|
|
14419
14643
|
const skillPath = getTunnelPath();
|
|
14420
|
-
if (
|
|
14644
|
+
if (existsSync7(skillPath)) {
|
|
14421
14645
|
unlinkSync4(skillPath);
|
|
14422
14646
|
try {
|
|
14423
14647
|
rmdirSync(dirname7(skillPath));
|
|
@@ -15180,7 +15404,7 @@ var init_config4 = __esm({
|
|
|
15180
15404
|
// src/core/doctor/checks/agents.ts
|
|
15181
15405
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
15182
15406
|
import * as fs24 from "fs";
|
|
15183
|
-
import * as
|
|
15407
|
+
import * as path28 from "path";
|
|
15184
15408
|
function commandExists2(cmd) {
|
|
15185
15409
|
try {
|
|
15186
15410
|
execFileSync4("which", [cmd], { stdio: "pipe" });
|
|
@@ -15189,9 +15413,9 @@ function commandExists2(cmd) {
|
|
|
15189
15413
|
}
|
|
15190
15414
|
let dir = process.cwd();
|
|
15191
15415
|
while (true) {
|
|
15192
|
-
const binPath =
|
|
15416
|
+
const binPath = path28.join(dir, "node_modules", ".bin", cmd);
|
|
15193
15417
|
if (fs24.existsSync(binPath)) return true;
|
|
15194
|
-
const parent =
|
|
15418
|
+
const parent = path28.dirname(dir);
|
|
15195
15419
|
if (parent === dir) break;
|
|
15196
15420
|
dir = parent;
|
|
15197
15421
|
}
|
|
@@ -15213,7 +15437,7 @@ var init_agents3 = __esm({
|
|
|
15213
15437
|
const defaultAgent = ctx.config.defaultAgent;
|
|
15214
15438
|
let agents = {};
|
|
15215
15439
|
try {
|
|
15216
|
-
const agentsPath =
|
|
15440
|
+
const agentsPath = path28.join(ctx.dataDir, "agents.json");
|
|
15217
15441
|
if (fs24.existsSync(agentsPath)) {
|
|
15218
15442
|
const data = JSON.parse(fs24.readFileSync(agentsPath, "utf-8"));
|
|
15219
15443
|
agents = data.installed ?? {};
|
|
@@ -15254,7 +15478,7 @@ __export(settings_manager_exports, {
|
|
|
15254
15478
|
SettingsManager: () => SettingsManager
|
|
15255
15479
|
});
|
|
15256
15480
|
import fs25 from "fs";
|
|
15257
|
-
import
|
|
15481
|
+
import path29 from "path";
|
|
15258
15482
|
var SettingsManager, SettingsAPIImpl;
|
|
15259
15483
|
var init_settings_manager = __esm({
|
|
15260
15484
|
"src/core/plugin/settings-manager.ts"() {
|
|
@@ -15297,7 +15521,7 @@ var init_settings_manager = __esm({
|
|
|
15297
15521
|
}
|
|
15298
15522
|
/** Resolve the absolute path to a plugin's settings.json file. */
|
|
15299
15523
|
getSettingsPath(pluginName) {
|
|
15300
|
-
return
|
|
15524
|
+
return path29.join(this.basePath, pluginName, "settings.json");
|
|
15301
15525
|
}
|
|
15302
15526
|
async getPluginSettings(pluginName) {
|
|
15303
15527
|
return this.loadSettings(pluginName);
|
|
@@ -15327,7 +15551,7 @@ var init_settings_manager = __esm({
|
|
|
15327
15551
|
}
|
|
15328
15552
|
}
|
|
15329
15553
|
writeFile(data) {
|
|
15330
|
-
const dir =
|
|
15554
|
+
const dir = path29.dirname(this.settingsPath);
|
|
15331
15555
|
fs25.mkdirSync(dir, { recursive: true });
|
|
15332
15556
|
fs25.writeFileSync(this.settingsPath, JSON.stringify(data, null, 2));
|
|
15333
15557
|
this.cache = data;
|
|
@@ -15364,7 +15588,7 @@ var init_settings_manager = __esm({
|
|
|
15364
15588
|
});
|
|
15365
15589
|
|
|
15366
15590
|
// src/core/doctor/checks/telegram.ts
|
|
15367
|
-
import * as
|
|
15591
|
+
import * as path30 from "path";
|
|
15368
15592
|
var BOT_TOKEN_REGEX, telegramCheck;
|
|
15369
15593
|
var init_telegram = __esm({
|
|
15370
15594
|
"src/core/doctor/checks/telegram.ts"() {
|
|
@@ -15380,7 +15604,7 @@ var init_telegram = __esm({
|
|
|
15380
15604
|
return results;
|
|
15381
15605
|
}
|
|
15382
15606
|
const { SettingsManager: SettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
|
|
15383
|
-
const sm = new SettingsManager2(
|
|
15607
|
+
const sm = new SettingsManager2(path30.join(ctx.pluginsDir, "data"));
|
|
15384
15608
|
const ps = await sm.loadSettings("@openacp/telegram");
|
|
15385
15609
|
const botToken = ps.botToken;
|
|
15386
15610
|
const chatId = ps.chatId;
|
|
@@ -15552,7 +15776,7 @@ var init_storage = __esm({
|
|
|
15552
15776
|
|
|
15553
15777
|
// src/core/doctor/checks/workspace.ts
|
|
15554
15778
|
import * as fs27 from "fs";
|
|
15555
|
-
import * as
|
|
15779
|
+
import * as path31 from "path";
|
|
15556
15780
|
var workspaceCheck;
|
|
15557
15781
|
var init_workspace2 = __esm({
|
|
15558
15782
|
"src/core/doctor/checks/workspace.ts"() {
|
|
@@ -15562,7 +15786,7 @@ var init_workspace2 = __esm({
|
|
|
15562
15786
|
order: 5,
|
|
15563
15787
|
async run(ctx) {
|
|
15564
15788
|
const results = [];
|
|
15565
|
-
const workspace =
|
|
15789
|
+
const workspace = path31.dirname(ctx.dataDir);
|
|
15566
15790
|
if (!fs27.existsSync(workspace)) {
|
|
15567
15791
|
results.push({
|
|
15568
15792
|
status: "warn",
|
|
@@ -15590,7 +15814,7 @@ var init_workspace2 = __esm({
|
|
|
15590
15814
|
|
|
15591
15815
|
// src/core/doctor/checks/plugins.ts
|
|
15592
15816
|
import * as fs28 from "fs";
|
|
15593
|
-
import * as
|
|
15817
|
+
import * as path32 from "path";
|
|
15594
15818
|
var pluginsCheck;
|
|
15595
15819
|
var init_plugins2 = __esm({
|
|
15596
15820
|
"src/core/doctor/checks/plugins.ts"() {
|
|
@@ -15609,7 +15833,7 @@ var init_plugins2 = __esm({
|
|
|
15609
15833
|
fix: async () => {
|
|
15610
15834
|
fs28.mkdirSync(ctx.pluginsDir, { recursive: true });
|
|
15611
15835
|
fs28.writeFileSync(
|
|
15612
|
-
|
|
15836
|
+
path32.join(ctx.pluginsDir, "package.json"),
|
|
15613
15837
|
JSON.stringify({ name: "openacp-plugins", private: true, dependencies: {} }, null, 2)
|
|
15614
15838
|
);
|
|
15615
15839
|
return { success: true, message: "initialized plugins directory" };
|
|
@@ -15618,7 +15842,7 @@ var init_plugins2 = __esm({
|
|
|
15618
15842
|
return results;
|
|
15619
15843
|
}
|
|
15620
15844
|
results.push({ status: "pass", message: "Plugins directory exists" });
|
|
15621
|
-
const pkgPath =
|
|
15845
|
+
const pkgPath = path32.join(ctx.pluginsDir, "package.json");
|
|
15622
15846
|
if (!fs28.existsSync(pkgPath)) {
|
|
15623
15847
|
results.push({
|
|
15624
15848
|
status: "warn",
|
|
@@ -15673,12 +15897,12 @@ function isProcessAlive(pid) {
|
|
|
15673
15897
|
}
|
|
15674
15898
|
}
|
|
15675
15899
|
function checkPortInUse(port) {
|
|
15676
|
-
return new Promise((
|
|
15900
|
+
return new Promise((resolve8) => {
|
|
15677
15901
|
const server = net.createServer();
|
|
15678
|
-
server.once("error", () =>
|
|
15902
|
+
server.once("error", () => resolve8(true));
|
|
15679
15903
|
server.once("listening", () => {
|
|
15680
15904
|
server.close();
|
|
15681
|
-
|
|
15905
|
+
resolve8(false);
|
|
15682
15906
|
});
|
|
15683
15907
|
server.listen(port, "127.0.0.1");
|
|
15684
15908
|
});
|
|
@@ -15765,7 +15989,7 @@ var init_daemon = __esm({
|
|
|
15765
15989
|
|
|
15766
15990
|
// src/core/doctor/checks/tunnel.ts
|
|
15767
15991
|
import * as fs30 from "fs";
|
|
15768
|
-
import * as
|
|
15992
|
+
import * as path33 from "path";
|
|
15769
15993
|
import * as os7 from "os";
|
|
15770
15994
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
15771
15995
|
var tunnelCheck;
|
|
@@ -15782,7 +16006,7 @@ var init_tunnel3 = __esm({
|
|
|
15782
16006
|
return results;
|
|
15783
16007
|
}
|
|
15784
16008
|
const { SettingsManager: SettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
|
|
15785
|
-
const sm = new SettingsManager2(
|
|
16009
|
+
const sm = new SettingsManager2(path33.join(ctx.pluginsDir, "data"));
|
|
15786
16010
|
const tunnelSettings = await sm.loadSettings("@openacp/tunnel");
|
|
15787
16011
|
const tunnelEnabled = tunnelSettings.enabled ?? false;
|
|
15788
16012
|
const provider = tunnelSettings.provider ?? "cloudflare";
|
|
@@ -15794,7 +16018,7 @@ var init_tunnel3 = __esm({
|
|
|
15794
16018
|
results.push({ status: "pass", message: `Tunnel provider: ${provider}` });
|
|
15795
16019
|
if (provider === "cloudflare") {
|
|
15796
16020
|
const binName = os7.platform() === "win32" ? "cloudflared.exe" : "cloudflared";
|
|
15797
|
-
const binPath =
|
|
16021
|
+
const binPath = path33.join(ctx.dataDir, "bin", binName);
|
|
15798
16022
|
let found = false;
|
|
15799
16023
|
if (fs30.existsSync(binPath)) {
|
|
15800
16024
|
found = true;
|
|
@@ -15842,7 +16066,7 @@ __export(doctor_exports, {
|
|
|
15842
16066
|
DoctorEngine: () => DoctorEngine
|
|
15843
16067
|
});
|
|
15844
16068
|
import * as fs31 from "fs";
|
|
15845
|
-
import * as
|
|
16069
|
+
import * as path34 from "path";
|
|
15846
16070
|
var ALL_CHECKS, CHECK_TIMEOUT_MS, DoctorEngine;
|
|
15847
16071
|
var init_doctor = __esm({
|
|
15848
16072
|
"src/core/doctor/index.ts"() {
|
|
@@ -15930,7 +16154,7 @@ var init_doctor = __esm({
|
|
|
15930
16154
|
/** Constructs the shared context used by all checks — loads config if available. */
|
|
15931
16155
|
async buildContext() {
|
|
15932
16156
|
const dataDir = this.dataDir;
|
|
15933
|
-
const configPath = process.env.OPENACP_CONFIG_PATH ||
|
|
16157
|
+
const configPath = process.env.OPENACP_CONFIG_PATH || path34.join(dataDir, "config.json");
|
|
15934
16158
|
let config = null;
|
|
15935
16159
|
let rawConfig = null;
|
|
15936
16160
|
try {
|
|
@@ -15941,16 +16165,16 @@ var init_doctor = __esm({
|
|
|
15941
16165
|
config = cm.get();
|
|
15942
16166
|
} catch {
|
|
15943
16167
|
}
|
|
15944
|
-
const logsDir = config ? expandHome2(config.logging.logDir) :
|
|
16168
|
+
const logsDir = config ? expandHome2(config.logging.logDir) : path34.join(dataDir, "logs");
|
|
15945
16169
|
return {
|
|
15946
16170
|
config,
|
|
15947
16171
|
rawConfig,
|
|
15948
16172
|
configPath,
|
|
15949
16173
|
dataDir,
|
|
15950
|
-
sessionsPath:
|
|
15951
|
-
pidPath:
|
|
15952
|
-
portFilePath:
|
|
15953
|
-
pluginsDir:
|
|
16174
|
+
sessionsPath: path34.join(dataDir, "sessions.json"),
|
|
16175
|
+
pidPath: path34.join(dataDir, "openacp.pid"),
|
|
16176
|
+
portFilePath: path34.join(dataDir, "api.port"),
|
|
16177
|
+
pluginsDir: path34.join(dataDir, "plugins"),
|
|
15954
16178
|
logsDir
|
|
15955
16179
|
};
|
|
15956
16180
|
}
|
|
@@ -17531,10 +17755,10 @@ var init_send_queue = __esm({
|
|
|
17531
17755
|
const type = opts?.type ?? "other";
|
|
17532
17756
|
const key = opts?.key;
|
|
17533
17757
|
const category = opts?.category;
|
|
17534
|
-
let
|
|
17758
|
+
let resolve8;
|
|
17535
17759
|
let reject;
|
|
17536
17760
|
const promise = new Promise((res, rej) => {
|
|
17537
|
-
|
|
17761
|
+
resolve8 = res;
|
|
17538
17762
|
reject = rej;
|
|
17539
17763
|
});
|
|
17540
17764
|
promise.catch(() => {
|
|
@@ -17545,12 +17769,12 @@ var init_send_queue = __esm({
|
|
|
17545
17769
|
);
|
|
17546
17770
|
if (idx !== -1) {
|
|
17547
17771
|
this.items[idx].resolve(void 0);
|
|
17548
|
-
this.items[idx] = { fn, type, key, category, resolve:
|
|
17772
|
+
this.items[idx] = { fn, type, key, category, resolve: resolve8, reject, promise };
|
|
17549
17773
|
this.scheduleProcess();
|
|
17550
17774
|
return promise;
|
|
17551
17775
|
}
|
|
17552
17776
|
}
|
|
17553
|
-
this.items.push({ fn, type, key, category, resolve:
|
|
17777
|
+
this.items.push({ fn, type, key, category, resolve: resolve8, reject, promise });
|
|
17554
17778
|
this.scheduleProcess();
|
|
17555
17779
|
return promise;
|
|
17556
17780
|
}
|
|
@@ -20507,10 +20731,10 @@ var install_context_exports = {};
|
|
|
20507
20731
|
__export(install_context_exports, {
|
|
20508
20732
|
createInstallContext: () => createInstallContext
|
|
20509
20733
|
});
|
|
20510
|
-
import
|
|
20734
|
+
import path35 from "path";
|
|
20511
20735
|
function createInstallContext(opts) {
|
|
20512
20736
|
const { pluginName, settingsManager, basePath, instanceRoot } = opts;
|
|
20513
|
-
const dataDir =
|
|
20737
|
+
const dataDir = path35.join(basePath, pluginName, "data");
|
|
20514
20738
|
return {
|
|
20515
20739
|
pluginName,
|
|
20516
20740
|
terminal: createTerminalIO(),
|
|
@@ -20538,13 +20762,13 @@ __export(api_client_exports, {
|
|
|
20538
20762
|
waitForPortFile: () => waitForPortFile
|
|
20539
20763
|
});
|
|
20540
20764
|
import * as fs33 from "fs";
|
|
20541
|
-
import * as
|
|
20765
|
+
import * as path37 from "path";
|
|
20542
20766
|
import { setTimeout as sleep } from "timers/promises";
|
|
20543
20767
|
function defaultPortFile(root) {
|
|
20544
|
-
return
|
|
20768
|
+
return path37.join(root, "api.port");
|
|
20545
20769
|
}
|
|
20546
20770
|
function defaultSecretFile(root) {
|
|
20547
|
-
return
|
|
20771
|
+
return path37.join(root, "api-secret");
|
|
20548
20772
|
}
|
|
20549
20773
|
async function waitForPortFile(portFilePath, timeoutMs = 5e3, intervalMs = 100) {
|
|
20550
20774
|
const deadline = Date.now() + timeoutMs;
|
|
@@ -20639,9 +20863,9 @@ var init_suggest = __esm({
|
|
|
20639
20863
|
|
|
20640
20864
|
// src/cli/instance-hint.ts
|
|
20641
20865
|
import os8 from "os";
|
|
20642
|
-
import
|
|
20866
|
+
import path38 from "path";
|
|
20643
20867
|
function printInstanceHint(root) {
|
|
20644
|
-
const workspaceDir =
|
|
20868
|
+
const workspaceDir = path38.dirname(root);
|
|
20645
20869
|
const displayPath = workspaceDir.replace(os8.homedir(), "~");
|
|
20646
20870
|
console.log(` Workspace: ${displayPath}`);
|
|
20647
20871
|
}
|
|
@@ -20657,23 +20881,23 @@ __export(resolve_instance_id_exports, {
|
|
|
20657
20881
|
resolveInstanceId: () => resolveInstanceId
|
|
20658
20882
|
});
|
|
20659
20883
|
import fs34 from "fs";
|
|
20660
|
-
import
|
|
20884
|
+
import path39 from "path";
|
|
20661
20885
|
function resolveInstanceId(instanceRoot) {
|
|
20662
20886
|
try {
|
|
20663
|
-
const configPath =
|
|
20887
|
+
const configPath = path39.join(instanceRoot, "config.json");
|
|
20664
20888
|
const raw = JSON.parse(fs34.readFileSync(configPath, "utf-8"));
|
|
20665
20889
|
if (raw.id && typeof raw.id === "string") return raw.id;
|
|
20666
20890
|
} catch {
|
|
20667
20891
|
}
|
|
20668
20892
|
try {
|
|
20669
|
-
const reg = new InstanceRegistry(
|
|
20893
|
+
const reg = new InstanceRegistry(path39.join(getGlobalRoot(), "instances.json"));
|
|
20670
20894
|
reg.load();
|
|
20671
20895
|
const entry = reg.getByRoot(instanceRoot);
|
|
20672
20896
|
if (entry?.id) return entry.id;
|
|
20673
20897
|
} catch (err) {
|
|
20674
20898
|
log31.debug({ err: err.message, instanceRoot }, "Could not read instance registry, using fallback id");
|
|
20675
20899
|
}
|
|
20676
|
-
return
|
|
20900
|
+
return path39.basename(path39.dirname(instanceRoot)).replace(/[^a-zA-Z0-9-]/g, "-") || "default";
|
|
20677
20901
|
}
|
|
20678
20902
|
var log31;
|
|
20679
20903
|
var init_resolve_instance_id = __esm({
|
|
@@ -20705,18 +20929,18 @@ __export(daemon_exports, {
|
|
|
20705
20929
|
});
|
|
20706
20930
|
import { spawn as spawn6 } from "child_process";
|
|
20707
20931
|
import * as fs35 from "fs";
|
|
20708
|
-
import * as
|
|
20932
|
+
import * as path40 from "path";
|
|
20709
20933
|
function getPidPath(root) {
|
|
20710
|
-
return
|
|
20934
|
+
return path40.join(root, "openacp.pid");
|
|
20711
20935
|
}
|
|
20712
20936
|
function getLogDir(root) {
|
|
20713
|
-
return
|
|
20937
|
+
return path40.join(root, "logs");
|
|
20714
20938
|
}
|
|
20715
20939
|
function getRunningMarker(root) {
|
|
20716
|
-
return
|
|
20940
|
+
return path40.join(root, "running");
|
|
20717
20941
|
}
|
|
20718
20942
|
function writePidFile(pidPath, pid) {
|
|
20719
|
-
const dir =
|
|
20943
|
+
const dir = path40.dirname(pidPath);
|
|
20720
20944
|
fs35.mkdirSync(dir, { recursive: true });
|
|
20721
20945
|
fs35.writeFileSync(pidPath, String(pid));
|
|
20722
20946
|
}
|
|
@@ -20765,8 +20989,8 @@ function startDaemon(pidPath, logDir2, instanceRoot) {
|
|
|
20765
20989
|
}
|
|
20766
20990
|
const resolvedLogDir = logDir2 ? expandHome2(logDir2) : getLogDir(instanceRoot);
|
|
20767
20991
|
fs35.mkdirSync(resolvedLogDir, { recursive: true });
|
|
20768
|
-
const logFile =
|
|
20769
|
-
const cliPath =
|
|
20992
|
+
const logFile = path40.join(resolvedLogDir, "openacp.log");
|
|
20993
|
+
const cliPath = path40.resolve(process.argv[1]);
|
|
20770
20994
|
const nodePath = process.execPath;
|
|
20771
20995
|
const out = fs35.openSync(logFile, "a");
|
|
20772
20996
|
const err = fs35.openSync(logFile, "a");
|
|
@@ -20788,7 +21012,7 @@ function startDaemon(pidPath, logDir2, instanceRoot) {
|
|
|
20788
21012
|
return { pid: child.pid };
|
|
20789
21013
|
}
|
|
20790
21014
|
function sleep2(ms) {
|
|
20791
|
-
return new Promise((
|
|
21015
|
+
return new Promise((resolve8) => setTimeout(resolve8, ms));
|
|
20792
21016
|
}
|
|
20793
21017
|
function isProcessAlive2(pid) {
|
|
20794
21018
|
try {
|
|
@@ -20850,7 +21074,7 @@ async function stopDaemon(pidPath, instanceRoot) {
|
|
|
20850
21074
|
}
|
|
20851
21075
|
function markRunning(root) {
|
|
20852
21076
|
const marker = getRunningMarker(root);
|
|
20853
|
-
fs35.mkdirSync(
|
|
21077
|
+
fs35.mkdirSync(path40.dirname(marker), { recursive: true });
|
|
20854
21078
|
fs35.writeFileSync(marker, "");
|
|
20855
21079
|
}
|
|
20856
21080
|
function clearRunning(root) {
|
|
@@ -20883,19 +21107,19 @@ __export(autostart_exports, {
|
|
|
20883
21107
|
});
|
|
20884
21108
|
import { execFileSync as execFileSync6 } from "child_process";
|
|
20885
21109
|
import * as fs36 from "fs";
|
|
20886
|
-
import * as
|
|
21110
|
+
import * as path41 from "path";
|
|
20887
21111
|
import * as os9 from "os";
|
|
20888
21112
|
function getLaunchdLabel(instanceId) {
|
|
20889
21113
|
return `com.openacp.daemon.${instanceId}`;
|
|
20890
21114
|
}
|
|
20891
21115
|
function getLaunchdPlistPath(instanceId) {
|
|
20892
|
-
return
|
|
21116
|
+
return path41.join(os9.homedir(), "Library", "LaunchAgents", `${getLaunchdLabel(instanceId)}.plist`);
|
|
20893
21117
|
}
|
|
20894
21118
|
function getSystemdServiceName(instanceId) {
|
|
20895
21119
|
return `openacp-${instanceId}`;
|
|
20896
21120
|
}
|
|
20897
21121
|
function getSystemdServicePath(instanceId) {
|
|
20898
|
-
return
|
|
21122
|
+
return path41.join(os9.homedir(), ".config", "systemd", "user", `${getSystemdServiceName(instanceId)}.service`);
|
|
20899
21123
|
}
|
|
20900
21124
|
function isAutoStartSupported() {
|
|
20901
21125
|
return process.platform === "darwin" || process.platform === "linux";
|
|
@@ -20909,7 +21133,7 @@ function escapeSystemdValue(str) {
|
|
|
20909
21133
|
}
|
|
20910
21134
|
function generateLaunchdPlist(nodePath, cliPath, logDir2, instanceRoot, instanceId) {
|
|
20911
21135
|
const label = getLaunchdLabel(instanceId);
|
|
20912
|
-
const logFile =
|
|
21136
|
+
const logFile = path41.join(logDir2, "openacp.log");
|
|
20913
21137
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
20914
21138
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
20915
21139
|
<plist version="1.0">
|
|
@@ -20991,14 +21215,14 @@ function installAutoStart(logDir2, instanceRoot, instanceId) {
|
|
|
20991
21215
|
return { success: false, error: "Auto-start not supported on this platform" };
|
|
20992
21216
|
}
|
|
20993
21217
|
const nodePath = process.execPath;
|
|
20994
|
-
const cliPath =
|
|
20995
|
-
const resolvedLogDir = logDir2.startsWith("~") ?
|
|
21218
|
+
const cliPath = path41.resolve(process.argv[1]);
|
|
21219
|
+
const resolvedLogDir = logDir2.startsWith("~") ? path41.join(os9.homedir(), logDir2.slice(1)) : logDir2;
|
|
20996
21220
|
try {
|
|
20997
21221
|
migrateLegacy();
|
|
20998
21222
|
if (process.platform === "darwin") {
|
|
20999
21223
|
const plistPath = getLaunchdPlistPath(instanceId);
|
|
21000
21224
|
const plist = generateLaunchdPlist(nodePath, cliPath, resolvedLogDir, instanceRoot, instanceId);
|
|
21001
|
-
const dir =
|
|
21225
|
+
const dir = path41.dirname(plistPath);
|
|
21002
21226
|
fs36.mkdirSync(dir, { recursive: true });
|
|
21003
21227
|
fs36.writeFileSync(plistPath, plist);
|
|
21004
21228
|
const uid = process.getuid();
|
|
@@ -21015,7 +21239,7 @@ function installAutoStart(logDir2, instanceRoot, instanceId) {
|
|
|
21015
21239
|
const servicePath = getSystemdServicePath(instanceId);
|
|
21016
21240
|
const serviceName = getSystemdServiceName(instanceId);
|
|
21017
21241
|
const unit = generateSystemdUnit(nodePath, cliPath, instanceRoot, instanceId);
|
|
21018
|
-
const dir =
|
|
21242
|
+
const dir = path41.dirname(servicePath);
|
|
21019
21243
|
fs36.mkdirSync(dir, { recursive: true });
|
|
21020
21244
|
fs36.writeFileSync(servicePath, unit);
|
|
21021
21245
|
execFileSync6("systemctl", ["--user", "daemon-reload"], { stdio: "pipe" });
|
|
@@ -21084,8 +21308,8 @@ var init_autostart = __esm({
|
|
|
21084
21308
|
"use strict";
|
|
21085
21309
|
init_log();
|
|
21086
21310
|
log32 = createChildLogger({ module: "autostart" });
|
|
21087
|
-
LEGACY_LAUNCHD_PLIST_PATH =
|
|
21088
|
-
LEGACY_SYSTEMD_SERVICE_PATH =
|
|
21311
|
+
LEGACY_LAUNCHD_PLIST_PATH = path41.join(os9.homedir(), "Library", "LaunchAgents", "com.openacp.daemon.plist");
|
|
21312
|
+
LEGACY_SYSTEMD_SERVICE_PATH = path41.join(os9.homedir(), ".config", "systemd", "user", "openacp.service");
|
|
21089
21313
|
}
|
|
21090
21314
|
});
|
|
21091
21315
|
|
|
@@ -21140,7 +21364,7 @@ var init_stop = __esm({
|
|
|
21140
21364
|
|
|
21141
21365
|
// src/core/security/path-guard.ts
|
|
21142
21366
|
import fs37 from "fs";
|
|
21143
|
-
import
|
|
21367
|
+
import path43 from "path";
|
|
21144
21368
|
import ignore from "ignore";
|
|
21145
21369
|
var DEFAULT_DENY_PATTERNS, PathGuard;
|
|
21146
21370
|
var init_path_guard = __esm({
|
|
@@ -21169,15 +21393,15 @@ var init_path_guard = __esm({
|
|
|
21169
21393
|
ig;
|
|
21170
21394
|
constructor(options) {
|
|
21171
21395
|
try {
|
|
21172
|
-
this.cwd = fs37.realpathSync(
|
|
21396
|
+
this.cwd = fs37.realpathSync(path43.resolve(options.cwd));
|
|
21173
21397
|
} catch {
|
|
21174
|
-
this.cwd =
|
|
21398
|
+
this.cwd = path43.resolve(options.cwd);
|
|
21175
21399
|
}
|
|
21176
21400
|
this.allowedPaths = options.allowedPaths.map((p2) => {
|
|
21177
21401
|
try {
|
|
21178
|
-
return fs37.realpathSync(
|
|
21402
|
+
return fs37.realpathSync(path43.resolve(p2));
|
|
21179
21403
|
} catch {
|
|
21180
|
-
return
|
|
21404
|
+
return path43.resolve(p2);
|
|
21181
21405
|
}
|
|
21182
21406
|
});
|
|
21183
21407
|
this.ig = ignore();
|
|
@@ -21201,19 +21425,19 @@ var init_path_guard = __esm({
|
|
|
21201
21425
|
* @returns `{ allowed: true }` or `{ allowed: false, reason: "..." }`
|
|
21202
21426
|
*/
|
|
21203
21427
|
validatePath(targetPath, operation) {
|
|
21204
|
-
const resolved =
|
|
21428
|
+
const resolved = path43.resolve(targetPath);
|
|
21205
21429
|
let realPath;
|
|
21206
21430
|
try {
|
|
21207
21431
|
realPath = fs37.realpathSync(resolved);
|
|
21208
21432
|
} catch {
|
|
21209
21433
|
realPath = resolved;
|
|
21210
21434
|
}
|
|
21211
|
-
if (operation === "write" &&
|
|
21435
|
+
if (operation === "write" && path43.basename(realPath) === ".openacpignore") {
|
|
21212
21436
|
return { allowed: false, reason: "Cannot write to .openacpignore" };
|
|
21213
21437
|
}
|
|
21214
|
-
const isWithinCwd = realPath === this.cwd || realPath.startsWith(this.cwd +
|
|
21438
|
+
const isWithinCwd = realPath === this.cwd || realPath.startsWith(this.cwd + path43.sep);
|
|
21215
21439
|
const isWithinAllowed = this.allowedPaths.some(
|
|
21216
|
-
(ap) => realPath === ap || realPath.startsWith(ap +
|
|
21440
|
+
(ap) => realPath === ap || realPath.startsWith(ap + path43.sep)
|
|
21217
21441
|
);
|
|
21218
21442
|
if (!isWithinCwd && !isWithinAllowed) {
|
|
21219
21443
|
return {
|
|
@@ -21222,7 +21446,7 @@ var init_path_guard = __esm({
|
|
|
21222
21446
|
};
|
|
21223
21447
|
}
|
|
21224
21448
|
if (isWithinCwd && !isWithinAllowed) {
|
|
21225
|
-
const relativePath =
|
|
21449
|
+
const relativePath = path43.relative(this.cwd, realPath);
|
|
21226
21450
|
if (relativePath === ".openacpignore") {
|
|
21227
21451
|
return { allowed: true, reason: "" };
|
|
21228
21452
|
}
|
|
@@ -21238,9 +21462,9 @@ var init_path_guard = __esm({
|
|
|
21238
21462
|
/** Adds an additional allowed path at runtime (e.g. for file-service uploads). */
|
|
21239
21463
|
addAllowedPath(p2) {
|
|
21240
21464
|
try {
|
|
21241
|
-
this.allowedPaths.push(fs37.realpathSync(
|
|
21465
|
+
this.allowedPaths.push(fs37.realpathSync(path43.resolve(p2)));
|
|
21242
21466
|
} catch {
|
|
21243
|
-
this.allowedPaths.push(
|
|
21467
|
+
this.allowedPaths.push(path43.resolve(p2));
|
|
21244
21468
|
}
|
|
21245
21469
|
}
|
|
21246
21470
|
/**
|
|
@@ -21248,7 +21472,7 @@ var init_path_guard = __esm({
|
|
|
21248
21472
|
* Follows .gitignore syntax — blank lines and lines starting with # are skipped.
|
|
21249
21473
|
*/
|
|
21250
21474
|
static loadIgnoreFile(cwd) {
|
|
21251
|
-
const ignorePath =
|
|
21475
|
+
const ignorePath = path43.join(cwd, ".openacpignore");
|
|
21252
21476
|
try {
|
|
21253
21477
|
const content = fs37.readFileSync(ignorePath, "utf-8");
|
|
21254
21478
|
return content.split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
@@ -21328,15 +21552,15 @@ var init_env_filter = __esm({
|
|
|
21328
21552
|
function nodeToWebWritable(nodeStream) {
|
|
21329
21553
|
return new WritableStream({
|
|
21330
21554
|
write(chunk) {
|
|
21331
|
-
return new Promise((
|
|
21555
|
+
return new Promise((resolve8, reject) => {
|
|
21332
21556
|
const ok3 = nodeStream.write(chunk);
|
|
21333
21557
|
if (ok3) {
|
|
21334
|
-
|
|
21558
|
+
resolve8();
|
|
21335
21559
|
return;
|
|
21336
21560
|
}
|
|
21337
21561
|
const onDrain = () => {
|
|
21338
21562
|
nodeStream.removeListener("error", onError);
|
|
21339
|
-
|
|
21563
|
+
resolve8();
|
|
21340
21564
|
};
|
|
21341
21565
|
const onError = (err) => {
|
|
21342
21566
|
nodeStream.removeListener("drain", onDrain);
|
|
@@ -21666,12 +21890,12 @@ var init_terminal_manager = __esm({
|
|
|
21666
21890
|
signal: state.exitStatus.signal
|
|
21667
21891
|
};
|
|
21668
21892
|
}
|
|
21669
|
-
return new Promise((
|
|
21893
|
+
return new Promise((resolve8) => {
|
|
21670
21894
|
state.process.on("exit", (code, signal) => {
|
|
21671
|
-
|
|
21895
|
+
resolve8({ exitCode: code, signal });
|
|
21672
21896
|
});
|
|
21673
21897
|
if (state.exitStatus !== null) {
|
|
21674
|
-
|
|
21898
|
+
resolve8({
|
|
21675
21899
|
exitCode: state.exitStatus.exitCode,
|
|
21676
21900
|
signal: state.exitStatus.signal
|
|
21677
21901
|
});
|
|
@@ -21725,7 +21949,7 @@ var init_mcp_manager = __esm({
|
|
|
21725
21949
|
|
|
21726
21950
|
// src/core/utils/debug-tracer.ts
|
|
21727
21951
|
import fs38 from "fs";
|
|
21728
|
-
import
|
|
21952
|
+
import path44 from "path";
|
|
21729
21953
|
function createDebugTracer(sessionId, workingDirectory) {
|
|
21730
21954
|
if (!DEBUG_ENABLED) return null;
|
|
21731
21955
|
return new DebugTracer(sessionId, workingDirectory);
|
|
@@ -21739,7 +21963,7 @@ var init_debug_tracer = __esm({
|
|
|
21739
21963
|
constructor(sessionId, workingDirectory) {
|
|
21740
21964
|
this.sessionId = sessionId;
|
|
21741
21965
|
this.workingDirectory = workingDirectory;
|
|
21742
|
-
this.logDir =
|
|
21966
|
+
this.logDir = path44.join(workingDirectory, ".log");
|
|
21743
21967
|
}
|
|
21744
21968
|
sessionId;
|
|
21745
21969
|
workingDirectory;
|
|
@@ -21757,7 +21981,7 @@ var init_debug_tracer = __esm({
|
|
|
21757
21981
|
fs38.mkdirSync(this.logDir, { recursive: true });
|
|
21758
21982
|
this.dirCreated = true;
|
|
21759
21983
|
}
|
|
21760
|
-
const filePath =
|
|
21984
|
+
const filePath = path44.join(this.logDir, `${this.sessionId}_${layer}.jsonl`);
|
|
21761
21985
|
const seen = /* @__PURE__ */ new WeakSet();
|
|
21762
21986
|
const line = JSON.stringify({ ts: Date.now(), ...data }, (_key, value) => {
|
|
21763
21987
|
if (typeof value === "object" && value !== null) {
|
|
@@ -21781,21 +22005,21 @@ var init_debug_tracer = __esm({
|
|
|
21781
22005
|
import { spawn as spawn8, execFileSync as execFileSync7 } from "child_process";
|
|
21782
22006
|
import { Transform } from "stream";
|
|
21783
22007
|
import fs39 from "fs";
|
|
21784
|
-
import
|
|
22008
|
+
import path45 from "path";
|
|
21785
22009
|
import { ClientSideConnection, ndJsonStream } from "@agentclientprotocol/sdk";
|
|
21786
22010
|
import { PROTOCOL_VERSION } from "@agentclientprotocol/sdk";
|
|
21787
22011
|
function findPackageRoot(startDir) {
|
|
21788
22012
|
let dir = startDir;
|
|
21789
|
-
while (dir !==
|
|
21790
|
-
if (fs39.existsSync(
|
|
22013
|
+
while (dir !== path45.dirname(dir)) {
|
|
22014
|
+
if (fs39.existsSync(path45.join(dir, "package.json"))) {
|
|
21791
22015
|
return dir;
|
|
21792
22016
|
}
|
|
21793
|
-
dir =
|
|
22017
|
+
dir = path45.dirname(dir);
|
|
21794
22018
|
}
|
|
21795
22019
|
return startDir;
|
|
21796
22020
|
}
|
|
21797
22021
|
function commandForWindowsScript(filePath) {
|
|
21798
|
-
const ext =
|
|
22022
|
+
const ext = path45.extname(filePath).toLowerCase();
|
|
21799
22023
|
if (process.platform === "win32" && (ext === ".cmd" || ext === ".bat")) {
|
|
21800
22024
|
return { command: process.env.ComSpec ?? "cmd.exe", args: ["/d", "/s", "/c", `"${filePath}"`] };
|
|
21801
22025
|
}
|
|
@@ -21809,8 +22033,8 @@ function resolveAgentCommand(cmd) {
|
|
|
21809
22033
|
}
|
|
21810
22034
|
for (const root of searchRoots) {
|
|
21811
22035
|
const packageDirs = [
|
|
21812
|
-
|
|
21813
|
-
|
|
22036
|
+
path45.resolve(root, "node_modules", "@zed-industries", cmd, "dist", "index.js"),
|
|
22037
|
+
path45.resolve(root, "node_modules", cmd, "dist", "index.js")
|
|
21814
22038
|
];
|
|
21815
22039
|
for (const jsPath of packageDirs) {
|
|
21816
22040
|
if (fs39.existsSync(jsPath)) {
|
|
@@ -21819,7 +22043,7 @@ function resolveAgentCommand(cmd) {
|
|
|
21819
22043
|
}
|
|
21820
22044
|
}
|
|
21821
22045
|
for (const root of searchRoots) {
|
|
21822
|
-
const localBin =
|
|
22046
|
+
const localBin = path45.resolve(root, "node_modules", ".bin", cmd);
|
|
21823
22047
|
if (fs39.existsSync(localBin)) {
|
|
21824
22048
|
const content = fs39.readFileSync(localBin, "utf-8");
|
|
21825
22049
|
if (content.startsWith("#!/usr/bin/env node")) {
|
|
@@ -21827,7 +22051,7 @@ function resolveAgentCommand(cmd) {
|
|
|
21827
22051
|
}
|
|
21828
22052
|
const match = content.match(/"([^"]+\.js)"/);
|
|
21829
22053
|
if (match) {
|
|
21830
|
-
const target =
|
|
22054
|
+
const target = path45.resolve(path45.dirname(localBin), match[1]);
|
|
21831
22055
|
if (fs39.existsSync(target)) {
|
|
21832
22056
|
return { command: process.execPath, args: [target] };
|
|
21833
22057
|
}
|
|
@@ -21843,9 +22067,9 @@ function resolveAgentCommand(cmd) {
|
|
|
21843
22067
|
candidates.push(dir);
|
|
21844
22068
|
}
|
|
21845
22069
|
};
|
|
21846
|
-
addCandidate(
|
|
22070
|
+
addCandidate(path45.dirname(process.execPath));
|
|
21847
22071
|
try {
|
|
21848
|
-
addCandidate(
|
|
22072
|
+
addCandidate(path45.dirname(fs39.realpathSync(process.execPath)));
|
|
21849
22073
|
} catch {
|
|
21850
22074
|
}
|
|
21851
22075
|
addCandidate("/opt/homebrew/bin");
|
|
@@ -21854,8 +22078,8 @@ function resolveAgentCommand(cmd) {
|
|
|
21854
22078
|
for (const dir of candidates) {
|
|
21855
22079
|
if (cmd === "npx") {
|
|
21856
22080
|
const npxCliCandidates = [
|
|
21857
|
-
|
|
21858
|
-
|
|
22081
|
+
path45.join(dir, "node_modules", "npm", "bin", "npx-cli.js"),
|
|
22082
|
+
path45.join(path45.dirname(dir), "lib", "node_modules", "npm", "bin", "npx-cli.js")
|
|
21859
22083
|
];
|
|
21860
22084
|
for (const npxCli of npxCliCandidates) {
|
|
21861
22085
|
if (fs39.existsSync(npxCli)) {
|
|
@@ -21865,7 +22089,7 @@ function resolveAgentCommand(cmd) {
|
|
|
21865
22089
|
}
|
|
21866
22090
|
}
|
|
21867
22091
|
for (const name of executableNames) {
|
|
21868
|
-
const candidate =
|
|
22092
|
+
const candidate = path45.join(dir, name);
|
|
21869
22093
|
if (fs39.existsSync(candidate)) {
|
|
21870
22094
|
const resolved = commandForWindowsScript(candidate);
|
|
21871
22095
|
log33.info({ cmd, resolved: candidate }, "Resolved package runner from fallback search");
|
|
@@ -21877,7 +22101,7 @@ function resolveAgentCommand(cmd) {
|
|
|
21877
22101
|
}
|
|
21878
22102
|
try {
|
|
21879
22103
|
const fullPath = execFileSync7("which", [cmd], { encoding: "utf-8" }).trim();
|
|
21880
|
-
const isUnspawnableWindowsShim = process.platform === "win32" && (cmd === "npx" || cmd === "uvx") && !
|
|
22104
|
+
const isUnspawnableWindowsShim = process.platform === "win32" && (cmd === "npx" || cmd === "uvx") && !path45.extname(fullPath);
|
|
21881
22105
|
if (fullPath && !isUnspawnableWindowsShim) {
|
|
21882
22106
|
try {
|
|
21883
22107
|
const content = fs39.readFileSync(fullPath, "utf-8");
|
|
@@ -21894,7 +22118,7 @@ function resolveAgentCommand(cmd) {
|
|
|
21894
22118
|
}
|
|
21895
22119
|
function withAgentTimeout(promise, agentName, op, timeoutMs) {
|
|
21896
22120
|
const timeout = timeoutMs ?? AGENT_INIT_TIMEOUT_MS;
|
|
21897
|
-
return new Promise((
|
|
22121
|
+
return new Promise((resolve8, reject) => {
|
|
21898
22122
|
const timer = setTimeout(() => {
|
|
21899
22123
|
reject(new Error(
|
|
21900
22124
|
`Agent "${agentName}" did not respond to ${op} within ${timeout / 1e3}s. The agent process may have hung during initialization.`
|
|
@@ -21903,7 +22127,7 @@ function withAgentTimeout(promise, agentName, op, timeoutMs) {
|
|
|
21903
22127
|
promise.then(
|
|
21904
22128
|
(val) => {
|
|
21905
22129
|
clearTimeout(timer);
|
|
21906
|
-
|
|
22130
|
+
resolve8(val);
|
|
21907
22131
|
},
|
|
21908
22132
|
(err) => {
|
|
21909
22133
|
clearTimeout(timer);
|
|
@@ -22007,7 +22231,7 @@ var init_agent_instance = __esm({
|
|
|
22007
22231
|
env: filterEnv(process.env, agentDef.env)
|
|
22008
22232
|
}
|
|
22009
22233
|
);
|
|
22010
|
-
await new Promise((
|
|
22234
|
+
await new Promise((resolve8, reject) => {
|
|
22011
22235
|
instance.child.on("error", (err) => {
|
|
22012
22236
|
reject(
|
|
22013
22237
|
new Error(
|
|
@@ -22015,7 +22239,7 @@ var init_agent_instance = __esm({
|
|
|
22015
22239
|
)
|
|
22016
22240
|
);
|
|
22017
22241
|
});
|
|
22018
|
-
instance.child.on("spawn", () =>
|
|
22242
|
+
instance.child.on("spawn", () => resolve8());
|
|
22019
22243
|
});
|
|
22020
22244
|
instance.stderrCapture = new StderrCapture(50);
|
|
22021
22245
|
instance.child.stderr.on("data", (chunk) => {
|
|
@@ -22458,7 +22682,7 @@ ${stderr}`
|
|
|
22458
22682
|
writePath = result.path;
|
|
22459
22683
|
writeContent = result.content;
|
|
22460
22684
|
}
|
|
22461
|
-
await fs39.promises.mkdir(
|
|
22685
|
+
await fs39.promises.mkdir(path45.dirname(writePath), { recursive: true });
|
|
22462
22686
|
await fs39.promises.writeFile(writePath, writeContent, "utf-8");
|
|
22463
22687
|
return {};
|
|
22464
22688
|
},
|
|
@@ -22641,15 +22865,15 @@ ${skipNote}`;
|
|
|
22641
22865
|
this._destroying = true;
|
|
22642
22866
|
this.terminalManager.destroyAll();
|
|
22643
22867
|
if (this.child.exitCode !== null) return;
|
|
22644
|
-
await new Promise((
|
|
22868
|
+
await new Promise((resolve8) => {
|
|
22645
22869
|
this.child.on("exit", () => {
|
|
22646
22870
|
clearTimeout(forceKillTimer);
|
|
22647
|
-
|
|
22871
|
+
resolve8();
|
|
22648
22872
|
});
|
|
22649
22873
|
this.child.kill("SIGTERM");
|
|
22650
22874
|
const forceKillTimer = setTimeout(() => {
|
|
22651
22875
|
if (this.child.exitCode === null) this.child.kill("SIGKILL");
|
|
22652
|
-
|
|
22876
|
+
resolve8();
|
|
22653
22877
|
}, 1e4);
|
|
22654
22878
|
if (typeof forceKillTimer === "object" && forceKillTimer !== null && "unref" in forceKillTimer) {
|
|
22655
22879
|
forceKillTimer.unref();
|
|
@@ -22894,8 +23118,8 @@ var init_prompt_queue = __esm({
|
|
|
22894
23118
|
if (this.processing) {
|
|
22895
23119
|
const position = this.queue.length + 1;
|
|
22896
23120
|
this.onActuallyQueued?.(turnId, position, routing);
|
|
22897
|
-
return new Promise((
|
|
22898
|
-
this.queue.push({ text: text5, userPrompt, attachments, routing, turnId, meta, resolve:
|
|
23121
|
+
return new Promise((resolve8) => {
|
|
23122
|
+
this.queue.push({ text: text5, userPrompt, attachments, routing, turnId, meta, resolve: resolve8 });
|
|
22899
23123
|
});
|
|
22900
23124
|
}
|
|
22901
23125
|
await this.process(text5, userPrompt, attachments, routing, turnId, meta);
|
|
@@ -23031,8 +23255,8 @@ var init_permission_gate = __esm({
|
|
|
23031
23255
|
this.request = request;
|
|
23032
23256
|
this.settled = false;
|
|
23033
23257
|
this.clearTimeout();
|
|
23034
|
-
return new Promise((
|
|
23035
|
-
this.resolveFn =
|
|
23258
|
+
return new Promise((resolve8, reject) => {
|
|
23259
|
+
this.resolveFn = resolve8;
|
|
23036
23260
|
this.rejectFn = reject;
|
|
23037
23261
|
this.timeoutTimer = setTimeout(() => {
|
|
23038
23262
|
this.reject("Permission request timed out (no response received)");
|
|
@@ -24718,7 +24942,7 @@ var init_extract_file_info = __esm({
|
|
|
24718
24942
|
});
|
|
24719
24943
|
|
|
24720
24944
|
// src/core/message-transformer.ts
|
|
24721
|
-
import * as
|
|
24945
|
+
import * as path46 from "path";
|
|
24722
24946
|
function computeLineDiff(oldStr, newStr) {
|
|
24723
24947
|
const oldLines = oldStr ? oldStr.split("\n") : [];
|
|
24724
24948
|
const newLines = newStr ? newStr.split("\n") : [];
|
|
@@ -25024,7 +25248,7 @@ var init_message_transformer = __esm({
|
|
|
25024
25248
|
);
|
|
25025
25249
|
return;
|
|
25026
25250
|
}
|
|
25027
|
-
const fileExt =
|
|
25251
|
+
const fileExt = path46.extname(fileInfo.filePath).toLowerCase();
|
|
25028
25252
|
if (BINARY_VIEWER_EXTENSIONS.has(fileExt)) {
|
|
25029
25253
|
log36.debug({ kind, filePath: fileInfo.filePath }, "enrichWithViewerLinks: skipping binary file");
|
|
25030
25254
|
return;
|
|
@@ -25079,7 +25303,7 @@ var init_message_transformer = __esm({
|
|
|
25079
25303
|
|
|
25080
25304
|
// src/core/sessions/session-store.ts
|
|
25081
25305
|
import fs41 from "fs";
|
|
25082
|
-
import
|
|
25306
|
+
import path47 from "path";
|
|
25083
25307
|
var log37, DEBOUNCE_MS3, JsonFileSessionStore;
|
|
25084
25308
|
var init_session_store = __esm({
|
|
25085
25309
|
"src/core/sessions/session-store.ts"() {
|
|
@@ -25171,7 +25395,7 @@ var init_session_store = __esm({
|
|
|
25171
25395
|
version: 1,
|
|
25172
25396
|
sessions: Object.fromEntries(this.records)
|
|
25173
25397
|
};
|
|
25174
|
-
const dir =
|
|
25398
|
+
const dir = path47.dirname(this.filePath);
|
|
25175
25399
|
if (!fs41.existsSync(dir)) fs41.mkdirSync(dir, { recursive: true });
|
|
25176
25400
|
const tmpPath = `${this.filePath}.tmp`;
|
|
25177
25401
|
fs41.writeFileSync(tmpPath, JSON.stringify(data, null, 2));
|
|
@@ -25940,7 +26164,7 @@ __export(agent_catalog_exports, {
|
|
|
25940
26164
|
AgentCatalog: () => AgentCatalog
|
|
25941
26165
|
});
|
|
25942
26166
|
import * as fs42 from "fs";
|
|
25943
|
-
import * as
|
|
26167
|
+
import * as path48 from "path";
|
|
25944
26168
|
function stripNpmVersion(pkg) {
|
|
25945
26169
|
if (pkg.startsWith("@")) {
|
|
25946
26170
|
const slashIdx = pkg.indexOf("/");
|
|
@@ -26007,7 +26231,7 @@ var init_agent_catalog = __esm({
|
|
|
26007
26231
|
ttlHours: DEFAULT_TTL_HOURS,
|
|
26008
26232
|
data
|
|
26009
26233
|
};
|
|
26010
|
-
fs42.mkdirSync(
|
|
26234
|
+
fs42.mkdirSync(path48.dirname(this.cachePath), { recursive: true });
|
|
26011
26235
|
fs42.writeFileSync(this.cachePath, JSON.stringify(cache, null, 2), { mode: 384 });
|
|
26012
26236
|
this.enrichInstalledFromRegistry();
|
|
26013
26237
|
log40.info({ count: this.registryAgents.length }, "Registry updated");
|
|
@@ -26249,9 +26473,9 @@ var init_agent_catalog = __esm({
|
|
|
26249
26473
|
}
|
|
26250
26474
|
try {
|
|
26251
26475
|
const candidates = [
|
|
26252
|
-
|
|
26253
|
-
|
|
26254
|
-
|
|
26476
|
+
path48.join(import.meta.dirname, "data", "registry-snapshot.json"),
|
|
26477
|
+
path48.join(import.meta.dirname, "..", "data", "registry-snapshot.json"),
|
|
26478
|
+
path48.join(import.meta.dirname, "..", "..", "data", "registry-snapshot.json")
|
|
26255
26479
|
];
|
|
26256
26480
|
for (const candidate of candidates) {
|
|
26257
26481
|
if (fs42.existsSync(candidate)) {
|
|
@@ -26276,7 +26500,7 @@ __export(agent_store_exports, {
|
|
|
26276
26500
|
AgentStore: () => AgentStore
|
|
26277
26501
|
});
|
|
26278
26502
|
import * as fs43 from "fs";
|
|
26279
|
-
import * as
|
|
26503
|
+
import * as path49 from "path";
|
|
26280
26504
|
import { z as z10 } from "zod";
|
|
26281
26505
|
var log41, InstalledAgentSchema, AgentStoreSchema, AgentStore;
|
|
26282
26506
|
var init_agent_store = __esm({
|
|
@@ -26353,7 +26577,7 @@ var init_agent_store = __esm({
|
|
|
26353
26577
|
* may contain agent binary paths and environment variables.
|
|
26354
26578
|
*/
|
|
26355
26579
|
save() {
|
|
26356
|
-
fs43.mkdirSync(
|
|
26580
|
+
fs43.mkdirSync(path49.dirname(this.filePath), { recursive: true });
|
|
26357
26581
|
const tmpPath = this.filePath + ".tmp";
|
|
26358
26582
|
fs43.writeFileSync(tmpPath, JSON.stringify(this.data, null, 2), { mode: 384 });
|
|
26359
26583
|
fs43.renameSync(tmpPath, this.filePath);
|
|
@@ -26672,7 +26896,7 @@ var init_error_tracker = __esm({
|
|
|
26672
26896
|
|
|
26673
26897
|
// src/core/plugin/plugin-storage.ts
|
|
26674
26898
|
import fs44 from "fs";
|
|
26675
|
-
import
|
|
26899
|
+
import path50 from "path";
|
|
26676
26900
|
var PluginStorageImpl;
|
|
26677
26901
|
var init_plugin_storage = __esm({
|
|
26678
26902
|
"src/core/plugin/plugin-storage.ts"() {
|
|
@@ -26683,8 +26907,8 @@ var init_plugin_storage = __esm({
|
|
|
26683
26907
|
/** Serializes writes to prevent concurrent file corruption */
|
|
26684
26908
|
writeChain = Promise.resolve();
|
|
26685
26909
|
constructor(baseDir) {
|
|
26686
|
-
this.dataDir =
|
|
26687
|
-
this.kvPath =
|
|
26910
|
+
this.dataDir = path50.join(baseDir, "data");
|
|
26911
|
+
this.kvPath = path50.join(baseDir, "kv.json");
|
|
26688
26912
|
fs44.mkdirSync(baseDir, { recursive: true });
|
|
26689
26913
|
}
|
|
26690
26914
|
readKv() {
|
|
@@ -27048,13 +27272,13 @@ var init_plugin_context = __esm({
|
|
|
27048
27272
|
|
|
27049
27273
|
// src/core/plugin/lifecycle-manager.ts
|
|
27050
27274
|
function withTimeout(promise, ms, label) {
|
|
27051
|
-
return new Promise((
|
|
27275
|
+
return new Promise((resolve8, reject) => {
|
|
27052
27276
|
const timer = setTimeout(() => reject(new Error(`Timeout: ${label} exceeded ${ms}ms`)), ms);
|
|
27053
27277
|
if (typeof timer === "object" && timer !== null && "unref" in timer) {
|
|
27054
27278
|
;
|
|
27055
27279
|
timer.unref();
|
|
27056
27280
|
}
|
|
27057
|
-
promise.then(
|
|
27281
|
+
promise.then(resolve8, reject).finally(() => clearTimeout(timer));
|
|
27058
27282
|
});
|
|
27059
27283
|
}
|
|
27060
27284
|
function resolvePluginConfig(pluginName, configManager) {
|
|
@@ -27809,7 +28033,7 @@ var init_core_items = __esm({
|
|
|
27809
28033
|
});
|
|
27810
28034
|
|
|
27811
28035
|
// src/core/core.ts
|
|
27812
|
-
import
|
|
28036
|
+
import path51 from "path";
|
|
27813
28037
|
import { nanoid as nanoid6 } from "nanoid";
|
|
27814
28038
|
var log45, OpenACPCore;
|
|
27815
28039
|
var init_core = __esm({
|
|
@@ -27835,6 +28059,7 @@ var init_core = __esm({
|
|
|
27835
28059
|
init_middleware_chain();
|
|
27836
28060
|
init_error_tracker();
|
|
27837
28061
|
init_log();
|
|
28062
|
+
init_native_stt();
|
|
27838
28063
|
init_events();
|
|
27839
28064
|
init_turn_context();
|
|
27840
28065
|
log45 = createChildLogger({ module: "core" });
|
|
@@ -27979,21 +28204,7 @@ var init_core = __esm({
|
|
|
27979
28204
|
const settingsMgr = this.settingsManager;
|
|
27980
28205
|
if (settingsMgr) {
|
|
27981
28206
|
const pluginCfg = await settingsMgr.loadSettings("@openacp/speech");
|
|
27982
|
-
const
|
|
27983
|
-
const sttProviders = {};
|
|
27984
|
-
if (groqApiKey) {
|
|
27985
|
-
sttProviders.groq = { apiKey: groqApiKey };
|
|
27986
|
-
}
|
|
27987
|
-
const newSpeechConfig = {
|
|
27988
|
-
stt: {
|
|
27989
|
-
provider: groqApiKey ? "groq" : null,
|
|
27990
|
-
providers: sttProviders
|
|
27991
|
-
},
|
|
27992
|
-
tts: {
|
|
27993
|
-
provider: pluginCfg.ttsProvider ?? null,
|
|
27994
|
-
providers: {}
|
|
27995
|
-
}
|
|
27996
|
-
};
|
|
28207
|
+
const newSpeechConfig = buildSpeechServiceConfig(pluginCfg);
|
|
27997
28208
|
speechSvc.refreshProviders(newSpeechConfig);
|
|
27998
28209
|
log45.info("Speech service config updated at runtime (from plugin settings)");
|
|
27999
28210
|
}
|
|
@@ -28002,7 +28213,7 @@ var init_core = __esm({
|
|
|
28002
28213
|
}
|
|
28003
28214
|
);
|
|
28004
28215
|
registerCoreMenuItems(this.menuRegistry);
|
|
28005
|
-
this.assistantRegistry.setInstanceRoot(
|
|
28216
|
+
this.assistantRegistry.setInstanceRoot(path51.dirname(ctx.root));
|
|
28006
28217
|
this.assistantRegistry.register(createSessionsSection(this));
|
|
28007
28218
|
this.assistantRegistry.register(createAgentsSection(this));
|
|
28008
28219
|
this.assistantRegistry.register(createConfigSection(this));
|
|
@@ -28436,8 +28647,8 @@ ${text5}`;
|
|
|
28436
28647
|
message: `Agent '${agentName}' not found`
|
|
28437
28648
|
};
|
|
28438
28649
|
}
|
|
28439
|
-
const { existsSync:
|
|
28440
|
-
if (!
|
|
28650
|
+
const { existsSync: existsSync21 } = await import("fs");
|
|
28651
|
+
if (!existsSync21(cwd)) {
|
|
28441
28652
|
return {
|
|
28442
28653
|
ok: false,
|
|
28443
28654
|
error: "invalid_cwd",
|
|
@@ -30155,11 +30366,11 @@ __export(instance_copy_exports, {
|
|
|
30155
30366
|
copyInstance: () => copyInstance
|
|
30156
30367
|
});
|
|
30157
30368
|
import fs45 from "fs";
|
|
30158
|
-
import
|
|
30369
|
+
import path52 from "path";
|
|
30159
30370
|
async function copyInstance(src, dst, opts) {
|
|
30160
30371
|
const { inheritableKeys = {}, onProgress } = opts;
|
|
30161
30372
|
fs45.mkdirSync(dst, { recursive: true });
|
|
30162
|
-
const configSrc =
|
|
30373
|
+
const configSrc = path52.join(src, "config.json");
|
|
30163
30374
|
if (fs45.existsSync(configSrc)) {
|
|
30164
30375
|
onProgress?.("Configuration", "start");
|
|
30165
30376
|
const config = JSON.parse(fs45.readFileSync(configSrc, "utf-8"));
|
|
@@ -30183,44 +30394,44 @@ async function copyInstance(src, dst, opts) {
|
|
|
30183
30394
|
}
|
|
30184
30395
|
}
|
|
30185
30396
|
}
|
|
30186
|
-
fs45.writeFileSync(
|
|
30397
|
+
fs45.writeFileSync(path52.join(dst, "config.json"), JSON.stringify(config, null, 2));
|
|
30187
30398
|
onProgress?.("Configuration", "done");
|
|
30188
30399
|
}
|
|
30189
|
-
const pluginsSrc =
|
|
30400
|
+
const pluginsSrc = path52.join(src, "plugins.json");
|
|
30190
30401
|
if (fs45.existsSync(pluginsSrc)) {
|
|
30191
30402
|
onProgress?.("Plugin list", "start");
|
|
30192
|
-
fs45.copyFileSync(pluginsSrc,
|
|
30403
|
+
fs45.copyFileSync(pluginsSrc, path52.join(dst, "plugins.json"));
|
|
30193
30404
|
onProgress?.("Plugin list", "done");
|
|
30194
30405
|
}
|
|
30195
|
-
const pluginsDir =
|
|
30406
|
+
const pluginsDir = path52.join(src, "plugins");
|
|
30196
30407
|
if (fs45.existsSync(pluginsDir)) {
|
|
30197
30408
|
onProgress?.("Plugins", "start");
|
|
30198
|
-
const dstPlugins =
|
|
30409
|
+
const dstPlugins = path52.join(dst, "plugins");
|
|
30199
30410
|
fs45.mkdirSync(dstPlugins, { recursive: true });
|
|
30200
|
-
const pkgJson =
|
|
30201
|
-
if (fs45.existsSync(pkgJson)) fs45.copyFileSync(pkgJson,
|
|
30202
|
-
const nodeModules =
|
|
30203
|
-
if (fs45.existsSync(nodeModules)) fs45.cpSync(nodeModules,
|
|
30411
|
+
const pkgJson = path52.join(pluginsDir, "package.json");
|
|
30412
|
+
if (fs45.existsSync(pkgJson)) fs45.copyFileSync(pkgJson, path52.join(dstPlugins, "package.json"));
|
|
30413
|
+
const nodeModules = path52.join(pluginsDir, "node_modules");
|
|
30414
|
+
if (fs45.existsSync(nodeModules)) fs45.cpSync(nodeModules, path52.join(dstPlugins, "node_modules"), { recursive: true });
|
|
30204
30415
|
onProgress?.("Plugins", "done");
|
|
30205
30416
|
}
|
|
30206
|
-
const agentsJson =
|
|
30417
|
+
const agentsJson = path52.join(src, "agents.json");
|
|
30207
30418
|
if (fs45.existsSync(agentsJson)) {
|
|
30208
30419
|
onProgress?.("Agents", "start");
|
|
30209
|
-
fs45.copyFileSync(agentsJson,
|
|
30210
|
-
const agentsDir =
|
|
30211
|
-
if (fs45.existsSync(agentsDir)) fs45.cpSync(agentsDir,
|
|
30420
|
+
fs45.copyFileSync(agentsJson, path52.join(dst, "agents.json"));
|
|
30421
|
+
const agentsDir = path52.join(src, "agents");
|
|
30422
|
+
if (fs45.existsSync(agentsDir)) fs45.cpSync(agentsDir, path52.join(dst, "agents"), { recursive: true });
|
|
30212
30423
|
onProgress?.("Agents", "done");
|
|
30213
30424
|
}
|
|
30214
|
-
const binDir =
|
|
30425
|
+
const binDir = path52.join(src, "bin");
|
|
30215
30426
|
if (fs45.existsSync(binDir)) {
|
|
30216
30427
|
onProgress?.("Tools", "start");
|
|
30217
|
-
fs45.cpSync(binDir,
|
|
30428
|
+
fs45.cpSync(binDir, path52.join(dst, "bin"), { recursive: true });
|
|
30218
30429
|
onProgress?.("Tools", "done");
|
|
30219
30430
|
}
|
|
30220
|
-
const pluginDataSrc =
|
|
30431
|
+
const pluginDataSrc = path52.join(src, "plugins", "data");
|
|
30221
30432
|
if (fs45.existsSync(pluginDataSrc)) {
|
|
30222
30433
|
onProgress?.("Preferences", "start");
|
|
30223
|
-
copyPluginSettings(pluginDataSrc,
|
|
30434
|
+
copyPluginSettings(pluginDataSrc, path52.join(dst, "plugins", "data"), inheritableKeys);
|
|
30224
30435
|
onProgress?.("Preferences", "done");
|
|
30225
30436
|
}
|
|
30226
30437
|
}
|
|
@@ -30235,10 +30446,10 @@ function copyPluginSettings(srcData, dstData, inheritableKeys) {
|
|
|
30235
30446
|
if (key in settings) filtered[key] = settings[key];
|
|
30236
30447
|
}
|
|
30237
30448
|
if (Object.keys(filtered).length > 0) {
|
|
30238
|
-
const relative =
|
|
30239
|
-
const dstDir =
|
|
30449
|
+
const relative = path52.relative(srcData, path52.dirname(settingsPath));
|
|
30450
|
+
const dstDir = path52.join(dstData, relative);
|
|
30240
30451
|
fs45.mkdirSync(dstDir, { recursive: true });
|
|
30241
|
-
fs45.writeFileSync(
|
|
30452
|
+
fs45.writeFileSync(path52.join(dstDir, "settings.json"), JSON.stringify(filtered, null, 2));
|
|
30242
30453
|
}
|
|
30243
30454
|
} catch {
|
|
30244
30455
|
}
|
|
@@ -30249,15 +30460,15 @@ function walkPluginDirs(base, cb) {
|
|
|
30249
30460
|
for (const entry of fs45.readdirSync(base, { withFileTypes: true })) {
|
|
30250
30461
|
if (!entry.isDirectory()) continue;
|
|
30251
30462
|
if (entry.name.startsWith("@")) {
|
|
30252
|
-
const scopeDir =
|
|
30463
|
+
const scopeDir = path52.join(base, entry.name);
|
|
30253
30464
|
for (const sub of fs45.readdirSync(scopeDir, { withFileTypes: true })) {
|
|
30254
30465
|
if (!sub.isDirectory()) continue;
|
|
30255
30466
|
const pluginName = `${entry.name}/${sub.name}`;
|
|
30256
|
-
const settingsPath =
|
|
30467
|
+
const settingsPath = path52.join(scopeDir, sub.name, "settings.json");
|
|
30257
30468
|
if (fs45.existsSync(settingsPath)) cb(pluginName, settingsPath);
|
|
30258
30469
|
}
|
|
30259
30470
|
} else {
|
|
30260
|
-
const settingsPath =
|
|
30471
|
+
const settingsPath = path52.join(base, entry.name, "settings.json");
|
|
30261
30472
|
if (fs45.existsSync(settingsPath)) cb(entry.name, settingsPath);
|
|
30262
30473
|
}
|
|
30263
30474
|
}
|
|
@@ -30270,14 +30481,14 @@ var init_instance_copy = __esm({
|
|
|
30270
30481
|
|
|
30271
30482
|
// src/core/setup/git-protect.ts
|
|
30272
30483
|
import fs46 from "fs";
|
|
30273
|
-
import
|
|
30484
|
+
import path53 from "path";
|
|
30274
30485
|
function protectLocalInstance(projectDir) {
|
|
30275
30486
|
ensureGitignore(projectDir);
|
|
30276
30487
|
ensureClaudeMd(projectDir);
|
|
30277
30488
|
printSecurityWarning();
|
|
30278
30489
|
}
|
|
30279
30490
|
function ensureGitignore(projectDir) {
|
|
30280
|
-
const gitignorePath =
|
|
30491
|
+
const gitignorePath = path53.join(projectDir, ".gitignore");
|
|
30281
30492
|
const entry = ".openacp";
|
|
30282
30493
|
if (fs46.existsSync(gitignorePath)) {
|
|
30283
30494
|
const content = fs46.readFileSync(gitignorePath, "utf-8");
|
|
@@ -30297,7 +30508,7 @@ ${entry}
|
|
|
30297
30508
|
}
|
|
30298
30509
|
}
|
|
30299
30510
|
function ensureClaudeMd(projectDir) {
|
|
30300
|
-
const claudeMdPath =
|
|
30511
|
+
const claudeMdPath = path53.join(projectDir, "CLAUDE.md");
|
|
30301
30512
|
const marker = "## Local OpenACP Workspace";
|
|
30302
30513
|
if (fs46.existsSync(claudeMdPath)) {
|
|
30303
30514
|
const content = fs46.readFileSync(claudeMdPath, "utf-8");
|
|
@@ -30340,7 +30551,7 @@ var init_git_protect = __esm({
|
|
|
30340
30551
|
});
|
|
30341
30552
|
|
|
30342
30553
|
// src/core/setup/wizard.ts
|
|
30343
|
-
import * as
|
|
30554
|
+
import * as path54 from "path";
|
|
30344
30555
|
import * as fs47 from "fs";
|
|
30345
30556
|
import * as os10 from "os";
|
|
30346
30557
|
import * as clack7 from "@clack/prompts";
|
|
@@ -30388,7 +30599,7 @@ async function runSetup(configManager, opts) {
|
|
|
30388
30599
|
const instanceRoot = opts?.instanceRoot;
|
|
30389
30600
|
let instanceName = opts?.instanceName;
|
|
30390
30601
|
if (!instanceName) {
|
|
30391
|
-
const defaultName =
|
|
30602
|
+
const defaultName = path54.basename(path54.dirname(instanceRoot));
|
|
30392
30603
|
const locationHint = instanceRoot.replace(/\/.openacp$/, "").replace(os10.homedir(), "~");
|
|
30393
30604
|
const nameResult = await clack7.text({
|
|
30394
30605
|
message: `Name for this workspace (${locationHint})`,
|
|
@@ -30399,13 +30610,13 @@ async function runSetup(configManager, opts) {
|
|
|
30399
30610
|
instanceName = nameResult.trim();
|
|
30400
30611
|
}
|
|
30401
30612
|
const globalRoot = getGlobalRoot();
|
|
30402
|
-
const registryPath =
|
|
30613
|
+
const registryPath = path54.join(globalRoot, "instances.json");
|
|
30403
30614
|
const instanceRegistry = new InstanceRegistry(registryPath);
|
|
30404
30615
|
instanceRegistry.load();
|
|
30405
30616
|
let didCopy = false;
|
|
30406
30617
|
if (opts?.from) {
|
|
30407
|
-
const fromRoot =
|
|
30408
|
-
if (fs47.existsSync(
|
|
30618
|
+
const fromRoot = path54.join(opts.from, ".openacp");
|
|
30619
|
+
if (fs47.existsSync(path54.join(fromRoot, "config.json"))) {
|
|
30409
30620
|
const inheritableMap = buildInheritableKeysMap();
|
|
30410
30621
|
await copyInstance(fromRoot, instanceRoot, { inheritableKeys: inheritableMap });
|
|
30411
30622
|
didCopy = true;
|
|
@@ -30416,7 +30627,7 @@ async function runSetup(configManager, opts) {
|
|
|
30416
30627
|
}
|
|
30417
30628
|
if (!didCopy) {
|
|
30418
30629
|
const existingInstances = instanceRegistry.list().filter(
|
|
30419
|
-
(e) => fs47.existsSync(
|
|
30630
|
+
(e) => fs47.existsSync(path54.join(e.root, "config.json")) && e.root !== instanceRoot
|
|
30420
30631
|
);
|
|
30421
30632
|
if (existingInstances.length > 0) {
|
|
30422
30633
|
let singleLabel;
|
|
@@ -30424,7 +30635,7 @@ async function runSetup(configManager, opts) {
|
|
|
30424
30635
|
const e = existingInstances[0];
|
|
30425
30636
|
let name = e.id;
|
|
30426
30637
|
try {
|
|
30427
|
-
const cfg = JSON.parse(fs47.readFileSync(
|
|
30638
|
+
const cfg = JSON.parse(fs47.readFileSync(path54.join(e.root, "config.json"), "utf-8"));
|
|
30428
30639
|
if (cfg.instanceName) name = cfg.instanceName;
|
|
30429
30640
|
} catch {
|
|
30430
30641
|
}
|
|
@@ -30447,7 +30658,7 @@ async function runSetup(configManager, opts) {
|
|
|
30447
30658
|
options: existingInstances.map((e) => {
|
|
30448
30659
|
let name = e.id;
|
|
30449
30660
|
try {
|
|
30450
|
-
const cfg = JSON.parse(fs47.readFileSync(
|
|
30661
|
+
const cfg = JSON.parse(fs47.readFileSync(path54.join(e.root, "config.json"), "utf-8"));
|
|
30451
30662
|
if (cfg.instanceName) name = cfg.instanceName;
|
|
30452
30663
|
} catch {
|
|
30453
30664
|
}
|
|
@@ -30542,9 +30753,9 @@ async function runSetup(configManager, opts) {
|
|
|
30542
30753
|
if (channelId.startsWith("official:")) {
|
|
30543
30754
|
const npmPackage = channelId.slice("official:".length);
|
|
30544
30755
|
const { execFileSync: execFileSync9 } = await import("child_process");
|
|
30545
|
-
const pluginsDir =
|
|
30546
|
-
const nodeModulesDir =
|
|
30547
|
-
const installedPath =
|
|
30756
|
+
const pluginsDir = path54.join(instanceRoot, "plugins");
|
|
30757
|
+
const nodeModulesDir = path54.join(pluginsDir, "node_modules");
|
|
30758
|
+
const installedPath = path54.join(nodeModulesDir, npmPackage);
|
|
30548
30759
|
if (!fs47.existsSync(installedPath)) {
|
|
30549
30760
|
try {
|
|
30550
30761
|
clack7.log.step(`Installing ${npmPackage}...`);
|
|
@@ -30558,9 +30769,9 @@ async function runSetup(configManager, opts) {
|
|
|
30558
30769
|
}
|
|
30559
30770
|
}
|
|
30560
30771
|
try {
|
|
30561
|
-
const installedPkgPath =
|
|
30772
|
+
const installedPkgPath = path54.join(nodeModulesDir, npmPackage, "package.json");
|
|
30562
30773
|
const installedPkg = JSON.parse(fs47.readFileSync(installedPkgPath, "utf-8"));
|
|
30563
|
-
const pluginModule = await import(
|
|
30774
|
+
const pluginModule = await import(path54.join(nodeModulesDir, npmPackage, installedPkg.main ?? "dist/index.js"));
|
|
30564
30775
|
const plugin2 = pluginModule.default;
|
|
30565
30776
|
if (plugin2?.install) {
|
|
30566
30777
|
const installCtx = createInstallContext2({
|
|
@@ -30590,8 +30801,8 @@ async function runSetup(configManager, opts) {
|
|
|
30590
30801
|
if (channelId.startsWith("community:")) {
|
|
30591
30802
|
const npmPackage = channelId.slice("community:".length);
|
|
30592
30803
|
const { execFileSync: execFileSync9 } = await import("child_process");
|
|
30593
|
-
const pluginsDir =
|
|
30594
|
-
const nodeModulesDir =
|
|
30804
|
+
const pluginsDir = path54.join(instanceRoot, "plugins");
|
|
30805
|
+
const nodeModulesDir = path54.join(pluginsDir, "node_modules");
|
|
30595
30806
|
try {
|
|
30596
30807
|
execFileSync9("npm", ["install", npmPackage, "--prefix", pluginsDir, "--save", "--ignore-scripts"], {
|
|
30597
30808
|
stdio: "inherit",
|
|
@@ -30603,9 +30814,9 @@ async function runSetup(configManager, opts) {
|
|
|
30603
30814
|
}
|
|
30604
30815
|
try {
|
|
30605
30816
|
const { readFileSync: readFileSync18 } = await import("fs");
|
|
30606
|
-
const installedPkgPath =
|
|
30817
|
+
const installedPkgPath = path54.join(nodeModulesDir, npmPackage, "package.json");
|
|
30607
30818
|
const installedPkg = JSON.parse(readFileSync18(installedPkgPath, "utf-8"));
|
|
30608
|
-
const pluginModule = await import(
|
|
30819
|
+
const pluginModule = await import(path54.join(nodeModulesDir, npmPackage, installedPkg.main ?? "dist/index.js"));
|
|
30609
30820
|
const plugin2 = pluginModule.default;
|
|
30610
30821
|
if (plugin2?.install) {
|
|
30611
30822
|
const installCtx = createInstallContext2({
|
|
@@ -30658,7 +30869,7 @@ async function runSetup(configManager, opts) {
|
|
|
30658
30869
|
workspace: { allowExternalWorkspaces: true, security: { allowedPaths: [], envWhitelist: [] } },
|
|
30659
30870
|
logging: {
|
|
30660
30871
|
level: "info",
|
|
30661
|
-
logDir:
|
|
30872
|
+
logDir: path54.join(instanceRoot, "logs"),
|
|
30662
30873
|
maxFileSize: "10m",
|
|
30663
30874
|
maxFiles: 7,
|
|
30664
30875
|
sessionLogRetentionDays: 30
|
|
@@ -30685,7 +30896,7 @@ async function runSetup(configManager, opts) {
|
|
|
30685
30896
|
instanceRegistry.register(instanceId, instanceRoot);
|
|
30686
30897
|
await instanceRegistry.save();
|
|
30687
30898
|
}
|
|
30688
|
-
const projectDir =
|
|
30899
|
+
const projectDir = path54.dirname(instanceRoot);
|
|
30689
30900
|
protectLocalInstance(projectDir);
|
|
30690
30901
|
clack7.outro(`Config saved to ${configManager.getConfigPath()}`);
|
|
30691
30902
|
if (!opts?.skipRunMode) {
|
|
@@ -30764,7 +30975,7 @@ async function runReconfigure(configManager, settingsManager) {
|
|
|
30764
30975
|
await configureChannels(config, settingsManager);
|
|
30765
30976
|
}
|
|
30766
30977
|
if (choice === "agents") {
|
|
30767
|
-
const reconfigRoot =
|
|
30978
|
+
const reconfigRoot = path54.dirname(configManager.getConfigPath());
|
|
30768
30979
|
const { defaultAgent } = await setupAgents(reconfigRoot);
|
|
30769
30980
|
await configManager.save({ defaultAgent });
|
|
30770
30981
|
config = configManager.get();
|
|
@@ -30969,7 +31180,7 @@ __export(dev_loader_exports, {
|
|
|
30969
31180
|
});
|
|
30970
31181
|
import fs48 from "fs";
|
|
30971
31182
|
import os11 from "os";
|
|
30972
|
-
import
|
|
31183
|
+
import path55 from "path";
|
|
30973
31184
|
var loadCounter, DevPluginLoader;
|
|
30974
31185
|
var init_dev_loader = __esm({
|
|
30975
31186
|
"src/core/plugin/dev-loader.ts"() {
|
|
@@ -30979,24 +31190,24 @@ var init_dev_loader = __esm({
|
|
|
30979
31190
|
pluginPath;
|
|
30980
31191
|
lastTempDir = null;
|
|
30981
31192
|
constructor(pluginPath) {
|
|
30982
|
-
this.pluginPath =
|
|
31193
|
+
this.pluginPath = path55.resolve(pluginPath);
|
|
30983
31194
|
}
|
|
30984
31195
|
async load() {
|
|
30985
|
-
const distPath =
|
|
30986
|
-
const distIndex =
|
|
30987
|
-
const srcIndex =
|
|
31196
|
+
const distPath = path55.join(this.pluginPath, "dist");
|
|
31197
|
+
const distIndex = path55.join(distPath, "index.js");
|
|
31198
|
+
const srcIndex = path55.join(this.pluginPath, "src", "index.ts");
|
|
30988
31199
|
if (!fs48.existsSync(distIndex) && !fs48.existsSync(srcIndex)) {
|
|
30989
31200
|
throw new Error(`Plugin not found at ${this.pluginPath}. Expected dist/index.js or src/index.ts`);
|
|
30990
31201
|
}
|
|
30991
31202
|
if (!fs48.existsSync(distIndex)) {
|
|
30992
31203
|
throw new Error(`Built plugin not found at ${distIndex}. Run 'npm run build' first.`);
|
|
30993
31204
|
}
|
|
30994
|
-
const tempDir =
|
|
31205
|
+
const tempDir = path55.join(os11.tmpdir(), `openacp-dev-plugin-${Date.now()}-${++loadCounter}`);
|
|
30995
31206
|
fs48.cpSync(distPath, tempDir, { recursive: true });
|
|
30996
31207
|
const previousTempDir = this.lastTempDir;
|
|
30997
31208
|
this.lastTempDir = tempDir;
|
|
30998
31209
|
try {
|
|
30999
|
-
const mod = await import(`file://${
|
|
31210
|
+
const mod = await import(`file://${path55.join(tempDir, "index.js")}`);
|
|
31000
31211
|
const plugin2 = mod.default;
|
|
31001
31212
|
if (!plugin2 || !plugin2.name || !plugin2.setup) {
|
|
31002
31213
|
throw new Error(`Invalid plugin at ${distIndex}. Must export default OpenACPPlugin with name and setup().`);
|
|
@@ -31019,7 +31230,7 @@ var init_dev_loader = __esm({
|
|
|
31019
31230
|
}
|
|
31020
31231
|
/** Returns the path to the plugin's dist directory (the source of truth — NOT the temp copy). */
|
|
31021
31232
|
getDistPath() {
|
|
31022
|
-
return
|
|
31233
|
+
return path55.join(this.pluginPath, "dist");
|
|
31023
31234
|
}
|
|
31024
31235
|
};
|
|
31025
31236
|
}
|
|
@@ -31031,7 +31242,7 @@ __export(main_exports, {
|
|
|
31031
31242
|
RESTART_EXIT_CODE: () => RESTART_EXIT_CODE,
|
|
31032
31243
|
startServer: () => startServer
|
|
31033
31244
|
});
|
|
31034
|
-
import
|
|
31245
|
+
import path56 from "path";
|
|
31035
31246
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
31036
31247
|
import fs49 from "fs";
|
|
31037
31248
|
async function startServer(opts) {
|
|
@@ -31056,7 +31267,7 @@ async function startServer(opts) {
|
|
|
31056
31267
|
process.exit(1);
|
|
31057
31268
|
}
|
|
31058
31269
|
const globalRoot = getGlobalRoot();
|
|
31059
|
-
const reg = new InstanceRegistry(
|
|
31270
|
+
const reg = new InstanceRegistry(path56.join(globalRoot, "instances.json"));
|
|
31060
31271
|
reg.load();
|
|
31061
31272
|
const entry = reg.getByRoot(root);
|
|
31062
31273
|
opts = { ...opts, instanceContext: createInstanceContext({ id: entry?.id ?? randomUUID4(), root }) };
|
|
@@ -31144,22 +31355,22 @@ async function startServer(opts) {
|
|
|
31144
31355
|
try {
|
|
31145
31356
|
let modulePath;
|
|
31146
31357
|
if (name.startsWith("/") || name.startsWith(".")) {
|
|
31147
|
-
const resolved =
|
|
31148
|
-
const pkgPath =
|
|
31358
|
+
const resolved = path56.resolve(name);
|
|
31359
|
+
const pkgPath = path56.join(resolved, "package.json");
|
|
31149
31360
|
const pkg = JSON.parse(await fs49.promises.readFile(pkgPath, "utf-8"));
|
|
31150
|
-
modulePath =
|
|
31361
|
+
modulePath = path56.join(resolved, pkg.main || "dist/index.js");
|
|
31151
31362
|
} else {
|
|
31152
|
-
const nodeModulesDir =
|
|
31153
|
-
let pkgDir =
|
|
31154
|
-
if (!fs49.existsSync(
|
|
31363
|
+
const nodeModulesDir = path56.join(ctx.paths.plugins, "node_modules");
|
|
31364
|
+
let pkgDir = path56.join(nodeModulesDir, name);
|
|
31365
|
+
if (!fs49.existsSync(path56.join(pkgDir, "package.json"))) {
|
|
31155
31366
|
let found = false;
|
|
31156
31367
|
const scopes = fs49.existsSync(nodeModulesDir) ? fs49.readdirSync(nodeModulesDir).filter((d) => d.startsWith("@")) : [];
|
|
31157
31368
|
for (const scope of scopes) {
|
|
31158
|
-
const scopeDir =
|
|
31369
|
+
const scopeDir = path56.join(nodeModulesDir, scope);
|
|
31159
31370
|
const pkgs = fs49.readdirSync(scopeDir);
|
|
31160
31371
|
for (const pkg2 of pkgs) {
|
|
31161
|
-
const candidateDir =
|
|
31162
|
-
const candidatePkgPath =
|
|
31372
|
+
const candidateDir = path56.join(scopeDir, pkg2);
|
|
31373
|
+
const candidatePkgPath = path56.join(candidateDir, "package.json");
|
|
31163
31374
|
if (fs49.existsSync(candidatePkgPath)) {
|
|
31164
31375
|
try {
|
|
31165
31376
|
const candidatePkg = JSON.parse(fs49.readFileSync(candidatePkgPath, "utf-8"));
|
|
@@ -31176,9 +31387,9 @@ async function startServer(opts) {
|
|
|
31176
31387
|
if (found) break;
|
|
31177
31388
|
}
|
|
31178
31389
|
}
|
|
31179
|
-
const pkgJsonPath =
|
|
31390
|
+
const pkgJsonPath = path56.join(pkgDir, "package.json");
|
|
31180
31391
|
const pkg = JSON.parse(await fs49.promises.readFile(pkgJsonPath, "utf-8"));
|
|
31181
|
-
modulePath =
|
|
31392
|
+
modulePath = path56.join(pkgDir, pkg.main || "dist/index.js");
|
|
31182
31393
|
}
|
|
31183
31394
|
log.debug({ plugin: name, modulePath }, "Loading community plugin");
|
|
31184
31395
|
const mod = await import(modulePath);
|
|
@@ -31350,7 +31561,7 @@ async function startServer(opts) {
|
|
|
31350
31561
|
await core.start();
|
|
31351
31562
|
try {
|
|
31352
31563
|
const globalRoot = getGlobalRoot();
|
|
31353
|
-
const registryPath =
|
|
31564
|
+
const registryPath = path56.join(globalRoot, "instances.json");
|
|
31354
31565
|
const instanceReg = new InstanceRegistry(registryPath);
|
|
31355
31566
|
await instanceReg.load();
|
|
31356
31567
|
if (!instanceReg.getByRoot(ctx.root)) {
|
|
@@ -31522,7 +31733,7 @@ var restart_exports = {};
|
|
|
31522
31733
|
__export(restart_exports, {
|
|
31523
31734
|
cmdRestart: () => cmdRestart
|
|
31524
31735
|
});
|
|
31525
|
-
import
|
|
31736
|
+
import path57 from "path";
|
|
31526
31737
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
31527
31738
|
async function cmdRestart(args2 = [], instanceRoot) {
|
|
31528
31739
|
const json = isJsonMode(args2);
|
|
@@ -31562,7 +31773,7 @@ Stops the running daemon (if any) and starts a new one.
|
|
|
31562
31773
|
if (!json && stopResult.stopped) {
|
|
31563
31774
|
console.log(`Stopped daemon (was PID ${stopResult.pid})`);
|
|
31564
31775
|
}
|
|
31565
|
-
const cm = new ConfigManager2(
|
|
31776
|
+
const cm = new ConfigManager2(path57.join(root, "config.json"));
|
|
31566
31777
|
if (!await cm.exists()) {
|
|
31567
31778
|
if (json) jsonError(ErrorCodes.CONFIG_NOT_FOUND, 'No config found. Run "openacp" first to set up.');
|
|
31568
31779
|
console.error('No config found. Run "openacp" first to set up.');
|
|
@@ -31583,7 +31794,7 @@ Stops the running daemon (if any) and starts a new one.
|
|
|
31583
31794
|
printInstanceHint(root);
|
|
31584
31795
|
console.log("Starting in foreground mode...");
|
|
31585
31796
|
const { startServer: startServer2 } = await Promise.resolve().then(() => (init_main(), main_exports));
|
|
31586
|
-
const reg = new InstanceRegistry(
|
|
31797
|
+
const reg = new InstanceRegistry(path57.join(getGlobalRoot(), "instances.json"));
|
|
31587
31798
|
reg.load();
|
|
31588
31799
|
const existingEntry = reg.getByRoot(root);
|
|
31589
31800
|
const ctx = createInstanceContext({
|
|
@@ -31632,7 +31843,7 @@ __export(status_exports, {
|
|
|
31632
31843
|
readInstanceInfo: () => readInstanceInfo
|
|
31633
31844
|
});
|
|
31634
31845
|
import fs50 from "fs";
|
|
31635
|
-
import
|
|
31846
|
+
import path58 from "path";
|
|
31636
31847
|
import os12 from "os";
|
|
31637
31848
|
async function cmdStatus(args2 = [], instanceRoot) {
|
|
31638
31849
|
const json = isJsonMode(args2);
|
|
@@ -31650,7 +31861,7 @@ async function cmdStatus(args2 = [], instanceRoot) {
|
|
|
31650
31861
|
await showSingleInstance(root, json);
|
|
31651
31862
|
}
|
|
31652
31863
|
async function showAllInstances(json = false) {
|
|
31653
|
-
const registryPath =
|
|
31864
|
+
const registryPath = path58.join(getGlobalRoot(), "instances.json");
|
|
31654
31865
|
const registry = new InstanceRegistry(registryPath);
|
|
31655
31866
|
await registry.load();
|
|
31656
31867
|
const instances = registry.list();
|
|
@@ -31693,7 +31904,7 @@ async function showAllInstances(json = false) {
|
|
|
31693
31904
|
console.log("");
|
|
31694
31905
|
}
|
|
31695
31906
|
async function showInstanceById(id, json = false) {
|
|
31696
|
-
const registryPath =
|
|
31907
|
+
const registryPath = path58.join(getGlobalRoot(), "instances.json");
|
|
31697
31908
|
const registry = new InstanceRegistry(registryPath);
|
|
31698
31909
|
await registry.load();
|
|
31699
31910
|
const entry = registry.get(id);
|
|
@@ -31708,7 +31919,7 @@ async function showSingleInstance(root, json = false) {
|
|
|
31708
31919
|
const info = readInstanceInfo(root);
|
|
31709
31920
|
if (json) {
|
|
31710
31921
|
jsonSuccess({
|
|
31711
|
-
id:
|
|
31922
|
+
id: path58.basename(root),
|
|
31712
31923
|
name: info.name,
|
|
31713
31924
|
status: info.pid ? "online" : "offline",
|
|
31714
31925
|
pid: info.pid,
|
|
@@ -31739,13 +31950,13 @@ function readInstanceInfo(root) {
|
|
|
31739
31950
|
channels: []
|
|
31740
31951
|
};
|
|
31741
31952
|
try {
|
|
31742
|
-
const config = JSON.parse(fs50.readFileSync(
|
|
31953
|
+
const config = JSON.parse(fs50.readFileSync(path58.join(root, "config.json"), "utf-8"));
|
|
31743
31954
|
result.name = config.instanceName ?? null;
|
|
31744
31955
|
result.runMode = config.runMode ?? null;
|
|
31745
31956
|
} catch {
|
|
31746
31957
|
}
|
|
31747
31958
|
try {
|
|
31748
|
-
const pid = parseInt(fs50.readFileSync(
|
|
31959
|
+
const pid = parseInt(fs50.readFileSync(path58.join(root, "openacp.pid"), "utf-8").trim());
|
|
31749
31960
|
if (!isNaN(pid)) {
|
|
31750
31961
|
process.kill(pid, 0);
|
|
31751
31962
|
result.pid = pid;
|
|
@@ -31753,19 +31964,19 @@ function readInstanceInfo(root) {
|
|
|
31753
31964
|
} catch {
|
|
31754
31965
|
}
|
|
31755
31966
|
try {
|
|
31756
|
-
const port = parseInt(fs50.readFileSync(
|
|
31967
|
+
const port = parseInt(fs50.readFileSync(path58.join(root, "api.port"), "utf-8").trim());
|
|
31757
31968
|
if (!isNaN(port)) result.apiPort = port;
|
|
31758
31969
|
} catch {
|
|
31759
31970
|
}
|
|
31760
31971
|
try {
|
|
31761
|
-
const tunnels = JSON.parse(fs50.readFileSync(
|
|
31972
|
+
const tunnels = JSON.parse(fs50.readFileSync(path58.join(root, "tunnels.json"), "utf-8"));
|
|
31762
31973
|
const entries = Object.values(tunnels);
|
|
31763
31974
|
const systemEntry = entries.find((t) => t.type === "system");
|
|
31764
31975
|
if (systemEntry?.port) result.tunnelPort = systemEntry.port;
|
|
31765
31976
|
} catch {
|
|
31766
31977
|
}
|
|
31767
31978
|
try {
|
|
31768
|
-
const plugins = JSON.parse(fs50.readFileSync(
|
|
31979
|
+
const plugins = JSON.parse(fs50.readFileSync(path58.join(root, "plugins.json"), "utf-8"));
|
|
31769
31980
|
const adapterMap = [
|
|
31770
31981
|
{ pluginName: "@openacp/telegram", channelId: "telegram" },
|
|
31771
31982
|
{ pluginName: "@openacp/discord-adapter", channelId: "discord" },
|
|
@@ -31783,7 +31994,7 @@ function readInstanceInfo(root) {
|
|
|
31783
31994
|
function formatInstanceStatus(root) {
|
|
31784
31995
|
const info = readInstanceInfo(root);
|
|
31785
31996
|
if (!info.pid) return null;
|
|
31786
|
-
const workspaceDir =
|
|
31997
|
+
const workspaceDir = path58.dirname(root);
|
|
31787
31998
|
const displayPath = workspaceDir.replace(os12.homedir(), "~");
|
|
31788
31999
|
const lines = [];
|
|
31789
32000
|
lines.push(` PID: ${info.pid}`);
|
|
@@ -31852,7 +32063,7 @@ var config_editor_exports = {};
|
|
|
31852
32063
|
__export(config_editor_exports, {
|
|
31853
32064
|
runConfigEditor: () => runConfigEditor
|
|
31854
32065
|
});
|
|
31855
|
-
import * as
|
|
32066
|
+
import * as path59 from "path";
|
|
31856
32067
|
import * as clack8 from "@clack/prompts";
|
|
31857
32068
|
async function select8(opts) {
|
|
31858
32069
|
const result = await clack8.select({
|
|
@@ -32406,7 +32617,7 @@ async function runConfigEditor(configManager, mode = "file", apiPort, settingsMa
|
|
|
32406
32617
|
await configManager.load();
|
|
32407
32618
|
const config = configManager.get();
|
|
32408
32619
|
const updates = {};
|
|
32409
|
-
const instanceRoot =
|
|
32620
|
+
const instanceRoot = path59.dirname(configManager.getConfigPath());
|
|
32410
32621
|
console.log(`
|
|
32411
32622
|
${c2.cyan}${c2.bold}OpenACP Config Editor${c2.reset}`);
|
|
32412
32623
|
console.log(dim2(`Config: ${configManager.getConfigPath()}`));
|
|
@@ -32463,17 +32674,17 @@ ${c2.cyan}${c2.bold}OpenACP Config Editor${c2.reset}`);
|
|
|
32463
32674
|
async function sendConfigViaApi(port, updates) {
|
|
32464
32675
|
const { apiCall: call } = await Promise.resolve().then(() => (init_api_client(), api_client_exports));
|
|
32465
32676
|
const paths = flattenToPaths(updates);
|
|
32466
|
-
for (const { path:
|
|
32677
|
+
for (const { path: path72, value } of paths) {
|
|
32467
32678
|
const res = await call(port, "/api/config", {
|
|
32468
32679
|
method: "PATCH",
|
|
32469
32680
|
headers: { "Content-Type": "application/json" },
|
|
32470
|
-
body: JSON.stringify({ path:
|
|
32681
|
+
body: JSON.stringify({ path: path72, value })
|
|
32471
32682
|
});
|
|
32472
32683
|
const data = await res.json();
|
|
32473
32684
|
if (!res.ok) {
|
|
32474
|
-
console.log(warn2(`Failed to update ${
|
|
32685
|
+
console.log(warn2(`Failed to update ${path72}: ${data.error}`));
|
|
32475
32686
|
} else if (data.needsRestart) {
|
|
32476
|
-
console.log(warn2(`${
|
|
32687
|
+
console.log(warn2(`${path72} updated \u2014 restart required`));
|
|
32477
32688
|
}
|
|
32478
32689
|
}
|
|
32479
32690
|
}
|
|
@@ -32541,7 +32752,7 @@ function showInteractiveMenu(options) {
|
|
|
32541
32752
|
}
|
|
32542
32753
|
}
|
|
32543
32754
|
console.log("");
|
|
32544
|
-
return new Promise((
|
|
32755
|
+
return new Promise((resolve8) => {
|
|
32545
32756
|
process.stdin.setRawMode(true);
|
|
32546
32757
|
process.stdin.resume();
|
|
32547
32758
|
const onData = async (buf) => {
|
|
@@ -32560,7 +32771,7 @@ function showInteractiveMenu(options) {
|
|
|
32560
32771
|
console.error(err);
|
|
32561
32772
|
process.exit(1);
|
|
32562
32773
|
}
|
|
32563
|
-
|
|
32774
|
+
resolve8(true);
|
|
32564
32775
|
}
|
|
32565
32776
|
};
|
|
32566
32777
|
const cleanup = () => {
|
|
@@ -32583,24 +32794,24 @@ __export(migration_exports, {
|
|
|
32583
32794
|
migrateGlobalInstance: () => migrateGlobalInstance
|
|
32584
32795
|
});
|
|
32585
32796
|
import fs55 from "fs";
|
|
32586
|
-
import
|
|
32797
|
+
import path69 from "path";
|
|
32587
32798
|
import os15 from "os";
|
|
32588
32799
|
import { randomUUID as randomUUID8 } from "crypto";
|
|
32589
32800
|
async function migrateGlobalInstance() {
|
|
32590
32801
|
const globalRoot = getGlobalRoot();
|
|
32591
|
-
const globalConfig =
|
|
32802
|
+
const globalConfig = path69.join(globalRoot, "config.json");
|
|
32592
32803
|
if (!fs55.existsSync(globalConfig)) return null;
|
|
32593
|
-
let baseDir =
|
|
32804
|
+
let baseDir = path69.join(os15.homedir(), "openacp-workspace");
|
|
32594
32805
|
try {
|
|
32595
32806
|
const raw = JSON.parse(fs55.readFileSync(globalConfig, "utf-8"));
|
|
32596
32807
|
if (raw.workspace?.baseDir) {
|
|
32597
32808
|
const configured = raw.workspace.baseDir;
|
|
32598
|
-
baseDir = configured.startsWith("~") ?
|
|
32809
|
+
baseDir = configured.startsWith("~") ? path69.join(os15.homedir(), configured.slice(1)) : configured;
|
|
32599
32810
|
}
|
|
32600
32811
|
} catch {
|
|
32601
32812
|
}
|
|
32602
|
-
const targetRoot =
|
|
32603
|
-
if (
|
|
32813
|
+
const targetRoot = path69.join(baseDir, ".openacp");
|
|
32814
|
+
if (path69.resolve(targetRoot) === path69.resolve(globalRoot)) {
|
|
32604
32815
|
return null;
|
|
32605
32816
|
}
|
|
32606
32817
|
const instanceFiles = [
|
|
@@ -32614,34 +32825,34 @@ async function migrateGlobalInstance() {
|
|
|
32614
32825
|
const instanceDirs = ["plugins", "logs", "history", "files"];
|
|
32615
32826
|
fs55.mkdirSync(targetRoot, { recursive: true });
|
|
32616
32827
|
for (const file of instanceFiles) {
|
|
32617
|
-
const src =
|
|
32618
|
-
const dst =
|
|
32828
|
+
const src = path69.join(globalRoot, file);
|
|
32829
|
+
const dst = path69.join(targetRoot, file);
|
|
32619
32830
|
if (fs55.existsSync(src)) {
|
|
32620
32831
|
fs55.cpSync(src, dst, { force: true });
|
|
32621
32832
|
fs55.rmSync(src);
|
|
32622
32833
|
}
|
|
32623
32834
|
}
|
|
32624
32835
|
for (const dir of instanceDirs) {
|
|
32625
|
-
const src =
|
|
32626
|
-
const dst =
|
|
32836
|
+
const src = path69.join(globalRoot, dir);
|
|
32837
|
+
const dst = path69.join(targetRoot, dir);
|
|
32627
32838
|
if (fs55.existsSync(src)) {
|
|
32628
32839
|
fs55.cpSync(src, dst, { recursive: true, force: true });
|
|
32629
32840
|
fs55.rmSync(src, { recursive: true, force: true });
|
|
32630
32841
|
}
|
|
32631
32842
|
}
|
|
32632
|
-
const srcCache =
|
|
32633
|
-
const dstCache =
|
|
32843
|
+
const srcCache = path69.join(globalRoot, "cache");
|
|
32844
|
+
const dstCache = path69.join(targetRoot, "cache");
|
|
32634
32845
|
if (fs55.existsSync(srcCache)) {
|
|
32635
32846
|
fs55.mkdirSync(dstCache, { recursive: true });
|
|
32636
32847
|
for (const entry of fs55.readdirSync(srcCache)) {
|
|
32637
32848
|
if (entry === "registry-cache.json") continue;
|
|
32638
|
-
const s =
|
|
32639
|
-
const d =
|
|
32849
|
+
const s = path69.join(srcCache, entry);
|
|
32850
|
+
const d = path69.join(dstCache, entry);
|
|
32640
32851
|
fs55.cpSync(s, d, { recursive: true, force: true });
|
|
32641
32852
|
fs55.rmSync(s, { recursive: true, force: true });
|
|
32642
32853
|
}
|
|
32643
32854
|
}
|
|
32644
|
-
const migratedConfigPath =
|
|
32855
|
+
const migratedConfigPath = path69.join(targetRoot, "config.json");
|
|
32645
32856
|
try {
|
|
32646
32857
|
const config = JSON.parse(fs55.readFileSync(migratedConfigPath, "utf-8"));
|
|
32647
32858
|
if (config.workspace?.baseDir) {
|
|
@@ -32650,7 +32861,7 @@ async function migrateGlobalInstance() {
|
|
|
32650
32861
|
fs55.writeFileSync(migratedConfigPath, JSON.stringify(config, null, 2));
|
|
32651
32862
|
} catch {
|
|
32652
32863
|
}
|
|
32653
|
-
const registryPath =
|
|
32864
|
+
const registryPath = path69.join(globalRoot, "instances.json");
|
|
32654
32865
|
try {
|
|
32655
32866
|
const registry = new InstanceRegistry(registryPath);
|
|
32656
32867
|
registry.load();
|
|
@@ -32682,17 +32893,17 @@ __export(instance_prompt_exports, {
|
|
|
32682
32893
|
promptForInstance: () => promptForInstance
|
|
32683
32894
|
});
|
|
32684
32895
|
import fs56 from "fs";
|
|
32685
|
-
import
|
|
32896
|
+
import path70 from "path";
|
|
32686
32897
|
import os16 from "os";
|
|
32687
32898
|
async function promptForInstance(opts) {
|
|
32688
32899
|
const globalRoot = getGlobalRoot();
|
|
32689
|
-
const globalConfigExists = fs56.existsSync(
|
|
32900
|
+
const globalConfigExists = fs56.existsSync(path70.join(globalRoot, "config.json"));
|
|
32690
32901
|
const cwd = process.cwd();
|
|
32691
|
-
const isHomeDir =
|
|
32692
|
-
const defaultWorkspace =
|
|
32693
|
-
const createRoot = isHomeDir ?
|
|
32902
|
+
const isHomeDir = path70.resolve(cwd) === path70.resolve(os16.homedir());
|
|
32903
|
+
const defaultWorkspace = path70.join(os16.homedir(), "openacp-workspace");
|
|
32904
|
+
const createRoot = isHomeDir ? path70.join(defaultWorkspace, ".openacp") : path70.join(cwd, ".openacp");
|
|
32694
32905
|
const detectedParent = findParentInstance(cwd, globalRoot);
|
|
32695
|
-
const registryPath =
|
|
32906
|
+
const registryPath = path70.join(globalRoot, "instances.json");
|
|
32696
32907
|
const registry = new InstanceRegistry(registryPath);
|
|
32697
32908
|
registry.load();
|
|
32698
32909
|
const instances = registry.list().filter((e) => fs56.existsSync(e.root));
|
|
@@ -32724,24 +32935,24 @@ async function promptForInstance(opts) {
|
|
|
32724
32935
|
const instanceOptions = instances.filter((e) => !detectedParent || e.root !== detectedParent).map((e) => {
|
|
32725
32936
|
let name = e.id;
|
|
32726
32937
|
try {
|
|
32727
|
-
const raw = fs56.readFileSync(
|
|
32938
|
+
const raw = fs56.readFileSync(path70.join(e.root, "config.json"), "utf-8");
|
|
32728
32939
|
const parsed = JSON.parse(raw);
|
|
32729
32940
|
if (parsed.instanceName) name = parsed.instanceName;
|
|
32730
32941
|
} catch {
|
|
32731
32942
|
}
|
|
32732
|
-
const workspaceDir =
|
|
32943
|
+
const workspaceDir = path70.dirname(e.root);
|
|
32733
32944
|
const displayPath = workspaceDir.replace(os16.homedir(), "~");
|
|
32734
32945
|
return { value: e.root, label: `${name} (${displayPath})` };
|
|
32735
32946
|
});
|
|
32736
32947
|
if (detectedParent) {
|
|
32737
|
-
let name =
|
|
32948
|
+
let name = path70.basename(path70.dirname(detectedParent));
|
|
32738
32949
|
try {
|
|
32739
|
-
const raw = fs56.readFileSync(
|
|
32950
|
+
const raw = fs56.readFileSync(path70.join(detectedParent, "config.json"), "utf-8");
|
|
32740
32951
|
const parsed = JSON.parse(raw);
|
|
32741
32952
|
if (parsed.instanceName) name = parsed.instanceName;
|
|
32742
32953
|
} catch {
|
|
32743
32954
|
}
|
|
32744
|
-
const workspaceDir =
|
|
32955
|
+
const workspaceDir = path70.dirname(detectedParent);
|
|
32745
32956
|
const displayPath = workspaceDir.replace(os16.homedir(), "~");
|
|
32746
32957
|
instanceOptions.unshift({ value: detectedParent, label: `${name} (${displayPath})` });
|
|
32747
32958
|
}
|
|
@@ -32780,11 +32991,11 @@ async function promptForInstance(opts) {
|
|
|
32780
32991
|
return choice;
|
|
32781
32992
|
}
|
|
32782
32993
|
function findParentInstance(cwd, globalRoot) {
|
|
32783
|
-
let dir =
|
|
32994
|
+
let dir = path70.dirname(cwd);
|
|
32784
32995
|
while (true) {
|
|
32785
|
-
const candidate =
|
|
32786
|
-
if (candidate !== globalRoot && fs56.existsSync(
|
|
32787
|
-
const parent =
|
|
32996
|
+
const candidate = path70.join(dir, ".openacp");
|
|
32997
|
+
if (candidate !== globalRoot && fs56.existsSync(path70.join(candidate, "config.json"))) return candidate;
|
|
32998
|
+
const parent = path70.dirname(dir);
|
|
32788
32999
|
if (parent === dir) break;
|
|
32789
33000
|
dir = parent;
|
|
32790
33001
|
}
|
|
@@ -32800,7 +33011,7 @@ var init_instance_prompt = __esm({
|
|
|
32800
33011
|
|
|
32801
33012
|
// src/cli.ts
|
|
32802
33013
|
import { setDefaultAutoSelectFamily } from "net";
|
|
32803
|
-
import
|
|
33014
|
+
import path71 from "path";
|
|
32804
33015
|
|
|
32805
33016
|
// src/cli/commands/help.ts
|
|
32806
33017
|
function printHelp() {
|
|
@@ -32944,10 +33155,10 @@ Shows all plugins registered in the plugin registry.
|
|
|
32944
33155
|
`);
|
|
32945
33156
|
return;
|
|
32946
33157
|
}
|
|
32947
|
-
const
|
|
33158
|
+
const path72 = await import("path");
|
|
32948
33159
|
const { PluginRegistry: PluginRegistry2 } = await Promise.resolve().then(() => (init_plugin_registry(), plugin_registry_exports));
|
|
32949
33160
|
const root = instanceRoot;
|
|
32950
|
-
const registryPath =
|
|
33161
|
+
const registryPath = path72.join(root, "plugins.json");
|
|
32951
33162
|
const registry = new PluginRegistry2(registryPath);
|
|
32952
33163
|
await registry.load();
|
|
32953
33164
|
const plugins = registry.list();
|
|
@@ -33083,10 +33294,10 @@ async function cmdPlugin(args2 = [], instanceRoot) {
|
|
|
33083
33294
|
}
|
|
33084
33295
|
async function setPluginEnabled(name, enabled, instanceRoot, json = false) {
|
|
33085
33296
|
if (json) await muteForJson();
|
|
33086
|
-
const
|
|
33297
|
+
const path72 = await import("path");
|
|
33087
33298
|
const { PluginRegistry: PluginRegistry2 } = await Promise.resolve().then(() => (init_plugin_registry(), plugin_registry_exports));
|
|
33088
33299
|
const root = instanceRoot;
|
|
33089
|
-
const registryPath =
|
|
33300
|
+
const registryPath = path72.join(root, "plugins.json");
|
|
33090
33301
|
const registry = new PluginRegistry2(registryPath);
|
|
33091
33302
|
await registry.load();
|
|
33092
33303
|
const entry = registry.get(name);
|
|
@@ -33101,7 +33312,7 @@ async function setPluginEnabled(name, enabled, instanceRoot, json = false) {
|
|
|
33101
33312
|
console.log(`Plugin ${name} ${enabled ? "enabled" : "disabled"}. Restart to apply.`);
|
|
33102
33313
|
}
|
|
33103
33314
|
async function configurePlugin(name, instanceRoot) {
|
|
33104
|
-
const
|
|
33315
|
+
const path72 = await import("path");
|
|
33105
33316
|
const { corePlugins: corePlugins2 } = await Promise.resolve().then(() => (init_core_plugins(), core_plugins_exports));
|
|
33106
33317
|
const { SettingsManager: SettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
|
|
33107
33318
|
const { createInstallContext: createInstallContext2 } = await Promise.resolve().then(() => (init_install_context(), install_context_exports));
|
|
@@ -33111,7 +33322,7 @@ async function configurePlugin(name, instanceRoot) {
|
|
|
33111
33322
|
process.exit(1);
|
|
33112
33323
|
}
|
|
33113
33324
|
const root = instanceRoot;
|
|
33114
|
-
const basePath =
|
|
33325
|
+
const basePath = path72.join(root, "plugins", "data");
|
|
33115
33326
|
const settingsManager = new SettingsManager2(basePath);
|
|
33116
33327
|
const ctx = createInstallContext2({ pluginName: name, settingsManager, basePath });
|
|
33117
33328
|
if (plugin2.configure) {
|
|
@@ -33124,7 +33335,7 @@ async function configurePlugin(name, instanceRoot) {
|
|
|
33124
33335
|
}
|
|
33125
33336
|
async function installPlugin(input2, instanceRoot, json = false) {
|
|
33126
33337
|
if (json) await muteForJson();
|
|
33127
|
-
const
|
|
33338
|
+
const path72 = await import("path");
|
|
33128
33339
|
const { execFileSync: execFileSync9 } = await import("child_process");
|
|
33129
33340
|
const { getCurrentVersion: getCurrentVersion2 } = await Promise.resolve().then(() => (init_version(), version_exports));
|
|
33130
33341
|
const { SettingsManager: SettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
|
|
@@ -33175,9 +33386,9 @@ async function installPlugin(input2, instanceRoot, json = false) {
|
|
|
33175
33386
|
if (!json) console.log(`Installing ${installSpec}...`);
|
|
33176
33387
|
const { corePlugins: corePlugins2 } = await Promise.resolve().then(() => (init_core_plugins(), core_plugins_exports));
|
|
33177
33388
|
const builtinPlugin = corePlugins2.find((p2) => p2.name === pkgName);
|
|
33178
|
-
const basePath =
|
|
33389
|
+
const basePath = path72.join(root, "plugins", "data");
|
|
33179
33390
|
const settingsManager = new SettingsManager2(basePath);
|
|
33180
|
-
const registryPath =
|
|
33391
|
+
const registryPath = path72.join(root, "plugins.json");
|
|
33181
33392
|
const pluginRegistry = new PluginRegistry2(registryPath);
|
|
33182
33393
|
await pluginRegistry.load();
|
|
33183
33394
|
if (builtinPlugin) {
|
|
@@ -33197,8 +33408,8 @@ async function installPlugin(input2, instanceRoot, json = false) {
|
|
|
33197
33408
|
console.log(`\u2713 ${builtinPlugin.name} installed! Restart to activate.`);
|
|
33198
33409
|
return;
|
|
33199
33410
|
}
|
|
33200
|
-
const pluginsDir =
|
|
33201
|
-
const nodeModulesDir =
|
|
33411
|
+
const pluginsDir = path72.join(root, "plugins");
|
|
33412
|
+
const nodeModulesDir = path72.join(pluginsDir, "node_modules");
|
|
33202
33413
|
try {
|
|
33203
33414
|
execFileSync9("npm", ["install", installSpec, "--prefix", pluginsDir, "--save"], {
|
|
33204
33415
|
stdio: json ? "pipe" : "inherit",
|
|
@@ -33212,8 +33423,8 @@ async function installPlugin(input2, instanceRoot, json = false) {
|
|
|
33212
33423
|
const cliVersion = getCurrentVersion2();
|
|
33213
33424
|
const isLocalPath = pkgName.startsWith("/") || pkgName.startsWith(".");
|
|
33214
33425
|
try {
|
|
33215
|
-
const pluginRoot = isLocalPath ?
|
|
33216
|
-
const installedPkgPath =
|
|
33426
|
+
const pluginRoot = isLocalPath ? path72.resolve(pkgName) : path72.join(nodeModulesDir, pkgName);
|
|
33427
|
+
const installedPkgPath = path72.join(pluginRoot, "package.json");
|
|
33217
33428
|
const { readFileSync: readFileSync18 } = await import("fs");
|
|
33218
33429
|
const installedPkg = JSON.parse(readFileSync18(installedPkgPath, "utf-8"));
|
|
33219
33430
|
const minVersion = installedPkg.engines?.openacp?.replace(/[>=^~\s]/g, "");
|
|
@@ -33228,7 +33439,7 @@ async function installPlugin(input2, instanceRoot, json = false) {
|
|
|
33228
33439
|
}
|
|
33229
33440
|
}
|
|
33230
33441
|
}
|
|
33231
|
-
const pluginModule = await import(
|
|
33442
|
+
const pluginModule = await import(path72.join(pluginRoot, installedPkg.main ?? "dist/index.js"));
|
|
33232
33443
|
const plugin2 = pluginModule.default;
|
|
33233
33444
|
if (plugin2?.install) {
|
|
33234
33445
|
const ctx = createInstallContext2({ pluginName: plugin2.name ?? pkgName, settingsManager, basePath });
|
|
@@ -33258,11 +33469,11 @@ async function installPlugin(input2, instanceRoot, json = false) {
|
|
|
33258
33469
|
}
|
|
33259
33470
|
async function uninstallPlugin(name, purge, instanceRoot, json = false) {
|
|
33260
33471
|
if (json) await muteForJson();
|
|
33261
|
-
const
|
|
33472
|
+
const path72 = await import("path");
|
|
33262
33473
|
const fs57 = await import("fs");
|
|
33263
33474
|
const { PluginRegistry: PluginRegistry2 } = await Promise.resolve().then(() => (init_plugin_registry(), plugin_registry_exports));
|
|
33264
33475
|
const root = instanceRoot;
|
|
33265
|
-
const registryPath =
|
|
33476
|
+
const registryPath = path72.join(root, "plugins.json");
|
|
33266
33477
|
const registry = new PluginRegistry2(registryPath);
|
|
33267
33478
|
await registry.load();
|
|
33268
33479
|
const entry = registry.get(name);
|
|
@@ -33282,7 +33493,7 @@ async function uninstallPlugin(name, purge, instanceRoot, json = false) {
|
|
|
33282
33493
|
if (plugin2?.uninstall) {
|
|
33283
33494
|
const { SettingsManager: SettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
|
|
33284
33495
|
const { createInstallContext: createInstallContext2 } = await Promise.resolve().then(() => (init_install_context(), install_context_exports));
|
|
33285
|
-
const basePath =
|
|
33496
|
+
const basePath = path72.join(root, "plugins", "data");
|
|
33286
33497
|
const settingsManager = new SettingsManager2(basePath);
|
|
33287
33498
|
const ctx = createInstallContext2({ pluginName: name, settingsManager, basePath });
|
|
33288
33499
|
await plugin2.uninstall(ctx, { purge });
|
|
@@ -33290,7 +33501,7 @@ async function uninstallPlugin(name, purge, instanceRoot, json = false) {
|
|
|
33290
33501
|
} catch {
|
|
33291
33502
|
}
|
|
33292
33503
|
if (purge) {
|
|
33293
|
-
const pluginDir =
|
|
33504
|
+
const pluginDir = path72.join(root, "plugins", name);
|
|
33294
33505
|
fs57.rmSync(pluginDir, { recursive: true, force: true });
|
|
33295
33506
|
}
|
|
33296
33507
|
registry.remove(name);
|
|
@@ -33331,12 +33542,12 @@ init_helpers();
|
|
|
33331
33542
|
init_output();
|
|
33332
33543
|
import { execSync as execSync2 } from "child_process";
|
|
33333
33544
|
import * as fs32 from "fs";
|
|
33334
|
-
import * as
|
|
33545
|
+
import * as path36 from "path";
|
|
33335
33546
|
async function cmdUninstall(args2, instanceRoot) {
|
|
33336
33547
|
const json = isJsonMode(args2);
|
|
33337
33548
|
if (json) await muteForJson();
|
|
33338
33549
|
const root = instanceRoot;
|
|
33339
|
-
const pluginsDir =
|
|
33550
|
+
const pluginsDir = path36.join(root, "plugins");
|
|
33340
33551
|
if (!json && wantsHelp(args2)) {
|
|
33341
33552
|
console.log(`
|
|
33342
33553
|
\x1B[1mopenacp uninstall\x1B[0m \u2014 Remove a plugin adapter
|
|
@@ -33363,7 +33574,7 @@ async function cmdUninstall(args2, instanceRoot) {
|
|
|
33363
33574
|
process.exit(1);
|
|
33364
33575
|
}
|
|
33365
33576
|
fs32.mkdirSync(pluginsDir, { recursive: true });
|
|
33366
|
-
const pkgPath =
|
|
33577
|
+
const pkgPath = path36.join(pluginsDir, "package.json");
|
|
33367
33578
|
if (!fs32.existsSync(pkgPath)) {
|
|
33368
33579
|
fs32.writeFileSync(pkgPath, JSON.stringify({ name: "openacp-plugins", private: true, dependencies: {} }, null, 2));
|
|
33369
33580
|
}
|
|
@@ -34209,7 +34420,7 @@ init_helpers();
|
|
|
34209
34420
|
init_output();
|
|
34210
34421
|
init_instance_hint();
|
|
34211
34422
|
init_resolve_instance_id();
|
|
34212
|
-
import
|
|
34423
|
+
import path42 from "path";
|
|
34213
34424
|
async function cmdStart(args2 = [], instanceRoot) {
|
|
34214
34425
|
const json = isJsonMode(args2);
|
|
34215
34426
|
if (json) await muteForJson();
|
|
@@ -34239,7 +34450,7 @@ Requires an existing config \u2014 run 'openacp' first to set up.
|
|
|
34239
34450
|
await checkAndPromptUpdate();
|
|
34240
34451
|
const { startDaemon: startDaemon2, getPidPath: getPidPath2, isProcessRunning: isProcessRunning2 } = await Promise.resolve().then(() => (init_daemon2(), daemon_exports));
|
|
34241
34452
|
const { ConfigManager: ConfigManager2 } = await Promise.resolve().then(() => (init_config2(), config_exports));
|
|
34242
|
-
const cm = new ConfigManager2(
|
|
34453
|
+
const cm = new ConfigManager2(path42.join(root, "config.json"));
|
|
34243
34454
|
if (await cm.exists()) {
|
|
34244
34455
|
await cm.load();
|
|
34245
34456
|
const config = cm.get();
|
|
@@ -34265,12 +34476,12 @@ Requires an existing config \u2014 run 'openacp' first to set up.
|
|
|
34265
34476
|
}
|
|
34266
34477
|
if (json) {
|
|
34267
34478
|
const { waitForPortFile: waitForPortFile2 } = await Promise.resolve().then(() => (init_api_client(), api_client_exports));
|
|
34268
|
-
const port = await waitForPortFile2(
|
|
34479
|
+
const port = await waitForPortFile2(path42.join(root, "api.port")) ?? 21420;
|
|
34269
34480
|
jsonSuccess({
|
|
34270
34481
|
pid: result.pid,
|
|
34271
34482
|
instanceId,
|
|
34272
34483
|
name: config.instanceName ?? null,
|
|
34273
|
-
directory:
|
|
34484
|
+
directory: path42.dirname(root),
|
|
34274
34485
|
dir: root,
|
|
34275
34486
|
port
|
|
34276
34487
|
});
|
|
@@ -34440,7 +34651,7 @@ start fresh with the setup wizard. The daemon must be stopped first.
|
|
|
34440
34651
|
`);
|
|
34441
34652
|
return;
|
|
34442
34653
|
}
|
|
34443
|
-
const
|
|
34654
|
+
const path72 = await import("path");
|
|
34444
34655
|
const root = instanceRoot;
|
|
34445
34656
|
const { getStatus: getStatus2, getPidPath: getPidPath2 } = await Promise.resolve().then(() => (init_daemon2(), daemon_exports));
|
|
34446
34657
|
const status = getStatus2(getPidPath2(root));
|
|
@@ -34602,14 +34813,14 @@ as a messaging thread. Requires a running daemon.
|
|
|
34602
34813
|
// src/cli/commands/instances.ts
|
|
34603
34814
|
init_instance_registry();
|
|
34604
34815
|
init_instance_context();
|
|
34605
|
-
import
|
|
34816
|
+
import path61 from "path";
|
|
34606
34817
|
import os13 from "os";
|
|
34607
34818
|
import fs52 from "fs";
|
|
34608
34819
|
import { randomUUID as randomUUID6 } from "crypto";
|
|
34609
34820
|
|
|
34610
34821
|
// src/core/instance/instance-init.ts
|
|
34611
34822
|
import fs51 from "fs";
|
|
34612
|
-
import
|
|
34823
|
+
import path60 from "path";
|
|
34613
34824
|
function initInstanceFiles(instanceRoot, opts = {}) {
|
|
34614
34825
|
fs51.mkdirSync(instanceRoot, { recursive: true });
|
|
34615
34826
|
writeConfig(instanceRoot, opts);
|
|
@@ -34619,7 +34830,7 @@ function initInstanceFiles(instanceRoot, opts = {}) {
|
|
|
34619
34830
|
writePluginsIfMissing(instanceRoot);
|
|
34620
34831
|
}
|
|
34621
34832
|
function writeConfig(instanceRoot, opts) {
|
|
34622
|
-
const configPath =
|
|
34833
|
+
const configPath = path60.join(instanceRoot, "config.json");
|
|
34623
34834
|
let existing = {};
|
|
34624
34835
|
if (opts.mergeExisting && fs51.existsSync(configPath)) {
|
|
34625
34836
|
try {
|
|
@@ -34649,7 +34860,7 @@ function writeConfig(instanceRoot, opts) {
|
|
|
34649
34860
|
fs51.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
34650
34861
|
}
|
|
34651
34862
|
function writeAgentsIfMissing(instanceRoot, agents) {
|
|
34652
|
-
const agentsPath =
|
|
34863
|
+
const agentsPath = path60.join(instanceRoot, "agents.json");
|
|
34653
34864
|
if (fs51.existsSync(agentsPath)) return;
|
|
34654
34865
|
const installed = {};
|
|
34655
34866
|
for (const agentName of agents) {
|
|
@@ -34668,7 +34879,7 @@ function writeAgentsIfMissing(instanceRoot, agents) {
|
|
|
34668
34879
|
fs51.writeFileSync(agentsPath, JSON.stringify({ version: 1, installed }, null, 2));
|
|
34669
34880
|
}
|
|
34670
34881
|
function writePluginsIfMissing(instanceRoot) {
|
|
34671
|
-
const pluginsPath =
|
|
34882
|
+
const pluginsPath = path60.join(instanceRoot, "plugins.json");
|
|
34672
34883
|
if (!fs51.existsSync(pluginsPath)) {
|
|
34673
34884
|
fs51.writeFileSync(pluginsPath, JSON.stringify({ version: 1, installed: {} }, null, 2));
|
|
34674
34885
|
}
|
|
@@ -34679,7 +34890,7 @@ init_status();
|
|
|
34679
34890
|
init_output();
|
|
34680
34891
|
init_helpers();
|
|
34681
34892
|
async function buildInstanceListEntries() {
|
|
34682
|
-
const registryPath =
|
|
34893
|
+
const registryPath = path61.join(getGlobalRoot(), "instances.json");
|
|
34683
34894
|
const registry = new InstanceRegistry(registryPath);
|
|
34684
34895
|
registry.load();
|
|
34685
34896
|
const entries = registry.list();
|
|
@@ -34689,7 +34900,7 @@ async function buildInstanceListEntries() {
|
|
|
34689
34900
|
return {
|
|
34690
34901
|
id: entry.id,
|
|
34691
34902
|
name: info.name,
|
|
34692
|
-
directory:
|
|
34903
|
+
directory: path61.dirname(entry.root),
|
|
34693
34904
|
root: entry.root,
|
|
34694
34905
|
status,
|
|
34695
34906
|
port: info.apiPort
|
|
@@ -34782,9 +34993,9 @@ async function cmdInstancesCreate(args2) {
|
|
|
34782
34993
|
const agentIdx = args2.indexOf("--agent");
|
|
34783
34994
|
const agent = agentIdx !== -1 ? args2[agentIdx + 1] : void 0;
|
|
34784
34995
|
const noInteractive = args2.includes("--no-interactive");
|
|
34785
|
-
const resolvedDir =
|
|
34786
|
-
const instanceRoot =
|
|
34787
|
-
const registryPath =
|
|
34996
|
+
const resolvedDir = path61.resolve(rawDir.replace(/^~/, os13.homedir()));
|
|
34997
|
+
const instanceRoot = path61.join(resolvedDir, ".openacp");
|
|
34998
|
+
const registryPath = path61.join(getGlobalRoot(), "instances.json");
|
|
34788
34999
|
const registry = new InstanceRegistry(registryPath);
|
|
34789
35000
|
registry.load();
|
|
34790
35001
|
if (fs52.existsSync(instanceRoot)) {
|
|
@@ -34809,8 +35020,8 @@ async function cmdInstancesCreate(args2) {
|
|
|
34809
35020
|
const name = instanceName ?? `openacp-${registry.list().length + 1}`;
|
|
34810
35021
|
const id = randomUUID6();
|
|
34811
35022
|
if (rawFrom) {
|
|
34812
|
-
const fromRoot =
|
|
34813
|
-
if (!fs52.existsSync(
|
|
35023
|
+
const fromRoot = path61.join(path61.resolve(rawFrom.replace(/^~/, os13.homedir())), ".openacp");
|
|
35024
|
+
if (!fs52.existsSync(path61.join(fromRoot, "config.json"))) {
|
|
34814
35025
|
console.error(`Error: No OpenACP instance found at ${rawFrom}`);
|
|
34815
35026
|
process.exit(1);
|
|
34816
35027
|
}
|
|
@@ -34834,7 +35045,7 @@ async function outputInstance(json, { id, root }) {
|
|
|
34834
35045
|
const entry = {
|
|
34835
35046
|
id,
|
|
34836
35047
|
name: info.name,
|
|
34837
|
-
directory:
|
|
35048
|
+
directory: path61.dirname(root),
|
|
34838
35049
|
root,
|
|
34839
35050
|
status: info.pid ? "running" : "stopped",
|
|
34840
35051
|
port: info.apiPort
|
|
@@ -34843,7 +35054,7 @@ async function outputInstance(json, { id, root }) {
|
|
|
34843
35054
|
jsonSuccess(entry);
|
|
34844
35055
|
return;
|
|
34845
35056
|
}
|
|
34846
|
-
console.log(`Instance created: ${info.name ?? id} at ${
|
|
35057
|
+
console.log(`Instance created: ${info.name ?? id} at ${path61.dirname(root)}`);
|
|
34847
35058
|
}
|
|
34848
35059
|
|
|
34849
35060
|
// src/cli/commands/integrate.ts
|
|
@@ -35604,15 +35815,15 @@ Options:
|
|
|
35604
35815
|
}
|
|
35605
35816
|
|
|
35606
35817
|
// src/cli/commands/onboard.ts
|
|
35607
|
-
import * as
|
|
35818
|
+
import * as path62 from "path";
|
|
35608
35819
|
async function cmdOnboard(instanceRoot) {
|
|
35609
35820
|
const { ConfigManager: ConfigManager2 } = await Promise.resolve().then(() => (init_config2(), config_exports));
|
|
35610
35821
|
const { SettingsManager: SettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
|
|
35611
35822
|
const { PluginRegistry: PluginRegistry2 } = await Promise.resolve().then(() => (init_plugin_registry(), plugin_registry_exports));
|
|
35612
35823
|
const OPENACP_DIR = instanceRoot;
|
|
35613
|
-
const PLUGINS_DATA_DIR =
|
|
35614
|
-
const REGISTRY_PATH =
|
|
35615
|
-
const cm = new ConfigManager2(
|
|
35824
|
+
const PLUGINS_DATA_DIR = path62.join(OPENACP_DIR, "plugins", "data");
|
|
35825
|
+
const REGISTRY_PATH = path62.join(OPENACP_DIR, "plugins.json");
|
|
35826
|
+
const cm = new ConfigManager2(path62.join(OPENACP_DIR, "config.json"));
|
|
35616
35827
|
const settingsManager = new SettingsManager2(PLUGINS_DATA_DIR);
|
|
35617
35828
|
const pluginRegistry = new PluginRegistry2(REGISTRY_PATH);
|
|
35618
35829
|
await pluginRegistry.load();
|
|
@@ -35632,15 +35843,15 @@ init_instance_registry();
|
|
|
35632
35843
|
init_instance_hint();
|
|
35633
35844
|
init_output();
|
|
35634
35845
|
init_resolve_instance_id();
|
|
35635
|
-
import
|
|
35846
|
+
import path63 from "path";
|
|
35636
35847
|
import { randomUUID as randomUUID7 } from "crypto";
|
|
35637
35848
|
async function cmdDefault(command2, instanceRoot) {
|
|
35638
35849
|
const args2 = command2 ? [command2] : [];
|
|
35639
35850
|
const json = isJsonMode(args2);
|
|
35640
35851
|
if (json) await muteForJson();
|
|
35641
35852
|
const root = instanceRoot;
|
|
35642
|
-
const pluginsDataDir =
|
|
35643
|
-
const registryPath =
|
|
35853
|
+
const pluginsDataDir = path63.join(root, "plugins", "data");
|
|
35854
|
+
const registryPath = path63.join(root, "plugins.json");
|
|
35644
35855
|
const forceForeground = command2 === "--foreground";
|
|
35645
35856
|
if (command2 && !command2.startsWith("-")) {
|
|
35646
35857
|
const { suggestMatch: suggestMatch2 } = await Promise.resolve().then(() => (init_suggest(), suggest_exports));
|
|
@@ -35672,7 +35883,7 @@ async function cmdDefault(command2, instanceRoot) {
|
|
|
35672
35883
|
}
|
|
35673
35884
|
await checkAndPromptUpdate();
|
|
35674
35885
|
const { ConfigManager: ConfigManager2 } = await Promise.resolve().then(() => (init_config2(), config_exports));
|
|
35675
|
-
const configPath =
|
|
35886
|
+
const configPath = path63.join(root, "config.json");
|
|
35676
35887
|
const cm = new ConfigManager2(configPath);
|
|
35677
35888
|
if (!await cm.exists()) {
|
|
35678
35889
|
const { SettingsManager: SettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
|
|
@@ -35709,12 +35920,12 @@ async function cmdDefault(command2, instanceRoot) {
|
|
|
35709
35920
|
}
|
|
35710
35921
|
if (json) {
|
|
35711
35922
|
const { waitForPortFile: waitForPortFile2 } = await Promise.resolve().then(() => (init_api_client(), api_client_exports));
|
|
35712
|
-
const port = await waitForPortFile2(
|
|
35923
|
+
const port = await waitForPortFile2(path63.join(root, "api.port")) ?? 21420;
|
|
35713
35924
|
jsonSuccess({
|
|
35714
35925
|
pid: result.pid,
|
|
35715
35926
|
instanceId: instanceId2,
|
|
35716
35927
|
name: config.instanceName ?? null,
|
|
35717
|
-
directory:
|
|
35928
|
+
directory: path63.dirname(root),
|
|
35718
35929
|
dir: root,
|
|
35719
35930
|
port
|
|
35720
35931
|
});
|
|
@@ -35727,7 +35938,7 @@ async function cmdDefault(command2, instanceRoot) {
|
|
|
35727
35938
|
markRunning2(root);
|
|
35728
35939
|
printInstanceHint(root);
|
|
35729
35940
|
const { startServer: startServer2 } = await Promise.resolve().then(() => (init_main(), main_exports));
|
|
35730
|
-
const reg = new InstanceRegistry(
|
|
35941
|
+
const reg = new InstanceRegistry(path63.join(getGlobalRoot(), "instances.json"));
|
|
35731
35942
|
reg.load();
|
|
35732
35943
|
const existingEntry = reg.getByRoot(root);
|
|
35733
35944
|
const instanceId = existingEntry?.id ?? randomUUID7();
|
|
@@ -35741,7 +35952,7 @@ async function cmdDefault(command2, instanceRoot) {
|
|
|
35741
35952
|
pid: process.pid,
|
|
35742
35953
|
instanceId,
|
|
35743
35954
|
name: config.instanceName ?? null,
|
|
35744
|
-
directory:
|
|
35955
|
+
directory: path63.dirname(root),
|
|
35745
35956
|
dir: root,
|
|
35746
35957
|
port
|
|
35747
35958
|
});
|
|
@@ -35810,7 +36021,7 @@ async function showAlreadyRunningMenu(root) {
|
|
|
35810
36021
|
// src/cli/commands/dev.ts
|
|
35811
36022
|
init_helpers();
|
|
35812
36023
|
import fs53 from "fs";
|
|
35813
|
-
import
|
|
36024
|
+
import path64 from "path";
|
|
35814
36025
|
async function cmdDev(args2 = []) {
|
|
35815
36026
|
if (wantsHelp(args2)) {
|
|
35816
36027
|
console.log(`
|
|
@@ -35837,12 +36048,12 @@ async function cmdDev(args2 = []) {
|
|
|
35837
36048
|
console.error("Error: missing plugin path. Usage: openacp dev <plugin-path>");
|
|
35838
36049
|
process.exit(1);
|
|
35839
36050
|
}
|
|
35840
|
-
const pluginPath =
|
|
36051
|
+
const pluginPath = path64.resolve(pluginPathArg);
|
|
35841
36052
|
if (!fs53.existsSync(pluginPath)) {
|
|
35842
36053
|
console.error(`Error: plugin path does not exist: ${pluginPath}`);
|
|
35843
36054
|
process.exit(1);
|
|
35844
36055
|
}
|
|
35845
|
-
const tsconfigPath =
|
|
36056
|
+
const tsconfigPath = path64.join(pluginPath, "tsconfig.json");
|
|
35846
36057
|
const hasTsconfig = fs53.existsSync(tsconfigPath);
|
|
35847
36058
|
if (hasTsconfig) {
|
|
35848
36059
|
console.log("Compiling plugin TypeScript...");
|
|
@@ -35884,7 +36095,7 @@ async function cmdDev(args2 = []) {
|
|
|
35884
36095
|
|
|
35885
36096
|
// src/cli/commands/attach.ts
|
|
35886
36097
|
init_helpers();
|
|
35887
|
-
import
|
|
36098
|
+
import path65 from "path";
|
|
35888
36099
|
async function cmdAttach(args2 = [], instanceRoot) {
|
|
35889
36100
|
const root = instanceRoot;
|
|
35890
36101
|
if (wantsHelp(args2)) {
|
|
@@ -35920,15 +36131,15 @@ Press Ctrl+C to detach.
|
|
|
35920
36131
|
console.log("");
|
|
35921
36132
|
const { spawn: spawn9 } = await import("child_process");
|
|
35922
36133
|
const { expandHome: expandHome4 } = await Promise.resolve().then(() => (init_config2(), config_exports));
|
|
35923
|
-
let logDir2 =
|
|
36134
|
+
let logDir2 = path65.join(root, "logs");
|
|
35924
36135
|
try {
|
|
35925
|
-
const configPath =
|
|
36136
|
+
const configPath = path65.join(root, "config.json");
|
|
35926
36137
|
const { readFileSync: readFileSync18 } = await import("fs");
|
|
35927
36138
|
const config = JSON.parse(readFileSync18(configPath, "utf-8"));
|
|
35928
36139
|
if (config.logging?.logDir) logDir2 = expandHome4(config.logging.logDir);
|
|
35929
36140
|
} catch {
|
|
35930
36141
|
}
|
|
35931
|
-
const logFile =
|
|
36142
|
+
const logFile = path65.join(logDir2, "openacp.log");
|
|
35932
36143
|
const tail = spawn9("tail", ["-f", "-n", "50", logFile], { stdio: "inherit" });
|
|
35933
36144
|
tail.on("error", (err) => {
|
|
35934
36145
|
console.error(`Cannot tail log file: ${err.message}`);
|
|
@@ -35940,7 +36151,7 @@ Press Ctrl+C to detach.
|
|
|
35940
36151
|
init_api_client();
|
|
35941
36152
|
init_instance_registry();
|
|
35942
36153
|
init_output();
|
|
35943
|
-
import
|
|
36154
|
+
import path66 from "path";
|
|
35944
36155
|
import os14 from "os";
|
|
35945
36156
|
import qrcode from "qrcode-terminal";
|
|
35946
36157
|
async function cmdRemote(args2, instanceRoot) {
|
|
@@ -35956,7 +36167,7 @@ async function cmdRemote(args2, instanceRoot) {
|
|
|
35956
36167
|
const scopes = scopesRaw ? scopesRaw.split(",").map((s) => s.trim()) : void 0;
|
|
35957
36168
|
let resolvedInstanceRoot2 = instanceRoot;
|
|
35958
36169
|
if (instanceId) {
|
|
35959
|
-
const registryPath =
|
|
36170
|
+
const registryPath = path66.join(os14.homedir(), ".openacp", "instances.json");
|
|
35960
36171
|
const registry = new InstanceRegistry(registryPath);
|
|
35961
36172
|
await registry.load();
|
|
35962
36173
|
const entry = registry.get(instanceId);
|
|
@@ -36095,7 +36306,7 @@ function extractFlag(args2, flag) {
|
|
|
36095
36306
|
init_output();
|
|
36096
36307
|
init_instance_context();
|
|
36097
36308
|
init_instance_registry();
|
|
36098
|
-
import * as
|
|
36309
|
+
import * as path67 from "path";
|
|
36099
36310
|
import fs54 from "fs";
|
|
36100
36311
|
function parseFlag(args2, flag) {
|
|
36101
36312
|
const idx = args2.indexOf(flag);
|
|
@@ -36103,7 +36314,7 @@ function parseFlag(args2, flag) {
|
|
|
36103
36314
|
}
|
|
36104
36315
|
function readConfigField(instanceRoot, field) {
|
|
36105
36316
|
try {
|
|
36106
|
-
const raw = JSON.parse(fs54.readFileSync(
|
|
36317
|
+
const raw = JSON.parse(fs54.readFileSync(path67.join(instanceRoot, "config.json"), "utf-8"));
|
|
36107
36318
|
return typeof raw[field] === "string" ? raw[field] : null;
|
|
36108
36319
|
} catch {
|
|
36109
36320
|
return null;
|
|
@@ -36126,7 +36337,7 @@ async function cmdSetup(args2, instanceRoot) {
|
|
|
36126
36337
|
}
|
|
36127
36338
|
const runMode = rawRunMode;
|
|
36128
36339
|
const agents = agentRaw.split(",").map((a) => a.trim());
|
|
36129
|
-
const registryPath =
|
|
36340
|
+
const registryPath = path67.join(getGlobalRoot(), "instances.json");
|
|
36130
36341
|
const registry = new InstanceRegistry(registryPath);
|
|
36131
36342
|
registry.load();
|
|
36132
36343
|
const { id, registryUpdated } = registry.resolveId(instanceRoot);
|
|
@@ -36134,9 +36345,9 @@ async function cmdSetup(args2, instanceRoot) {
|
|
|
36134
36345
|
if (registryUpdated) {
|
|
36135
36346
|
registry.save();
|
|
36136
36347
|
}
|
|
36137
|
-
const name = readConfigField(instanceRoot, "instanceName") ??
|
|
36348
|
+
const name = readConfigField(instanceRoot, "instanceName") ?? path67.basename(path67.dirname(instanceRoot));
|
|
36138
36349
|
if (!readConfigField(instanceRoot, "instanceName")) {
|
|
36139
|
-
const configPath =
|
|
36350
|
+
const configPath = path67.join(instanceRoot, "config.json");
|
|
36140
36351
|
try {
|
|
36141
36352
|
const raw = JSON.parse(fs54.readFileSync(configPath, "utf-8"));
|
|
36142
36353
|
raw.instanceName = name;
|
|
@@ -36145,17 +36356,17 @@ async function cmdSetup(args2, instanceRoot) {
|
|
|
36145
36356
|
}
|
|
36146
36357
|
}
|
|
36147
36358
|
if (json) {
|
|
36148
|
-
jsonSuccess({ id, name, directory:
|
|
36359
|
+
jsonSuccess({ id, name, directory: path67.dirname(instanceRoot), configPath: path67.join(instanceRoot, "config.json") });
|
|
36149
36360
|
} else {
|
|
36150
36361
|
console.log(`
|
|
36151
|
-
\x1B[32m\u2713 Setup complete.\x1B[0m Config written to ${
|
|
36362
|
+
\x1B[32m\u2713 Setup complete.\x1B[0m Config written to ${path67.join(instanceRoot, "config.json")}
|
|
36152
36363
|
`);
|
|
36153
36364
|
}
|
|
36154
36365
|
}
|
|
36155
36366
|
|
|
36156
36367
|
// src/cli/commands/autostart.ts
|
|
36157
36368
|
init_helpers();
|
|
36158
|
-
import
|
|
36369
|
+
import path68 from "path";
|
|
36159
36370
|
async function cmdAutostart(args2 = [], instanceRoot) {
|
|
36160
36371
|
const subcommand = args2[0];
|
|
36161
36372
|
if (!subcommand || wantsHelp(args2)) {
|
|
@@ -36193,7 +36404,7 @@ async function cmdAutostart(args2 = [], instanceRoot) {
|
|
|
36193
36404
|
let logDir2 = `${root}/logs`;
|
|
36194
36405
|
try {
|
|
36195
36406
|
const { ConfigManager: ConfigManager2 } = await Promise.resolve().then(() => (init_config2(), config_exports));
|
|
36196
|
-
const cm = new ConfigManager2(
|
|
36407
|
+
const cm = new ConfigManager2(path68.join(root, "config.json"));
|
|
36197
36408
|
if (await cm.exists()) {
|
|
36198
36409
|
await cm.load();
|
|
36199
36410
|
logDir2 = cm.get().logging?.logDir ?? logDir2;
|
|
@@ -36381,7 +36592,7 @@ async function main() {
|
|
|
36381
36592
|
if (envRoot) {
|
|
36382
36593
|
const { createInstanceContext: createInstanceContext2, getGlobalRoot: getGlobal } = await Promise.resolve().then(() => (init_instance_context(), instance_context_exports));
|
|
36383
36594
|
const { InstanceRegistry: InstanceRegistry2 } = await Promise.resolve().then(() => (init_instance_registry(), instance_registry_exports));
|
|
36384
|
-
const registry = new InstanceRegistry2(
|
|
36595
|
+
const registry = new InstanceRegistry2(path71.join(getGlobal(), "instances.json"));
|
|
36385
36596
|
await registry.load();
|
|
36386
36597
|
const entry = registry.getByRoot(envRoot);
|
|
36387
36598
|
const { randomUUID: randomUUID9 } = await import("crypto");
|