@n1creator/openacp-cli 2026.712.4 → 2026.712.6
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 +727 -501
- 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
|
@@ -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,7 +6308,7 @@ 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";
|
|
@@ -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"() {
|
|
@@ -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
|
}
|
|
@@ -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"() {
|
|
@@ -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",
|
|
@@ -10043,15 +10266,23 @@ var init_agent_registry = __esm({
|
|
|
10043
10266
|
// src/plugins/api-server/routes/agents.ts
|
|
10044
10267
|
var agents_exports = {};
|
|
10045
10268
|
__export(agents_exports, {
|
|
10046
|
-
agentRoutes: () => agentRoutes
|
|
10269
|
+
agentRoutes: () => agentRoutes,
|
|
10270
|
+
redactAgentEnv: () => redactAgentEnv
|
|
10047
10271
|
});
|
|
10272
|
+
function redactAgentEnv(agent) {
|
|
10273
|
+
if (!agent.env) return agent;
|
|
10274
|
+
return {
|
|
10275
|
+
...agent,
|
|
10276
|
+
env: Object.fromEntries(Object.keys(agent.env).map((key) => [key, "***"]))
|
|
10277
|
+
};
|
|
10278
|
+
}
|
|
10048
10279
|
async function agentRoutes(app, deps) {
|
|
10049
10280
|
function loadAndListAgents() {
|
|
10050
10281
|
deps.core.agentCatalog.load();
|
|
10051
10282
|
const agents = deps.core.agentManager.getAvailableAgents();
|
|
10052
10283
|
const defaultAgent = deps.core.configManager.get().defaultAgent;
|
|
10053
10284
|
const agentsWithCaps = agents.map((a) => ({
|
|
10054
|
-
...a,
|
|
10285
|
+
...redactAgentEnv(a),
|
|
10055
10286
|
capabilities: getAgentCapabilities(a.name)
|
|
10056
10287
|
}));
|
|
10057
10288
|
return { agents: agentsWithCaps, default: defaultAgent };
|
|
@@ -10069,7 +10300,7 @@ async function agentRoutes(app, deps) {
|
|
|
10069
10300
|
throw new NotFoundError("AGENT_NOT_FOUND", `Agent "${name}" not found`);
|
|
10070
10301
|
}
|
|
10071
10302
|
return {
|
|
10072
|
-
...agent,
|
|
10303
|
+
...redactAgentEnv(agent),
|
|
10073
10304
|
key: name,
|
|
10074
10305
|
capabilities: getAgentCapabilities(name)
|
|
10075
10306
|
};
|
|
@@ -10100,7 +10331,7 @@ var init_config = __esm({
|
|
|
10100
10331
|
|
|
10101
10332
|
// src/core/config/config-migrations.ts
|
|
10102
10333
|
import fs18 from "fs";
|
|
10103
|
-
import
|
|
10334
|
+
import path22 from "path";
|
|
10104
10335
|
import os4 from "os";
|
|
10105
10336
|
function applyMigrations(raw, migrationList = migrations, ctx) {
|
|
10106
10337
|
let changed = false;
|
|
@@ -10150,7 +10381,7 @@ var init_config_migrations = __esm({
|
|
|
10150
10381
|
if (!ctx?.configDir) return false;
|
|
10151
10382
|
const instanceRoot = ctx.configDir;
|
|
10152
10383
|
try {
|
|
10153
|
-
const registryPath =
|
|
10384
|
+
const registryPath = path22.join(os4.homedir(), ".openacp", "instances.json");
|
|
10154
10385
|
const data = JSON.parse(fs18.readFileSync(registryPath, "utf-8"));
|
|
10155
10386
|
const instances = data?.instances ?? {};
|
|
10156
10387
|
const entry = Object.values(instances).find(
|
|
@@ -10179,13 +10410,13 @@ __export(config_exports, {
|
|
|
10179
10410
|
});
|
|
10180
10411
|
import { z as z4 } from "zod";
|
|
10181
10412
|
import * as fs19 from "fs";
|
|
10182
|
-
import * as
|
|
10413
|
+
import * as path23 from "path";
|
|
10183
10414
|
import * as os5 from "os";
|
|
10184
10415
|
import { randomBytes as randomBytes3 } from "crypto";
|
|
10185
10416
|
import { EventEmitter } from "events";
|
|
10186
10417
|
function expandHome2(p2) {
|
|
10187
10418
|
if (p2.startsWith("~")) {
|
|
10188
|
-
return
|
|
10419
|
+
return path23.join(os5.homedir(), p2.slice(1));
|
|
10189
10420
|
}
|
|
10190
10421
|
return p2;
|
|
10191
10422
|
}
|
|
@@ -10259,7 +10490,7 @@ var init_config2 = __esm({
|
|
|
10259
10490
|
* 4. Validate against Zod schema — exits on failure
|
|
10260
10491
|
*/
|
|
10261
10492
|
async load() {
|
|
10262
|
-
const dir =
|
|
10493
|
+
const dir = path23.dirname(this.configPath);
|
|
10263
10494
|
fs19.mkdirSync(dir, { recursive: true });
|
|
10264
10495
|
if (!fs19.existsSync(this.configPath)) {
|
|
10265
10496
|
fs19.writeFileSync(
|
|
@@ -10273,7 +10504,7 @@ var init_config2 = __esm({
|
|
|
10273
10504
|
process.exit(1);
|
|
10274
10505
|
}
|
|
10275
10506
|
const raw = JSON.parse(fs19.readFileSync(this.configPath, "utf-8"));
|
|
10276
|
-
const { changed: configUpdated } = applyMigrations(raw, void 0, { configDir:
|
|
10507
|
+
const { changed: configUpdated } = applyMigrations(raw, void 0, { configDir: path23.dirname(this.configPath) });
|
|
10277
10508
|
if (configUpdated) {
|
|
10278
10509
|
fs19.writeFileSync(this.configPath, JSON.stringify(raw, null, 2));
|
|
10279
10510
|
}
|
|
@@ -10353,16 +10584,16 @@ var init_config2 = __esm({
|
|
|
10353
10584
|
* (alphanumeric subdirectories under the base).
|
|
10354
10585
|
*/
|
|
10355
10586
|
resolveWorkspace(input2) {
|
|
10356
|
-
const workspaceBase =
|
|
10587
|
+
const workspaceBase = path23.dirname(path23.dirname(this.configPath));
|
|
10357
10588
|
if (!input2) {
|
|
10358
10589
|
fs19.mkdirSync(workspaceBase, { recursive: true });
|
|
10359
10590
|
return workspaceBase;
|
|
10360
10591
|
}
|
|
10361
10592
|
const expanded = input2.startsWith("~") ? expandHome2(input2) : input2;
|
|
10362
|
-
if (
|
|
10363
|
-
const resolved =
|
|
10364
|
-
const base =
|
|
10365
|
-
const isInternal = resolved === base || resolved.startsWith(base +
|
|
10593
|
+
if (path23.isAbsolute(expanded)) {
|
|
10594
|
+
const resolved = path23.resolve(expanded);
|
|
10595
|
+
const base = path23.resolve(workspaceBase);
|
|
10596
|
+
const isInternal = resolved === base || resolved.startsWith(base + path23.sep);
|
|
10366
10597
|
if (!isInternal) {
|
|
10367
10598
|
if (!this.config.workspace.allowExternalWorkspaces) {
|
|
10368
10599
|
throw new Error(
|
|
@@ -10382,7 +10613,7 @@ var init_config2 = __esm({
|
|
|
10382
10613
|
`Invalid workspace name: "${input2}". Only alphanumeric characters, hyphens, and underscores are allowed.`
|
|
10383
10614
|
);
|
|
10384
10615
|
}
|
|
10385
|
-
const namedPath =
|
|
10616
|
+
const namedPath = path23.join(workspaceBase, input2.toLowerCase());
|
|
10386
10617
|
fs19.mkdirSync(namedPath, { recursive: true });
|
|
10387
10618
|
return namedPath;
|
|
10388
10619
|
}
|
|
@@ -10396,7 +10627,7 @@ var init_config2 = __esm({
|
|
|
10396
10627
|
}
|
|
10397
10628
|
/** Writes a complete config object to disk, creating the directory if needed. Used during initial setup. */
|
|
10398
10629
|
async writeNew(config) {
|
|
10399
|
-
const dir =
|
|
10630
|
+
const dir = path23.dirname(this.configPath);
|
|
10400
10631
|
fs19.mkdirSync(dir, { recursive: true });
|
|
10401
10632
|
fs19.writeFileSync(this.configPath, JSON.stringify(config, null, 2));
|
|
10402
10633
|
}
|
|
@@ -10414,6 +10645,14 @@ var init_config2 = __esm({
|
|
|
10414
10645
|
{ envVar: "OPENACP_API_PORT", pluginName: "@openacp/api-server", key: "port", transform: (v) => Number(v) },
|
|
10415
10646
|
{ envVar: "OPENACP_SPEECH_STT_PROVIDER", pluginName: "@openacp/speech", key: "sttProvider" },
|
|
10416
10647
|
{ envVar: "OPENACP_SPEECH_GROQ_API_KEY", pluginName: "@openacp/speech", key: "groqApiKey" },
|
|
10648
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_LANGUAGE", pluginName: "@openacp/speech", key: "localWhisperLanguage" },
|
|
10649
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_MODEL", pluginName: "@openacp/speech", key: "localWhisperModel" },
|
|
10650
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_BEAM_SIZE", pluginName: "@openacp/speech", key: "localWhisperBeamSize", transform: (v) => Number(v) },
|
|
10651
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_VAD_FILTER", pluginName: "@openacp/speech", key: "localWhisperVadFilter", transform: (v) => v === "true" },
|
|
10652
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_DEVICE", pluginName: "@openacp/speech", key: "localWhisperDevice" },
|
|
10653
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_COMPUTE_TYPE", pluginName: "@openacp/speech", key: "localWhisperComputeType" },
|
|
10654
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_TIMEOUT_MS", pluginName: "@openacp/speech", key: "localWhisperTimeoutMs", transform: (v) => Number(v) },
|
|
10655
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_SCRIPT_PATH", pluginName: "@openacp/speech", key: "localWhisperScriptPath" },
|
|
10417
10656
|
{ envVar: "OPENACP_TELEGRAM_BOT_TOKEN", pluginName: "@openacp/telegram", key: "botToken" },
|
|
10418
10657
|
{ envVar: "OPENACP_TELEGRAM_CHAT_ID", pluginName: "@openacp/telegram", key: "chatId", transform: (v) => Number(v) },
|
|
10419
10658
|
// Future adapters — no-ops if plugin settings don't exist
|
|
@@ -11131,7 +11370,7 @@ var plugins_exports = {};
|
|
|
11131
11370
|
__export(plugins_exports, {
|
|
11132
11371
|
pluginRoutes: () => pluginRoutes
|
|
11133
11372
|
});
|
|
11134
|
-
import
|
|
11373
|
+
import path24 from "path";
|
|
11135
11374
|
async function pluginRoutes(app, deps) {
|
|
11136
11375
|
const { lifecycleManager } = deps;
|
|
11137
11376
|
const admin = [requireScopes("system:admin")];
|
|
@@ -11196,7 +11435,7 @@ async function pluginRoutes(app, deps) {
|
|
|
11196
11435
|
} else {
|
|
11197
11436
|
const { importFromDir: importFromDir2 } = await Promise.resolve().then(() => (init_plugin_installer(), plugin_installer_exports));
|
|
11198
11437
|
const instanceRoot = lifecycleManager.instanceRoot;
|
|
11199
|
-
const pluginsDir =
|
|
11438
|
+
const pluginsDir = path24.join(instanceRoot, "plugins");
|
|
11200
11439
|
try {
|
|
11201
11440
|
const mod = await importFromDir2(name, pluginsDir);
|
|
11202
11441
|
pluginDef = mod.default ?? mod;
|
|
@@ -11272,11 +11511,11 @@ __export(instance_registry_exports, {
|
|
|
11272
11511
|
readIdFromConfig: () => readIdFromConfig
|
|
11273
11512
|
});
|
|
11274
11513
|
import fs20 from "fs";
|
|
11275
|
-
import
|
|
11514
|
+
import path25 from "path";
|
|
11276
11515
|
import { randomUUID } from "crypto";
|
|
11277
11516
|
function readIdFromConfig(instanceRoot) {
|
|
11278
11517
|
try {
|
|
11279
|
-
const raw = JSON.parse(fs20.readFileSync(
|
|
11518
|
+
const raw = JSON.parse(fs20.readFileSync(path25.join(instanceRoot, "config.json"), "utf-8"));
|
|
11280
11519
|
return typeof raw.id === "string" && raw.id ? raw.id : null;
|
|
11281
11520
|
} catch {
|
|
11282
11521
|
return null;
|
|
@@ -11322,7 +11561,7 @@ var init_instance_registry = __esm({
|
|
|
11322
11561
|
}
|
|
11323
11562
|
/** Persist the registry to disk, creating parent directories if needed. */
|
|
11324
11563
|
save() {
|
|
11325
|
-
const dir =
|
|
11564
|
+
const dir = path25.dirname(this.registryPath);
|
|
11326
11565
|
fs20.mkdirSync(dir, { recursive: true });
|
|
11327
11566
|
fs20.writeFileSync(this.registryPath, JSON.stringify(this.data, null, 2));
|
|
11328
11567
|
}
|
|
@@ -11392,7 +11631,7 @@ __export(instance_context_exports, {
|
|
|
11392
11631
|
resolveInstanceRoot: () => resolveInstanceRoot,
|
|
11393
11632
|
resolveRunningInstance: () => resolveRunningInstance
|
|
11394
11633
|
});
|
|
11395
|
-
import
|
|
11634
|
+
import path26 from "path";
|
|
11396
11635
|
import fs21 from "fs";
|
|
11397
11636
|
import os6 from "os";
|
|
11398
11637
|
function createInstanceContext(opts) {
|
|
@@ -11402,22 +11641,22 @@ function createInstanceContext(opts) {
|
|
|
11402
11641
|
id,
|
|
11403
11642
|
root,
|
|
11404
11643
|
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:
|
|
11644
|
+
config: path26.join(root, "config.json"),
|
|
11645
|
+
sessions: path26.join(root, "sessions.json"),
|
|
11646
|
+
agents: path26.join(root, "agents.json"),
|
|
11647
|
+
registryCache: path26.join(globalRoot, "cache", "registry-cache.json"),
|
|
11648
|
+
plugins: path26.join(root, "plugins"),
|
|
11649
|
+
pluginsData: path26.join(root, "plugins", "data"),
|
|
11650
|
+
pluginRegistry: path26.join(root, "plugins.json"),
|
|
11651
|
+
logs: path26.join(root, "logs"),
|
|
11652
|
+
pid: path26.join(root, "openacp.pid"),
|
|
11653
|
+
running: path26.join(root, "running"),
|
|
11654
|
+
apiPort: path26.join(root, "api.port"),
|
|
11655
|
+
apiSecret: path26.join(root, "api-secret"),
|
|
11656
|
+
bin: path26.join(globalRoot, "bin"),
|
|
11657
|
+
cache: path26.join(root, "cache"),
|
|
11658
|
+
tunnels: path26.join(root, "tunnels.json"),
|
|
11659
|
+
agentsDir: path26.join(globalRoot, "agents")
|
|
11421
11660
|
}
|
|
11422
11661
|
};
|
|
11423
11662
|
}
|
|
@@ -11426,50 +11665,50 @@ function generateSlug(name) {
|
|
|
11426
11665
|
return slug || "openacp";
|
|
11427
11666
|
}
|
|
11428
11667
|
function expandHome3(p2) {
|
|
11429
|
-
if (p2.startsWith("~")) return
|
|
11668
|
+
if (p2.startsWith("~")) return path26.join(os6.homedir(), p2.slice(1));
|
|
11430
11669
|
return p2;
|
|
11431
11670
|
}
|
|
11432
11671
|
function resolveInstanceRoot(opts) {
|
|
11433
11672
|
const cwd = opts.cwd ?? process.cwd();
|
|
11434
11673
|
const home = os6.homedir();
|
|
11435
11674
|
const globalRoot = getGlobalRoot();
|
|
11436
|
-
if (opts.dir) return
|
|
11437
|
-
if (opts.local) return
|
|
11438
|
-
const cwdRoot =
|
|
11439
|
-
if (fs21.existsSync(
|
|
11440
|
-
let dir =
|
|
11675
|
+
if (opts.dir) return path26.join(expandHome3(opts.dir), ".openacp");
|
|
11676
|
+
if (opts.local) return path26.join(cwd, ".openacp");
|
|
11677
|
+
const cwdRoot = path26.join(cwd, ".openacp");
|
|
11678
|
+
if (fs21.existsSync(path26.join(cwdRoot, "config.json"))) return cwdRoot;
|
|
11679
|
+
let dir = path26.resolve(cwd);
|
|
11441
11680
|
while (true) {
|
|
11442
|
-
const parent =
|
|
11681
|
+
const parent = path26.dirname(dir);
|
|
11443
11682
|
if (parent === dir) break;
|
|
11444
11683
|
dir = parent;
|
|
11445
|
-
const candidate =
|
|
11684
|
+
const candidate = path26.join(dir, ".openacp");
|
|
11446
11685
|
if (candidate === globalRoot) {
|
|
11447
11686
|
if (dir === home) break;
|
|
11448
11687
|
continue;
|
|
11449
11688
|
}
|
|
11450
|
-
if (fs21.existsSync(
|
|
11689
|
+
if (fs21.existsSync(path26.join(candidate, "config.json"))) return candidate;
|
|
11451
11690
|
if (dir === home) break;
|
|
11452
11691
|
}
|
|
11453
|
-
if (
|
|
11454
|
-
const defaultWs =
|
|
11455
|
-
if (fs21.existsSync(
|
|
11692
|
+
if (path26.resolve(cwd) === path26.resolve(home)) {
|
|
11693
|
+
const defaultWs = path26.join(home, "openacp-workspace", ".openacp");
|
|
11694
|
+
if (fs21.existsSync(path26.join(defaultWs, "config.json"))) return defaultWs;
|
|
11456
11695
|
}
|
|
11457
11696
|
if (process.env.OPENACP_INSTANCE_ROOT) return process.env.OPENACP_INSTANCE_ROOT;
|
|
11458
11697
|
return null;
|
|
11459
11698
|
}
|
|
11460
11699
|
function getGlobalRoot() {
|
|
11461
|
-
return
|
|
11700
|
+
return path26.join(os6.homedir(), ".openacp");
|
|
11462
11701
|
}
|
|
11463
11702
|
async function resolveRunningInstance(cwd) {
|
|
11464
11703
|
const globalRoot = getGlobalRoot();
|
|
11465
11704
|
const home = os6.homedir();
|
|
11466
|
-
let dir =
|
|
11705
|
+
let dir = path26.resolve(cwd);
|
|
11467
11706
|
while (true) {
|
|
11468
|
-
const candidate =
|
|
11707
|
+
const candidate = path26.join(dir, ".openacp");
|
|
11469
11708
|
if (candidate !== globalRoot && fs21.existsSync(candidate)) {
|
|
11470
11709
|
if (await isInstanceRunning(candidate)) return candidate;
|
|
11471
11710
|
}
|
|
11472
|
-
const parent =
|
|
11711
|
+
const parent = path26.dirname(dir);
|
|
11473
11712
|
if (parent === dir) break;
|
|
11474
11713
|
if (dir === home) break;
|
|
11475
11714
|
dir = parent;
|
|
@@ -11477,7 +11716,7 @@ async function resolveRunningInstance(cwd) {
|
|
|
11477
11716
|
return null;
|
|
11478
11717
|
}
|
|
11479
11718
|
async function isInstanceRunning(instanceRoot) {
|
|
11480
|
-
const portFile =
|
|
11719
|
+
const portFile = path26.join(instanceRoot, "api.port");
|
|
11481
11720
|
try {
|
|
11482
11721
|
const content = fs21.readFileSync(portFile, "utf-8").trim();
|
|
11483
11722
|
const port = parseInt(content, 10);
|
|
@@ -11506,14 +11745,14 @@ __export(api_server_exports, {
|
|
|
11506
11745
|
});
|
|
11507
11746
|
import * as fs22 from "fs";
|
|
11508
11747
|
import * as crypto3 from "crypto";
|
|
11509
|
-
import * as
|
|
11748
|
+
import * as path27 from "path";
|
|
11510
11749
|
function getVersion() {
|
|
11511
11750
|
if (cachedVersion) return cachedVersion;
|
|
11512
11751
|
cachedVersion = getCurrentVersion();
|
|
11513
11752
|
return cachedVersion;
|
|
11514
11753
|
}
|
|
11515
11754
|
function loadOrCreateSecret(secretFilePath) {
|
|
11516
|
-
const dir =
|
|
11755
|
+
const dir = path27.dirname(secretFilePath);
|
|
11517
11756
|
fs22.mkdirSync(dir, { recursive: true });
|
|
11518
11757
|
try {
|
|
11519
11758
|
const existing = fs22.readFileSync(secretFilePath, "utf-8").trim();
|
|
@@ -11539,7 +11778,7 @@ function loadOrCreateSecret(secretFilePath) {
|
|
|
11539
11778
|
return secret;
|
|
11540
11779
|
}
|
|
11541
11780
|
function writePortFile(portFilePath, port) {
|
|
11542
|
-
const dir =
|
|
11781
|
+
const dir = path27.dirname(portFilePath);
|
|
11543
11782
|
fs22.mkdirSync(dir, { recursive: true });
|
|
11544
11783
|
fs22.writeFileSync(portFilePath, String(port));
|
|
11545
11784
|
}
|
|
@@ -11624,10 +11863,10 @@ function createApiServerPlugin() {
|
|
|
11624
11863
|
{ port: apiConfig.port, host: apiConfig.host, instanceRoot },
|
|
11625
11864
|
"API server plugin setup \u2014 config loaded"
|
|
11626
11865
|
);
|
|
11627
|
-
portFilePath =
|
|
11628
|
-
const secretFilePath =
|
|
11629
|
-
const jwtSecretFilePath =
|
|
11630
|
-
const tokensFilePath =
|
|
11866
|
+
portFilePath = path27.join(instanceRoot, "api.port");
|
|
11867
|
+
const secretFilePath = path27.join(instanceRoot, "api-secret");
|
|
11868
|
+
const jwtSecretFilePath = path27.join(instanceRoot, "jwt-secret");
|
|
11869
|
+
const tokensFilePath = path27.join(instanceRoot, "tokens.json");
|
|
11631
11870
|
const startedAt = Date.now();
|
|
11632
11871
|
const secret = loadOrCreateSecret(secretFilePath);
|
|
11633
11872
|
const jwtSecret = loadOrCreateSecret(jwtSecretFilePath);
|
|
@@ -11666,7 +11905,7 @@ function createApiServerPlugin() {
|
|
|
11666
11905
|
const { InstanceRegistry: InstanceRegistry2 } = await Promise.resolve().then(() => (init_instance_registry(), instance_registry_exports));
|
|
11667
11906
|
const { getGlobalRoot: getGlobalRoot2 } = await Promise.resolve().then(() => (init_instance_context(), instance_context_exports));
|
|
11668
11907
|
const globalRoot = getGlobalRoot2();
|
|
11669
|
-
const instanceReg = new InstanceRegistry2(
|
|
11908
|
+
const instanceReg = new InstanceRegistry2(path27.join(globalRoot, "instances.json"));
|
|
11670
11909
|
instanceReg.load();
|
|
11671
11910
|
const instanceEntry = instanceReg.getByRoot(instanceRoot);
|
|
11672
11911
|
const workspaceId = instanceEntry?.id ?? "main";
|
|
@@ -11698,7 +11937,7 @@ function createApiServerPlugin() {
|
|
|
11698
11937
|
server.registerPlugin("/api/v1/plugins", async (app) => pluginRoutes2(app, deps));
|
|
11699
11938
|
const appConfig = core.configManager.get();
|
|
11700
11939
|
const workspaceName = appConfig.instanceName ?? "Main";
|
|
11701
|
-
const workspaceDir =
|
|
11940
|
+
const workspaceDir = path27.dirname(instanceRoot);
|
|
11702
11941
|
server.registerPlugin("/api/v1", async (app) => {
|
|
11703
11942
|
await app.register(workspaceRoute2, {
|
|
11704
11943
|
id: workspaceId,
|
|
@@ -12792,8 +13031,8 @@ function formatToolSummary(name, rawInput, displaySummary) {
|
|
|
12792
13031
|
}
|
|
12793
13032
|
if (lowerName === "grep") {
|
|
12794
13033
|
const pattern = args2.pattern ?? "";
|
|
12795
|
-
const
|
|
12796
|
-
return pattern ? `\u{1F50D} Grep "${pattern}"${
|
|
13034
|
+
const path72 = args2.path ?? "";
|
|
13035
|
+
return pattern ? `\u{1F50D} Grep "${pattern}"${path72 ? ` in ${path72}` : ""}` : `\u{1F527} ${name}`;
|
|
12797
13036
|
}
|
|
12798
13037
|
if (lowerName === "glob") {
|
|
12799
13038
|
const pattern = args2.pattern ?? "";
|
|
@@ -12829,8 +13068,8 @@ function formatToolTitle(name, rawInput, displayTitle) {
|
|
|
12829
13068
|
}
|
|
12830
13069
|
if (lowerName === "grep") {
|
|
12831
13070
|
const pattern = args2.pattern ?? "";
|
|
12832
|
-
const
|
|
12833
|
-
return pattern ? `"${pattern}"${
|
|
13071
|
+
const path72 = args2.path ?? "";
|
|
13072
|
+
return pattern ? `"${pattern}"${path72 ? ` in ${path72}` : ""}` : name;
|
|
12834
13073
|
}
|
|
12835
13074
|
if (lowerName === "glob") {
|
|
12836
13075
|
return String(args2.pattern ?? name);
|
|
@@ -13973,7 +14212,7 @@ __export(integrate_exports, {
|
|
|
13973
14212
|
listIntegrations: () => listIntegrations,
|
|
13974
14213
|
uninstallIntegration: () => uninstallIntegration
|
|
13975
14214
|
});
|
|
13976
|
-
import { existsSync as
|
|
14215
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync5, unlinkSync as unlinkSync4, chmodSync, rmdirSync } from "fs";
|
|
13977
14216
|
import { join as join10, dirname as dirname7 } from "path";
|
|
13978
14217
|
import { homedir as homedir3 } from "os";
|
|
13979
14218
|
function isHooksIntegrationSpec(spec) {
|
|
@@ -14135,7 +14374,7 @@ function generateOpencodePlugin(spec) {
|
|
|
14135
14374
|
function mergeSettingsJson(settingsPath, hookEvent, hookScriptPath) {
|
|
14136
14375
|
const fullPath = expandPath(settingsPath);
|
|
14137
14376
|
let settings = {};
|
|
14138
|
-
if (
|
|
14377
|
+
if (existsSync7(fullPath)) {
|
|
14139
14378
|
const raw = readFileSync5(fullPath, "utf-8");
|
|
14140
14379
|
writeFileSync5(`${fullPath}.bak`, raw);
|
|
14141
14380
|
settings = JSON.parse(raw);
|
|
@@ -14158,7 +14397,7 @@ function mergeSettingsJson(settingsPath, hookEvent, hookScriptPath) {
|
|
|
14158
14397
|
function mergeHooksJson(settingsPath, hookEvent, hookScriptPath) {
|
|
14159
14398
|
const fullPath = expandPath(settingsPath);
|
|
14160
14399
|
let config = { version: 1 };
|
|
14161
|
-
if (
|
|
14400
|
+
if (existsSync7(fullPath)) {
|
|
14162
14401
|
const raw = readFileSync5(fullPath, "utf-8");
|
|
14163
14402
|
writeFileSync5(`${fullPath}.bak`, raw);
|
|
14164
14403
|
config = JSON.parse(raw);
|
|
@@ -14176,7 +14415,7 @@ function mergeHooksJson(settingsPath, hookEvent, hookScriptPath) {
|
|
|
14176
14415
|
}
|
|
14177
14416
|
function removeFromSettingsJson(settingsPath, hookEvent) {
|
|
14178
14417
|
const fullPath = expandPath(settingsPath);
|
|
14179
|
-
if (!
|
|
14418
|
+
if (!existsSync7(fullPath)) return;
|
|
14180
14419
|
const raw = readFileSync5(fullPath, "utf-8");
|
|
14181
14420
|
const settings = JSON.parse(raw);
|
|
14182
14421
|
const hooks = settings.hooks;
|
|
@@ -14191,7 +14430,7 @@ function removeFromSettingsJson(settingsPath, hookEvent) {
|
|
|
14191
14430
|
}
|
|
14192
14431
|
function removeFromHooksJson(settingsPath, hookEvent) {
|
|
14193
14432
|
const fullPath = expandPath(settingsPath);
|
|
14194
|
-
if (!
|
|
14433
|
+
if (!existsSync7(fullPath)) return;
|
|
14195
14434
|
const raw = readFileSync5(fullPath, "utf-8");
|
|
14196
14435
|
const config = JSON.parse(raw);
|
|
14197
14436
|
const hooks = config.hooks;
|
|
@@ -14257,7 +14496,7 @@ async function uninstallHooksIntegration(agentKey, spec) {
|
|
|
14257
14496
|
const hooksDir = expandPath(spec.hooksDirPath);
|
|
14258
14497
|
for (const filename of ["openacp-inject-session.sh", "openacp-handoff.sh"]) {
|
|
14259
14498
|
const filePath = join10(hooksDir, filename);
|
|
14260
|
-
if (
|
|
14499
|
+
if (existsSync7(filePath)) {
|
|
14261
14500
|
unlinkSync4(filePath);
|
|
14262
14501
|
logs.push(`Removed ${filePath}`);
|
|
14263
14502
|
}
|
|
@@ -14266,7 +14505,7 @@ async function uninstallHooksIntegration(agentKey, spec) {
|
|
|
14266
14505
|
if (spec.commandFormat === "skill") {
|
|
14267
14506
|
const skillDir = expandPath(join10(spec.commandsPath, spec.handoffCommandName));
|
|
14268
14507
|
const skillPath = join10(skillDir, "SKILL.md");
|
|
14269
|
-
if (
|
|
14508
|
+
if (existsSync7(skillPath)) {
|
|
14270
14509
|
unlinkSync4(skillPath);
|
|
14271
14510
|
try {
|
|
14272
14511
|
rmdirSync(skillDir);
|
|
@@ -14276,7 +14515,7 @@ async function uninstallHooksIntegration(agentKey, spec) {
|
|
|
14276
14515
|
}
|
|
14277
14516
|
} else {
|
|
14278
14517
|
const cmdPath = expandPath(join10(spec.commandsPath, `${spec.handoffCommandName}.md`));
|
|
14279
|
-
if (
|
|
14518
|
+
if (existsSync7(cmdPath)) {
|
|
14280
14519
|
unlinkSync4(cmdPath);
|
|
14281
14520
|
logs.push(`Removed ${cmdPath}`);
|
|
14282
14521
|
}
|
|
@@ -14303,11 +14542,11 @@ async function installPluginIntegration(_agentKey, spec) {
|
|
|
14303
14542
|
const pluginsDir = expandPath(spec.pluginsPath);
|
|
14304
14543
|
mkdirSync5(pluginsDir, { recursive: true });
|
|
14305
14544
|
const pluginPath = join10(pluginsDir, spec.pluginFileName);
|
|
14306
|
-
if (
|
|
14545
|
+
if (existsSync7(commandPath) && existsSync7(pluginPath)) {
|
|
14307
14546
|
logs.push("Already installed, skipping.");
|
|
14308
14547
|
return { success: true, logs };
|
|
14309
14548
|
}
|
|
14310
|
-
if (
|
|
14549
|
+
if (existsSync7(commandPath) || existsSync7(pluginPath)) {
|
|
14311
14550
|
logs.push("Overwriting existing files.");
|
|
14312
14551
|
}
|
|
14313
14552
|
writeFileSync5(commandPath, generateOpencodeHandoffCommand(spec));
|
|
@@ -14325,13 +14564,13 @@ async function uninstallPluginIntegration(_agentKey, spec) {
|
|
|
14325
14564
|
try {
|
|
14326
14565
|
const commandPath = join10(expandPath(spec.commandsPath), spec.handoffCommandFile);
|
|
14327
14566
|
let removedCount = 0;
|
|
14328
|
-
if (
|
|
14567
|
+
if (existsSync7(commandPath)) {
|
|
14329
14568
|
unlinkSync4(commandPath);
|
|
14330
14569
|
logs.push(`Removed ${commandPath}`);
|
|
14331
14570
|
removedCount += 1;
|
|
14332
14571
|
}
|
|
14333
14572
|
const pluginPath = join10(expandPath(spec.pluginsPath), spec.pluginFileName);
|
|
14334
|
-
if (
|
|
14573
|
+
if (existsSync7(pluginPath)) {
|
|
14335
14574
|
unlinkSync4(pluginPath);
|
|
14336
14575
|
logs.push(`Removed ${pluginPath}`);
|
|
14337
14576
|
removedCount += 1;
|
|
@@ -14365,11 +14604,11 @@ function buildHandoffItem(agentKey, spec) {
|
|
|
14365
14604
|
isInstalled() {
|
|
14366
14605
|
if (isHooksIntegrationSpec(spec)) {
|
|
14367
14606
|
const hooksDir = expandPath(spec.hooksDirPath);
|
|
14368
|
-
return
|
|
14607
|
+
return existsSync7(join10(hooksDir, "openacp-inject-session.sh")) && existsSync7(join10(hooksDir, "openacp-handoff.sh"));
|
|
14369
14608
|
}
|
|
14370
14609
|
const commandPath = join10(expandPath(spec.commandsPath), spec.handoffCommandFile);
|
|
14371
14610
|
const pluginPath = join10(expandPath(spec.pluginsPath), spec.pluginFileName);
|
|
14372
|
-
return
|
|
14611
|
+
return existsSync7(commandPath) && existsSync7(pluginPath);
|
|
14373
14612
|
},
|
|
14374
14613
|
install: () => installIntegration(agentKey, spec),
|
|
14375
14614
|
uninstall: () => uninstallIntegration(agentKey, spec)
|
|
@@ -14391,7 +14630,7 @@ function buildTunnelItem(spec) {
|
|
|
14391
14630
|
name: "Tunnel",
|
|
14392
14631
|
description: "Expose local ports to the internet via OpenACP tunnel",
|
|
14393
14632
|
isInstalled() {
|
|
14394
|
-
return
|
|
14633
|
+
return existsSync7(getTunnelPath());
|
|
14395
14634
|
},
|
|
14396
14635
|
async install() {
|
|
14397
14636
|
const logs = [];
|
|
@@ -14410,7 +14649,7 @@ function buildTunnelItem(spec) {
|
|
|
14410
14649
|
const logs = [];
|
|
14411
14650
|
try {
|
|
14412
14651
|
const skillPath = getTunnelPath();
|
|
14413
|
-
if (
|
|
14652
|
+
if (existsSync7(skillPath)) {
|
|
14414
14653
|
unlinkSync4(skillPath);
|
|
14415
14654
|
try {
|
|
14416
14655
|
rmdirSync(dirname7(skillPath));
|
|
@@ -15173,7 +15412,7 @@ var init_config4 = __esm({
|
|
|
15173
15412
|
// src/core/doctor/checks/agents.ts
|
|
15174
15413
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
15175
15414
|
import * as fs24 from "fs";
|
|
15176
|
-
import * as
|
|
15415
|
+
import * as path28 from "path";
|
|
15177
15416
|
function commandExists2(cmd) {
|
|
15178
15417
|
try {
|
|
15179
15418
|
execFileSync4("which", [cmd], { stdio: "pipe" });
|
|
@@ -15182,9 +15421,9 @@ function commandExists2(cmd) {
|
|
|
15182
15421
|
}
|
|
15183
15422
|
let dir = process.cwd();
|
|
15184
15423
|
while (true) {
|
|
15185
|
-
const binPath =
|
|
15424
|
+
const binPath = path28.join(dir, "node_modules", ".bin", cmd);
|
|
15186
15425
|
if (fs24.existsSync(binPath)) return true;
|
|
15187
|
-
const parent =
|
|
15426
|
+
const parent = path28.dirname(dir);
|
|
15188
15427
|
if (parent === dir) break;
|
|
15189
15428
|
dir = parent;
|
|
15190
15429
|
}
|
|
@@ -15206,7 +15445,7 @@ var init_agents3 = __esm({
|
|
|
15206
15445
|
const defaultAgent = ctx.config.defaultAgent;
|
|
15207
15446
|
let agents = {};
|
|
15208
15447
|
try {
|
|
15209
|
-
const agentsPath =
|
|
15448
|
+
const agentsPath = path28.join(ctx.dataDir, "agents.json");
|
|
15210
15449
|
if (fs24.existsSync(agentsPath)) {
|
|
15211
15450
|
const data = JSON.parse(fs24.readFileSync(agentsPath, "utf-8"));
|
|
15212
15451
|
agents = data.installed ?? {};
|
|
@@ -15247,7 +15486,7 @@ __export(settings_manager_exports, {
|
|
|
15247
15486
|
SettingsManager: () => SettingsManager
|
|
15248
15487
|
});
|
|
15249
15488
|
import fs25 from "fs";
|
|
15250
|
-
import
|
|
15489
|
+
import path29 from "path";
|
|
15251
15490
|
var SettingsManager, SettingsAPIImpl;
|
|
15252
15491
|
var init_settings_manager = __esm({
|
|
15253
15492
|
"src/core/plugin/settings-manager.ts"() {
|
|
@@ -15290,7 +15529,7 @@ var init_settings_manager = __esm({
|
|
|
15290
15529
|
}
|
|
15291
15530
|
/** Resolve the absolute path to a plugin's settings.json file. */
|
|
15292
15531
|
getSettingsPath(pluginName) {
|
|
15293
|
-
return
|
|
15532
|
+
return path29.join(this.basePath, pluginName, "settings.json");
|
|
15294
15533
|
}
|
|
15295
15534
|
async getPluginSettings(pluginName) {
|
|
15296
15535
|
return this.loadSettings(pluginName);
|
|
@@ -15320,7 +15559,7 @@ var init_settings_manager = __esm({
|
|
|
15320
15559
|
}
|
|
15321
15560
|
}
|
|
15322
15561
|
writeFile(data) {
|
|
15323
|
-
const dir =
|
|
15562
|
+
const dir = path29.dirname(this.settingsPath);
|
|
15324
15563
|
fs25.mkdirSync(dir, { recursive: true });
|
|
15325
15564
|
fs25.writeFileSync(this.settingsPath, JSON.stringify(data, null, 2));
|
|
15326
15565
|
this.cache = data;
|
|
@@ -15357,7 +15596,7 @@ var init_settings_manager = __esm({
|
|
|
15357
15596
|
});
|
|
15358
15597
|
|
|
15359
15598
|
// src/core/doctor/checks/telegram.ts
|
|
15360
|
-
import * as
|
|
15599
|
+
import * as path30 from "path";
|
|
15361
15600
|
var BOT_TOKEN_REGEX, telegramCheck;
|
|
15362
15601
|
var init_telegram = __esm({
|
|
15363
15602
|
"src/core/doctor/checks/telegram.ts"() {
|
|
@@ -15373,7 +15612,7 @@ var init_telegram = __esm({
|
|
|
15373
15612
|
return results;
|
|
15374
15613
|
}
|
|
15375
15614
|
const { SettingsManager: SettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
|
|
15376
|
-
const sm = new SettingsManager2(
|
|
15615
|
+
const sm = new SettingsManager2(path30.join(ctx.pluginsDir, "data"));
|
|
15377
15616
|
const ps = await sm.loadSettings("@openacp/telegram");
|
|
15378
15617
|
const botToken = ps.botToken;
|
|
15379
15618
|
const chatId = ps.chatId;
|
|
@@ -15545,7 +15784,7 @@ var init_storage = __esm({
|
|
|
15545
15784
|
|
|
15546
15785
|
// src/core/doctor/checks/workspace.ts
|
|
15547
15786
|
import * as fs27 from "fs";
|
|
15548
|
-
import * as
|
|
15787
|
+
import * as path31 from "path";
|
|
15549
15788
|
var workspaceCheck;
|
|
15550
15789
|
var init_workspace2 = __esm({
|
|
15551
15790
|
"src/core/doctor/checks/workspace.ts"() {
|
|
@@ -15555,7 +15794,7 @@ var init_workspace2 = __esm({
|
|
|
15555
15794
|
order: 5,
|
|
15556
15795
|
async run(ctx) {
|
|
15557
15796
|
const results = [];
|
|
15558
|
-
const workspace =
|
|
15797
|
+
const workspace = path31.dirname(ctx.dataDir);
|
|
15559
15798
|
if (!fs27.existsSync(workspace)) {
|
|
15560
15799
|
results.push({
|
|
15561
15800
|
status: "warn",
|
|
@@ -15583,7 +15822,7 @@ var init_workspace2 = __esm({
|
|
|
15583
15822
|
|
|
15584
15823
|
// src/core/doctor/checks/plugins.ts
|
|
15585
15824
|
import * as fs28 from "fs";
|
|
15586
|
-
import * as
|
|
15825
|
+
import * as path32 from "path";
|
|
15587
15826
|
var pluginsCheck;
|
|
15588
15827
|
var init_plugins2 = __esm({
|
|
15589
15828
|
"src/core/doctor/checks/plugins.ts"() {
|
|
@@ -15602,7 +15841,7 @@ var init_plugins2 = __esm({
|
|
|
15602
15841
|
fix: async () => {
|
|
15603
15842
|
fs28.mkdirSync(ctx.pluginsDir, { recursive: true });
|
|
15604
15843
|
fs28.writeFileSync(
|
|
15605
|
-
|
|
15844
|
+
path32.join(ctx.pluginsDir, "package.json"),
|
|
15606
15845
|
JSON.stringify({ name: "openacp-plugins", private: true, dependencies: {} }, null, 2)
|
|
15607
15846
|
);
|
|
15608
15847
|
return { success: true, message: "initialized plugins directory" };
|
|
@@ -15611,7 +15850,7 @@ var init_plugins2 = __esm({
|
|
|
15611
15850
|
return results;
|
|
15612
15851
|
}
|
|
15613
15852
|
results.push({ status: "pass", message: "Plugins directory exists" });
|
|
15614
|
-
const pkgPath =
|
|
15853
|
+
const pkgPath = path32.join(ctx.pluginsDir, "package.json");
|
|
15615
15854
|
if (!fs28.existsSync(pkgPath)) {
|
|
15616
15855
|
results.push({
|
|
15617
15856
|
status: "warn",
|
|
@@ -15758,7 +15997,7 @@ var init_daemon = __esm({
|
|
|
15758
15997
|
|
|
15759
15998
|
// src/core/doctor/checks/tunnel.ts
|
|
15760
15999
|
import * as fs30 from "fs";
|
|
15761
|
-
import * as
|
|
16000
|
+
import * as path33 from "path";
|
|
15762
16001
|
import * as os7 from "os";
|
|
15763
16002
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
15764
16003
|
var tunnelCheck;
|
|
@@ -15775,7 +16014,7 @@ var init_tunnel3 = __esm({
|
|
|
15775
16014
|
return results;
|
|
15776
16015
|
}
|
|
15777
16016
|
const { SettingsManager: SettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
|
|
15778
|
-
const sm = new SettingsManager2(
|
|
16017
|
+
const sm = new SettingsManager2(path33.join(ctx.pluginsDir, "data"));
|
|
15779
16018
|
const tunnelSettings = await sm.loadSettings("@openacp/tunnel");
|
|
15780
16019
|
const tunnelEnabled = tunnelSettings.enabled ?? false;
|
|
15781
16020
|
const provider = tunnelSettings.provider ?? "cloudflare";
|
|
@@ -15787,7 +16026,7 @@ var init_tunnel3 = __esm({
|
|
|
15787
16026
|
results.push({ status: "pass", message: `Tunnel provider: ${provider}` });
|
|
15788
16027
|
if (provider === "cloudflare") {
|
|
15789
16028
|
const binName = os7.platform() === "win32" ? "cloudflared.exe" : "cloudflared";
|
|
15790
|
-
const binPath =
|
|
16029
|
+
const binPath = path33.join(ctx.dataDir, "bin", binName);
|
|
15791
16030
|
let found = false;
|
|
15792
16031
|
if (fs30.existsSync(binPath)) {
|
|
15793
16032
|
found = true;
|
|
@@ -15835,7 +16074,7 @@ __export(doctor_exports, {
|
|
|
15835
16074
|
DoctorEngine: () => DoctorEngine
|
|
15836
16075
|
});
|
|
15837
16076
|
import * as fs31 from "fs";
|
|
15838
|
-
import * as
|
|
16077
|
+
import * as path34 from "path";
|
|
15839
16078
|
var ALL_CHECKS, CHECK_TIMEOUT_MS, DoctorEngine;
|
|
15840
16079
|
var init_doctor = __esm({
|
|
15841
16080
|
"src/core/doctor/index.ts"() {
|
|
@@ -15923,7 +16162,7 @@ var init_doctor = __esm({
|
|
|
15923
16162
|
/** Constructs the shared context used by all checks — loads config if available. */
|
|
15924
16163
|
async buildContext() {
|
|
15925
16164
|
const dataDir = this.dataDir;
|
|
15926
|
-
const configPath = process.env.OPENACP_CONFIG_PATH ||
|
|
16165
|
+
const configPath = process.env.OPENACP_CONFIG_PATH || path34.join(dataDir, "config.json");
|
|
15927
16166
|
let config = null;
|
|
15928
16167
|
let rawConfig = null;
|
|
15929
16168
|
try {
|
|
@@ -15934,16 +16173,16 @@ var init_doctor = __esm({
|
|
|
15934
16173
|
config = cm.get();
|
|
15935
16174
|
} catch {
|
|
15936
16175
|
}
|
|
15937
|
-
const logsDir = config ? expandHome2(config.logging.logDir) :
|
|
16176
|
+
const logsDir = config ? expandHome2(config.logging.logDir) : path34.join(dataDir, "logs");
|
|
15938
16177
|
return {
|
|
15939
16178
|
config,
|
|
15940
16179
|
rawConfig,
|
|
15941
16180
|
configPath,
|
|
15942
16181
|
dataDir,
|
|
15943
|
-
sessionsPath:
|
|
15944
|
-
pidPath:
|
|
15945
|
-
portFilePath:
|
|
15946
|
-
pluginsDir:
|
|
16182
|
+
sessionsPath: path34.join(dataDir, "sessions.json"),
|
|
16183
|
+
pidPath: path34.join(dataDir, "openacp.pid"),
|
|
16184
|
+
portFilePath: path34.join(dataDir, "api.port"),
|
|
16185
|
+
pluginsDir: path34.join(dataDir, "plugins"),
|
|
15947
16186
|
logsDir
|
|
15948
16187
|
};
|
|
15949
16188
|
}
|
|
@@ -20500,10 +20739,10 @@ var install_context_exports = {};
|
|
|
20500
20739
|
__export(install_context_exports, {
|
|
20501
20740
|
createInstallContext: () => createInstallContext
|
|
20502
20741
|
});
|
|
20503
|
-
import
|
|
20742
|
+
import path35 from "path";
|
|
20504
20743
|
function createInstallContext(opts) {
|
|
20505
20744
|
const { pluginName, settingsManager, basePath, instanceRoot } = opts;
|
|
20506
|
-
const dataDir =
|
|
20745
|
+
const dataDir = path35.join(basePath, pluginName, "data");
|
|
20507
20746
|
return {
|
|
20508
20747
|
pluginName,
|
|
20509
20748
|
terminal: createTerminalIO(),
|
|
@@ -20531,13 +20770,13 @@ __export(api_client_exports, {
|
|
|
20531
20770
|
waitForPortFile: () => waitForPortFile
|
|
20532
20771
|
});
|
|
20533
20772
|
import * as fs33 from "fs";
|
|
20534
|
-
import * as
|
|
20773
|
+
import * as path37 from "path";
|
|
20535
20774
|
import { setTimeout as sleep } from "timers/promises";
|
|
20536
20775
|
function defaultPortFile(root) {
|
|
20537
|
-
return
|
|
20776
|
+
return path37.join(root, "api.port");
|
|
20538
20777
|
}
|
|
20539
20778
|
function defaultSecretFile(root) {
|
|
20540
|
-
return
|
|
20779
|
+
return path37.join(root, "api-secret");
|
|
20541
20780
|
}
|
|
20542
20781
|
async function waitForPortFile(portFilePath, timeoutMs = 5e3, intervalMs = 100) {
|
|
20543
20782
|
const deadline = Date.now() + timeoutMs;
|
|
@@ -20632,9 +20871,9 @@ var init_suggest = __esm({
|
|
|
20632
20871
|
|
|
20633
20872
|
// src/cli/instance-hint.ts
|
|
20634
20873
|
import os8 from "os";
|
|
20635
|
-
import
|
|
20874
|
+
import path38 from "path";
|
|
20636
20875
|
function printInstanceHint(root) {
|
|
20637
|
-
const workspaceDir =
|
|
20876
|
+
const workspaceDir = path38.dirname(root);
|
|
20638
20877
|
const displayPath = workspaceDir.replace(os8.homedir(), "~");
|
|
20639
20878
|
console.log(` Workspace: ${displayPath}`);
|
|
20640
20879
|
}
|
|
@@ -20650,23 +20889,23 @@ __export(resolve_instance_id_exports, {
|
|
|
20650
20889
|
resolveInstanceId: () => resolveInstanceId
|
|
20651
20890
|
});
|
|
20652
20891
|
import fs34 from "fs";
|
|
20653
|
-
import
|
|
20892
|
+
import path39 from "path";
|
|
20654
20893
|
function resolveInstanceId(instanceRoot) {
|
|
20655
20894
|
try {
|
|
20656
|
-
const configPath =
|
|
20895
|
+
const configPath = path39.join(instanceRoot, "config.json");
|
|
20657
20896
|
const raw = JSON.parse(fs34.readFileSync(configPath, "utf-8"));
|
|
20658
20897
|
if (raw.id && typeof raw.id === "string") return raw.id;
|
|
20659
20898
|
} catch {
|
|
20660
20899
|
}
|
|
20661
20900
|
try {
|
|
20662
|
-
const reg = new InstanceRegistry(
|
|
20901
|
+
const reg = new InstanceRegistry(path39.join(getGlobalRoot(), "instances.json"));
|
|
20663
20902
|
reg.load();
|
|
20664
20903
|
const entry = reg.getByRoot(instanceRoot);
|
|
20665
20904
|
if (entry?.id) return entry.id;
|
|
20666
20905
|
} catch (err) {
|
|
20667
20906
|
log31.debug({ err: err.message, instanceRoot }, "Could not read instance registry, using fallback id");
|
|
20668
20907
|
}
|
|
20669
|
-
return
|
|
20908
|
+
return path39.basename(path39.dirname(instanceRoot)).replace(/[^a-zA-Z0-9-]/g, "-") || "default";
|
|
20670
20909
|
}
|
|
20671
20910
|
var log31;
|
|
20672
20911
|
var init_resolve_instance_id = __esm({
|
|
@@ -20698,18 +20937,18 @@ __export(daemon_exports, {
|
|
|
20698
20937
|
});
|
|
20699
20938
|
import { spawn as spawn6 } from "child_process";
|
|
20700
20939
|
import * as fs35 from "fs";
|
|
20701
|
-
import * as
|
|
20940
|
+
import * as path40 from "path";
|
|
20702
20941
|
function getPidPath(root) {
|
|
20703
|
-
return
|
|
20942
|
+
return path40.join(root, "openacp.pid");
|
|
20704
20943
|
}
|
|
20705
20944
|
function getLogDir(root) {
|
|
20706
|
-
return
|
|
20945
|
+
return path40.join(root, "logs");
|
|
20707
20946
|
}
|
|
20708
20947
|
function getRunningMarker(root) {
|
|
20709
|
-
return
|
|
20948
|
+
return path40.join(root, "running");
|
|
20710
20949
|
}
|
|
20711
20950
|
function writePidFile(pidPath, pid) {
|
|
20712
|
-
const dir =
|
|
20951
|
+
const dir = path40.dirname(pidPath);
|
|
20713
20952
|
fs35.mkdirSync(dir, { recursive: true });
|
|
20714
20953
|
fs35.writeFileSync(pidPath, String(pid));
|
|
20715
20954
|
}
|
|
@@ -20758,8 +20997,8 @@ function startDaemon(pidPath, logDir2, instanceRoot) {
|
|
|
20758
20997
|
}
|
|
20759
20998
|
const resolvedLogDir = logDir2 ? expandHome2(logDir2) : getLogDir(instanceRoot);
|
|
20760
20999
|
fs35.mkdirSync(resolvedLogDir, { recursive: true });
|
|
20761
|
-
const logFile =
|
|
20762
|
-
const cliPath =
|
|
21000
|
+
const logFile = path40.join(resolvedLogDir, "openacp.log");
|
|
21001
|
+
const cliPath = path40.resolve(process.argv[1]);
|
|
20763
21002
|
const nodePath = process.execPath;
|
|
20764
21003
|
const out = fs35.openSync(logFile, "a");
|
|
20765
21004
|
const err = fs35.openSync(logFile, "a");
|
|
@@ -20843,7 +21082,7 @@ async function stopDaemon(pidPath, instanceRoot) {
|
|
|
20843
21082
|
}
|
|
20844
21083
|
function markRunning(root) {
|
|
20845
21084
|
const marker = getRunningMarker(root);
|
|
20846
|
-
fs35.mkdirSync(
|
|
21085
|
+
fs35.mkdirSync(path40.dirname(marker), { recursive: true });
|
|
20847
21086
|
fs35.writeFileSync(marker, "");
|
|
20848
21087
|
}
|
|
20849
21088
|
function clearRunning(root) {
|
|
@@ -20876,19 +21115,19 @@ __export(autostart_exports, {
|
|
|
20876
21115
|
});
|
|
20877
21116
|
import { execFileSync as execFileSync6 } from "child_process";
|
|
20878
21117
|
import * as fs36 from "fs";
|
|
20879
|
-
import * as
|
|
21118
|
+
import * as path41 from "path";
|
|
20880
21119
|
import * as os9 from "os";
|
|
20881
21120
|
function getLaunchdLabel(instanceId) {
|
|
20882
21121
|
return `com.openacp.daemon.${instanceId}`;
|
|
20883
21122
|
}
|
|
20884
21123
|
function getLaunchdPlistPath(instanceId) {
|
|
20885
|
-
return
|
|
21124
|
+
return path41.join(os9.homedir(), "Library", "LaunchAgents", `${getLaunchdLabel(instanceId)}.plist`);
|
|
20886
21125
|
}
|
|
20887
21126
|
function getSystemdServiceName(instanceId) {
|
|
20888
21127
|
return `openacp-${instanceId}`;
|
|
20889
21128
|
}
|
|
20890
21129
|
function getSystemdServicePath(instanceId) {
|
|
20891
|
-
return
|
|
21130
|
+
return path41.join(os9.homedir(), ".config", "systemd", "user", `${getSystemdServiceName(instanceId)}.service`);
|
|
20892
21131
|
}
|
|
20893
21132
|
function isAutoStartSupported() {
|
|
20894
21133
|
return process.platform === "darwin" || process.platform === "linux";
|
|
@@ -20902,7 +21141,7 @@ function escapeSystemdValue(str) {
|
|
|
20902
21141
|
}
|
|
20903
21142
|
function generateLaunchdPlist(nodePath, cliPath, logDir2, instanceRoot, instanceId) {
|
|
20904
21143
|
const label = getLaunchdLabel(instanceId);
|
|
20905
|
-
const logFile =
|
|
21144
|
+
const logFile = path41.join(logDir2, "openacp.log");
|
|
20906
21145
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
20907
21146
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
20908
21147
|
<plist version="1.0">
|
|
@@ -20984,14 +21223,14 @@ function installAutoStart(logDir2, instanceRoot, instanceId) {
|
|
|
20984
21223
|
return { success: false, error: "Auto-start not supported on this platform" };
|
|
20985
21224
|
}
|
|
20986
21225
|
const nodePath = process.execPath;
|
|
20987
|
-
const cliPath =
|
|
20988
|
-
const resolvedLogDir = logDir2.startsWith("~") ?
|
|
21226
|
+
const cliPath = path41.resolve(process.argv[1]);
|
|
21227
|
+
const resolvedLogDir = logDir2.startsWith("~") ? path41.join(os9.homedir(), logDir2.slice(1)) : logDir2;
|
|
20989
21228
|
try {
|
|
20990
21229
|
migrateLegacy();
|
|
20991
21230
|
if (process.platform === "darwin") {
|
|
20992
21231
|
const plistPath = getLaunchdPlistPath(instanceId);
|
|
20993
21232
|
const plist = generateLaunchdPlist(nodePath, cliPath, resolvedLogDir, instanceRoot, instanceId);
|
|
20994
|
-
const dir =
|
|
21233
|
+
const dir = path41.dirname(plistPath);
|
|
20995
21234
|
fs36.mkdirSync(dir, { recursive: true });
|
|
20996
21235
|
fs36.writeFileSync(plistPath, plist);
|
|
20997
21236
|
const uid = process.getuid();
|
|
@@ -21008,7 +21247,7 @@ function installAutoStart(logDir2, instanceRoot, instanceId) {
|
|
|
21008
21247
|
const servicePath = getSystemdServicePath(instanceId);
|
|
21009
21248
|
const serviceName = getSystemdServiceName(instanceId);
|
|
21010
21249
|
const unit = generateSystemdUnit(nodePath, cliPath, instanceRoot, instanceId);
|
|
21011
|
-
const dir =
|
|
21250
|
+
const dir = path41.dirname(servicePath);
|
|
21012
21251
|
fs36.mkdirSync(dir, { recursive: true });
|
|
21013
21252
|
fs36.writeFileSync(servicePath, unit);
|
|
21014
21253
|
execFileSync6("systemctl", ["--user", "daemon-reload"], { stdio: "pipe" });
|
|
@@ -21077,8 +21316,8 @@ var init_autostart = __esm({
|
|
|
21077
21316
|
"use strict";
|
|
21078
21317
|
init_log();
|
|
21079
21318
|
log32 = createChildLogger({ module: "autostart" });
|
|
21080
|
-
LEGACY_LAUNCHD_PLIST_PATH =
|
|
21081
|
-
LEGACY_SYSTEMD_SERVICE_PATH =
|
|
21319
|
+
LEGACY_LAUNCHD_PLIST_PATH = path41.join(os9.homedir(), "Library", "LaunchAgents", "com.openacp.daemon.plist");
|
|
21320
|
+
LEGACY_SYSTEMD_SERVICE_PATH = path41.join(os9.homedir(), ".config", "systemd", "user", "openacp.service");
|
|
21082
21321
|
}
|
|
21083
21322
|
});
|
|
21084
21323
|
|
|
@@ -21133,7 +21372,7 @@ var init_stop = __esm({
|
|
|
21133
21372
|
|
|
21134
21373
|
// src/core/security/path-guard.ts
|
|
21135
21374
|
import fs37 from "fs";
|
|
21136
|
-
import
|
|
21375
|
+
import path43 from "path";
|
|
21137
21376
|
import ignore from "ignore";
|
|
21138
21377
|
var DEFAULT_DENY_PATTERNS, PathGuard;
|
|
21139
21378
|
var init_path_guard = __esm({
|
|
@@ -21162,15 +21401,15 @@ var init_path_guard = __esm({
|
|
|
21162
21401
|
ig;
|
|
21163
21402
|
constructor(options) {
|
|
21164
21403
|
try {
|
|
21165
|
-
this.cwd = fs37.realpathSync(
|
|
21404
|
+
this.cwd = fs37.realpathSync(path43.resolve(options.cwd));
|
|
21166
21405
|
} catch {
|
|
21167
|
-
this.cwd =
|
|
21406
|
+
this.cwd = path43.resolve(options.cwd);
|
|
21168
21407
|
}
|
|
21169
21408
|
this.allowedPaths = options.allowedPaths.map((p2) => {
|
|
21170
21409
|
try {
|
|
21171
|
-
return fs37.realpathSync(
|
|
21410
|
+
return fs37.realpathSync(path43.resolve(p2));
|
|
21172
21411
|
} catch {
|
|
21173
|
-
return
|
|
21412
|
+
return path43.resolve(p2);
|
|
21174
21413
|
}
|
|
21175
21414
|
});
|
|
21176
21415
|
this.ig = ignore();
|
|
@@ -21194,19 +21433,19 @@ var init_path_guard = __esm({
|
|
|
21194
21433
|
* @returns `{ allowed: true }` or `{ allowed: false, reason: "..." }`
|
|
21195
21434
|
*/
|
|
21196
21435
|
validatePath(targetPath, operation) {
|
|
21197
|
-
const resolved =
|
|
21436
|
+
const resolved = path43.resolve(targetPath);
|
|
21198
21437
|
let realPath;
|
|
21199
21438
|
try {
|
|
21200
21439
|
realPath = fs37.realpathSync(resolved);
|
|
21201
21440
|
} catch {
|
|
21202
21441
|
realPath = resolved;
|
|
21203
21442
|
}
|
|
21204
|
-
if (operation === "write" &&
|
|
21443
|
+
if (operation === "write" && path43.basename(realPath) === ".openacpignore") {
|
|
21205
21444
|
return { allowed: false, reason: "Cannot write to .openacpignore" };
|
|
21206
21445
|
}
|
|
21207
|
-
const isWithinCwd = realPath === this.cwd || realPath.startsWith(this.cwd +
|
|
21446
|
+
const isWithinCwd = realPath === this.cwd || realPath.startsWith(this.cwd + path43.sep);
|
|
21208
21447
|
const isWithinAllowed = this.allowedPaths.some(
|
|
21209
|
-
(ap) => realPath === ap || realPath.startsWith(ap +
|
|
21448
|
+
(ap) => realPath === ap || realPath.startsWith(ap + path43.sep)
|
|
21210
21449
|
);
|
|
21211
21450
|
if (!isWithinCwd && !isWithinAllowed) {
|
|
21212
21451
|
return {
|
|
@@ -21215,7 +21454,7 @@ var init_path_guard = __esm({
|
|
|
21215
21454
|
};
|
|
21216
21455
|
}
|
|
21217
21456
|
if (isWithinCwd && !isWithinAllowed) {
|
|
21218
|
-
const relativePath =
|
|
21457
|
+
const relativePath = path43.relative(this.cwd, realPath);
|
|
21219
21458
|
if (relativePath === ".openacpignore") {
|
|
21220
21459
|
return { allowed: true, reason: "" };
|
|
21221
21460
|
}
|
|
@@ -21231,9 +21470,9 @@ var init_path_guard = __esm({
|
|
|
21231
21470
|
/** Adds an additional allowed path at runtime (e.g. for file-service uploads). */
|
|
21232
21471
|
addAllowedPath(p2) {
|
|
21233
21472
|
try {
|
|
21234
|
-
this.allowedPaths.push(fs37.realpathSync(
|
|
21473
|
+
this.allowedPaths.push(fs37.realpathSync(path43.resolve(p2)));
|
|
21235
21474
|
} catch {
|
|
21236
|
-
this.allowedPaths.push(
|
|
21475
|
+
this.allowedPaths.push(path43.resolve(p2));
|
|
21237
21476
|
}
|
|
21238
21477
|
}
|
|
21239
21478
|
/**
|
|
@@ -21241,7 +21480,7 @@ var init_path_guard = __esm({
|
|
|
21241
21480
|
* Follows .gitignore syntax — blank lines and lines starting with # are skipped.
|
|
21242
21481
|
*/
|
|
21243
21482
|
static loadIgnoreFile(cwd) {
|
|
21244
|
-
const ignorePath =
|
|
21483
|
+
const ignorePath = path43.join(cwd, ".openacpignore");
|
|
21245
21484
|
try {
|
|
21246
21485
|
const content = fs37.readFileSync(ignorePath, "utf-8");
|
|
21247
21486
|
return content.split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
@@ -21718,7 +21957,7 @@ var init_mcp_manager = __esm({
|
|
|
21718
21957
|
|
|
21719
21958
|
// src/core/utils/debug-tracer.ts
|
|
21720
21959
|
import fs38 from "fs";
|
|
21721
|
-
import
|
|
21960
|
+
import path44 from "path";
|
|
21722
21961
|
function createDebugTracer(sessionId, workingDirectory) {
|
|
21723
21962
|
if (!DEBUG_ENABLED) return null;
|
|
21724
21963
|
return new DebugTracer(sessionId, workingDirectory);
|
|
@@ -21732,7 +21971,7 @@ var init_debug_tracer = __esm({
|
|
|
21732
21971
|
constructor(sessionId, workingDirectory) {
|
|
21733
21972
|
this.sessionId = sessionId;
|
|
21734
21973
|
this.workingDirectory = workingDirectory;
|
|
21735
|
-
this.logDir =
|
|
21974
|
+
this.logDir = path44.join(workingDirectory, ".log");
|
|
21736
21975
|
}
|
|
21737
21976
|
sessionId;
|
|
21738
21977
|
workingDirectory;
|
|
@@ -21750,7 +21989,7 @@ var init_debug_tracer = __esm({
|
|
|
21750
21989
|
fs38.mkdirSync(this.logDir, { recursive: true });
|
|
21751
21990
|
this.dirCreated = true;
|
|
21752
21991
|
}
|
|
21753
|
-
const filePath =
|
|
21992
|
+
const filePath = path44.join(this.logDir, `${this.sessionId}_${layer}.jsonl`);
|
|
21754
21993
|
const seen = /* @__PURE__ */ new WeakSet();
|
|
21755
21994
|
const line = JSON.stringify({ ts: Date.now(), ...data }, (_key, value) => {
|
|
21756
21995
|
if (typeof value === "object" && value !== null) {
|
|
@@ -21774,21 +22013,21 @@ var init_debug_tracer = __esm({
|
|
|
21774
22013
|
import { spawn as spawn8, execFileSync as execFileSync7 } from "child_process";
|
|
21775
22014
|
import { Transform } from "stream";
|
|
21776
22015
|
import fs39 from "fs";
|
|
21777
|
-
import
|
|
22016
|
+
import path45 from "path";
|
|
21778
22017
|
import { ClientSideConnection, ndJsonStream } from "@agentclientprotocol/sdk";
|
|
21779
22018
|
import { PROTOCOL_VERSION } from "@agentclientprotocol/sdk";
|
|
21780
22019
|
function findPackageRoot(startDir) {
|
|
21781
22020
|
let dir = startDir;
|
|
21782
|
-
while (dir !==
|
|
21783
|
-
if (fs39.existsSync(
|
|
22021
|
+
while (dir !== path45.dirname(dir)) {
|
|
22022
|
+
if (fs39.existsSync(path45.join(dir, "package.json"))) {
|
|
21784
22023
|
return dir;
|
|
21785
22024
|
}
|
|
21786
|
-
dir =
|
|
22025
|
+
dir = path45.dirname(dir);
|
|
21787
22026
|
}
|
|
21788
22027
|
return startDir;
|
|
21789
22028
|
}
|
|
21790
22029
|
function commandForWindowsScript(filePath) {
|
|
21791
|
-
const ext =
|
|
22030
|
+
const ext = path45.extname(filePath).toLowerCase();
|
|
21792
22031
|
if (process.platform === "win32" && (ext === ".cmd" || ext === ".bat")) {
|
|
21793
22032
|
return { command: process.env.ComSpec ?? "cmd.exe", args: ["/d", "/s", "/c", `"${filePath}"`] };
|
|
21794
22033
|
}
|
|
@@ -21802,8 +22041,8 @@ function resolveAgentCommand(cmd) {
|
|
|
21802
22041
|
}
|
|
21803
22042
|
for (const root of searchRoots) {
|
|
21804
22043
|
const packageDirs = [
|
|
21805
|
-
|
|
21806
|
-
|
|
22044
|
+
path45.resolve(root, "node_modules", "@zed-industries", cmd, "dist", "index.js"),
|
|
22045
|
+
path45.resolve(root, "node_modules", cmd, "dist", "index.js")
|
|
21807
22046
|
];
|
|
21808
22047
|
for (const jsPath of packageDirs) {
|
|
21809
22048
|
if (fs39.existsSync(jsPath)) {
|
|
@@ -21812,7 +22051,7 @@ function resolveAgentCommand(cmd) {
|
|
|
21812
22051
|
}
|
|
21813
22052
|
}
|
|
21814
22053
|
for (const root of searchRoots) {
|
|
21815
|
-
const localBin =
|
|
22054
|
+
const localBin = path45.resolve(root, "node_modules", ".bin", cmd);
|
|
21816
22055
|
if (fs39.existsSync(localBin)) {
|
|
21817
22056
|
const content = fs39.readFileSync(localBin, "utf-8");
|
|
21818
22057
|
if (content.startsWith("#!/usr/bin/env node")) {
|
|
@@ -21820,7 +22059,7 @@ function resolveAgentCommand(cmd) {
|
|
|
21820
22059
|
}
|
|
21821
22060
|
const match = content.match(/"([^"]+\.js)"/);
|
|
21822
22061
|
if (match) {
|
|
21823
|
-
const target =
|
|
22062
|
+
const target = path45.resolve(path45.dirname(localBin), match[1]);
|
|
21824
22063
|
if (fs39.existsSync(target)) {
|
|
21825
22064
|
return { command: process.execPath, args: [target] };
|
|
21826
22065
|
}
|
|
@@ -21836,9 +22075,9 @@ function resolveAgentCommand(cmd) {
|
|
|
21836
22075
|
candidates.push(dir);
|
|
21837
22076
|
}
|
|
21838
22077
|
};
|
|
21839
|
-
addCandidate(
|
|
22078
|
+
addCandidate(path45.dirname(process.execPath));
|
|
21840
22079
|
try {
|
|
21841
|
-
addCandidate(
|
|
22080
|
+
addCandidate(path45.dirname(fs39.realpathSync(process.execPath)));
|
|
21842
22081
|
} catch {
|
|
21843
22082
|
}
|
|
21844
22083
|
addCandidate("/opt/homebrew/bin");
|
|
@@ -21847,8 +22086,8 @@ function resolveAgentCommand(cmd) {
|
|
|
21847
22086
|
for (const dir of candidates) {
|
|
21848
22087
|
if (cmd === "npx") {
|
|
21849
22088
|
const npxCliCandidates = [
|
|
21850
|
-
|
|
21851
|
-
|
|
22089
|
+
path45.join(dir, "node_modules", "npm", "bin", "npx-cli.js"),
|
|
22090
|
+
path45.join(path45.dirname(dir), "lib", "node_modules", "npm", "bin", "npx-cli.js")
|
|
21852
22091
|
];
|
|
21853
22092
|
for (const npxCli of npxCliCandidates) {
|
|
21854
22093
|
if (fs39.existsSync(npxCli)) {
|
|
@@ -21858,7 +22097,7 @@ function resolveAgentCommand(cmd) {
|
|
|
21858
22097
|
}
|
|
21859
22098
|
}
|
|
21860
22099
|
for (const name of executableNames) {
|
|
21861
|
-
const candidate =
|
|
22100
|
+
const candidate = path45.join(dir, name);
|
|
21862
22101
|
if (fs39.existsSync(candidate)) {
|
|
21863
22102
|
const resolved = commandForWindowsScript(candidate);
|
|
21864
22103
|
log33.info({ cmd, resolved: candidate }, "Resolved package runner from fallback search");
|
|
@@ -21870,7 +22109,7 @@ function resolveAgentCommand(cmd) {
|
|
|
21870
22109
|
}
|
|
21871
22110
|
try {
|
|
21872
22111
|
const fullPath = execFileSync7("which", [cmd], { encoding: "utf-8" }).trim();
|
|
21873
|
-
const isUnspawnableWindowsShim = process.platform === "win32" && (cmd === "npx" || cmd === "uvx") && !
|
|
22112
|
+
const isUnspawnableWindowsShim = process.platform === "win32" && (cmd === "npx" || cmd === "uvx") && !path45.extname(fullPath);
|
|
21874
22113
|
if (fullPath && !isUnspawnableWindowsShim) {
|
|
21875
22114
|
try {
|
|
21876
22115
|
const content = fs39.readFileSync(fullPath, "utf-8");
|
|
@@ -22451,7 +22690,7 @@ ${stderr}`
|
|
|
22451
22690
|
writePath = result.path;
|
|
22452
22691
|
writeContent = result.content;
|
|
22453
22692
|
}
|
|
22454
|
-
await fs39.promises.mkdir(
|
|
22693
|
+
await fs39.promises.mkdir(path45.dirname(writePath), { recursive: true });
|
|
22455
22694
|
await fs39.promises.writeFile(writePath, writeContent, "utf-8");
|
|
22456
22695
|
return {};
|
|
22457
22696
|
},
|
|
@@ -24711,7 +24950,7 @@ var init_extract_file_info = __esm({
|
|
|
24711
24950
|
});
|
|
24712
24951
|
|
|
24713
24952
|
// src/core/message-transformer.ts
|
|
24714
|
-
import * as
|
|
24953
|
+
import * as path46 from "path";
|
|
24715
24954
|
function computeLineDiff(oldStr, newStr) {
|
|
24716
24955
|
const oldLines = oldStr ? oldStr.split("\n") : [];
|
|
24717
24956
|
const newLines = newStr ? newStr.split("\n") : [];
|
|
@@ -25017,7 +25256,7 @@ var init_message_transformer = __esm({
|
|
|
25017
25256
|
);
|
|
25018
25257
|
return;
|
|
25019
25258
|
}
|
|
25020
|
-
const fileExt =
|
|
25259
|
+
const fileExt = path46.extname(fileInfo.filePath).toLowerCase();
|
|
25021
25260
|
if (BINARY_VIEWER_EXTENSIONS.has(fileExt)) {
|
|
25022
25261
|
log36.debug({ kind, filePath: fileInfo.filePath }, "enrichWithViewerLinks: skipping binary file");
|
|
25023
25262
|
return;
|
|
@@ -25072,7 +25311,7 @@ var init_message_transformer = __esm({
|
|
|
25072
25311
|
|
|
25073
25312
|
// src/core/sessions/session-store.ts
|
|
25074
25313
|
import fs41 from "fs";
|
|
25075
|
-
import
|
|
25314
|
+
import path47 from "path";
|
|
25076
25315
|
var log37, DEBOUNCE_MS3, JsonFileSessionStore;
|
|
25077
25316
|
var init_session_store = __esm({
|
|
25078
25317
|
"src/core/sessions/session-store.ts"() {
|
|
@@ -25164,7 +25403,7 @@ var init_session_store = __esm({
|
|
|
25164
25403
|
version: 1,
|
|
25165
25404
|
sessions: Object.fromEntries(this.records)
|
|
25166
25405
|
};
|
|
25167
|
-
const dir =
|
|
25406
|
+
const dir = path47.dirname(this.filePath);
|
|
25168
25407
|
if (!fs41.existsSync(dir)) fs41.mkdirSync(dir, { recursive: true });
|
|
25169
25408
|
const tmpPath = `${this.filePath}.tmp`;
|
|
25170
25409
|
fs41.writeFileSync(tmpPath, JSON.stringify(data, null, 2));
|
|
@@ -25933,7 +26172,7 @@ __export(agent_catalog_exports, {
|
|
|
25933
26172
|
AgentCatalog: () => AgentCatalog
|
|
25934
26173
|
});
|
|
25935
26174
|
import * as fs42 from "fs";
|
|
25936
|
-
import * as
|
|
26175
|
+
import * as path48 from "path";
|
|
25937
26176
|
function stripNpmVersion(pkg) {
|
|
25938
26177
|
if (pkg.startsWith("@")) {
|
|
25939
26178
|
const slashIdx = pkg.indexOf("/");
|
|
@@ -26000,7 +26239,7 @@ var init_agent_catalog = __esm({
|
|
|
26000
26239
|
ttlHours: DEFAULT_TTL_HOURS,
|
|
26001
26240
|
data
|
|
26002
26241
|
};
|
|
26003
|
-
fs42.mkdirSync(
|
|
26242
|
+
fs42.mkdirSync(path48.dirname(this.cachePath), { recursive: true });
|
|
26004
26243
|
fs42.writeFileSync(this.cachePath, JSON.stringify(cache, null, 2), { mode: 384 });
|
|
26005
26244
|
this.enrichInstalledFromRegistry();
|
|
26006
26245
|
log40.info({ count: this.registryAgents.length }, "Registry updated");
|
|
@@ -26242,9 +26481,9 @@ var init_agent_catalog = __esm({
|
|
|
26242
26481
|
}
|
|
26243
26482
|
try {
|
|
26244
26483
|
const candidates = [
|
|
26245
|
-
|
|
26246
|
-
|
|
26247
|
-
|
|
26484
|
+
path48.join(import.meta.dirname, "data", "registry-snapshot.json"),
|
|
26485
|
+
path48.join(import.meta.dirname, "..", "data", "registry-snapshot.json"),
|
|
26486
|
+
path48.join(import.meta.dirname, "..", "..", "data", "registry-snapshot.json")
|
|
26248
26487
|
];
|
|
26249
26488
|
for (const candidate of candidates) {
|
|
26250
26489
|
if (fs42.existsSync(candidate)) {
|
|
@@ -26269,7 +26508,7 @@ __export(agent_store_exports, {
|
|
|
26269
26508
|
AgentStore: () => AgentStore
|
|
26270
26509
|
});
|
|
26271
26510
|
import * as fs43 from "fs";
|
|
26272
|
-
import * as
|
|
26511
|
+
import * as path49 from "path";
|
|
26273
26512
|
import { z as z10 } from "zod";
|
|
26274
26513
|
var log41, InstalledAgentSchema, AgentStoreSchema, AgentStore;
|
|
26275
26514
|
var init_agent_store = __esm({
|
|
@@ -26346,7 +26585,7 @@ var init_agent_store = __esm({
|
|
|
26346
26585
|
* may contain agent binary paths and environment variables.
|
|
26347
26586
|
*/
|
|
26348
26587
|
save() {
|
|
26349
|
-
fs43.mkdirSync(
|
|
26588
|
+
fs43.mkdirSync(path49.dirname(this.filePath), { recursive: true });
|
|
26350
26589
|
const tmpPath = this.filePath + ".tmp";
|
|
26351
26590
|
fs43.writeFileSync(tmpPath, JSON.stringify(this.data, null, 2), { mode: 384 });
|
|
26352
26591
|
fs43.renameSync(tmpPath, this.filePath);
|
|
@@ -26665,7 +26904,7 @@ var init_error_tracker = __esm({
|
|
|
26665
26904
|
|
|
26666
26905
|
// src/core/plugin/plugin-storage.ts
|
|
26667
26906
|
import fs44 from "fs";
|
|
26668
|
-
import
|
|
26907
|
+
import path50 from "path";
|
|
26669
26908
|
var PluginStorageImpl;
|
|
26670
26909
|
var init_plugin_storage = __esm({
|
|
26671
26910
|
"src/core/plugin/plugin-storage.ts"() {
|
|
@@ -26676,8 +26915,8 @@ var init_plugin_storage = __esm({
|
|
|
26676
26915
|
/** Serializes writes to prevent concurrent file corruption */
|
|
26677
26916
|
writeChain = Promise.resolve();
|
|
26678
26917
|
constructor(baseDir) {
|
|
26679
|
-
this.dataDir =
|
|
26680
|
-
this.kvPath =
|
|
26918
|
+
this.dataDir = path50.join(baseDir, "data");
|
|
26919
|
+
this.kvPath = path50.join(baseDir, "kv.json");
|
|
26681
26920
|
fs44.mkdirSync(baseDir, { recursive: true });
|
|
26682
26921
|
}
|
|
26683
26922
|
readKv() {
|
|
@@ -27802,7 +28041,7 @@ var init_core_items = __esm({
|
|
|
27802
28041
|
});
|
|
27803
28042
|
|
|
27804
28043
|
// src/core/core.ts
|
|
27805
|
-
import
|
|
28044
|
+
import path51 from "path";
|
|
27806
28045
|
import { nanoid as nanoid6 } from "nanoid";
|
|
27807
28046
|
var log45, OpenACPCore;
|
|
27808
28047
|
var init_core = __esm({
|
|
@@ -27828,6 +28067,7 @@ var init_core = __esm({
|
|
|
27828
28067
|
init_middleware_chain();
|
|
27829
28068
|
init_error_tracker();
|
|
27830
28069
|
init_log();
|
|
28070
|
+
init_native_stt();
|
|
27831
28071
|
init_events();
|
|
27832
28072
|
init_turn_context();
|
|
27833
28073
|
log45 = createChildLogger({ module: "core" });
|
|
@@ -27972,21 +28212,7 @@ var init_core = __esm({
|
|
|
27972
28212
|
const settingsMgr = this.settingsManager;
|
|
27973
28213
|
if (settingsMgr) {
|
|
27974
28214
|
const pluginCfg = await settingsMgr.loadSettings("@openacp/speech");
|
|
27975
|
-
const
|
|
27976
|
-
const sttProviders = {};
|
|
27977
|
-
if (groqApiKey) {
|
|
27978
|
-
sttProviders.groq = { apiKey: groqApiKey };
|
|
27979
|
-
}
|
|
27980
|
-
const newSpeechConfig = {
|
|
27981
|
-
stt: {
|
|
27982
|
-
provider: groqApiKey ? "groq" : null,
|
|
27983
|
-
providers: sttProviders
|
|
27984
|
-
},
|
|
27985
|
-
tts: {
|
|
27986
|
-
provider: pluginCfg.ttsProvider ?? null,
|
|
27987
|
-
providers: {}
|
|
27988
|
-
}
|
|
27989
|
-
};
|
|
28215
|
+
const newSpeechConfig = buildSpeechServiceConfig(pluginCfg);
|
|
27990
28216
|
speechSvc.refreshProviders(newSpeechConfig);
|
|
27991
28217
|
log45.info("Speech service config updated at runtime (from plugin settings)");
|
|
27992
28218
|
}
|
|
@@ -27995,7 +28221,7 @@ var init_core = __esm({
|
|
|
27995
28221
|
}
|
|
27996
28222
|
);
|
|
27997
28223
|
registerCoreMenuItems(this.menuRegistry);
|
|
27998
|
-
this.assistantRegistry.setInstanceRoot(
|
|
28224
|
+
this.assistantRegistry.setInstanceRoot(path51.dirname(ctx.root));
|
|
27999
28225
|
this.assistantRegistry.register(createSessionsSection(this));
|
|
28000
28226
|
this.assistantRegistry.register(createAgentsSection(this));
|
|
28001
28227
|
this.assistantRegistry.register(createConfigSection(this));
|
|
@@ -28429,8 +28655,8 @@ ${text5}`;
|
|
|
28429
28655
|
message: `Agent '${agentName}' not found`
|
|
28430
28656
|
};
|
|
28431
28657
|
}
|
|
28432
|
-
const { existsSync:
|
|
28433
|
-
if (!
|
|
28658
|
+
const { existsSync: existsSync21 } = await import("fs");
|
|
28659
|
+
if (!existsSync21(cwd)) {
|
|
28434
28660
|
return {
|
|
28435
28661
|
ok: false,
|
|
28436
28662
|
error: "invalid_cwd",
|
|
@@ -30148,11 +30374,11 @@ __export(instance_copy_exports, {
|
|
|
30148
30374
|
copyInstance: () => copyInstance
|
|
30149
30375
|
});
|
|
30150
30376
|
import fs45 from "fs";
|
|
30151
|
-
import
|
|
30377
|
+
import path52 from "path";
|
|
30152
30378
|
async function copyInstance(src, dst, opts) {
|
|
30153
30379
|
const { inheritableKeys = {}, onProgress } = opts;
|
|
30154
30380
|
fs45.mkdirSync(dst, { recursive: true });
|
|
30155
|
-
const configSrc =
|
|
30381
|
+
const configSrc = path52.join(src, "config.json");
|
|
30156
30382
|
if (fs45.existsSync(configSrc)) {
|
|
30157
30383
|
onProgress?.("Configuration", "start");
|
|
30158
30384
|
const config = JSON.parse(fs45.readFileSync(configSrc, "utf-8"));
|
|
@@ -30176,44 +30402,44 @@ async function copyInstance(src, dst, opts) {
|
|
|
30176
30402
|
}
|
|
30177
30403
|
}
|
|
30178
30404
|
}
|
|
30179
|
-
fs45.writeFileSync(
|
|
30405
|
+
fs45.writeFileSync(path52.join(dst, "config.json"), JSON.stringify(config, null, 2));
|
|
30180
30406
|
onProgress?.("Configuration", "done");
|
|
30181
30407
|
}
|
|
30182
|
-
const pluginsSrc =
|
|
30408
|
+
const pluginsSrc = path52.join(src, "plugins.json");
|
|
30183
30409
|
if (fs45.existsSync(pluginsSrc)) {
|
|
30184
30410
|
onProgress?.("Plugin list", "start");
|
|
30185
|
-
fs45.copyFileSync(pluginsSrc,
|
|
30411
|
+
fs45.copyFileSync(pluginsSrc, path52.join(dst, "plugins.json"));
|
|
30186
30412
|
onProgress?.("Plugin list", "done");
|
|
30187
30413
|
}
|
|
30188
|
-
const pluginsDir =
|
|
30414
|
+
const pluginsDir = path52.join(src, "plugins");
|
|
30189
30415
|
if (fs45.existsSync(pluginsDir)) {
|
|
30190
30416
|
onProgress?.("Plugins", "start");
|
|
30191
|
-
const dstPlugins =
|
|
30417
|
+
const dstPlugins = path52.join(dst, "plugins");
|
|
30192
30418
|
fs45.mkdirSync(dstPlugins, { recursive: true });
|
|
30193
|
-
const pkgJson =
|
|
30194
|
-
if (fs45.existsSync(pkgJson)) fs45.copyFileSync(pkgJson,
|
|
30195
|
-
const nodeModules =
|
|
30196
|
-
if (fs45.existsSync(nodeModules)) fs45.cpSync(nodeModules,
|
|
30419
|
+
const pkgJson = path52.join(pluginsDir, "package.json");
|
|
30420
|
+
if (fs45.existsSync(pkgJson)) fs45.copyFileSync(pkgJson, path52.join(dstPlugins, "package.json"));
|
|
30421
|
+
const nodeModules = path52.join(pluginsDir, "node_modules");
|
|
30422
|
+
if (fs45.existsSync(nodeModules)) fs45.cpSync(nodeModules, path52.join(dstPlugins, "node_modules"), { recursive: true });
|
|
30197
30423
|
onProgress?.("Plugins", "done");
|
|
30198
30424
|
}
|
|
30199
|
-
const agentsJson =
|
|
30425
|
+
const agentsJson = path52.join(src, "agents.json");
|
|
30200
30426
|
if (fs45.existsSync(agentsJson)) {
|
|
30201
30427
|
onProgress?.("Agents", "start");
|
|
30202
|
-
fs45.copyFileSync(agentsJson,
|
|
30203
|
-
const agentsDir =
|
|
30204
|
-
if (fs45.existsSync(agentsDir)) fs45.cpSync(agentsDir,
|
|
30428
|
+
fs45.copyFileSync(agentsJson, path52.join(dst, "agents.json"));
|
|
30429
|
+
const agentsDir = path52.join(src, "agents");
|
|
30430
|
+
if (fs45.existsSync(agentsDir)) fs45.cpSync(agentsDir, path52.join(dst, "agents"), { recursive: true });
|
|
30205
30431
|
onProgress?.("Agents", "done");
|
|
30206
30432
|
}
|
|
30207
|
-
const binDir =
|
|
30433
|
+
const binDir = path52.join(src, "bin");
|
|
30208
30434
|
if (fs45.existsSync(binDir)) {
|
|
30209
30435
|
onProgress?.("Tools", "start");
|
|
30210
|
-
fs45.cpSync(binDir,
|
|
30436
|
+
fs45.cpSync(binDir, path52.join(dst, "bin"), { recursive: true });
|
|
30211
30437
|
onProgress?.("Tools", "done");
|
|
30212
30438
|
}
|
|
30213
|
-
const pluginDataSrc =
|
|
30439
|
+
const pluginDataSrc = path52.join(src, "plugins", "data");
|
|
30214
30440
|
if (fs45.existsSync(pluginDataSrc)) {
|
|
30215
30441
|
onProgress?.("Preferences", "start");
|
|
30216
|
-
copyPluginSettings(pluginDataSrc,
|
|
30442
|
+
copyPluginSettings(pluginDataSrc, path52.join(dst, "plugins", "data"), inheritableKeys);
|
|
30217
30443
|
onProgress?.("Preferences", "done");
|
|
30218
30444
|
}
|
|
30219
30445
|
}
|
|
@@ -30228,10 +30454,10 @@ function copyPluginSettings(srcData, dstData, inheritableKeys) {
|
|
|
30228
30454
|
if (key in settings) filtered[key] = settings[key];
|
|
30229
30455
|
}
|
|
30230
30456
|
if (Object.keys(filtered).length > 0) {
|
|
30231
|
-
const relative =
|
|
30232
|
-
const dstDir =
|
|
30457
|
+
const relative = path52.relative(srcData, path52.dirname(settingsPath));
|
|
30458
|
+
const dstDir = path52.join(dstData, relative);
|
|
30233
30459
|
fs45.mkdirSync(dstDir, { recursive: true });
|
|
30234
|
-
fs45.writeFileSync(
|
|
30460
|
+
fs45.writeFileSync(path52.join(dstDir, "settings.json"), JSON.stringify(filtered, null, 2));
|
|
30235
30461
|
}
|
|
30236
30462
|
} catch {
|
|
30237
30463
|
}
|
|
@@ -30242,15 +30468,15 @@ function walkPluginDirs(base, cb) {
|
|
|
30242
30468
|
for (const entry of fs45.readdirSync(base, { withFileTypes: true })) {
|
|
30243
30469
|
if (!entry.isDirectory()) continue;
|
|
30244
30470
|
if (entry.name.startsWith("@")) {
|
|
30245
|
-
const scopeDir =
|
|
30471
|
+
const scopeDir = path52.join(base, entry.name);
|
|
30246
30472
|
for (const sub of fs45.readdirSync(scopeDir, { withFileTypes: true })) {
|
|
30247
30473
|
if (!sub.isDirectory()) continue;
|
|
30248
30474
|
const pluginName = `${entry.name}/${sub.name}`;
|
|
30249
|
-
const settingsPath =
|
|
30475
|
+
const settingsPath = path52.join(scopeDir, sub.name, "settings.json");
|
|
30250
30476
|
if (fs45.existsSync(settingsPath)) cb(pluginName, settingsPath);
|
|
30251
30477
|
}
|
|
30252
30478
|
} else {
|
|
30253
|
-
const settingsPath =
|
|
30479
|
+
const settingsPath = path52.join(base, entry.name, "settings.json");
|
|
30254
30480
|
if (fs45.existsSync(settingsPath)) cb(entry.name, settingsPath);
|
|
30255
30481
|
}
|
|
30256
30482
|
}
|
|
@@ -30263,14 +30489,14 @@ var init_instance_copy = __esm({
|
|
|
30263
30489
|
|
|
30264
30490
|
// src/core/setup/git-protect.ts
|
|
30265
30491
|
import fs46 from "fs";
|
|
30266
|
-
import
|
|
30492
|
+
import path53 from "path";
|
|
30267
30493
|
function protectLocalInstance(projectDir) {
|
|
30268
30494
|
ensureGitignore(projectDir);
|
|
30269
30495
|
ensureClaudeMd(projectDir);
|
|
30270
30496
|
printSecurityWarning();
|
|
30271
30497
|
}
|
|
30272
30498
|
function ensureGitignore(projectDir) {
|
|
30273
|
-
const gitignorePath =
|
|
30499
|
+
const gitignorePath = path53.join(projectDir, ".gitignore");
|
|
30274
30500
|
const entry = ".openacp";
|
|
30275
30501
|
if (fs46.existsSync(gitignorePath)) {
|
|
30276
30502
|
const content = fs46.readFileSync(gitignorePath, "utf-8");
|
|
@@ -30290,7 +30516,7 @@ ${entry}
|
|
|
30290
30516
|
}
|
|
30291
30517
|
}
|
|
30292
30518
|
function ensureClaudeMd(projectDir) {
|
|
30293
|
-
const claudeMdPath =
|
|
30519
|
+
const claudeMdPath = path53.join(projectDir, "CLAUDE.md");
|
|
30294
30520
|
const marker = "## Local OpenACP Workspace";
|
|
30295
30521
|
if (fs46.existsSync(claudeMdPath)) {
|
|
30296
30522
|
const content = fs46.readFileSync(claudeMdPath, "utf-8");
|
|
@@ -30333,7 +30559,7 @@ var init_git_protect = __esm({
|
|
|
30333
30559
|
});
|
|
30334
30560
|
|
|
30335
30561
|
// src/core/setup/wizard.ts
|
|
30336
|
-
import * as
|
|
30562
|
+
import * as path54 from "path";
|
|
30337
30563
|
import * as fs47 from "fs";
|
|
30338
30564
|
import * as os10 from "os";
|
|
30339
30565
|
import * as clack7 from "@clack/prompts";
|
|
@@ -30381,7 +30607,7 @@ async function runSetup(configManager, opts) {
|
|
|
30381
30607
|
const instanceRoot = opts?.instanceRoot;
|
|
30382
30608
|
let instanceName = opts?.instanceName;
|
|
30383
30609
|
if (!instanceName) {
|
|
30384
|
-
const defaultName =
|
|
30610
|
+
const defaultName = path54.basename(path54.dirname(instanceRoot));
|
|
30385
30611
|
const locationHint = instanceRoot.replace(/\/.openacp$/, "").replace(os10.homedir(), "~");
|
|
30386
30612
|
const nameResult = await clack7.text({
|
|
30387
30613
|
message: `Name for this workspace (${locationHint})`,
|
|
@@ -30392,13 +30618,13 @@ async function runSetup(configManager, opts) {
|
|
|
30392
30618
|
instanceName = nameResult.trim();
|
|
30393
30619
|
}
|
|
30394
30620
|
const globalRoot = getGlobalRoot();
|
|
30395
|
-
const registryPath =
|
|
30621
|
+
const registryPath = path54.join(globalRoot, "instances.json");
|
|
30396
30622
|
const instanceRegistry = new InstanceRegistry(registryPath);
|
|
30397
30623
|
instanceRegistry.load();
|
|
30398
30624
|
let didCopy = false;
|
|
30399
30625
|
if (opts?.from) {
|
|
30400
|
-
const fromRoot =
|
|
30401
|
-
if (fs47.existsSync(
|
|
30626
|
+
const fromRoot = path54.join(opts.from, ".openacp");
|
|
30627
|
+
if (fs47.existsSync(path54.join(fromRoot, "config.json"))) {
|
|
30402
30628
|
const inheritableMap = buildInheritableKeysMap();
|
|
30403
30629
|
await copyInstance(fromRoot, instanceRoot, { inheritableKeys: inheritableMap });
|
|
30404
30630
|
didCopy = true;
|
|
@@ -30409,7 +30635,7 @@ async function runSetup(configManager, opts) {
|
|
|
30409
30635
|
}
|
|
30410
30636
|
if (!didCopy) {
|
|
30411
30637
|
const existingInstances = instanceRegistry.list().filter(
|
|
30412
|
-
(e) => fs47.existsSync(
|
|
30638
|
+
(e) => fs47.existsSync(path54.join(e.root, "config.json")) && e.root !== instanceRoot
|
|
30413
30639
|
);
|
|
30414
30640
|
if (existingInstances.length > 0) {
|
|
30415
30641
|
let singleLabel;
|
|
@@ -30417,7 +30643,7 @@ async function runSetup(configManager, opts) {
|
|
|
30417
30643
|
const e = existingInstances[0];
|
|
30418
30644
|
let name = e.id;
|
|
30419
30645
|
try {
|
|
30420
|
-
const cfg = JSON.parse(fs47.readFileSync(
|
|
30646
|
+
const cfg = JSON.parse(fs47.readFileSync(path54.join(e.root, "config.json"), "utf-8"));
|
|
30421
30647
|
if (cfg.instanceName) name = cfg.instanceName;
|
|
30422
30648
|
} catch {
|
|
30423
30649
|
}
|
|
@@ -30440,7 +30666,7 @@ async function runSetup(configManager, opts) {
|
|
|
30440
30666
|
options: existingInstances.map((e) => {
|
|
30441
30667
|
let name = e.id;
|
|
30442
30668
|
try {
|
|
30443
|
-
const cfg = JSON.parse(fs47.readFileSync(
|
|
30669
|
+
const cfg = JSON.parse(fs47.readFileSync(path54.join(e.root, "config.json"), "utf-8"));
|
|
30444
30670
|
if (cfg.instanceName) name = cfg.instanceName;
|
|
30445
30671
|
} catch {
|
|
30446
30672
|
}
|
|
@@ -30535,9 +30761,9 @@ async function runSetup(configManager, opts) {
|
|
|
30535
30761
|
if (channelId.startsWith("official:")) {
|
|
30536
30762
|
const npmPackage = channelId.slice("official:".length);
|
|
30537
30763
|
const { execFileSync: execFileSync9 } = await import("child_process");
|
|
30538
|
-
const pluginsDir =
|
|
30539
|
-
const nodeModulesDir =
|
|
30540
|
-
const installedPath =
|
|
30764
|
+
const pluginsDir = path54.join(instanceRoot, "plugins");
|
|
30765
|
+
const nodeModulesDir = path54.join(pluginsDir, "node_modules");
|
|
30766
|
+
const installedPath = path54.join(nodeModulesDir, npmPackage);
|
|
30541
30767
|
if (!fs47.existsSync(installedPath)) {
|
|
30542
30768
|
try {
|
|
30543
30769
|
clack7.log.step(`Installing ${npmPackage}...`);
|
|
@@ -30551,9 +30777,9 @@ async function runSetup(configManager, opts) {
|
|
|
30551
30777
|
}
|
|
30552
30778
|
}
|
|
30553
30779
|
try {
|
|
30554
|
-
const installedPkgPath =
|
|
30780
|
+
const installedPkgPath = path54.join(nodeModulesDir, npmPackage, "package.json");
|
|
30555
30781
|
const installedPkg = JSON.parse(fs47.readFileSync(installedPkgPath, "utf-8"));
|
|
30556
|
-
const pluginModule = await import(
|
|
30782
|
+
const pluginModule = await import(path54.join(nodeModulesDir, npmPackage, installedPkg.main ?? "dist/index.js"));
|
|
30557
30783
|
const plugin2 = pluginModule.default;
|
|
30558
30784
|
if (plugin2?.install) {
|
|
30559
30785
|
const installCtx = createInstallContext2({
|
|
@@ -30583,8 +30809,8 @@ async function runSetup(configManager, opts) {
|
|
|
30583
30809
|
if (channelId.startsWith("community:")) {
|
|
30584
30810
|
const npmPackage = channelId.slice("community:".length);
|
|
30585
30811
|
const { execFileSync: execFileSync9 } = await import("child_process");
|
|
30586
|
-
const pluginsDir =
|
|
30587
|
-
const nodeModulesDir =
|
|
30812
|
+
const pluginsDir = path54.join(instanceRoot, "plugins");
|
|
30813
|
+
const nodeModulesDir = path54.join(pluginsDir, "node_modules");
|
|
30588
30814
|
try {
|
|
30589
30815
|
execFileSync9("npm", ["install", npmPackage, "--prefix", pluginsDir, "--save", "--ignore-scripts"], {
|
|
30590
30816
|
stdio: "inherit",
|
|
@@ -30596,9 +30822,9 @@ async function runSetup(configManager, opts) {
|
|
|
30596
30822
|
}
|
|
30597
30823
|
try {
|
|
30598
30824
|
const { readFileSync: readFileSync18 } = await import("fs");
|
|
30599
|
-
const installedPkgPath =
|
|
30825
|
+
const installedPkgPath = path54.join(nodeModulesDir, npmPackage, "package.json");
|
|
30600
30826
|
const installedPkg = JSON.parse(readFileSync18(installedPkgPath, "utf-8"));
|
|
30601
|
-
const pluginModule = await import(
|
|
30827
|
+
const pluginModule = await import(path54.join(nodeModulesDir, npmPackage, installedPkg.main ?? "dist/index.js"));
|
|
30602
30828
|
const plugin2 = pluginModule.default;
|
|
30603
30829
|
if (plugin2?.install) {
|
|
30604
30830
|
const installCtx = createInstallContext2({
|
|
@@ -30651,7 +30877,7 @@ async function runSetup(configManager, opts) {
|
|
|
30651
30877
|
workspace: { allowExternalWorkspaces: true, security: { allowedPaths: [], envWhitelist: [] } },
|
|
30652
30878
|
logging: {
|
|
30653
30879
|
level: "info",
|
|
30654
|
-
logDir:
|
|
30880
|
+
logDir: path54.join(instanceRoot, "logs"),
|
|
30655
30881
|
maxFileSize: "10m",
|
|
30656
30882
|
maxFiles: 7,
|
|
30657
30883
|
sessionLogRetentionDays: 30
|
|
@@ -30678,7 +30904,7 @@ async function runSetup(configManager, opts) {
|
|
|
30678
30904
|
instanceRegistry.register(instanceId, instanceRoot);
|
|
30679
30905
|
await instanceRegistry.save();
|
|
30680
30906
|
}
|
|
30681
|
-
const projectDir =
|
|
30907
|
+
const projectDir = path54.dirname(instanceRoot);
|
|
30682
30908
|
protectLocalInstance(projectDir);
|
|
30683
30909
|
clack7.outro(`Config saved to ${configManager.getConfigPath()}`);
|
|
30684
30910
|
if (!opts?.skipRunMode) {
|
|
@@ -30757,7 +30983,7 @@ async function runReconfigure(configManager, settingsManager) {
|
|
|
30757
30983
|
await configureChannels(config, settingsManager);
|
|
30758
30984
|
}
|
|
30759
30985
|
if (choice === "agents") {
|
|
30760
|
-
const reconfigRoot =
|
|
30986
|
+
const reconfigRoot = path54.dirname(configManager.getConfigPath());
|
|
30761
30987
|
const { defaultAgent } = await setupAgents(reconfigRoot);
|
|
30762
30988
|
await configManager.save({ defaultAgent });
|
|
30763
30989
|
config = configManager.get();
|
|
@@ -30962,7 +31188,7 @@ __export(dev_loader_exports, {
|
|
|
30962
31188
|
});
|
|
30963
31189
|
import fs48 from "fs";
|
|
30964
31190
|
import os11 from "os";
|
|
30965
|
-
import
|
|
31191
|
+
import path55 from "path";
|
|
30966
31192
|
var loadCounter, DevPluginLoader;
|
|
30967
31193
|
var init_dev_loader = __esm({
|
|
30968
31194
|
"src/core/plugin/dev-loader.ts"() {
|
|
@@ -30972,24 +31198,24 @@ var init_dev_loader = __esm({
|
|
|
30972
31198
|
pluginPath;
|
|
30973
31199
|
lastTempDir = null;
|
|
30974
31200
|
constructor(pluginPath) {
|
|
30975
|
-
this.pluginPath =
|
|
31201
|
+
this.pluginPath = path55.resolve(pluginPath);
|
|
30976
31202
|
}
|
|
30977
31203
|
async load() {
|
|
30978
|
-
const distPath =
|
|
30979
|
-
const distIndex =
|
|
30980
|
-
const srcIndex =
|
|
31204
|
+
const distPath = path55.join(this.pluginPath, "dist");
|
|
31205
|
+
const distIndex = path55.join(distPath, "index.js");
|
|
31206
|
+
const srcIndex = path55.join(this.pluginPath, "src", "index.ts");
|
|
30981
31207
|
if (!fs48.existsSync(distIndex) && !fs48.existsSync(srcIndex)) {
|
|
30982
31208
|
throw new Error(`Plugin not found at ${this.pluginPath}. Expected dist/index.js or src/index.ts`);
|
|
30983
31209
|
}
|
|
30984
31210
|
if (!fs48.existsSync(distIndex)) {
|
|
30985
31211
|
throw new Error(`Built plugin not found at ${distIndex}. Run 'npm run build' first.`);
|
|
30986
31212
|
}
|
|
30987
|
-
const tempDir =
|
|
31213
|
+
const tempDir = path55.join(os11.tmpdir(), `openacp-dev-plugin-${Date.now()}-${++loadCounter}`);
|
|
30988
31214
|
fs48.cpSync(distPath, tempDir, { recursive: true });
|
|
30989
31215
|
const previousTempDir = this.lastTempDir;
|
|
30990
31216
|
this.lastTempDir = tempDir;
|
|
30991
31217
|
try {
|
|
30992
|
-
const mod = await import(`file://${
|
|
31218
|
+
const mod = await import(`file://${path55.join(tempDir, "index.js")}`);
|
|
30993
31219
|
const plugin2 = mod.default;
|
|
30994
31220
|
if (!plugin2 || !plugin2.name || !plugin2.setup) {
|
|
30995
31221
|
throw new Error(`Invalid plugin at ${distIndex}. Must export default OpenACPPlugin with name and setup().`);
|
|
@@ -31012,7 +31238,7 @@ var init_dev_loader = __esm({
|
|
|
31012
31238
|
}
|
|
31013
31239
|
/** Returns the path to the plugin's dist directory (the source of truth — NOT the temp copy). */
|
|
31014
31240
|
getDistPath() {
|
|
31015
|
-
return
|
|
31241
|
+
return path55.join(this.pluginPath, "dist");
|
|
31016
31242
|
}
|
|
31017
31243
|
};
|
|
31018
31244
|
}
|
|
@@ -31024,7 +31250,7 @@ __export(main_exports, {
|
|
|
31024
31250
|
RESTART_EXIT_CODE: () => RESTART_EXIT_CODE,
|
|
31025
31251
|
startServer: () => startServer
|
|
31026
31252
|
});
|
|
31027
|
-
import
|
|
31253
|
+
import path56 from "path";
|
|
31028
31254
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
31029
31255
|
import fs49 from "fs";
|
|
31030
31256
|
async function startServer(opts) {
|
|
@@ -31049,7 +31275,7 @@ async function startServer(opts) {
|
|
|
31049
31275
|
process.exit(1);
|
|
31050
31276
|
}
|
|
31051
31277
|
const globalRoot = getGlobalRoot();
|
|
31052
|
-
const reg = new InstanceRegistry(
|
|
31278
|
+
const reg = new InstanceRegistry(path56.join(globalRoot, "instances.json"));
|
|
31053
31279
|
reg.load();
|
|
31054
31280
|
const entry = reg.getByRoot(root);
|
|
31055
31281
|
opts = { ...opts, instanceContext: createInstanceContext({ id: entry?.id ?? randomUUID4(), root }) };
|
|
@@ -31137,22 +31363,22 @@ async function startServer(opts) {
|
|
|
31137
31363
|
try {
|
|
31138
31364
|
let modulePath;
|
|
31139
31365
|
if (name.startsWith("/") || name.startsWith(".")) {
|
|
31140
|
-
const resolved =
|
|
31141
|
-
const pkgPath =
|
|
31366
|
+
const resolved = path56.resolve(name);
|
|
31367
|
+
const pkgPath = path56.join(resolved, "package.json");
|
|
31142
31368
|
const pkg = JSON.parse(await fs49.promises.readFile(pkgPath, "utf-8"));
|
|
31143
|
-
modulePath =
|
|
31369
|
+
modulePath = path56.join(resolved, pkg.main || "dist/index.js");
|
|
31144
31370
|
} else {
|
|
31145
|
-
const nodeModulesDir =
|
|
31146
|
-
let pkgDir =
|
|
31147
|
-
if (!fs49.existsSync(
|
|
31371
|
+
const nodeModulesDir = path56.join(ctx.paths.plugins, "node_modules");
|
|
31372
|
+
let pkgDir = path56.join(nodeModulesDir, name);
|
|
31373
|
+
if (!fs49.existsSync(path56.join(pkgDir, "package.json"))) {
|
|
31148
31374
|
let found = false;
|
|
31149
31375
|
const scopes = fs49.existsSync(nodeModulesDir) ? fs49.readdirSync(nodeModulesDir).filter((d) => d.startsWith("@")) : [];
|
|
31150
31376
|
for (const scope of scopes) {
|
|
31151
|
-
const scopeDir =
|
|
31377
|
+
const scopeDir = path56.join(nodeModulesDir, scope);
|
|
31152
31378
|
const pkgs = fs49.readdirSync(scopeDir);
|
|
31153
31379
|
for (const pkg2 of pkgs) {
|
|
31154
|
-
const candidateDir =
|
|
31155
|
-
const candidatePkgPath =
|
|
31380
|
+
const candidateDir = path56.join(scopeDir, pkg2);
|
|
31381
|
+
const candidatePkgPath = path56.join(candidateDir, "package.json");
|
|
31156
31382
|
if (fs49.existsSync(candidatePkgPath)) {
|
|
31157
31383
|
try {
|
|
31158
31384
|
const candidatePkg = JSON.parse(fs49.readFileSync(candidatePkgPath, "utf-8"));
|
|
@@ -31169,9 +31395,9 @@ async function startServer(opts) {
|
|
|
31169
31395
|
if (found) break;
|
|
31170
31396
|
}
|
|
31171
31397
|
}
|
|
31172
|
-
const pkgJsonPath =
|
|
31398
|
+
const pkgJsonPath = path56.join(pkgDir, "package.json");
|
|
31173
31399
|
const pkg = JSON.parse(await fs49.promises.readFile(pkgJsonPath, "utf-8"));
|
|
31174
|
-
modulePath =
|
|
31400
|
+
modulePath = path56.join(pkgDir, pkg.main || "dist/index.js");
|
|
31175
31401
|
}
|
|
31176
31402
|
log.debug({ plugin: name, modulePath }, "Loading community plugin");
|
|
31177
31403
|
const mod = await import(modulePath);
|
|
@@ -31343,7 +31569,7 @@ async function startServer(opts) {
|
|
|
31343
31569
|
await core.start();
|
|
31344
31570
|
try {
|
|
31345
31571
|
const globalRoot = getGlobalRoot();
|
|
31346
|
-
const registryPath =
|
|
31572
|
+
const registryPath = path56.join(globalRoot, "instances.json");
|
|
31347
31573
|
const instanceReg = new InstanceRegistry(registryPath);
|
|
31348
31574
|
await instanceReg.load();
|
|
31349
31575
|
if (!instanceReg.getByRoot(ctx.root)) {
|
|
@@ -31515,7 +31741,7 @@ var restart_exports = {};
|
|
|
31515
31741
|
__export(restart_exports, {
|
|
31516
31742
|
cmdRestart: () => cmdRestart
|
|
31517
31743
|
});
|
|
31518
|
-
import
|
|
31744
|
+
import path57 from "path";
|
|
31519
31745
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
31520
31746
|
async function cmdRestart(args2 = [], instanceRoot) {
|
|
31521
31747
|
const json = isJsonMode(args2);
|
|
@@ -31555,7 +31781,7 @@ Stops the running daemon (if any) and starts a new one.
|
|
|
31555
31781
|
if (!json && stopResult.stopped) {
|
|
31556
31782
|
console.log(`Stopped daemon (was PID ${stopResult.pid})`);
|
|
31557
31783
|
}
|
|
31558
|
-
const cm = new ConfigManager2(
|
|
31784
|
+
const cm = new ConfigManager2(path57.join(root, "config.json"));
|
|
31559
31785
|
if (!await cm.exists()) {
|
|
31560
31786
|
if (json) jsonError(ErrorCodes.CONFIG_NOT_FOUND, 'No config found. Run "openacp" first to set up.');
|
|
31561
31787
|
console.error('No config found. Run "openacp" first to set up.');
|
|
@@ -31576,7 +31802,7 @@ Stops the running daemon (if any) and starts a new one.
|
|
|
31576
31802
|
printInstanceHint(root);
|
|
31577
31803
|
console.log("Starting in foreground mode...");
|
|
31578
31804
|
const { startServer: startServer2 } = await Promise.resolve().then(() => (init_main(), main_exports));
|
|
31579
|
-
const reg = new InstanceRegistry(
|
|
31805
|
+
const reg = new InstanceRegistry(path57.join(getGlobalRoot(), "instances.json"));
|
|
31580
31806
|
reg.load();
|
|
31581
31807
|
const existingEntry = reg.getByRoot(root);
|
|
31582
31808
|
const ctx = createInstanceContext({
|
|
@@ -31625,7 +31851,7 @@ __export(status_exports, {
|
|
|
31625
31851
|
readInstanceInfo: () => readInstanceInfo
|
|
31626
31852
|
});
|
|
31627
31853
|
import fs50 from "fs";
|
|
31628
|
-
import
|
|
31854
|
+
import path58 from "path";
|
|
31629
31855
|
import os12 from "os";
|
|
31630
31856
|
async function cmdStatus(args2 = [], instanceRoot) {
|
|
31631
31857
|
const json = isJsonMode(args2);
|
|
@@ -31643,7 +31869,7 @@ async function cmdStatus(args2 = [], instanceRoot) {
|
|
|
31643
31869
|
await showSingleInstance(root, json);
|
|
31644
31870
|
}
|
|
31645
31871
|
async function showAllInstances(json = false) {
|
|
31646
|
-
const registryPath =
|
|
31872
|
+
const registryPath = path58.join(getGlobalRoot(), "instances.json");
|
|
31647
31873
|
const registry = new InstanceRegistry(registryPath);
|
|
31648
31874
|
await registry.load();
|
|
31649
31875
|
const instances = registry.list();
|
|
@@ -31686,7 +31912,7 @@ async function showAllInstances(json = false) {
|
|
|
31686
31912
|
console.log("");
|
|
31687
31913
|
}
|
|
31688
31914
|
async function showInstanceById(id, json = false) {
|
|
31689
|
-
const registryPath =
|
|
31915
|
+
const registryPath = path58.join(getGlobalRoot(), "instances.json");
|
|
31690
31916
|
const registry = new InstanceRegistry(registryPath);
|
|
31691
31917
|
await registry.load();
|
|
31692
31918
|
const entry = registry.get(id);
|
|
@@ -31701,7 +31927,7 @@ async function showSingleInstance(root, json = false) {
|
|
|
31701
31927
|
const info = readInstanceInfo(root);
|
|
31702
31928
|
if (json) {
|
|
31703
31929
|
jsonSuccess({
|
|
31704
|
-
id:
|
|
31930
|
+
id: path58.basename(root),
|
|
31705
31931
|
name: info.name,
|
|
31706
31932
|
status: info.pid ? "online" : "offline",
|
|
31707
31933
|
pid: info.pid,
|
|
@@ -31732,13 +31958,13 @@ function readInstanceInfo(root) {
|
|
|
31732
31958
|
channels: []
|
|
31733
31959
|
};
|
|
31734
31960
|
try {
|
|
31735
|
-
const config = JSON.parse(fs50.readFileSync(
|
|
31961
|
+
const config = JSON.parse(fs50.readFileSync(path58.join(root, "config.json"), "utf-8"));
|
|
31736
31962
|
result.name = config.instanceName ?? null;
|
|
31737
31963
|
result.runMode = config.runMode ?? null;
|
|
31738
31964
|
} catch {
|
|
31739
31965
|
}
|
|
31740
31966
|
try {
|
|
31741
|
-
const pid = parseInt(fs50.readFileSync(
|
|
31967
|
+
const pid = parseInt(fs50.readFileSync(path58.join(root, "openacp.pid"), "utf-8").trim());
|
|
31742
31968
|
if (!isNaN(pid)) {
|
|
31743
31969
|
process.kill(pid, 0);
|
|
31744
31970
|
result.pid = pid;
|
|
@@ -31746,19 +31972,19 @@ function readInstanceInfo(root) {
|
|
|
31746
31972
|
} catch {
|
|
31747
31973
|
}
|
|
31748
31974
|
try {
|
|
31749
|
-
const port = parseInt(fs50.readFileSync(
|
|
31975
|
+
const port = parseInt(fs50.readFileSync(path58.join(root, "api.port"), "utf-8").trim());
|
|
31750
31976
|
if (!isNaN(port)) result.apiPort = port;
|
|
31751
31977
|
} catch {
|
|
31752
31978
|
}
|
|
31753
31979
|
try {
|
|
31754
|
-
const tunnels = JSON.parse(fs50.readFileSync(
|
|
31980
|
+
const tunnels = JSON.parse(fs50.readFileSync(path58.join(root, "tunnels.json"), "utf-8"));
|
|
31755
31981
|
const entries = Object.values(tunnels);
|
|
31756
31982
|
const systemEntry = entries.find((t) => t.type === "system");
|
|
31757
31983
|
if (systemEntry?.port) result.tunnelPort = systemEntry.port;
|
|
31758
31984
|
} catch {
|
|
31759
31985
|
}
|
|
31760
31986
|
try {
|
|
31761
|
-
const plugins = JSON.parse(fs50.readFileSync(
|
|
31987
|
+
const plugins = JSON.parse(fs50.readFileSync(path58.join(root, "plugins.json"), "utf-8"));
|
|
31762
31988
|
const adapterMap = [
|
|
31763
31989
|
{ pluginName: "@openacp/telegram", channelId: "telegram" },
|
|
31764
31990
|
{ pluginName: "@openacp/discord-adapter", channelId: "discord" },
|
|
@@ -31776,7 +32002,7 @@ function readInstanceInfo(root) {
|
|
|
31776
32002
|
function formatInstanceStatus(root) {
|
|
31777
32003
|
const info = readInstanceInfo(root);
|
|
31778
32004
|
if (!info.pid) return null;
|
|
31779
|
-
const workspaceDir =
|
|
32005
|
+
const workspaceDir = path58.dirname(root);
|
|
31780
32006
|
const displayPath = workspaceDir.replace(os12.homedir(), "~");
|
|
31781
32007
|
const lines = [];
|
|
31782
32008
|
lines.push(` PID: ${info.pid}`);
|
|
@@ -31845,7 +32071,7 @@ var config_editor_exports = {};
|
|
|
31845
32071
|
__export(config_editor_exports, {
|
|
31846
32072
|
runConfigEditor: () => runConfigEditor
|
|
31847
32073
|
});
|
|
31848
|
-
import * as
|
|
32074
|
+
import * as path59 from "path";
|
|
31849
32075
|
import * as clack8 from "@clack/prompts";
|
|
31850
32076
|
async function select8(opts) {
|
|
31851
32077
|
const result = await clack8.select({
|
|
@@ -32399,7 +32625,7 @@ async function runConfigEditor(configManager, mode = "file", apiPort, settingsMa
|
|
|
32399
32625
|
await configManager.load();
|
|
32400
32626
|
const config = configManager.get();
|
|
32401
32627
|
const updates = {};
|
|
32402
|
-
const instanceRoot =
|
|
32628
|
+
const instanceRoot = path59.dirname(configManager.getConfigPath());
|
|
32403
32629
|
console.log(`
|
|
32404
32630
|
${c2.cyan}${c2.bold}OpenACP Config Editor${c2.reset}`);
|
|
32405
32631
|
console.log(dim2(`Config: ${configManager.getConfigPath()}`));
|
|
@@ -32456,17 +32682,17 @@ ${c2.cyan}${c2.bold}OpenACP Config Editor${c2.reset}`);
|
|
|
32456
32682
|
async function sendConfigViaApi(port, updates) {
|
|
32457
32683
|
const { apiCall: call } = await Promise.resolve().then(() => (init_api_client(), api_client_exports));
|
|
32458
32684
|
const paths = flattenToPaths(updates);
|
|
32459
|
-
for (const { path:
|
|
32685
|
+
for (const { path: path72, value } of paths) {
|
|
32460
32686
|
const res = await call(port, "/api/config", {
|
|
32461
32687
|
method: "PATCH",
|
|
32462
32688
|
headers: { "Content-Type": "application/json" },
|
|
32463
|
-
body: JSON.stringify({ path:
|
|
32689
|
+
body: JSON.stringify({ path: path72, value })
|
|
32464
32690
|
});
|
|
32465
32691
|
const data = await res.json();
|
|
32466
32692
|
if (!res.ok) {
|
|
32467
|
-
console.log(warn2(`Failed to update ${
|
|
32693
|
+
console.log(warn2(`Failed to update ${path72}: ${data.error}`));
|
|
32468
32694
|
} else if (data.needsRestart) {
|
|
32469
|
-
console.log(warn2(`${
|
|
32695
|
+
console.log(warn2(`${path72} updated \u2014 restart required`));
|
|
32470
32696
|
}
|
|
32471
32697
|
}
|
|
32472
32698
|
}
|
|
@@ -32576,24 +32802,24 @@ __export(migration_exports, {
|
|
|
32576
32802
|
migrateGlobalInstance: () => migrateGlobalInstance
|
|
32577
32803
|
});
|
|
32578
32804
|
import fs55 from "fs";
|
|
32579
|
-
import
|
|
32805
|
+
import path69 from "path";
|
|
32580
32806
|
import os15 from "os";
|
|
32581
32807
|
import { randomUUID as randomUUID8 } from "crypto";
|
|
32582
32808
|
async function migrateGlobalInstance() {
|
|
32583
32809
|
const globalRoot = getGlobalRoot();
|
|
32584
|
-
const globalConfig =
|
|
32810
|
+
const globalConfig = path69.join(globalRoot, "config.json");
|
|
32585
32811
|
if (!fs55.existsSync(globalConfig)) return null;
|
|
32586
|
-
let baseDir =
|
|
32812
|
+
let baseDir = path69.join(os15.homedir(), "openacp-workspace");
|
|
32587
32813
|
try {
|
|
32588
32814
|
const raw = JSON.parse(fs55.readFileSync(globalConfig, "utf-8"));
|
|
32589
32815
|
if (raw.workspace?.baseDir) {
|
|
32590
32816
|
const configured = raw.workspace.baseDir;
|
|
32591
|
-
baseDir = configured.startsWith("~") ?
|
|
32817
|
+
baseDir = configured.startsWith("~") ? path69.join(os15.homedir(), configured.slice(1)) : configured;
|
|
32592
32818
|
}
|
|
32593
32819
|
} catch {
|
|
32594
32820
|
}
|
|
32595
|
-
const targetRoot =
|
|
32596
|
-
if (
|
|
32821
|
+
const targetRoot = path69.join(baseDir, ".openacp");
|
|
32822
|
+
if (path69.resolve(targetRoot) === path69.resolve(globalRoot)) {
|
|
32597
32823
|
return null;
|
|
32598
32824
|
}
|
|
32599
32825
|
const instanceFiles = [
|
|
@@ -32607,34 +32833,34 @@ async function migrateGlobalInstance() {
|
|
|
32607
32833
|
const instanceDirs = ["plugins", "logs", "history", "files"];
|
|
32608
32834
|
fs55.mkdirSync(targetRoot, { recursive: true });
|
|
32609
32835
|
for (const file of instanceFiles) {
|
|
32610
|
-
const src =
|
|
32611
|
-
const dst =
|
|
32836
|
+
const src = path69.join(globalRoot, file);
|
|
32837
|
+
const dst = path69.join(targetRoot, file);
|
|
32612
32838
|
if (fs55.existsSync(src)) {
|
|
32613
32839
|
fs55.cpSync(src, dst, { force: true });
|
|
32614
32840
|
fs55.rmSync(src);
|
|
32615
32841
|
}
|
|
32616
32842
|
}
|
|
32617
32843
|
for (const dir of instanceDirs) {
|
|
32618
|
-
const src =
|
|
32619
|
-
const dst =
|
|
32844
|
+
const src = path69.join(globalRoot, dir);
|
|
32845
|
+
const dst = path69.join(targetRoot, dir);
|
|
32620
32846
|
if (fs55.existsSync(src)) {
|
|
32621
32847
|
fs55.cpSync(src, dst, { recursive: true, force: true });
|
|
32622
32848
|
fs55.rmSync(src, { recursive: true, force: true });
|
|
32623
32849
|
}
|
|
32624
32850
|
}
|
|
32625
|
-
const srcCache =
|
|
32626
|
-
const dstCache =
|
|
32851
|
+
const srcCache = path69.join(globalRoot, "cache");
|
|
32852
|
+
const dstCache = path69.join(targetRoot, "cache");
|
|
32627
32853
|
if (fs55.existsSync(srcCache)) {
|
|
32628
32854
|
fs55.mkdirSync(dstCache, { recursive: true });
|
|
32629
32855
|
for (const entry of fs55.readdirSync(srcCache)) {
|
|
32630
32856
|
if (entry === "registry-cache.json") continue;
|
|
32631
|
-
const s =
|
|
32632
|
-
const d =
|
|
32857
|
+
const s = path69.join(srcCache, entry);
|
|
32858
|
+
const d = path69.join(dstCache, entry);
|
|
32633
32859
|
fs55.cpSync(s, d, { recursive: true, force: true });
|
|
32634
32860
|
fs55.rmSync(s, { recursive: true, force: true });
|
|
32635
32861
|
}
|
|
32636
32862
|
}
|
|
32637
|
-
const migratedConfigPath =
|
|
32863
|
+
const migratedConfigPath = path69.join(targetRoot, "config.json");
|
|
32638
32864
|
try {
|
|
32639
32865
|
const config = JSON.parse(fs55.readFileSync(migratedConfigPath, "utf-8"));
|
|
32640
32866
|
if (config.workspace?.baseDir) {
|
|
@@ -32643,7 +32869,7 @@ async function migrateGlobalInstance() {
|
|
|
32643
32869
|
fs55.writeFileSync(migratedConfigPath, JSON.stringify(config, null, 2));
|
|
32644
32870
|
} catch {
|
|
32645
32871
|
}
|
|
32646
|
-
const registryPath =
|
|
32872
|
+
const registryPath = path69.join(globalRoot, "instances.json");
|
|
32647
32873
|
try {
|
|
32648
32874
|
const registry = new InstanceRegistry(registryPath);
|
|
32649
32875
|
registry.load();
|
|
@@ -32675,17 +32901,17 @@ __export(instance_prompt_exports, {
|
|
|
32675
32901
|
promptForInstance: () => promptForInstance
|
|
32676
32902
|
});
|
|
32677
32903
|
import fs56 from "fs";
|
|
32678
|
-
import
|
|
32904
|
+
import path70 from "path";
|
|
32679
32905
|
import os16 from "os";
|
|
32680
32906
|
async function promptForInstance(opts) {
|
|
32681
32907
|
const globalRoot = getGlobalRoot();
|
|
32682
|
-
const globalConfigExists = fs56.existsSync(
|
|
32908
|
+
const globalConfigExists = fs56.existsSync(path70.join(globalRoot, "config.json"));
|
|
32683
32909
|
const cwd = process.cwd();
|
|
32684
|
-
const isHomeDir =
|
|
32685
|
-
const defaultWorkspace =
|
|
32686
|
-
const createRoot = isHomeDir ?
|
|
32910
|
+
const isHomeDir = path70.resolve(cwd) === path70.resolve(os16.homedir());
|
|
32911
|
+
const defaultWorkspace = path70.join(os16.homedir(), "openacp-workspace");
|
|
32912
|
+
const createRoot = isHomeDir ? path70.join(defaultWorkspace, ".openacp") : path70.join(cwd, ".openacp");
|
|
32687
32913
|
const detectedParent = findParentInstance(cwd, globalRoot);
|
|
32688
|
-
const registryPath =
|
|
32914
|
+
const registryPath = path70.join(globalRoot, "instances.json");
|
|
32689
32915
|
const registry = new InstanceRegistry(registryPath);
|
|
32690
32916
|
registry.load();
|
|
32691
32917
|
const instances = registry.list().filter((e) => fs56.existsSync(e.root));
|
|
@@ -32717,24 +32943,24 @@ async function promptForInstance(opts) {
|
|
|
32717
32943
|
const instanceOptions = instances.filter((e) => !detectedParent || e.root !== detectedParent).map((e) => {
|
|
32718
32944
|
let name = e.id;
|
|
32719
32945
|
try {
|
|
32720
|
-
const raw = fs56.readFileSync(
|
|
32946
|
+
const raw = fs56.readFileSync(path70.join(e.root, "config.json"), "utf-8");
|
|
32721
32947
|
const parsed = JSON.parse(raw);
|
|
32722
32948
|
if (parsed.instanceName) name = parsed.instanceName;
|
|
32723
32949
|
} catch {
|
|
32724
32950
|
}
|
|
32725
|
-
const workspaceDir =
|
|
32951
|
+
const workspaceDir = path70.dirname(e.root);
|
|
32726
32952
|
const displayPath = workspaceDir.replace(os16.homedir(), "~");
|
|
32727
32953
|
return { value: e.root, label: `${name} (${displayPath})` };
|
|
32728
32954
|
});
|
|
32729
32955
|
if (detectedParent) {
|
|
32730
|
-
let name =
|
|
32956
|
+
let name = path70.basename(path70.dirname(detectedParent));
|
|
32731
32957
|
try {
|
|
32732
|
-
const raw = fs56.readFileSync(
|
|
32958
|
+
const raw = fs56.readFileSync(path70.join(detectedParent, "config.json"), "utf-8");
|
|
32733
32959
|
const parsed = JSON.parse(raw);
|
|
32734
32960
|
if (parsed.instanceName) name = parsed.instanceName;
|
|
32735
32961
|
} catch {
|
|
32736
32962
|
}
|
|
32737
|
-
const workspaceDir =
|
|
32963
|
+
const workspaceDir = path70.dirname(detectedParent);
|
|
32738
32964
|
const displayPath = workspaceDir.replace(os16.homedir(), "~");
|
|
32739
32965
|
instanceOptions.unshift({ value: detectedParent, label: `${name} (${displayPath})` });
|
|
32740
32966
|
}
|
|
@@ -32773,11 +32999,11 @@ async function promptForInstance(opts) {
|
|
|
32773
32999
|
return choice;
|
|
32774
33000
|
}
|
|
32775
33001
|
function findParentInstance(cwd, globalRoot) {
|
|
32776
|
-
let dir =
|
|
33002
|
+
let dir = path70.dirname(cwd);
|
|
32777
33003
|
while (true) {
|
|
32778
|
-
const candidate =
|
|
32779
|
-
if (candidate !== globalRoot && fs56.existsSync(
|
|
32780
|
-
const parent =
|
|
33004
|
+
const candidate = path70.join(dir, ".openacp");
|
|
33005
|
+
if (candidate !== globalRoot && fs56.existsSync(path70.join(candidate, "config.json"))) return candidate;
|
|
33006
|
+
const parent = path70.dirname(dir);
|
|
32781
33007
|
if (parent === dir) break;
|
|
32782
33008
|
dir = parent;
|
|
32783
33009
|
}
|
|
@@ -32793,7 +33019,7 @@ var init_instance_prompt = __esm({
|
|
|
32793
33019
|
|
|
32794
33020
|
// src/cli.ts
|
|
32795
33021
|
import { setDefaultAutoSelectFamily } from "net";
|
|
32796
|
-
import
|
|
33022
|
+
import path71 from "path";
|
|
32797
33023
|
|
|
32798
33024
|
// src/cli/commands/help.ts
|
|
32799
33025
|
function printHelp() {
|
|
@@ -32937,10 +33163,10 @@ Shows all plugins registered in the plugin registry.
|
|
|
32937
33163
|
`);
|
|
32938
33164
|
return;
|
|
32939
33165
|
}
|
|
32940
|
-
const
|
|
33166
|
+
const path72 = await import("path");
|
|
32941
33167
|
const { PluginRegistry: PluginRegistry2 } = await Promise.resolve().then(() => (init_plugin_registry(), plugin_registry_exports));
|
|
32942
33168
|
const root = instanceRoot;
|
|
32943
|
-
const registryPath =
|
|
33169
|
+
const registryPath = path72.join(root, "plugins.json");
|
|
32944
33170
|
const registry = new PluginRegistry2(registryPath);
|
|
32945
33171
|
await registry.load();
|
|
32946
33172
|
const plugins = registry.list();
|
|
@@ -33076,10 +33302,10 @@ async function cmdPlugin(args2 = [], instanceRoot) {
|
|
|
33076
33302
|
}
|
|
33077
33303
|
async function setPluginEnabled(name, enabled, instanceRoot, json = false) {
|
|
33078
33304
|
if (json) await muteForJson();
|
|
33079
|
-
const
|
|
33305
|
+
const path72 = await import("path");
|
|
33080
33306
|
const { PluginRegistry: PluginRegistry2 } = await Promise.resolve().then(() => (init_plugin_registry(), plugin_registry_exports));
|
|
33081
33307
|
const root = instanceRoot;
|
|
33082
|
-
const registryPath =
|
|
33308
|
+
const registryPath = path72.join(root, "plugins.json");
|
|
33083
33309
|
const registry = new PluginRegistry2(registryPath);
|
|
33084
33310
|
await registry.load();
|
|
33085
33311
|
const entry = registry.get(name);
|
|
@@ -33094,7 +33320,7 @@ async function setPluginEnabled(name, enabled, instanceRoot, json = false) {
|
|
|
33094
33320
|
console.log(`Plugin ${name} ${enabled ? "enabled" : "disabled"}. Restart to apply.`);
|
|
33095
33321
|
}
|
|
33096
33322
|
async function configurePlugin(name, instanceRoot) {
|
|
33097
|
-
const
|
|
33323
|
+
const path72 = await import("path");
|
|
33098
33324
|
const { corePlugins: corePlugins2 } = await Promise.resolve().then(() => (init_core_plugins(), core_plugins_exports));
|
|
33099
33325
|
const { SettingsManager: SettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
|
|
33100
33326
|
const { createInstallContext: createInstallContext2 } = await Promise.resolve().then(() => (init_install_context(), install_context_exports));
|
|
@@ -33104,7 +33330,7 @@ async function configurePlugin(name, instanceRoot) {
|
|
|
33104
33330
|
process.exit(1);
|
|
33105
33331
|
}
|
|
33106
33332
|
const root = instanceRoot;
|
|
33107
|
-
const basePath =
|
|
33333
|
+
const basePath = path72.join(root, "plugins", "data");
|
|
33108
33334
|
const settingsManager = new SettingsManager2(basePath);
|
|
33109
33335
|
const ctx = createInstallContext2({ pluginName: name, settingsManager, basePath });
|
|
33110
33336
|
if (plugin2.configure) {
|
|
@@ -33117,7 +33343,7 @@ async function configurePlugin(name, instanceRoot) {
|
|
|
33117
33343
|
}
|
|
33118
33344
|
async function installPlugin(input2, instanceRoot, json = false) {
|
|
33119
33345
|
if (json) await muteForJson();
|
|
33120
|
-
const
|
|
33346
|
+
const path72 = await import("path");
|
|
33121
33347
|
const { execFileSync: execFileSync9 } = await import("child_process");
|
|
33122
33348
|
const { getCurrentVersion: getCurrentVersion2 } = await Promise.resolve().then(() => (init_version(), version_exports));
|
|
33123
33349
|
const { SettingsManager: SettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
|
|
@@ -33168,9 +33394,9 @@ async function installPlugin(input2, instanceRoot, json = false) {
|
|
|
33168
33394
|
if (!json) console.log(`Installing ${installSpec}...`);
|
|
33169
33395
|
const { corePlugins: corePlugins2 } = await Promise.resolve().then(() => (init_core_plugins(), core_plugins_exports));
|
|
33170
33396
|
const builtinPlugin = corePlugins2.find((p2) => p2.name === pkgName);
|
|
33171
|
-
const basePath =
|
|
33397
|
+
const basePath = path72.join(root, "plugins", "data");
|
|
33172
33398
|
const settingsManager = new SettingsManager2(basePath);
|
|
33173
|
-
const registryPath =
|
|
33399
|
+
const registryPath = path72.join(root, "plugins.json");
|
|
33174
33400
|
const pluginRegistry = new PluginRegistry2(registryPath);
|
|
33175
33401
|
await pluginRegistry.load();
|
|
33176
33402
|
if (builtinPlugin) {
|
|
@@ -33190,8 +33416,8 @@ async function installPlugin(input2, instanceRoot, json = false) {
|
|
|
33190
33416
|
console.log(`\u2713 ${builtinPlugin.name} installed! Restart to activate.`);
|
|
33191
33417
|
return;
|
|
33192
33418
|
}
|
|
33193
|
-
const pluginsDir =
|
|
33194
|
-
const nodeModulesDir =
|
|
33419
|
+
const pluginsDir = path72.join(root, "plugins");
|
|
33420
|
+
const nodeModulesDir = path72.join(pluginsDir, "node_modules");
|
|
33195
33421
|
try {
|
|
33196
33422
|
execFileSync9("npm", ["install", installSpec, "--prefix", pluginsDir, "--save"], {
|
|
33197
33423
|
stdio: json ? "pipe" : "inherit",
|
|
@@ -33205,8 +33431,8 @@ async function installPlugin(input2, instanceRoot, json = false) {
|
|
|
33205
33431
|
const cliVersion = getCurrentVersion2();
|
|
33206
33432
|
const isLocalPath = pkgName.startsWith("/") || pkgName.startsWith(".");
|
|
33207
33433
|
try {
|
|
33208
|
-
const pluginRoot = isLocalPath ?
|
|
33209
|
-
const installedPkgPath =
|
|
33434
|
+
const pluginRoot = isLocalPath ? path72.resolve(pkgName) : path72.join(nodeModulesDir, pkgName);
|
|
33435
|
+
const installedPkgPath = path72.join(pluginRoot, "package.json");
|
|
33210
33436
|
const { readFileSync: readFileSync18 } = await import("fs");
|
|
33211
33437
|
const installedPkg = JSON.parse(readFileSync18(installedPkgPath, "utf-8"));
|
|
33212
33438
|
const minVersion = installedPkg.engines?.openacp?.replace(/[>=^~\s]/g, "");
|
|
@@ -33221,7 +33447,7 @@ async function installPlugin(input2, instanceRoot, json = false) {
|
|
|
33221
33447
|
}
|
|
33222
33448
|
}
|
|
33223
33449
|
}
|
|
33224
|
-
const pluginModule = await import(
|
|
33450
|
+
const pluginModule = await import(path72.join(pluginRoot, installedPkg.main ?? "dist/index.js"));
|
|
33225
33451
|
const plugin2 = pluginModule.default;
|
|
33226
33452
|
if (plugin2?.install) {
|
|
33227
33453
|
const ctx = createInstallContext2({ pluginName: plugin2.name ?? pkgName, settingsManager, basePath });
|
|
@@ -33251,11 +33477,11 @@ async function installPlugin(input2, instanceRoot, json = false) {
|
|
|
33251
33477
|
}
|
|
33252
33478
|
async function uninstallPlugin(name, purge, instanceRoot, json = false) {
|
|
33253
33479
|
if (json) await muteForJson();
|
|
33254
|
-
const
|
|
33480
|
+
const path72 = await import("path");
|
|
33255
33481
|
const fs57 = await import("fs");
|
|
33256
33482
|
const { PluginRegistry: PluginRegistry2 } = await Promise.resolve().then(() => (init_plugin_registry(), plugin_registry_exports));
|
|
33257
33483
|
const root = instanceRoot;
|
|
33258
|
-
const registryPath =
|
|
33484
|
+
const registryPath = path72.join(root, "plugins.json");
|
|
33259
33485
|
const registry = new PluginRegistry2(registryPath);
|
|
33260
33486
|
await registry.load();
|
|
33261
33487
|
const entry = registry.get(name);
|
|
@@ -33275,7 +33501,7 @@ async function uninstallPlugin(name, purge, instanceRoot, json = false) {
|
|
|
33275
33501
|
if (plugin2?.uninstall) {
|
|
33276
33502
|
const { SettingsManager: SettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
|
|
33277
33503
|
const { createInstallContext: createInstallContext2 } = await Promise.resolve().then(() => (init_install_context(), install_context_exports));
|
|
33278
|
-
const basePath =
|
|
33504
|
+
const basePath = path72.join(root, "plugins", "data");
|
|
33279
33505
|
const settingsManager = new SettingsManager2(basePath);
|
|
33280
33506
|
const ctx = createInstallContext2({ pluginName: name, settingsManager, basePath });
|
|
33281
33507
|
await plugin2.uninstall(ctx, { purge });
|
|
@@ -33283,7 +33509,7 @@ async function uninstallPlugin(name, purge, instanceRoot, json = false) {
|
|
|
33283
33509
|
} catch {
|
|
33284
33510
|
}
|
|
33285
33511
|
if (purge) {
|
|
33286
|
-
const pluginDir =
|
|
33512
|
+
const pluginDir = path72.join(root, "plugins", name);
|
|
33287
33513
|
fs57.rmSync(pluginDir, { recursive: true, force: true });
|
|
33288
33514
|
}
|
|
33289
33515
|
registry.remove(name);
|
|
@@ -33324,12 +33550,12 @@ init_helpers();
|
|
|
33324
33550
|
init_output();
|
|
33325
33551
|
import { execSync as execSync2 } from "child_process";
|
|
33326
33552
|
import * as fs32 from "fs";
|
|
33327
|
-
import * as
|
|
33553
|
+
import * as path36 from "path";
|
|
33328
33554
|
async function cmdUninstall(args2, instanceRoot) {
|
|
33329
33555
|
const json = isJsonMode(args2);
|
|
33330
33556
|
if (json) await muteForJson();
|
|
33331
33557
|
const root = instanceRoot;
|
|
33332
|
-
const pluginsDir =
|
|
33558
|
+
const pluginsDir = path36.join(root, "plugins");
|
|
33333
33559
|
if (!json && wantsHelp(args2)) {
|
|
33334
33560
|
console.log(`
|
|
33335
33561
|
\x1B[1mopenacp uninstall\x1B[0m \u2014 Remove a plugin adapter
|
|
@@ -33356,7 +33582,7 @@ async function cmdUninstall(args2, instanceRoot) {
|
|
|
33356
33582
|
process.exit(1);
|
|
33357
33583
|
}
|
|
33358
33584
|
fs32.mkdirSync(pluginsDir, { recursive: true });
|
|
33359
|
-
const pkgPath =
|
|
33585
|
+
const pkgPath = path36.join(pluginsDir, "package.json");
|
|
33360
33586
|
if (!fs32.existsSync(pkgPath)) {
|
|
33361
33587
|
fs32.writeFileSync(pkgPath, JSON.stringify({ name: "openacp-plugins", private: true, dependencies: {} }, null, 2));
|
|
33362
33588
|
}
|
|
@@ -34202,7 +34428,7 @@ init_helpers();
|
|
|
34202
34428
|
init_output();
|
|
34203
34429
|
init_instance_hint();
|
|
34204
34430
|
init_resolve_instance_id();
|
|
34205
|
-
import
|
|
34431
|
+
import path42 from "path";
|
|
34206
34432
|
async function cmdStart(args2 = [], instanceRoot) {
|
|
34207
34433
|
const json = isJsonMode(args2);
|
|
34208
34434
|
if (json) await muteForJson();
|
|
@@ -34232,7 +34458,7 @@ Requires an existing config \u2014 run 'openacp' first to set up.
|
|
|
34232
34458
|
await checkAndPromptUpdate();
|
|
34233
34459
|
const { startDaemon: startDaemon2, getPidPath: getPidPath2, isProcessRunning: isProcessRunning2 } = await Promise.resolve().then(() => (init_daemon2(), daemon_exports));
|
|
34234
34460
|
const { ConfigManager: ConfigManager2 } = await Promise.resolve().then(() => (init_config2(), config_exports));
|
|
34235
|
-
const cm = new ConfigManager2(
|
|
34461
|
+
const cm = new ConfigManager2(path42.join(root, "config.json"));
|
|
34236
34462
|
if (await cm.exists()) {
|
|
34237
34463
|
await cm.load();
|
|
34238
34464
|
const config = cm.get();
|
|
@@ -34258,12 +34484,12 @@ Requires an existing config \u2014 run 'openacp' first to set up.
|
|
|
34258
34484
|
}
|
|
34259
34485
|
if (json) {
|
|
34260
34486
|
const { waitForPortFile: waitForPortFile2 } = await Promise.resolve().then(() => (init_api_client(), api_client_exports));
|
|
34261
|
-
const port = await waitForPortFile2(
|
|
34487
|
+
const port = await waitForPortFile2(path42.join(root, "api.port")) ?? 21420;
|
|
34262
34488
|
jsonSuccess({
|
|
34263
34489
|
pid: result.pid,
|
|
34264
34490
|
instanceId,
|
|
34265
34491
|
name: config.instanceName ?? null,
|
|
34266
|
-
directory:
|
|
34492
|
+
directory: path42.dirname(root),
|
|
34267
34493
|
dir: root,
|
|
34268
34494
|
port
|
|
34269
34495
|
});
|
|
@@ -34433,7 +34659,7 @@ start fresh with the setup wizard. The daemon must be stopped first.
|
|
|
34433
34659
|
`);
|
|
34434
34660
|
return;
|
|
34435
34661
|
}
|
|
34436
|
-
const
|
|
34662
|
+
const path72 = await import("path");
|
|
34437
34663
|
const root = instanceRoot;
|
|
34438
34664
|
const { getStatus: getStatus2, getPidPath: getPidPath2 } = await Promise.resolve().then(() => (init_daemon2(), daemon_exports));
|
|
34439
34665
|
const status = getStatus2(getPidPath2(root));
|
|
@@ -34595,14 +34821,14 @@ as a messaging thread. Requires a running daemon.
|
|
|
34595
34821
|
// src/cli/commands/instances.ts
|
|
34596
34822
|
init_instance_registry();
|
|
34597
34823
|
init_instance_context();
|
|
34598
|
-
import
|
|
34824
|
+
import path61 from "path";
|
|
34599
34825
|
import os13 from "os";
|
|
34600
34826
|
import fs52 from "fs";
|
|
34601
34827
|
import { randomUUID as randomUUID6 } from "crypto";
|
|
34602
34828
|
|
|
34603
34829
|
// src/core/instance/instance-init.ts
|
|
34604
34830
|
import fs51 from "fs";
|
|
34605
|
-
import
|
|
34831
|
+
import path60 from "path";
|
|
34606
34832
|
function initInstanceFiles(instanceRoot, opts = {}) {
|
|
34607
34833
|
fs51.mkdirSync(instanceRoot, { recursive: true });
|
|
34608
34834
|
writeConfig(instanceRoot, opts);
|
|
@@ -34612,7 +34838,7 @@ function initInstanceFiles(instanceRoot, opts = {}) {
|
|
|
34612
34838
|
writePluginsIfMissing(instanceRoot);
|
|
34613
34839
|
}
|
|
34614
34840
|
function writeConfig(instanceRoot, opts) {
|
|
34615
|
-
const configPath =
|
|
34841
|
+
const configPath = path60.join(instanceRoot, "config.json");
|
|
34616
34842
|
let existing = {};
|
|
34617
34843
|
if (opts.mergeExisting && fs51.existsSync(configPath)) {
|
|
34618
34844
|
try {
|
|
@@ -34642,7 +34868,7 @@ function writeConfig(instanceRoot, opts) {
|
|
|
34642
34868
|
fs51.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
34643
34869
|
}
|
|
34644
34870
|
function writeAgentsIfMissing(instanceRoot, agents) {
|
|
34645
|
-
const agentsPath =
|
|
34871
|
+
const agentsPath = path60.join(instanceRoot, "agents.json");
|
|
34646
34872
|
if (fs51.existsSync(agentsPath)) return;
|
|
34647
34873
|
const installed = {};
|
|
34648
34874
|
for (const agentName of agents) {
|
|
@@ -34661,7 +34887,7 @@ function writeAgentsIfMissing(instanceRoot, agents) {
|
|
|
34661
34887
|
fs51.writeFileSync(agentsPath, JSON.stringify({ version: 1, installed }, null, 2));
|
|
34662
34888
|
}
|
|
34663
34889
|
function writePluginsIfMissing(instanceRoot) {
|
|
34664
|
-
const pluginsPath =
|
|
34890
|
+
const pluginsPath = path60.join(instanceRoot, "plugins.json");
|
|
34665
34891
|
if (!fs51.existsSync(pluginsPath)) {
|
|
34666
34892
|
fs51.writeFileSync(pluginsPath, JSON.stringify({ version: 1, installed: {} }, null, 2));
|
|
34667
34893
|
}
|
|
@@ -34672,7 +34898,7 @@ init_status();
|
|
|
34672
34898
|
init_output();
|
|
34673
34899
|
init_helpers();
|
|
34674
34900
|
async function buildInstanceListEntries() {
|
|
34675
|
-
const registryPath =
|
|
34901
|
+
const registryPath = path61.join(getGlobalRoot(), "instances.json");
|
|
34676
34902
|
const registry = new InstanceRegistry(registryPath);
|
|
34677
34903
|
registry.load();
|
|
34678
34904
|
const entries = registry.list();
|
|
@@ -34682,7 +34908,7 @@ async function buildInstanceListEntries() {
|
|
|
34682
34908
|
return {
|
|
34683
34909
|
id: entry.id,
|
|
34684
34910
|
name: info.name,
|
|
34685
|
-
directory:
|
|
34911
|
+
directory: path61.dirname(entry.root),
|
|
34686
34912
|
root: entry.root,
|
|
34687
34913
|
status,
|
|
34688
34914
|
port: info.apiPort
|
|
@@ -34775,9 +35001,9 @@ async function cmdInstancesCreate(args2) {
|
|
|
34775
35001
|
const agentIdx = args2.indexOf("--agent");
|
|
34776
35002
|
const agent = agentIdx !== -1 ? args2[agentIdx + 1] : void 0;
|
|
34777
35003
|
const noInteractive = args2.includes("--no-interactive");
|
|
34778
|
-
const resolvedDir =
|
|
34779
|
-
const instanceRoot =
|
|
34780
|
-
const registryPath =
|
|
35004
|
+
const resolvedDir = path61.resolve(rawDir.replace(/^~/, os13.homedir()));
|
|
35005
|
+
const instanceRoot = path61.join(resolvedDir, ".openacp");
|
|
35006
|
+
const registryPath = path61.join(getGlobalRoot(), "instances.json");
|
|
34781
35007
|
const registry = new InstanceRegistry(registryPath);
|
|
34782
35008
|
registry.load();
|
|
34783
35009
|
if (fs52.existsSync(instanceRoot)) {
|
|
@@ -34802,8 +35028,8 @@ async function cmdInstancesCreate(args2) {
|
|
|
34802
35028
|
const name = instanceName ?? `openacp-${registry.list().length + 1}`;
|
|
34803
35029
|
const id = randomUUID6();
|
|
34804
35030
|
if (rawFrom) {
|
|
34805
|
-
const fromRoot =
|
|
34806
|
-
if (!fs52.existsSync(
|
|
35031
|
+
const fromRoot = path61.join(path61.resolve(rawFrom.replace(/^~/, os13.homedir())), ".openacp");
|
|
35032
|
+
if (!fs52.existsSync(path61.join(fromRoot, "config.json"))) {
|
|
34807
35033
|
console.error(`Error: No OpenACP instance found at ${rawFrom}`);
|
|
34808
35034
|
process.exit(1);
|
|
34809
35035
|
}
|
|
@@ -34827,7 +35053,7 @@ async function outputInstance(json, { id, root }) {
|
|
|
34827
35053
|
const entry = {
|
|
34828
35054
|
id,
|
|
34829
35055
|
name: info.name,
|
|
34830
|
-
directory:
|
|
35056
|
+
directory: path61.dirname(root),
|
|
34831
35057
|
root,
|
|
34832
35058
|
status: info.pid ? "running" : "stopped",
|
|
34833
35059
|
port: info.apiPort
|
|
@@ -34836,7 +35062,7 @@ async function outputInstance(json, { id, root }) {
|
|
|
34836
35062
|
jsonSuccess(entry);
|
|
34837
35063
|
return;
|
|
34838
35064
|
}
|
|
34839
|
-
console.log(`Instance created: ${info.name ?? id} at ${
|
|
35065
|
+
console.log(`Instance created: ${info.name ?? id} at ${path61.dirname(root)}`);
|
|
34840
35066
|
}
|
|
34841
35067
|
|
|
34842
35068
|
// src/cli/commands/integrate.ts
|
|
@@ -35597,15 +35823,15 @@ Options:
|
|
|
35597
35823
|
}
|
|
35598
35824
|
|
|
35599
35825
|
// src/cli/commands/onboard.ts
|
|
35600
|
-
import * as
|
|
35826
|
+
import * as path62 from "path";
|
|
35601
35827
|
async function cmdOnboard(instanceRoot) {
|
|
35602
35828
|
const { ConfigManager: ConfigManager2 } = await Promise.resolve().then(() => (init_config2(), config_exports));
|
|
35603
35829
|
const { SettingsManager: SettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
|
|
35604
35830
|
const { PluginRegistry: PluginRegistry2 } = await Promise.resolve().then(() => (init_plugin_registry(), plugin_registry_exports));
|
|
35605
35831
|
const OPENACP_DIR = instanceRoot;
|
|
35606
|
-
const PLUGINS_DATA_DIR =
|
|
35607
|
-
const REGISTRY_PATH =
|
|
35608
|
-
const cm = new ConfigManager2(
|
|
35832
|
+
const PLUGINS_DATA_DIR = path62.join(OPENACP_DIR, "plugins", "data");
|
|
35833
|
+
const REGISTRY_PATH = path62.join(OPENACP_DIR, "plugins.json");
|
|
35834
|
+
const cm = new ConfigManager2(path62.join(OPENACP_DIR, "config.json"));
|
|
35609
35835
|
const settingsManager = new SettingsManager2(PLUGINS_DATA_DIR);
|
|
35610
35836
|
const pluginRegistry = new PluginRegistry2(REGISTRY_PATH);
|
|
35611
35837
|
await pluginRegistry.load();
|
|
@@ -35625,15 +35851,15 @@ init_instance_registry();
|
|
|
35625
35851
|
init_instance_hint();
|
|
35626
35852
|
init_output();
|
|
35627
35853
|
init_resolve_instance_id();
|
|
35628
|
-
import
|
|
35854
|
+
import path63 from "path";
|
|
35629
35855
|
import { randomUUID as randomUUID7 } from "crypto";
|
|
35630
35856
|
async function cmdDefault(command2, instanceRoot) {
|
|
35631
35857
|
const args2 = command2 ? [command2] : [];
|
|
35632
35858
|
const json = isJsonMode(args2);
|
|
35633
35859
|
if (json) await muteForJson();
|
|
35634
35860
|
const root = instanceRoot;
|
|
35635
|
-
const pluginsDataDir =
|
|
35636
|
-
const registryPath =
|
|
35861
|
+
const pluginsDataDir = path63.join(root, "plugins", "data");
|
|
35862
|
+
const registryPath = path63.join(root, "plugins.json");
|
|
35637
35863
|
const forceForeground = command2 === "--foreground";
|
|
35638
35864
|
if (command2 && !command2.startsWith("-")) {
|
|
35639
35865
|
const { suggestMatch: suggestMatch2 } = await Promise.resolve().then(() => (init_suggest(), suggest_exports));
|
|
@@ -35665,7 +35891,7 @@ async function cmdDefault(command2, instanceRoot) {
|
|
|
35665
35891
|
}
|
|
35666
35892
|
await checkAndPromptUpdate();
|
|
35667
35893
|
const { ConfigManager: ConfigManager2 } = await Promise.resolve().then(() => (init_config2(), config_exports));
|
|
35668
|
-
const configPath =
|
|
35894
|
+
const configPath = path63.join(root, "config.json");
|
|
35669
35895
|
const cm = new ConfigManager2(configPath);
|
|
35670
35896
|
if (!await cm.exists()) {
|
|
35671
35897
|
const { SettingsManager: SettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
|
|
@@ -35702,12 +35928,12 @@ async function cmdDefault(command2, instanceRoot) {
|
|
|
35702
35928
|
}
|
|
35703
35929
|
if (json) {
|
|
35704
35930
|
const { waitForPortFile: waitForPortFile2 } = await Promise.resolve().then(() => (init_api_client(), api_client_exports));
|
|
35705
|
-
const port = await waitForPortFile2(
|
|
35931
|
+
const port = await waitForPortFile2(path63.join(root, "api.port")) ?? 21420;
|
|
35706
35932
|
jsonSuccess({
|
|
35707
35933
|
pid: result.pid,
|
|
35708
35934
|
instanceId: instanceId2,
|
|
35709
35935
|
name: config.instanceName ?? null,
|
|
35710
|
-
directory:
|
|
35936
|
+
directory: path63.dirname(root),
|
|
35711
35937
|
dir: root,
|
|
35712
35938
|
port
|
|
35713
35939
|
});
|
|
@@ -35720,7 +35946,7 @@ async function cmdDefault(command2, instanceRoot) {
|
|
|
35720
35946
|
markRunning2(root);
|
|
35721
35947
|
printInstanceHint(root);
|
|
35722
35948
|
const { startServer: startServer2 } = await Promise.resolve().then(() => (init_main(), main_exports));
|
|
35723
|
-
const reg = new InstanceRegistry(
|
|
35949
|
+
const reg = new InstanceRegistry(path63.join(getGlobalRoot(), "instances.json"));
|
|
35724
35950
|
reg.load();
|
|
35725
35951
|
const existingEntry = reg.getByRoot(root);
|
|
35726
35952
|
const instanceId = existingEntry?.id ?? randomUUID7();
|
|
@@ -35734,7 +35960,7 @@ async function cmdDefault(command2, instanceRoot) {
|
|
|
35734
35960
|
pid: process.pid,
|
|
35735
35961
|
instanceId,
|
|
35736
35962
|
name: config.instanceName ?? null,
|
|
35737
|
-
directory:
|
|
35963
|
+
directory: path63.dirname(root),
|
|
35738
35964
|
dir: root,
|
|
35739
35965
|
port
|
|
35740
35966
|
});
|
|
@@ -35803,7 +36029,7 @@ async function showAlreadyRunningMenu(root) {
|
|
|
35803
36029
|
// src/cli/commands/dev.ts
|
|
35804
36030
|
init_helpers();
|
|
35805
36031
|
import fs53 from "fs";
|
|
35806
|
-
import
|
|
36032
|
+
import path64 from "path";
|
|
35807
36033
|
async function cmdDev(args2 = []) {
|
|
35808
36034
|
if (wantsHelp(args2)) {
|
|
35809
36035
|
console.log(`
|
|
@@ -35830,12 +36056,12 @@ async function cmdDev(args2 = []) {
|
|
|
35830
36056
|
console.error("Error: missing plugin path. Usage: openacp dev <plugin-path>");
|
|
35831
36057
|
process.exit(1);
|
|
35832
36058
|
}
|
|
35833
|
-
const pluginPath =
|
|
36059
|
+
const pluginPath = path64.resolve(pluginPathArg);
|
|
35834
36060
|
if (!fs53.existsSync(pluginPath)) {
|
|
35835
36061
|
console.error(`Error: plugin path does not exist: ${pluginPath}`);
|
|
35836
36062
|
process.exit(1);
|
|
35837
36063
|
}
|
|
35838
|
-
const tsconfigPath =
|
|
36064
|
+
const tsconfigPath = path64.join(pluginPath, "tsconfig.json");
|
|
35839
36065
|
const hasTsconfig = fs53.existsSync(tsconfigPath);
|
|
35840
36066
|
if (hasTsconfig) {
|
|
35841
36067
|
console.log("Compiling plugin TypeScript...");
|
|
@@ -35877,7 +36103,7 @@ async function cmdDev(args2 = []) {
|
|
|
35877
36103
|
|
|
35878
36104
|
// src/cli/commands/attach.ts
|
|
35879
36105
|
init_helpers();
|
|
35880
|
-
import
|
|
36106
|
+
import path65 from "path";
|
|
35881
36107
|
async function cmdAttach(args2 = [], instanceRoot) {
|
|
35882
36108
|
const root = instanceRoot;
|
|
35883
36109
|
if (wantsHelp(args2)) {
|
|
@@ -35913,15 +36139,15 @@ Press Ctrl+C to detach.
|
|
|
35913
36139
|
console.log("");
|
|
35914
36140
|
const { spawn: spawn9 } = await import("child_process");
|
|
35915
36141
|
const { expandHome: expandHome4 } = await Promise.resolve().then(() => (init_config2(), config_exports));
|
|
35916
|
-
let logDir2 =
|
|
36142
|
+
let logDir2 = path65.join(root, "logs");
|
|
35917
36143
|
try {
|
|
35918
|
-
const configPath =
|
|
36144
|
+
const configPath = path65.join(root, "config.json");
|
|
35919
36145
|
const { readFileSync: readFileSync18 } = await import("fs");
|
|
35920
36146
|
const config = JSON.parse(readFileSync18(configPath, "utf-8"));
|
|
35921
36147
|
if (config.logging?.logDir) logDir2 = expandHome4(config.logging.logDir);
|
|
35922
36148
|
} catch {
|
|
35923
36149
|
}
|
|
35924
|
-
const logFile =
|
|
36150
|
+
const logFile = path65.join(logDir2, "openacp.log");
|
|
35925
36151
|
const tail = spawn9("tail", ["-f", "-n", "50", logFile], { stdio: "inherit" });
|
|
35926
36152
|
tail.on("error", (err) => {
|
|
35927
36153
|
console.error(`Cannot tail log file: ${err.message}`);
|
|
@@ -35933,7 +36159,7 @@ Press Ctrl+C to detach.
|
|
|
35933
36159
|
init_api_client();
|
|
35934
36160
|
init_instance_registry();
|
|
35935
36161
|
init_output();
|
|
35936
|
-
import
|
|
36162
|
+
import path66 from "path";
|
|
35937
36163
|
import os14 from "os";
|
|
35938
36164
|
import qrcode from "qrcode-terminal";
|
|
35939
36165
|
async function cmdRemote(args2, instanceRoot) {
|
|
@@ -35949,7 +36175,7 @@ async function cmdRemote(args2, instanceRoot) {
|
|
|
35949
36175
|
const scopes = scopesRaw ? scopesRaw.split(",").map((s) => s.trim()) : void 0;
|
|
35950
36176
|
let resolvedInstanceRoot2 = instanceRoot;
|
|
35951
36177
|
if (instanceId) {
|
|
35952
|
-
const registryPath =
|
|
36178
|
+
const registryPath = path66.join(os14.homedir(), ".openacp", "instances.json");
|
|
35953
36179
|
const registry = new InstanceRegistry(registryPath);
|
|
35954
36180
|
await registry.load();
|
|
35955
36181
|
const entry = registry.get(instanceId);
|
|
@@ -36088,7 +36314,7 @@ function extractFlag(args2, flag) {
|
|
|
36088
36314
|
init_output();
|
|
36089
36315
|
init_instance_context();
|
|
36090
36316
|
init_instance_registry();
|
|
36091
|
-
import * as
|
|
36317
|
+
import * as path67 from "path";
|
|
36092
36318
|
import fs54 from "fs";
|
|
36093
36319
|
function parseFlag(args2, flag) {
|
|
36094
36320
|
const idx = args2.indexOf(flag);
|
|
@@ -36096,7 +36322,7 @@ function parseFlag(args2, flag) {
|
|
|
36096
36322
|
}
|
|
36097
36323
|
function readConfigField(instanceRoot, field) {
|
|
36098
36324
|
try {
|
|
36099
|
-
const raw = JSON.parse(fs54.readFileSync(
|
|
36325
|
+
const raw = JSON.parse(fs54.readFileSync(path67.join(instanceRoot, "config.json"), "utf-8"));
|
|
36100
36326
|
return typeof raw[field] === "string" ? raw[field] : null;
|
|
36101
36327
|
} catch {
|
|
36102
36328
|
return null;
|
|
@@ -36119,7 +36345,7 @@ async function cmdSetup(args2, instanceRoot) {
|
|
|
36119
36345
|
}
|
|
36120
36346
|
const runMode = rawRunMode;
|
|
36121
36347
|
const agents = agentRaw.split(",").map((a) => a.trim());
|
|
36122
|
-
const registryPath =
|
|
36348
|
+
const registryPath = path67.join(getGlobalRoot(), "instances.json");
|
|
36123
36349
|
const registry = new InstanceRegistry(registryPath);
|
|
36124
36350
|
registry.load();
|
|
36125
36351
|
const { id, registryUpdated } = registry.resolveId(instanceRoot);
|
|
@@ -36127,9 +36353,9 @@ async function cmdSetup(args2, instanceRoot) {
|
|
|
36127
36353
|
if (registryUpdated) {
|
|
36128
36354
|
registry.save();
|
|
36129
36355
|
}
|
|
36130
|
-
const name = readConfigField(instanceRoot, "instanceName") ??
|
|
36356
|
+
const name = readConfigField(instanceRoot, "instanceName") ?? path67.basename(path67.dirname(instanceRoot));
|
|
36131
36357
|
if (!readConfigField(instanceRoot, "instanceName")) {
|
|
36132
|
-
const configPath =
|
|
36358
|
+
const configPath = path67.join(instanceRoot, "config.json");
|
|
36133
36359
|
try {
|
|
36134
36360
|
const raw = JSON.parse(fs54.readFileSync(configPath, "utf-8"));
|
|
36135
36361
|
raw.instanceName = name;
|
|
@@ -36138,17 +36364,17 @@ async function cmdSetup(args2, instanceRoot) {
|
|
|
36138
36364
|
}
|
|
36139
36365
|
}
|
|
36140
36366
|
if (json) {
|
|
36141
|
-
jsonSuccess({ id, name, directory:
|
|
36367
|
+
jsonSuccess({ id, name, directory: path67.dirname(instanceRoot), configPath: path67.join(instanceRoot, "config.json") });
|
|
36142
36368
|
} else {
|
|
36143
36369
|
console.log(`
|
|
36144
|
-
\x1B[32m\u2713 Setup complete.\x1B[0m Config written to ${
|
|
36370
|
+
\x1B[32m\u2713 Setup complete.\x1B[0m Config written to ${path67.join(instanceRoot, "config.json")}
|
|
36145
36371
|
`);
|
|
36146
36372
|
}
|
|
36147
36373
|
}
|
|
36148
36374
|
|
|
36149
36375
|
// src/cli/commands/autostart.ts
|
|
36150
36376
|
init_helpers();
|
|
36151
|
-
import
|
|
36377
|
+
import path68 from "path";
|
|
36152
36378
|
async function cmdAutostart(args2 = [], instanceRoot) {
|
|
36153
36379
|
const subcommand = args2[0];
|
|
36154
36380
|
if (!subcommand || wantsHelp(args2)) {
|
|
@@ -36186,7 +36412,7 @@ async function cmdAutostart(args2 = [], instanceRoot) {
|
|
|
36186
36412
|
let logDir2 = `${root}/logs`;
|
|
36187
36413
|
try {
|
|
36188
36414
|
const { ConfigManager: ConfigManager2 } = await Promise.resolve().then(() => (init_config2(), config_exports));
|
|
36189
|
-
const cm = new ConfigManager2(
|
|
36415
|
+
const cm = new ConfigManager2(path68.join(root, "config.json"));
|
|
36190
36416
|
if (await cm.exists()) {
|
|
36191
36417
|
await cm.load();
|
|
36192
36418
|
logDir2 = cm.get().logging?.logDir ?? logDir2;
|
|
@@ -36374,7 +36600,7 @@ async function main() {
|
|
|
36374
36600
|
if (envRoot) {
|
|
36375
36601
|
const { createInstanceContext: createInstanceContext2, getGlobalRoot: getGlobal } = await Promise.resolve().then(() => (init_instance_context(), instance_context_exports));
|
|
36376
36602
|
const { InstanceRegistry: InstanceRegistry2 } = await Promise.resolve().then(() => (init_instance_registry(), instance_registry_exports));
|
|
36377
|
-
const registry = new InstanceRegistry2(
|
|
36603
|
+
const registry = new InstanceRegistry2(path71.join(getGlobal(), "instances.json"));
|
|
36378
36604
|
await registry.load();
|
|
36379
36605
|
const entry = registry.getByRoot(envRoot);
|
|
36380
36606
|
const { randomUUID: randomUUID9 } = await import("crypto");
|