thinkpool-pair 0.7.274 → 0.7.275
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/account.mjs +6 -8
- package/package.json +1 -1
- package/service.mjs +12 -15
package/account.mjs
CHANGED
|
@@ -501,12 +501,11 @@ export async function runAccount(SUPABASE_URL, SUPABASE_ANON) {
|
|
|
501
501
|
acct.on('broadcast', { event: 'restart' }, () => {
|
|
502
502
|
restarting = true
|
|
503
503
|
// The dashboard "Restart bridge" button ALSO updates to the newest published version
|
|
504
|
-
// (Max, 2026-07-03).
|
|
505
|
-
//
|
|
506
|
-
//
|
|
507
|
-
//
|
|
508
|
-
//
|
|
509
|
-
// PATH would NOT (the 2026-07-03 gotcha that made a manual updater silently no-op).
|
|
504
|
+
// (Max, 2026-07-03). Use service.mjs's authoritative registry → immutable runtime →
|
|
505
|
+
// one-shot reload transaction directly. Spawning `npx install-service` here used a
|
|
506
|
+
// disposable cache that legacy services could delete underneath the updater. The
|
|
507
|
+
// service primitive arms an independent launchd handoff before this process is booted
|
|
508
|
+
// out, so the reload survives us without a second package execution tree.
|
|
510
509
|
// The reload IS the bounce; sessions resume from disk on the new version. Best-effort:
|
|
511
510
|
// if there's no service or npm is unreachable, we fall through to the plain bounce, so
|
|
512
511
|
// the button is never dead — and even a failed update degrades to today's behaviour.
|
|
@@ -525,8 +524,7 @@ export async function runAccount(SUPABASE_URL, SUPABASE_ANON) {
|
|
|
525
524
|
try {
|
|
526
525
|
const svc = await import('./service.mjs')
|
|
527
526
|
if (svc.serviceActive(null)) {
|
|
528
|
-
|
|
529
|
-
updating = true
|
|
527
|
+
updating = svc.updateService(null) !== false
|
|
530
528
|
}
|
|
531
529
|
} catch { /* no service / spawn failed → plain bounce below */ }
|
|
532
530
|
process.stderr.write(updating
|
package/package.json
CHANGED
package/service.mjs
CHANGED
|
@@ -46,16 +46,12 @@ export function darwinServiceRunning(output) {
|
|
|
46
46
|
const text = String(output || '')
|
|
47
47
|
return /(^|\n)[ \t]*state = running[ \t]*($|\n)/.test(text) && /(^|\n)[ \t]*pid = \d+[ \t]*($|\n)/.test(text)
|
|
48
48
|
}
|
|
49
|
-
// Legacy auto-update services still use npx.
|
|
50
|
-
//
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
// state where `npm view` sees a version but `npx` reports ETARGET or no executable.
|
|
56
|
-
// The whole _npx directory is disposable; clear its children so the next launch is a
|
|
57
|
-
// genuinely clean install.
|
|
58
|
-
const cacheWipe = (home) => `rm -rf ${home}/.npm/_npx/* 2>/dev/null`
|
|
49
|
+
// Legacy auto-update services still use npx. They MUST use a bridge-owned cache:
|
|
50
|
+
// deleting ~/.npm/_npx corrupts unrelated interactive `npx thinkpool-pair` processes
|
|
51
|
+
// (0.7.274 removed account.mjs underneath a live launcher). The service cache is
|
|
52
|
+
// disposable and isolated, so clearing it cannot mutate a person's npm execution tree.
|
|
53
|
+
const serviceNpmCache = () => path.join(os.homedir(), '.thinkpool-pair', 'npm-cache')
|
|
54
|
+
const cacheWipe = (cacheRoot) => `rm -rf ${shq(path.join(cacheRoot, '_npx'))}/* 2>/dev/null`
|
|
59
55
|
|
|
60
56
|
// The version installing the service. By DEFAULT the service is pinned to this exact
|
|
61
57
|
// version (not @latest) so a future bad npm publish can't auto-roll to every machine's
|
|
@@ -130,6 +126,7 @@ export function buildArtifact(platform, { room = null, cmdArgs = [], autoUpdate
|
|
|
130
126
|
const logDir = path.join(os.homedir(), '.thinkpool-pair')
|
|
131
127
|
const log = path.join(logDir, `${id}.log`)
|
|
132
128
|
const servicePath = sanitizeServicePath(process.env.PATH || '', platform)
|
|
129
|
+
const npmCache = serviceNpmCache()
|
|
133
130
|
const tail = cmdArgs.length ? ['--', ...cmdArgs] : []
|
|
134
131
|
const desc = room ? `bridge (${room})` : 'account bridge'
|
|
135
132
|
// OS-supervised tiers (launchd KeepAlive / systemd Restart) don't need --supervise.
|
|
@@ -156,7 +153,7 @@ export function buildArtifact(platform, { room = null, cmdArgs = [], autoUpdate
|
|
|
156
153
|
const args = runtimeEntry
|
|
157
154
|
? [process.execPath, runtimeEntry, ...(room ? [room] : []), ...tail]
|
|
158
155
|
: staleProof
|
|
159
|
-
? ['/bin/bash', '-lc', `${cacheWipe(
|
|
156
|
+
? ['/bin/bash', '-lc', `${cacheWipe(npmCache)}; export NPM_CONFIG_CACHE=${shq(npmCache)}; exec ${[npx, ...pkgArgs, ...tail].map(shq).join(' ')}`]
|
|
160
157
|
: [npx, ...pkgArgs, ...tail]
|
|
161
158
|
const file = path.join(os.homedir(), 'Library', 'LaunchAgents', `${label(room)}.plist`)
|
|
162
159
|
const content = `<?xml version="1.0" encoding="UTF-8"?>
|
|
@@ -175,7 +172,7 @@ export function buildArtifact(platform, { room = null, cmdArgs = [], autoUpdate
|
|
|
175
172
|
<key>WorkingDirectory</key><string>${xml(cwd)}</string>
|
|
176
173
|
<key>StandardOutPath</key><string>${xml(log)}</string>
|
|
177
174
|
<key>StandardErrorPath</key><string>${xml(log)}</string>
|
|
178
|
-
<key>EnvironmentVariables</key><dict><key>PATH</key><string>${xml(servicePath)}</string>${autoUpdate ? '<key>THINKPOOL_PAIR_AUTOUPDATE</key><string>1</string>' : ''}</dict>
|
|
175
|
+
<key>EnvironmentVariables</key><dict><key>PATH</key><string>${xml(servicePath)}</string>${runtimeEntry ? '' : `<key>NPM_CONFIG_CACHE</key><string>${xml(npmCache)}</string>`}${autoUpdate ? '<key>THINKPOOL_PAIR_AUTOUPDATE</key><string>1</string>' : ''}</dict>
|
|
179
176
|
</dict></plist>\n`
|
|
180
177
|
// The destructive reload is intentionally NOT represented as an inline `post`
|
|
181
178
|
// command. installService stages this plist and hands the transaction to an
|
|
@@ -193,7 +190,7 @@ export function buildArtifact(platform, { room = null, cmdArgs = [], autoUpdate
|
|
|
193
190
|
const execStart = runtimeEntry
|
|
194
191
|
? args.map((a) => `'${a.replace(/'/g, "'\\''")}'`).join(' ')
|
|
195
192
|
: staleProof
|
|
196
|
-
? `/bin/bash -lc "${cacheWipe(
|
|
193
|
+
? `/bin/bash -lc "${cacheWipe(npmCache)}; export NPM_CONFIG_CACHE=${shq(npmCache)}; exec ${[npx, ...pkgArgs, ...tail].join(' ')}"`
|
|
197
194
|
: args.map((a) => `'${a.replace(/'/g, "'\\''")}'`).join(' ')
|
|
198
195
|
const content = `[Unit]
|
|
199
196
|
Description=ThinkPool Code ${desc}
|
|
@@ -211,7 +208,7 @@ RestartSec=2
|
|
|
211
208
|
RestartPreventExitStatus=0
|
|
212
209
|
WorkingDirectory=${cwd}
|
|
213
210
|
Environment=PATH=${servicePath}
|
|
214
|
-
${autoUpdate ? 'Environment=THINKPOOL_PAIR_AUTOUPDATE=1\n' : ''}StandardOutput=append:${log}
|
|
211
|
+
${runtimeEntry ? '' : `Environment=NPM_CONFIG_CACHE=${npmCache}\n`}${autoUpdate ? 'Environment=THINKPOOL_PAIR_AUTOUPDATE=1\n' : ''}StandardOutput=append:${log}
|
|
215
212
|
StandardError=append:${log}
|
|
216
213
|
|
|
217
214
|
[Install]
|
|
@@ -232,7 +229,7 @@ WantedBy=default.target
|
|
|
232
229
|
: room
|
|
233
230
|
? ['npx', '-y', ...onlineFlag, verSpec, room, '--supervise', ...tail].join(' ')
|
|
234
231
|
: ['npx', '-y', ...onlineFlag, verSpec].join(' ')
|
|
235
|
-
const content = `@echo off\r\ntitle thinkpool-pair ${id}\r\n${inner}\r\n`
|
|
232
|
+
const content = `@echo off\r\ntitle thinkpool-pair ${id}\r\n${runtimeEntry ? '' : `set "NPM_CONFIG_CACHE=${npmCache}"\r\n`}${inner}\r\n`
|
|
236
233
|
return { file, content, logDir, post: [], note: 'Installed to the Startup folder — runs at login' + (room ? ' with --supervise (auto-restart on crash).' : ' (account mode).') + ' Start it now without rebooting by double-clicking the .cmd, or run it from a terminal.' }
|
|
237
234
|
}
|
|
238
235
|
|