@dylanpiercey/work 0.0.5 → 0.0.7
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/bin/work.mjs +88 -18
- package/dist/index.mjs +1218 -820
- package/dist/public/assets/{_DwWKKIbx.js → _B-_0cKbG.js} +2 -2
- package/dist/public/assets/{_DwWKKIbx.js.map → _B-_0cKbG.js.map} +1 -1
- package/dist/public/assets/{_BbQjjMLb2.js → _B1F2GQHq2.js} +2 -2
- package/dist/public/assets/{_BbQjjMLb2.js.map → _B1F2GQHq2.js.map} +1 -1
- package/dist/public/assets/{_DThwiCYf.js → _B49hrT7F.js} +2 -2
- package/dist/public/assets/{_DThwiCYf.js.map → _B49hrT7F.js.map} +1 -1
- package/dist/public/assets/{_L0QEXXRu.js → _B4R8SNvy.js} +2 -2
- package/dist/public/assets/{_L0QEXXRu.js.map → _B4R8SNvy.js.map} +1 -1
- package/dist/public/assets/{_g24DOTM6.js → _B7K5PePe.js} +2 -2
- package/dist/public/assets/{_g24DOTM6.js.map → _B7K5PePe.js.map} +1 -1
- package/dist/public/assets/{_DsH6sF8_.js → _B8mEgNvE.js} +2 -2
- package/dist/public/assets/{_DsH6sF8_.js.map → _B8mEgNvE.js.map} +1 -1
- package/dist/public/assets/{_Dp2I7SvR2.js → _BBbcogWL2.js} +2 -2
- package/dist/public/assets/{_Dp2I7SvR2.js.map → _BBbcogWL2.js.map} +1 -1
- package/dist/public/assets/{_BQnjw6qe.js → _BDxD__Ca.js} +2 -2
- package/dist/public/assets/{_BQnjw6qe.js.map → _BDxD__Ca.js.map} +1 -1
- package/dist/public/assets/{_BxHj_AmV.js → _BE5Ltp0D.js} +2 -2
- package/dist/public/assets/{_BxHj_AmV.js.map → _BE5Ltp0D.js.map} +1 -1
- package/dist/public/assets/{_lZmV1DmL.js → _BE8gA6TO.js} +2 -2
- package/dist/public/assets/{_lZmV1DmL.js.map → _BE8gA6TO.js.map} +1 -1
- package/dist/public/assets/{_f31sxhc9.js → _BEY9qyEj.js} +2 -2
- package/dist/public/assets/{_f31sxhc9.js.map → _BEY9qyEj.js.map} +1 -1
- package/dist/public/assets/{_3LSnPXE-2.js → _BFPTVBh82.js} +2 -2
- package/dist/public/assets/{_3LSnPXE-2.js.map → _BFPTVBh82.js.map} +1 -1
- package/dist/public/assets/{_CPt59YK-2.js → _BKNwgsJI2.js} +2 -2
- package/dist/public/assets/{_CPt59YK-2.js.map → _BKNwgsJI2.js.map} +1 -1
- package/dist/public/assets/{_CGEJqu1l.js → _BLuo0bJF.js} +2 -2
- package/dist/public/assets/{_CGEJqu1l.js.map → _BLuo0bJF.js.map} +1 -1
- package/dist/public/assets/{_De1qIUYL2.js → _BMbg6Q_32.js} +2 -2
- package/dist/public/assets/{_De1qIUYL2.js.map → _BMbg6Q_32.js.map} +1 -1
- package/dist/public/assets/{_DFdBRroy.js → _BQqn5S5j.js} +2 -2
- package/dist/public/assets/{_DFdBRroy.js.map → _BQqn5S5j.js.map} +1 -1
- package/dist/public/assets/{_C_AWyxBB.js → _BTJ_-CIz.js} +2 -2
- package/dist/public/assets/{_C_AWyxBB.js.map → _BTJ_-CIz.js.map} +1 -1
- package/dist/public/assets/{_DWh6hcFb.js → _BTnhYWUT.js} +2 -2
- package/dist/public/assets/{_DWh6hcFb.js.map → _BTnhYWUT.js.map} +1 -1
- package/dist/public/assets/{_C55X2_br.js → _B_U5SPso.js} +2 -2
- package/dist/public/assets/{_C55X2_br.js.map → _B_U5SPso.js.map} +1 -1
- package/dist/public/assets/{_BmLItN7n.js → _BfxQEfor.js} +2 -2
- package/dist/public/assets/{_BmLItN7n.js.map → _BfxQEfor.js.map} +1 -1
- package/dist/public/assets/{_Cxre_eVs2.js → _Bhn-MKXG2.js} +2 -2
- package/dist/public/assets/{_Cxre_eVs2.js.map → _Bhn-MKXG2.js.map} +1 -1
- package/dist/public/assets/{_G2euCJ5s2.js → _BkEOzqHA2.js} +2 -2
- package/dist/public/assets/{_G2euCJ5s2.js.map → _BkEOzqHA2.js.map} +1 -1
- package/dist/public/assets/{_BtEwCzLt.js → _BqeWVi6c.js} +2 -2
- package/dist/public/assets/{_BtEwCzLt.js.map → _BqeWVi6c.js.map} +1 -1
- package/dist/public/assets/{_D25eFvus.js → _Bx6coq7v.js} +2 -2
- package/dist/public/assets/{_D25eFvus.js.map → _Bx6coq7v.js.map} +1 -1
- package/dist/public/assets/{_Dj5K_vdY.js → _BxWguH11.js} +2 -2
- package/dist/public/assets/{_Dj5K_vdY.js.map → _BxWguH11.js.map} +1 -1
- package/dist/public/assets/{_BO52x4nD2.js → _C2TX6Jrr2.js} +2 -2
- package/dist/public/assets/{_BO52x4nD2.js.map → _C2TX6Jrr2.js.map} +1 -1
- package/dist/public/assets/{_UUjPxQzk.js → _C8Lw1Tmb.js} +2 -2
- package/dist/public/assets/{_UUjPxQzk.js.map → _C8Lw1Tmb.js.map} +1 -1
- package/dist/public/assets/{_C_RO1bIU.js → _CDtlFxZX.js} +2 -2
- package/dist/public/assets/{_C_RO1bIU.js.map → _CDtlFxZX.js.map} +1 -1
- package/dist/public/assets/{_AAkZyuUo2.js → _CF3V7ZyO2.js} +2 -2
- package/dist/public/assets/{_AAkZyuUo2.js.map → _CF3V7ZyO2.js.map} +1 -1
- package/dist/public/assets/{_BMIj0szP.js → _CIUf_Jmq.js} +2 -2
- package/dist/public/assets/{_BMIj0szP.js.map → _CIUf_Jmq.js.map} +1 -1
- package/dist/public/assets/{_CZjGo4EJ2.js → _CJlF2h3E2.js} +2 -2
- package/dist/public/assets/{_CZjGo4EJ2.js.map → _CJlF2h3E2.js.map} +1 -1
- package/dist/public/assets/{_DjF3hk4N.js → _CNDjHC1Q.js} +2 -2
- package/dist/public/assets/{_DjF3hk4N.js.map → _CNDjHC1Q.js.map} +1 -1
- package/dist/public/assets/{_Dg0ufwJw.js → _CTkR0S8t.js} +2 -2
- package/dist/public/assets/{_Dg0ufwJw.js.map → _CTkR0S8t.js.map} +1 -1
- package/dist/public/assets/{_DWBu1oTd.js → _C_K-IZx7.js} +2 -2
- package/dist/public/assets/{_DWBu1oTd.js.map → _C_K-IZx7.js.map} +1 -1
- package/dist/public/assets/{_B7ycuWnF.js → _CawcEo7A.js} +2 -2
- package/dist/public/assets/{_B7ycuWnF.js.map → _CawcEo7A.js.map} +1 -1
- package/dist/public/assets/{_BF4oeZAs2.js → _Ch0uVmAz2.js} +2 -2
- package/dist/public/assets/{_BF4oeZAs2.js.map → _Ch0uVmAz2.js.map} +1 -1
- package/dist/public/assets/{_BksA_4pq.js → _Ck30GMoL.js} +2 -2
- package/dist/public/assets/{_BksA_4pq.js.map → _Ck30GMoL.js.map} +1 -1
- package/dist/public/assets/{_LMf8ZNAk.js → _Cpqbvj5d.js} +2 -2
- package/dist/public/assets/{_LMf8ZNAk.js.map → _Cpqbvj5d.js.map} +1 -1
- package/dist/public/assets/{_MSZeR7tc.js → _CqNVh0h5.js} +2 -2
- package/dist/public/assets/{_MSZeR7tc.js.map → _CqNVh0h5.js.map} +1 -1
- package/dist/public/assets/{_CZJ6f1W42.js → _Cx_br0wh2.js} +2 -2
- package/dist/public/assets/{_CZJ6f1W42.js.map → _Cx_br0wh2.js.map} +1 -1
- package/dist/public/assets/{_dbpNK3ti.js → _CzBadWXq.js} +2 -2
- package/dist/public/assets/{_dbpNK3ti.js.map → _CzBadWXq.js.map} +1 -1
- package/dist/public/assets/{_BKWC43v9.js → _D0Dk2eMz.js} +2 -2
- package/dist/public/assets/{_BKWC43v9.js.map → _D0Dk2eMz.js.map} +1 -1
- package/dist/public/assets/{_BWobArGx2.js → _D0PyqJyr2.js} +2 -2
- package/dist/public/assets/{_BWobArGx2.js.map → _D0PyqJyr2.js.map} +1 -1
- package/dist/public/assets/{_Cp2dVuf7.js → _D409hg3n.js} +2 -2
- package/dist/public/assets/{_Cp2dVuf7.js.map → _D409hg3n.js.map} +1 -1
- package/dist/public/assets/{_DgS0ehtc.js → _D4uduNrb.js} +2 -2
- package/dist/public/assets/{_DgS0ehtc.js.map → _D4uduNrb.js.map} +1 -1
- package/dist/public/assets/{_DwvTHP0H.js → _DBj-L0Ww.js} +2 -2
- package/dist/public/assets/{_DwvTHP0H.js.map → _DBj-L0Ww.js.map} +1 -1
- package/dist/public/assets/{_DkAxFIdj2.js → _DC9uMckf2.js} +2 -2
- package/dist/public/assets/{_DkAxFIdj2.js.map → _DC9uMckf2.js.map} +1 -1
- package/dist/public/assets/{_m6OqtXq5.js → _DHsfzMP_.js} +2 -2
- package/dist/public/assets/{_m6OqtXq5.js.map → _DHsfzMP_.js.map} +1 -1
- package/dist/public/assets/{_DR7HMLdt.js → _DPDjFNn3.js} +2 -2
- package/dist/public/assets/{_DR7HMLdt.js.map → _DPDjFNn3.js.map} +1 -1
- package/dist/public/assets/{_CFYld88W.js → _DS1r4Da7.js} +2 -2
- package/dist/public/assets/{_CFYld88W.js.map → _DS1r4Da7.js.map} +1 -1
- package/dist/public/assets/{_XySmXsU3.js → _DZp-Xvf0.js} +2 -2
- package/dist/public/assets/{_XySmXsU3.js.map → _DZp-Xvf0.js.map} +1 -1
- package/dist/public/assets/{_C7WwEVpI.js → _DbP8pES9.js} +2 -2
- package/dist/public/assets/{_C7WwEVpI.js.map → _DbP8pES9.js.map} +1 -1
- package/dist/public/assets/{_B-CqRNtV.js → _DhqQ2yva.js} +2 -2
- package/dist/public/assets/{_B-CqRNtV.js.map → _DhqQ2yva.js.map} +1 -1
- package/dist/public/assets/{_qGiUFV1r.js → _Din9HEMs.js} +2 -2
- package/dist/public/assets/{_qGiUFV1r.js.map → _Din9HEMs.js.map} +1 -1
- package/dist/public/assets/{_MSjbYDCb.js → _Dk-i8IAv.js} +2 -2
- package/dist/public/assets/{_MSjbYDCb.js.map → _Dk-i8IAv.js.map} +1 -1
- package/dist/public/assets/{_CMH9CsQN.js → _DvdWf5o-.js} +2 -2
- package/dist/public/assets/{_CMH9CsQN.js.map → _DvdWf5o-.js.map} +1 -1
- package/dist/public/assets/{_DaxEJQAG2.js → _DwmbSeOR2.js} +2 -2
- package/dist/public/assets/{_DaxEJQAG2.js.map → _DwmbSeOR2.js.map} +1 -1
- package/dist/public/assets/{_DdXxywnu.js → _Dz57V0my.js} +2 -2
- package/dist/public/assets/{_DdXxywnu.js.map → _Dz57V0my.js.map} +1 -1
- package/dist/public/assets/{_DVqaReFM2.js → _JDPB-L9T2.js} +2 -2
- package/dist/public/assets/{_DVqaReFM2.js.map → _JDPB-L9T2.js.map} +1 -1
- package/dist/public/assets/{_BacHRrKm2.js → _T3Aahgg12.js} +2 -2
- package/dist/public/assets/{_BacHRrKm2.js.map → _T3Aahgg12.js.map} +1 -1
- package/dist/public/assets/{_sQkp9ieF.js → _Tbp9N0Pq.js} +2 -2
- package/dist/public/assets/{_sQkp9ieF.js.map → _Tbp9N0Pq.js.map} +1 -1
- package/dist/public/assets/{_CSxCkWdX2.js → _Tqwd1-8Z2.js} +2 -2
- package/dist/public/assets/{_CSxCkWdX2.js.map → _Tqwd1-8Z2.js.map} +1 -1
- package/dist/public/assets/{_Dc3WoyCf.js → _UPkRAhR-.js} +2 -2
- package/dist/public/assets/{_Dc3WoyCf.js.map → _UPkRAhR-.js.map} +1 -1
- package/dist/public/assets/{_D4G4BzdU2.js → _WO2um4ce2.js} +2 -2
- package/dist/public/assets/{_D4G4BzdU2.js.map → _WO2um4ce2.js.map} +1 -1
- package/dist/public/assets/{_DwB4tost2.js → _WXstblxD2.js} +2 -2
- package/dist/public/assets/{_DwB4tost2.js.map → _WXstblxD2.js.map} +1 -1
- package/dist/public/assets/{_BPAMsQ-Y2.js → _Wq5Lwig62.js} +2 -2
- package/dist/public/assets/{_BPAMsQ-Y2.js.map → _Wq5Lwig62.js.map} +1 -1
- package/dist/public/assets/{_B7BQvLFA2.js → _YMDMk2XX2.js} +2 -2
- package/dist/public/assets/{_B7BQvLFA2.js.map → _YMDMk2XX2.js.map} +1 -1
- package/dist/public/assets/{_A4VtPfAb.js → _b9uzSPzx.js} +2 -2
- package/dist/public/assets/{_A4VtPfAb.js.map → _b9uzSPzx.js.map} +1 -1
- package/dist/public/assets/{_Bjvy806u2.js → _dfWRmwy82.js} +2 -2
- package/dist/public/assets/{_Bjvy806u2.js.map → _dfWRmwy82.js.map} +1 -1
- package/dist/public/assets/{_2JdtdC0N.js → _ehtlhcCR.js} +2 -2
- package/dist/public/assets/{_2JdtdC0N.js.map → _ehtlhcCR.js.map} +1 -1
- package/dist/public/assets/{_Fpix3N3i.js → _fZl_Qerv.js} +2 -2
- package/dist/public/assets/{_Fpix3N3i.js.map → _fZl_Qerv.js.map} +1 -1
- package/dist/public/assets/{_C6fTVhaS.js → _js4WyaBT.js} +2 -2
- package/dist/public/assets/{_C6fTVhaS.js.map → _js4WyaBT.js.map} +1 -1
- package/dist/public/assets/{_Ck_58QRD.js → _okHqOb61.js} +2 -2
- package/dist/public/assets/{_Ck_58QRD.js.map → _okHqOb61.js.map} +1 -1
- package/dist/public/assets/{_5XJqee1K2.js → _rMU5-5Oc2.js} +2 -2
- package/dist/public/assets/{_5XJqee1K2.js.map → _rMU5-5Oc2.js.map} +1 -1
- package/dist/public/assets/{index-BAGH9WA4.js → index-Bx9UtyrE.js} +63 -61
- package/dist/public/assets/index-Bx9UtyrE.js.map +1 -0
- package/dist/public/assets/{index-KIy0rCx1.css → index-C_YqjXeW.css} +1 -1
- package/install.sh +4 -1
- package/package.json +1 -1
- package/scripts/migrate.mjs +141 -0
- package/dist/public/assets/index-BAGH9WA4.js.map +0 -1
package/bin/work.mjs
CHANGED
|
@@ -107,15 +107,21 @@ async function setup() {
|
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
// One-shot cleanups between versions.
|
|
110
|
+
// One-shot cleanups between versions. Run them against the settings the
|
|
111
|
+
// service actually uses: migrate.mjs exits quietly when it finds no db, so
|
|
112
|
+
// an ambient environment missing WORK_DATA_DIR skips every sweep.
|
|
111
113
|
const migrate = path.join(pkgRoot, "scripts", "migrate.mjs");
|
|
112
114
|
if (fs.existsSync(migrate)) {
|
|
113
|
-
spawnSync(process.execPath, [migrate], {
|
|
115
|
+
spawnSync(process.execPath, [migrate], {
|
|
116
|
+
stdio: "inherit",
|
|
117
|
+
env: { ...process.env, ...serviceEnv() },
|
|
118
|
+
});
|
|
114
119
|
}
|
|
115
120
|
|
|
116
121
|
installService();
|
|
117
|
-
|
|
118
|
-
|
|
122
|
+
const port = serviceEnv().PORT;
|
|
123
|
+
maybeTunnel(port);
|
|
124
|
+
log(`done — http://localhost:${port}`);
|
|
119
125
|
}
|
|
120
126
|
|
|
121
127
|
async function update() {
|
|
@@ -139,18 +145,73 @@ function servicePath() {
|
|
|
139
145
|
].join(":");
|
|
140
146
|
}
|
|
141
147
|
|
|
148
|
+
/** Argv prefix that keeps the host awake while the server runs. A suspended
|
|
149
|
+
* host is a dead host: agents keep running in tmux, but the machine stops
|
|
150
|
+
* answering, so remote sessions look hung until someone wakes it by hand. The
|
|
151
|
+
* inhibitor needs no privileges and lifts when the service stops — masking
|
|
152
|
+
* sleep.target is the stronger machine-wide version, but that wants sudo. */
|
|
153
|
+
function awakePrefix() {
|
|
154
|
+
if (process.platform === "darwin")
|
|
155
|
+
return have("caffeinate") ? ["/usr/bin/caffeinate", "-s"] : [];
|
|
156
|
+
if (process.platform === "linux" && have("systemd-inhibit"))
|
|
157
|
+
return [
|
|
158
|
+
"systemd-inhibit",
|
|
159
|
+
"--what=sleep:idle",
|
|
160
|
+
"--who=work",
|
|
161
|
+
"--why=work server is running",
|
|
162
|
+
"--mode=block",
|
|
163
|
+
];
|
|
164
|
+
return [];
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/** Where installService() writes the service definition — also the store we
|
|
168
|
+
* read settings back out of, so there is no second config file to keep. */
|
|
169
|
+
function serviceFile() {
|
|
170
|
+
return process.platform === "darwin"
|
|
171
|
+
? path.join(os.homedir(), "Library/LaunchAgents/dev.work.app.plist")
|
|
172
|
+
: path.join(
|
|
173
|
+
process.env.XDG_CONFIG_HOME || path.join(os.homedir(), ".config"),
|
|
174
|
+
"systemd/user/work.service",
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** WORK_* already baked into the installed service. `work update` re-runs
|
|
179
|
+
* setup from whatever shell the user happens to be in, so without this the
|
|
180
|
+
* first update silently resets the port, root and data dir to defaults —
|
|
181
|
+
* and a lost WORK_DATA_DIR points the server at an empty database, making
|
|
182
|
+
* every workspace look like it vanished. */
|
|
183
|
+
function installedServiceEnv() {
|
|
184
|
+
const installed = {};
|
|
185
|
+
try {
|
|
186
|
+
const text = fs.readFileSync(serviceFile(), "utf8");
|
|
187
|
+
const re =
|
|
188
|
+
process.platform === "darwin"
|
|
189
|
+
? /<key>(WORK_[A-Z_]+)<\/key>\s*<string>([^<]*)<\/string>/g
|
|
190
|
+
: /^Environment=(WORK_[A-Z_]+)=(.*)$/gm;
|
|
191
|
+
for (const [, key, value] of text.matchAll(re)) installed[key] = value;
|
|
192
|
+
} catch {}
|
|
193
|
+
return installed;
|
|
194
|
+
}
|
|
195
|
+
|
|
142
196
|
function serviceEnv() {
|
|
143
|
-
const env = { PATH: servicePath()
|
|
144
|
-
|
|
145
|
-
|
|
197
|
+
const env = { PATH: servicePath() };
|
|
198
|
+
const installed = installedServiceEnv();
|
|
199
|
+
for (const key of ["WORK_APP_PORT", "WORK_ROOT", "WORK_DATA_DIR", "WORK_ALLOWED_HOSTS"]) {
|
|
200
|
+
// `in` rather than a truthy check, so `WORK_ALLOWED_HOSTS= work setup`
|
|
201
|
+
// can deliberately clear a setting the installed service still carries.
|
|
202
|
+
const value = key in process.env ? process.env[key] : installed[key];
|
|
203
|
+
if (value) env[key] = value;
|
|
146
204
|
}
|
|
205
|
+
// entry.ts prefers PORT, so carrying WORK_APP_PORT forward without this
|
|
206
|
+
// would leave the service on the default port anyway.
|
|
207
|
+
env.PORT = env.WORK_APP_PORT || appPort;
|
|
147
208
|
return env;
|
|
148
209
|
}
|
|
149
210
|
|
|
150
211
|
function installService() {
|
|
151
212
|
const cliPath = fileURLToPath(import.meta.url);
|
|
152
213
|
if (process.platform === "darwin") {
|
|
153
|
-
const plist =
|
|
214
|
+
const plist = serviceFile();
|
|
154
215
|
fs.mkdirSync(path.dirname(plist), { recursive: true });
|
|
155
216
|
fs.mkdirSync(path.join(os.homedir(), "Library/Logs"), { recursive: true });
|
|
156
217
|
const envXml = Object.entries(serviceEnv())
|
|
@@ -164,7 +225,7 @@ function installService() {
|
|
|
164
225
|
<dict>
|
|
165
226
|
<key>Label</key><string>dev.work.app</string>
|
|
166
227
|
<key>ProgramArguments</key>
|
|
167
|
-
<array
|
|
228
|
+
<array>${[...awakePrefix(), process.execPath, cliPath, "start"].map((a) => `<string>${a}</string>`).join("")}</array>
|
|
168
229
|
<key>RunAtLoad</key><true/>
|
|
169
230
|
<key>KeepAlive</key><true/>
|
|
170
231
|
<key>StandardOutPath</key><string>${os.homedir()}/Library/Logs/work.log</string>
|
|
@@ -192,22 +253,31 @@ ${envXml}
|
|
|
192
253
|
}
|
|
193
254
|
|
|
194
255
|
if (process.platform === "linux" && have("systemctl")) {
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
"systemd/user",
|
|
198
|
-
);
|
|
256
|
+
const unitFile = serviceFile();
|
|
257
|
+
const unitDir = path.dirname(unitFile);
|
|
199
258
|
fs.mkdirSync(unitDir, { recursive: true });
|
|
200
259
|
const envLines = Object.entries(serviceEnv())
|
|
201
260
|
.map(([k, v]) => `Environment=${k}=${v}`)
|
|
202
261
|
.join("\n");
|
|
262
|
+
// systemd splits ExecStart on whitespace, so quote the inhibitor's --why.
|
|
263
|
+
const execStart = [...awakePrefix(), process.execPath, cliPath, "start"]
|
|
264
|
+
.map((a) => (a.includes(" ") ? `"${a}"` : a))
|
|
265
|
+
.join(" ");
|
|
203
266
|
fs.writeFileSync(
|
|
204
|
-
|
|
267
|
+
unitFile,
|
|
205
268
|
`[Unit]
|
|
206
269
|
Description=work — agentic dev workspace GUI
|
|
270
|
+
# Keep retrying forever: hitting the default start limit parks the unit in
|
|
271
|
+
# failed state, which is the manual-restart hole we are closing.
|
|
272
|
+
StartLimitIntervalSec=0
|
|
207
273
|
|
|
208
274
|
[Service]
|
|
209
|
-
ExecStart=${
|
|
210
|
-
|
|
275
|
+
ExecStart=${execStart}
|
|
276
|
+
# always, not on-failure: a stray SIGTERM (an agent running \`pkill node\`) or a
|
|
277
|
+
# clean exit looks like success to systemd and leaves the service down until
|
|
278
|
+
# someone notices. Matches launchd's KeepAlive on the macOS side.
|
|
279
|
+
Restart=always
|
|
280
|
+
RestartSec=2
|
|
211
281
|
${envLines}
|
|
212
282
|
|
|
213
283
|
[Install]
|
|
@@ -227,12 +297,12 @@ WantedBy=default.target
|
|
|
227
297
|
warn("no service manager found — start manually with: work start");
|
|
228
298
|
}
|
|
229
299
|
|
|
230
|
-
function maybeTunnel() {
|
|
300
|
+
function maybeTunnel(port = appPort) {
|
|
231
301
|
if (yes || have("cloudflared")) return;
|
|
232
302
|
console.log(`
|
|
233
303
|
To reach work from your phone or other devices, put it behind something
|
|
234
304
|
that terminates TLS and authenticates — e.g. a Cloudflare Tunnel with
|
|
235
305
|
Access (https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/)
|
|
236
|
-
pointing at http://localhost:${
|
|
306
|
+
pointing at http://localhost:${port}, or Tailscale. The server itself has
|
|
237
307
|
no auth of its own.`);
|
|
238
308
|
}
|