@parall/daemon 1.32.0 → 1.32.1
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/bundle/manifest.json +9 -9
- package/bundle/parall-claude-agent.js +54 -36
- package/bundle/parall-codex-agent.js +54 -36
- package/bundle/parall-daemon.js +319 -251
- package/dist/clip-runtime/bun-resolver.d.ts +24 -0
- package/dist/clip-runtime/bun-resolver.d.ts.map +1 -0
- package/dist/clip-runtime/bun-resolver.js +58 -0
- package/dist/clip-runtime/clip-installer.d.ts.map +1 -1
- package/dist/clip-runtime/clip-installer.js +59 -18
- package/dist/clip-runtime/clip-provider.d.ts +3 -1
- package/dist/clip-runtime/clip-provider.d.ts.map +1 -1
- package/dist/clip-runtime/clip-provider.js +50 -22
- package/dist/clip-runtime/process-manager.d.ts.map +1 -1
- package/dist/clip-runtime/process-manager.js +8 -29
- package/package.json +6 -6
package/bundle/parall-daemon.js
CHANGED
|
@@ -17718,9 +17718,9 @@ var require_getMachineId_linux = __commonJS({
|
|
|
17718
17718
|
var api_1 = (init_esm(), __toCommonJS(esm_exports));
|
|
17719
17719
|
async function getMachineId() {
|
|
17720
17720
|
const paths = ["/etc/machine-id", "/var/lib/dbus/machine-id"];
|
|
17721
|
-
for (const
|
|
17721
|
+
for (const path12 of paths) {
|
|
17722
17722
|
try {
|
|
17723
|
-
const result = await fs_1.promises.readFile(
|
|
17723
|
+
const result = await fs_1.promises.readFile(path12, { encoding: "utf8" });
|
|
17724
17724
|
return result.trim();
|
|
17725
17725
|
} catch (e) {
|
|
17726
17726
|
api_1.diag.debug(`error reading machine id: ${e}`);
|
|
@@ -21123,7 +21123,7 @@ function appendRootPathToUrlIfNeeded(url) {
|
|
|
21123
21123
|
return void 0;
|
|
21124
21124
|
}
|
|
21125
21125
|
}
|
|
21126
|
-
function appendResourcePathToUrl(url,
|
|
21126
|
+
function appendResourcePathToUrl(url, path12) {
|
|
21127
21127
|
try {
|
|
21128
21128
|
new URL(url);
|
|
21129
21129
|
} catch (_a) {
|
|
@@ -21133,11 +21133,11 @@ function appendResourcePathToUrl(url, path11) {
|
|
|
21133
21133
|
if (!url.endsWith("/")) {
|
|
21134
21134
|
url = url + "/";
|
|
21135
21135
|
}
|
|
21136
|
-
url +=
|
|
21136
|
+
url += path12;
|
|
21137
21137
|
try {
|
|
21138
21138
|
new URL(url);
|
|
21139
21139
|
} catch (_b) {
|
|
21140
|
-
diag2.warn("Configuration: Provided URL appended with '" +
|
|
21140
|
+
diag2.warn("Configuration: Provided URL appended with '" + path12 + "' is not a valid URL, using 'undefined' instead of '" + url + "'");
|
|
21141
21141
|
return void 0;
|
|
21142
21142
|
}
|
|
21143
21143
|
return url;
|
|
@@ -26656,8 +26656,8 @@ var updater_exports = {};
|
|
|
26656
26656
|
__export(updater_exports, {
|
|
26657
26657
|
DaemonUpdater: () => DaemonUpdater
|
|
26658
26658
|
});
|
|
26659
|
-
import * as
|
|
26660
|
-
import * as
|
|
26659
|
+
import * as fs10 from "node:fs";
|
|
26660
|
+
import * as path10 from "node:path";
|
|
26661
26661
|
import * as https2 from "node:https";
|
|
26662
26662
|
import * as http3 from "node:http";
|
|
26663
26663
|
import { createHash as createHash3 } from "node:crypto";
|
|
@@ -26748,20 +26748,20 @@ MCowBQYDK2VwAyEAQHQAZThNX7+deJNyHl/5DgiAa1OHx7UQoJotam0JhUk=
|
|
|
26748
26748
|
return false;
|
|
26749
26749
|
if (!state.previous_version)
|
|
26750
26750
|
return false;
|
|
26751
|
-
const previousDir =
|
|
26752
|
-
if (!
|
|
26751
|
+
const previousDir = path10.join(this.bundleDir, "versions", state.previous_version);
|
|
26752
|
+
if (!fs10.existsSync(previousDir))
|
|
26753
26753
|
return false;
|
|
26754
26754
|
this.log.warn(`rollback: ${current.version} failed ${state.boot_count} boots, reverting to ${state.previous_version}`);
|
|
26755
26755
|
if (process.platform === "win32") {
|
|
26756
|
-
const currentDir =
|
|
26757
|
-
if (
|
|
26758
|
-
for (const file of
|
|
26759
|
-
|
|
26756
|
+
const currentDir = path10.join(this.bundleDir, "current");
|
|
26757
|
+
if (fs10.existsSync(currentDir)) {
|
|
26758
|
+
for (const file of fs10.readdirSync(currentDir)) {
|
|
26759
|
+
fs10.unlinkSync(path10.join(currentDir, file));
|
|
26760
26760
|
}
|
|
26761
26761
|
}
|
|
26762
|
-
|
|
26763
|
-
for (const file of
|
|
26764
|
-
|
|
26762
|
+
fs10.mkdirSync(currentDir, { recursive: true });
|
|
26763
|
+
for (const file of fs10.readdirSync(previousDir)) {
|
|
26764
|
+
fs10.copyFileSync(path10.join(previousDir, file), path10.join(currentDir, file));
|
|
26765
26765
|
}
|
|
26766
26766
|
} else {
|
|
26767
26767
|
this.swapSymlink(state.previous_version);
|
|
@@ -26869,11 +26869,11 @@ MCowBQYDK2VwAyEAQHQAZThNX7+deJNyHl/5DgiAa1OHx7UQoJotam0JhUk=
|
|
|
26869
26869
|
return false;
|
|
26870
26870
|
}
|
|
26871
26871
|
}
|
|
26872
|
-
const stagingDir =
|
|
26872
|
+
const stagingDir = path10.join(this.bundleDir, "staging");
|
|
26873
26873
|
this.cleanDir(stagingDir);
|
|
26874
|
-
|
|
26874
|
+
fs10.mkdirSync(stagingDir, { recursive: true });
|
|
26875
26875
|
for (const [filename, meta] of Object.entries(remote.files)) {
|
|
26876
|
-
const filePath =
|
|
26876
|
+
const filePath = path10.join(stagingDir, filename);
|
|
26877
26877
|
const fileUrl = `${this.cdnBaseUrl}/${remote.version}/${filename}`;
|
|
26878
26878
|
try {
|
|
26879
26879
|
await this.downloadFile(fileUrl, filePath);
|
|
@@ -26882,7 +26882,7 @@ MCowBQYDK2VwAyEAQHQAZThNX7+deJNyHl/5DgiAa1OHx7UQoJotam0JhUk=
|
|
|
26882
26882
|
this.cleanDir(stagingDir);
|
|
26883
26883
|
return false;
|
|
26884
26884
|
}
|
|
26885
|
-
const content =
|
|
26885
|
+
const content = fs10.readFileSync(filePath);
|
|
26886
26886
|
const hash = createHash3("sha256").update(content).digest("hex");
|
|
26887
26887
|
if (hash !== meta.sha256) {
|
|
26888
26888
|
this.log.error(`update: sha256 mismatch for ${filename} (expected ${meta.sha256}, got ${hash})`);
|
|
@@ -26895,7 +26895,7 @@ MCowBQYDK2VwAyEAQHQAZThNX7+deJNyHl/5DgiAa1OHx7UQoJotam0JhUk=
|
|
|
26895
26895
|
return false;
|
|
26896
26896
|
}
|
|
26897
26897
|
}
|
|
26898
|
-
|
|
26898
|
+
fs10.writeFileSync(path10.join(stagingDir, "manifest.json"), JSON.stringify(remote, null, 2));
|
|
26899
26899
|
this.atomicSwap(stagingDir, remote.version);
|
|
26900
26900
|
const newState = {
|
|
26901
26901
|
confirmed_version: local?.version ?? state?.confirmed_version,
|
|
@@ -26909,24 +26909,24 @@ MCowBQYDK2VwAyEAQHQAZThNX7+deJNyHl/5DgiAa1OHx7UQoJotam0JhUk=
|
|
|
26909
26909
|
return true;
|
|
26910
26910
|
}
|
|
26911
26911
|
atomicSwap(stagingDir, newVersion) {
|
|
26912
|
-
const versionsDir =
|
|
26913
|
-
const targetDir =
|
|
26914
|
-
const currentLink =
|
|
26915
|
-
|
|
26916
|
-
if (
|
|
26917
|
-
|
|
26918
|
-
}
|
|
26919
|
-
|
|
26912
|
+
const versionsDir = path10.join(this.bundleDir, "versions");
|
|
26913
|
+
const targetDir = path10.join(versionsDir, newVersion);
|
|
26914
|
+
const currentLink = path10.join(this.bundleDir, "current");
|
|
26915
|
+
fs10.mkdirSync(versionsDir, { recursive: true });
|
|
26916
|
+
if (fs10.existsSync(targetDir)) {
|
|
26917
|
+
fs10.rmSync(targetDir, { recursive: true });
|
|
26918
|
+
}
|
|
26919
|
+
fs10.renameSync(stagingDir, targetDir);
|
|
26920
26920
|
if (process.platform === "win32") {
|
|
26921
26921
|
const currentDir = currentLink;
|
|
26922
|
-
if (
|
|
26923
|
-
for (const file of
|
|
26924
|
-
|
|
26922
|
+
if (fs10.existsSync(currentDir)) {
|
|
26923
|
+
for (const file of fs10.readdirSync(currentDir)) {
|
|
26924
|
+
fs10.unlinkSync(path10.join(currentDir, file));
|
|
26925
26925
|
}
|
|
26926
26926
|
}
|
|
26927
|
-
|
|
26928
|
-
for (const file of
|
|
26929
|
-
|
|
26927
|
+
fs10.mkdirSync(currentDir, { recursive: true });
|
|
26928
|
+
for (const file of fs10.readdirSync(targetDir)) {
|
|
26929
|
+
fs10.copyFileSync(path10.join(targetDir, file), path10.join(currentDir, file));
|
|
26930
26930
|
}
|
|
26931
26931
|
} else {
|
|
26932
26932
|
this.swapSymlink(newVersion);
|
|
@@ -26934,14 +26934,14 @@ MCowBQYDK2VwAyEAQHQAZThNX7+deJNyHl/5DgiAa1OHx7UQoJotam0JhUk=
|
|
|
26934
26934
|
this.pruneOldVersions(versionsDir, newVersion);
|
|
26935
26935
|
}
|
|
26936
26936
|
swapSymlink(version) {
|
|
26937
|
-
const currentLink =
|
|
26937
|
+
const currentLink = path10.join(this.bundleDir, "current");
|
|
26938
26938
|
const tmpLink = `${currentLink}.new`;
|
|
26939
26939
|
try {
|
|
26940
|
-
|
|
26940
|
+
fs10.unlinkSync(tmpLink);
|
|
26941
26941
|
} catch {
|
|
26942
26942
|
}
|
|
26943
|
-
|
|
26944
|
-
|
|
26943
|
+
fs10.symlinkSync(`versions/${version}`, tmpLink);
|
|
26944
|
+
fs10.renameSync(tmpLink, currentLink);
|
|
26945
26945
|
}
|
|
26946
26946
|
pruneOldVersions(versionsDir, currentVersion) {
|
|
26947
26947
|
const state = this.loadUpdateState();
|
|
@@ -26951,9 +26951,9 @@ MCowBQYDK2VwAyEAQHQAZThNX7+deJNyHl/5DgiAa1OHx7UQoJotam0JhUk=
|
|
|
26951
26951
|
if (state?.confirmed_version)
|
|
26952
26952
|
keep.add(state.confirmed_version);
|
|
26953
26953
|
try {
|
|
26954
|
-
for (const entry of
|
|
26954
|
+
for (const entry of fs10.readdirSync(versionsDir)) {
|
|
26955
26955
|
if (!keep.has(entry)) {
|
|
26956
|
-
|
|
26956
|
+
fs10.rmSync(path10.join(versionsDir, entry), { recursive: true });
|
|
26957
26957
|
}
|
|
26958
26958
|
}
|
|
26959
26959
|
} catch {
|
|
@@ -26961,26 +26961,26 @@ MCowBQYDK2VwAyEAQHQAZThNX7+deJNyHl/5DgiAa1OHx7UQoJotam0JhUk=
|
|
|
26961
26961
|
}
|
|
26962
26962
|
// --- Manifest & State I/O ---
|
|
26963
26963
|
loadLocalManifest() {
|
|
26964
|
-
const currentDir =
|
|
26965
|
-
const manifestPath =
|
|
26964
|
+
const currentDir = path10.join(this.bundleDir, "current");
|
|
26965
|
+
const manifestPath = path10.join(currentDir, "manifest.json");
|
|
26966
26966
|
try {
|
|
26967
|
-
return JSON.parse(
|
|
26967
|
+
return JSON.parse(fs10.readFileSync(manifestPath, "utf-8"));
|
|
26968
26968
|
} catch {
|
|
26969
26969
|
return null;
|
|
26970
26970
|
}
|
|
26971
26971
|
}
|
|
26972
26972
|
loadUpdateState() {
|
|
26973
|
-
const statePath =
|
|
26973
|
+
const statePath = path10.join(this.bundleDir, "update-state.json");
|
|
26974
26974
|
try {
|
|
26975
|
-
return JSON.parse(
|
|
26975
|
+
return JSON.parse(fs10.readFileSync(statePath, "utf-8"));
|
|
26976
26976
|
} catch {
|
|
26977
26977
|
return null;
|
|
26978
26978
|
}
|
|
26979
26979
|
}
|
|
26980
26980
|
saveUpdateState(state) {
|
|
26981
|
-
const statePath =
|
|
26982
|
-
|
|
26983
|
-
|
|
26981
|
+
const statePath = path10.join(this.bundleDir, "update-state.json");
|
|
26982
|
+
fs10.mkdirSync(path10.dirname(statePath), { recursive: true });
|
|
26983
|
+
fs10.writeFileSync(statePath, JSON.stringify(state, null, 2));
|
|
26984
26984
|
}
|
|
26985
26985
|
// --- HTTP helpers ---
|
|
26986
26986
|
httpGet(url, maxRedirects = 5) {
|
|
@@ -27030,14 +27030,14 @@ MCowBQYDK2VwAyEAQHQAZThNX7+deJNyHl/5DgiAa1OHx7UQoJotam0JhUk=
|
|
|
27030
27030
|
reject(new Error(`HTTP ${res.statusCode} for ${url}`));
|
|
27031
27031
|
return;
|
|
27032
27032
|
}
|
|
27033
|
-
const file =
|
|
27033
|
+
const file = fs10.createWriteStream(dest);
|
|
27034
27034
|
res.pipe(file);
|
|
27035
27035
|
file.on("finish", () => {
|
|
27036
27036
|
file.close();
|
|
27037
27037
|
resolve5();
|
|
27038
27038
|
});
|
|
27039
27039
|
file.on("error", (err) => {
|
|
27040
|
-
|
|
27040
|
+
fs10.unlinkSync(dest);
|
|
27041
27041
|
reject(err);
|
|
27042
27042
|
});
|
|
27043
27043
|
});
|
|
@@ -27049,7 +27049,7 @@ MCowBQYDK2VwAyEAQHQAZThNX7+deJNyHl/5DgiAa1OHx7UQoJotam0JhUk=
|
|
|
27049
27049
|
}
|
|
27050
27050
|
cleanDir(dir) {
|
|
27051
27051
|
try {
|
|
27052
|
-
|
|
27052
|
+
fs10.rmSync(dir, { recursive: true });
|
|
27053
27053
|
} catch {
|
|
27054
27054
|
}
|
|
27055
27055
|
}
|
|
@@ -27506,10 +27506,10 @@ var ParallClient = class _ParallClient {
|
|
|
27506
27506
|
* REFRESH_THRESHOLD_S, refresh it **before** sending the request.
|
|
27507
27507
|
* No-op when the token is still fresh, missing, or un-parseable.
|
|
27508
27508
|
*/
|
|
27509
|
-
async ensureFreshToken(
|
|
27509
|
+
async ensureFreshToken(path12) {
|
|
27510
27510
|
if (!this.token || !this.getRefreshToken)
|
|
27511
27511
|
return;
|
|
27512
|
-
const pathSuffix =
|
|
27512
|
+
const pathSuffix = path12.replace(/^\/api\/v1/, "");
|
|
27513
27513
|
if (_ParallClient.AUTH_PATHS.has(pathSuffix))
|
|
27514
27514
|
return;
|
|
27515
27515
|
const exp = _ParallClient.decodeJwtExp(this.token);
|
|
@@ -27541,11 +27541,11 @@ var ParallClient = class _ParallClient {
|
|
|
27541
27541
|
this.refreshPromise = null;
|
|
27542
27542
|
}
|
|
27543
27543
|
}
|
|
27544
|
-
async request(method,
|
|
27544
|
+
async request(method, path12, body, query, retried = false, opts) {
|
|
27545
27545
|
if (!retried) {
|
|
27546
|
-
await this.ensureFreshToken(
|
|
27546
|
+
await this.ensureFreshToken(path12);
|
|
27547
27547
|
}
|
|
27548
|
-
let url = `${this.baseUrl}${
|
|
27548
|
+
let url = `${this.baseUrl}${path12}`;
|
|
27549
27549
|
if (query) {
|
|
27550
27550
|
const params = new URLSearchParams();
|
|
27551
27551
|
for (const [key, value] of Object.entries(query)) {
|
|
@@ -27570,12 +27570,12 @@ var ParallClient = class _ParallClient {
|
|
|
27570
27570
|
throw _ParallClient.normalizeFetchError(err);
|
|
27571
27571
|
}
|
|
27572
27572
|
if (res.status === 401) {
|
|
27573
|
-
const pathSuffix =
|
|
27573
|
+
const pathSuffix = path12.replace(/^\/api\/v1/, "");
|
|
27574
27574
|
const isAuthPath = _ParallClient.AUTH_PATHS.has(pathSuffix);
|
|
27575
27575
|
if (!retried && !isAuthPath && this.getRefreshToken) {
|
|
27576
27576
|
const refreshed = await this.tryRefresh();
|
|
27577
27577
|
if (refreshed) {
|
|
27578
|
-
return this.request(method,
|
|
27578
|
+
return this.request(method, path12, body, query, true, opts);
|
|
27579
27579
|
}
|
|
27580
27580
|
}
|
|
27581
27581
|
if (this.onTokenExpired && !isAuthPath) {
|
|
@@ -27584,15 +27584,7 @@ var ParallClient = class _ParallClient {
|
|
|
27584
27584
|
}
|
|
27585
27585
|
if (!res.ok) {
|
|
27586
27586
|
const rawErrorBody = await res.json().catch(() => ({}));
|
|
27587
|
-
|
|
27588
|
-
const errorObj = errorBody?.error && typeof errorBody.error === "object" ? errorBody.error : void 0;
|
|
27589
|
-
const errMsg = errorObj?.message ?? (typeof errorBody?.error === "string" ? errorBody.error : void 0);
|
|
27590
|
-
const errCode = errorObj?.code ?? (typeof errorBody?.code === "string" ? errorBody.code : void 0);
|
|
27591
|
-
const apiError = new ApiError(res.status, errMsg ?? res.statusText, errCode);
|
|
27592
|
-
const { error: _e, code: _c, message: _m, ...extras } = errorBody;
|
|
27593
|
-
if (Object.keys(extras).length > 0)
|
|
27594
|
-
apiError.extras = extras;
|
|
27595
|
-
throw apiError;
|
|
27587
|
+
throw buildApiError(res, rawErrorBody);
|
|
27596
27588
|
}
|
|
27597
27589
|
if (res.status === 204)
|
|
27598
27590
|
return void 0;
|
|
@@ -27612,15 +27604,15 @@ var ParallClient = class _ParallClient {
|
|
|
27612
27604
|
* hit the 100 MiB cap, so a longer 5-minute timeout is used so a
|
|
27613
27605
|
* 50 MiB blob on a slow connection doesn't get chopped at 15 s.
|
|
27614
27606
|
*/
|
|
27615
|
-
async multipartRequest(method,
|
|
27607
|
+
async multipartRequest(method, path12, body, retried = false) {
|
|
27616
27608
|
if (!retried) {
|
|
27617
|
-
await this.ensureFreshToken(
|
|
27609
|
+
await this.ensureFreshToken(path12);
|
|
27618
27610
|
}
|
|
27619
27611
|
const { "Content-Type": _drop, ...headers } = this.buildHeaders();
|
|
27620
27612
|
void _drop;
|
|
27621
27613
|
let res;
|
|
27622
27614
|
try {
|
|
27623
|
-
res = await fetch(`${this.baseUrl}${
|
|
27615
|
+
res = await fetch(`${this.baseUrl}${path12}`, {
|
|
27624
27616
|
method,
|
|
27625
27617
|
headers,
|
|
27626
27618
|
body,
|
|
@@ -27630,12 +27622,12 @@ var ParallClient = class _ParallClient {
|
|
|
27630
27622
|
throw _ParallClient.normalizeFetchError(err);
|
|
27631
27623
|
}
|
|
27632
27624
|
if (res.status === 401) {
|
|
27633
|
-
const pathSuffix =
|
|
27625
|
+
const pathSuffix = path12.replace(/^\/api\/v1/, "");
|
|
27634
27626
|
const isAuthPath = _ParallClient.AUTH_PATHS.has(pathSuffix);
|
|
27635
27627
|
if (!retried && !isAuthPath && this.getRefreshToken) {
|
|
27636
27628
|
const refreshed = await this.tryRefresh();
|
|
27637
27629
|
if (refreshed) {
|
|
27638
|
-
return this.multipartRequest(method,
|
|
27630
|
+
return this.multipartRequest(method, path12, body, true);
|
|
27639
27631
|
}
|
|
27640
27632
|
}
|
|
27641
27633
|
if (this.onTokenExpired && !isAuthPath) {
|
|
@@ -27644,15 +27636,7 @@ var ParallClient = class _ParallClient {
|
|
|
27644
27636
|
}
|
|
27645
27637
|
if (!res.ok) {
|
|
27646
27638
|
const rawErrorBody = await res.json().catch(() => ({}));
|
|
27647
|
-
|
|
27648
|
-
const errorObj = errorBody?.error && typeof errorBody.error === "object" ? errorBody.error : void 0;
|
|
27649
|
-
const errMsg = errorObj?.message ?? (typeof errorBody?.error === "string" ? errorBody.error : void 0);
|
|
27650
|
-
const errCode = errorObj?.code ?? (typeof errorBody?.code === "string" ? errorBody.code : void 0);
|
|
27651
|
-
const apiError = new ApiError(res.status, errMsg ?? res.statusText, errCode);
|
|
27652
|
-
const { error: _e, code: _c, message: _m, ...extras } = errorBody;
|
|
27653
|
-
if (Object.keys(extras).length > 0)
|
|
27654
|
-
apiError.extras = extras;
|
|
27655
|
-
throw apiError;
|
|
27639
|
+
throw buildApiError(res, rawErrorBody);
|
|
27656
27640
|
}
|
|
27657
27641
|
if (res.status === 204)
|
|
27658
27642
|
return void 0;
|
|
@@ -28233,8 +28217,8 @@ var ParallClient = class _ParallClient {
|
|
|
28233
28217
|
async requestMachineUpdate(orgId, machineId, mandatory = false) {
|
|
28234
28218
|
await this.request("POST", ENDPOINTS.MACHINE_REQUEST_UPDATE(orgId, machineId), { mandatory });
|
|
28235
28219
|
}
|
|
28236
|
-
async browseMachineFilesystem(orgId, machineId,
|
|
28237
|
-
return this.request("POST", ENDPOINTS.MACHINE_BROWSE(orgId, machineId), { path:
|
|
28220
|
+
async browseMachineFilesystem(orgId, machineId, path12) {
|
|
28221
|
+
return this.request("POST", ENDPOINTS.MACHINE_BROWSE(orgId, machineId), { path: path12 }, void 0, false, { timeoutMs: 15e3 });
|
|
28238
28222
|
}
|
|
28239
28223
|
/** Create a new machine key. Returns the raw key string (shown once) + metadata. */
|
|
28240
28224
|
async createMachineKey(orgId, machineId, name) {
|
|
@@ -28334,15 +28318,7 @@ var ParallClient = class _ParallClient {
|
|
|
28334
28318
|
return null;
|
|
28335
28319
|
if (!res.ok) {
|
|
28336
28320
|
const rawErrorBody = await res.json().catch(() => ({}));
|
|
28337
|
-
|
|
28338
|
-
const errorObj = errorBody?.error && typeof errorBody.error === "object" ? errorBody.error : void 0;
|
|
28339
|
-
const errMsg = errorObj?.message ?? (typeof errorBody?.error === "string" ? errorBody.error : void 0);
|
|
28340
|
-
const errCode = errorObj?.code ?? (typeof errorBody?.code === "string" ? errorBody.code : void 0);
|
|
28341
|
-
const apiError = new ApiError(res.status, errMsg ?? res.statusText, errCode);
|
|
28342
|
-
const { error: _e, code: _c, message: _m, ...extras } = errorBody;
|
|
28343
|
-
if (Object.keys(extras).length > 0)
|
|
28344
|
-
apiError.extras = extras;
|
|
28345
|
-
throw apiError;
|
|
28321
|
+
throw buildApiError(res, rawErrorBody);
|
|
28346
28322
|
}
|
|
28347
28323
|
return res.json();
|
|
28348
28324
|
}
|
|
@@ -28603,8 +28579,8 @@ var ParallClient = class _ParallClient {
|
|
|
28603
28579
|
async deleteWikiPathScope(orgId, wikiId, scopeId) {
|
|
28604
28580
|
await this.request("DELETE", ENDPOINTS.WIKI_PATH_SCOPE(orgId, wikiId, scopeId));
|
|
28605
28581
|
}
|
|
28606
|
-
async getWikiAccessStatus(orgId, wikiId,
|
|
28607
|
-
return this.request("GET", ENDPOINTS.WIKI_ACCESS_STATUS(orgId, wikiId), void 0,
|
|
28582
|
+
async getWikiAccessStatus(orgId, wikiId, path12) {
|
|
28583
|
+
return this.request("GET", ENDPOINTS.WIKI_ACCESS_STATUS(orgId, wikiId), void 0, path12 ? { path: path12 } : void 0);
|
|
28608
28584
|
}
|
|
28609
28585
|
async createWikiAccessRequest(orgId, wikiId, data) {
|
|
28610
28586
|
await this.request("POST", ENDPOINTS.WIKI_ACCESS_REQUESTS(orgId, wikiId), data);
|
|
@@ -28613,14 +28589,14 @@ var ParallClient = class _ParallClient {
|
|
|
28613
28589
|
async getWikiCommits(orgId, wikiId, params) {
|
|
28614
28590
|
return this.request("GET", ENDPOINTS.WIKI_COMMITS(orgId, wikiId), void 0, params);
|
|
28615
28591
|
}
|
|
28616
|
-
async getWikiFileCommits(orgId, wikiId,
|
|
28592
|
+
async getWikiFileCommits(orgId, wikiId, path12, params) {
|
|
28617
28593
|
return this.request("GET", ENDPOINTS.WIKI_FILE_COMMITS(orgId, wikiId), void 0, {
|
|
28618
|
-
path:
|
|
28594
|
+
path: path12,
|
|
28619
28595
|
...params
|
|
28620
28596
|
});
|
|
28621
28597
|
}
|
|
28622
|
-
async getWikiBlame(orgId, wikiId,
|
|
28623
|
-
return this.request("GET", ENDPOINTS.WIKI_BLAME(orgId, wikiId), void 0, { path:
|
|
28598
|
+
async getWikiBlame(orgId, wikiId, path12, ref) {
|
|
28599
|
+
return this.request("GET", ENDPOINTS.WIKI_BLAME(orgId, wikiId), void 0, { path: path12, ref });
|
|
28624
28600
|
}
|
|
28625
28601
|
// ---- Wiki Operations (audit log) ----
|
|
28626
28602
|
async getWikiOperations(orgId, wikiId, params) {
|
|
@@ -28808,6 +28784,12 @@ var ApiError = class extends Error {
|
|
|
28808
28784
|
status;
|
|
28809
28785
|
code;
|
|
28810
28786
|
extras;
|
|
28787
|
+
/** Attempted action (authorization denials) — e.g. "chat.add_member". */
|
|
28788
|
+
action;
|
|
28789
|
+
/** Target resource URI that was evaluated — e.g. "prll://cht_…". */
|
|
28790
|
+
resourceUri;
|
|
28791
|
+
/** Whether the action is approval-executable (PERMISSION_DENIED only). */
|
|
28792
|
+
approvable;
|
|
28811
28793
|
constructor(status, message, code) {
|
|
28812
28794
|
super(message);
|
|
28813
28795
|
this.status = status;
|
|
@@ -28815,6 +28797,33 @@ var ApiError = class extends Error {
|
|
|
28815
28797
|
this.name = "ApiError";
|
|
28816
28798
|
}
|
|
28817
28799
|
};
|
|
28800
|
+
function buildApiError(res, rawErrorBody) {
|
|
28801
|
+
const errorBody = rawErrorBody !== null && typeof rawErrorBody === "object" ? rawErrorBody : {};
|
|
28802
|
+
const errorObj = errorBody.error && typeof errorBody.error === "object" ? errorBody.error : void 0;
|
|
28803
|
+
const errMsg = (typeof errorObj?.message === "string" ? errorObj.message : void 0) ?? (typeof errorBody.message === "string" ? errorBody.message : void 0) ?? (typeof errorBody.error === "string" ? errorBody.error : void 0);
|
|
28804
|
+
const errCode = (typeof errorObj?.code === "string" ? errorObj.code : void 0) ?? (typeof errorBody.code === "string" ? errorBody.code : void 0);
|
|
28805
|
+
const apiError = new ApiError(res.status, errMsg ?? res.statusText, errCode);
|
|
28806
|
+
const anchors = errorObj ?? errorBody;
|
|
28807
|
+
if (typeof anchors.action === "string")
|
|
28808
|
+
apiError.action = anchors.action;
|
|
28809
|
+
if (typeof anchors.resource_uri === "string")
|
|
28810
|
+
apiError.resourceUri = anchors.resource_uri;
|
|
28811
|
+
if (typeof anchors.approvable === "boolean")
|
|
28812
|
+
apiError.approvable = anchors.approvable;
|
|
28813
|
+
const structural = /* @__PURE__ */ new Set(["error", "code", "message", "status"]);
|
|
28814
|
+
const extras = {};
|
|
28815
|
+
for (const [k, v] of Object.entries(errorBody))
|
|
28816
|
+
if (!structural.has(k))
|
|
28817
|
+
extras[k] = v;
|
|
28818
|
+
if (errorObj) {
|
|
28819
|
+
for (const [k, v] of Object.entries(errorObj))
|
|
28820
|
+
if (!structural.has(k))
|
|
28821
|
+
extras[k] = v;
|
|
28822
|
+
}
|
|
28823
|
+
if (Object.keys(extras).length > 0)
|
|
28824
|
+
apiError.extras = extras;
|
|
28825
|
+
return apiError;
|
|
28826
|
+
}
|
|
28818
28827
|
|
|
28819
28828
|
// ts/sdk/dist/ws.js
|
|
28820
28829
|
function isRetryableNetworkError(err) {
|
|
@@ -29283,8 +29292,8 @@ init_config();
|
|
|
29283
29292
|
|
|
29284
29293
|
// ts/daemon/dist/supervisor.js
|
|
29285
29294
|
import { spawn as spawn3 } from "node:child_process";
|
|
29286
|
-
import * as
|
|
29287
|
-
import * as
|
|
29295
|
+
import * as fs9 from "node:fs";
|
|
29296
|
+
import * as path9 from "node:path";
|
|
29288
29297
|
|
|
29289
29298
|
// ts/daemon/dist/filesystem.js
|
|
29290
29299
|
import * as fs2 from "fs";
|
|
@@ -29913,9 +29922,8 @@ function isNodeError(err) {
|
|
|
29913
29922
|
}
|
|
29914
29923
|
|
|
29915
29924
|
// ts/daemon/dist/clip-runtime/process-manager.js
|
|
29916
|
-
import * as
|
|
29917
|
-
import * as
|
|
29918
|
-
import { execFileSync } from "node:child_process";
|
|
29925
|
+
import * as fs7 from "node:fs";
|
|
29926
|
+
import * as path7 from "node:path";
|
|
29919
29927
|
|
|
29920
29928
|
// ts/daemon/dist/clip-runtime/process.js
|
|
29921
29929
|
import { spawn as spawn2 } from "node:child_process";
|
|
@@ -30487,6 +30495,39 @@ var ClipProcess = class {
|
|
|
30487
30495
|
}
|
|
30488
30496
|
};
|
|
30489
30497
|
|
|
30498
|
+
// ts/daemon/dist/clip-runtime/bun-resolver.js
|
|
30499
|
+
import * as fs6 from "node:fs";
|
|
30500
|
+
import * as path6 from "node:path";
|
|
30501
|
+
import { execFileSync } from "node:child_process";
|
|
30502
|
+
function findBunBinary() {
|
|
30503
|
+
const isWindows = process.platform === "win32";
|
|
30504
|
+
const binName = isWindows ? "bun.exe" : "bun";
|
|
30505
|
+
const embedded = path6.join(path6.dirname(process.execPath), binName);
|
|
30506
|
+
if (fs6.existsSync(embedded))
|
|
30507
|
+
return embedded;
|
|
30508
|
+
if (!isWindows) {
|
|
30509
|
+
const candidates = [
|
|
30510
|
+
path6.join(process.env.HOME || "", ".bun", "bin", "bun"),
|
|
30511
|
+
"/usr/local/bin/bun",
|
|
30512
|
+
"/opt/homebrew/bin/bun"
|
|
30513
|
+
];
|
|
30514
|
+
for (const candidate of candidates) {
|
|
30515
|
+
if (fs6.existsSync(candidate))
|
|
30516
|
+
return candidate;
|
|
30517
|
+
}
|
|
30518
|
+
}
|
|
30519
|
+
const lookupCmd = isWindows ? "where.exe" : "which";
|
|
30520
|
+
const lookupArg = isWindows ? "bun.exe" : "bun";
|
|
30521
|
+
try {
|
|
30522
|
+
const result = execFileSync(lookupCmd, [lookupArg], { encoding: "utf-8" }).trim();
|
|
30523
|
+
const firstLine = result.split("\n")[0]?.trim();
|
|
30524
|
+
if (firstLine)
|
|
30525
|
+
return firstLine;
|
|
30526
|
+
} catch {
|
|
30527
|
+
}
|
|
30528
|
+
throw new Error("bun binary not found \u2014 install Bun (https://bun.sh) or set bunPath option");
|
|
30529
|
+
}
|
|
30530
|
+
|
|
30490
30531
|
// ts/daemon/dist/clip-runtime/process-manager.js
|
|
30491
30532
|
var ClipProcessManager = class {
|
|
30492
30533
|
bunPath;
|
|
@@ -30664,10 +30705,10 @@ var ClipProcessManager = class {
|
|
|
30664
30705
|
* Reads clip-config.json if present, or scans subdirectories for clip.json files.
|
|
30665
30706
|
*/
|
|
30666
30707
|
async loadInstalledClips() {
|
|
30667
|
-
const configFile =
|
|
30668
|
-
if (
|
|
30708
|
+
const configFile = path7.join(path7.dirname(this.clipsDir), "clip-config.json");
|
|
30709
|
+
if (fs7.existsSync(configFile)) {
|
|
30669
30710
|
try {
|
|
30670
|
-
const content =
|
|
30711
|
+
const content = fs7.readFileSync(configFile, "utf-8");
|
|
30671
30712
|
const configs = JSON.parse(content);
|
|
30672
30713
|
for (const config of configs) {
|
|
30673
30714
|
this.registerClip(config);
|
|
@@ -30677,18 +30718,18 @@ var ClipProcessManager = class {
|
|
|
30677
30718
|
console.warn("[clip-manager] failed to parse clip-config.json, scanning directory");
|
|
30678
30719
|
}
|
|
30679
30720
|
}
|
|
30680
|
-
if (!
|
|
30721
|
+
if (!fs7.existsSync(this.clipsDir))
|
|
30681
30722
|
return;
|
|
30682
|
-
const entries =
|
|
30723
|
+
const entries = fs7.readdirSync(this.clipsDir, { withFileTypes: true });
|
|
30683
30724
|
for (const entry of entries) {
|
|
30684
30725
|
if (!entry.isDirectory())
|
|
30685
30726
|
continue;
|
|
30686
|
-
const clipDir =
|
|
30687
|
-
const clipJsonPath =
|
|
30688
|
-
const pkgJsonPath =
|
|
30689
|
-
if (
|
|
30727
|
+
const clipDir = path7.join(this.clipsDir, entry.name);
|
|
30728
|
+
const clipJsonPath = path7.join(clipDir, "clip.json");
|
|
30729
|
+
const pkgJsonPath = path7.join(clipDir, "package.json");
|
|
30730
|
+
if (fs7.existsSync(clipJsonPath)) {
|
|
30690
30731
|
try {
|
|
30691
|
-
const clipJson = JSON.parse(
|
|
30732
|
+
const clipJson = JSON.parse(fs7.readFileSync(clipJsonPath, "utf-8"));
|
|
30692
30733
|
this.registerClip({
|
|
30693
30734
|
name: clipJson.name || entry.name,
|
|
30694
30735
|
package: clipJson.name,
|
|
@@ -30699,9 +30740,9 @@ var ClipProcessManager = class {
|
|
|
30699
30740
|
} catch {
|
|
30700
30741
|
console.warn(`[clip-manager] failed to parse clip.json in ${clipDir}`);
|
|
30701
30742
|
}
|
|
30702
|
-
} else if (
|
|
30743
|
+
} else if (fs7.existsSync(pkgJsonPath)) {
|
|
30703
30744
|
try {
|
|
30704
|
-
const pkgJson = JSON.parse(
|
|
30745
|
+
const pkgJson = JSON.parse(fs7.readFileSync(pkgJsonPath, "utf-8"));
|
|
30705
30746
|
this.registerClip({
|
|
30706
30747
|
name: pkgJson.name || entry.name,
|
|
30707
30748
|
package: pkgJson.name,
|
|
@@ -30740,8 +30781,14 @@ var ClipProcessManager = class {
|
|
|
30740
30781
|
async spawnProcess(config) {
|
|
30741
30782
|
const proc = new ClipProcess(config);
|
|
30742
30783
|
const clipDataDir = this.ensureClipDataDir(config);
|
|
30743
|
-
|
|
30744
|
-
|
|
30784
|
+
const bunPath = this.resolveBun();
|
|
30785
|
+
proc.spawn(bunPath, {
|
|
30786
|
+
PINIX_DATA_DIR: clipDataDir,
|
|
30787
|
+
// Expose the embedded bun's directory on the clip's PATH so a clip that
|
|
30788
|
+
// shells out to `bun` by name resolves it — the daemon's launchd PATH
|
|
30789
|
+
// does not include Frameworks/. Symmetric with installDeps(); relies on
|
|
30790
|
+
// the embedded binary being named `bun` (Frameworks/bun).
|
|
30791
|
+
PATH: `${path7.dirname(bunPath)}${path7.delimiter}${process.env.PATH ?? ""}`
|
|
30745
30792
|
});
|
|
30746
30793
|
this.setStatus(config.name, "running", "starting");
|
|
30747
30794
|
try {
|
|
@@ -30770,8 +30817,8 @@ var ClipProcessManager = class {
|
|
|
30770
30817
|
return proc;
|
|
30771
30818
|
}
|
|
30772
30819
|
ensureClipDataDir(config) {
|
|
30773
|
-
const dir =
|
|
30774
|
-
|
|
30820
|
+
const dir = path7.join(this.dataDir, config.name);
|
|
30821
|
+
fs7.mkdirSync(dir, { recursive: true });
|
|
30775
30822
|
return dir;
|
|
30776
30823
|
}
|
|
30777
30824
|
removeIfSame(name, proc) {
|
|
@@ -30789,30 +30836,6 @@ var ClipProcessManager = class {
|
|
|
30789
30836
|
}
|
|
30790
30837
|
}
|
|
30791
30838
|
};
|
|
30792
|
-
function findBunBinary() {
|
|
30793
|
-
const isWindows = process.platform === "win32";
|
|
30794
|
-
if (!isWindows) {
|
|
30795
|
-
const candidates = [
|
|
30796
|
-
path6.join(process.env.HOME || "", ".bun", "bin", "bun"),
|
|
30797
|
-
"/usr/local/bin/bun",
|
|
30798
|
-
"/opt/homebrew/bin/bun"
|
|
30799
|
-
];
|
|
30800
|
-
for (const candidate of candidates) {
|
|
30801
|
-
if (fs6.existsSync(candidate))
|
|
30802
|
-
return candidate;
|
|
30803
|
-
}
|
|
30804
|
-
}
|
|
30805
|
-
const lookupCmd = isWindows ? "where.exe" : "which";
|
|
30806
|
-
const lookupArg = isWindows ? "bun.exe" : "bun";
|
|
30807
|
-
try {
|
|
30808
|
-
const result = execFileSync(lookupCmd, [lookupArg], { encoding: "utf-8" }).trim();
|
|
30809
|
-
const firstLine = result.split("\n")[0]?.trim();
|
|
30810
|
-
if (firstLine)
|
|
30811
|
-
return firstLine;
|
|
30812
|
-
} catch {
|
|
30813
|
-
}
|
|
30814
|
-
throw new Error("bun binary not found \u2014 install Bun (https://bun.sh) or set bunPath option");
|
|
30815
|
-
}
|
|
30816
30839
|
|
|
30817
30840
|
// ts/daemon/dist/clip-runtime/clip-provider.js
|
|
30818
30841
|
import * as http2 from "node:http2";
|
|
@@ -30995,7 +31018,7 @@ var ClipProvider = class _ClipProvider {
|
|
|
30995
31018
|
void this.openStream();
|
|
30996
31019
|
return;
|
|
30997
31020
|
}
|
|
30998
|
-
this.sendProviderMessage({
|
|
31021
|
+
this.sendProviderMessage({ ping: { sentAtUnixMs: Date.now() } }).catch((err) => {
|
|
30999
31022
|
this.opts.log.warn(`[clip-provider] heartbeat send failed: ${String(err)}`);
|
|
31000
31023
|
});
|
|
31001
31024
|
}, _ClipProvider.HEARTBEAT_INTERVAL_MS);
|
|
@@ -31024,12 +31047,12 @@ var ClipProvider = class _ClipProvider {
|
|
|
31024
31047
|
// ---------------------------------------------------------------------------
|
|
31025
31048
|
subscribeStatusChanges() {
|
|
31026
31049
|
const mgr = this.opts.clipManager;
|
|
31027
|
-
this.statusUnsubscribe = mgr.addStatusListener((name, status,
|
|
31050
|
+
this.statusUnsubscribe = mgr.addStatusListener((name, status, message) => {
|
|
31028
31051
|
if (!this.connected)
|
|
31029
31052
|
return;
|
|
31030
|
-
const protoStatus = status === "running" ? "
|
|
31053
|
+
const protoStatus = status === "running" ? "CLIP_STATUS_RUNNING" : status === "error" ? "CLIP_STATUS_ERROR" : "CLIP_STATUS_SLEEPING";
|
|
31031
31054
|
this.sendProviderMessage({
|
|
31032
|
-
clipStatusChanged: {
|
|
31055
|
+
clipStatusChanged: { name, status: protoStatus, message }
|
|
31033
31056
|
}).catch((err) => {
|
|
31034
31057
|
this.opts.log.warn(`[clip-provider] status change send failed: ${String(err)}`);
|
|
31035
31058
|
});
|
|
@@ -31048,18 +31071,16 @@ var ClipProvider = class _ClipProvider {
|
|
|
31048
31071
|
// Message handling
|
|
31049
31072
|
// ---------------------------------------------------------------------------
|
|
31050
31073
|
handleHubMessage(msg) {
|
|
31051
|
-
if (msg.
|
|
31052
|
-
this.handleRegistered(msg.
|
|
31074
|
+
if (msg.registerResponse) {
|
|
31075
|
+
this.handleRegistered(msg.registerResponse);
|
|
31053
31076
|
} else if (msg.invokeCommand) {
|
|
31054
31077
|
void this.handleInvokeCommand(msg.invokeCommand);
|
|
31055
|
-
} else if (msg.
|
|
31056
|
-
this.sendProviderMessage({ heartbeat: {} }).catch(() => {
|
|
31057
|
-
});
|
|
31078
|
+
} else if (msg.pong !== void 0) {
|
|
31058
31079
|
}
|
|
31059
31080
|
}
|
|
31060
31081
|
handleRegistered(reg) {
|
|
31061
31082
|
if (reg.accepted) {
|
|
31062
|
-
this.opts.log.info(`[clip-provider] registered with hub (org=${
|
|
31083
|
+
this.opts.log.info(`[clip-provider] registered with hub (org=${this.opts.orgId})`);
|
|
31063
31084
|
this.connected = true;
|
|
31064
31085
|
this.reconnectAttempt = 0;
|
|
31065
31086
|
this.startHeartbeat();
|
|
@@ -31071,7 +31092,7 @@ var ClipProvider = class _ClipProvider {
|
|
|
31071
31092
|
}
|
|
31072
31093
|
}
|
|
31073
31094
|
async handleInvokeCommand(cmd) {
|
|
31074
|
-
const { requestId,
|
|
31095
|
+
const { requestId, clipName, command } = cmd;
|
|
31075
31096
|
const timeoutMs = cmd.timeoutMs ?? 3e4;
|
|
31076
31097
|
try {
|
|
31077
31098
|
let input;
|
|
@@ -31085,7 +31106,7 @@ var ClipProvider = class _ClipProvider {
|
|
|
31085
31106
|
}
|
|
31086
31107
|
let timer;
|
|
31087
31108
|
const output = await Promise.race([
|
|
31088
|
-
this.opts.clipManager.invoke(
|
|
31109
|
+
this.opts.clipManager.invoke(clipName, command, input),
|
|
31089
31110
|
new Promise((_, reject) => {
|
|
31090
31111
|
timer = setTimeout(() => reject(new Error("invoke timeout")), timeoutMs);
|
|
31091
31112
|
})
|
|
@@ -31102,7 +31123,10 @@ var ClipProvider = class _ClipProvider {
|
|
|
31102
31123
|
await this.sendProviderMessage({
|
|
31103
31124
|
invokeResult: {
|
|
31104
31125
|
requestId,
|
|
31105
|
-
error:
|
|
31126
|
+
error: {
|
|
31127
|
+
code: isCommandError ? "CLIP_COMMAND_ERROR" : "INVOKE_FAILED",
|
|
31128
|
+
message: isCommandError ? err.message : String(err)
|
|
31129
|
+
},
|
|
31106
31130
|
errorIsCommand: isCommandError,
|
|
31107
31131
|
done: true
|
|
31108
31132
|
}
|
|
@@ -31118,8 +31142,7 @@ var ClipProvider = class _ClipProvider {
|
|
|
31118
31142
|
await this.sendProviderMessage({
|
|
31119
31143
|
register: {
|
|
31120
31144
|
providerName: this.opts.providerName,
|
|
31121
|
-
clips
|
|
31122
|
-
orgId: this.opts.orgId
|
|
31145
|
+
clips
|
|
31123
31146
|
}
|
|
31124
31147
|
});
|
|
31125
31148
|
}
|
|
@@ -31147,26 +31170,50 @@ var ClipProvider = class _ClipProvider {
|
|
|
31147
31170
|
clipConfigToRegistration(clip) {
|
|
31148
31171
|
const manifest = clip.manifest;
|
|
31149
31172
|
const commands = manifest ? manifest.commandDetails.map((cmd) => this.commandDetailToInfo(cmd)) : [];
|
|
31173
|
+
const pkg = manifest?.package ?? clip.package ?? clip.name;
|
|
31150
31174
|
return {
|
|
31151
31175
|
alias: clip.name,
|
|
31152
|
-
|
|
31176
|
+
package: pkg,
|
|
31153
31177
|
version: manifest?.version ?? clip.version ?? "",
|
|
31154
|
-
|
|
31178
|
+
domain: manifest?.domain,
|
|
31179
|
+
commands,
|
|
31180
|
+
hasWeb: manifest?.hasWeb ?? false,
|
|
31181
|
+
dependencies: this.dependencyNames(manifest?.dependencies),
|
|
31182
|
+
tokenProtected: Boolean(clip.token),
|
|
31183
|
+
name: pkg,
|
|
31184
|
+
patterns: manifest?.patterns,
|
|
31185
|
+
entities: this.stringEntities(manifest?.entities),
|
|
31186
|
+
description: manifest?.description
|
|
31155
31187
|
};
|
|
31156
31188
|
}
|
|
31157
31189
|
commandDetailToInfo(detail) {
|
|
31158
31190
|
return {
|
|
31159
31191
|
name: detail.name,
|
|
31160
31192
|
description: detail.description ?? "",
|
|
31161
|
-
|
|
31162
|
-
|
|
31193
|
+
input: detail.input,
|
|
31194
|
+
output: detail.output
|
|
31163
31195
|
};
|
|
31164
31196
|
}
|
|
31197
|
+
dependencyNames(deps) {
|
|
31198
|
+
if (!deps)
|
|
31199
|
+
return void 0;
|
|
31200
|
+
const names = Object.entries(deps).map(([slot, dep]) => dep.package ?? slot).filter((name) => name.length > 0);
|
|
31201
|
+
return names.length > 0 ? names : void 0;
|
|
31202
|
+
}
|
|
31203
|
+
stringEntities(entities) {
|
|
31204
|
+
if (!entities)
|
|
31205
|
+
return void 0;
|
|
31206
|
+
const out = {};
|
|
31207
|
+
for (const [key, value] of Object.entries(entities)) {
|
|
31208
|
+
out[key] = typeof value === "string" ? value : JSON.stringify(value);
|
|
31209
|
+
}
|
|
31210
|
+
return out;
|
|
31211
|
+
}
|
|
31165
31212
|
};
|
|
31166
31213
|
|
|
31167
31214
|
// ts/daemon/dist/clip-runtime/clip-installer.js
|
|
31168
|
-
import * as
|
|
31169
|
-
import * as
|
|
31215
|
+
import * as fs8 from "node:fs";
|
|
31216
|
+
import * as path8 from "node:path";
|
|
31170
31217
|
import * as crypto from "node:crypto";
|
|
31171
31218
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
31172
31219
|
import { pipeline } from "node:stream/promises";
|
|
@@ -31245,7 +31292,7 @@ async function httpDownload(url, destPath, maxRedirects = 10) {
|
|
|
31245
31292
|
reject(new Error(`download failed: HTTP ${res.statusCode} for ${url}`));
|
|
31246
31293
|
return;
|
|
31247
31294
|
}
|
|
31248
|
-
const ws =
|
|
31295
|
+
const ws = fs8.createWriteStream(destPath);
|
|
31249
31296
|
pipeline(res, ws).then(resolve5, reject);
|
|
31250
31297
|
});
|
|
31251
31298
|
req.on("error", reject);
|
|
@@ -31377,11 +31424,11 @@ function verifyChecksum(filePath, algo, expectedHex) {
|
|
|
31377
31424
|
return;
|
|
31378
31425
|
}
|
|
31379
31426
|
const hash = crypto.createHash(algo);
|
|
31380
|
-
const content =
|
|
31427
|
+
const content = fs8.readFileSync(filePath);
|
|
31381
31428
|
hash.update(content);
|
|
31382
31429
|
const actual = hash.digest("hex");
|
|
31383
31430
|
if (actual !== expectedHex) {
|
|
31384
|
-
throw new Error(`checksum mismatch for ${
|
|
31431
|
+
throw new Error(`checksum mismatch for ${path8.basename(filePath)}: expected ${algo}:${expectedHex}, got ${algo}:${actual}`);
|
|
31385
31432
|
}
|
|
31386
31433
|
}
|
|
31387
31434
|
function validateTarEntries(tarballPath) {
|
|
@@ -31398,18 +31445,18 @@ function validateTarEntries(tarballPath) {
|
|
|
31398
31445
|
const trimmed = entry.trim();
|
|
31399
31446
|
if (!trimmed)
|
|
31400
31447
|
continue;
|
|
31401
|
-
if (
|
|
31448
|
+
if (path8.isAbsolute(trimmed)) {
|
|
31402
31449
|
throw new Error(`tarball contains absolute path: "${trimmed}"`);
|
|
31403
31450
|
}
|
|
31404
|
-
const normalized =
|
|
31405
|
-
if (normalized.startsWith("..") || normalized.includes(`${
|
|
31451
|
+
const normalized = path8.normalize(trimmed);
|
|
31452
|
+
if (normalized.startsWith("..") || normalized.includes(`${path8.sep}..${path8.sep}`)) {
|
|
31406
31453
|
throw new Error(`tarball contains path traversal: "${trimmed}"`);
|
|
31407
31454
|
}
|
|
31408
31455
|
}
|
|
31409
31456
|
}
|
|
31410
31457
|
function extractTarball(tarballPath, destDir) {
|
|
31411
31458
|
const stripComponents = detectStripComponents(tarballPath);
|
|
31412
|
-
|
|
31459
|
+
fs8.mkdirSync(destDir, { recursive: true });
|
|
31413
31460
|
try {
|
|
31414
31461
|
execFileSync2("tar", [
|
|
31415
31462
|
"xzf",
|
|
@@ -31450,74 +31497,95 @@ function detectStripComponents(tarballPath) {
|
|
|
31450
31497
|
return commonPrefix ? 1 : 0;
|
|
31451
31498
|
}
|
|
31452
31499
|
function installDeps(clipDir) {
|
|
31453
|
-
const pkgJsonPath =
|
|
31454
|
-
if (!
|
|
31500
|
+
const pkgJsonPath = path8.join(clipDir, "package.json");
|
|
31501
|
+
if (!fs8.existsSync(pkgJsonPath))
|
|
31455
31502
|
return;
|
|
31456
31503
|
let hasDeps = false;
|
|
31457
31504
|
try {
|
|
31458
|
-
const pkg = JSON.parse(
|
|
31505
|
+
const pkg = JSON.parse(fs8.readFileSync(pkgJsonPath, "utf-8"));
|
|
31459
31506
|
hasDeps = !!(pkg.dependencies && Object.keys(pkg.dependencies).length > 0);
|
|
31460
31507
|
} catch {
|
|
31461
31508
|
}
|
|
31462
|
-
const
|
|
31463
|
-
|
|
31464
|
-
|
|
31465
|
-
|
|
31466
|
-
|
|
31467
|
-
|
|
31468
|
-
|
|
31469
|
-
|
|
31470
|
-
|
|
31471
|
-
|
|
31472
|
-
|
|
31473
|
-
|
|
31474
|
-
|
|
31475
|
-
|
|
31509
|
+
const failures = [];
|
|
31510
|
+
let bunPath = null;
|
|
31511
|
+
try {
|
|
31512
|
+
bunPath = findBunBinary();
|
|
31513
|
+
} catch (err) {
|
|
31514
|
+
failures.push(`resolve bun: ${err instanceof Error ? err.message : String(err)}`);
|
|
31515
|
+
}
|
|
31516
|
+
if (bunPath) {
|
|
31517
|
+
const bunEnv = {
|
|
31518
|
+
...process.env,
|
|
31519
|
+
PATH: `${path8.dirname(bunPath)}${path8.delimiter}${process.env.PATH ?? ""}`
|
|
31520
|
+
};
|
|
31521
|
+
for (const args of [["install", "--frozen-lockfile"], ["install"]]) {
|
|
31522
|
+
try {
|
|
31523
|
+
execFileSync2(bunPath, args, {
|
|
31524
|
+
cwd: clipDir,
|
|
31525
|
+
stdio: "pipe",
|
|
31526
|
+
timeout: 12e4,
|
|
31527
|
+
env: bunEnv
|
|
31528
|
+
});
|
|
31529
|
+
return;
|
|
31530
|
+
} catch (err) {
|
|
31531
|
+
failures.push(`bun ${args.join(" ")}: ${err instanceof Error ? err.message : String(err)}`);
|
|
31532
|
+
}
|
|
31476
31533
|
}
|
|
31477
31534
|
}
|
|
31535
|
+
try {
|
|
31536
|
+
execFileSync2("npm", ["install", "--production"], {
|
|
31537
|
+
cwd: clipDir,
|
|
31538
|
+
stdio: "pipe",
|
|
31539
|
+
timeout: 12e4
|
|
31540
|
+
});
|
|
31541
|
+
return;
|
|
31542
|
+
} catch (err) {
|
|
31543
|
+
failures.push(`npm install: ${err instanceof Error ? err.message : String(err)}`);
|
|
31544
|
+
}
|
|
31478
31545
|
if (hasDeps) {
|
|
31479
|
-
throw new Error(`failed to install dependencies in ${clipDir} \u2014 clip declares dependencies but no package manager succeeded
|
|
31546
|
+
throw new Error(`failed to install dependencies in ${clipDir} \u2014 clip declares dependencies but no package manager succeeded:
|
|
31547
|
+
${failures.join("\n ")}`);
|
|
31480
31548
|
}
|
|
31481
|
-
console.warn(`[clip-installer] could not run package manager in ${clipDir} (no dependencies declared, continuing)`);
|
|
31549
|
+
console.warn(`[clip-installer] could not run a package manager in ${clipDir} (no dependencies declared, continuing): ${failures.join("; ")}`);
|
|
31482
31550
|
}
|
|
31483
31551
|
async function installClip(opts) {
|
|
31484
31552
|
const registryUrl = (opts.registryUrl ?? DEFAULT_REGISTRY_URL).replace(/\/+$/, "");
|
|
31485
31553
|
const parsed = parseSource(opts.source);
|
|
31486
31554
|
const alias = opts.alias ?? deriveAlias(parsed);
|
|
31487
|
-
const destDir =
|
|
31555
|
+
const destDir = path8.join(opts.clipsDir, alias);
|
|
31488
31556
|
const versionMeta = await resolveVersionMeta(registryUrl, parsed);
|
|
31489
|
-
const tmpDir =
|
|
31490
|
-
|
|
31491
|
-
const tarballPath =
|
|
31492
|
-
const stageDir =
|
|
31557
|
+
const tmpDir = path8.join(opts.clipsDir, `.tmp-${alias}-${Date.now()}`);
|
|
31558
|
+
fs8.mkdirSync(tmpDir, { recursive: true });
|
|
31559
|
+
const tarballPath = path8.join(tmpDir, `${alias}-${versionMeta.version}.tgz`);
|
|
31560
|
+
const stageDir = path8.join(tmpDir, "stage");
|
|
31493
31561
|
try {
|
|
31494
31562
|
await httpDownload(versionMeta.tarball, tarballPath);
|
|
31495
31563
|
verifyChecksum(tarballPath, versionMeta.checksumAlgo, versionMeta.checksumHex);
|
|
31496
31564
|
validateTarEntries(tarballPath);
|
|
31497
31565
|
extractTarball(tarballPath, stageDir);
|
|
31498
31566
|
installDeps(stageDir);
|
|
31499
|
-
const backupDir =
|
|
31567
|
+
const backupDir = path8.join(opts.clipsDir, `.backup-${alias}-${Date.now()}`);
|
|
31500
31568
|
let backedUp = false;
|
|
31501
31569
|
try {
|
|
31502
|
-
if (
|
|
31503
|
-
|
|
31570
|
+
if (fs8.existsSync(destDir)) {
|
|
31571
|
+
fs8.renameSync(destDir, backupDir);
|
|
31504
31572
|
backedUp = true;
|
|
31505
31573
|
}
|
|
31506
|
-
|
|
31574
|
+
fs8.renameSync(stageDir, destDir);
|
|
31507
31575
|
if (backedUp) {
|
|
31508
|
-
|
|
31576
|
+
fs8.rmSync(backupDir, { recursive: true, force: true });
|
|
31509
31577
|
}
|
|
31510
31578
|
} catch (swapErr) {
|
|
31511
|
-
if (backedUp && !
|
|
31579
|
+
if (backedUp && !fs8.existsSync(destDir)) {
|
|
31512
31580
|
try {
|
|
31513
|
-
|
|
31581
|
+
fs8.renameSync(backupDir, destDir);
|
|
31514
31582
|
} catch {
|
|
31515
31583
|
}
|
|
31516
31584
|
}
|
|
31517
31585
|
throw swapErr;
|
|
31518
31586
|
}
|
|
31519
31587
|
} finally {
|
|
31520
|
-
|
|
31588
|
+
fs8.rmSync(tmpDir, { recursive: true, force: true });
|
|
31521
31589
|
}
|
|
31522
31590
|
return {
|
|
31523
31591
|
alias,
|
|
@@ -31599,8 +31667,8 @@ var DaemonSupervisor = class {
|
|
|
31599
31667
|
this.migrateFlatLayout();
|
|
31600
31668
|
if (process.env.PRLL_CLIP_RUNTIME_ENABLED === "true") {
|
|
31601
31669
|
this.clipManager = new ClipProcessManager({
|
|
31602
|
-
clipsDir:
|
|
31603
|
-
dataDir:
|
|
31670
|
+
clipsDir: path9.join(this.config.rootStateDir, "clips"),
|
|
31671
|
+
dataDir: path9.join(this.config.rootStateDir, "clip-data")
|
|
31604
31672
|
});
|
|
31605
31673
|
try {
|
|
31606
31674
|
await this.clipManager.loadInstalledClips();
|
|
@@ -31827,15 +31895,15 @@ var DaemonSupervisor = class {
|
|
|
31827
31895
|
*/
|
|
31828
31896
|
migrateFlatLayout() {
|
|
31829
31897
|
const root = this.config.rootStateDir;
|
|
31830
|
-
const agentsDir =
|
|
31831
|
-
const flatWorkspace =
|
|
31832
|
-
if (!
|
|
31898
|
+
const agentsDir = path9.join(root, "agents");
|
|
31899
|
+
const flatWorkspace = path9.join(root, "workspace");
|
|
31900
|
+
if (!fs9.existsSync(flatWorkspace) || fs9.existsSync(agentsDir))
|
|
31833
31901
|
return;
|
|
31834
31902
|
let ownerAgentId;
|
|
31835
|
-
const sessionsDir =
|
|
31836
|
-
if (
|
|
31903
|
+
const sessionsDir = path9.join(root, "sessions");
|
|
31904
|
+
if (fs9.existsSync(sessionsDir)) {
|
|
31837
31905
|
try {
|
|
31838
|
-
for (const file of
|
|
31906
|
+
for (const file of fs9.readdirSync(sessionsDir)) {
|
|
31839
31907
|
if (!file.endsWith(".json"))
|
|
31840
31908
|
continue;
|
|
31841
31909
|
const decoded = Buffer.from(file.replace(".json", ""), "base64url").toString();
|
|
@@ -31849,13 +31917,13 @@ var DaemonSupervisor = class {
|
|
|
31849
31917
|
}
|
|
31850
31918
|
}
|
|
31851
31919
|
const targetId = ownerAgentId ?? "_orphan";
|
|
31852
|
-
const targetDir =
|
|
31920
|
+
const targetDir = path9.join(agentsDir, targetId);
|
|
31853
31921
|
try {
|
|
31854
|
-
|
|
31922
|
+
fs9.mkdirSync(targetDir, { recursive: true });
|
|
31855
31923
|
for (const sub of ["workspace", "sessions", "dispatch-context"]) {
|
|
31856
|
-
const src =
|
|
31857
|
-
if (
|
|
31858
|
-
|
|
31924
|
+
const src = path9.join(root, sub);
|
|
31925
|
+
if (fs9.existsSync(src)) {
|
|
31926
|
+
fs9.renameSync(src, path9.join(targetDir, sub));
|
|
31859
31927
|
}
|
|
31860
31928
|
}
|
|
31861
31929
|
this.log.info(`migrated legacy flat state \u2192 agents/${targetId}/`);
|
|
@@ -31950,7 +32018,7 @@ var DaemonSupervisor = class {
|
|
|
31950
32018
|
});
|
|
31951
32019
|
return true;
|
|
31952
32020
|
}
|
|
31953
|
-
const clipsDir =
|
|
32021
|
+
const clipsDir = path9.join(this.config.rootStateDir, "clips");
|
|
31954
32022
|
let source = data.source_ref;
|
|
31955
32023
|
if (data.version) {
|
|
31956
32024
|
let sourceHasVersion = false;
|
|
@@ -32136,9 +32204,9 @@ var DaemonSupervisor = class {
|
|
|
32136
32204
|
const isK8s = !!process.env.KUBERNETES_SERVICE_HOST;
|
|
32137
32205
|
const claudeHome = isK8s ? agentClaudeHomeFor(this.config.rootClaudeHome, agentId) : this.config.rootClaudeHome;
|
|
32138
32206
|
try {
|
|
32139
|
-
|
|
32207
|
+
fs9.mkdirSync(stateDir, { recursive: true });
|
|
32140
32208
|
if (isK8s) {
|
|
32141
|
-
|
|
32209
|
+
fs9.mkdirSync(claudeHome, { recursive: true });
|
|
32142
32210
|
this.ensureSharedCredentialLink(claudeHome, agentId);
|
|
32143
32211
|
}
|
|
32144
32212
|
} catch (err) {
|
|
@@ -32276,31 +32344,31 @@ var DaemonSupervisor = class {
|
|
|
32276
32344
|
});
|
|
32277
32345
|
}
|
|
32278
32346
|
ensureSharedCredentialLink(agentClaudeHome, agentId) {
|
|
32279
|
-
const sharedCredentials =
|
|
32347
|
+
const sharedCredentials = path9.resolve(sharedClaudeCredentialsFileFor(this.config.rootClaudeHome));
|
|
32280
32348
|
const agentCredentials = agentClaudeCredentialsFileFor(agentClaudeHome);
|
|
32281
|
-
const agentCredentialsDir =
|
|
32282
|
-
|
|
32283
|
-
|
|
32349
|
+
const agentCredentialsDir = path9.dirname(agentCredentials);
|
|
32350
|
+
fs9.mkdirSync(path9.dirname(sharedCredentials), { recursive: true });
|
|
32351
|
+
fs9.mkdirSync(agentCredentialsDir, { recursive: true });
|
|
32284
32352
|
try {
|
|
32285
|
-
const existing =
|
|
32353
|
+
const existing = fs9.lstatSync(agentCredentials);
|
|
32286
32354
|
if (existing.isSymbolicLink()) {
|
|
32287
|
-
const currentTarget =
|
|
32288
|
-
if (
|
|
32355
|
+
const currentTarget = fs9.readlinkSync(agentCredentials);
|
|
32356
|
+
if (path9.resolve(agentCredentialsDir, currentTarget) === sharedCredentials) {
|
|
32289
32357
|
return;
|
|
32290
32358
|
}
|
|
32291
|
-
|
|
32359
|
+
fs9.unlinkSync(agentCredentials);
|
|
32292
32360
|
} else if (existing.isDirectory()) {
|
|
32293
32361
|
this.log.warn(`agent ${agentId}: credential path is a directory, cannot link ${agentCredentials}`);
|
|
32294
32362
|
return;
|
|
32295
32363
|
} else {
|
|
32296
|
-
|
|
32364
|
+
fs9.unlinkSync(agentCredentials);
|
|
32297
32365
|
}
|
|
32298
32366
|
} catch (err) {
|
|
32299
32367
|
if (err.code !== "ENOENT") {
|
|
32300
32368
|
throw err;
|
|
32301
32369
|
}
|
|
32302
32370
|
}
|
|
32303
|
-
|
|
32371
|
+
fs9.symlinkSync(sharedCredentials, agentCredentials);
|
|
32304
32372
|
}
|
|
32305
32373
|
};
|
|
32306
32374
|
|
|
@@ -32309,8 +32377,8 @@ init_updater();
|
|
|
32309
32377
|
|
|
32310
32378
|
// ts/daemon/dist/cli.js
|
|
32311
32379
|
init_config();
|
|
32312
|
-
import * as
|
|
32313
|
-
import * as
|
|
32380
|
+
import * as fs11 from "node:fs";
|
|
32381
|
+
import * as path11 from "node:path";
|
|
32314
32382
|
import * as os3 from "node:os";
|
|
32315
32383
|
import * as readline from "node:readline";
|
|
32316
32384
|
import { spawn as spawn4, execSync } from "node:child_process";
|
|
@@ -32318,15 +32386,15 @@ var CONFIG_DIR = daemonConfigDir();
|
|
|
32318
32386
|
var CONFIG_PATH = daemonConfigPath();
|
|
32319
32387
|
function readConfig() {
|
|
32320
32388
|
try {
|
|
32321
|
-
return JSON.parse(
|
|
32389
|
+
return JSON.parse(fs11.readFileSync(CONFIG_PATH, "utf-8"));
|
|
32322
32390
|
} catch {
|
|
32323
32391
|
return null;
|
|
32324
32392
|
}
|
|
32325
32393
|
}
|
|
32326
32394
|
function writeConfig(config) {
|
|
32327
|
-
|
|
32328
|
-
|
|
32329
|
-
|
|
32395
|
+
fs11.mkdirSync(CONFIG_DIR, { recursive: true, mode: 448 });
|
|
32396
|
+
fs11.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2), { mode: 384 });
|
|
32397
|
+
fs11.chmodSync(CONFIG_PATH, 384);
|
|
32330
32398
|
}
|
|
32331
32399
|
function prompt(question) {
|
|
32332
32400
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
@@ -32345,10 +32413,10 @@ function isLinux() {
|
|
|
32345
32413
|
}
|
|
32346
32414
|
var PLIST_LABEL = "com.parall.daemon";
|
|
32347
32415
|
function plistPath() {
|
|
32348
|
-
return
|
|
32416
|
+
return path11.join(os3.homedir(), "Library", "LaunchAgents", `${PLIST_LABEL}.plist`);
|
|
32349
32417
|
}
|
|
32350
32418
|
function systemdUnitPath() {
|
|
32351
|
-
return
|
|
32419
|
+
return path11.join(os3.homedir(), ".config", "systemd", "user", "parall-daemon.service");
|
|
32352
32420
|
}
|
|
32353
32421
|
function getDaemonBin() {
|
|
32354
32422
|
try {
|
|
@@ -32358,7 +32426,7 @@ function getDaemonBin() {
|
|
|
32358
32426
|
}
|
|
32359
32427
|
}
|
|
32360
32428
|
function generatePlist(daemonBin) {
|
|
32361
|
-
const logPath =
|
|
32429
|
+
const logPath = path11.join(os3.homedir(), "Library", "Logs", "parall-daemon.log");
|
|
32362
32430
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
32363
32431
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
32364
32432
|
<plist version="1.0">
|
|
@@ -32407,16 +32475,16 @@ function installService() {
|
|
|
32407
32475
|
}
|
|
32408
32476
|
const bin = getDaemonBin();
|
|
32409
32477
|
if (isMacOS()) {
|
|
32410
|
-
const dir =
|
|
32411
|
-
|
|
32412
|
-
|
|
32478
|
+
const dir = path11.dirname(plistPath());
|
|
32479
|
+
fs11.mkdirSync(dir, { recursive: true });
|
|
32480
|
+
fs11.writeFileSync(plistPath(), generatePlist(bin));
|
|
32413
32481
|
execSync(`launchctl bootout gui/$(id -u) ${plistPath()} 2>/dev/null || true`);
|
|
32414
32482
|
execSync(`launchctl bootstrap gui/$(id -u) ${plistPath()}`);
|
|
32415
32483
|
console.log(`launchd agent installed: ${plistPath()}`);
|
|
32416
32484
|
} else if (isLinux()) {
|
|
32417
|
-
const dir =
|
|
32418
|
-
|
|
32419
|
-
|
|
32485
|
+
const dir = path11.dirname(systemdUnitPath());
|
|
32486
|
+
fs11.mkdirSync(dir, { recursive: true });
|
|
32487
|
+
fs11.writeFileSync(systemdUnitPath(), generateSystemdUnit(bin));
|
|
32420
32488
|
execSync("systemctl --user daemon-reload");
|
|
32421
32489
|
execSync("systemctl --user enable --now parall-daemon");
|
|
32422
32490
|
console.log(`systemd service installed: ${systemdUnitPath()}`);
|
|
@@ -32483,8 +32551,8 @@ function cmdLogs(lines) {
|
|
|
32483
32551
|
child2.on("exit", (code) => process.exit(code ?? 0));
|
|
32484
32552
|
return;
|
|
32485
32553
|
}
|
|
32486
|
-
const logPath =
|
|
32487
|
-
if (!
|
|
32554
|
+
const logPath = path11.join(os3.homedir(), "Library", "Logs", "parall-daemon.log");
|
|
32555
|
+
if (!fs11.existsSync(logPath)) {
|
|
32488
32556
|
console.log("No log file found at", logPath);
|
|
32489
32557
|
return;
|
|
32490
32558
|
}
|
|
@@ -32494,14 +32562,14 @@ function cmdLogs(lines) {
|
|
|
32494
32562
|
function cmdServiceUninstall() {
|
|
32495
32563
|
if (isMacOS()) {
|
|
32496
32564
|
execSync(`launchctl bootout gui/$(id -u) ${plistPath()} 2>/dev/null || true`);
|
|
32497
|
-
if (
|
|
32498
|
-
|
|
32565
|
+
if (fs11.existsSync(plistPath()))
|
|
32566
|
+
fs11.unlinkSync(plistPath());
|
|
32499
32567
|
console.log("launchd agent uninstalled.");
|
|
32500
32568
|
} else if (isLinux()) {
|
|
32501
32569
|
execSync("systemctl --user stop parall-daemon 2>/dev/null || true");
|
|
32502
32570
|
execSync("systemctl --user disable parall-daemon 2>/dev/null || true");
|
|
32503
|
-
if (
|
|
32504
|
-
|
|
32571
|
+
if (fs11.existsSync(systemdUnitPath()))
|
|
32572
|
+
fs11.unlinkSync(systemdUnitPath());
|
|
32505
32573
|
execSync("systemctl --user daemon-reload");
|
|
32506
32574
|
console.log("systemd service uninstalled.");
|
|
32507
32575
|
} else {
|