@opentig/cli 0.2.3 → 0.2.4
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/LICENSE +1 -1
- package/README.md +14 -14
- package/dist/bin.mjs +25 -10
- package/dist/chunks/{cli-L6lvCZdX.mjs → cli-gyjD1t0O.mjs} +611 -268
- package/dist/chunks/network-settings-CdFeKFRB.mjs +142 -0
- package/dist/chunks/{server-Cz0gvydn.mjs → server-DMk8-Xxt.mjs} +557 -105
- package/dist/chunks/{service-manager-Jyx-MWo-.mjs → service-manager-BxSmV_8Z.mjs} +88 -14
- package/dist/client/assets/App-Bfw_TX8q.js +132 -0
- package/dist/client/assets/CreatePullRequestDialog-DyPd6SKH.js +2 -0
- package/dist/client/assets/DiffWorkspace-DCo89dF1.js +7 -0
- package/dist/client/assets/EditableFileViewer-Dotntfij.js +1 -0
- package/dist/client/assets/EditableFileViewer-svutjHZv.css +1 -0
- package/dist/client/assets/ExternalLink-jdtpN_yL.js +1 -0
- package/dist/client/assets/{File-BPxtFxHC.js → File-DHnVtIhS.js} +1 -1
- package/dist/client/assets/FilesView-D6f1hPVy.js +1 -0
- package/dist/client/assets/GitHubAvatar-B6vyoVlh.js +1 -0
- package/dist/client/assets/HistoryView-D9RhzCPY.js +1 -0
- package/dist/client/assets/HtmlFileViewer-Bwmj5umg.js +2 -0
- package/dist/client/assets/{IconAlertTriangle-C1OX2bTH.js → IconAlertTriangle-B9iDJKvP.js} +1 -1
- package/dist/client/assets/IconCheck-C-G-IA13.js +1 -0
- package/dist/client/assets/IconChevronDown-DU5i40lD.js +1 -0
- package/dist/client/assets/{IconEdit-BP5Emwzw.js → IconEdit-CZe-EJxX.js} +1 -1
- package/dist/client/assets/{IconFolderSymlink-BNWI0eXB.js → IconFolderSymlink-DkLEuUb6.js} +1 -1
- package/dist/client/assets/IconGitMerge-D9KEj1cE.js +1 -0
- package/dist/client/assets/IconGitPullRequest-ClaUqyVa.js +1 -0
- package/dist/client/assets/{IconLoader4-Bk6G4Bls.js → IconLoader4-D2VN7u1V.js} +1 -1
- package/dist/client/assets/{IconPlus-DUFNSK_i.js → IconPlus-DJCoD3wt.js} +1 -1
- package/dist/client/assets/{IconSearch-ZL3YVslZ.js → IconSearch-1VQ4P4kW.js} +1 -1
- package/dist/client/assets/{IconSelector-BGwY84R8.js → IconSelector-BVMU1PEt.js} +1 -1
- package/dist/client/assets/ImageFileViewer-3izbFVTw.css +1 -0
- package/dist/client/assets/ImageFileViewer-CdFLl_in.js +1 -0
- package/dist/client/assets/LinkedMarkdown-Bnc2OA63.js +1 -0
- package/dist/client/assets/LinkedText-BD6K3d1t.js +1 -0
- package/dist/client/assets/LocalRefsDialog-Bl-fddap.js +1 -0
- package/dist/client/assets/MarkdownFileViewer-NUAoQmv5.js +2 -0
- package/dist/client/assets/PairingPage-CqrxpC3_.js +1 -0
- package/dist/client/assets/PierreDiffViewer-CDfQ32e0.js +1 -0
- package/dist/client/assets/{PierreEditBoundary-Bt0q7SXc.js → PierreEditBoundary-DAdYNYZ3.js} +1 -1
- package/dist/client/assets/{PierreWorkerPool-DMFigp0u.js → PierreWorkerPool-mIDzTMB9.js} +3 -3
- package/dist/client/assets/PullRequestDiff-n1NZFHKN.js +1 -0
- package/dist/client/assets/PullRequestViewer-u89zl169.js +2 -0
- package/dist/client/assets/PullRequestsView-D6BqvB4E.js +1 -0
- package/dist/client/assets/QuickOpenDialog-BbEifGRi.js +1 -0
- package/dist/client/assets/RepositoryProjectsDialog-EGAsXL-Z.js +1 -0
- package/dist/client/assets/{SearchView-BYz1K1Ta.js → SearchView-BMz7qOdc.js} +1 -1
- package/dist/client/assets/SettingsDialog-DmD7HvhX.js +9 -0
- package/dist/client/assets/Viewer-CDj_vo6w.js +3 -0
- package/dist/client/assets/{abnfDiagram-YUKMZFIV-CpKAN_8n.js → abnfDiagram-YUKMZFIV-It6tW-4v.js} +1 -1
- package/dist/client/assets/{architecture-WOLXFQ4H-DrizVopY.js → architecture-WOLXFQ4H-CaOaChND.js} +1 -1
- package/dist/client/assets/{architectureDiagram-47P4ROYG-gvUijB3H.js → architectureDiagram-47P4ROYG-COtncecA.js} +1 -1
- package/dist/client/assets/{blockDiagram-E7TT5TSB-CdcXmnf_.js → blockDiagram-E7TT5TSB-NU4wFrfP.js} +1 -1
- package/dist/client/assets/{c4Diagram-CRA5TL53-DtoD1jKt.js → c4Diagram-CRA5TL53-0xzM4S8q.js} +1 -1
- package/dist/client/assets/channel-QED-4ACa.js +1 -0
- package/dist/client/assets/checkbox-Dh4T0bCe.js +1 -0
- package/dist/client/assets/{chunk-2BW5OAIV-Bxqf2dFQ.js → chunk-2BW5OAIV-BQMxlSNI.js} +1 -1
- package/dist/client/assets/{chunk-3YJQHVM4-BhzXJiq0.js → chunk-3YJQHVM4-CdP15KtA.js} +1 -1
- package/dist/client/assets/{chunk-4EA7E6EY-CvEILf8c.js → chunk-4EA7E6EY-xRPCCZLU.js} +1 -1
- package/dist/client/assets/{chunk-7TKQ45FW-pTEdzVz3.js → chunk-7TKQ45FW-Cr_UAObV.js} +1 -1
- package/dist/client/assets/{chunk-AW2ZBBNX-LVROkcXk.js → chunk-AW2ZBBNX-DBqqxF2h.js} +1 -1
- package/dist/client/assets/{chunk-DBDB3WZW-FCGrB-q8.js → chunk-DBDB3WZW-BonEIRP2.js} +1 -1
- package/dist/client/assets/{chunk-E2ZNV5FY-B3rGXPn-.js → chunk-E2ZNV5FY-DnKvxSiA.js} +1 -1
- package/dist/client/assets/{chunk-EU5HNXII-D6a_Ly_W.js → chunk-EU5HNXII-DLK0K3sR.js} +1 -1
- package/dist/client/assets/{chunk-FVRAUYC3-B5hy0Ket.js → chunk-FVRAUYC3-DmjKoYAh.js} +1 -1
- package/dist/client/assets/{chunk-HJ2JQQFS-CKHFz1Wl.js → chunk-HJ2JQQFS-AF4phse0.js} +1 -1
- package/dist/client/assets/{chunk-HTAEGDNF-CtwDuO27.js → chunk-HTAEGDNF-CG4pBnUZ.js} +1 -1
- package/dist/client/assets/{chunk-KQW6MTUR-BN3uxLYf.js → chunk-KQW6MTUR-Dd87yj5r.js} +1 -1
- package/dist/client/assets/{chunk-NTY3LDVX-CfXSvyIC.js → chunk-NTY3LDVX-OolU2PaP.js} +1 -1
- package/dist/client/assets/{chunk-VPRB5NB3-LAggcSji.js → chunk-VPRB5NB3-Dnr3edxV.js} +3 -3
- package/dist/client/assets/{chunk-XC4XBNZT-BksIPWQU.js → chunk-XC4XBNZT-CIqGRxkD.js} +1 -1
- package/dist/client/assets/{classDiagram-v2-K4WV4PDN-DH78Maqm.js → classDiagram-v2-K4WV4PDN-CPGawm8n.js} +1 -1
- package/dist/client/assets/createReactComponent-Ctub7J3a.js +1 -0
- package/dist/client/assets/{cynefin-EF2NZ3EQ-DozKlDV1.js → cynefin-EF2NZ3EQ-OA2R9WCH.js} +1 -1
- package/dist/client/assets/{cynefinDiagram-3GCD6N5R-A1yS7NKN.js → cynefinDiagram-3GCD6N5R-DqCVtoKt.js} +1 -1
- package/dist/client/assets/{dagre-W4DXFKR2-DRJ1mmbe.js → dagre-W4DXFKR2-kc3-tkAQ.js} +1 -1
- package/dist/client/assets/{diagram-2UJZ2QOL-B1sI2b2o.js → diagram-2UJZ2QOL-DoBZKT3s.js} +1 -1
- package/dist/client/assets/{diagram-OVF4WLC6-DLE1o4-P.js → diagram-OVF4WLC6-DGkyha_F.js} +1 -1
- package/dist/client/assets/{diagram-PFPMY2P6-UtIEsv14.js → diagram-PFPMY2P6-DpRDDgdV.js} +1 -1
- package/dist/client/assets/{diagram-UMYRVEAY-BwTyzVap.js → diagram-UMYRVEAY-DlsfhYv3.js} +1 -1
- package/dist/client/assets/{diagram-YEKJPTXX-DNPUQqu0.js → diagram-YEKJPTXX-BIhRZzBM.js} +1 -1
- package/dist/client/assets/{diagram-ZIFT7M5P-ClXykQ3I.js → diagram-ZIFT7M5P-mweJcgBZ.js} +1 -1
- package/dist/client/assets/diff-parse.worker-C1IFRYY9.js +13 -0
- package/dist/client/assets/{ebnfDiagram-VR2GEFS7-Dm8VAviu.js → ebnfDiagram-VR2GEFS7-Dn5zyIbZ.js} +1 -1
- package/dist/client/assets/{elk-IJKZMXRS-CEEoPARn.js → elk-IJKZMXRS-eBPlf1-o.js} +1 -1
- package/dist/client/assets/{erDiagram-O2IAPWRE-CaDE4obX.js → erDiagram-O2IAPWRE-WEE519yZ.js} +1 -1
- package/dist/client/assets/{eventmodeling-K75KTNOO-PjYgMkPC.js → eventmodeling-K75KTNOO-BgE_VmNy.js} +1 -1
- package/dist/client/assets/external-url-IUS7RmYD.js +1 -0
- package/dist/client/assets/flowDiagram-OXPTDLAJ-CHQYfkMg.js +1 -0
- package/dist/client/assets/{ganttDiagram-R7TSEDQI-CmkBarBi.js → ganttDiagram-R7TSEDQI-D_1KyJZU.js} +1 -1
- package/dist/client/assets/{gitGraph-VSP46ZUC-DeotTdHj.js → gitGraph-VSP46ZUC-CEbT7DA4.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-XJZIOB7I-uV1hPaZT.js → gitGraphDiagram-XJZIOB7I-QQyYc1gM.js} +1 -1
- package/dist/client/assets/index-DsKvWsTs.js +47 -0
- package/dist/client/assets/index-kyWCnbkb.css +2 -0
- package/dist/client/assets/{info-OHQRW6UA-BQDsGvSl.js → info-OHQRW6UA-ChHAnveo.js} +1 -1
- package/dist/client/assets/{infoDiagram-5W2HQ5XZ-CDfEPsgZ.js → infoDiagram-5W2HQ5XZ-BaxAE7UA.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-K3B6WC7H-Bb7PQGe6.js → ishikawaDiagram-K3B6WC7H-vhUflBE_.js} +1 -1
- package/dist/client/assets/{journeyDiagram-COXZFDF6-BDythglw.js → journeyDiagram-COXZFDF6-C8WWosVa.js} +1 -1
- package/dist/client/assets/{kanban-definition-P3RFRI5V-CvY5kXhh.js → kanban-definition-P3RFRI5V-CU6W9Yi3.js} +1 -1
- package/dist/client/assets/katex-CQfTPFh0.js +1 -0
- package/dist/client/assets/{line-99p2yFnB.js → line-Axq4vVX-.js} +1 -1
- package/dist/client/assets/{mermaid-parser.core-BjZYtoJ8.js → mermaid-parser.core-DNeaCX12.js} +3 -3
- package/dist/client/assets/{mermaid.core-DRcXnUox.js → mermaid.core-Dtt7rXw0.js} +4 -4
- package/dist/client/assets/{mindmap-definition-LZFPQGKD-t9LoCpnW.js → mindmap-definition-LZFPQGKD-D_8ZqQot.js} +1 -1
- package/dist/client/assets/{packet-JDAUHWVQ-BlR-5V7K.js → packet-JDAUHWVQ-6z7ujmGF.js} +1 -1
- package/dist/client/assets/{pegDiagram-BGZESJAR-CWeGI-T9.js → pegDiagram-BGZESJAR-3ujyk-bt.js} +1 -1
- package/dist/client/assets/{pie-XZMESJXO-BkvYHWgl.js → pie-XZMESJXO-DvpLy2DB.js} +1 -1
- package/dist/client/assets/{pieDiagram-CAPJLFHJ-CY5PPIr3.js → pieDiagram-CAPJLFHJ-BPMPWyc7.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-GDMTTRAM-kqj-z271.js → quadrantDiagram-GDMTTRAM-BVUCR_lf.js} +1 -1
- package/dist/client/assets/{radar-ABXABTNO-DuEtYatv.js → radar-ABXABTNO-lu14X99R.js} +1 -1
- package/dist/client/assets/{railroad-I3PHUGI6-CVlnj2j9.js → railroad-I3PHUGI6-DI_WtDmt.js} +1 -1
- package/dist/client/assets/{railroad-abnf-LNEFI6M7-9Qiczw4d.js → railroad-abnf-LNEFI6M7-CmWAKZ2T.js} +1 -1
- package/dist/client/assets/{railroad-ebnf-DWYD2UWJ-BNL7TMEg.js → railroad-ebnf-DWYD2UWJ-BWKFU_UH.js} +1 -1
- package/dist/client/assets/{railroad-peg-JR7BVNR7-DdpRxgk6.js → railroad-peg-JR7BVNR7-9wkgzxMB.js} +1 -1
- package/dist/client/assets/{railroadDiagram-SM67HX2B-CDXvYNqW.js → railroadDiagram-SM67HX2B-4JnRbxl_.js} +1 -1
- package/dist/client/assets/{render-markdown-DF9Fy7MD.js → render-markdown-CQi2yKYQ.js} +2 -2
- package/dist/client/assets/{requirementDiagram-X7JNWC4A-BDdhqnZA.js → requirementDiagram-X7JNWC4A-CVJiZZsi.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-UM26HJRW-Rkyk5oEf.js → sankeyDiagram-UM26HJRW-BmlWQdkv.js} +1 -1
- package/dist/client/assets/select-Dq3KDX2O.js +1 -0
- package/dist/client/assets/{sequenceDiagram-ZO4K6R2Y-Coj9ap7h.js → sequenceDiagram-ZO4K6R2Y-zUx3LmPj.js} +1 -1
- package/dist/client/assets/{stateDiagram-v2-TBUQTH76-BucWlahR.js → stateDiagram-v2-TBUQTH76-o_ci-2bu.js} +1 -1
- package/dist/client/assets/{swimlanes-N4OXWK64-tEECcFP9.js → swimlanes-N4OXWK64-BlI0GC5-.js} +1 -1
- package/dist/client/assets/swimlanesDiagram-K3J5GTZL-BEeJLN8d.js +8 -0
- package/dist/client/assets/tanstack-CVAt_k_T.js +1 -0
- package/dist/client/assets/{timeline-definition-YOQAKGHF-XvIbGO4d.js → timeline-definition-YOQAKGHF-DLnvF__o.js} +1 -1
- package/dist/client/assets/{treeView-D4JQ5SDB-DuhJpfXe.js → treeView-D4JQ5SDB-DPuMLQhB.js} +1 -1
- package/dist/client/assets/{treemap-SAJKECNS-CLiUWfZh.js → treemap-SAJKECNS-DjxqxJ8-.js} +1 -1
- package/dist/client/assets/{usecaseDiagram-VIAY4XPW-BuwkpV9w.js → usecaseDiagram-VIAY4XPW-BtnFNltN.js} +1 -1
- package/dist/client/assets/utils-D0T3A-kS.js +1 -0
- package/dist/client/assets/{vennDiagram-BLWOH2XV-kfza5Rxq.js → vennDiagram-BLWOH2XV-CAiF2FKz.js} +1 -1
- package/dist/client/assets/viewer-tabs-DkkqN9MD.js +1 -0
- package/dist/client/assets/{wardley-7MLQ67FV-CcbU_Ykg.js → wardley-7MLQ67FV-DAWySamq.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YMQ3BMBF-DnxlEg3a.js → wardleyDiagram-YMQ3BMBF-DiBCclEL.js} +1 -1
- package/dist/client/assets/{xychartDiagram-TAQBALBS-BzgtwtvK.js → xychartDiagram-TAQBALBS-B0NgfXz6.js} +1 -1
- package/dist/client/index.html +6 -4
- package/dist/dev.mjs +6 -6
- package/dist/manifest.json +1 -1
- package/dist/server.mjs +1 -1
- package/dist/service-update.mjs +11 -3
- package/dist/utility.mjs +25 -4
- package/package.json +4 -4
- package/dist/client/assets/App-DEIZhWJG.js +0 -132
- package/dist/client/assets/CreatePullRequestDialog-BceOUbYK.js +0 -2
- package/dist/client/assets/DiffWorkspace-BMtV4MMc.js +0 -6
- package/dist/client/assets/EditableFileViewer-B44TSuFu.css +0 -1
- package/dist/client/assets/EditableFileViewer-BE3AsnVa.js +0 -1
- package/dist/client/assets/FilesView-DoVhRfi1.js +0 -1
- package/dist/client/assets/GitHubAvatar-RiePq1Yf.js +0 -1
- package/dist/client/assets/HistoryView-Dl8uqmKe.js +0 -1
- package/dist/client/assets/HtmlFileViewer-xfjY1Swc.js +0 -2
- package/dist/client/assets/IconCheck-BPhxw_LS.js +0 -1
- package/dist/client/assets/IconChevronDown-C3FplJL8.js +0 -1
- package/dist/client/assets/ImageFileViewer-BJBOmpsf.css +0 -1
- package/dist/client/assets/ImageFileViewer-DXaIo7_d.js +0 -1
- package/dist/client/assets/LocalRefsDialog-C5J3kgTe.js +0 -1
- package/dist/client/assets/MarkdownFileViewer-18mvm0f2.js +0 -2
- package/dist/client/assets/PairingPage-BEUj3t0V.js +0 -1
- package/dist/client/assets/PierreDiffViewer-p29h7lW_.js +0 -1
- package/dist/client/assets/PullRequestDiff-C17JA4ko.js +0 -1
- package/dist/client/assets/PullRequestViewer-DaMtkESD.js +0 -2
- package/dist/client/assets/PullRequestsView-44f03VLC.js +0 -1
- package/dist/client/assets/QuickOpenDialog-Bi-L68PU.js +0 -1
- package/dist/client/assets/RepositoryProjectsDialog-DFGn74fe.js +0 -1
- package/dist/client/assets/SettingsDialog-CruoIiyN.js +0 -9
- package/dist/client/assets/Viewer-3WKpwRzo.js +0 -3
- package/dist/client/assets/channel-BqKQxg-1.js +0 -1
- package/dist/client/assets/checkbox-MDl2t9_3.js +0 -1
- package/dist/client/assets/createReactComponent-BfrD_oQK.js +0 -1
- package/dist/client/assets/flowDiagram-OXPTDLAJ-DSokwYKA.js +0 -1
- package/dist/client/assets/index-CoZCJqTQ.js +0 -47
- package/dist/client/assets/index-DUERTTRS.css +0 -2
- package/dist/client/assets/katex-C6e6EqXB.js +0 -1
- package/dist/client/assets/select-pZpCy7qn.js +0 -1
- package/dist/client/assets/swimlanesDiagram-K3J5GTZL-DEFKR6Vf.js +0 -8
- package/dist/client/assets/tanstack-CYi5knVJ.js +0 -1
- package/dist/client/assets/viewer-tabs-MMNrJqGE.js +0 -1
|
@@ -1,10 +1,59 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { randomUUID } from "node:crypto";
|
|
1
|
+
import { c as redactSensitiveText } from "./network-settings-CdFeKFRB.mjs";
|
|
3
2
|
import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
4
3
|
import path from "node:path";
|
|
4
|
+
import { randomUUID } from "node:crypto";
|
|
5
5
|
import os from "node:os";
|
|
6
|
+
import { execFile } from "node:child_process";
|
|
6
7
|
import { promisify } from "node:util";
|
|
7
8
|
import { setTimeout } from "node:timers/promises";
|
|
9
|
+
//#region src/cli-errors.ts
|
|
10
|
+
/** Operational errors retain a stable identity independently of their wording. */
|
|
11
|
+
var CliError = class extends Error {
|
|
12
|
+
code;
|
|
13
|
+
actions;
|
|
14
|
+
constructor(code, message, actions = [], options) {
|
|
15
|
+
super(message, options);
|
|
16
|
+
this.code = code;
|
|
17
|
+
this.actions = actions;
|
|
18
|
+
this.name = "CliError";
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
function cliCommand(home, ...args) {
|
|
22
|
+
const quote = (value) => `'${value.replaceAll("'", process.platform === "win32" ? "''" : "'\\''")}'`;
|
|
23
|
+
return `opentig ${args.map((arg) => /^[a-zA-Z0-9_.:=/-]+$/.test(arg) ? arg : quote(arg)).join(" ")} --home ${quote(home)}`;
|
|
24
|
+
}
|
|
25
|
+
function errorCode(error) {
|
|
26
|
+
return error && typeof error === "object" && "code" in error && typeof error.code === "string" ? error.code : void 0;
|
|
27
|
+
}
|
|
28
|
+
function diagnostic(error) {
|
|
29
|
+
const message = error instanceof Error ? error.message : "An unexpected error occurred.";
|
|
30
|
+
return redactSensitiveText(error instanceof CliError ? `${message}\n${error.actions.join("\n")}`.trim() : message);
|
|
31
|
+
}
|
|
32
|
+
function operationError(error, home, operation) {
|
|
33
|
+
if (error instanceof CliError) return error;
|
|
34
|
+
const code = errorCode(error);
|
|
35
|
+
const checks = [`Check: ${cliCommand(home, "service", "status")}`, `Server log: ${path.join(home, "logs/server.log")}`];
|
|
36
|
+
if (code === "EACCES" || code === "EPERM") return new CliError("PERMISSION_DENIED", `Cannot ${operation}: permission was denied.`, [`Check this user's access to ${home} and the user service manager. Organization policies may restrict service tasks.`, "Use your normal OS account; do not switch to a different account or run the server as administrator."], { cause: error });
|
|
37
|
+
if (code === "ENOSPC") return new CliError("DISK_FULL", `Cannot ${operation}: the disk is full.`, [`Free space on the volume containing ${home}, then retry.`], { cause: error });
|
|
38
|
+
if (code === "ECONNREFUSED" || code === "ECONNRESET" || code === "UND_ERR_CONNECT_TIMEOUT" || error instanceof Error && (error.name === "TimeoutError" || error.name === "AbortError" || error.message === "fetch failed")) return new CliError("CONNECTION_FAILED", `Cannot ${operation}: the server could not be reached or did not respond in time.`, checks, { cause: error });
|
|
39
|
+
return new CliError("OPERATION_FAILED", `Cannot ${operation}.`, ["The cause could not be determined automatically.", ...checks], { cause: error });
|
|
40
|
+
}
|
|
41
|
+
function serviceError(error, home, action) {
|
|
42
|
+
if (error instanceof CliError) return error;
|
|
43
|
+
const verb = action === "status" ? "inspect" : action;
|
|
44
|
+
if ([
|
|
45
|
+
"EACCES",
|
|
46
|
+
"EPERM",
|
|
47
|
+
"ENOSPC"
|
|
48
|
+
].includes(errorCode(error) ?? "")) return operationError(error, home, `${verb} the service`);
|
|
49
|
+
return new CliError("SUPERVISOR_FAILED", `Could not ${verb} the OpenTig user service.`, [
|
|
50
|
+
process.platform === "win32" ? "Check Task Scheduler access and organization policies for your Windows account." : process.platform === "darwin" ? "Check the user LaunchAgent in an active macOS GUI login session." : "Check the systemd user manager in your login session.",
|
|
51
|
+
`Check: ${cliCommand(home, "service", "status")}`,
|
|
52
|
+
`Service startup output: ${path.join(home, "logs/service-stderr.log")} (Windows), or the user supervisor's logs.`,
|
|
53
|
+
"The requested operation may be incomplete. Inspect its state before retrying."
|
|
54
|
+
], { cause: error });
|
|
55
|
+
}
|
|
56
|
+
//#endregion
|
|
8
57
|
//#region src/service-installation.ts
|
|
9
58
|
var execute = promisify(execFile);
|
|
10
59
|
var SERVICE_NAME = "opentig.service";
|
|
@@ -17,7 +66,7 @@ function newerVersion(a, b) {
|
|
|
17
66
|
return false;
|
|
18
67
|
}
|
|
19
68
|
function packageDirectory(home, install) {
|
|
20
|
-
if (!stableVersion(install.version) || !["flat", "npm"].includes(install.layout)) throw new
|
|
69
|
+
if (!stableVersion(install.version) || !["flat", "npm"].includes(install.layout)) throw new CliError("SERVICE_METADATA_INVALID", "Invalid managed service version.", ["Inspect the service installation metadata and restore a trusted backup before retrying."]);
|
|
21
70
|
const base = path.join(home, "service", `app-${install.version}`);
|
|
22
71
|
return install.layout === "flat" ? base : path.join(base, "node_modules/@opentig/cli");
|
|
23
72
|
}
|
|
@@ -25,15 +74,15 @@ async function readInstallation(home) {
|
|
|
25
74
|
let value;
|
|
26
75
|
try {
|
|
27
76
|
value = JSON.parse(await readFile(path.join(home, "service/installation.json"), "utf8"));
|
|
28
|
-
} catch (
|
|
29
|
-
if (
|
|
30
|
-
throw
|
|
77
|
+
} catch (cause) {
|
|
78
|
+
if (cause.code === "ENOENT") return null;
|
|
79
|
+
throw new CliError("SERVICE_METADATA_INVALID", "Could not read managed service installation metadata.", [`Check permissions and JSON in ${path.join(home, "service/installation.json")}. Do not remove the entire home or paired browser data.`], { cause });
|
|
31
80
|
}
|
|
32
|
-
if (value.manager !== void 0 && ![
|
|
81
|
+
if (!value || typeof value !== "object" || value.manager !== void 0 && ![
|
|
33
82
|
"systemd",
|
|
34
83
|
"launchd",
|
|
35
84
|
"windows-task"
|
|
36
|
-
].includes(value.manager) || value.schema !== 1 || !stableVersion(value.version) || !["flat", "npm"].includes(value.layout) || typeof value.host !== "string" || !/^[a-zA-Z0-9.:[\]-]+$/.test(value.host) || !Number.isInteger(value.port) || value.port < 1 || value.port > 65535 || value.environmentPath !== void 0 && (typeof value.environmentPath !== "string" || /[\0\r\n]/.test(value.environmentPath)) || typeof value.node !== "string" || !path.isAbsolute(value.node) || /[\0\r\n]/.test(value.node)) throw new
|
|
85
|
+
].includes(value.manager) || value.schema !== 1 || !stableVersion(value.version) || !["flat", "npm"].includes(value.layout) || typeof value.host !== "string" || !/^[a-zA-Z0-9.:[\]-]+$/.test(value.host) || !Number.isInteger(value.port) || value.port < 1 || value.port > 65535 || value.environmentPath !== void 0 && (typeof value.environmentPath !== "string" || /[\0\r\n]/.test(value.environmentPath)) || typeof value.node !== "string" || !path.isAbsolute(value.node) || /[\0\r\n]/.test(value.node)) throw new CliError("SERVICE_METADATA_INVALID", "Invalid managed service installation.", [`Inspect ${path.join(home, "service/installation.json")} and restore valid installation metadata before retrying.`]);
|
|
37
86
|
return value;
|
|
38
87
|
}
|
|
39
88
|
async function atomicWrite(file, contents) {
|
|
@@ -70,6 +119,7 @@ Type=simple
|
|
|
70
119
|
WorkingDirectory=${systemdWorkingDirectory(input.home)}
|
|
71
120
|
ExecStart=${args.map((arg) => systemdQuote(arg.replaceAll("$", () => "$$"))).join(" ")}
|
|
72
121
|
Environment=NODE_ENV=production
|
|
122
|
+
Environment=${systemdQuote(`OPENTIG_SERVICE_HOME=${input.home}`)}
|
|
73
123
|
${input.environmentPath === void 0 ? "" : `Environment=${systemdQuote(`PATH=${input.environmentPath}`)}\n`}Restart=on-failure
|
|
74
124
|
RestartSec=3
|
|
75
125
|
KillSignal=SIGTERM
|
|
@@ -138,7 +188,8 @@ ${input.environmentPath === void 0 ? "" : `<key>PATH</key><string>${xml(input.en
|
|
|
138
188
|
}
|
|
139
189
|
/** Keep a recognizable parent attached so service stop can terminate its process tree. */
|
|
140
190
|
function windowsServerScript(input) {
|
|
141
|
-
|
|
191
|
+
const log = path.win32.join(input.home, "logs", "service-stderr.log");
|
|
192
|
+
return `$ErrorActionPreference = 'Stop'; $env:NODE_ENV = 'production'; $env:OPENTIG_SERVICE_HOME = ${psQuote(input.home)}; ` + (input.environmentPath === void 0 ? "" : `$env:PATH = ${psQuote(input.environmentPath)}; `) + `$null = New-Item -ItemType Directory -Force -Path ${psQuote(path.win32.dirname(log))}; if (Test-Path -LiteralPath ${psQuote(log)}) { Move-Item -LiteralPath ${psQuote(log)} -Destination ${psQuote(`${log}.1`)} -Force }; & ${[input.nodeExecutable, ...serviceArgs(input)].map(psQuote).join(" ")} > $null 2>> ${psQuote(log)}; exit $LASTEXITCODE`;
|
|
142
193
|
}
|
|
143
194
|
function renderWindowsTask(input) {
|
|
144
195
|
return `<?xml version="1.0" encoding="UTF-16"?>
|
|
@@ -171,10 +222,10 @@ function managerKind(platform = process.platform) {
|
|
|
171
222
|
if (platform === "linux") return "systemd";
|
|
172
223
|
if (platform === "darwin") return "launchd";
|
|
173
224
|
if (platform === "win32") return "windows-task";
|
|
174
|
-
throw new
|
|
225
|
+
throw new CliError("PLATFORM_UNSUPPORTED", "Managed CLI services support Linux, macOS, and Windows.", ["Use opentig serve in a terminal on a supported Node.js host."]);
|
|
175
226
|
}
|
|
176
227
|
function assertManager(installation, kind) {
|
|
177
|
-
if ((installation.manager ?? "systemd") !== kind) throw new
|
|
228
|
+
if ((installation.manager ?? "systemd") !== kind) throw new CliError("SERVICE_PLATFORM_MISMATCH", "This service was installed for another operating system.", ["Use the original OS and home to manage this service; do not copy its installation metadata to this machine."]);
|
|
178
229
|
}
|
|
179
230
|
/** Optional identity is only for isolated native integration tests, never CLI input. */
|
|
180
231
|
async function createServiceManager(home, identity) {
|
|
@@ -206,7 +257,7 @@ function linuxManager(home, identity) {
|
|
|
206
257
|
try {
|
|
207
258
|
await execute("loginctl", ["enable-linger"], { timeout: 15e3 });
|
|
208
259
|
} catch {
|
|
209
|
-
throw new
|
|
260
|
+
throw new CliError("LINGERING_REQUIRED", "Lingering is required for the Linux user service.", ["Ask an administrator to run: sudo loginctl enable-linger <your-user>", "Then retry service install as your normal user."]);
|
|
210
261
|
}
|
|
211
262
|
},
|
|
212
263
|
render: renderSystemdUnit,
|
|
@@ -291,7 +342,7 @@ function macManager(home, identity) {
|
|
|
291
342
|
try {
|
|
292
343
|
await launchctl("print", domain);
|
|
293
344
|
} catch {
|
|
294
|
-
throw new
|
|
345
|
+
throw new CliError("LOGIN_SESSION_REQUIRED", "No macOS login session is available.", ["Sign in to a GUI session on the Mac, then run service install as that user."]);
|
|
295
346
|
}
|
|
296
347
|
},
|
|
297
348
|
render: (input) => renderLaunchAgent(input, label),
|
|
@@ -426,6 +477,29 @@ if ($null -ne $task) {
|
|
|
426
477
|
stop: () => stopTask(name),
|
|
427
478
|
remove: () => removeTask(name),
|
|
428
479
|
status: () => state(name),
|
|
480
|
+
ownsRuntime: async (pid) => {
|
|
481
|
+
if (!Number.isSafeInteger(pid) || pid <= 0) return false;
|
|
482
|
+
return await ps(`${task(name)}
|
|
483
|
+
if ($null -eq $task -or $task.State -ne 4) { 'false'; exit }
|
|
484
|
+
$action = $task.Definition.Actions.Item(1)
|
|
485
|
+
$arguments = [string]$action.Arguments
|
|
486
|
+
if ($arguments -notmatch '-EncodedCommand ([A-Za-z0-9+/=]+)$') { 'false'; exit }
|
|
487
|
+
$encoded = $Matches[1]
|
|
488
|
+
$processes = @(Get-CimInstance Win32_Process)
|
|
489
|
+
$cursor = ${pid}
|
|
490
|
+
$owned = $false
|
|
491
|
+
for ($depth = 0; $depth -lt 16 -and $cursor -gt 0; $depth++) {
|
|
492
|
+
$current = $processes | Where-Object { $_.ProcessId -eq $cursor } | Select-Object -First 1
|
|
493
|
+
if ($null -eq $current) { break }
|
|
494
|
+
if ($current.ExecutablePath -eq $action.Path -and $current.CommandLine -match ('(?i)-EncodedCommand\\s+"?' + [regex]::Escape($encoded) + '"?\\s*$')) {
|
|
495
|
+
$owner = Invoke-CimMethod -InputObject $current -MethodName GetOwnerSid
|
|
496
|
+
$owned = $owner.ReturnValue -eq 0 -and $owner.Sid -eq ${psQuote(sid)}
|
|
497
|
+
break
|
|
498
|
+
}
|
|
499
|
+
$cursor = $current.ParentProcessId
|
|
500
|
+
}
|
|
501
|
+
$owned.ToString().ToLowerInvariant()`) === "true";
|
|
502
|
+
},
|
|
429
503
|
ownsProcess: async () => process.env.OPENTIG_SERVICE_HOME === home && (await state(name)).running,
|
|
430
504
|
launchWorker: async (node, entry) => {
|
|
431
505
|
const id = `OpenTig Update ${randomUUID()}`;
|
|
@@ -466,4 +540,4 @@ if ($null -ne $task) {
|
|
|
466
540
|
};
|
|
467
541
|
}
|
|
468
542
|
//#endregion
|
|
469
|
-
export { newerVersion as a, saveInstallation as c, execute as i, stableVersion as l, createServiceManager as n, packageDirectory as o, atomicWrite as r, readInstallation as s, assertManager as t };
|
|
543
|
+
export { newerVersion as a, saveInstallation as c, cliCommand as d, diagnostic as f, serviceError as h, execute as i, stableVersion as l, operationError as m, createServiceManager as n, packageDirectory as o, errorCode as p, atomicWrite as r, readInstallation as s, assertManager as t, CliError as u };
|