@n1creator/openacp-cli 2026.712.4 → 2026.712.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cli.js +727 -501
- package/dist/cli.js.map +1 -1
- package/dist/index.js +302 -215
- package/dist/index.js.map +1 -1
- package/dist/speech/transcribe_audio.sh +118 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -328,22 +328,22 @@ __export(config_registry_exports, {
|
|
|
328
328
|
resolveOptions: () => resolveOptions,
|
|
329
329
|
setFieldValueAsync: () => setFieldValueAsync
|
|
330
330
|
});
|
|
331
|
-
function getFieldDef(
|
|
332
|
-
return CONFIG_REGISTRY.find((f) => f.path ===
|
|
331
|
+
function getFieldDef(path36) {
|
|
332
|
+
return CONFIG_REGISTRY.find((f) => f.path === path36);
|
|
333
333
|
}
|
|
334
334
|
function getSafeFields() {
|
|
335
335
|
return CONFIG_REGISTRY.filter((f) => f.scope === "safe");
|
|
336
336
|
}
|
|
337
|
-
function isHotReloadable(
|
|
338
|
-
const def = getFieldDef(
|
|
337
|
+
function isHotReloadable(path36) {
|
|
338
|
+
const def = getFieldDef(path36);
|
|
339
339
|
return def?.hotReload ?? false;
|
|
340
340
|
}
|
|
341
341
|
function resolveOptions(def, config) {
|
|
342
342
|
if (!def.options) return void 0;
|
|
343
343
|
return typeof def.options === "function" ? def.options(config) : def.options;
|
|
344
344
|
}
|
|
345
|
-
function getConfigValue(config,
|
|
346
|
-
const parts =
|
|
345
|
+
function getConfigValue(config, path36) {
|
|
346
|
+
const parts = path36.split(".");
|
|
347
347
|
let current = config;
|
|
348
348
|
for (const part of parts) {
|
|
349
349
|
if (current && typeof current === "object" && part in current) {
|
|
@@ -674,6 +674,14 @@ var init_config = __esm({
|
|
|
674
674
|
{ envVar: "OPENACP_API_PORT", pluginName: "@openacp/api-server", key: "port", transform: (v) => Number(v) },
|
|
675
675
|
{ envVar: "OPENACP_SPEECH_STT_PROVIDER", pluginName: "@openacp/speech", key: "sttProvider" },
|
|
676
676
|
{ envVar: "OPENACP_SPEECH_GROQ_API_KEY", pluginName: "@openacp/speech", key: "groqApiKey" },
|
|
677
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_LANGUAGE", pluginName: "@openacp/speech", key: "localWhisperLanguage" },
|
|
678
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_MODEL", pluginName: "@openacp/speech", key: "localWhisperModel" },
|
|
679
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_BEAM_SIZE", pluginName: "@openacp/speech", key: "localWhisperBeamSize", transform: (v) => Number(v) },
|
|
680
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_VAD_FILTER", pluginName: "@openacp/speech", key: "localWhisperVadFilter", transform: (v) => v === "true" },
|
|
681
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_DEVICE", pluginName: "@openacp/speech", key: "localWhisperDevice" },
|
|
682
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_COMPUTE_TYPE", pluginName: "@openacp/speech", key: "localWhisperComputeType" },
|
|
683
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_TIMEOUT_MS", pluginName: "@openacp/speech", key: "localWhisperTimeoutMs", transform: (v) => Number(v) },
|
|
684
|
+
{ envVar: "OPENACP_SPEECH_LOCAL_WHISPER_SCRIPT_PATH", pluginName: "@openacp/speech", key: "localWhisperScriptPath" },
|
|
677
685
|
{ envVar: "OPENACP_TELEGRAM_BOT_TOKEN", pluginName: "@openacp/telegram", key: "botToken" },
|
|
678
686
|
{ envVar: "OPENACP_TELEGRAM_CHAT_ID", pluginName: "@openacp/telegram", key: "chatId", transform: (v) => Number(v) },
|
|
679
687
|
// Future adapters — no-ops if plugin settings don't exist
|
|
@@ -1525,6 +1533,166 @@ var init_agent_installer = __esm({
|
|
|
1525
1533
|
}
|
|
1526
1534
|
});
|
|
1527
1535
|
|
|
1536
|
+
// src/plugins/speech/providers/groq.ts
|
|
1537
|
+
function mimeToExt(mimeType) {
|
|
1538
|
+
const map = {
|
|
1539
|
+
"audio/ogg": ".ogg",
|
|
1540
|
+
"audio/wav": ".wav",
|
|
1541
|
+
"audio/mpeg": ".mp3",
|
|
1542
|
+
"audio/mp4": ".m4a",
|
|
1543
|
+
"audio/webm": ".webm",
|
|
1544
|
+
"audio/flac": ".flac"
|
|
1545
|
+
};
|
|
1546
|
+
return map[mimeType] || ".bin";
|
|
1547
|
+
}
|
|
1548
|
+
var GROQ_API_URL, GroqSTT;
|
|
1549
|
+
var init_groq = __esm({
|
|
1550
|
+
"src/plugins/speech/providers/groq.ts"() {
|
|
1551
|
+
"use strict";
|
|
1552
|
+
GROQ_API_URL = "https://api.groq.com/openai/v1/audio/transcriptions";
|
|
1553
|
+
GroqSTT = class {
|
|
1554
|
+
constructor(apiKey, defaultModel = "whisper-large-v3-turbo") {
|
|
1555
|
+
this.apiKey = apiKey;
|
|
1556
|
+
this.defaultModel = defaultModel;
|
|
1557
|
+
}
|
|
1558
|
+
apiKey;
|
|
1559
|
+
defaultModel;
|
|
1560
|
+
name = "groq";
|
|
1561
|
+
/**
|
|
1562
|
+
* Transcribes audio using the Groq Whisper API.
|
|
1563
|
+
*
|
|
1564
|
+
* `verbose_json` response format is requested so the API returns language
|
|
1565
|
+
* detection and duration metadata alongside the transcript text.
|
|
1566
|
+
*/
|
|
1567
|
+
async transcribe(audioBuffer, mimeType, options) {
|
|
1568
|
+
const ext = mimeToExt(mimeType);
|
|
1569
|
+
const form = new FormData();
|
|
1570
|
+
form.append("file", new Blob([new Uint8Array(audioBuffer)], { type: mimeType }), `audio${ext}`);
|
|
1571
|
+
form.append("model", options?.model || this.defaultModel);
|
|
1572
|
+
form.append("response_format", "verbose_json");
|
|
1573
|
+
if (options?.language) {
|
|
1574
|
+
form.append("language", options.language);
|
|
1575
|
+
}
|
|
1576
|
+
const resp = await fetch(GROQ_API_URL, {
|
|
1577
|
+
method: "POST",
|
|
1578
|
+
headers: { Authorization: `Bearer ${this.apiKey}` },
|
|
1579
|
+
body: form
|
|
1580
|
+
});
|
|
1581
|
+
if (!resp.ok) {
|
|
1582
|
+
const body = await resp.text();
|
|
1583
|
+
if (resp.status === 401) {
|
|
1584
|
+
throw new Error("Invalid Groq API key. Check your key at console.groq.com.");
|
|
1585
|
+
}
|
|
1586
|
+
if (resp.status === 413) {
|
|
1587
|
+
throw new Error("Audio file too large for Groq API (max 25MB).");
|
|
1588
|
+
}
|
|
1589
|
+
if (resp.status === 429) {
|
|
1590
|
+
throw new Error("Groq rate limit exceeded. Free tier: 28,800 seconds/day. Try again later.");
|
|
1591
|
+
}
|
|
1592
|
+
throw new Error(`Groq STT error (${resp.status}): ${body}`);
|
|
1593
|
+
}
|
|
1594
|
+
const data = await resp.json();
|
|
1595
|
+
return {
|
|
1596
|
+
text: data.text,
|
|
1597
|
+
language: data.language,
|
|
1598
|
+
duration: data.duration
|
|
1599
|
+
};
|
|
1600
|
+
}
|
|
1601
|
+
};
|
|
1602
|
+
}
|
|
1603
|
+
});
|
|
1604
|
+
|
|
1605
|
+
// src/plugins/speech/providers/local-whisper.ts
|
|
1606
|
+
import { execFile } from "child_process";
|
|
1607
|
+
import { existsSync as existsSync6 } from "fs";
|
|
1608
|
+
import { mkdtemp, rm, writeFile } from "fs/promises";
|
|
1609
|
+
import { tmpdir } from "os";
|
|
1610
|
+
import path14 from "path";
|
|
1611
|
+
import { fileURLToPath } from "url";
|
|
1612
|
+
import { promisify } from "util";
|
|
1613
|
+
function resolveLocalWhisperScriptPath() {
|
|
1614
|
+
const moduleDir = path14.dirname(fileURLToPath(import.meta.url));
|
|
1615
|
+
const candidates = [
|
|
1616
|
+
path14.resolve(moduleDir, "../scripts/transcribe_audio.sh"),
|
|
1617
|
+
path14.resolve(moduleDir, "speech/transcribe_audio.sh")
|
|
1618
|
+
];
|
|
1619
|
+
return candidates.find(existsSync6) ?? candidates[0];
|
|
1620
|
+
}
|
|
1621
|
+
var execFileAsync, LOCAL_WHISPER_PROVIDER, LOCAL_WHISPER_DEFAULTS;
|
|
1622
|
+
var init_local_whisper = __esm({
|
|
1623
|
+
"src/plugins/speech/providers/local-whisper.ts"() {
|
|
1624
|
+
"use strict";
|
|
1625
|
+
execFileAsync = promisify(execFile);
|
|
1626
|
+
LOCAL_WHISPER_PROVIDER = "local-whisper";
|
|
1627
|
+
LOCAL_WHISPER_DEFAULTS = {
|
|
1628
|
+
language: "ru",
|
|
1629
|
+
model: "base",
|
|
1630
|
+
beamSize: 5,
|
|
1631
|
+
vadFilter: false,
|
|
1632
|
+
device: "cpu",
|
|
1633
|
+
computeType: "int8",
|
|
1634
|
+
timeoutMs: 12e4
|
|
1635
|
+
};
|
|
1636
|
+
}
|
|
1637
|
+
});
|
|
1638
|
+
|
|
1639
|
+
// src/plugins/speech/native-stt.ts
|
|
1640
|
+
function readLocalWhisperSettings(raw) {
|
|
1641
|
+
return {
|
|
1642
|
+
scriptPath: readString(raw.localWhisperScriptPath, resolveLocalWhisperScriptPath()),
|
|
1643
|
+
language: readString(raw.localWhisperLanguage, LOCAL_WHISPER_DEFAULTS.language),
|
|
1644
|
+
model: readString(raw.localWhisperModel, LOCAL_WHISPER_DEFAULTS.model),
|
|
1645
|
+
beamSize: readNumber(raw.localWhisperBeamSize, LOCAL_WHISPER_DEFAULTS.beamSize),
|
|
1646
|
+
vadFilter: readBoolean(raw.localWhisperVadFilter, LOCAL_WHISPER_DEFAULTS.vadFilter),
|
|
1647
|
+
device: readString(raw.localWhisperDevice, LOCAL_WHISPER_DEFAULTS.device),
|
|
1648
|
+
computeType: readString(raw.localWhisperComputeType, LOCAL_WHISPER_DEFAULTS.computeType),
|
|
1649
|
+
timeoutMs: readNumber(raw.localWhisperTimeoutMs, LOCAL_WHISPER_DEFAULTS.timeoutMs)
|
|
1650
|
+
};
|
|
1651
|
+
}
|
|
1652
|
+
function buildSpeechServiceConfig(raw) {
|
|
1653
|
+
const groqApiKey = readOptionalString(raw.groqApiKey);
|
|
1654
|
+
const requestedProvider = readOptionalString(raw.sttProvider);
|
|
1655
|
+
const provider = requestedProvider === LOCAL_WHISPER_PROVIDER ? LOCAL_WHISPER_PROVIDER : groqApiKey ? "groq" : null;
|
|
1656
|
+
const providers = {};
|
|
1657
|
+
if (groqApiKey) providers.groq = { apiKey: groqApiKey };
|
|
1658
|
+
if (provider === LOCAL_WHISPER_PROVIDER) {
|
|
1659
|
+
providers[LOCAL_WHISPER_PROVIDER] = {
|
|
1660
|
+
apiKey: "local",
|
|
1661
|
+
...readLocalWhisperSettings(raw)
|
|
1662
|
+
};
|
|
1663
|
+
}
|
|
1664
|
+
return {
|
|
1665
|
+
stt: { provider, providers },
|
|
1666
|
+
tts: {
|
|
1667
|
+
provider: readOptionalString(raw.ttsProvider) ?? "edge-tts",
|
|
1668
|
+
providers: {}
|
|
1669
|
+
}
|
|
1670
|
+
};
|
|
1671
|
+
}
|
|
1672
|
+
function readString(value, fallback) {
|
|
1673
|
+
return readOptionalString(value) ?? fallback;
|
|
1674
|
+
}
|
|
1675
|
+
function readOptionalString(value) {
|
|
1676
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
1677
|
+
}
|
|
1678
|
+
function readNumber(value, fallback) {
|
|
1679
|
+
return readOptionalNumber(value) ?? fallback;
|
|
1680
|
+
}
|
|
1681
|
+
function readOptionalNumber(value) {
|
|
1682
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
1683
|
+
}
|
|
1684
|
+
function readBoolean(value, fallback) {
|
|
1685
|
+
return typeof value === "boolean" ? value : fallback;
|
|
1686
|
+
}
|
|
1687
|
+
var init_native_stt = __esm({
|
|
1688
|
+
"src/plugins/speech/native-stt.ts"() {
|
|
1689
|
+
"use strict";
|
|
1690
|
+
init_groq();
|
|
1691
|
+
init_local_whisper();
|
|
1692
|
+
init_local_whisper();
|
|
1693
|
+
}
|
|
1694
|
+
});
|
|
1695
|
+
|
|
1528
1696
|
// src/core/doctor/checks/config.ts
|
|
1529
1697
|
import * as fs15 from "fs";
|
|
1530
1698
|
var configCheck;
|
|
@@ -1589,7 +1757,7 @@ var init_config2 = __esm({
|
|
|
1589
1757
|
// src/core/doctor/checks/agents.ts
|
|
1590
1758
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
1591
1759
|
import * as fs16 from "fs";
|
|
1592
|
-
import * as
|
|
1760
|
+
import * as path16 from "path";
|
|
1593
1761
|
function commandExists2(cmd) {
|
|
1594
1762
|
try {
|
|
1595
1763
|
execFileSync3("which", [cmd], { stdio: "pipe" });
|
|
@@ -1598,9 +1766,9 @@ function commandExists2(cmd) {
|
|
|
1598
1766
|
}
|
|
1599
1767
|
let dir = process.cwd();
|
|
1600
1768
|
while (true) {
|
|
1601
|
-
const binPath =
|
|
1769
|
+
const binPath = path16.join(dir, "node_modules", ".bin", cmd);
|
|
1602
1770
|
if (fs16.existsSync(binPath)) return true;
|
|
1603
|
-
const parent =
|
|
1771
|
+
const parent = path16.dirname(dir);
|
|
1604
1772
|
if (parent === dir) break;
|
|
1605
1773
|
dir = parent;
|
|
1606
1774
|
}
|
|
@@ -1622,7 +1790,7 @@ var init_agents = __esm({
|
|
|
1622
1790
|
const defaultAgent = ctx.config.defaultAgent;
|
|
1623
1791
|
let agents = {};
|
|
1624
1792
|
try {
|
|
1625
|
-
const agentsPath =
|
|
1793
|
+
const agentsPath = path16.join(ctx.dataDir, "agents.json");
|
|
1626
1794
|
if (fs16.existsSync(agentsPath)) {
|
|
1627
1795
|
const data = JSON.parse(fs16.readFileSync(agentsPath, "utf-8"));
|
|
1628
1796
|
agents = data.installed ?? {};
|
|
@@ -1663,7 +1831,7 @@ __export(settings_manager_exports, {
|
|
|
1663
1831
|
SettingsManager: () => SettingsManager
|
|
1664
1832
|
});
|
|
1665
1833
|
import fs17 from "fs";
|
|
1666
|
-
import
|
|
1834
|
+
import path17 from "path";
|
|
1667
1835
|
var SettingsManager, SettingsAPIImpl;
|
|
1668
1836
|
var init_settings_manager = __esm({
|
|
1669
1837
|
"src/core/plugin/settings-manager.ts"() {
|
|
@@ -1706,7 +1874,7 @@ var init_settings_manager = __esm({
|
|
|
1706
1874
|
}
|
|
1707
1875
|
/** Resolve the absolute path to a plugin's settings.json file. */
|
|
1708
1876
|
getSettingsPath(pluginName) {
|
|
1709
|
-
return
|
|
1877
|
+
return path17.join(this.basePath, pluginName, "settings.json");
|
|
1710
1878
|
}
|
|
1711
1879
|
async getPluginSettings(pluginName) {
|
|
1712
1880
|
return this.loadSettings(pluginName);
|
|
@@ -1736,7 +1904,7 @@ var init_settings_manager = __esm({
|
|
|
1736
1904
|
}
|
|
1737
1905
|
}
|
|
1738
1906
|
writeFile(data) {
|
|
1739
|
-
const dir =
|
|
1907
|
+
const dir = path17.dirname(this.settingsPath);
|
|
1740
1908
|
fs17.mkdirSync(dir, { recursive: true });
|
|
1741
1909
|
fs17.writeFileSync(this.settingsPath, JSON.stringify(data, null, 2));
|
|
1742
1910
|
this.cache = data;
|
|
@@ -1773,7 +1941,7 @@ var init_settings_manager = __esm({
|
|
|
1773
1941
|
});
|
|
1774
1942
|
|
|
1775
1943
|
// src/core/doctor/checks/telegram.ts
|
|
1776
|
-
import * as
|
|
1944
|
+
import * as path18 from "path";
|
|
1777
1945
|
var BOT_TOKEN_REGEX, telegramCheck;
|
|
1778
1946
|
var init_telegram = __esm({
|
|
1779
1947
|
"src/core/doctor/checks/telegram.ts"() {
|
|
@@ -1789,7 +1957,7 @@ var init_telegram = __esm({
|
|
|
1789
1957
|
return results;
|
|
1790
1958
|
}
|
|
1791
1959
|
const { SettingsManager: SettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
|
|
1792
|
-
const sm = new SettingsManager2(
|
|
1960
|
+
const sm = new SettingsManager2(path18.join(ctx.pluginsDir, "data"));
|
|
1793
1961
|
const ps = await sm.loadSettings("@openacp/telegram");
|
|
1794
1962
|
const botToken = ps.botToken;
|
|
1795
1963
|
const chatId = ps.chatId;
|
|
@@ -1961,7 +2129,7 @@ var init_storage = __esm({
|
|
|
1961
2129
|
|
|
1962
2130
|
// src/core/doctor/checks/workspace.ts
|
|
1963
2131
|
import * as fs19 from "fs";
|
|
1964
|
-
import * as
|
|
2132
|
+
import * as path19 from "path";
|
|
1965
2133
|
var workspaceCheck;
|
|
1966
2134
|
var init_workspace = __esm({
|
|
1967
2135
|
"src/core/doctor/checks/workspace.ts"() {
|
|
@@ -1971,7 +2139,7 @@ var init_workspace = __esm({
|
|
|
1971
2139
|
order: 5,
|
|
1972
2140
|
async run(ctx) {
|
|
1973
2141
|
const results = [];
|
|
1974
|
-
const workspace =
|
|
2142
|
+
const workspace = path19.dirname(ctx.dataDir);
|
|
1975
2143
|
if (!fs19.existsSync(workspace)) {
|
|
1976
2144
|
results.push({
|
|
1977
2145
|
status: "warn",
|
|
@@ -1999,7 +2167,7 @@ var init_workspace = __esm({
|
|
|
1999
2167
|
|
|
2000
2168
|
// src/core/doctor/checks/plugins.ts
|
|
2001
2169
|
import * as fs20 from "fs";
|
|
2002
|
-
import * as
|
|
2170
|
+
import * as path20 from "path";
|
|
2003
2171
|
var pluginsCheck;
|
|
2004
2172
|
var init_plugins = __esm({
|
|
2005
2173
|
"src/core/doctor/checks/plugins.ts"() {
|
|
@@ -2018,7 +2186,7 @@ var init_plugins = __esm({
|
|
|
2018
2186
|
fix: async () => {
|
|
2019
2187
|
fs20.mkdirSync(ctx.pluginsDir, { recursive: true });
|
|
2020
2188
|
fs20.writeFileSync(
|
|
2021
|
-
|
|
2189
|
+
path20.join(ctx.pluginsDir, "package.json"),
|
|
2022
2190
|
JSON.stringify({ name: "openacp-plugins", private: true, dependencies: {} }, null, 2)
|
|
2023
2191
|
);
|
|
2024
2192
|
return { success: true, message: "initialized plugins directory" };
|
|
@@ -2027,7 +2195,7 @@ var init_plugins = __esm({
|
|
|
2027
2195
|
return results;
|
|
2028
2196
|
}
|
|
2029
2197
|
results.push({ status: "pass", message: "Plugins directory exists" });
|
|
2030
|
-
const pkgPath =
|
|
2198
|
+
const pkgPath = path20.join(ctx.pluginsDir, "package.json");
|
|
2031
2199
|
if (!fs20.existsSync(pkgPath)) {
|
|
2032
2200
|
results.push({
|
|
2033
2201
|
status: "warn",
|
|
@@ -2174,7 +2342,7 @@ var init_daemon = __esm({
|
|
|
2174
2342
|
|
|
2175
2343
|
// src/core/utils/install-binary.ts
|
|
2176
2344
|
import fs22 from "fs";
|
|
2177
|
-
import
|
|
2345
|
+
import path21 from "path";
|
|
2178
2346
|
import https from "https";
|
|
2179
2347
|
import os5 from "os";
|
|
2180
2348
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
@@ -2249,7 +2417,7 @@ function getDownloadUrl(spec) {
|
|
|
2249
2417
|
async function ensureBinary(spec, binDir) {
|
|
2250
2418
|
const resolvedBinDir = binDir ?? DEFAULT_BIN_DIR;
|
|
2251
2419
|
const binName = IS_WINDOWS ? `${spec.name}.exe` : spec.name;
|
|
2252
|
-
const binPath =
|
|
2420
|
+
const binPath = path21.join(resolvedBinDir, binName);
|
|
2253
2421
|
if (commandExists(spec.name)) {
|
|
2254
2422
|
log18.debug({ name: spec.name }, "Found in PATH");
|
|
2255
2423
|
return spec.name;
|
|
@@ -2263,7 +2431,7 @@ async function ensureBinary(spec, binDir) {
|
|
|
2263
2431
|
fs22.mkdirSync(resolvedBinDir, { recursive: true });
|
|
2264
2432
|
const url = getDownloadUrl(spec);
|
|
2265
2433
|
const isArchive = spec.isArchive?.(url) ?? false;
|
|
2266
|
-
const downloadDest = isArchive ?
|
|
2434
|
+
const downloadDest = isArchive ? path21.join(resolvedBinDir, `${spec.name}.tgz`) : binPath;
|
|
2267
2435
|
await downloadFile(url, downloadDest);
|
|
2268
2436
|
if (isArchive) {
|
|
2269
2437
|
const listing = execFileSync4("tar", ["-tf", downloadDest], { stdio: "pipe" }).toString().trim().split("\n").filter(Boolean);
|
|
@@ -2291,7 +2459,7 @@ var init_install_binary = __esm({
|
|
|
2291
2459
|
init_agent_dependencies();
|
|
2292
2460
|
init_agent_installer();
|
|
2293
2461
|
log18 = createChildLogger({ module: "binary-installer" });
|
|
2294
|
-
DEFAULT_BIN_DIR =
|
|
2462
|
+
DEFAULT_BIN_DIR = path21.join(os5.homedir(), ".openacp", "bin");
|
|
2295
2463
|
IS_WINDOWS = os5.platform() === "win32";
|
|
2296
2464
|
}
|
|
2297
2465
|
});
|
|
@@ -2333,7 +2501,7 @@ var init_install_cloudflared = __esm({
|
|
|
2333
2501
|
|
|
2334
2502
|
// src/core/doctor/checks/tunnel.ts
|
|
2335
2503
|
import * as fs23 from "fs";
|
|
2336
|
-
import * as
|
|
2504
|
+
import * as path22 from "path";
|
|
2337
2505
|
import * as os6 from "os";
|
|
2338
2506
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
2339
2507
|
var tunnelCheck;
|
|
@@ -2350,7 +2518,7 @@ var init_tunnel = __esm({
|
|
|
2350
2518
|
return results;
|
|
2351
2519
|
}
|
|
2352
2520
|
const { SettingsManager: SettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
|
|
2353
|
-
const sm = new SettingsManager2(
|
|
2521
|
+
const sm = new SettingsManager2(path22.join(ctx.pluginsDir, "data"));
|
|
2354
2522
|
const tunnelSettings = await sm.loadSettings("@openacp/tunnel");
|
|
2355
2523
|
const tunnelEnabled = tunnelSettings.enabled ?? false;
|
|
2356
2524
|
const provider = tunnelSettings.provider ?? "cloudflare";
|
|
@@ -2362,7 +2530,7 @@ var init_tunnel = __esm({
|
|
|
2362
2530
|
results.push({ status: "pass", message: `Tunnel provider: ${provider}` });
|
|
2363
2531
|
if (provider === "cloudflare") {
|
|
2364
2532
|
const binName = os6.platform() === "win32" ? "cloudflared.exe" : "cloudflared";
|
|
2365
|
-
const binPath =
|
|
2533
|
+
const binPath = path22.join(ctx.dataDir, "bin", binName);
|
|
2366
2534
|
let found = false;
|
|
2367
2535
|
if (fs23.existsSync(binPath)) {
|
|
2368
2536
|
found = true;
|
|
@@ -2406,7 +2574,7 @@ var init_tunnel = __esm({
|
|
|
2406
2574
|
|
|
2407
2575
|
// src/core/doctor/index.ts
|
|
2408
2576
|
import * as fs24 from "fs";
|
|
2409
|
-
import * as
|
|
2577
|
+
import * as path23 from "path";
|
|
2410
2578
|
var ALL_CHECKS, CHECK_TIMEOUT_MS, DoctorEngine;
|
|
2411
2579
|
var init_doctor = __esm({
|
|
2412
2580
|
"src/core/doctor/index.ts"() {
|
|
@@ -2494,7 +2662,7 @@ var init_doctor = __esm({
|
|
|
2494
2662
|
/** Constructs the shared context used by all checks — loads config if available. */
|
|
2495
2663
|
async buildContext() {
|
|
2496
2664
|
const dataDir = this.dataDir;
|
|
2497
|
-
const configPath = process.env.OPENACP_CONFIG_PATH ||
|
|
2665
|
+
const configPath = process.env.OPENACP_CONFIG_PATH || path23.join(dataDir, "config.json");
|
|
2498
2666
|
let config = null;
|
|
2499
2667
|
let rawConfig = null;
|
|
2500
2668
|
try {
|
|
@@ -2505,16 +2673,16 @@ var init_doctor = __esm({
|
|
|
2505
2673
|
config = cm.get();
|
|
2506
2674
|
} catch {
|
|
2507
2675
|
}
|
|
2508
|
-
const logsDir = config ? expandHome2(config.logging.logDir) :
|
|
2676
|
+
const logsDir = config ? expandHome2(config.logging.logDir) : path23.join(dataDir, "logs");
|
|
2509
2677
|
return {
|
|
2510
2678
|
config,
|
|
2511
2679
|
rawConfig,
|
|
2512
2680
|
configPath,
|
|
2513
2681
|
dataDir,
|
|
2514
|
-
sessionsPath:
|
|
2515
|
-
pidPath:
|
|
2516
|
-
portFilePath:
|
|
2517
|
-
pluginsDir:
|
|
2682
|
+
sessionsPath: path23.join(dataDir, "sessions.json"),
|
|
2683
|
+
pidPath: path23.join(dataDir, "openacp.pid"),
|
|
2684
|
+
portFilePath: path23.join(dataDir, "api.port"),
|
|
2685
|
+
pluginsDir: path23.join(dataDir, "plugins"),
|
|
2518
2686
|
logsDir
|
|
2519
2687
|
};
|
|
2520
2688
|
}
|
|
@@ -2523,11 +2691,11 @@ var init_doctor = __esm({
|
|
|
2523
2691
|
});
|
|
2524
2692
|
|
|
2525
2693
|
// src/core/instance/instance-context.ts
|
|
2526
|
-
import
|
|
2694
|
+
import path25 from "path";
|
|
2527
2695
|
import fs26 from "fs";
|
|
2528
2696
|
import os8 from "os";
|
|
2529
2697
|
function getGlobalRoot() {
|
|
2530
|
-
return
|
|
2698
|
+
return path25.join(os8.homedir(), ".openacp");
|
|
2531
2699
|
}
|
|
2532
2700
|
var init_instance_context = __esm({
|
|
2533
2701
|
"src/core/instance/instance-context.ts"() {
|
|
@@ -2537,11 +2705,11 @@ var init_instance_context = __esm({
|
|
|
2537
2705
|
|
|
2538
2706
|
// src/core/instance/instance-registry.ts
|
|
2539
2707
|
import fs27 from "fs";
|
|
2540
|
-
import
|
|
2708
|
+
import path26 from "path";
|
|
2541
2709
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
2542
2710
|
function readIdFromConfig(instanceRoot) {
|
|
2543
2711
|
try {
|
|
2544
|
-
const raw = JSON.parse(fs27.readFileSync(
|
|
2712
|
+
const raw = JSON.parse(fs27.readFileSync(path26.join(instanceRoot, "config.json"), "utf-8"));
|
|
2545
2713
|
return typeof raw.id === "string" && raw.id ? raw.id : null;
|
|
2546
2714
|
} catch {
|
|
2547
2715
|
return null;
|
|
@@ -2587,7 +2755,7 @@ var init_instance_registry = __esm({
|
|
|
2587
2755
|
}
|
|
2588
2756
|
/** Persist the registry to disk, creating parent directories if needed. */
|
|
2589
2757
|
save() {
|
|
2590
|
-
const dir =
|
|
2758
|
+
const dir = path26.dirname(this.registryPath);
|
|
2591
2759
|
fs27.mkdirSync(dir, { recursive: true });
|
|
2592
2760
|
fs27.writeFileSync(this.registryPath, JSON.stringify(this.data, null, 2));
|
|
2593
2761
|
}
|
|
@@ -2654,14 +2822,14 @@ __export(plugin_installer_exports, {
|
|
|
2654
2822
|
importFromDir: () => importFromDir,
|
|
2655
2823
|
installNpmPlugin: () => installNpmPlugin
|
|
2656
2824
|
});
|
|
2657
|
-
import { execFile } from "child_process";
|
|
2658
|
-
import { promisify } from "util";
|
|
2825
|
+
import { execFile as execFile2 } from "child_process";
|
|
2826
|
+
import { promisify as promisify2 } from "util";
|
|
2659
2827
|
import * as fs29 from "fs/promises";
|
|
2660
|
-
import * as
|
|
2828
|
+
import * as path28 from "path";
|
|
2661
2829
|
import { pathToFileURL } from "url";
|
|
2662
2830
|
async function importFromDir(packageName, dir) {
|
|
2663
|
-
const pkgDir =
|
|
2664
|
-
const pkgJsonPath =
|
|
2831
|
+
const pkgDir = path28.join(dir, "node_modules", ...packageName.split("/"));
|
|
2832
|
+
const pkgJsonPath = path28.join(pkgDir, "package.json");
|
|
2665
2833
|
let pkgJson;
|
|
2666
2834
|
try {
|
|
2667
2835
|
pkgJson = JSON.parse(await fs29.readFile(pkgJsonPath, "utf-8"));
|
|
@@ -2677,7 +2845,7 @@ async function importFromDir(packageName, dir) {
|
|
|
2677
2845
|
} else {
|
|
2678
2846
|
entry = pkgJson.main ?? "index.js";
|
|
2679
2847
|
}
|
|
2680
|
-
const entryPath =
|
|
2848
|
+
const entryPath = path28.join(pkgDir, entry);
|
|
2681
2849
|
try {
|
|
2682
2850
|
await fs29.access(entryPath);
|
|
2683
2851
|
} catch {
|
|
@@ -2694,16 +2862,16 @@ async function installNpmPlugin(packageName, pluginsDir) {
|
|
|
2694
2862
|
return await importFromDir(packageName, dir);
|
|
2695
2863
|
} catch {
|
|
2696
2864
|
}
|
|
2697
|
-
await
|
|
2865
|
+
await execFileAsync2("npm", ["install", packageName, "--prefix", dir, "--save", "--ignore-scripts"], {
|
|
2698
2866
|
timeout: 6e4
|
|
2699
2867
|
});
|
|
2700
2868
|
return await importFromDir(packageName, dir);
|
|
2701
2869
|
}
|
|
2702
|
-
var
|
|
2870
|
+
var execFileAsync2, VALID_NPM_NAME;
|
|
2703
2871
|
var init_plugin_installer = __esm({
|
|
2704
2872
|
"src/core/plugin/plugin-installer.ts"() {
|
|
2705
2873
|
"use strict";
|
|
2706
|
-
|
|
2874
|
+
execFileAsync2 = promisify2(execFile2);
|
|
2707
2875
|
VALID_NPM_NAME = /^(@[a-z0-9][\w.-]*\/)?[a-z0-9][\w.-]*(@[\w.^~>=<|-]+)?$/i;
|
|
2708
2876
|
}
|
|
2709
2877
|
});
|
|
@@ -2771,10 +2939,10 @@ var install_context_exports = {};
|
|
|
2771
2939
|
__export(install_context_exports, {
|
|
2772
2940
|
createInstallContext: () => createInstallContext
|
|
2773
2941
|
});
|
|
2774
|
-
import
|
|
2942
|
+
import path29 from "path";
|
|
2775
2943
|
function createInstallContext(opts) {
|
|
2776
2944
|
const { pluginName, settingsManager, basePath, instanceRoot } = opts;
|
|
2777
|
-
const dataDir =
|
|
2945
|
+
const dataDir = path29.join(basePath, pluginName, "data");
|
|
2778
2946
|
return {
|
|
2779
2947
|
pluginName,
|
|
2780
2948
|
terminal: createTerminalIO(),
|
|
@@ -2802,13 +2970,13 @@ __export(api_client_exports, {
|
|
|
2802
2970
|
waitForPortFile: () => waitForPortFile
|
|
2803
2971
|
});
|
|
2804
2972
|
import * as fs30 from "fs";
|
|
2805
|
-
import * as
|
|
2973
|
+
import * as path30 from "path";
|
|
2806
2974
|
import { setTimeout as sleep } from "timers/promises";
|
|
2807
2975
|
function defaultPortFile(root) {
|
|
2808
|
-
return
|
|
2976
|
+
return path30.join(root, "api.port");
|
|
2809
2977
|
}
|
|
2810
2978
|
function defaultSecretFile(root) {
|
|
2811
|
-
return
|
|
2979
|
+
return path30.join(root, "api-secret");
|
|
2812
2980
|
}
|
|
2813
2981
|
async function waitForPortFile(portFilePath, timeoutMs = 5e3, intervalMs = 100) {
|
|
2814
2982
|
const deadline = Date.now() + timeoutMs;
|
|
@@ -2979,7 +3147,7 @@ var init_notification = __esm({
|
|
|
2979
3147
|
|
|
2980
3148
|
// src/plugins/file-service/file-service.ts
|
|
2981
3149
|
import fs32 from "fs";
|
|
2982
|
-
import
|
|
3150
|
+
import path33 from "path";
|
|
2983
3151
|
import { OggOpusDecoder } from "ogg-opus-decoder";
|
|
2984
3152
|
import wav from "node-wav";
|
|
2985
3153
|
function classifyMime(mimeType) {
|
|
@@ -3039,7 +3207,7 @@ var init_file_service = __esm({
|
|
|
3039
3207
|
const entries = await fs32.promises.readdir(this.baseDir, { withFileTypes: true });
|
|
3040
3208
|
for (const entry of entries) {
|
|
3041
3209
|
if (!entry.isDirectory()) continue;
|
|
3042
|
-
const dirPath =
|
|
3210
|
+
const dirPath = path33.join(this.baseDir, entry.name);
|
|
3043
3211
|
try {
|
|
3044
3212
|
const stat = await fs32.promises.stat(dirPath);
|
|
3045
3213
|
if (stat.mtimeMs < cutoff) {
|
|
@@ -3062,10 +3230,10 @@ var init_file_service = __esm({
|
|
|
3062
3230
|
* so the user-facing name is not lost.
|
|
3063
3231
|
*/
|
|
3064
3232
|
async saveFile(sessionId, fileName, data, mimeType) {
|
|
3065
|
-
const sessionDir =
|
|
3233
|
+
const sessionDir = path33.join(this.baseDir, sessionId);
|
|
3066
3234
|
await fs32.promises.mkdir(sessionDir, { recursive: true });
|
|
3067
3235
|
const safeName = `${Date.now()}-${fileName.replace(/[^a-zA-Z0-9._-]/g, "_")}`;
|
|
3068
|
-
const filePath =
|
|
3236
|
+
const filePath = path33.join(sessionDir, safeName);
|
|
3069
3237
|
await fs32.promises.writeFile(filePath, data);
|
|
3070
3238
|
return {
|
|
3071
3239
|
type: classifyMime(mimeType),
|
|
@@ -3083,12 +3251,12 @@ var init_file_service = __esm({
|
|
|
3083
3251
|
try {
|
|
3084
3252
|
const stat = await fs32.promises.stat(filePath);
|
|
3085
3253
|
if (!stat.isFile()) return null;
|
|
3086
|
-
const ext =
|
|
3254
|
+
const ext = path33.extname(filePath).toLowerCase();
|
|
3087
3255
|
const mimeType = EXT_TO_MIME[ext] || "application/octet-stream";
|
|
3088
3256
|
return {
|
|
3089
3257
|
type: classifyMime(mimeType),
|
|
3090
3258
|
filePath,
|
|
3091
|
-
fileName:
|
|
3259
|
+
fileName: path33.basename(filePath),
|
|
3092
3260
|
mimeType,
|
|
3093
3261
|
size: stat.size
|
|
3094
3262
|
};
|
|
@@ -3720,8 +3888,8 @@ data: ${JSON.stringify(data)}
|
|
|
3720
3888
|
|
|
3721
3889
|
// src/plugins/api-server/static-server.ts
|
|
3722
3890
|
import * as fs33 from "fs";
|
|
3723
|
-
import * as
|
|
3724
|
-
import { fileURLToPath } from "url";
|
|
3891
|
+
import * as path34 from "path";
|
|
3892
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
3725
3893
|
var MIME_TYPES, StaticServer;
|
|
3726
3894
|
var init_static_server = __esm({
|
|
3727
3895
|
"src/plugins/api-server/static-server.ts"() {
|
|
@@ -3743,17 +3911,17 @@ var init_static_server = __esm({
|
|
|
3743
3911
|
constructor(uiDir) {
|
|
3744
3912
|
this.uiDir = uiDir;
|
|
3745
3913
|
if (!this.uiDir) {
|
|
3746
|
-
const __filename =
|
|
3747
|
-
const candidate =
|
|
3748
|
-
if (fs33.existsSync(
|
|
3914
|
+
const __filename = fileURLToPath2(import.meta.url);
|
|
3915
|
+
const candidate = path34.resolve(path34.dirname(__filename), "../../ui/dist");
|
|
3916
|
+
if (fs33.existsSync(path34.join(candidate, "index.html"))) {
|
|
3749
3917
|
this.uiDir = candidate;
|
|
3750
3918
|
}
|
|
3751
3919
|
if (!this.uiDir) {
|
|
3752
|
-
const publishCandidate =
|
|
3753
|
-
|
|
3920
|
+
const publishCandidate = path34.resolve(
|
|
3921
|
+
path34.dirname(__filename),
|
|
3754
3922
|
"../ui"
|
|
3755
3923
|
);
|
|
3756
|
-
if (fs33.existsSync(
|
|
3924
|
+
if (fs33.existsSync(path34.join(publishCandidate, "index.html"))) {
|
|
3757
3925
|
this.uiDir = publishCandidate;
|
|
3758
3926
|
}
|
|
3759
3927
|
}
|
|
@@ -3771,9 +3939,9 @@ var init_static_server = __esm({
|
|
|
3771
3939
|
serve(req, res) {
|
|
3772
3940
|
if (!this.uiDir) return false;
|
|
3773
3941
|
const urlPath = (req.url || "/").split("?")[0];
|
|
3774
|
-
const safePath =
|
|
3775
|
-
const filePath =
|
|
3776
|
-
if (!filePath.startsWith(this.uiDir +
|
|
3942
|
+
const safePath = path34.normalize(urlPath);
|
|
3943
|
+
const filePath = path34.join(this.uiDir, safePath);
|
|
3944
|
+
if (!filePath.startsWith(this.uiDir + path34.sep) && filePath !== this.uiDir)
|
|
3777
3945
|
return false;
|
|
3778
3946
|
let realFilePath;
|
|
3779
3947
|
try {
|
|
@@ -3783,11 +3951,11 @@ var init_static_server = __esm({
|
|
|
3783
3951
|
}
|
|
3784
3952
|
if (realFilePath !== null) {
|
|
3785
3953
|
const realUiDir = fs33.realpathSync(this.uiDir);
|
|
3786
|
-
if (!realFilePath.startsWith(realUiDir +
|
|
3954
|
+
if (!realFilePath.startsWith(realUiDir + path34.sep) && realFilePath !== realUiDir)
|
|
3787
3955
|
return false;
|
|
3788
3956
|
}
|
|
3789
3957
|
if (realFilePath !== null && fs33.existsSync(realFilePath) && fs33.statSync(realFilePath).isFile()) {
|
|
3790
|
-
const ext =
|
|
3958
|
+
const ext = path34.extname(filePath);
|
|
3791
3959
|
const contentType = MIME_TYPES[ext] ?? "application/octet-stream";
|
|
3792
3960
|
const isHashed = /\.[a-zA-Z0-9]{8,}\.(js|css)$/.test(filePath);
|
|
3793
3961
|
const cacheControl = isHashed ? "public, max-age=31536000, immutable" : "no-cache";
|
|
@@ -3798,7 +3966,7 @@ var init_static_server = __esm({
|
|
|
3798
3966
|
fs33.createReadStream(realFilePath).pipe(res);
|
|
3799
3967
|
return true;
|
|
3800
3968
|
}
|
|
3801
|
-
const indexPath =
|
|
3969
|
+
const indexPath = path34.join(this.uiDir, "index.html");
|
|
3802
3970
|
if (fs33.existsSync(indexPath)) {
|
|
3803
3971
|
res.writeHead(200, {
|
|
3804
3972
|
"Content-Type": "text/html; charset=utf-8",
|
|
@@ -3916,87 +4084,19 @@ var init_speech_service = __esm({
|
|
|
3916
4084
|
}
|
|
3917
4085
|
});
|
|
3918
4086
|
|
|
3919
|
-
// src/plugins/speech/providers/groq.ts
|
|
3920
|
-
function mimeToExt(mimeType) {
|
|
3921
|
-
const map = {
|
|
3922
|
-
"audio/ogg": ".ogg",
|
|
3923
|
-
"audio/wav": ".wav",
|
|
3924
|
-
"audio/mpeg": ".mp3",
|
|
3925
|
-
"audio/mp4": ".m4a",
|
|
3926
|
-
"audio/webm": ".webm",
|
|
3927
|
-
"audio/flac": ".flac"
|
|
3928
|
-
};
|
|
3929
|
-
return map[mimeType] || ".bin";
|
|
3930
|
-
}
|
|
3931
|
-
var GROQ_API_URL, GroqSTT;
|
|
3932
|
-
var init_groq = __esm({
|
|
3933
|
-
"src/plugins/speech/providers/groq.ts"() {
|
|
3934
|
-
"use strict";
|
|
3935
|
-
GROQ_API_URL = "https://api.groq.com/openai/v1/audio/transcriptions";
|
|
3936
|
-
GroqSTT = class {
|
|
3937
|
-
constructor(apiKey, defaultModel = "whisper-large-v3-turbo") {
|
|
3938
|
-
this.apiKey = apiKey;
|
|
3939
|
-
this.defaultModel = defaultModel;
|
|
3940
|
-
}
|
|
3941
|
-
apiKey;
|
|
3942
|
-
defaultModel;
|
|
3943
|
-
name = "groq";
|
|
3944
|
-
/**
|
|
3945
|
-
* Transcribes audio using the Groq Whisper API.
|
|
3946
|
-
*
|
|
3947
|
-
* `verbose_json` response format is requested so the API returns language
|
|
3948
|
-
* detection and duration metadata alongside the transcript text.
|
|
3949
|
-
*/
|
|
3950
|
-
async transcribe(audioBuffer, mimeType, options) {
|
|
3951
|
-
const ext = mimeToExt(mimeType);
|
|
3952
|
-
const form = new FormData();
|
|
3953
|
-
form.append("file", new Blob([new Uint8Array(audioBuffer)], { type: mimeType }), `audio${ext}`);
|
|
3954
|
-
form.append("model", options?.model || this.defaultModel);
|
|
3955
|
-
form.append("response_format", "verbose_json");
|
|
3956
|
-
if (options?.language) {
|
|
3957
|
-
form.append("language", options.language);
|
|
3958
|
-
}
|
|
3959
|
-
const resp = await fetch(GROQ_API_URL, {
|
|
3960
|
-
method: "POST",
|
|
3961
|
-
headers: { Authorization: `Bearer ${this.apiKey}` },
|
|
3962
|
-
body: form
|
|
3963
|
-
});
|
|
3964
|
-
if (!resp.ok) {
|
|
3965
|
-
const body = await resp.text();
|
|
3966
|
-
if (resp.status === 401) {
|
|
3967
|
-
throw new Error("Invalid Groq API key. Check your key at console.groq.com.");
|
|
3968
|
-
}
|
|
3969
|
-
if (resp.status === 413) {
|
|
3970
|
-
throw new Error("Audio file too large for Groq API (max 25MB).");
|
|
3971
|
-
}
|
|
3972
|
-
if (resp.status === 429) {
|
|
3973
|
-
throw new Error("Groq rate limit exceeded. Free tier: 28,800 seconds/day. Try again later.");
|
|
3974
|
-
}
|
|
3975
|
-
throw new Error(`Groq STT error (${resp.status}): ${body}`);
|
|
3976
|
-
}
|
|
3977
|
-
const data = await resp.json();
|
|
3978
|
-
return {
|
|
3979
|
-
text: data.text,
|
|
3980
|
-
language: data.language,
|
|
3981
|
-
duration: data.duration
|
|
3982
|
-
};
|
|
3983
|
-
}
|
|
3984
|
-
};
|
|
3985
|
-
}
|
|
3986
|
-
});
|
|
3987
|
-
|
|
3988
4087
|
// src/plugins/speech/exports.ts
|
|
3989
4088
|
var init_exports = __esm({
|
|
3990
4089
|
"src/plugins/speech/exports.ts"() {
|
|
3991
4090
|
"use strict";
|
|
3992
4091
|
init_speech_service();
|
|
3993
4092
|
init_groq();
|
|
4093
|
+
init_local_whisper();
|
|
3994
4094
|
}
|
|
3995
4095
|
});
|
|
3996
4096
|
|
|
3997
4097
|
// src/plugins/context/context-cache.ts
|
|
3998
4098
|
import * as fs34 from "fs";
|
|
3999
|
-
import * as
|
|
4099
|
+
import * as path35 from "path";
|
|
4000
4100
|
import * as crypto2 from "crypto";
|
|
4001
4101
|
var DEFAULT_TTL_MS, ContextCache;
|
|
4002
4102
|
var init_context_cache = __esm({
|
|
@@ -4015,7 +4115,7 @@ var init_context_cache = __esm({
|
|
|
4015
4115
|
return crypto2.createHash("sha256").update(`${repoPath}:${queryKey}`).digest("hex").slice(0, 16);
|
|
4016
4116
|
}
|
|
4017
4117
|
filePath(repoPath, queryKey) {
|
|
4018
|
-
return
|
|
4118
|
+
return path35.join(this.cacheDir, `${this.keyHash(repoPath, queryKey)}.json`);
|
|
4019
4119
|
}
|
|
4020
4120
|
get(repoPath, queryKey) {
|
|
4021
4121
|
const fp = this.filePath(repoPath, queryKey);
|
|
@@ -5005,8 +5105,8 @@ function formatToolSummary(name, rawInput, displaySummary) {
|
|
|
5005
5105
|
}
|
|
5006
5106
|
if (lowerName === "grep") {
|
|
5007
5107
|
const pattern = args.pattern ?? "";
|
|
5008
|
-
const
|
|
5009
|
-
return pattern ? `\u{1F50D} Grep "${pattern}"${
|
|
5108
|
+
const path36 = args.path ?? "";
|
|
5109
|
+
return pattern ? `\u{1F50D} Grep "${pattern}"${path36 ? ` in ${path36}` : ""}` : `\u{1F527} ${name}`;
|
|
5010
5110
|
}
|
|
5011
5111
|
if (lowerName === "glob") {
|
|
5012
5112
|
const pattern = args.pattern ?? "";
|
|
@@ -5042,8 +5142,8 @@ function formatToolTitle(name, rawInput, displayTitle) {
|
|
|
5042
5142
|
}
|
|
5043
5143
|
if (lowerName === "grep") {
|
|
5044
5144
|
const pattern = args.pattern ?? "";
|
|
5045
|
-
const
|
|
5046
|
-
return pattern ? `"${pattern}"${
|
|
5145
|
+
const path36 = args.path ?? "";
|
|
5146
|
+
return pattern ? `"${pattern}"${path36 ? ` in ${path36}` : ""}` : name;
|
|
5047
5147
|
}
|
|
5048
5148
|
if (lowerName === "glob") {
|
|
5049
5149
|
return String(args.pattern ?? name);
|
|
@@ -6356,14 +6456,14 @@ __export(version_exports, {
|
|
|
6356
6456
|
getLatestVersion: () => getLatestVersion,
|
|
6357
6457
|
runUpdate: () => runUpdate
|
|
6358
6458
|
});
|
|
6359
|
-
import { fileURLToPath as
|
|
6459
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
6360
6460
|
import { dirname as dirname12, join as join16, resolve as resolve6 } from "path";
|
|
6361
|
-
import { existsSync as
|
|
6461
|
+
import { existsSync as existsSync17, readFileSync as readFileSync14 } from "fs";
|
|
6362
6462
|
function findPackageJson() {
|
|
6363
|
-
let dir = dirname12(
|
|
6463
|
+
let dir = dirname12(fileURLToPath3(import.meta.url));
|
|
6364
6464
|
for (let i = 0; i < 5; i++) {
|
|
6365
6465
|
const candidate = join16(dir, "package.json");
|
|
6366
|
-
if (
|
|
6466
|
+
if (existsSync17(candidate)) return candidate;
|
|
6367
6467
|
const parent = resolve6(dir, "..");
|
|
6368
6468
|
if (parent === dir) break;
|
|
6369
6469
|
dir = parent;
|
|
@@ -7241,7 +7341,7 @@ __export(integrate_exports, {
|
|
|
7241
7341
|
listIntegrations: () => listIntegrations,
|
|
7242
7342
|
uninstallIntegration: () => uninstallIntegration
|
|
7243
7343
|
});
|
|
7244
|
-
import { existsSync as
|
|
7344
|
+
import { existsSync as existsSync18, mkdirSync as mkdirSync11, readFileSync as readFileSync15, writeFileSync as writeFileSync11, unlinkSync as unlinkSync7, chmodSync, rmdirSync } from "fs";
|
|
7245
7345
|
import { join as join17, dirname as dirname13 } from "path";
|
|
7246
7346
|
import { homedir as homedir4 } from "os";
|
|
7247
7347
|
function isHooksIntegrationSpec(spec) {
|
|
@@ -7403,7 +7503,7 @@ function generateOpencodePlugin(spec) {
|
|
|
7403
7503
|
function mergeSettingsJson(settingsPath, hookEvent, hookScriptPath) {
|
|
7404
7504
|
const fullPath = expandPath(settingsPath);
|
|
7405
7505
|
let settings = {};
|
|
7406
|
-
if (
|
|
7506
|
+
if (existsSync18(fullPath)) {
|
|
7407
7507
|
const raw = readFileSync15(fullPath, "utf-8");
|
|
7408
7508
|
writeFileSync11(`${fullPath}.bak`, raw);
|
|
7409
7509
|
settings = JSON.parse(raw);
|
|
@@ -7426,7 +7526,7 @@ function mergeSettingsJson(settingsPath, hookEvent, hookScriptPath) {
|
|
|
7426
7526
|
function mergeHooksJson(settingsPath, hookEvent, hookScriptPath) {
|
|
7427
7527
|
const fullPath = expandPath(settingsPath);
|
|
7428
7528
|
let config = { version: 1 };
|
|
7429
|
-
if (
|
|
7529
|
+
if (existsSync18(fullPath)) {
|
|
7430
7530
|
const raw = readFileSync15(fullPath, "utf-8");
|
|
7431
7531
|
writeFileSync11(`${fullPath}.bak`, raw);
|
|
7432
7532
|
config = JSON.parse(raw);
|
|
@@ -7444,7 +7544,7 @@ function mergeHooksJson(settingsPath, hookEvent, hookScriptPath) {
|
|
|
7444
7544
|
}
|
|
7445
7545
|
function removeFromSettingsJson(settingsPath, hookEvent) {
|
|
7446
7546
|
const fullPath = expandPath(settingsPath);
|
|
7447
|
-
if (!
|
|
7547
|
+
if (!existsSync18(fullPath)) return;
|
|
7448
7548
|
const raw = readFileSync15(fullPath, "utf-8");
|
|
7449
7549
|
const settings = JSON.parse(raw);
|
|
7450
7550
|
const hooks = settings.hooks;
|
|
@@ -7459,7 +7559,7 @@ function removeFromSettingsJson(settingsPath, hookEvent) {
|
|
|
7459
7559
|
}
|
|
7460
7560
|
function removeFromHooksJson(settingsPath, hookEvent) {
|
|
7461
7561
|
const fullPath = expandPath(settingsPath);
|
|
7462
|
-
if (!
|
|
7562
|
+
if (!existsSync18(fullPath)) return;
|
|
7463
7563
|
const raw = readFileSync15(fullPath, "utf-8");
|
|
7464
7564
|
const config = JSON.parse(raw);
|
|
7465
7565
|
const hooks = config.hooks;
|
|
@@ -7525,7 +7625,7 @@ async function uninstallHooksIntegration(agentKey, spec) {
|
|
|
7525
7625
|
const hooksDir = expandPath(spec.hooksDirPath);
|
|
7526
7626
|
for (const filename of ["openacp-inject-session.sh", "openacp-handoff.sh"]) {
|
|
7527
7627
|
const filePath = join17(hooksDir, filename);
|
|
7528
|
-
if (
|
|
7628
|
+
if (existsSync18(filePath)) {
|
|
7529
7629
|
unlinkSync7(filePath);
|
|
7530
7630
|
logs.push(`Removed ${filePath}`);
|
|
7531
7631
|
}
|
|
@@ -7534,7 +7634,7 @@ async function uninstallHooksIntegration(agentKey, spec) {
|
|
|
7534
7634
|
if (spec.commandFormat === "skill") {
|
|
7535
7635
|
const skillDir = expandPath(join17(spec.commandsPath, spec.handoffCommandName));
|
|
7536
7636
|
const skillPath = join17(skillDir, "SKILL.md");
|
|
7537
|
-
if (
|
|
7637
|
+
if (existsSync18(skillPath)) {
|
|
7538
7638
|
unlinkSync7(skillPath);
|
|
7539
7639
|
try {
|
|
7540
7640
|
rmdirSync(skillDir);
|
|
@@ -7544,7 +7644,7 @@ async function uninstallHooksIntegration(agentKey, spec) {
|
|
|
7544
7644
|
}
|
|
7545
7645
|
} else {
|
|
7546
7646
|
const cmdPath = expandPath(join17(spec.commandsPath, `${spec.handoffCommandName}.md`));
|
|
7547
|
-
if (
|
|
7647
|
+
if (existsSync18(cmdPath)) {
|
|
7548
7648
|
unlinkSync7(cmdPath);
|
|
7549
7649
|
logs.push(`Removed ${cmdPath}`);
|
|
7550
7650
|
}
|
|
@@ -7571,11 +7671,11 @@ async function installPluginIntegration(_agentKey, spec) {
|
|
|
7571
7671
|
const pluginsDir = expandPath(spec.pluginsPath);
|
|
7572
7672
|
mkdirSync11(pluginsDir, { recursive: true });
|
|
7573
7673
|
const pluginPath = join17(pluginsDir, spec.pluginFileName);
|
|
7574
|
-
if (
|
|
7674
|
+
if (existsSync18(commandPath) && existsSync18(pluginPath)) {
|
|
7575
7675
|
logs.push("Already installed, skipping.");
|
|
7576
7676
|
return { success: true, logs };
|
|
7577
7677
|
}
|
|
7578
|
-
if (
|
|
7678
|
+
if (existsSync18(commandPath) || existsSync18(pluginPath)) {
|
|
7579
7679
|
logs.push("Overwriting existing files.");
|
|
7580
7680
|
}
|
|
7581
7681
|
writeFileSync11(commandPath, generateOpencodeHandoffCommand(spec));
|
|
@@ -7593,13 +7693,13 @@ async function uninstallPluginIntegration(_agentKey, spec) {
|
|
|
7593
7693
|
try {
|
|
7594
7694
|
const commandPath = join17(expandPath(spec.commandsPath), spec.handoffCommandFile);
|
|
7595
7695
|
let removedCount = 0;
|
|
7596
|
-
if (
|
|
7696
|
+
if (existsSync18(commandPath)) {
|
|
7597
7697
|
unlinkSync7(commandPath);
|
|
7598
7698
|
logs.push(`Removed ${commandPath}`);
|
|
7599
7699
|
removedCount += 1;
|
|
7600
7700
|
}
|
|
7601
7701
|
const pluginPath = join17(expandPath(spec.pluginsPath), spec.pluginFileName);
|
|
7602
|
-
if (
|
|
7702
|
+
if (existsSync18(pluginPath)) {
|
|
7603
7703
|
unlinkSync7(pluginPath);
|
|
7604
7704
|
logs.push(`Removed ${pluginPath}`);
|
|
7605
7705
|
removedCount += 1;
|
|
@@ -7633,11 +7733,11 @@ function buildHandoffItem(agentKey, spec) {
|
|
|
7633
7733
|
isInstalled() {
|
|
7634
7734
|
if (isHooksIntegrationSpec(spec)) {
|
|
7635
7735
|
const hooksDir = expandPath(spec.hooksDirPath);
|
|
7636
|
-
return
|
|
7736
|
+
return existsSync18(join17(hooksDir, "openacp-inject-session.sh")) && existsSync18(join17(hooksDir, "openacp-handoff.sh"));
|
|
7637
7737
|
}
|
|
7638
7738
|
const commandPath = join17(expandPath(spec.commandsPath), spec.handoffCommandFile);
|
|
7639
7739
|
const pluginPath = join17(expandPath(spec.pluginsPath), spec.pluginFileName);
|
|
7640
|
-
return
|
|
7740
|
+
return existsSync18(commandPath) && existsSync18(pluginPath);
|
|
7641
7741
|
},
|
|
7642
7742
|
install: () => installIntegration(agentKey, spec),
|
|
7643
7743
|
uninstall: () => uninstallIntegration(agentKey, spec)
|
|
@@ -7659,7 +7759,7 @@ function buildTunnelItem(spec) {
|
|
|
7659
7759
|
name: "Tunnel",
|
|
7660
7760
|
description: "Expose local ports to the internet via OpenACP tunnel",
|
|
7661
7761
|
isInstalled() {
|
|
7662
|
-
return
|
|
7762
|
+
return existsSync18(getTunnelPath());
|
|
7663
7763
|
},
|
|
7664
7764
|
async install() {
|
|
7665
7765
|
const logs = [];
|
|
@@ -7678,7 +7778,7 @@ function buildTunnelItem(spec) {
|
|
|
7678
7778
|
const logs = [];
|
|
7679
7779
|
try {
|
|
7680
7780
|
const skillPath = getTunnelPath();
|
|
7681
|
-
if (
|
|
7781
|
+
if (existsSync18(skillPath)) {
|
|
7682
7782
|
unlinkSync7(skillPath);
|
|
7683
7783
|
try {
|
|
7684
7784
|
rmdirSync(dirname13(skillPath));
|
|
@@ -16124,7 +16224,7 @@ var SessionFactory = class {
|
|
|
16124
16224
|
};
|
|
16125
16225
|
|
|
16126
16226
|
// src/core/core.ts
|
|
16127
|
-
import
|
|
16227
|
+
import path15 from "path";
|
|
16128
16228
|
import { nanoid as nanoid3 } from "nanoid";
|
|
16129
16229
|
|
|
16130
16230
|
// src/core/sessions/session-store.ts
|
|
@@ -18238,6 +18338,7 @@ function registerCoreMenuItems(registry) {
|
|
|
18238
18338
|
|
|
18239
18339
|
// src/core/core.ts
|
|
18240
18340
|
init_log();
|
|
18341
|
+
init_native_stt();
|
|
18241
18342
|
init_events();
|
|
18242
18343
|
var log17 = createChildLogger({ module: "core" });
|
|
18243
18344
|
var OpenACPCore = class {
|
|
@@ -18381,21 +18482,7 @@ var OpenACPCore = class {
|
|
|
18381
18482
|
const settingsMgr = this.settingsManager;
|
|
18382
18483
|
if (settingsMgr) {
|
|
18383
18484
|
const pluginCfg = await settingsMgr.loadSettings("@openacp/speech");
|
|
18384
|
-
const
|
|
18385
|
-
const sttProviders = {};
|
|
18386
|
-
if (groqApiKey) {
|
|
18387
|
-
sttProviders.groq = { apiKey: groqApiKey };
|
|
18388
|
-
}
|
|
18389
|
-
const newSpeechConfig = {
|
|
18390
|
-
stt: {
|
|
18391
|
-
provider: groqApiKey ? "groq" : null,
|
|
18392
|
-
providers: sttProviders
|
|
18393
|
-
},
|
|
18394
|
-
tts: {
|
|
18395
|
-
provider: pluginCfg.ttsProvider ?? null,
|
|
18396
|
-
providers: {}
|
|
18397
|
-
}
|
|
18398
|
-
};
|
|
18485
|
+
const newSpeechConfig = buildSpeechServiceConfig(pluginCfg);
|
|
18399
18486
|
speechSvc.refreshProviders(newSpeechConfig);
|
|
18400
18487
|
log17.info("Speech service config updated at runtime (from plugin settings)");
|
|
18401
18488
|
}
|
|
@@ -18404,7 +18491,7 @@ var OpenACPCore = class {
|
|
|
18404
18491
|
}
|
|
18405
18492
|
);
|
|
18406
18493
|
registerCoreMenuItems(this.menuRegistry);
|
|
18407
|
-
this.assistantRegistry.setInstanceRoot(
|
|
18494
|
+
this.assistantRegistry.setInstanceRoot(path15.dirname(ctx.root));
|
|
18408
18495
|
this.assistantRegistry.register(createSessionsSection(this));
|
|
18409
18496
|
this.assistantRegistry.register(createAgentsSection(this));
|
|
18410
18497
|
this.assistantRegistry.register(createConfigSection(this));
|
|
@@ -18838,8 +18925,8 @@ ${text3}`;
|
|
|
18838
18925
|
message: `Agent '${agentName}' not found`
|
|
18839
18926
|
};
|
|
18840
18927
|
}
|
|
18841
|
-
const { existsSync:
|
|
18842
|
-
if (!
|
|
18928
|
+
const { existsSync: existsSync19 } = await import("fs");
|
|
18929
|
+
if (!existsSync19(cwd)) {
|
|
18843
18930
|
return {
|
|
18844
18931
|
ok: false,
|
|
18845
18932
|
error: "invalid_cwd",
|
|
@@ -19224,29 +19311,29 @@ init_doctor();
|
|
|
19224
19311
|
init_config_registry();
|
|
19225
19312
|
|
|
19226
19313
|
// src/core/config/config-editor.ts
|
|
19227
|
-
import * as
|
|
19314
|
+
import * as path31 from "path";
|
|
19228
19315
|
import * as clack2 from "@clack/prompts";
|
|
19229
19316
|
|
|
19230
19317
|
// src/cli/autostart.ts
|
|
19231
19318
|
init_log();
|
|
19232
19319
|
import { execFileSync as execFileSync6 } from "child_process";
|
|
19233
19320
|
import * as fs25 from "fs";
|
|
19234
|
-
import * as
|
|
19321
|
+
import * as path24 from "path";
|
|
19235
19322
|
import * as os7 from "os";
|
|
19236
19323
|
var log19 = createChildLogger({ module: "autostart" });
|
|
19237
|
-
var LEGACY_LAUNCHD_PLIST_PATH =
|
|
19238
|
-
var LEGACY_SYSTEMD_SERVICE_PATH =
|
|
19324
|
+
var LEGACY_LAUNCHD_PLIST_PATH = path24.join(os7.homedir(), "Library", "LaunchAgents", "com.openacp.daemon.plist");
|
|
19325
|
+
var LEGACY_SYSTEMD_SERVICE_PATH = path24.join(os7.homedir(), ".config", "systemd", "user", "openacp.service");
|
|
19239
19326
|
function getLaunchdLabel(instanceId) {
|
|
19240
19327
|
return `com.openacp.daemon.${instanceId}`;
|
|
19241
19328
|
}
|
|
19242
19329
|
function getLaunchdPlistPath(instanceId) {
|
|
19243
|
-
return
|
|
19330
|
+
return path24.join(os7.homedir(), "Library", "LaunchAgents", `${getLaunchdLabel(instanceId)}.plist`);
|
|
19244
19331
|
}
|
|
19245
19332
|
function getSystemdServiceName(instanceId) {
|
|
19246
19333
|
return `openacp-${instanceId}`;
|
|
19247
19334
|
}
|
|
19248
19335
|
function getSystemdServicePath(instanceId) {
|
|
19249
|
-
return
|
|
19336
|
+
return path24.join(os7.homedir(), ".config", "systemd", "user", `${getSystemdServiceName(instanceId)}.service`);
|
|
19250
19337
|
}
|
|
19251
19338
|
function isAutoStartSupported() {
|
|
19252
19339
|
return process.platform === "darwin" || process.platform === "linux";
|
|
@@ -19260,7 +19347,7 @@ function escapeSystemdValue(str) {
|
|
|
19260
19347
|
}
|
|
19261
19348
|
function generateLaunchdPlist(nodePath, cliPath, logDir2, instanceRoot, instanceId) {
|
|
19262
19349
|
const label = getLaunchdLabel(instanceId);
|
|
19263
|
-
const logFile =
|
|
19350
|
+
const logFile = path24.join(logDir2, "openacp.log");
|
|
19264
19351
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
19265
19352
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
19266
19353
|
<plist version="1.0">
|
|
@@ -19342,14 +19429,14 @@ function installAutoStart(logDir2, instanceRoot, instanceId) {
|
|
|
19342
19429
|
return { success: false, error: "Auto-start not supported on this platform" };
|
|
19343
19430
|
}
|
|
19344
19431
|
const nodePath = process.execPath;
|
|
19345
|
-
const cliPath =
|
|
19346
|
-
const resolvedLogDir = logDir2.startsWith("~") ?
|
|
19432
|
+
const cliPath = path24.resolve(process.argv[1]);
|
|
19433
|
+
const resolvedLogDir = logDir2.startsWith("~") ? path24.join(os7.homedir(), logDir2.slice(1)) : logDir2;
|
|
19347
19434
|
try {
|
|
19348
19435
|
migrateLegacy();
|
|
19349
19436
|
if (process.platform === "darwin") {
|
|
19350
19437
|
const plistPath = getLaunchdPlistPath(instanceId);
|
|
19351
19438
|
const plist = generateLaunchdPlist(nodePath, cliPath, resolvedLogDir, instanceRoot, instanceId);
|
|
19352
|
-
const dir =
|
|
19439
|
+
const dir = path24.dirname(plistPath);
|
|
19353
19440
|
fs25.mkdirSync(dir, { recursive: true });
|
|
19354
19441
|
fs25.writeFileSync(plistPath, plist);
|
|
19355
19442
|
const uid = process.getuid();
|
|
@@ -19366,7 +19453,7 @@ function installAutoStart(logDir2, instanceRoot, instanceId) {
|
|
|
19366
19453
|
const servicePath = getSystemdServicePath(instanceId);
|
|
19367
19454
|
const serviceName = getSystemdServiceName(instanceId);
|
|
19368
19455
|
const unit = generateSystemdUnit(nodePath, cliPath, instanceRoot, instanceId);
|
|
19369
|
-
const dir =
|
|
19456
|
+
const dir = path24.dirname(servicePath);
|
|
19370
19457
|
fs25.mkdirSync(dir, { recursive: true });
|
|
19371
19458
|
fs25.writeFileSync(servicePath, unit);
|
|
19372
19459
|
execFileSync6("systemctl", ["--user", "daemon-reload"], { stdio: "pipe" });
|
|
@@ -19435,24 +19522,24 @@ init_instance_context();
|
|
|
19435
19522
|
init_instance_registry();
|
|
19436
19523
|
init_log();
|
|
19437
19524
|
import fs28 from "fs";
|
|
19438
|
-
import
|
|
19525
|
+
import path27 from "path";
|
|
19439
19526
|
var log20 = createChildLogger({ module: "resolve-instance-id" });
|
|
19440
19527
|
function resolveInstanceId(instanceRoot) {
|
|
19441
19528
|
try {
|
|
19442
|
-
const configPath =
|
|
19529
|
+
const configPath = path27.join(instanceRoot, "config.json");
|
|
19443
19530
|
const raw = JSON.parse(fs28.readFileSync(configPath, "utf-8"));
|
|
19444
19531
|
if (raw.id && typeof raw.id === "string") return raw.id;
|
|
19445
19532
|
} catch {
|
|
19446
19533
|
}
|
|
19447
19534
|
try {
|
|
19448
|
-
const reg = new InstanceRegistry(
|
|
19535
|
+
const reg = new InstanceRegistry(path27.join(getGlobalRoot(), "instances.json"));
|
|
19449
19536
|
reg.load();
|
|
19450
19537
|
const entry = reg.getByRoot(instanceRoot);
|
|
19451
19538
|
if (entry?.id) return entry.id;
|
|
19452
19539
|
} catch (err) {
|
|
19453
19540
|
log20.debug({ err: err.message, instanceRoot }, "Could not read instance registry, using fallback id");
|
|
19454
19541
|
}
|
|
19455
|
-
return
|
|
19542
|
+
return path27.basename(path27.dirname(instanceRoot)).replace(/[^a-zA-Z0-9-]/g, "-") || "default";
|
|
19456
19543
|
}
|
|
19457
19544
|
|
|
19458
19545
|
// src/core/config/config-editor.ts
|
|
@@ -20024,7 +20111,7 @@ async function runConfigEditor(configManager, mode = "file", apiPort, settingsMa
|
|
|
20024
20111
|
await configManager.load();
|
|
20025
20112
|
const config = configManager.get();
|
|
20026
20113
|
const updates = {};
|
|
20027
|
-
const instanceRoot =
|
|
20114
|
+
const instanceRoot = path31.dirname(configManager.getConfigPath());
|
|
20028
20115
|
console.log(`
|
|
20029
20116
|
${c.cyan}${c.bold}OpenACP Config Editor${c.reset}`);
|
|
20030
20117
|
console.log(dim(`Config: ${configManager.getConfigPath()}`));
|
|
@@ -20081,17 +20168,17 @@ ${c.cyan}${c.bold}OpenACP Config Editor${c.reset}`);
|
|
|
20081
20168
|
async function sendConfigViaApi(port, updates) {
|
|
20082
20169
|
const { apiCall: call } = await Promise.resolve().then(() => (init_api_client(), api_client_exports));
|
|
20083
20170
|
const paths = flattenToPaths(updates);
|
|
20084
|
-
for (const { path:
|
|
20171
|
+
for (const { path: path36, value } of paths) {
|
|
20085
20172
|
const res = await call(port, "/api/config", {
|
|
20086
20173
|
method: "PATCH",
|
|
20087
20174
|
headers: { "Content-Type": "application/json" },
|
|
20088
|
-
body: JSON.stringify({ path:
|
|
20175
|
+
body: JSON.stringify({ path: path36, value })
|
|
20089
20176
|
});
|
|
20090
20177
|
const data = await res.json();
|
|
20091
20178
|
if (!res.ok) {
|
|
20092
|
-
console.log(warn(`Failed to update ${
|
|
20179
|
+
console.log(warn(`Failed to update ${path36}: ${data.error}`));
|
|
20093
20180
|
} else if (data.needsRestart) {
|
|
20094
|
-
console.log(warn(`${
|
|
20181
|
+
console.log(warn(`${path36} updated \u2014 restart required`));
|
|
20095
20182
|
}
|
|
20096
20183
|
}
|
|
20097
20184
|
}
|
|
@@ -20112,18 +20199,18 @@ function flattenToPaths(obj, prefix = "") {
|
|
|
20112
20199
|
init_config();
|
|
20113
20200
|
import { spawn as spawn3 } from "child_process";
|
|
20114
20201
|
import * as fs31 from "fs";
|
|
20115
|
-
import * as
|
|
20202
|
+
import * as path32 from "path";
|
|
20116
20203
|
function getPidPath(root) {
|
|
20117
|
-
return
|
|
20204
|
+
return path32.join(root, "openacp.pid");
|
|
20118
20205
|
}
|
|
20119
20206
|
function getLogDir(root) {
|
|
20120
|
-
return
|
|
20207
|
+
return path32.join(root, "logs");
|
|
20121
20208
|
}
|
|
20122
20209
|
function getRunningMarker(root) {
|
|
20123
|
-
return
|
|
20210
|
+
return path32.join(root, "running");
|
|
20124
20211
|
}
|
|
20125
20212
|
function writePidFile(pidPath, pid) {
|
|
20126
|
-
const dir =
|
|
20213
|
+
const dir = path32.dirname(pidPath);
|
|
20127
20214
|
fs31.mkdirSync(dir, { recursive: true });
|
|
20128
20215
|
fs31.writeFileSync(pidPath, String(pid));
|
|
20129
20216
|
}
|
|
@@ -20172,8 +20259,8 @@ function startDaemon(pidPath, logDir2, instanceRoot) {
|
|
|
20172
20259
|
}
|
|
20173
20260
|
const resolvedLogDir = logDir2 ? expandHome2(logDir2) : getLogDir(instanceRoot);
|
|
20174
20261
|
fs31.mkdirSync(resolvedLogDir, { recursive: true });
|
|
20175
|
-
const logFile =
|
|
20176
|
-
const cliPath =
|
|
20262
|
+
const logFile = path32.join(resolvedLogDir, "openacp.log");
|
|
20263
|
+
const cliPath = path32.resolve(process.argv[1]);
|
|
20177
20264
|
const nodePath = process.execPath;
|
|
20178
20265
|
const out = fs31.openSync(logFile, "a");
|
|
20179
20266
|
const err = fs31.openSync(logFile, "a");
|
|
@@ -20257,7 +20344,7 @@ async function stopDaemon(pidPath, instanceRoot) {
|
|
|
20257
20344
|
}
|
|
20258
20345
|
function markRunning(root) {
|
|
20259
20346
|
const marker = getRunningMarker(root);
|
|
20260
|
-
fs31.mkdirSync(
|
|
20347
|
+
fs31.mkdirSync(path32.dirname(marker), { recursive: true });
|
|
20261
20348
|
fs31.writeFileSync(marker, "");
|
|
20262
20349
|
}
|
|
20263
20350
|
function clearRunning(root) {
|