@n1creator/openacp-cli 2026.712.4 → 2026.712.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cli.js +716 -498
- 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",
|
|
@@ -10100,7 +10323,7 @@ var init_config = __esm({
|
|
|
10100
10323
|
|
|
10101
10324
|
// src/core/config/config-migrations.ts
|
|
10102
10325
|
import fs18 from "fs";
|
|
10103
|
-
import
|
|
10326
|
+
import path22 from "path";
|
|
10104
10327
|
import os4 from "os";
|
|
10105
10328
|
function applyMigrations(raw, migrationList = migrations, ctx) {
|
|
10106
10329
|
let changed = false;
|
|
@@ -10150,7 +10373,7 @@ var init_config_migrations = __esm({
|
|
|
10150
10373
|
if (!ctx?.configDir) return false;
|
|
10151
10374
|
const instanceRoot = ctx.configDir;
|
|
10152
10375
|
try {
|
|
10153
|
-
const registryPath =
|
|
10376
|
+
const registryPath = path22.join(os4.homedir(), ".openacp", "instances.json");
|
|
10154
10377
|
const data = JSON.parse(fs18.readFileSync(registryPath, "utf-8"));
|
|
10155
10378
|
const instances = data?.instances ?? {};
|
|
10156
10379
|
const entry = Object.values(instances).find(
|
|
@@ -10179,13 +10402,13 @@ __export(config_exports, {
|
|
|
10179
10402
|
});
|
|
10180
10403
|
import { z as z4 } from "zod";
|
|
10181
10404
|
import * as fs19 from "fs";
|
|
10182
|
-
import * as
|
|
10405
|
+
import * as path23 from "path";
|
|
10183
10406
|
import * as os5 from "os";
|
|
10184
10407
|
import { randomBytes as randomBytes3 } from "crypto";
|
|
10185
10408
|
import { EventEmitter } from "events";
|
|
10186
10409
|
function expandHome2(p2) {
|
|
10187
10410
|
if (p2.startsWith("~")) {
|
|
10188
|
-
return
|
|
10411
|
+
return path23.join(os5.homedir(), p2.slice(1));
|
|
10189
10412
|
}
|
|
10190
10413
|
return p2;
|
|
10191
10414
|
}
|
|
@@ -10259,7 +10482,7 @@ var init_config2 = __esm({
|
|
|
10259
10482
|
* 4. Validate against Zod schema — exits on failure
|
|
10260
10483
|
*/
|
|
10261
10484
|
async load() {
|
|
10262
|
-
const dir =
|
|
10485
|
+
const dir = path23.dirname(this.configPath);
|
|
10263
10486
|
fs19.mkdirSync(dir, { recursive: true });
|
|
10264
10487
|
if (!fs19.existsSync(this.configPath)) {
|
|
10265
10488
|
fs19.writeFileSync(
|
|
@@ -10273,7 +10496,7 @@ var init_config2 = __esm({
|
|
|
10273
10496
|
process.exit(1);
|
|
10274
10497
|
}
|
|
10275
10498
|
const raw = JSON.parse(fs19.readFileSync(this.configPath, "utf-8"));
|
|
10276
|
-
const { changed: configUpdated } = applyMigrations(raw, void 0, { configDir:
|
|
10499
|
+
const { changed: configUpdated } = applyMigrations(raw, void 0, { configDir: path23.dirname(this.configPath) });
|
|
10277
10500
|
if (configUpdated) {
|
|
10278
10501
|
fs19.writeFileSync(this.configPath, JSON.stringify(raw, null, 2));
|
|
10279
10502
|
}
|
|
@@ -10353,16 +10576,16 @@ var init_config2 = __esm({
|
|
|
10353
10576
|
* (alphanumeric subdirectories under the base).
|
|
10354
10577
|
*/
|
|
10355
10578
|
resolveWorkspace(input2) {
|
|
10356
|
-
const workspaceBase =
|
|
10579
|
+
const workspaceBase = path23.dirname(path23.dirname(this.configPath));
|
|
10357
10580
|
if (!input2) {
|
|
10358
10581
|
fs19.mkdirSync(workspaceBase, { recursive: true });
|
|
10359
10582
|
return workspaceBase;
|
|
10360
10583
|
}
|
|
10361
10584
|
const expanded = input2.startsWith("~") ? expandHome2(input2) : input2;
|
|
10362
|
-
if (
|
|
10363
|
-
const resolved =
|
|
10364
|
-
const base =
|
|
10365
|
-
const isInternal = resolved === base || resolved.startsWith(base +
|
|
10585
|
+
if (path23.isAbsolute(expanded)) {
|
|
10586
|
+
const resolved = path23.resolve(expanded);
|
|
10587
|
+
const base = path23.resolve(workspaceBase);
|
|
10588
|
+
const isInternal = resolved === base || resolved.startsWith(base + path23.sep);
|
|
10366
10589
|
if (!isInternal) {
|
|
10367
10590
|
if (!this.config.workspace.allowExternalWorkspaces) {
|
|
10368
10591
|
throw new Error(
|
|
@@ -10382,7 +10605,7 @@ var init_config2 = __esm({
|
|
|
10382
10605
|
`Invalid workspace name: "${input2}". Only alphanumeric characters, hyphens, and underscores are allowed.`
|
|
10383
10606
|
);
|
|
10384
10607
|
}
|
|
10385
|
-
const namedPath =
|
|
10608
|
+
const namedPath = path23.join(workspaceBase, input2.toLowerCase());
|
|
10386
10609
|
fs19.mkdirSync(namedPath, { recursive: true });
|
|
10387
10610
|
return namedPath;
|
|
10388
10611
|
}
|
|
@@ -10396,7 +10619,7 @@ var init_config2 = __esm({
|
|
|
10396
10619
|
}
|
|
10397
10620
|
/** Writes a complete config object to disk, creating the directory if needed. Used during initial setup. */
|
|
10398
10621
|
async writeNew(config) {
|
|
10399
|
-
const dir =
|
|
10622
|
+
const dir = path23.dirname(this.configPath);
|
|
10400
10623
|
fs19.mkdirSync(dir, { recursive: true });
|
|
10401
10624
|
fs19.writeFileSync(this.configPath, JSON.stringify(config, null, 2));
|
|
10402
10625
|
}
|
|
@@ -10414,6 +10637,14 @@ var init_config2 = __esm({
|
|
|
10414
10637
|
{ envVar: "OPENACP_API_PORT", pluginName: "@openacp/api-server", key: "port", transform: (v) => Number(v) },
|
|
10415
10638
|
{ envVar: "OPENACP_SPEECH_STT_PROVIDER", pluginName: "@openacp/speech", key: "sttProvider" },
|
|
10416
10639
|
{ envVar: "OPENACP_SPEECH_GROQ_API_KEY", pluginName: "@openacp/speech", key: "groqApiKey" },
|
|
10640
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_LANGUAGE", pluginName: "@openacp/speech", key: "localWhisperLanguage" },
|
|
10641
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_MODEL", pluginName: "@openacp/speech", key: "localWhisperModel" },
|
|
10642
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_BEAM_SIZE", pluginName: "@openacp/speech", key: "localWhisperBeamSize", transform: (v) => Number(v) },
|
|
10643
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_VAD_FILTER", pluginName: "@openacp/speech", key: "localWhisperVadFilter", transform: (v) => v === "true" },
|
|
10644
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_DEVICE", pluginName: "@openacp/speech", key: "localWhisperDevice" },
|
|
10645
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_COMPUTE_TYPE", pluginName: "@openacp/speech", key: "localWhisperComputeType" },
|
|
10646
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_TIMEOUT_MS", pluginName: "@openacp/speech", key: "localWhisperTimeoutMs", transform: (v) => Number(v) },
|
|
10647
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_SCRIPT_PATH", pluginName: "@openacp/speech", key: "localWhisperScriptPath" },
|
|
10417
10648
|
{ envVar: "OPENACP_TELEGRAM_BOT_TOKEN", pluginName: "@openacp/telegram", key: "botToken" },
|
|
10418
10649
|
{ envVar: "OPENACP_TELEGRAM_CHAT_ID", pluginName: "@openacp/telegram", key: "chatId", transform: (v) => Number(v) },
|
|
10419
10650
|
// Future adapters — no-ops if plugin settings don't exist
|
|
@@ -11131,7 +11362,7 @@ var plugins_exports = {};
|
|
|
11131
11362
|
__export(plugins_exports, {
|
|
11132
11363
|
pluginRoutes: () => pluginRoutes
|
|
11133
11364
|
});
|
|
11134
|
-
import
|
|
11365
|
+
import path24 from "path";
|
|
11135
11366
|
async function pluginRoutes(app, deps) {
|
|
11136
11367
|
const { lifecycleManager } = deps;
|
|
11137
11368
|
const admin = [requireScopes("system:admin")];
|
|
@@ -11196,7 +11427,7 @@ async function pluginRoutes(app, deps) {
|
|
|
11196
11427
|
} else {
|
|
11197
11428
|
const { importFromDir: importFromDir2 } = await Promise.resolve().then(() => (init_plugin_installer(), plugin_installer_exports));
|
|
11198
11429
|
const instanceRoot = lifecycleManager.instanceRoot;
|
|
11199
|
-
const pluginsDir =
|
|
11430
|
+
const pluginsDir = path24.join(instanceRoot, "plugins");
|
|
11200
11431
|
try {
|
|
11201
11432
|
const mod = await importFromDir2(name, pluginsDir);
|
|
11202
11433
|
pluginDef = mod.default ?? mod;
|
|
@@ -11272,11 +11503,11 @@ __export(instance_registry_exports, {
|
|
|
11272
11503
|
readIdFromConfig: () => readIdFromConfig
|
|
11273
11504
|
});
|
|
11274
11505
|
import fs20 from "fs";
|
|
11275
|
-
import
|
|
11506
|
+
import path25 from "path";
|
|
11276
11507
|
import { randomUUID } from "crypto";
|
|
11277
11508
|
function readIdFromConfig(instanceRoot) {
|
|
11278
11509
|
try {
|
|
11279
|
-
const raw = JSON.parse(fs20.readFileSync(
|
|
11510
|
+
const raw = JSON.parse(fs20.readFileSync(path25.join(instanceRoot, "config.json"), "utf-8"));
|
|
11280
11511
|
return typeof raw.id === "string" && raw.id ? raw.id : null;
|
|
11281
11512
|
} catch {
|
|
11282
11513
|
return null;
|
|
@@ -11322,7 +11553,7 @@ var init_instance_registry = __esm({
|
|
|
11322
11553
|
}
|
|
11323
11554
|
/** Persist the registry to disk, creating parent directories if needed. */
|
|
11324
11555
|
save() {
|
|
11325
|
-
const dir =
|
|
11556
|
+
const dir = path25.dirname(this.registryPath);
|
|
11326
11557
|
fs20.mkdirSync(dir, { recursive: true });
|
|
11327
11558
|
fs20.writeFileSync(this.registryPath, JSON.stringify(this.data, null, 2));
|
|
11328
11559
|
}
|
|
@@ -11392,7 +11623,7 @@ __export(instance_context_exports, {
|
|
|
11392
11623
|
resolveInstanceRoot: () => resolveInstanceRoot,
|
|
11393
11624
|
resolveRunningInstance: () => resolveRunningInstance
|
|
11394
11625
|
});
|
|
11395
|
-
import
|
|
11626
|
+
import path26 from "path";
|
|
11396
11627
|
import fs21 from "fs";
|
|
11397
11628
|
import os6 from "os";
|
|
11398
11629
|
function createInstanceContext(opts) {
|
|
@@ -11402,22 +11633,22 @@ function createInstanceContext(opts) {
|
|
|
11402
11633
|
id,
|
|
11403
11634
|
root,
|
|
11404
11635
|
paths: {
|
|
11405
|
-
config:
|
|
11406
|
-
sessions:
|
|
11407
|
-
agents:
|
|
11408
|
-
registryCache:
|
|
11409
|
-
plugins:
|
|
11410
|
-
pluginsData:
|
|
11411
|
-
pluginRegistry:
|
|
11412
|
-
logs:
|
|
11413
|
-
pid:
|
|
11414
|
-
running:
|
|
11415
|
-
apiPort:
|
|
11416
|
-
apiSecret:
|
|
11417
|
-
bin:
|
|
11418
|
-
cache:
|
|
11419
|
-
tunnels:
|
|
11420
|
-
agentsDir:
|
|
11636
|
+
config: path26.join(root, "config.json"),
|
|
11637
|
+
sessions: path26.join(root, "sessions.json"),
|
|
11638
|
+
agents: path26.join(root, "agents.json"),
|
|
11639
|
+
registryCache: path26.join(globalRoot, "cache", "registry-cache.json"),
|
|
11640
|
+
plugins: path26.join(root, "plugins"),
|
|
11641
|
+
pluginsData: path26.join(root, "plugins", "data"),
|
|
11642
|
+
pluginRegistry: path26.join(root, "plugins.json"),
|
|
11643
|
+
logs: path26.join(root, "logs"),
|
|
11644
|
+
pid: path26.join(root, "openacp.pid"),
|
|
11645
|
+
running: path26.join(root, "running"),
|
|
11646
|
+
apiPort: path26.join(root, "api.port"),
|
|
11647
|
+
apiSecret: path26.join(root, "api-secret"),
|
|
11648
|
+
bin: path26.join(globalRoot, "bin"),
|
|
11649
|
+
cache: path26.join(root, "cache"),
|
|
11650
|
+
tunnels: path26.join(root, "tunnels.json"),
|
|
11651
|
+
agentsDir: path26.join(globalRoot, "agents")
|
|
11421
11652
|
}
|
|
11422
11653
|
};
|
|
11423
11654
|
}
|
|
@@ -11426,50 +11657,50 @@ function generateSlug(name) {
|
|
|
11426
11657
|
return slug || "openacp";
|
|
11427
11658
|
}
|
|
11428
11659
|
function expandHome3(p2) {
|
|
11429
|
-
if (p2.startsWith("~")) return
|
|
11660
|
+
if (p2.startsWith("~")) return path26.join(os6.homedir(), p2.slice(1));
|
|
11430
11661
|
return p2;
|
|
11431
11662
|
}
|
|
11432
11663
|
function resolveInstanceRoot(opts) {
|
|
11433
11664
|
const cwd = opts.cwd ?? process.cwd();
|
|
11434
11665
|
const home = os6.homedir();
|
|
11435
11666
|
const globalRoot = getGlobalRoot();
|
|
11436
|
-
if (opts.dir) return
|
|
11437
|
-
if (opts.local) return
|
|
11438
|
-
const cwdRoot =
|
|
11439
|
-
if (fs21.existsSync(
|
|
11440
|
-
let dir =
|
|
11667
|
+
if (opts.dir) return path26.join(expandHome3(opts.dir), ".openacp");
|
|
11668
|
+
if (opts.local) return path26.join(cwd, ".openacp");
|
|
11669
|
+
const cwdRoot = path26.join(cwd, ".openacp");
|
|
11670
|
+
if (fs21.existsSync(path26.join(cwdRoot, "config.json"))) return cwdRoot;
|
|
11671
|
+
let dir = path26.resolve(cwd);
|
|
11441
11672
|
while (true) {
|
|
11442
|
-
const parent =
|
|
11673
|
+
const parent = path26.dirname(dir);
|
|
11443
11674
|
if (parent === dir) break;
|
|
11444
11675
|
dir = parent;
|
|
11445
|
-
const candidate =
|
|
11676
|
+
const candidate = path26.join(dir, ".openacp");
|
|
11446
11677
|
if (candidate === globalRoot) {
|
|
11447
11678
|
if (dir === home) break;
|
|
11448
11679
|
continue;
|
|
11449
11680
|
}
|
|
11450
|
-
if (fs21.existsSync(
|
|
11681
|
+
if (fs21.existsSync(path26.join(candidate, "config.json"))) return candidate;
|
|
11451
11682
|
if (dir === home) break;
|
|
11452
11683
|
}
|
|
11453
|
-
if (
|
|
11454
|
-
const defaultWs =
|
|
11455
|
-
if (fs21.existsSync(
|
|
11684
|
+
if (path26.resolve(cwd) === path26.resolve(home)) {
|
|
11685
|
+
const defaultWs = path26.join(home, "openacp-workspace", ".openacp");
|
|
11686
|
+
if (fs21.existsSync(path26.join(defaultWs, "config.json"))) return defaultWs;
|
|
11456
11687
|
}
|
|
11457
11688
|
if (process.env.OPENACP_INSTANCE_ROOT) return process.env.OPENACP_INSTANCE_ROOT;
|
|
11458
11689
|
return null;
|
|
11459
11690
|
}
|
|
11460
11691
|
function getGlobalRoot() {
|
|
11461
|
-
return
|
|
11692
|
+
return path26.join(os6.homedir(), ".openacp");
|
|
11462
11693
|
}
|
|
11463
11694
|
async function resolveRunningInstance(cwd) {
|
|
11464
11695
|
const globalRoot = getGlobalRoot();
|
|
11465
11696
|
const home = os6.homedir();
|
|
11466
|
-
let dir =
|
|
11697
|
+
let dir = path26.resolve(cwd);
|
|
11467
11698
|
while (true) {
|
|
11468
|
-
const candidate =
|
|
11699
|
+
const candidate = path26.join(dir, ".openacp");
|
|
11469
11700
|
if (candidate !== globalRoot && fs21.existsSync(candidate)) {
|
|
11470
11701
|
if (await isInstanceRunning(candidate)) return candidate;
|
|
11471
11702
|
}
|
|
11472
|
-
const parent =
|
|
11703
|
+
const parent = path26.dirname(dir);
|
|
11473
11704
|
if (parent === dir) break;
|
|
11474
11705
|
if (dir === home) break;
|
|
11475
11706
|
dir = parent;
|
|
@@ -11477,7 +11708,7 @@ async function resolveRunningInstance(cwd) {
|
|
|
11477
11708
|
return null;
|
|
11478
11709
|
}
|
|
11479
11710
|
async function isInstanceRunning(instanceRoot) {
|
|
11480
|
-
const portFile =
|
|
11711
|
+
const portFile = path26.join(instanceRoot, "api.port");
|
|
11481
11712
|
try {
|
|
11482
11713
|
const content = fs21.readFileSync(portFile, "utf-8").trim();
|
|
11483
11714
|
const port = parseInt(content, 10);
|
|
@@ -11506,14 +11737,14 @@ __export(api_server_exports, {
|
|
|
11506
11737
|
});
|
|
11507
11738
|
import * as fs22 from "fs";
|
|
11508
11739
|
import * as crypto3 from "crypto";
|
|
11509
|
-
import * as
|
|
11740
|
+
import * as path27 from "path";
|
|
11510
11741
|
function getVersion() {
|
|
11511
11742
|
if (cachedVersion) return cachedVersion;
|
|
11512
11743
|
cachedVersion = getCurrentVersion();
|
|
11513
11744
|
return cachedVersion;
|
|
11514
11745
|
}
|
|
11515
11746
|
function loadOrCreateSecret(secretFilePath) {
|
|
11516
|
-
const dir =
|
|
11747
|
+
const dir = path27.dirname(secretFilePath);
|
|
11517
11748
|
fs22.mkdirSync(dir, { recursive: true });
|
|
11518
11749
|
try {
|
|
11519
11750
|
const existing = fs22.readFileSync(secretFilePath, "utf-8").trim();
|
|
@@ -11539,7 +11770,7 @@ function loadOrCreateSecret(secretFilePath) {
|
|
|
11539
11770
|
return secret;
|
|
11540
11771
|
}
|
|
11541
11772
|
function writePortFile(portFilePath, port) {
|
|
11542
|
-
const dir =
|
|
11773
|
+
const dir = path27.dirname(portFilePath);
|
|
11543
11774
|
fs22.mkdirSync(dir, { recursive: true });
|
|
11544
11775
|
fs22.writeFileSync(portFilePath, String(port));
|
|
11545
11776
|
}
|
|
@@ -11624,10 +11855,10 @@ function createApiServerPlugin() {
|
|
|
11624
11855
|
{ port: apiConfig.port, host: apiConfig.host, instanceRoot },
|
|
11625
11856
|
"API server plugin setup \u2014 config loaded"
|
|
11626
11857
|
);
|
|
11627
|
-
portFilePath =
|
|
11628
|
-
const secretFilePath =
|
|
11629
|
-
const jwtSecretFilePath =
|
|
11630
|
-
const tokensFilePath =
|
|
11858
|
+
portFilePath = path27.join(instanceRoot, "api.port");
|
|
11859
|
+
const secretFilePath = path27.join(instanceRoot, "api-secret");
|
|
11860
|
+
const jwtSecretFilePath = path27.join(instanceRoot, "jwt-secret");
|
|
11861
|
+
const tokensFilePath = path27.join(instanceRoot, "tokens.json");
|
|
11631
11862
|
const startedAt = Date.now();
|
|
11632
11863
|
const secret = loadOrCreateSecret(secretFilePath);
|
|
11633
11864
|
const jwtSecret = loadOrCreateSecret(jwtSecretFilePath);
|
|
@@ -11666,7 +11897,7 @@ function createApiServerPlugin() {
|
|
|
11666
11897
|
const { InstanceRegistry: InstanceRegistry2 } = await Promise.resolve().then(() => (init_instance_registry(), instance_registry_exports));
|
|
11667
11898
|
const { getGlobalRoot: getGlobalRoot2 } = await Promise.resolve().then(() => (init_instance_context(), instance_context_exports));
|
|
11668
11899
|
const globalRoot = getGlobalRoot2();
|
|
11669
|
-
const instanceReg = new InstanceRegistry2(
|
|
11900
|
+
const instanceReg = new InstanceRegistry2(path27.join(globalRoot, "instances.json"));
|
|
11670
11901
|
instanceReg.load();
|
|
11671
11902
|
const instanceEntry = instanceReg.getByRoot(instanceRoot);
|
|
11672
11903
|
const workspaceId = instanceEntry?.id ?? "main";
|
|
@@ -11698,7 +11929,7 @@ function createApiServerPlugin() {
|
|
|
11698
11929
|
server.registerPlugin("/api/v1/plugins", async (app) => pluginRoutes2(app, deps));
|
|
11699
11930
|
const appConfig = core.configManager.get();
|
|
11700
11931
|
const workspaceName = appConfig.instanceName ?? "Main";
|
|
11701
|
-
const workspaceDir =
|
|
11932
|
+
const workspaceDir = path27.dirname(instanceRoot);
|
|
11702
11933
|
server.registerPlugin("/api/v1", async (app) => {
|
|
11703
11934
|
await app.register(workspaceRoute2, {
|
|
11704
11935
|
id: workspaceId,
|
|
@@ -12792,8 +13023,8 @@ function formatToolSummary(name, rawInput, displaySummary) {
|
|
|
12792
13023
|
}
|
|
12793
13024
|
if (lowerName === "grep") {
|
|
12794
13025
|
const pattern = args2.pattern ?? "";
|
|
12795
|
-
const
|
|
12796
|
-
return pattern ? `\u{1F50D} Grep "${pattern}"${
|
|
13026
|
+
const path72 = args2.path ?? "";
|
|
13027
|
+
return pattern ? `\u{1F50D} Grep "${pattern}"${path72 ? ` in ${path72}` : ""}` : `\u{1F527} ${name}`;
|
|
12797
13028
|
}
|
|
12798
13029
|
if (lowerName === "glob") {
|
|
12799
13030
|
const pattern = args2.pattern ?? "";
|
|
@@ -12829,8 +13060,8 @@ function formatToolTitle(name, rawInput, displayTitle) {
|
|
|
12829
13060
|
}
|
|
12830
13061
|
if (lowerName === "grep") {
|
|
12831
13062
|
const pattern = args2.pattern ?? "";
|
|
12832
|
-
const
|
|
12833
|
-
return pattern ? `"${pattern}"${
|
|
13063
|
+
const path72 = args2.path ?? "";
|
|
13064
|
+
return pattern ? `"${pattern}"${path72 ? ` in ${path72}` : ""}` : name;
|
|
12834
13065
|
}
|
|
12835
13066
|
if (lowerName === "glob") {
|
|
12836
13067
|
return String(args2.pattern ?? name);
|
|
@@ -13973,7 +14204,7 @@ __export(integrate_exports, {
|
|
|
13973
14204
|
listIntegrations: () => listIntegrations,
|
|
13974
14205
|
uninstallIntegration: () => uninstallIntegration
|
|
13975
14206
|
});
|
|
13976
|
-
import { existsSync as
|
|
14207
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync5, unlinkSync as unlinkSync4, chmodSync, rmdirSync } from "fs";
|
|
13977
14208
|
import { join as join10, dirname as dirname7 } from "path";
|
|
13978
14209
|
import { homedir as homedir3 } from "os";
|
|
13979
14210
|
function isHooksIntegrationSpec(spec) {
|
|
@@ -14135,7 +14366,7 @@ function generateOpencodePlugin(spec) {
|
|
|
14135
14366
|
function mergeSettingsJson(settingsPath, hookEvent, hookScriptPath) {
|
|
14136
14367
|
const fullPath = expandPath(settingsPath);
|
|
14137
14368
|
let settings = {};
|
|
14138
|
-
if (
|
|
14369
|
+
if (existsSync7(fullPath)) {
|
|
14139
14370
|
const raw = readFileSync5(fullPath, "utf-8");
|
|
14140
14371
|
writeFileSync5(`${fullPath}.bak`, raw);
|
|
14141
14372
|
settings = JSON.parse(raw);
|
|
@@ -14158,7 +14389,7 @@ function mergeSettingsJson(settingsPath, hookEvent, hookScriptPath) {
|
|
|
14158
14389
|
function mergeHooksJson(settingsPath, hookEvent, hookScriptPath) {
|
|
14159
14390
|
const fullPath = expandPath(settingsPath);
|
|
14160
14391
|
let config = { version: 1 };
|
|
14161
|
-
if (
|
|
14392
|
+
if (existsSync7(fullPath)) {
|
|
14162
14393
|
const raw = readFileSync5(fullPath, "utf-8");
|
|
14163
14394
|
writeFileSync5(`${fullPath}.bak`, raw);
|
|
14164
14395
|
config = JSON.parse(raw);
|
|
@@ -14176,7 +14407,7 @@ function mergeHooksJson(settingsPath, hookEvent, hookScriptPath) {
|
|
|
14176
14407
|
}
|
|
14177
14408
|
function removeFromSettingsJson(settingsPath, hookEvent) {
|
|
14178
14409
|
const fullPath = expandPath(settingsPath);
|
|
14179
|
-
if (!
|
|
14410
|
+
if (!existsSync7(fullPath)) return;
|
|
14180
14411
|
const raw = readFileSync5(fullPath, "utf-8");
|
|
14181
14412
|
const settings = JSON.parse(raw);
|
|
14182
14413
|
const hooks = settings.hooks;
|
|
@@ -14191,7 +14422,7 @@ function removeFromSettingsJson(settingsPath, hookEvent) {
|
|
|
14191
14422
|
}
|
|
14192
14423
|
function removeFromHooksJson(settingsPath, hookEvent) {
|
|
14193
14424
|
const fullPath = expandPath(settingsPath);
|
|
14194
|
-
if (!
|
|
14425
|
+
if (!existsSync7(fullPath)) return;
|
|
14195
14426
|
const raw = readFileSync5(fullPath, "utf-8");
|
|
14196
14427
|
const config = JSON.parse(raw);
|
|
14197
14428
|
const hooks = config.hooks;
|
|
@@ -14257,7 +14488,7 @@ async function uninstallHooksIntegration(agentKey, spec) {
|
|
|
14257
14488
|
const hooksDir = expandPath(spec.hooksDirPath);
|
|
14258
14489
|
for (const filename of ["openacp-inject-session.sh", "openacp-handoff.sh"]) {
|
|
14259
14490
|
const filePath = join10(hooksDir, filename);
|
|
14260
|
-
if (
|
|
14491
|
+
if (existsSync7(filePath)) {
|
|
14261
14492
|
unlinkSync4(filePath);
|
|
14262
14493
|
logs.push(`Removed ${filePath}`);
|
|
14263
14494
|
}
|
|
@@ -14266,7 +14497,7 @@ async function uninstallHooksIntegration(agentKey, spec) {
|
|
|
14266
14497
|
if (spec.commandFormat === "skill") {
|
|
14267
14498
|
const skillDir = expandPath(join10(spec.commandsPath, spec.handoffCommandName));
|
|
14268
14499
|
const skillPath = join10(skillDir, "SKILL.md");
|
|
14269
|
-
if (
|
|
14500
|
+
if (existsSync7(skillPath)) {
|
|
14270
14501
|
unlinkSync4(skillPath);
|
|
14271
14502
|
try {
|
|
14272
14503
|
rmdirSync(skillDir);
|
|
@@ -14276,7 +14507,7 @@ async function uninstallHooksIntegration(agentKey, spec) {
|
|
|
14276
14507
|
}
|
|
14277
14508
|
} else {
|
|
14278
14509
|
const cmdPath = expandPath(join10(spec.commandsPath, `${spec.handoffCommandName}.md`));
|
|
14279
|
-
if (
|
|
14510
|
+
if (existsSync7(cmdPath)) {
|
|
14280
14511
|
unlinkSync4(cmdPath);
|
|
14281
14512
|
logs.push(`Removed ${cmdPath}`);
|
|
14282
14513
|
}
|
|
@@ -14303,11 +14534,11 @@ async function installPluginIntegration(_agentKey, spec) {
|
|
|
14303
14534
|
const pluginsDir = expandPath(spec.pluginsPath);
|
|
14304
14535
|
mkdirSync5(pluginsDir, { recursive: true });
|
|
14305
14536
|
const pluginPath = join10(pluginsDir, spec.pluginFileName);
|
|
14306
|
-
if (
|
|
14537
|
+
if (existsSync7(commandPath) && existsSync7(pluginPath)) {
|
|
14307
14538
|
logs.push("Already installed, skipping.");
|
|
14308
14539
|
return { success: true, logs };
|
|
14309
14540
|
}
|
|
14310
|
-
if (
|
|
14541
|
+
if (existsSync7(commandPath) || existsSync7(pluginPath)) {
|
|
14311
14542
|
logs.push("Overwriting existing files.");
|
|
14312
14543
|
}
|
|
14313
14544
|
writeFileSync5(commandPath, generateOpencodeHandoffCommand(spec));
|
|
@@ -14325,13 +14556,13 @@ async function uninstallPluginIntegration(_agentKey, spec) {
|
|
|
14325
14556
|
try {
|
|
14326
14557
|
const commandPath = join10(expandPath(spec.commandsPath), spec.handoffCommandFile);
|
|
14327
14558
|
let removedCount = 0;
|
|
14328
|
-
if (
|
|
14559
|
+
if (existsSync7(commandPath)) {
|
|
14329
14560
|
unlinkSync4(commandPath);
|
|
14330
14561
|
logs.push(`Removed ${commandPath}`);
|
|
14331
14562
|
removedCount += 1;
|
|
14332
14563
|
}
|
|
14333
14564
|
const pluginPath = join10(expandPath(spec.pluginsPath), spec.pluginFileName);
|
|
14334
|
-
if (
|
|
14565
|
+
if (existsSync7(pluginPath)) {
|
|
14335
14566
|
unlinkSync4(pluginPath);
|
|
14336
14567
|
logs.push(`Removed ${pluginPath}`);
|
|
14337
14568
|
removedCount += 1;
|
|
@@ -14365,11 +14596,11 @@ function buildHandoffItem(agentKey, spec) {
|
|
|
14365
14596
|
isInstalled() {
|
|
14366
14597
|
if (isHooksIntegrationSpec(spec)) {
|
|
14367
14598
|
const hooksDir = expandPath(spec.hooksDirPath);
|
|
14368
|
-
return
|
|
14599
|
+
return existsSync7(join10(hooksDir, "openacp-inject-session.sh")) && existsSync7(join10(hooksDir, "openacp-handoff.sh"));
|
|
14369
14600
|
}
|
|
14370
14601
|
const commandPath = join10(expandPath(spec.commandsPath), spec.handoffCommandFile);
|
|
14371
14602
|
const pluginPath = join10(expandPath(spec.pluginsPath), spec.pluginFileName);
|
|
14372
|
-
return
|
|
14603
|
+
return existsSync7(commandPath) && existsSync7(pluginPath);
|
|
14373
14604
|
},
|
|
14374
14605
|
install: () => installIntegration(agentKey, spec),
|
|
14375
14606
|
uninstall: () => uninstallIntegration(agentKey, spec)
|
|
@@ -14391,7 +14622,7 @@ function buildTunnelItem(spec) {
|
|
|
14391
14622
|
name: "Tunnel",
|
|
14392
14623
|
description: "Expose local ports to the internet via OpenACP tunnel",
|
|
14393
14624
|
isInstalled() {
|
|
14394
|
-
return
|
|
14625
|
+
return existsSync7(getTunnelPath());
|
|
14395
14626
|
},
|
|
14396
14627
|
async install() {
|
|
14397
14628
|
const logs = [];
|
|
@@ -14410,7 +14641,7 @@ function buildTunnelItem(spec) {
|
|
|
14410
14641
|
const logs = [];
|
|
14411
14642
|
try {
|
|
14412
14643
|
const skillPath = getTunnelPath();
|
|
14413
|
-
if (
|
|
14644
|
+
if (existsSync7(skillPath)) {
|
|
14414
14645
|
unlinkSync4(skillPath);
|
|
14415
14646
|
try {
|
|
14416
14647
|
rmdirSync(dirname7(skillPath));
|
|
@@ -15173,7 +15404,7 @@ var init_config4 = __esm({
|
|
|
15173
15404
|
// src/core/doctor/checks/agents.ts
|
|
15174
15405
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
15175
15406
|
import * as fs24 from "fs";
|
|
15176
|
-
import * as
|
|
15407
|
+
import * as path28 from "path";
|
|
15177
15408
|
function commandExists2(cmd) {
|
|
15178
15409
|
try {
|
|
15179
15410
|
execFileSync4("which", [cmd], { stdio: "pipe" });
|
|
@@ -15182,9 +15413,9 @@ function commandExists2(cmd) {
|
|
|
15182
15413
|
}
|
|
15183
15414
|
let dir = process.cwd();
|
|
15184
15415
|
while (true) {
|
|
15185
|
-
const binPath =
|
|
15416
|
+
const binPath = path28.join(dir, "node_modules", ".bin", cmd);
|
|
15186
15417
|
if (fs24.existsSync(binPath)) return true;
|
|
15187
|
-
const parent =
|
|
15418
|
+
const parent = path28.dirname(dir);
|
|
15188
15419
|
if (parent === dir) break;
|
|
15189
15420
|
dir = parent;
|
|
15190
15421
|
}
|
|
@@ -15206,7 +15437,7 @@ var init_agents3 = __esm({
|
|
|
15206
15437
|
const defaultAgent = ctx.config.defaultAgent;
|
|
15207
15438
|
let agents = {};
|
|
15208
15439
|
try {
|
|
15209
|
-
const agentsPath =
|
|
15440
|
+
const agentsPath = path28.join(ctx.dataDir, "agents.json");
|
|
15210
15441
|
if (fs24.existsSync(agentsPath)) {
|
|
15211
15442
|
const data = JSON.parse(fs24.readFileSync(agentsPath, "utf-8"));
|
|
15212
15443
|
agents = data.installed ?? {};
|
|
@@ -15247,7 +15478,7 @@ __export(settings_manager_exports, {
|
|
|
15247
15478
|
SettingsManager: () => SettingsManager
|
|
15248
15479
|
});
|
|
15249
15480
|
import fs25 from "fs";
|
|
15250
|
-
import
|
|
15481
|
+
import path29 from "path";
|
|
15251
15482
|
var SettingsManager, SettingsAPIImpl;
|
|
15252
15483
|
var init_settings_manager = __esm({
|
|
15253
15484
|
"src/core/plugin/settings-manager.ts"() {
|
|
@@ -15290,7 +15521,7 @@ var init_settings_manager = __esm({
|
|
|
15290
15521
|
}
|
|
15291
15522
|
/** Resolve the absolute path to a plugin's settings.json file. */
|
|
15292
15523
|
getSettingsPath(pluginName) {
|
|
15293
|
-
return
|
|
15524
|
+
return path29.join(this.basePath, pluginName, "settings.json");
|
|
15294
15525
|
}
|
|
15295
15526
|
async getPluginSettings(pluginName) {
|
|
15296
15527
|
return this.loadSettings(pluginName);
|
|
@@ -15320,7 +15551,7 @@ var init_settings_manager = __esm({
|
|
|
15320
15551
|
}
|
|
15321
15552
|
}
|
|
15322
15553
|
writeFile(data) {
|
|
15323
|
-
const dir =
|
|
15554
|
+
const dir = path29.dirname(this.settingsPath);
|
|
15324
15555
|
fs25.mkdirSync(dir, { recursive: true });
|
|
15325
15556
|
fs25.writeFileSync(this.settingsPath, JSON.stringify(data, null, 2));
|
|
15326
15557
|
this.cache = data;
|
|
@@ -15357,7 +15588,7 @@ var init_settings_manager = __esm({
|
|
|
15357
15588
|
});
|
|
15358
15589
|
|
|
15359
15590
|
// src/core/doctor/checks/telegram.ts
|
|
15360
|
-
import * as
|
|
15591
|
+
import * as path30 from "path";
|
|
15361
15592
|
var BOT_TOKEN_REGEX, telegramCheck;
|
|
15362
15593
|
var init_telegram = __esm({
|
|
15363
15594
|
"src/core/doctor/checks/telegram.ts"() {
|
|
@@ -15373,7 +15604,7 @@ var init_telegram = __esm({
|
|
|
15373
15604
|
return results;
|
|
15374
15605
|
}
|
|
15375
15606
|
const { SettingsManager: SettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
|
|
15376
|
-
const sm = new SettingsManager2(
|
|
15607
|
+
const sm = new SettingsManager2(path30.join(ctx.pluginsDir, "data"));
|
|
15377
15608
|
const ps = await sm.loadSettings("@openacp/telegram");
|
|
15378
15609
|
const botToken = ps.botToken;
|
|
15379
15610
|
const chatId = ps.chatId;
|
|
@@ -15545,7 +15776,7 @@ var init_storage = __esm({
|
|
|
15545
15776
|
|
|
15546
15777
|
// src/core/doctor/checks/workspace.ts
|
|
15547
15778
|
import * as fs27 from "fs";
|
|
15548
|
-
import * as
|
|
15779
|
+
import * as path31 from "path";
|
|
15549
15780
|
var workspaceCheck;
|
|
15550
15781
|
var init_workspace2 = __esm({
|
|
15551
15782
|
"src/core/doctor/checks/workspace.ts"() {
|
|
@@ -15555,7 +15786,7 @@ var init_workspace2 = __esm({
|
|
|
15555
15786
|
order: 5,
|
|
15556
15787
|
async run(ctx) {
|
|
15557
15788
|
const results = [];
|
|
15558
|
-
const workspace =
|
|
15789
|
+
const workspace = path31.dirname(ctx.dataDir);
|
|
15559
15790
|
if (!fs27.existsSync(workspace)) {
|
|
15560
15791
|
results.push({
|
|
15561
15792
|
status: "warn",
|
|
@@ -15583,7 +15814,7 @@ var init_workspace2 = __esm({
|
|
|
15583
15814
|
|
|
15584
15815
|
// src/core/doctor/checks/plugins.ts
|
|
15585
15816
|
import * as fs28 from "fs";
|
|
15586
|
-
import * as
|
|
15817
|
+
import * as path32 from "path";
|
|
15587
15818
|
var pluginsCheck;
|
|
15588
15819
|
var init_plugins2 = __esm({
|
|
15589
15820
|
"src/core/doctor/checks/plugins.ts"() {
|
|
@@ -15602,7 +15833,7 @@ var init_plugins2 = __esm({
|
|
|
15602
15833
|
fix: async () => {
|
|
15603
15834
|
fs28.mkdirSync(ctx.pluginsDir, { recursive: true });
|
|
15604
15835
|
fs28.writeFileSync(
|
|
15605
|
-
|
|
15836
|
+
path32.join(ctx.pluginsDir, "package.json"),
|
|
15606
15837
|
JSON.stringify({ name: "openacp-plugins", private: true, dependencies: {} }, null, 2)
|
|
15607
15838
|
);
|
|
15608
15839
|
return { success: true, message: "initialized plugins directory" };
|
|
@@ -15611,7 +15842,7 @@ var init_plugins2 = __esm({
|
|
|
15611
15842
|
return results;
|
|
15612
15843
|
}
|
|
15613
15844
|
results.push({ status: "pass", message: "Plugins directory exists" });
|
|
15614
|
-
const pkgPath =
|
|
15845
|
+
const pkgPath = path32.join(ctx.pluginsDir, "package.json");
|
|
15615
15846
|
if (!fs28.existsSync(pkgPath)) {
|
|
15616
15847
|
results.push({
|
|
15617
15848
|
status: "warn",
|
|
@@ -15758,7 +15989,7 @@ var init_daemon = __esm({
|
|
|
15758
15989
|
|
|
15759
15990
|
// src/core/doctor/checks/tunnel.ts
|
|
15760
15991
|
import * as fs30 from "fs";
|
|
15761
|
-
import * as
|
|
15992
|
+
import * as path33 from "path";
|
|
15762
15993
|
import * as os7 from "os";
|
|
15763
15994
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
15764
15995
|
var tunnelCheck;
|
|
@@ -15775,7 +16006,7 @@ var init_tunnel3 = __esm({
|
|
|
15775
16006
|
return results;
|
|
15776
16007
|
}
|
|
15777
16008
|
const { SettingsManager: SettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
|
|
15778
|
-
const sm = new SettingsManager2(
|
|
16009
|
+
const sm = new SettingsManager2(path33.join(ctx.pluginsDir, "data"));
|
|
15779
16010
|
const tunnelSettings = await sm.loadSettings("@openacp/tunnel");
|
|
15780
16011
|
const tunnelEnabled = tunnelSettings.enabled ?? false;
|
|
15781
16012
|
const provider = tunnelSettings.provider ?? "cloudflare";
|
|
@@ -15787,7 +16018,7 @@ var init_tunnel3 = __esm({
|
|
|
15787
16018
|
results.push({ status: "pass", message: `Tunnel provider: ${provider}` });
|
|
15788
16019
|
if (provider === "cloudflare") {
|
|
15789
16020
|
const binName = os7.platform() === "win32" ? "cloudflared.exe" : "cloudflared";
|
|
15790
|
-
const binPath =
|
|
16021
|
+
const binPath = path33.join(ctx.dataDir, "bin", binName);
|
|
15791
16022
|
let found = false;
|
|
15792
16023
|
if (fs30.existsSync(binPath)) {
|
|
15793
16024
|
found = true;
|
|
@@ -15835,7 +16066,7 @@ __export(doctor_exports, {
|
|
|
15835
16066
|
DoctorEngine: () => DoctorEngine
|
|
15836
16067
|
});
|
|
15837
16068
|
import * as fs31 from "fs";
|
|
15838
|
-
import * as
|
|
16069
|
+
import * as path34 from "path";
|
|
15839
16070
|
var ALL_CHECKS, CHECK_TIMEOUT_MS, DoctorEngine;
|
|
15840
16071
|
var init_doctor = __esm({
|
|
15841
16072
|
"src/core/doctor/index.ts"() {
|
|
@@ -15923,7 +16154,7 @@ var init_doctor = __esm({
|
|
|
15923
16154
|
/** Constructs the shared context used by all checks — loads config if available. */
|
|
15924
16155
|
async buildContext() {
|
|
15925
16156
|
const dataDir = this.dataDir;
|
|
15926
|
-
const configPath = process.env.OPENACP_CONFIG_PATH ||
|
|
16157
|
+
const configPath = process.env.OPENACP_CONFIG_PATH || path34.join(dataDir, "config.json");
|
|
15927
16158
|
let config = null;
|
|
15928
16159
|
let rawConfig = null;
|
|
15929
16160
|
try {
|
|
@@ -15934,16 +16165,16 @@ var init_doctor = __esm({
|
|
|
15934
16165
|
config = cm.get();
|
|
15935
16166
|
} catch {
|
|
15936
16167
|
}
|
|
15937
|
-
const logsDir = config ? expandHome2(config.logging.logDir) :
|
|
16168
|
+
const logsDir = config ? expandHome2(config.logging.logDir) : path34.join(dataDir, "logs");
|
|
15938
16169
|
return {
|
|
15939
16170
|
config,
|
|
15940
16171
|
rawConfig,
|
|
15941
16172
|
configPath,
|
|
15942
16173
|
dataDir,
|
|
15943
|
-
sessionsPath:
|
|
15944
|
-
pidPath:
|
|
15945
|
-
portFilePath:
|
|
15946
|
-
pluginsDir:
|
|
16174
|
+
sessionsPath: path34.join(dataDir, "sessions.json"),
|
|
16175
|
+
pidPath: path34.join(dataDir, "openacp.pid"),
|
|
16176
|
+
portFilePath: path34.join(dataDir, "api.port"),
|
|
16177
|
+
pluginsDir: path34.join(dataDir, "plugins"),
|
|
15947
16178
|
logsDir
|
|
15948
16179
|
};
|
|
15949
16180
|
}
|
|
@@ -20500,10 +20731,10 @@ var install_context_exports = {};
|
|
|
20500
20731
|
__export(install_context_exports, {
|
|
20501
20732
|
createInstallContext: () => createInstallContext
|
|
20502
20733
|
});
|
|
20503
|
-
import
|
|
20734
|
+
import path35 from "path";
|
|
20504
20735
|
function createInstallContext(opts) {
|
|
20505
20736
|
const { pluginName, settingsManager, basePath, instanceRoot } = opts;
|
|
20506
|
-
const dataDir =
|
|
20737
|
+
const dataDir = path35.join(basePath, pluginName, "data");
|
|
20507
20738
|
return {
|
|
20508
20739
|
pluginName,
|
|
20509
20740
|
terminal: createTerminalIO(),
|
|
@@ -20531,13 +20762,13 @@ __export(api_client_exports, {
|
|
|
20531
20762
|
waitForPortFile: () => waitForPortFile
|
|
20532
20763
|
});
|
|
20533
20764
|
import * as fs33 from "fs";
|
|
20534
|
-
import * as
|
|
20765
|
+
import * as path37 from "path";
|
|
20535
20766
|
import { setTimeout as sleep } from "timers/promises";
|
|
20536
20767
|
function defaultPortFile(root) {
|
|
20537
|
-
return
|
|
20768
|
+
return path37.join(root, "api.port");
|
|
20538
20769
|
}
|
|
20539
20770
|
function defaultSecretFile(root) {
|
|
20540
|
-
return
|
|
20771
|
+
return path37.join(root, "api-secret");
|
|
20541
20772
|
}
|
|
20542
20773
|
async function waitForPortFile(portFilePath, timeoutMs = 5e3, intervalMs = 100) {
|
|
20543
20774
|
const deadline = Date.now() + timeoutMs;
|
|
@@ -20632,9 +20863,9 @@ var init_suggest = __esm({
|
|
|
20632
20863
|
|
|
20633
20864
|
// src/cli/instance-hint.ts
|
|
20634
20865
|
import os8 from "os";
|
|
20635
|
-
import
|
|
20866
|
+
import path38 from "path";
|
|
20636
20867
|
function printInstanceHint(root) {
|
|
20637
|
-
const workspaceDir =
|
|
20868
|
+
const workspaceDir = path38.dirname(root);
|
|
20638
20869
|
const displayPath = workspaceDir.replace(os8.homedir(), "~");
|
|
20639
20870
|
console.log(` Workspace: ${displayPath}`);
|
|
20640
20871
|
}
|
|
@@ -20650,23 +20881,23 @@ __export(resolve_instance_id_exports, {
|
|
|
20650
20881
|
resolveInstanceId: () => resolveInstanceId
|
|
20651
20882
|
});
|
|
20652
20883
|
import fs34 from "fs";
|
|
20653
|
-
import
|
|
20884
|
+
import path39 from "path";
|
|
20654
20885
|
function resolveInstanceId(instanceRoot) {
|
|
20655
20886
|
try {
|
|
20656
|
-
const configPath =
|
|
20887
|
+
const configPath = path39.join(instanceRoot, "config.json");
|
|
20657
20888
|
const raw = JSON.parse(fs34.readFileSync(configPath, "utf-8"));
|
|
20658
20889
|
if (raw.id && typeof raw.id === "string") return raw.id;
|
|
20659
20890
|
} catch {
|
|
20660
20891
|
}
|
|
20661
20892
|
try {
|
|
20662
|
-
const reg = new InstanceRegistry(
|
|
20893
|
+
const reg = new InstanceRegistry(path39.join(getGlobalRoot(), "instances.json"));
|
|
20663
20894
|
reg.load();
|
|
20664
20895
|
const entry = reg.getByRoot(instanceRoot);
|
|
20665
20896
|
if (entry?.id) return entry.id;
|
|
20666
20897
|
} catch (err) {
|
|
20667
20898
|
log31.debug({ err: err.message, instanceRoot }, "Could not read instance registry, using fallback id");
|
|
20668
20899
|
}
|
|
20669
|
-
return
|
|
20900
|
+
return path39.basename(path39.dirname(instanceRoot)).replace(/[^a-zA-Z0-9-]/g, "-") || "default";
|
|
20670
20901
|
}
|
|
20671
20902
|
var log31;
|
|
20672
20903
|
var init_resolve_instance_id = __esm({
|
|
@@ -20698,18 +20929,18 @@ __export(daemon_exports, {
|
|
|
20698
20929
|
});
|
|
20699
20930
|
import { spawn as spawn6 } from "child_process";
|
|
20700
20931
|
import * as fs35 from "fs";
|
|
20701
|
-
import * as
|
|
20932
|
+
import * as path40 from "path";
|
|
20702
20933
|
function getPidPath(root) {
|
|
20703
|
-
return
|
|
20934
|
+
return path40.join(root, "openacp.pid");
|
|
20704
20935
|
}
|
|
20705
20936
|
function getLogDir(root) {
|
|
20706
|
-
return
|
|
20937
|
+
return path40.join(root, "logs");
|
|
20707
20938
|
}
|
|
20708
20939
|
function getRunningMarker(root) {
|
|
20709
|
-
return
|
|
20940
|
+
return path40.join(root, "running");
|
|
20710
20941
|
}
|
|
20711
20942
|
function writePidFile(pidPath, pid) {
|
|
20712
|
-
const dir =
|
|
20943
|
+
const dir = path40.dirname(pidPath);
|
|
20713
20944
|
fs35.mkdirSync(dir, { recursive: true });
|
|
20714
20945
|
fs35.writeFileSync(pidPath, String(pid));
|
|
20715
20946
|
}
|
|
@@ -20758,8 +20989,8 @@ function startDaemon(pidPath, logDir2, instanceRoot) {
|
|
|
20758
20989
|
}
|
|
20759
20990
|
const resolvedLogDir = logDir2 ? expandHome2(logDir2) : getLogDir(instanceRoot);
|
|
20760
20991
|
fs35.mkdirSync(resolvedLogDir, { recursive: true });
|
|
20761
|
-
const logFile =
|
|
20762
|
-
const cliPath =
|
|
20992
|
+
const logFile = path40.join(resolvedLogDir, "openacp.log");
|
|
20993
|
+
const cliPath = path40.resolve(process.argv[1]);
|
|
20763
20994
|
const nodePath = process.execPath;
|
|
20764
20995
|
const out = fs35.openSync(logFile, "a");
|
|
20765
20996
|
const err = fs35.openSync(logFile, "a");
|
|
@@ -20843,7 +21074,7 @@ async function stopDaemon(pidPath, instanceRoot) {
|
|
|
20843
21074
|
}
|
|
20844
21075
|
function markRunning(root) {
|
|
20845
21076
|
const marker = getRunningMarker(root);
|
|
20846
|
-
fs35.mkdirSync(
|
|
21077
|
+
fs35.mkdirSync(path40.dirname(marker), { recursive: true });
|
|
20847
21078
|
fs35.writeFileSync(marker, "");
|
|
20848
21079
|
}
|
|
20849
21080
|
function clearRunning(root) {
|
|
@@ -20876,19 +21107,19 @@ __export(autostart_exports, {
|
|
|
20876
21107
|
});
|
|
20877
21108
|
import { execFileSync as execFileSync6 } from "child_process";
|
|
20878
21109
|
import * as fs36 from "fs";
|
|
20879
|
-
import * as
|
|
21110
|
+
import * as path41 from "path";
|
|
20880
21111
|
import * as os9 from "os";
|
|
20881
21112
|
function getLaunchdLabel(instanceId) {
|
|
20882
21113
|
return `com.openacp.daemon.${instanceId}`;
|
|
20883
21114
|
}
|
|
20884
21115
|
function getLaunchdPlistPath(instanceId) {
|
|
20885
|
-
return
|
|
21116
|
+
return path41.join(os9.homedir(), "Library", "LaunchAgents", `${getLaunchdLabel(instanceId)}.plist`);
|
|
20886
21117
|
}
|
|
20887
21118
|
function getSystemdServiceName(instanceId) {
|
|
20888
21119
|
return `openacp-${instanceId}`;
|
|
20889
21120
|
}
|
|
20890
21121
|
function getSystemdServicePath(instanceId) {
|
|
20891
|
-
return
|
|
21122
|
+
return path41.join(os9.homedir(), ".config", "systemd", "user", `${getSystemdServiceName(instanceId)}.service`);
|
|
20892
21123
|
}
|
|
20893
21124
|
function isAutoStartSupported() {
|
|
20894
21125
|
return process.platform === "darwin" || process.platform === "linux";
|
|
@@ -20902,7 +21133,7 @@ function escapeSystemdValue(str) {
|
|
|
20902
21133
|
}
|
|
20903
21134
|
function generateLaunchdPlist(nodePath, cliPath, logDir2, instanceRoot, instanceId) {
|
|
20904
21135
|
const label = getLaunchdLabel(instanceId);
|
|
20905
|
-
const logFile =
|
|
21136
|
+
const logFile = path41.join(logDir2, "openacp.log");
|
|
20906
21137
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
20907
21138
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
20908
21139
|
<plist version="1.0">
|
|
@@ -20984,14 +21215,14 @@ function installAutoStart(logDir2, instanceRoot, instanceId) {
|
|
|
20984
21215
|
return { success: false, error: "Auto-start not supported on this platform" };
|
|
20985
21216
|
}
|
|
20986
21217
|
const nodePath = process.execPath;
|
|
20987
|
-
const cliPath =
|
|
20988
|
-
const resolvedLogDir = logDir2.startsWith("~") ?
|
|
21218
|
+
const cliPath = path41.resolve(process.argv[1]);
|
|
21219
|
+
const resolvedLogDir = logDir2.startsWith("~") ? path41.join(os9.homedir(), logDir2.slice(1)) : logDir2;
|
|
20989
21220
|
try {
|
|
20990
21221
|
migrateLegacy();
|
|
20991
21222
|
if (process.platform === "darwin") {
|
|
20992
21223
|
const plistPath = getLaunchdPlistPath(instanceId);
|
|
20993
21224
|
const plist = generateLaunchdPlist(nodePath, cliPath, resolvedLogDir, instanceRoot, instanceId);
|
|
20994
|
-
const dir =
|
|
21225
|
+
const dir = path41.dirname(plistPath);
|
|
20995
21226
|
fs36.mkdirSync(dir, { recursive: true });
|
|
20996
21227
|
fs36.writeFileSync(plistPath, plist);
|
|
20997
21228
|
const uid = process.getuid();
|
|
@@ -21008,7 +21239,7 @@ function installAutoStart(logDir2, instanceRoot, instanceId) {
|
|
|
21008
21239
|
const servicePath = getSystemdServicePath(instanceId);
|
|
21009
21240
|
const serviceName = getSystemdServiceName(instanceId);
|
|
21010
21241
|
const unit = generateSystemdUnit(nodePath, cliPath, instanceRoot, instanceId);
|
|
21011
|
-
const dir =
|
|
21242
|
+
const dir = path41.dirname(servicePath);
|
|
21012
21243
|
fs36.mkdirSync(dir, { recursive: true });
|
|
21013
21244
|
fs36.writeFileSync(servicePath, unit);
|
|
21014
21245
|
execFileSync6("systemctl", ["--user", "daemon-reload"], { stdio: "pipe" });
|
|
@@ -21077,8 +21308,8 @@ var init_autostart = __esm({
|
|
|
21077
21308
|
"use strict";
|
|
21078
21309
|
init_log();
|
|
21079
21310
|
log32 = createChildLogger({ module: "autostart" });
|
|
21080
|
-
LEGACY_LAUNCHD_PLIST_PATH =
|
|
21081
|
-
LEGACY_SYSTEMD_SERVICE_PATH =
|
|
21311
|
+
LEGACY_LAUNCHD_PLIST_PATH = path41.join(os9.homedir(), "Library", "LaunchAgents", "com.openacp.daemon.plist");
|
|
21312
|
+
LEGACY_SYSTEMD_SERVICE_PATH = path41.join(os9.homedir(), ".config", "systemd", "user", "openacp.service");
|
|
21082
21313
|
}
|
|
21083
21314
|
});
|
|
21084
21315
|
|
|
@@ -21133,7 +21364,7 @@ var init_stop = __esm({
|
|
|
21133
21364
|
|
|
21134
21365
|
// src/core/security/path-guard.ts
|
|
21135
21366
|
import fs37 from "fs";
|
|
21136
|
-
import
|
|
21367
|
+
import path43 from "path";
|
|
21137
21368
|
import ignore from "ignore";
|
|
21138
21369
|
var DEFAULT_DENY_PATTERNS, PathGuard;
|
|
21139
21370
|
var init_path_guard = __esm({
|
|
@@ -21162,15 +21393,15 @@ var init_path_guard = __esm({
|
|
|
21162
21393
|
ig;
|
|
21163
21394
|
constructor(options) {
|
|
21164
21395
|
try {
|
|
21165
|
-
this.cwd = fs37.realpathSync(
|
|
21396
|
+
this.cwd = fs37.realpathSync(path43.resolve(options.cwd));
|
|
21166
21397
|
} catch {
|
|
21167
|
-
this.cwd =
|
|
21398
|
+
this.cwd = path43.resolve(options.cwd);
|
|
21168
21399
|
}
|
|
21169
21400
|
this.allowedPaths = options.allowedPaths.map((p2) => {
|
|
21170
21401
|
try {
|
|
21171
|
-
return fs37.realpathSync(
|
|
21402
|
+
return fs37.realpathSync(path43.resolve(p2));
|
|
21172
21403
|
} catch {
|
|
21173
|
-
return
|
|
21404
|
+
return path43.resolve(p2);
|
|
21174
21405
|
}
|
|
21175
21406
|
});
|
|
21176
21407
|
this.ig = ignore();
|
|
@@ -21194,19 +21425,19 @@ var init_path_guard = __esm({
|
|
|
21194
21425
|
* @returns `{ allowed: true }` or `{ allowed: false, reason: "..." }`
|
|
21195
21426
|
*/
|
|
21196
21427
|
validatePath(targetPath, operation) {
|
|
21197
|
-
const resolved =
|
|
21428
|
+
const resolved = path43.resolve(targetPath);
|
|
21198
21429
|
let realPath;
|
|
21199
21430
|
try {
|
|
21200
21431
|
realPath = fs37.realpathSync(resolved);
|
|
21201
21432
|
} catch {
|
|
21202
21433
|
realPath = resolved;
|
|
21203
21434
|
}
|
|
21204
|
-
if (operation === "write" &&
|
|
21435
|
+
if (operation === "write" && path43.basename(realPath) === ".openacpignore") {
|
|
21205
21436
|
return { allowed: false, reason: "Cannot write to .openacpignore" };
|
|
21206
21437
|
}
|
|
21207
|
-
const isWithinCwd = realPath === this.cwd || realPath.startsWith(this.cwd +
|
|
21438
|
+
const isWithinCwd = realPath === this.cwd || realPath.startsWith(this.cwd + path43.sep);
|
|
21208
21439
|
const isWithinAllowed = this.allowedPaths.some(
|
|
21209
|
-
(ap) => realPath === ap || realPath.startsWith(ap +
|
|
21440
|
+
(ap) => realPath === ap || realPath.startsWith(ap + path43.sep)
|
|
21210
21441
|
);
|
|
21211
21442
|
if (!isWithinCwd && !isWithinAllowed) {
|
|
21212
21443
|
return {
|
|
@@ -21215,7 +21446,7 @@ var init_path_guard = __esm({
|
|
|
21215
21446
|
};
|
|
21216
21447
|
}
|
|
21217
21448
|
if (isWithinCwd && !isWithinAllowed) {
|
|
21218
|
-
const relativePath =
|
|
21449
|
+
const relativePath = path43.relative(this.cwd, realPath);
|
|
21219
21450
|
if (relativePath === ".openacpignore") {
|
|
21220
21451
|
return { allowed: true, reason: "" };
|
|
21221
21452
|
}
|
|
@@ -21231,9 +21462,9 @@ var init_path_guard = __esm({
|
|
|
21231
21462
|
/** Adds an additional allowed path at runtime (e.g. for file-service uploads). */
|
|
21232
21463
|
addAllowedPath(p2) {
|
|
21233
21464
|
try {
|
|
21234
|
-
this.allowedPaths.push(fs37.realpathSync(
|
|
21465
|
+
this.allowedPaths.push(fs37.realpathSync(path43.resolve(p2)));
|
|
21235
21466
|
} catch {
|
|
21236
|
-
this.allowedPaths.push(
|
|
21467
|
+
this.allowedPaths.push(path43.resolve(p2));
|
|
21237
21468
|
}
|
|
21238
21469
|
}
|
|
21239
21470
|
/**
|
|
@@ -21241,7 +21472,7 @@ var init_path_guard = __esm({
|
|
|
21241
21472
|
* Follows .gitignore syntax — blank lines and lines starting with # are skipped.
|
|
21242
21473
|
*/
|
|
21243
21474
|
static loadIgnoreFile(cwd) {
|
|
21244
|
-
const ignorePath =
|
|
21475
|
+
const ignorePath = path43.join(cwd, ".openacpignore");
|
|
21245
21476
|
try {
|
|
21246
21477
|
const content = fs37.readFileSync(ignorePath, "utf-8");
|
|
21247
21478
|
return content.split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
@@ -21718,7 +21949,7 @@ var init_mcp_manager = __esm({
|
|
|
21718
21949
|
|
|
21719
21950
|
// src/core/utils/debug-tracer.ts
|
|
21720
21951
|
import fs38 from "fs";
|
|
21721
|
-
import
|
|
21952
|
+
import path44 from "path";
|
|
21722
21953
|
function createDebugTracer(sessionId, workingDirectory) {
|
|
21723
21954
|
if (!DEBUG_ENABLED) return null;
|
|
21724
21955
|
return new DebugTracer(sessionId, workingDirectory);
|
|
@@ -21732,7 +21963,7 @@ var init_debug_tracer = __esm({
|
|
|
21732
21963
|
constructor(sessionId, workingDirectory) {
|
|
21733
21964
|
this.sessionId = sessionId;
|
|
21734
21965
|
this.workingDirectory = workingDirectory;
|
|
21735
|
-
this.logDir =
|
|
21966
|
+
this.logDir = path44.join(workingDirectory, ".log");
|
|
21736
21967
|
}
|
|
21737
21968
|
sessionId;
|
|
21738
21969
|
workingDirectory;
|
|
@@ -21750,7 +21981,7 @@ var init_debug_tracer = __esm({
|
|
|
21750
21981
|
fs38.mkdirSync(this.logDir, { recursive: true });
|
|
21751
21982
|
this.dirCreated = true;
|
|
21752
21983
|
}
|
|
21753
|
-
const filePath =
|
|
21984
|
+
const filePath = path44.join(this.logDir, `${this.sessionId}_${layer}.jsonl`);
|
|
21754
21985
|
const seen = /* @__PURE__ */ new WeakSet();
|
|
21755
21986
|
const line = JSON.stringify({ ts: Date.now(), ...data }, (_key, value) => {
|
|
21756
21987
|
if (typeof value === "object" && value !== null) {
|
|
@@ -21774,21 +22005,21 @@ var init_debug_tracer = __esm({
|
|
|
21774
22005
|
import { spawn as spawn8, execFileSync as execFileSync7 } from "child_process";
|
|
21775
22006
|
import { Transform } from "stream";
|
|
21776
22007
|
import fs39 from "fs";
|
|
21777
|
-
import
|
|
22008
|
+
import path45 from "path";
|
|
21778
22009
|
import { ClientSideConnection, ndJsonStream } from "@agentclientprotocol/sdk";
|
|
21779
22010
|
import { PROTOCOL_VERSION } from "@agentclientprotocol/sdk";
|
|
21780
22011
|
function findPackageRoot(startDir) {
|
|
21781
22012
|
let dir = startDir;
|
|
21782
|
-
while (dir !==
|
|
21783
|
-
if (fs39.existsSync(
|
|
22013
|
+
while (dir !== path45.dirname(dir)) {
|
|
22014
|
+
if (fs39.existsSync(path45.join(dir, "package.json"))) {
|
|
21784
22015
|
return dir;
|
|
21785
22016
|
}
|
|
21786
|
-
dir =
|
|
22017
|
+
dir = path45.dirname(dir);
|
|
21787
22018
|
}
|
|
21788
22019
|
return startDir;
|
|
21789
22020
|
}
|
|
21790
22021
|
function commandForWindowsScript(filePath) {
|
|
21791
|
-
const ext =
|
|
22022
|
+
const ext = path45.extname(filePath).toLowerCase();
|
|
21792
22023
|
if (process.platform === "win32" && (ext === ".cmd" || ext === ".bat")) {
|
|
21793
22024
|
return { command: process.env.ComSpec ?? "cmd.exe", args: ["/d", "/s", "/c", `"${filePath}"`] };
|
|
21794
22025
|
}
|
|
@@ -21802,8 +22033,8 @@ function resolveAgentCommand(cmd) {
|
|
|
21802
22033
|
}
|
|
21803
22034
|
for (const root of searchRoots) {
|
|
21804
22035
|
const packageDirs = [
|
|
21805
|
-
|
|
21806
|
-
|
|
22036
|
+
path45.resolve(root, "node_modules", "@zed-industries", cmd, "dist", "index.js"),
|
|
22037
|
+
path45.resolve(root, "node_modules", cmd, "dist", "index.js")
|
|
21807
22038
|
];
|
|
21808
22039
|
for (const jsPath of packageDirs) {
|
|
21809
22040
|
if (fs39.existsSync(jsPath)) {
|
|
@@ -21812,7 +22043,7 @@ function resolveAgentCommand(cmd) {
|
|
|
21812
22043
|
}
|
|
21813
22044
|
}
|
|
21814
22045
|
for (const root of searchRoots) {
|
|
21815
|
-
const localBin =
|
|
22046
|
+
const localBin = path45.resolve(root, "node_modules", ".bin", cmd);
|
|
21816
22047
|
if (fs39.existsSync(localBin)) {
|
|
21817
22048
|
const content = fs39.readFileSync(localBin, "utf-8");
|
|
21818
22049
|
if (content.startsWith("#!/usr/bin/env node")) {
|
|
@@ -21820,7 +22051,7 @@ function resolveAgentCommand(cmd) {
|
|
|
21820
22051
|
}
|
|
21821
22052
|
const match = content.match(/"([^"]+\.js)"/);
|
|
21822
22053
|
if (match) {
|
|
21823
|
-
const target =
|
|
22054
|
+
const target = path45.resolve(path45.dirname(localBin), match[1]);
|
|
21824
22055
|
if (fs39.existsSync(target)) {
|
|
21825
22056
|
return { command: process.execPath, args: [target] };
|
|
21826
22057
|
}
|
|
@@ -21836,9 +22067,9 @@ function resolveAgentCommand(cmd) {
|
|
|
21836
22067
|
candidates.push(dir);
|
|
21837
22068
|
}
|
|
21838
22069
|
};
|
|
21839
|
-
addCandidate(
|
|
22070
|
+
addCandidate(path45.dirname(process.execPath));
|
|
21840
22071
|
try {
|
|
21841
|
-
addCandidate(
|
|
22072
|
+
addCandidate(path45.dirname(fs39.realpathSync(process.execPath)));
|
|
21842
22073
|
} catch {
|
|
21843
22074
|
}
|
|
21844
22075
|
addCandidate("/opt/homebrew/bin");
|
|
@@ -21847,8 +22078,8 @@ function resolveAgentCommand(cmd) {
|
|
|
21847
22078
|
for (const dir of candidates) {
|
|
21848
22079
|
if (cmd === "npx") {
|
|
21849
22080
|
const npxCliCandidates = [
|
|
21850
|
-
|
|
21851
|
-
|
|
22081
|
+
path45.join(dir, "node_modules", "npm", "bin", "npx-cli.js"),
|
|
22082
|
+
path45.join(path45.dirname(dir), "lib", "node_modules", "npm", "bin", "npx-cli.js")
|
|
21852
22083
|
];
|
|
21853
22084
|
for (const npxCli of npxCliCandidates) {
|
|
21854
22085
|
if (fs39.existsSync(npxCli)) {
|
|
@@ -21858,7 +22089,7 @@ function resolveAgentCommand(cmd) {
|
|
|
21858
22089
|
}
|
|
21859
22090
|
}
|
|
21860
22091
|
for (const name of executableNames) {
|
|
21861
|
-
const candidate =
|
|
22092
|
+
const candidate = path45.join(dir, name);
|
|
21862
22093
|
if (fs39.existsSync(candidate)) {
|
|
21863
22094
|
const resolved = commandForWindowsScript(candidate);
|
|
21864
22095
|
log33.info({ cmd, resolved: candidate }, "Resolved package runner from fallback search");
|
|
@@ -21870,7 +22101,7 @@ function resolveAgentCommand(cmd) {
|
|
|
21870
22101
|
}
|
|
21871
22102
|
try {
|
|
21872
22103
|
const fullPath = execFileSync7("which", [cmd], { encoding: "utf-8" }).trim();
|
|
21873
|
-
const isUnspawnableWindowsShim = process.platform === "win32" && (cmd === "npx" || cmd === "uvx") && !
|
|
22104
|
+
const isUnspawnableWindowsShim = process.platform === "win32" && (cmd === "npx" || cmd === "uvx") && !path45.extname(fullPath);
|
|
21874
22105
|
if (fullPath && !isUnspawnableWindowsShim) {
|
|
21875
22106
|
try {
|
|
21876
22107
|
const content = fs39.readFileSync(fullPath, "utf-8");
|
|
@@ -22451,7 +22682,7 @@ ${stderr}`
|
|
|
22451
22682
|
writePath = result.path;
|
|
22452
22683
|
writeContent = result.content;
|
|
22453
22684
|
}
|
|
22454
|
-
await fs39.promises.mkdir(
|
|
22685
|
+
await fs39.promises.mkdir(path45.dirname(writePath), { recursive: true });
|
|
22455
22686
|
await fs39.promises.writeFile(writePath, writeContent, "utf-8");
|
|
22456
22687
|
return {};
|
|
22457
22688
|
},
|
|
@@ -24711,7 +24942,7 @@ var init_extract_file_info = __esm({
|
|
|
24711
24942
|
});
|
|
24712
24943
|
|
|
24713
24944
|
// src/core/message-transformer.ts
|
|
24714
|
-
import * as
|
|
24945
|
+
import * as path46 from "path";
|
|
24715
24946
|
function computeLineDiff(oldStr, newStr) {
|
|
24716
24947
|
const oldLines = oldStr ? oldStr.split("\n") : [];
|
|
24717
24948
|
const newLines = newStr ? newStr.split("\n") : [];
|
|
@@ -25017,7 +25248,7 @@ var init_message_transformer = __esm({
|
|
|
25017
25248
|
);
|
|
25018
25249
|
return;
|
|
25019
25250
|
}
|
|
25020
|
-
const fileExt =
|
|
25251
|
+
const fileExt = path46.extname(fileInfo.filePath).toLowerCase();
|
|
25021
25252
|
if (BINARY_VIEWER_EXTENSIONS.has(fileExt)) {
|
|
25022
25253
|
log36.debug({ kind, filePath: fileInfo.filePath }, "enrichWithViewerLinks: skipping binary file");
|
|
25023
25254
|
return;
|
|
@@ -25072,7 +25303,7 @@ var init_message_transformer = __esm({
|
|
|
25072
25303
|
|
|
25073
25304
|
// src/core/sessions/session-store.ts
|
|
25074
25305
|
import fs41 from "fs";
|
|
25075
|
-
import
|
|
25306
|
+
import path47 from "path";
|
|
25076
25307
|
var log37, DEBOUNCE_MS3, JsonFileSessionStore;
|
|
25077
25308
|
var init_session_store = __esm({
|
|
25078
25309
|
"src/core/sessions/session-store.ts"() {
|
|
@@ -25164,7 +25395,7 @@ var init_session_store = __esm({
|
|
|
25164
25395
|
version: 1,
|
|
25165
25396
|
sessions: Object.fromEntries(this.records)
|
|
25166
25397
|
};
|
|
25167
|
-
const dir =
|
|
25398
|
+
const dir = path47.dirname(this.filePath);
|
|
25168
25399
|
if (!fs41.existsSync(dir)) fs41.mkdirSync(dir, { recursive: true });
|
|
25169
25400
|
const tmpPath = `${this.filePath}.tmp`;
|
|
25170
25401
|
fs41.writeFileSync(tmpPath, JSON.stringify(data, null, 2));
|
|
@@ -25933,7 +26164,7 @@ __export(agent_catalog_exports, {
|
|
|
25933
26164
|
AgentCatalog: () => AgentCatalog
|
|
25934
26165
|
});
|
|
25935
26166
|
import * as fs42 from "fs";
|
|
25936
|
-
import * as
|
|
26167
|
+
import * as path48 from "path";
|
|
25937
26168
|
function stripNpmVersion(pkg) {
|
|
25938
26169
|
if (pkg.startsWith("@")) {
|
|
25939
26170
|
const slashIdx = pkg.indexOf("/");
|
|
@@ -26000,7 +26231,7 @@ var init_agent_catalog = __esm({
|
|
|
26000
26231
|
ttlHours: DEFAULT_TTL_HOURS,
|
|
26001
26232
|
data
|
|
26002
26233
|
};
|
|
26003
|
-
fs42.mkdirSync(
|
|
26234
|
+
fs42.mkdirSync(path48.dirname(this.cachePath), { recursive: true });
|
|
26004
26235
|
fs42.writeFileSync(this.cachePath, JSON.stringify(cache, null, 2), { mode: 384 });
|
|
26005
26236
|
this.enrichInstalledFromRegistry();
|
|
26006
26237
|
log40.info({ count: this.registryAgents.length }, "Registry updated");
|
|
@@ -26242,9 +26473,9 @@ var init_agent_catalog = __esm({
|
|
|
26242
26473
|
}
|
|
26243
26474
|
try {
|
|
26244
26475
|
const candidates = [
|
|
26245
|
-
|
|
26246
|
-
|
|
26247
|
-
|
|
26476
|
+
path48.join(import.meta.dirname, "data", "registry-snapshot.json"),
|
|
26477
|
+
path48.join(import.meta.dirname, "..", "data", "registry-snapshot.json"),
|
|
26478
|
+
path48.join(import.meta.dirname, "..", "..", "data", "registry-snapshot.json")
|
|
26248
26479
|
];
|
|
26249
26480
|
for (const candidate of candidates) {
|
|
26250
26481
|
if (fs42.existsSync(candidate)) {
|
|
@@ -26269,7 +26500,7 @@ __export(agent_store_exports, {
|
|
|
26269
26500
|
AgentStore: () => AgentStore
|
|
26270
26501
|
});
|
|
26271
26502
|
import * as fs43 from "fs";
|
|
26272
|
-
import * as
|
|
26503
|
+
import * as path49 from "path";
|
|
26273
26504
|
import { z as z10 } from "zod";
|
|
26274
26505
|
var log41, InstalledAgentSchema, AgentStoreSchema, AgentStore;
|
|
26275
26506
|
var init_agent_store = __esm({
|
|
@@ -26346,7 +26577,7 @@ var init_agent_store = __esm({
|
|
|
26346
26577
|
* may contain agent binary paths and environment variables.
|
|
26347
26578
|
*/
|
|
26348
26579
|
save() {
|
|
26349
|
-
fs43.mkdirSync(
|
|
26580
|
+
fs43.mkdirSync(path49.dirname(this.filePath), { recursive: true });
|
|
26350
26581
|
const tmpPath = this.filePath + ".tmp";
|
|
26351
26582
|
fs43.writeFileSync(tmpPath, JSON.stringify(this.data, null, 2), { mode: 384 });
|
|
26352
26583
|
fs43.renameSync(tmpPath, this.filePath);
|
|
@@ -26665,7 +26896,7 @@ var init_error_tracker = __esm({
|
|
|
26665
26896
|
|
|
26666
26897
|
// src/core/plugin/plugin-storage.ts
|
|
26667
26898
|
import fs44 from "fs";
|
|
26668
|
-
import
|
|
26899
|
+
import path50 from "path";
|
|
26669
26900
|
var PluginStorageImpl;
|
|
26670
26901
|
var init_plugin_storage = __esm({
|
|
26671
26902
|
"src/core/plugin/plugin-storage.ts"() {
|
|
@@ -26676,8 +26907,8 @@ var init_plugin_storage = __esm({
|
|
|
26676
26907
|
/** Serializes writes to prevent concurrent file corruption */
|
|
26677
26908
|
writeChain = Promise.resolve();
|
|
26678
26909
|
constructor(baseDir) {
|
|
26679
|
-
this.dataDir =
|
|
26680
|
-
this.kvPath =
|
|
26910
|
+
this.dataDir = path50.join(baseDir, "data");
|
|
26911
|
+
this.kvPath = path50.join(baseDir, "kv.json");
|
|
26681
26912
|
fs44.mkdirSync(baseDir, { recursive: true });
|
|
26682
26913
|
}
|
|
26683
26914
|
readKv() {
|
|
@@ -27802,7 +28033,7 @@ var init_core_items = __esm({
|
|
|
27802
28033
|
});
|
|
27803
28034
|
|
|
27804
28035
|
// src/core/core.ts
|
|
27805
|
-
import
|
|
28036
|
+
import path51 from "path";
|
|
27806
28037
|
import { nanoid as nanoid6 } from "nanoid";
|
|
27807
28038
|
var log45, OpenACPCore;
|
|
27808
28039
|
var init_core = __esm({
|
|
@@ -27828,6 +28059,7 @@ var init_core = __esm({
|
|
|
27828
28059
|
init_middleware_chain();
|
|
27829
28060
|
init_error_tracker();
|
|
27830
28061
|
init_log();
|
|
28062
|
+
init_native_stt();
|
|
27831
28063
|
init_events();
|
|
27832
28064
|
init_turn_context();
|
|
27833
28065
|
log45 = createChildLogger({ module: "core" });
|
|
@@ -27972,21 +28204,7 @@ var init_core = __esm({
|
|
|
27972
28204
|
const settingsMgr = this.settingsManager;
|
|
27973
28205
|
if (settingsMgr) {
|
|
27974
28206
|
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
|
-
};
|
|
28207
|
+
const newSpeechConfig = buildSpeechServiceConfig(pluginCfg);
|
|
27990
28208
|
speechSvc.refreshProviders(newSpeechConfig);
|
|
27991
28209
|
log45.info("Speech service config updated at runtime (from plugin settings)");
|
|
27992
28210
|
}
|
|
@@ -27995,7 +28213,7 @@ var init_core = __esm({
|
|
|
27995
28213
|
}
|
|
27996
28214
|
);
|
|
27997
28215
|
registerCoreMenuItems(this.menuRegistry);
|
|
27998
|
-
this.assistantRegistry.setInstanceRoot(
|
|
28216
|
+
this.assistantRegistry.setInstanceRoot(path51.dirname(ctx.root));
|
|
27999
28217
|
this.assistantRegistry.register(createSessionsSection(this));
|
|
28000
28218
|
this.assistantRegistry.register(createAgentsSection(this));
|
|
28001
28219
|
this.assistantRegistry.register(createConfigSection(this));
|
|
@@ -28429,8 +28647,8 @@ ${text5}`;
|
|
|
28429
28647
|
message: `Agent '${agentName}' not found`
|
|
28430
28648
|
};
|
|
28431
28649
|
}
|
|
28432
|
-
const { existsSync:
|
|
28433
|
-
if (!
|
|
28650
|
+
const { existsSync: existsSync21 } = await import("fs");
|
|
28651
|
+
if (!existsSync21(cwd)) {
|
|
28434
28652
|
return {
|
|
28435
28653
|
ok: false,
|
|
28436
28654
|
error: "invalid_cwd",
|
|
@@ -30148,11 +30366,11 @@ __export(instance_copy_exports, {
|
|
|
30148
30366
|
copyInstance: () => copyInstance
|
|
30149
30367
|
});
|
|
30150
30368
|
import fs45 from "fs";
|
|
30151
|
-
import
|
|
30369
|
+
import path52 from "path";
|
|
30152
30370
|
async function copyInstance(src, dst, opts) {
|
|
30153
30371
|
const { inheritableKeys = {}, onProgress } = opts;
|
|
30154
30372
|
fs45.mkdirSync(dst, { recursive: true });
|
|
30155
|
-
const configSrc =
|
|
30373
|
+
const configSrc = path52.join(src, "config.json");
|
|
30156
30374
|
if (fs45.existsSync(configSrc)) {
|
|
30157
30375
|
onProgress?.("Configuration", "start");
|
|
30158
30376
|
const config = JSON.parse(fs45.readFileSync(configSrc, "utf-8"));
|
|
@@ -30176,44 +30394,44 @@ async function copyInstance(src, dst, opts) {
|
|
|
30176
30394
|
}
|
|
30177
30395
|
}
|
|
30178
30396
|
}
|
|
30179
|
-
fs45.writeFileSync(
|
|
30397
|
+
fs45.writeFileSync(path52.join(dst, "config.json"), JSON.stringify(config, null, 2));
|
|
30180
30398
|
onProgress?.("Configuration", "done");
|
|
30181
30399
|
}
|
|
30182
|
-
const pluginsSrc =
|
|
30400
|
+
const pluginsSrc = path52.join(src, "plugins.json");
|
|
30183
30401
|
if (fs45.existsSync(pluginsSrc)) {
|
|
30184
30402
|
onProgress?.("Plugin list", "start");
|
|
30185
|
-
fs45.copyFileSync(pluginsSrc,
|
|
30403
|
+
fs45.copyFileSync(pluginsSrc, path52.join(dst, "plugins.json"));
|
|
30186
30404
|
onProgress?.("Plugin list", "done");
|
|
30187
30405
|
}
|
|
30188
|
-
const pluginsDir =
|
|
30406
|
+
const pluginsDir = path52.join(src, "plugins");
|
|
30189
30407
|
if (fs45.existsSync(pluginsDir)) {
|
|
30190
30408
|
onProgress?.("Plugins", "start");
|
|
30191
|
-
const dstPlugins =
|
|
30409
|
+
const dstPlugins = path52.join(dst, "plugins");
|
|
30192
30410
|
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,
|
|
30411
|
+
const pkgJson = path52.join(pluginsDir, "package.json");
|
|
30412
|
+
if (fs45.existsSync(pkgJson)) fs45.copyFileSync(pkgJson, path52.join(dstPlugins, "package.json"));
|
|
30413
|
+
const nodeModules = path52.join(pluginsDir, "node_modules");
|
|
30414
|
+
if (fs45.existsSync(nodeModules)) fs45.cpSync(nodeModules, path52.join(dstPlugins, "node_modules"), { recursive: true });
|
|
30197
30415
|
onProgress?.("Plugins", "done");
|
|
30198
30416
|
}
|
|
30199
|
-
const agentsJson =
|
|
30417
|
+
const agentsJson = path52.join(src, "agents.json");
|
|
30200
30418
|
if (fs45.existsSync(agentsJson)) {
|
|
30201
30419
|
onProgress?.("Agents", "start");
|
|
30202
|
-
fs45.copyFileSync(agentsJson,
|
|
30203
|
-
const agentsDir =
|
|
30204
|
-
if (fs45.existsSync(agentsDir)) fs45.cpSync(agentsDir,
|
|
30420
|
+
fs45.copyFileSync(agentsJson, path52.join(dst, "agents.json"));
|
|
30421
|
+
const agentsDir = path52.join(src, "agents");
|
|
30422
|
+
if (fs45.existsSync(agentsDir)) fs45.cpSync(agentsDir, path52.join(dst, "agents"), { recursive: true });
|
|
30205
30423
|
onProgress?.("Agents", "done");
|
|
30206
30424
|
}
|
|
30207
|
-
const binDir =
|
|
30425
|
+
const binDir = path52.join(src, "bin");
|
|
30208
30426
|
if (fs45.existsSync(binDir)) {
|
|
30209
30427
|
onProgress?.("Tools", "start");
|
|
30210
|
-
fs45.cpSync(binDir,
|
|
30428
|
+
fs45.cpSync(binDir, path52.join(dst, "bin"), { recursive: true });
|
|
30211
30429
|
onProgress?.("Tools", "done");
|
|
30212
30430
|
}
|
|
30213
|
-
const pluginDataSrc =
|
|
30431
|
+
const pluginDataSrc = path52.join(src, "plugins", "data");
|
|
30214
30432
|
if (fs45.existsSync(pluginDataSrc)) {
|
|
30215
30433
|
onProgress?.("Preferences", "start");
|
|
30216
|
-
copyPluginSettings(pluginDataSrc,
|
|
30434
|
+
copyPluginSettings(pluginDataSrc, path52.join(dst, "plugins", "data"), inheritableKeys);
|
|
30217
30435
|
onProgress?.("Preferences", "done");
|
|
30218
30436
|
}
|
|
30219
30437
|
}
|
|
@@ -30228,10 +30446,10 @@ function copyPluginSettings(srcData, dstData, inheritableKeys) {
|
|
|
30228
30446
|
if (key in settings) filtered[key] = settings[key];
|
|
30229
30447
|
}
|
|
30230
30448
|
if (Object.keys(filtered).length > 0) {
|
|
30231
|
-
const relative =
|
|
30232
|
-
const dstDir =
|
|
30449
|
+
const relative = path52.relative(srcData, path52.dirname(settingsPath));
|
|
30450
|
+
const dstDir = path52.join(dstData, relative);
|
|
30233
30451
|
fs45.mkdirSync(dstDir, { recursive: true });
|
|
30234
|
-
fs45.writeFileSync(
|
|
30452
|
+
fs45.writeFileSync(path52.join(dstDir, "settings.json"), JSON.stringify(filtered, null, 2));
|
|
30235
30453
|
}
|
|
30236
30454
|
} catch {
|
|
30237
30455
|
}
|
|
@@ -30242,15 +30460,15 @@ function walkPluginDirs(base, cb) {
|
|
|
30242
30460
|
for (const entry of fs45.readdirSync(base, { withFileTypes: true })) {
|
|
30243
30461
|
if (!entry.isDirectory()) continue;
|
|
30244
30462
|
if (entry.name.startsWith("@")) {
|
|
30245
|
-
const scopeDir =
|
|
30463
|
+
const scopeDir = path52.join(base, entry.name);
|
|
30246
30464
|
for (const sub of fs45.readdirSync(scopeDir, { withFileTypes: true })) {
|
|
30247
30465
|
if (!sub.isDirectory()) continue;
|
|
30248
30466
|
const pluginName = `${entry.name}/${sub.name}`;
|
|
30249
|
-
const settingsPath =
|
|
30467
|
+
const settingsPath = path52.join(scopeDir, sub.name, "settings.json");
|
|
30250
30468
|
if (fs45.existsSync(settingsPath)) cb(pluginName, settingsPath);
|
|
30251
30469
|
}
|
|
30252
30470
|
} else {
|
|
30253
|
-
const settingsPath =
|
|
30471
|
+
const settingsPath = path52.join(base, entry.name, "settings.json");
|
|
30254
30472
|
if (fs45.existsSync(settingsPath)) cb(entry.name, settingsPath);
|
|
30255
30473
|
}
|
|
30256
30474
|
}
|
|
@@ -30263,14 +30481,14 @@ var init_instance_copy = __esm({
|
|
|
30263
30481
|
|
|
30264
30482
|
// src/core/setup/git-protect.ts
|
|
30265
30483
|
import fs46 from "fs";
|
|
30266
|
-
import
|
|
30484
|
+
import path53 from "path";
|
|
30267
30485
|
function protectLocalInstance(projectDir) {
|
|
30268
30486
|
ensureGitignore(projectDir);
|
|
30269
30487
|
ensureClaudeMd(projectDir);
|
|
30270
30488
|
printSecurityWarning();
|
|
30271
30489
|
}
|
|
30272
30490
|
function ensureGitignore(projectDir) {
|
|
30273
|
-
const gitignorePath =
|
|
30491
|
+
const gitignorePath = path53.join(projectDir, ".gitignore");
|
|
30274
30492
|
const entry = ".openacp";
|
|
30275
30493
|
if (fs46.existsSync(gitignorePath)) {
|
|
30276
30494
|
const content = fs46.readFileSync(gitignorePath, "utf-8");
|
|
@@ -30290,7 +30508,7 @@ ${entry}
|
|
|
30290
30508
|
}
|
|
30291
30509
|
}
|
|
30292
30510
|
function ensureClaudeMd(projectDir) {
|
|
30293
|
-
const claudeMdPath =
|
|
30511
|
+
const claudeMdPath = path53.join(projectDir, "CLAUDE.md");
|
|
30294
30512
|
const marker = "## Local OpenACP Workspace";
|
|
30295
30513
|
if (fs46.existsSync(claudeMdPath)) {
|
|
30296
30514
|
const content = fs46.readFileSync(claudeMdPath, "utf-8");
|
|
@@ -30333,7 +30551,7 @@ var init_git_protect = __esm({
|
|
|
30333
30551
|
});
|
|
30334
30552
|
|
|
30335
30553
|
// src/core/setup/wizard.ts
|
|
30336
|
-
import * as
|
|
30554
|
+
import * as path54 from "path";
|
|
30337
30555
|
import * as fs47 from "fs";
|
|
30338
30556
|
import * as os10 from "os";
|
|
30339
30557
|
import * as clack7 from "@clack/prompts";
|
|
@@ -30381,7 +30599,7 @@ async function runSetup(configManager, opts) {
|
|
|
30381
30599
|
const instanceRoot = opts?.instanceRoot;
|
|
30382
30600
|
let instanceName = opts?.instanceName;
|
|
30383
30601
|
if (!instanceName) {
|
|
30384
|
-
const defaultName =
|
|
30602
|
+
const defaultName = path54.basename(path54.dirname(instanceRoot));
|
|
30385
30603
|
const locationHint = instanceRoot.replace(/\/.openacp$/, "").replace(os10.homedir(), "~");
|
|
30386
30604
|
const nameResult = await clack7.text({
|
|
30387
30605
|
message: `Name for this workspace (${locationHint})`,
|
|
@@ -30392,13 +30610,13 @@ async function runSetup(configManager, opts) {
|
|
|
30392
30610
|
instanceName = nameResult.trim();
|
|
30393
30611
|
}
|
|
30394
30612
|
const globalRoot = getGlobalRoot();
|
|
30395
|
-
const registryPath =
|
|
30613
|
+
const registryPath = path54.join(globalRoot, "instances.json");
|
|
30396
30614
|
const instanceRegistry = new InstanceRegistry(registryPath);
|
|
30397
30615
|
instanceRegistry.load();
|
|
30398
30616
|
let didCopy = false;
|
|
30399
30617
|
if (opts?.from) {
|
|
30400
|
-
const fromRoot =
|
|
30401
|
-
if (fs47.existsSync(
|
|
30618
|
+
const fromRoot = path54.join(opts.from, ".openacp");
|
|
30619
|
+
if (fs47.existsSync(path54.join(fromRoot, "config.json"))) {
|
|
30402
30620
|
const inheritableMap = buildInheritableKeysMap();
|
|
30403
30621
|
await copyInstance(fromRoot, instanceRoot, { inheritableKeys: inheritableMap });
|
|
30404
30622
|
didCopy = true;
|
|
@@ -30409,7 +30627,7 @@ async function runSetup(configManager, opts) {
|
|
|
30409
30627
|
}
|
|
30410
30628
|
if (!didCopy) {
|
|
30411
30629
|
const existingInstances = instanceRegistry.list().filter(
|
|
30412
|
-
(e) => fs47.existsSync(
|
|
30630
|
+
(e) => fs47.existsSync(path54.join(e.root, "config.json")) && e.root !== instanceRoot
|
|
30413
30631
|
);
|
|
30414
30632
|
if (existingInstances.length > 0) {
|
|
30415
30633
|
let singleLabel;
|
|
@@ -30417,7 +30635,7 @@ async function runSetup(configManager, opts) {
|
|
|
30417
30635
|
const e = existingInstances[0];
|
|
30418
30636
|
let name = e.id;
|
|
30419
30637
|
try {
|
|
30420
|
-
const cfg = JSON.parse(fs47.readFileSync(
|
|
30638
|
+
const cfg = JSON.parse(fs47.readFileSync(path54.join(e.root, "config.json"), "utf-8"));
|
|
30421
30639
|
if (cfg.instanceName) name = cfg.instanceName;
|
|
30422
30640
|
} catch {
|
|
30423
30641
|
}
|
|
@@ -30440,7 +30658,7 @@ async function runSetup(configManager, opts) {
|
|
|
30440
30658
|
options: existingInstances.map((e) => {
|
|
30441
30659
|
let name = e.id;
|
|
30442
30660
|
try {
|
|
30443
|
-
const cfg = JSON.parse(fs47.readFileSync(
|
|
30661
|
+
const cfg = JSON.parse(fs47.readFileSync(path54.join(e.root, "config.json"), "utf-8"));
|
|
30444
30662
|
if (cfg.instanceName) name = cfg.instanceName;
|
|
30445
30663
|
} catch {
|
|
30446
30664
|
}
|
|
@@ -30535,9 +30753,9 @@ async function runSetup(configManager, opts) {
|
|
|
30535
30753
|
if (channelId.startsWith("official:")) {
|
|
30536
30754
|
const npmPackage = channelId.slice("official:".length);
|
|
30537
30755
|
const { execFileSync: execFileSync9 } = await import("child_process");
|
|
30538
|
-
const pluginsDir =
|
|
30539
|
-
const nodeModulesDir =
|
|
30540
|
-
const installedPath =
|
|
30756
|
+
const pluginsDir = path54.join(instanceRoot, "plugins");
|
|
30757
|
+
const nodeModulesDir = path54.join(pluginsDir, "node_modules");
|
|
30758
|
+
const installedPath = path54.join(nodeModulesDir, npmPackage);
|
|
30541
30759
|
if (!fs47.existsSync(installedPath)) {
|
|
30542
30760
|
try {
|
|
30543
30761
|
clack7.log.step(`Installing ${npmPackage}...`);
|
|
@@ -30551,9 +30769,9 @@ async function runSetup(configManager, opts) {
|
|
|
30551
30769
|
}
|
|
30552
30770
|
}
|
|
30553
30771
|
try {
|
|
30554
|
-
const installedPkgPath =
|
|
30772
|
+
const installedPkgPath = path54.join(nodeModulesDir, npmPackage, "package.json");
|
|
30555
30773
|
const installedPkg = JSON.parse(fs47.readFileSync(installedPkgPath, "utf-8"));
|
|
30556
|
-
const pluginModule = await import(
|
|
30774
|
+
const pluginModule = await import(path54.join(nodeModulesDir, npmPackage, installedPkg.main ?? "dist/index.js"));
|
|
30557
30775
|
const plugin2 = pluginModule.default;
|
|
30558
30776
|
if (plugin2?.install) {
|
|
30559
30777
|
const installCtx = createInstallContext2({
|
|
@@ -30583,8 +30801,8 @@ async function runSetup(configManager, opts) {
|
|
|
30583
30801
|
if (channelId.startsWith("community:")) {
|
|
30584
30802
|
const npmPackage = channelId.slice("community:".length);
|
|
30585
30803
|
const { execFileSync: execFileSync9 } = await import("child_process");
|
|
30586
|
-
const pluginsDir =
|
|
30587
|
-
const nodeModulesDir =
|
|
30804
|
+
const pluginsDir = path54.join(instanceRoot, "plugins");
|
|
30805
|
+
const nodeModulesDir = path54.join(pluginsDir, "node_modules");
|
|
30588
30806
|
try {
|
|
30589
30807
|
execFileSync9("npm", ["install", npmPackage, "--prefix", pluginsDir, "--save", "--ignore-scripts"], {
|
|
30590
30808
|
stdio: "inherit",
|
|
@@ -30596,9 +30814,9 @@ async function runSetup(configManager, opts) {
|
|
|
30596
30814
|
}
|
|
30597
30815
|
try {
|
|
30598
30816
|
const { readFileSync: readFileSync18 } = await import("fs");
|
|
30599
|
-
const installedPkgPath =
|
|
30817
|
+
const installedPkgPath = path54.join(nodeModulesDir, npmPackage, "package.json");
|
|
30600
30818
|
const installedPkg = JSON.parse(readFileSync18(installedPkgPath, "utf-8"));
|
|
30601
|
-
const pluginModule = await import(
|
|
30819
|
+
const pluginModule = await import(path54.join(nodeModulesDir, npmPackage, installedPkg.main ?? "dist/index.js"));
|
|
30602
30820
|
const plugin2 = pluginModule.default;
|
|
30603
30821
|
if (plugin2?.install) {
|
|
30604
30822
|
const installCtx = createInstallContext2({
|
|
@@ -30651,7 +30869,7 @@ async function runSetup(configManager, opts) {
|
|
|
30651
30869
|
workspace: { allowExternalWorkspaces: true, security: { allowedPaths: [], envWhitelist: [] } },
|
|
30652
30870
|
logging: {
|
|
30653
30871
|
level: "info",
|
|
30654
|
-
logDir:
|
|
30872
|
+
logDir: path54.join(instanceRoot, "logs"),
|
|
30655
30873
|
maxFileSize: "10m",
|
|
30656
30874
|
maxFiles: 7,
|
|
30657
30875
|
sessionLogRetentionDays: 30
|
|
@@ -30678,7 +30896,7 @@ async function runSetup(configManager, opts) {
|
|
|
30678
30896
|
instanceRegistry.register(instanceId, instanceRoot);
|
|
30679
30897
|
await instanceRegistry.save();
|
|
30680
30898
|
}
|
|
30681
|
-
const projectDir =
|
|
30899
|
+
const projectDir = path54.dirname(instanceRoot);
|
|
30682
30900
|
protectLocalInstance(projectDir);
|
|
30683
30901
|
clack7.outro(`Config saved to ${configManager.getConfigPath()}`);
|
|
30684
30902
|
if (!opts?.skipRunMode) {
|
|
@@ -30757,7 +30975,7 @@ async function runReconfigure(configManager, settingsManager) {
|
|
|
30757
30975
|
await configureChannels(config, settingsManager);
|
|
30758
30976
|
}
|
|
30759
30977
|
if (choice === "agents") {
|
|
30760
|
-
const reconfigRoot =
|
|
30978
|
+
const reconfigRoot = path54.dirname(configManager.getConfigPath());
|
|
30761
30979
|
const { defaultAgent } = await setupAgents(reconfigRoot);
|
|
30762
30980
|
await configManager.save({ defaultAgent });
|
|
30763
30981
|
config = configManager.get();
|
|
@@ -30962,7 +31180,7 @@ __export(dev_loader_exports, {
|
|
|
30962
31180
|
});
|
|
30963
31181
|
import fs48 from "fs";
|
|
30964
31182
|
import os11 from "os";
|
|
30965
|
-
import
|
|
31183
|
+
import path55 from "path";
|
|
30966
31184
|
var loadCounter, DevPluginLoader;
|
|
30967
31185
|
var init_dev_loader = __esm({
|
|
30968
31186
|
"src/core/plugin/dev-loader.ts"() {
|
|
@@ -30972,24 +31190,24 @@ var init_dev_loader = __esm({
|
|
|
30972
31190
|
pluginPath;
|
|
30973
31191
|
lastTempDir = null;
|
|
30974
31192
|
constructor(pluginPath) {
|
|
30975
|
-
this.pluginPath =
|
|
31193
|
+
this.pluginPath = path55.resolve(pluginPath);
|
|
30976
31194
|
}
|
|
30977
31195
|
async load() {
|
|
30978
|
-
const distPath =
|
|
30979
|
-
const distIndex =
|
|
30980
|
-
const srcIndex =
|
|
31196
|
+
const distPath = path55.join(this.pluginPath, "dist");
|
|
31197
|
+
const distIndex = path55.join(distPath, "index.js");
|
|
31198
|
+
const srcIndex = path55.join(this.pluginPath, "src", "index.ts");
|
|
30981
31199
|
if (!fs48.existsSync(distIndex) && !fs48.existsSync(srcIndex)) {
|
|
30982
31200
|
throw new Error(`Plugin not found at ${this.pluginPath}. Expected dist/index.js or src/index.ts`);
|
|
30983
31201
|
}
|
|
30984
31202
|
if (!fs48.existsSync(distIndex)) {
|
|
30985
31203
|
throw new Error(`Built plugin not found at ${distIndex}. Run 'npm run build' first.`);
|
|
30986
31204
|
}
|
|
30987
|
-
const tempDir =
|
|
31205
|
+
const tempDir = path55.join(os11.tmpdir(), `openacp-dev-plugin-${Date.now()}-${++loadCounter}`);
|
|
30988
31206
|
fs48.cpSync(distPath, tempDir, { recursive: true });
|
|
30989
31207
|
const previousTempDir = this.lastTempDir;
|
|
30990
31208
|
this.lastTempDir = tempDir;
|
|
30991
31209
|
try {
|
|
30992
|
-
const mod = await import(`file://${
|
|
31210
|
+
const mod = await import(`file://${path55.join(tempDir, "index.js")}`);
|
|
30993
31211
|
const plugin2 = mod.default;
|
|
30994
31212
|
if (!plugin2 || !plugin2.name || !plugin2.setup) {
|
|
30995
31213
|
throw new Error(`Invalid plugin at ${distIndex}. Must export default OpenACPPlugin with name and setup().`);
|
|
@@ -31012,7 +31230,7 @@ var init_dev_loader = __esm({
|
|
|
31012
31230
|
}
|
|
31013
31231
|
/** Returns the path to the plugin's dist directory (the source of truth — NOT the temp copy). */
|
|
31014
31232
|
getDistPath() {
|
|
31015
|
-
return
|
|
31233
|
+
return path55.join(this.pluginPath, "dist");
|
|
31016
31234
|
}
|
|
31017
31235
|
};
|
|
31018
31236
|
}
|
|
@@ -31024,7 +31242,7 @@ __export(main_exports, {
|
|
|
31024
31242
|
RESTART_EXIT_CODE: () => RESTART_EXIT_CODE,
|
|
31025
31243
|
startServer: () => startServer
|
|
31026
31244
|
});
|
|
31027
|
-
import
|
|
31245
|
+
import path56 from "path";
|
|
31028
31246
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
31029
31247
|
import fs49 from "fs";
|
|
31030
31248
|
async function startServer(opts) {
|
|
@@ -31049,7 +31267,7 @@ async function startServer(opts) {
|
|
|
31049
31267
|
process.exit(1);
|
|
31050
31268
|
}
|
|
31051
31269
|
const globalRoot = getGlobalRoot();
|
|
31052
|
-
const reg = new InstanceRegistry(
|
|
31270
|
+
const reg = new InstanceRegistry(path56.join(globalRoot, "instances.json"));
|
|
31053
31271
|
reg.load();
|
|
31054
31272
|
const entry = reg.getByRoot(root);
|
|
31055
31273
|
opts = { ...opts, instanceContext: createInstanceContext({ id: entry?.id ?? randomUUID4(), root }) };
|
|
@@ -31137,22 +31355,22 @@ async function startServer(opts) {
|
|
|
31137
31355
|
try {
|
|
31138
31356
|
let modulePath;
|
|
31139
31357
|
if (name.startsWith("/") || name.startsWith(".")) {
|
|
31140
|
-
const resolved =
|
|
31141
|
-
const pkgPath =
|
|
31358
|
+
const resolved = path56.resolve(name);
|
|
31359
|
+
const pkgPath = path56.join(resolved, "package.json");
|
|
31142
31360
|
const pkg = JSON.parse(await fs49.promises.readFile(pkgPath, "utf-8"));
|
|
31143
|
-
modulePath =
|
|
31361
|
+
modulePath = path56.join(resolved, pkg.main || "dist/index.js");
|
|
31144
31362
|
} else {
|
|
31145
|
-
const nodeModulesDir =
|
|
31146
|
-
let pkgDir =
|
|
31147
|
-
if (!fs49.existsSync(
|
|
31363
|
+
const nodeModulesDir = path56.join(ctx.paths.plugins, "node_modules");
|
|
31364
|
+
let pkgDir = path56.join(nodeModulesDir, name);
|
|
31365
|
+
if (!fs49.existsSync(path56.join(pkgDir, "package.json"))) {
|
|
31148
31366
|
let found = false;
|
|
31149
31367
|
const scopes = fs49.existsSync(nodeModulesDir) ? fs49.readdirSync(nodeModulesDir).filter((d) => d.startsWith("@")) : [];
|
|
31150
31368
|
for (const scope of scopes) {
|
|
31151
|
-
const scopeDir =
|
|
31369
|
+
const scopeDir = path56.join(nodeModulesDir, scope);
|
|
31152
31370
|
const pkgs = fs49.readdirSync(scopeDir);
|
|
31153
31371
|
for (const pkg2 of pkgs) {
|
|
31154
|
-
const candidateDir =
|
|
31155
|
-
const candidatePkgPath =
|
|
31372
|
+
const candidateDir = path56.join(scopeDir, pkg2);
|
|
31373
|
+
const candidatePkgPath = path56.join(candidateDir, "package.json");
|
|
31156
31374
|
if (fs49.existsSync(candidatePkgPath)) {
|
|
31157
31375
|
try {
|
|
31158
31376
|
const candidatePkg = JSON.parse(fs49.readFileSync(candidatePkgPath, "utf-8"));
|
|
@@ -31169,9 +31387,9 @@ async function startServer(opts) {
|
|
|
31169
31387
|
if (found) break;
|
|
31170
31388
|
}
|
|
31171
31389
|
}
|
|
31172
|
-
const pkgJsonPath =
|
|
31390
|
+
const pkgJsonPath = path56.join(pkgDir, "package.json");
|
|
31173
31391
|
const pkg = JSON.parse(await fs49.promises.readFile(pkgJsonPath, "utf-8"));
|
|
31174
|
-
modulePath =
|
|
31392
|
+
modulePath = path56.join(pkgDir, pkg.main || "dist/index.js");
|
|
31175
31393
|
}
|
|
31176
31394
|
log.debug({ plugin: name, modulePath }, "Loading community plugin");
|
|
31177
31395
|
const mod = await import(modulePath);
|
|
@@ -31343,7 +31561,7 @@ async function startServer(opts) {
|
|
|
31343
31561
|
await core.start();
|
|
31344
31562
|
try {
|
|
31345
31563
|
const globalRoot = getGlobalRoot();
|
|
31346
|
-
const registryPath =
|
|
31564
|
+
const registryPath = path56.join(globalRoot, "instances.json");
|
|
31347
31565
|
const instanceReg = new InstanceRegistry(registryPath);
|
|
31348
31566
|
await instanceReg.load();
|
|
31349
31567
|
if (!instanceReg.getByRoot(ctx.root)) {
|
|
@@ -31515,7 +31733,7 @@ var restart_exports = {};
|
|
|
31515
31733
|
__export(restart_exports, {
|
|
31516
31734
|
cmdRestart: () => cmdRestart
|
|
31517
31735
|
});
|
|
31518
|
-
import
|
|
31736
|
+
import path57 from "path";
|
|
31519
31737
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
31520
31738
|
async function cmdRestart(args2 = [], instanceRoot) {
|
|
31521
31739
|
const json = isJsonMode(args2);
|
|
@@ -31555,7 +31773,7 @@ Stops the running daemon (if any) and starts a new one.
|
|
|
31555
31773
|
if (!json && stopResult.stopped) {
|
|
31556
31774
|
console.log(`Stopped daemon (was PID ${stopResult.pid})`);
|
|
31557
31775
|
}
|
|
31558
|
-
const cm = new ConfigManager2(
|
|
31776
|
+
const cm = new ConfigManager2(path57.join(root, "config.json"));
|
|
31559
31777
|
if (!await cm.exists()) {
|
|
31560
31778
|
if (json) jsonError(ErrorCodes.CONFIG_NOT_FOUND, 'No config found. Run "openacp" first to set up.');
|
|
31561
31779
|
console.error('No config found. Run "openacp" first to set up.');
|
|
@@ -31576,7 +31794,7 @@ Stops the running daemon (if any) and starts a new one.
|
|
|
31576
31794
|
printInstanceHint(root);
|
|
31577
31795
|
console.log("Starting in foreground mode...");
|
|
31578
31796
|
const { startServer: startServer2 } = await Promise.resolve().then(() => (init_main(), main_exports));
|
|
31579
|
-
const reg = new InstanceRegistry(
|
|
31797
|
+
const reg = new InstanceRegistry(path57.join(getGlobalRoot(), "instances.json"));
|
|
31580
31798
|
reg.load();
|
|
31581
31799
|
const existingEntry = reg.getByRoot(root);
|
|
31582
31800
|
const ctx = createInstanceContext({
|
|
@@ -31625,7 +31843,7 @@ __export(status_exports, {
|
|
|
31625
31843
|
readInstanceInfo: () => readInstanceInfo
|
|
31626
31844
|
});
|
|
31627
31845
|
import fs50 from "fs";
|
|
31628
|
-
import
|
|
31846
|
+
import path58 from "path";
|
|
31629
31847
|
import os12 from "os";
|
|
31630
31848
|
async function cmdStatus(args2 = [], instanceRoot) {
|
|
31631
31849
|
const json = isJsonMode(args2);
|
|
@@ -31643,7 +31861,7 @@ async function cmdStatus(args2 = [], instanceRoot) {
|
|
|
31643
31861
|
await showSingleInstance(root, json);
|
|
31644
31862
|
}
|
|
31645
31863
|
async function showAllInstances(json = false) {
|
|
31646
|
-
const registryPath =
|
|
31864
|
+
const registryPath = path58.join(getGlobalRoot(), "instances.json");
|
|
31647
31865
|
const registry = new InstanceRegistry(registryPath);
|
|
31648
31866
|
await registry.load();
|
|
31649
31867
|
const instances = registry.list();
|
|
@@ -31686,7 +31904,7 @@ async function showAllInstances(json = false) {
|
|
|
31686
31904
|
console.log("");
|
|
31687
31905
|
}
|
|
31688
31906
|
async function showInstanceById(id, json = false) {
|
|
31689
|
-
const registryPath =
|
|
31907
|
+
const registryPath = path58.join(getGlobalRoot(), "instances.json");
|
|
31690
31908
|
const registry = new InstanceRegistry(registryPath);
|
|
31691
31909
|
await registry.load();
|
|
31692
31910
|
const entry = registry.get(id);
|
|
@@ -31701,7 +31919,7 @@ async function showSingleInstance(root, json = false) {
|
|
|
31701
31919
|
const info = readInstanceInfo(root);
|
|
31702
31920
|
if (json) {
|
|
31703
31921
|
jsonSuccess({
|
|
31704
|
-
id:
|
|
31922
|
+
id: path58.basename(root),
|
|
31705
31923
|
name: info.name,
|
|
31706
31924
|
status: info.pid ? "online" : "offline",
|
|
31707
31925
|
pid: info.pid,
|
|
@@ -31732,13 +31950,13 @@ function readInstanceInfo(root) {
|
|
|
31732
31950
|
channels: []
|
|
31733
31951
|
};
|
|
31734
31952
|
try {
|
|
31735
|
-
const config = JSON.parse(fs50.readFileSync(
|
|
31953
|
+
const config = JSON.parse(fs50.readFileSync(path58.join(root, "config.json"), "utf-8"));
|
|
31736
31954
|
result.name = config.instanceName ?? null;
|
|
31737
31955
|
result.runMode = config.runMode ?? null;
|
|
31738
31956
|
} catch {
|
|
31739
31957
|
}
|
|
31740
31958
|
try {
|
|
31741
|
-
const pid = parseInt(fs50.readFileSync(
|
|
31959
|
+
const pid = parseInt(fs50.readFileSync(path58.join(root, "openacp.pid"), "utf-8").trim());
|
|
31742
31960
|
if (!isNaN(pid)) {
|
|
31743
31961
|
process.kill(pid, 0);
|
|
31744
31962
|
result.pid = pid;
|
|
@@ -31746,19 +31964,19 @@ function readInstanceInfo(root) {
|
|
|
31746
31964
|
} catch {
|
|
31747
31965
|
}
|
|
31748
31966
|
try {
|
|
31749
|
-
const port = parseInt(fs50.readFileSync(
|
|
31967
|
+
const port = parseInt(fs50.readFileSync(path58.join(root, "api.port"), "utf-8").trim());
|
|
31750
31968
|
if (!isNaN(port)) result.apiPort = port;
|
|
31751
31969
|
} catch {
|
|
31752
31970
|
}
|
|
31753
31971
|
try {
|
|
31754
|
-
const tunnels = JSON.parse(fs50.readFileSync(
|
|
31972
|
+
const tunnels = JSON.parse(fs50.readFileSync(path58.join(root, "tunnels.json"), "utf-8"));
|
|
31755
31973
|
const entries = Object.values(tunnels);
|
|
31756
31974
|
const systemEntry = entries.find((t) => t.type === "system");
|
|
31757
31975
|
if (systemEntry?.port) result.tunnelPort = systemEntry.port;
|
|
31758
31976
|
} catch {
|
|
31759
31977
|
}
|
|
31760
31978
|
try {
|
|
31761
|
-
const plugins = JSON.parse(fs50.readFileSync(
|
|
31979
|
+
const plugins = JSON.parse(fs50.readFileSync(path58.join(root, "plugins.json"), "utf-8"));
|
|
31762
31980
|
const adapterMap = [
|
|
31763
31981
|
{ pluginName: "@openacp/telegram", channelId: "telegram" },
|
|
31764
31982
|
{ pluginName: "@openacp/discord-adapter", channelId: "discord" },
|
|
@@ -31776,7 +31994,7 @@ function readInstanceInfo(root) {
|
|
|
31776
31994
|
function formatInstanceStatus(root) {
|
|
31777
31995
|
const info = readInstanceInfo(root);
|
|
31778
31996
|
if (!info.pid) return null;
|
|
31779
|
-
const workspaceDir =
|
|
31997
|
+
const workspaceDir = path58.dirname(root);
|
|
31780
31998
|
const displayPath = workspaceDir.replace(os12.homedir(), "~");
|
|
31781
31999
|
const lines = [];
|
|
31782
32000
|
lines.push(` PID: ${info.pid}`);
|
|
@@ -31845,7 +32063,7 @@ var config_editor_exports = {};
|
|
|
31845
32063
|
__export(config_editor_exports, {
|
|
31846
32064
|
runConfigEditor: () => runConfigEditor
|
|
31847
32065
|
});
|
|
31848
|
-
import * as
|
|
32066
|
+
import * as path59 from "path";
|
|
31849
32067
|
import * as clack8 from "@clack/prompts";
|
|
31850
32068
|
async function select8(opts) {
|
|
31851
32069
|
const result = await clack8.select({
|
|
@@ -32399,7 +32617,7 @@ async function runConfigEditor(configManager, mode = "file", apiPort, settingsMa
|
|
|
32399
32617
|
await configManager.load();
|
|
32400
32618
|
const config = configManager.get();
|
|
32401
32619
|
const updates = {};
|
|
32402
|
-
const instanceRoot =
|
|
32620
|
+
const instanceRoot = path59.dirname(configManager.getConfigPath());
|
|
32403
32621
|
console.log(`
|
|
32404
32622
|
${c2.cyan}${c2.bold}OpenACP Config Editor${c2.reset}`);
|
|
32405
32623
|
console.log(dim2(`Config: ${configManager.getConfigPath()}`));
|
|
@@ -32456,17 +32674,17 @@ ${c2.cyan}${c2.bold}OpenACP Config Editor${c2.reset}`);
|
|
|
32456
32674
|
async function sendConfigViaApi(port, updates) {
|
|
32457
32675
|
const { apiCall: call } = await Promise.resolve().then(() => (init_api_client(), api_client_exports));
|
|
32458
32676
|
const paths = flattenToPaths(updates);
|
|
32459
|
-
for (const { path:
|
|
32677
|
+
for (const { path: path72, value } of paths) {
|
|
32460
32678
|
const res = await call(port, "/api/config", {
|
|
32461
32679
|
method: "PATCH",
|
|
32462
32680
|
headers: { "Content-Type": "application/json" },
|
|
32463
|
-
body: JSON.stringify({ path:
|
|
32681
|
+
body: JSON.stringify({ path: path72, value })
|
|
32464
32682
|
});
|
|
32465
32683
|
const data = await res.json();
|
|
32466
32684
|
if (!res.ok) {
|
|
32467
|
-
console.log(warn2(`Failed to update ${
|
|
32685
|
+
console.log(warn2(`Failed to update ${path72}: ${data.error}`));
|
|
32468
32686
|
} else if (data.needsRestart) {
|
|
32469
|
-
console.log(warn2(`${
|
|
32687
|
+
console.log(warn2(`${path72} updated \u2014 restart required`));
|
|
32470
32688
|
}
|
|
32471
32689
|
}
|
|
32472
32690
|
}
|
|
@@ -32576,24 +32794,24 @@ __export(migration_exports, {
|
|
|
32576
32794
|
migrateGlobalInstance: () => migrateGlobalInstance
|
|
32577
32795
|
});
|
|
32578
32796
|
import fs55 from "fs";
|
|
32579
|
-
import
|
|
32797
|
+
import path69 from "path";
|
|
32580
32798
|
import os15 from "os";
|
|
32581
32799
|
import { randomUUID as randomUUID8 } from "crypto";
|
|
32582
32800
|
async function migrateGlobalInstance() {
|
|
32583
32801
|
const globalRoot = getGlobalRoot();
|
|
32584
|
-
const globalConfig =
|
|
32802
|
+
const globalConfig = path69.join(globalRoot, "config.json");
|
|
32585
32803
|
if (!fs55.existsSync(globalConfig)) return null;
|
|
32586
|
-
let baseDir =
|
|
32804
|
+
let baseDir = path69.join(os15.homedir(), "openacp-workspace");
|
|
32587
32805
|
try {
|
|
32588
32806
|
const raw = JSON.parse(fs55.readFileSync(globalConfig, "utf-8"));
|
|
32589
32807
|
if (raw.workspace?.baseDir) {
|
|
32590
32808
|
const configured = raw.workspace.baseDir;
|
|
32591
|
-
baseDir = configured.startsWith("~") ?
|
|
32809
|
+
baseDir = configured.startsWith("~") ? path69.join(os15.homedir(), configured.slice(1)) : configured;
|
|
32592
32810
|
}
|
|
32593
32811
|
} catch {
|
|
32594
32812
|
}
|
|
32595
|
-
const targetRoot =
|
|
32596
|
-
if (
|
|
32813
|
+
const targetRoot = path69.join(baseDir, ".openacp");
|
|
32814
|
+
if (path69.resolve(targetRoot) === path69.resolve(globalRoot)) {
|
|
32597
32815
|
return null;
|
|
32598
32816
|
}
|
|
32599
32817
|
const instanceFiles = [
|
|
@@ -32607,34 +32825,34 @@ async function migrateGlobalInstance() {
|
|
|
32607
32825
|
const instanceDirs = ["plugins", "logs", "history", "files"];
|
|
32608
32826
|
fs55.mkdirSync(targetRoot, { recursive: true });
|
|
32609
32827
|
for (const file of instanceFiles) {
|
|
32610
|
-
const src =
|
|
32611
|
-
const dst =
|
|
32828
|
+
const src = path69.join(globalRoot, file);
|
|
32829
|
+
const dst = path69.join(targetRoot, file);
|
|
32612
32830
|
if (fs55.existsSync(src)) {
|
|
32613
32831
|
fs55.cpSync(src, dst, { force: true });
|
|
32614
32832
|
fs55.rmSync(src);
|
|
32615
32833
|
}
|
|
32616
32834
|
}
|
|
32617
32835
|
for (const dir of instanceDirs) {
|
|
32618
|
-
const src =
|
|
32619
|
-
const dst =
|
|
32836
|
+
const src = path69.join(globalRoot, dir);
|
|
32837
|
+
const dst = path69.join(targetRoot, dir);
|
|
32620
32838
|
if (fs55.existsSync(src)) {
|
|
32621
32839
|
fs55.cpSync(src, dst, { recursive: true, force: true });
|
|
32622
32840
|
fs55.rmSync(src, { recursive: true, force: true });
|
|
32623
32841
|
}
|
|
32624
32842
|
}
|
|
32625
|
-
const srcCache =
|
|
32626
|
-
const dstCache =
|
|
32843
|
+
const srcCache = path69.join(globalRoot, "cache");
|
|
32844
|
+
const dstCache = path69.join(targetRoot, "cache");
|
|
32627
32845
|
if (fs55.existsSync(srcCache)) {
|
|
32628
32846
|
fs55.mkdirSync(dstCache, { recursive: true });
|
|
32629
32847
|
for (const entry of fs55.readdirSync(srcCache)) {
|
|
32630
32848
|
if (entry === "registry-cache.json") continue;
|
|
32631
|
-
const s =
|
|
32632
|
-
const d =
|
|
32849
|
+
const s = path69.join(srcCache, entry);
|
|
32850
|
+
const d = path69.join(dstCache, entry);
|
|
32633
32851
|
fs55.cpSync(s, d, { recursive: true, force: true });
|
|
32634
32852
|
fs55.rmSync(s, { recursive: true, force: true });
|
|
32635
32853
|
}
|
|
32636
32854
|
}
|
|
32637
|
-
const migratedConfigPath =
|
|
32855
|
+
const migratedConfigPath = path69.join(targetRoot, "config.json");
|
|
32638
32856
|
try {
|
|
32639
32857
|
const config = JSON.parse(fs55.readFileSync(migratedConfigPath, "utf-8"));
|
|
32640
32858
|
if (config.workspace?.baseDir) {
|
|
@@ -32643,7 +32861,7 @@ async function migrateGlobalInstance() {
|
|
|
32643
32861
|
fs55.writeFileSync(migratedConfigPath, JSON.stringify(config, null, 2));
|
|
32644
32862
|
} catch {
|
|
32645
32863
|
}
|
|
32646
|
-
const registryPath =
|
|
32864
|
+
const registryPath = path69.join(globalRoot, "instances.json");
|
|
32647
32865
|
try {
|
|
32648
32866
|
const registry = new InstanceRegistry(registryPath);
|
|
32649
32867
|
registry.load();
|
|
@@ -32675,17 +32893,17 @@ __export(instance_prompt_exports, {
|
|
|
32675
32893
|
promptForInstance: () => promptForInstance
|
|
32676
32894
|
});
|
|
32677
32895
|
import fs56 from "fs";
|
|
32678
|
-
import
|
|
32896
|
+
import path70 from "path";
|
|
32679
32897
|
import os16 from "os";
|
|
32680
32898
|
async function promptForInstance(opts) {
|
|
32681
32899
|
const globalRoot = getGlobalRoot();
|
|
32682
|
-
const globalConfigExists = fs56.existsSync(
|
|
32900
|
+
const globalConfigExists = fs56.existsSync(path70.join(globalRoot, "config.json"));
|
|
32683
32901
|
const cwd = process.cwd();
|
|
32684
|
-
const isHomeDir =
|
|
32685
|
-
const defaultWorkspace =
|
|
32686
|
-
const createRoot = isHomeDir ?
|
|
32902
|
+
const isHomeDir = path70.resolve(cwd) === path70.resolve(os16.homedir());
|
|
32903
|
+
const defaultWorkspace = path70.join(os16.homedir(), "openacp-workspace");
|
|
32904
|
+
const createRoot = isHomeDir ? path70.join(defaultWorkspace, ".openacp") : path70.join(cwd, ".openacp");
|
|
32687
32905
|
const detectedParent = findParentInstance(cwd, globalRoot);
|
|
32688
|
-
const registryPath =
|
|
32906
|
+
const registryPath = path70.join(globalRoot, "instances.json");
|
|
32689
32907
|
const registry = new InstanceRegistry(registryPath);
|
|
32690
32908
|
registry.load();
|
|
32691
32909
|
const instances = registry.list().filter((e) => fs56.existsSync(e.root));
|
|
@@ -32717,24 +32935,24 @@ async function promptForInstance(opts) {
|
|
|
32717
32935
|
const instanceOptions = instances.filter((e) => !detectedParent || e.root !== detectedParent).map((e) => {
|
|
32718
32936
|
let name = e.id;
|
|
32719
32937
|
try {
|
|
32720
|
-
const raw = fs56.readFileSync(
|
|
32938
|
+
const raw = fs56.readFileSync(path70.join(e.root, "config.json"), "utf-8");
|
|
32721
32939
|
const parsed = JSON.parse(raw);
|
|
32722
32940
|
if (parsed.instanceName) name = parsed.instanceName;
|
|
32723
32941
|
} catch {
|
|
32724
32942
|
}
|
|
32725
|
-
const workspaceDir =
|
|
32943
|
+
const workspaceDir = path70.dirname(e.root);
|
|
32726
32944
|
const displayPath = workspaceDir.replace(os16.homedir(), "~");
|
|
32727
32945
|
return { value: e.root, label: `${name} (${displayPath})` };
|
|
32728
32946
|
});
|
|
32729
32947
|
if (detectedParent) {
|
|
32730
|
-
let name =
|
|
32948
|
+
let name = path70.basename(path70.dirname(detectedParent));
|
|
32731
32949
|
try {
|
|
32732
|
-
const raw = fs56.readFileSync(
|
|
32950
|
+
const raw = fs56.readFileSync(path70.join(detectedParent, "config.json"), "utf-8");
|
|
32733
32951
|
const parsed = JSON.parse(raw);
|
|
32734
32952
|
if (parsed.instanceName) name = parsed.instanceName;
|
|
32735
32953
|
} catch {
|
|
32736
32954
|
}
|
|
32737
|
-
const workspaceDir =
|
|
32955
|
+
const workspaceDir = path70.dirname(detectedParent);
|
|
32738
32956
|
const displayPath = workspaceDir.replace(os16.homedir(), "~");
|
|
32739
32957
|
instanceOptions.unshift({ value: detectedParent, label: `${name} (${displayPath})` });
|
|
32740
32958
|
}
|
|
@@ -32773,11 +32991,11 @@ async function promptForInstance(opts) {
|
|
|
32773
32991
|
return choice;
|
|
32774
32992
|
}
|
|
32775
32993
|
function findParentInstance(cwd, globalRoot) {
|
|
32776
|
-
let dir =
|
|
32994
|
+
let dir = path70.dirname(cwd);
|
|
32777
32995
|
while (true) {
|
|
32778
|
-
const candidate =
|
|
32779
|
-
if (candidate !== globalRoot && fs56.existsSync(
|
|
32780
|
-
const parent =
|
|
32996
|
+
const candidate = path70.join(dir, ".openacp");
|
|
32997
|
+
if (candidate !== globalRoot && fs56.existsSync(path70.join(candidate, "config.json"))) return candidate;
|
|
32998
|
+
const parent = path70.dirname(dir);
|
|
32781
32999
|
if (parent === dir) break;
|
|
32782
33000
|
dir = parent;
|
|
32783
33001
|
}
|
|
@@ -32793,7 +33011,7 @@ var init_instance_prompt = __esm({
|
|
|
32793
33011
|
|
|
32794
33012
|
// src/cli.ts
|
|
32795
33013
|
import { setDefaultAutoSelectFamily } from "net";
|
|
32796
|
-
import
|
|
33014
|
+
import path71 from "path";
|
|
32797
33015
|
|
|
32798
33016
|
// src/cli/commands/help.ts
|
|
32799
33017
|
function printHelp() {
|
|
@@ -32937,10 +33155,10 @@ Shows all plugins registered in the plugin registry.
|
|
|
32937
33155
|
`);
|
|
32938
33156
|
return;
|
|
32939
33157
|
}
|
|
32940
|
-
const
|
|
33158
|
+
const path72 = await import("path");
|
|
32941
33159
|
const { PluginRegistry: PluginRegistry2 } = await Promise.resolve().then(() => (init_plugin_registry(), plugin_registry_exports));
|
|
32942
33160
|
const root = instanceRoot;
|
|
32943
|
-
const registryPath =
|
|
33161
|
+
const registryPath = path72.join(root, "plugins.json");
|
|
32944
33162
|
const registry = new PluginRegistry2(registryPath);
|
|
32945
33163
|
await registry.load();
|
|
32946
33164
|
const plugins = registry.list();
|
|
@@ -33076,10 +33294,10 @@ async function cmdPlugin(args2 = [], instanceRoot) {
|
|
|
33076
33294
|
}
|
|
33077
33295
|
async function setPluginEnabled(name, enabled, instanceRoot, json = false) {
|
|
33078
33296
|
if (json) await muteForJson();
|
|
33079
|
-
const
|
|
33297
|
+
const path72 = await import("path");
|
|
33080
33298
|
const { PluginRegistry: PluginRegistry2 } = await Promise.resolve().then(() => (init_plugin_registry(), plugin_registry_exports));
|
|
33081
33299
|
const root = instanceRoot;
|
|
33082
|
-
const registryPath =
|
|
33300
|
+
const registryPath = path72.join(root, "plugins.json");
|
|
33083
33301
|
const registry = new PluginRegistry2(registryPath);
|
|
33084
33302
|
await registry.load();
|
|
33085
33303
|
const entry = registry.get(name);
|
|
@@ -33094,7 +33312,7 @@ async function setPluginEnabled(name, enabled, instanceRoot, json = false) {
|
|
|
33094
33312
|
console.log(`Plugin ${name} ${enabled ? "enabled" : "disabled"}. Restart to apply.`);
|
|
33095
33313
|
}
|
|
33096
33314
|
async function configurePlugin(name, instanceRoot) {
|
|
33097
|
-
const
|
|
33315
|
+
const path72 = await import("path");
|
|
33098
33316
|
const { corePlugins: corePlugins2 } = await Promise.resolve().then(() => (init_core_plugins(), core_plugins_exports));
|
|
33099
33317
|
const { SettingsManager: SettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
|
|
33100
33318
|
const { createInstallContext: createInstallContext2 } = await Promise.resolve().then(() => (init_install_context(), install_context_exports));
|
|
@@ -33104,7 +33322,7 @@ async function configurePlugin(name, instanceRoot) {
|
|
|
33104
33322
|
process.exit(1);
|
|
33105
33323
|
}
|
|
33106
33324
|
const root = instanceRoot;
|
|
33107
|
-
const basePath =
|
|
33325
|
+
const basePath = path72.join(root, "plugins", "data");
|
|
33108
33326
|
const settingsManager = new SettingsManager2(basePath);
|
|
33109
33327
|
const ctx = createInstallContext2({ pluginName: name, settingsManager, basePath });
|
|
33110
33328
|
if (plugin2.configure) {
|
|
@@ -33117,7 +33335,7 @@ async function configurePlugin(name, instanceRoot) {
|
|
|
33117
33335
|
}
|
|
33118
33336
|
async function installPlugin(input2, instanceRoot, json = false) {
|
|
33119
33337
|
if (json) await muteForJson();
|
|
33120
|
-
const
|
|
33338
|
+
const path72 = await import("path");
|
|
33121
33339
|
const { execFileSync: execFileSync9 } = await import("child_process");
|
|
33122
33340
|
const { getCurrentVersion: getCurrentVersion2 } = await Promise.resolve().then(() => (init_version(), version_exports));
|
|
33123
33341
|
const { SettingsManager: SettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
|
|
@@ -33168,9 +33386,9 @@ async function installPlugin(input2, instanceRoot, json = false) {
|
|
|
33168
33386
|
if (!json) console.log(`Installing ${installSpec}...`);
|
|
33169
33387
|
const { corePlugins: corePlugins2 } = await Promise.resolve().then(() => (init_core_plugins(), core_plugins_exports));
|
|
33170
33388
|
const builtinPlugin = corePlugins2.find((p2) => p2.name === pkgName);
|
|
33171
|
-
const basePath =
|
|
33389
|
+
const basePath = path72.join(root, "plugins", "data");
|
|
33172
33390
|
const settingsManager = new SettingsManager2(basePath);
|
|
33173
|
-
const registryPath =
|
|
33391
|
+
const registryPath = path72.join(root, "plugins.json");
|
|
33174
33392
|
const pluginRegistry = new PluginRegistry2(registryPath);
|
|
33175
33393
|
await pluginRegistry.load();
|
|
33176
33394
|
if (builtinPlugin) {
|
|
@@ -33190,8 +33408,8 @@ async function installPlugin(input2, instanceRoot, json = false) {
|
|
|
33190
33408
|
console.log(`\u2713 ${builtinPlugin.name} installed! Restart to activate.`);
|
|
33191
33409
|
return;
|
|
33192
33410
|
}
|
|
33193
|
-
const pluginsDir =
|
|
33194
|
-
const nodeModulesDir =
|
|
33411
|
+
const pluginsDir = path72.join(root, "plugins");
|
|
33412
|
+
const nodeModulesDir = path72.join(pluginsDir, "node_modules");
|
|
33195
33413
|
try {
|
|
33196
33414
|
execFileSync9("npm", ["install", installSpec, "--prefix", pluginsDir, "--save"], {
|
|
33197
33415
|
stdio: json ? "pipe" : "inherit",
|
|
@@ -33205,8 +33423,8 @@ async function installPlugin(input2, instanceRoot, json = false) {
|
|
|
33205
33423
|
const cliVersion = getCurrentVersion2();
|
|
33206
33424
|
const isLocalPath = pkgName.startsWith("/") || pkgName.startsWith(".");
|
|
33207
33425
|
try {
|
|
33208
|
-
const pluginRoot = isLocalPath ?
|
|
33209
|
-
const installedPkgPath =
|
|
33426
|
+
const pluginRoot = isLocalPath ? path72.resolve(pkgName) : path72.join(nodeModulesDir, pkgName);
|
|
33427
|
+
const installedPkgPath = path72.join(pluginRoot, "package.json");
|
|
33210
33428
|
const { readFileSync: readFileSync18 } = await import("fs");
|
|
33211
33429
|
const installedPkg = JSON.parse(readFileSync18(installedPkgPath, "utf-8"));
|
|
33212
33430
|
const minVersion = installedPkg.engines?.openacp?.replace(/[>=^~\s]/g, "");
|
|
@@ -33221,7 +33439,7 @@ async function installPlugin(input2, instanceRoot, json = false) {
|
|
|
33221
33439
|
}
|
|
33222
33440
|
}
|
|
33223
33441
|
}
|
|
33224
|
-
const pluginModule = await import(
|
|
33442
|
+
const pluginModule = await import(path72.join(pluginRoot, installedPkg.main ?? "dist/index.js"));
|
|
33225
33443
|
const plugin2 = pluginModule.default;
|
|
33226
33444
|
if (plugin2?.install) {
|
|
33227
33445
|
const ctx = createInstallContext2({ pluginName: plugin2.name ?? pkgName, settingsManager, basePath });
|
|
@@ -33251,11 +33469,11 @@ async function installPlugin(input2, instanceRoot, json = false) {
|
|
|
33251
33469
|
}
|
|
33252
33470
|
async function uninstallPlugin(name, purge, instanceRoot, json = false) {
|
|
33253
33471
|
if (json) await muteForJson();
|
|
33254
|
-
const
|
|
33472
|
+
const path72 = await import("path");
|
|
33255
33473
|
const fs57 = await import("fs");
|
|
33256
33474
|
const { PluginRegistry: PluginRegistry2 } = await Promise.resolve().then(() => (init_plugin_registry(), plugin_registry_exports));
|
|
33257
33475
|
const root = instanceRoot;
|
|
33258
|
-
const registryPath =
|
|
33476
|
+
const registryPath = path72.join(root, "plugins.json");
|
|
33259
33477
|
const registry = new PluginRegistry2(registryPath);
|
|
33260
33478
|
await registry.load();
|
|
33261
33479
|
const entry = registry.get(name);
|
|
@@ -33275,7 +33493,7 @@ async function uninstallPlugin(name, purge, instanceRoot, json = false) {
|
|
|
33275
33493
|
if (plugin2?.uninstall) {
|
|
33276
33494
|
const { SettingsManager: SettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
|
|
33277
33495
|
const { createInstallContext: createInstallContext2 } = await Promise.resolve().then(() => (init_install_context(), install_context_exports));
|
|
33278
|
-
const basePath =
|
|
33496
|
+
const basePath = path72.join(root, "plugins", "data");
|
|
33279
33497
|
const settingsManager = new SettingsManager2(basePath);
|
|
33280
33498
|
const ctx = createInstallContext2({ pluginName: name, settingsManager, basePath });
|
|
33281
33499
|
await plugin2.uninstall(ctx, { purge });
|
|
@@ -33283,7 +33501,7 @@ async function uninstallPlugin(name, purge, instanceRoot, json = false) {
|
|
|
33283
33501
|
} catch {
|
|
33284
33502
|
}
|
|
33285
33503
|
if (purge) {
|
|
33286
|
-
const pluginDir =
|
|
33504
|
+
const pluginDir = path72.join(root, "plugins", name);
|
|
33287
33505
|
fs57.rmSync(pluginDir, { recursive: true, force: true });
|
|
33288
33506
|
}
|
|
33289
33507
|
registry.remove(name);
|
|
@@ -33324,12 +33542,12 @@ init_helpers();
|
|
|
33324
33542
|
init_output();
|
|
33325
33543
|
import { execSync as execSync2 } from "child_process";
|
|
33326
33544
|
import * as fs32 from "fs";
|
|
33327
|
-
import * as
|
|
33545
|
+
import * as path36 from "path";
|
|
33328
33546
|
async function cmdUninstall(args2, instanceRoot) {
|
|
33329
33547
|
const json = isJsonMode(args2);
|
|
33330
33548
|
if (json) await muteForJson();
|
|
33331
33549
|
const root = instanceRoot;
|
|
33332
|
-
const pluginsDir =
|
|
33550
|
+
const pluginsDir = path36.join(root, "plugins");
|
|
33333
33551
|
if (!json && wantsHelp(args2)) {
|
|
33334
33552
|
console.log(`
|
|
33335
33553
|
\x1B[1mopenacp uninstall\x1B[0m \u2014 Remove a plugin adapter
|
|
@@ -33356,7 +33574,7 @@ async function cmdUninstall(args2, instanceRoot) {
|
|
|
33356
33574
|
process.exit(1);
|
|
33357
33575
|
}
|
|
33358
33576
|
fs32.mkdirSync(pluginsDir, { recursive: true });
|
|
33359
|
-
const pkgPath =
|
|
33577
|
+
const pkgPath = path36.join(pluginsDir, "package.json");
|
|
33360
33578
|
if (!fs32.existsSync(pkgPath)) {
|
|
33361
33579
|
fs32.writeFileSync(pkgPath, JSON.stringify({ name: "openacp-plugins", private: true, dependencies: {} }, null, 2));
|
|
33362
33580
|
}
|
|
@@ -34202,7 +34420,7 @@ init_helpers();
|
|
|
34202
34420
|
init_output();
|
|
34203
34421
|
init_instance_hint();
|
|
34204
34422
|
init_resolve_instance_id();
|
|
34205
|
-
import
|
|
34423
|
+
import path42 from "path";
|
|
34206
34424
|
async function cmdStart(args2 = [], instanceRoot) {
|
|
34207
34425
|
const json = isJsonMode(args2);
|
|
34208
34426
|
if (json) await muteForJson();
|
|
@@ -34232,7 +34450,7 @@ Requires an existing config \u2014 run 'openacp' first to set up.
|
|
|
34232
34450
|
await checkAndPromptUpdate();
|
|
34233
34451
|
const { startDaemon: startDaemon2, getPidPath: getPidPath2, isProcessRunning: isProcessRunning2 } = await Promise.resolve().then(() => (init_daemon2(), daemon_exports));
|
|
34234
34452
|
const { ConfigManager: ConfigManager2 } = await Promise.resolve().then(() => (init_config2(), config_exports));
|
|
34235
|
-
const cm = new ConfigManager2(
|
|
34453
|
+
const cm = new ConfigManager2(path42.join(root, "config.json"));
|
|
34236
34454
|
if (await cm.exists()) {
|
|
34237
34455
|
await cm.load();
|
|
34238
34456
|
const config = cm.get();
|
|
@@ -34258,12 +34476,12 @@ Requires an existing config \u2014 run 'openacp' first to set up.
|
|
|
34258
34476
|
}
|
|
34259
34477
|
if (json) {
|
|
34260
34478
|
const { waitForPortFile: waitForPortFile2 } = await Promise.resolve().then(() => (init_api_client(), api_client_exports));
|
|
34261
|
-
const port = await waitForPortFile2(
|
|
34479
|
+
const port = await waitForPortFile2(path42.join(root, "api.port")) ?? 21420;
|
|
34262
34480
|
jsonSuccess({
|
|
34263
34481
|
pid: result.pid,
|
|
34264
34482
|
instanceId,
|
|
34265
34483
|
name: config.instanceName ?? null,
|
|
34266
|
-
directory:
|
|
34484
|
+
directory: path42.dirname(root),
|
|
34267
34485
|
dir: root,
|
|
34268
34486
|
port
|
|
34269
34487
|
});
|
|
@@ -34433,7 +34651,7 @@ start fresh with the setup wizard. The daemon must be stopped first.
|
|
|
34433
34651
|
`);
|
|
34434
34652
|
return;
|
|
34435
34653
|
}
|
|
34436
|
-
const
|
|
34654
|
+
const path72 = await import("path");
|
|
34437
34655
|
const root = instanceRoot;
|
|
34438
34656
|
const { getStatus: getStatus2, getPidPath: getPidPath2 } = await Promise.resolve().then(() => (init_daemon2(), daemon_exports));
|
|
34439
34657
|
const status = getStatus2(getPidPath2(root));
|
|
@@ -34595,14 +34813,14 @@ as a messaging thread. Requires a running daemon.
|
|
|
34595
34813
|
// src/cli/commands/instances.ts
|
|
34596
34814
|
init_instance_registry();
|
|
34597
34815
|
init_instance_context();
|
|
34598
|
-
import
|
|
34816
|
+
import path61 from "path";
|
|
34599
34817
|
import os13 from "os";
|
|
34600
34818
|
import fs52 from "fs";
|
|
34601
34819
|
import { randomUUID as randomUUID6 } from "crypto";
|
|
34602
34820
|
|
|
34603
34821
|
// src/core/instance/instance-init.ts
|
|
34604
34822
|
import fs51 from "fs";
|
|
34605
|
-
import
|
|
34823
|
+
import path60 from "path";
|
|
34606
34824
|
function initInstanceFiles(instanceRoot, opts = {}) {
|
|
34607
34825
|
fs51.mkdirSync(instanceRoot, { recursive: true });
|
|
34608
34826
|
writeConfig(instanceRoot, opts);
|
|
@@ -34612,7 +34830,7 @@ function initInstanceFiles(instanceRoot, opts = {}) {
|
|
|
34612
34830
|
writePluginsIfMissing(instanceRoot);
|
|
34613
34831
|
}
|
|
34614
34832
|
function writeConfig(instanceRoot, opts) {
|
|
34615
|
-
const configPath =
|
|
34833
|
+
const configPath = path60.join(instanceRoot, "config.json");
|
|
34616
34834
|
let existing = {};
|
|
34617
34835
|
if (opts.mergeExisting && fs51.existsSync(configPath)) {
|
|
34618
34836
|
try {
|
|
@@ -34642,7 +34860,7 @@ function writeConfig(instanceRoot, opts) {
|
|
|
34642
34860
|
fs51.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
34643
34861
|
}
|
|
34644
34862
|
function writeAgentsIfMissing(instanceRoot, agents) {
|
|
34645
|
-
const agentsPath =
|
|
34863
|
+
const agentsPath = path60.join(instanceRoot, "agents.json");
|
|
34646
34864
|
if (fs51.existsSync(agentsPath)) return;
|
|
34647
34865
|
const installed = {};
|
|
34648
34866
|
for (const agentName of agents) {
|
|
@@ -34661,7 +34879,7 @@ function writeAgentsIfMissing(instanceRoot, agents) {
|
|
|
34661
34879
|
fs51.writeFileSync(agentsPath, JSON.stringify({ version: 1, installed }, null, 2));
|
|
34662
34880
|
}
|
|
34663
34881
|
function writePluginsIfMissing(instanceRoot) {
|
|
34664
|
-
const pluginsPath =
|
|
34882
|
+
const pluginsPath = path60.join(instanceRoot, "plugins.json");
|
|
34665
34883
|
if (!fs51.existsSync(pluginsPath)) {
|
|
34666
34884
|
fs51.writeFileSync(pluginsPath, JSON.stringify({ version: 1, installed: {} }, null, 2));
|
|
34667
34885
|
}
|
|
@@ -34672,7 +34890,7 @@ init_status();
|
|
|
34672
34890
|
init_output();
|
|
34673
34891
|
init_helpers();
|
|
34674
34892
|
async function buildInstanceListEntries() {
|
|
34675
|
-
const registryPath =
|
|
34893
|
+
const registryPath = path61.join(getGlobalRoot(), "instances.json");
|
|
34676
34894
|
const registry = new InstanceRegistry(registryPath);
|
|
34677
34895
|
registry.load();
|
|
34678
34896
|
const entries = registry.list();
|
|
@@ -34682,7 +34900,7 @@ async function buildInstanceListEntries() {
|
|
|
34682
34900
|
return {
|
|
34683
34901
|
id: entry.id,
|
|
34684
34902
|
name: info.name,
|
|
34685
|
-
directory:
|
|
34903
|
+
directory: path61.dirname(entry.root),
|
|
34686
34904
|
root: entry.root,
|
|
34687
34905
|
status,
|
|
34688
34906
|
port: info.apiPort
|
|
@@ -34775,9 +34993,9 @@ async function cmdInstancesCreate(args2) {
|
|
|
34775
34993
|
const agentIdx = args2.indexOf("--agent");
|
|
34776
34994
|
const agent = agentIdx !== -1 ? args2[agentIdx + 1] : void 0;
|
|
34777
34995
|
const noInteractive = args2.includes("--no-interactive");
|
|
34778
|
-
const resolvedDir =
|
|
34779
|
-
const instanceRoot =
|
|
34780
|
-
const registryPath =
|
|
34996
|
+
const resolvedDir = path61.resolve(rawDir.replace(/^~/, os13.homedir()));
|
|
34997
|
+
const instanceRoot = path61.join(resolvedDir, ".openacp");
|
|
34998
|
+
const registryPath = path61.join(getGlobalRoot(), "instances.json");
|
|
34781
34999
|
const registry = new InstanceRegistry(registryPath);
|
|
34782
35000
|
registry.load();
|
|
34783
35001
|
if (fs52.existsSync(instanceRoot)) {
|
|
@@ -34802,8 +35020,8 @@ async function cmdInstancesCreate(args2) {
|
|
|
34802
35020
|
const name = instanceName ?? `openacp-${registry.list().length + 1}`;
|
|
34803
35021
|
const id = randomUUID6();
|
|
34804
35022
|
if (rawFrom) {
|
|
34805
|
-
const fromRoot =
|
|
34806
|
-
if (!fs52.existsSync(
|
|
35023
|
+
const fromRoot = path61.join(path61.resolve(rawFrom.replace(/^~/, os13.homedir())), ".openacp");
|
|
35024
|
+
if (!fs52.existsSync(path61.join(fromRoot, "config.json"))) {
|
|
34807
35025
|
console.error(`Error: No OpenACP instance found at ${rawFrom}`);
|
|
34808
35026
|
process.exit(1);
|
|
34809
35027
|
}
|
|
@@ -34827,7 +35045,7 @@ async function outputInstance(json, { id, root }) {
|
|
|
34827
35045
|
const entry = {
|
|
34828
35046
|
id,
|
|
34829
35047
|
name: info.name,
|
|
34830
|
-
directory:
|
|
35048
|
+
directory: path61.dirname(root),
|
|
34831
35049
|
root,
|
|
34832
35050
|
status: info.pid ? "running" : "stopped",
|
|
34833
35051
|
port: info.apiPort
|
|
@@ -34836,7 +35054,7 @@ async function outputInstance(json, { id, root }) {
|
|
|
34836
35054
|
jsonSuccess(entry);
|
|
34837
35055
|
return;
|
|
34838
35056
|
}
|
|
34839
|
-
console.log(`Instance created: ${info.name ?? id} at ${
|
|
35057
|
+
console.log(`Instance created: ${info.name ?? id} at ${path61.dirname(root)}`);
|
|
34840
35058
|
}
|
|
34841
35059
|
|
|
34842
35060
|
// src/cli/commands/integrate.ts
|
|
@@ -35597,15 +35815,15 @@ Options:
|
|
|
35597
35815
|
}
|
|
35598
35816
|
|
|
35599
35817
|
// src/cli/commands/onboard.ts
|
|
35600
|
-
import * as
|
|
35818
|
+
import * as path62 from "path";
|
|
35601
35819
|
async function cmdOnboard(instanceRoot) {
|
|
35602
35820
|
const { ConfigManager: ConfigManager2 } = await Promise.resolve().then(() => (init_config2(), config_exports));
|
|
35603
35821
|
const { SettingsManager: SettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
|
|
35604
35822
|
const { PluginRegistry: PluginRegistry2 } = await Promise.resolve().then(() => (init_plugin_registry(), plugin_registry_exports));
|
|
35605
35823
|
const OPENACP_DIR = instanceRoot;
|
|
35606
|
-
const PLUGINS_DATA_DIR =
|
|
35607
|
-
const REGISTRY_PATH =
|
|
35608
|
-
const cm = new ConfigManager2(
|
|
35824
|
+
const PLUGINS_DATA_DIR = path62.join(OPENACP_DIR, "plugins", "data");
|
|
35825
|
+
const REGISTRY_PATH = path62.join(OPENACP_DIR, "plugins.json");
|
|
35826
|
+
const cm = new ConfigManager2(path62.join(OPENACP_DIR, "config.json"));
|
|
35609
35827
|
const settingsManager = new SettingsManager2(PLUGINS_DATA_DIR);
|
|
35610
35828
|
const pluginRegistry = new PluginRegistry2(REGISTRY_PATH);
|
|
35611
35829
|
await pluginRegistry.load();
|
|
@@ -35625,15 +35843,15 @@ init_instance_registry();
|
|
|
35625
35843
|
init_instance_hint();
|
|
35626
35844
|
init_output();
|
|
35627
35845
|
init_resolve_instance_id();
|
|
35628
|
-
import
|
|
35846
|
+
import path63 from "path";
|
|
35629
35847
|
import { randomUUID as randomUUID7 } from "crypto";
|
|
35630
35848
|
async function cmdDefault(command2, instanceRoot) {
|
|
35631
35849
|
const args2 = command2 ? [command2] : [];
|
|
35632
35850
|
const json = isJsonMode(args2);
|
|
35633
35851
|
if (json) await muteForJson();
|
|
35634
35852
|
const root = instanceRoot;
|
|
35635
|
-
const pluginsDataDir =
|
|
35636
|
-
const registryPath =
|
|
35853
|
+
const pluginsDataDir = path63.join(root, "plugins", "data");
|
|
35854
|
+
const registryPath = path63.join(root, "plugins.json");
|
|
35637
35855
|
const forceForeground = command2 === "--foreground";
|
|
35638
35856
|
if (command2 && !command2.startsWith("-")) {
|
|
35639
35857
|
const { suggestMatch: suggestMatch2 } = await Promise.resolve().then(() => (init_suggest(), suggest_exports));
|
|
@@ -35665,7 +35883,7 @@ async function cmdDefault(command2, instanceRoot) {
|
|
|
35665
35883
|
}
|
|
35666
35884
|
await checkAndPromptUpdate();
|
|
35667
35885
|
const { ConfigManager: ConfigManager2 } = await Promise.resolve().then(() => (init_config2(), config_exports));
|
|
35668
|
-
const configPath =
|
|
35886
|
+
const configPath = path63.join(root, "config.json");
|
|
35669
35887
|
const cm = new ConfigManager2(configPath);
|
|
35670
35888
|
if (!await cm.exists()) {
|
|
35671
35889
|
const { SettingsManager: SettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
|
|
@@ -35702,12 +35920,12 @@ async function cmdDefault(command2, instanceRoot) {
|
|
|
35702
35920
|
}
|
|
35703
35921
|
if (json) {
|
|
35704
35922
|
const { waitForPortFile: waitForPortFile2 } = await Promise.resolve().then(() => (init_api_client(), api_client_exports));
|
|
35705
|
-
const port = await waitForPortFile2(
|
|
35923
|
+
const port = await waitForPortFile2(path63.join(root, "api.port")) ?? 21420;
|
|
35706
35924
|
jsonSuccess({
|
|
35707
35925
|
pid: result.pid,
|
|
35708
35926
|
instanceId: instanceId2,
|
|
35709
35927
|
name: config.instanceName ?? null,
|
|
35710
|
-
directory:
|
|
35928
|
+
directory: path63.dirname(root),
|
|
35711
35929
|
dir: root,
|
|
35712
35930
|
port
|
|
35713
35931
|
});
|
|
@@ -35720,7 +35938,7 @@ async function cmdDefault(command2, instanceRoot) {
|
|
|
35720
35938
|
markRunning2(root);
|
|
35721
35939
|
printInstanceHint(root);
|
|
35722
35940
|
const { startServer: startServer2 } = await Promise.resolve().then(() => (init_main(), main_exports));
|
|
35723
|
-
const reg = new InstanceRegistry(
|
|
35941
|
+
const reg = new InstanceRegistry(path63.join(getGlobalRoot(), "instances.json"));
|
|
35724
35942
|
reg.load();
|
|
35725
35943
|
const existingEntry = reg.getByRoot(root);
|
|
35726
35944
|
const instanceId = existingEntry?.id ?? randomUUID7();
|
|
@@ -35734,7 +35952,7 @@ async function cmdDefault(command2, instanceRoot) {
|
|
|
35734
35952
|
pid: process.pid,
|
|
35735
35953
|
instanceId,
|
|
35736
35954
|
name: config.instanceName ?? null,
|
|
35737
|
-
directory:
|
|
35955
|
+
directory: path63.dirname(root),
|
|
35738
35956
|
dir: root,
|
|
35739
35957
|
port
|
|
35740
35958
|
});
|
|
@@ -35803,7 +36021,7 @@ async function showAlreadyRunningMenu(root) {
|
|
|
35803
36021
|
// src/cli/commands/dev.ts
|
|
35804
36022
|
init_helpers();
|
|
35805
36023
|
import fs53 from "fs";
|
|
35806
|
-
import
|
|
36024
|
+
import path64 from "path";
|
|
35807
36025
|
async function cmdDev(args2 = []) {
|
|
35808
36026
|
if (wantsHelp(args2)) {
|
|
35809
36027
|
console.log(`
|
|
@@ -35830,12 +36048,12 @@ async function cmdDev(args2 = []) {
|
|
|
35830
36048
|
console.error("Error: missing plugin path. Usage: openacp dev <plugin-path>");
|
|
35831
36049
|
process.exit(1);
|
|
35832
36050
|
}
|
|
35833
|
-
const pluginPath =
|
|
36051
|
+
const pluginPath = path64.resolve(pluginPathArg);
|
|
35834
36052
|
if (!fs53.existsSync(pluginPath)) {
|
|
35835
36053
|
console.error(`Error: plugin path does not exist: ${pluginPath}`);
|
|
35836
36054
|
process.exit(1);
|
|
35837
36055
|
}
|
|
35838
|
-
const tsconfigPath =
|
|
36056
|
+
const tsconfigPath = path64.join(pluginPath, "tsconfig.json");
|
|
35839
36057
|
const hasTsconfig = fs53.existsSync(tsconfigPath);
|
|
35840
36058
|
if (hasTsconfig) {
|
|
35841
36059
|
console.log("Compiling plugin TypeScript...");
|
|
@@ -35877,7 +36095,7 @@ async function cmdDev(args2 = []) {
|
|
|
35877
36095
|
|
|
35878
36096
|
// src/cli/commands/attach.ts
|
|
35879
36097
|
init_helpers();
|
|
35880
|
-
import
|
|
36098
|
+
import path65 from "path";
|
|
35881
36099
|
async function cmdAttach(args2 = [], instanceRoot) {
|
|
35882
36100
|
const root = instanceRoot;
|
|
35883
36101
|
if (wantsHelp(args2)) {
|
|
@@ -35913,15 +36131,15 @@ Press Ctrl+C to detach.
|
|
|
35913
36131
|
console.log("");
|
|
35914
36132
|
const { spawn: spawn9 } = await import("child_process");
|
|
35915
36133
|
const { expandHome: expandHome4 } = await Promise.resolve().then(() => (init_config2(), config_exports));
|
|
35916
|
-
let logDir2 =
|
|
36134
|
+
let logDir2 = path65.join(root, "logs");
|
|
35917
36135
|
try {
|
|
35918
|
-
const configPath =
|
|
36136
|
+
const configPath = path65.join(root, "config.json");
|
|
35919
36137
|
const { readFileSync: readFileSync18 } = await import("fs");
|
|
35920
36138
|
const config = JSON.parse(readFileSync18(configPath, "utf-8"));
|
|
35921
36139
|
if (config.logging?.logDir) logDir2 = expandHome4(config.logging.logDir);
|
|
35922
36140
|
} catch {
|
|
35923
36141
|
}
|
|
35924
|
-
const logFile =
|
|
36142
|
+
const logFile = path65.join(logDir2, "openacp.log");
|
|
35925
36143
|
const tail = spawn9("tail", ["-f", "-n", "50", logFile], { stdio: "inherit" });
|
|
35926
36144
|
tail.on("error", (err) => {
|
|
35927
36145
|
console.error(`Cannot tail log file: ${err.message}`);
|
|
@@ -35933,7 +36151,7 @@ Press Ctrl+C to detach.
|
|
|
35933
36151
|
init_api_client();
|
|
35934
36152
|
init_instance_registry();
|
|
35935
36153
|
init_output();
|
|
35936
|
-
import
|
|
36154
|
+
import path66 from "path";
|
|
35937
36155
|
import os14 from "os";
|
|
35938
36156
|
import qrcode from "qrcode-terminal";
|
|
35939
36157
|
async function cmdRemote(args2, instanceRoot) {
|
|
@@ -35949,7 +36167,7 @@ async function cmdRemote(args2, instanceRoot) {
|
|
|
35949
36167
|
const scopes = scopesRaw ? scopesRaw.split(",").map((s) => s.trim()) : void 0;
|
|
35950
36168
|
let resolvedInstanceRoot2 = instanceRoot;
|
|
35951
36169
|
if (instanceId) {
|
|
35952
|
-
const registryPath =
|
|
36170
|
+
const registryPath = path66.join(os14.homedir(), ".openacp", "instances.json");
|
|
35953
36171
|
const registry = new InstanceRegistry(registryPath);
|
|
35954
36172
|
await registry.load();
|
|
35955
36173
|
const entry = registry.get(instanceId);
|
|
@@ -36088,7 +36306,7 @@ function extractFlag(args2, flag) {
|
|
|
36088
36306
|
init_output();
|
|
36089
36307
|
init_instance_context();
|
|
36090
36308
|
init_instance_registry();
|
|
36091
|
-
import * as
|
|
36309
|
+
import * as path67 from "path";
|
|
36092
36310
|
import fs54 from "fs";
|
|
36093
36311
|
function parseFlag(args2, flag) {
|
|
36094
36312
|
const idx = args2.indexOf(flag);
|
|
@@ -36096,7 +36314,7 @@ function parseFlag(args2, flag) {
|
|
|
36096
36314
|
}
|
|
36097
36315
|
function readConfigField(instanceRoot, field) {
|
|
36098
36316
|
try {
|
|
36099
|
-
const raw = JSON.parse(fs54.readFileSync(
|
|
36317
|
+
const raw = JSON.parse(fs54.readFileSync(path67.join(instanceRoot, "config.json"), "utf-8"));
|
|
36100
36318
|
return typeof raw[field] === "string" ? raw[field] : null;
|
|
36101
36319
|
} catch {
|
|
36102
36320
|
return null;
|
|
@@ -36119,7 +36337,7 @@ async function cmdSetup(args2, instanceRoot) {
|
|
|
36119
36337
|
}
|
|
36120
36338
|
const runMode = rawRunMode;
|
|
36121
36339
|
const agents = agentRaw.split(",").map((a) => a.trim());
|
|
36122
|
-
const registryPath =
|
|
36340
|
+
const registryPath = path67.join(getGlobalRoot(), "instances.json");
|
|
36123
36341
|
const registry = new InstanceRegistry(registryPath);
|
|
36124
36342
|
registry.load();
|
|
36125
36343
|
const { id, registryUpdated } = registry.resolveId(instanceRoot);
|
|
@@ -36127,9 +36345,9 @@ async function cmdSetup(args2, instanceRoot) {
|
|
|
36127
36345
|
if (registryUpdated) {
|
|
36128
36346
|
registry.save();
|
|
36129
36347
|
}
|
|
36130
|
-
const name = readConfigField(instanceRoot, "instanceName") ??
|
|
36348
|
+
const name = readConfigField(instanceRoot, "instanceName") ?? path67.basename(path67.dirname(instanceRoot));
|
|
36131
36349
|
if (!readConfigField(instanceRoot, "instanceName")) {
|
|
36132
|
-
const configPath =
|
|
36350
|
+
const configPath = path67.join(instanceRoot, "config.json");
|
|
36133
36351
|
try {
|
|
36134
36352
|
const raw = JSON.parse(fs54.readFileSync(configPath, "utf-8"));
|
|
36135
36353
|
raw.instanceName = name;
|
|
@@ -36138,17 +36356,17 @@ async function cmdSetup(args2, instanceRoot) {
|
|
|
36138
36356
|
}
|
|
36139
36357
|
}
|
|
36140
36358
|
if (json) {
|
|
36141
|
-
jsonSuccess({ id, name, directory:
|
|
36359
|
+
jsonSuccess({ id, name, directory: path67.dirname(instanceRoot), configPath: path67.join(instanceRoot, "config.json") });
|
|
36142
36360
|
} else {
|
|
36143
36361
|
console.log(`
|
|
36144
|
-
\x1B[32m\u2713 Setup complete.\x1B[0m Config written to ${
|
|
36362
|
+
\x1B[32m\u2713 Setup complete.\x1B[0m Config written to ${path67.join(instanceRoot, "config.json")}
|
|
36145
36363
|
`);
|
|
36146
36364
|
}
|
|
36147
36365
|
}
|
|
36148
36366
|
|
|
36149
36367
|
// src/cli/commands/autostart.ts
|
|
36150
36368
|
init_helpers();
|
|
36151
|
-
import
|
|
36369
|
+
import path68 from "path";
|
|
36152
36370
|
async function cmdAutostart(args2 = [], instanceRoot) {
|
|
36153
36371
|
const subcommand = args2[0];
|
|
36154
36372
|
if (!subcommand || wantsHelp(args2)) {
|
|
@@ -36186,7 +36404,7 @@ async function cmdAutostart(args2 = [], instanceRoot) {
|
|
|
36186
36404
|
let logDir2 = `${root}/logs`;
|
|
36187
36405
|
try {
|
|
36188
36406
|
const { ConfigManager: ConfigManager2 } = await Promise.resolve().then(() => (init_config2(), config_exports));
|
|
36189
|
-
const cm = new ConfigManager2(
|
|
36407
|
+
const cm = new ConfigManager2(path68.join(root, "config.json"));
|
|
36190
36408
|
if (await cm.exists()) {
|
|
36191
36409
|
await cm.load();
|
|
36192
36410
|
logDir2 = cm.get().logging?.logDir ?? logDir2;
|
|
@@ -36374,7 +36592,7 @@ async function main() {
|
|
|
36374
36592
|
if (envRoot) {
|
|
36375
36593
|
const { createInstanceContext: createInstanceContext2, getGlobalRoot: getGlobal } = await Promise.resolve().then(() => (init_instance_context(), instance_context_exports));
|
|
36376
36594
|
const { InstanceRegistry: InstanceRegistry2 } = await Promise.resolve().then(() => (init_instance_registry(), instance_registry_exports));
|
|
36377
|
-
const registry = new InstanceRegistry2(
|
|
36595
|
+
const registry = new InstanceRegistry2(path71.join(getGlobal(), "instances.json"));
|
|
36378
36596
|
await registry.load();
|
|
36379
36597
|
const entry = registry.getByRoot(envRoot);
|
|
36380
36598
|
const { randomUUID: randomUUID9 } = await import("crypto");
|