unsnooze 1.4.0 → 1.5.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.5.0 — 2026-07-12
4
+
5
+ - **`unsnooze update`**: one command to update unsnooze itself — runs
6
+ `npm install -g unsnooze@latest` and immediately prints the new version's
7
+ changelog. Update notices and the daemon toast now say `run: unsnooze
8
+ update` instead of the raw npm command.
9
+
3
10
  ## 1.4.0 — 2026-07-12
4
11
 
5
12
  - **Update notices**: unsnooze now checks the npm registry (at most once a
package/README.md CHANGED
@@ -133,6 +133,7 @@ unsnooze message <id> "text" # per-session wake message (--clear to reset)
133
133
  unsnooze config list # settings (see below)
134
134
  unsnooze config set <k> <v> # e.g. autoResume off
135
135
  unsnooze logs [-f] # what unsnooze has been doing
136
+ unsnooze update # update unsnooze itself
136
137
  unsnooze daemon # persistent GUI-session watcher (usually run
137
138
  # by launchd/systemd via `install --daemon`)
138
139
  unsnooze report [agent] # capture a pane to report an undetected banner
@@ -226,7 +227,7 @@ verifies the limit actually lifted. It replaces the 4am alarm, not the limit.
226
227
 
227
228
  ### How do I update, and how do I know when to?
228
229
 
229
- `npm i -g unsnooze`. unsnooze checks the npm registry at most once a day and
230
+ `unsnooze update` (or `npm i -g unsnooze`). unsnooze checks the npm registry at most once a day and
230
231
  tells you when a newer version exists (a line after CLI commands, plus one
231
232
  desktop notification per version); after updating, the next command shows a
232
233
  short "what's new" from the changelog. It's a plain registry GET with nothing
package/bin/unsnooze.js CHANGED
@@ -82,6 +82,10 @@ async function main() {
82
82
  const { runResumer } = await import('../src/resumer.js');
83
83
  return runResumer();
84
84
  }
85
+ case 'update': {
86
+ const { runSelfUpdate } = await import('../src/update-check.js');
87
+ return runSelfUpdate();
88
+ }
85
89
  case '_update-check': {
86
90
  const { runUpdateCheck } = await import('../src/update-check.js');
87
91
  return runUpdateCheck();
@@ -116,6 +120,7 @@ Usage:
116
120
  unsnooze cancel [id|--all] stop tracking session(s)
117
121
  unsnooze message <id|--all> <t> set a per-session wake message (--clear to reset)
118
122
  unsnooze logs [-f] show (or follow) the unsnooze log
123
+ unsnooze update update unsnooze itself to the latest version
119
124
  unsnooze daemon persistent watcher for GUI sessions (VS Code
120
125
  extension, desktop apps) — no tmux needed to
121
126
  detect; revival still opens in tmux
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "unsnooze",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "description": "Auto-resume Claude Code, Codex CLI & Grok sessions in tmux when the usage limit (5-hour or weekly) resets. Wakes every limit-stopped AI coding session automatically.",
5
5
  "keywords": [
6
6
  "claude",
@@ -8,6 +8,7 @@
8
8
  // The check is a plain GET to registry.npmjs.org — nothing identifying.
9
9
 
10
10
  import { readFileSync, writeFileSync, renameSync, mkdirSync } from 'node:fs';
11
+ import { spawnSync } from 'node:child_process';
11
12
  import { join, dirname } from 'node:path';
12
13
  import { fileURLToPath } from 'node:url';
13
14
  import { getConfig } from './settings.js';
@@ -75,7 +76,7 @@ export function updateNotice(pkgVersion = PKG_VERSION) {
75
76
  if (!getConfig('updateCheck')) return null;
76
77
  const { latest } = readCache();
77
78
  if (!latest || !isNewer(latest, pkgVersion)) return null;
78
- return `unsnooze ${latest} is available (you have ${pkgVersion}) — npm i -g unsnooze · ${RELEASES_URL}`;
79
+ return `unsnooze ${latest} is available (you have ${pkgVersion}) — run: unsnooze update · ${RELEASES_URL}`;
79
80
  }
80
81
 
81
82
  // The "## <version>" block from the CHANGELOG.md that ships in the tarball.
@@ -113,8 +114,35 @@ export async function runUpdateCheck({ fetcher, notifier = notify, now = Date.no
113
114
  if (!latest) return 0;
114
115
  const cache = writeCache({ lastCheckedAt: now, latest });
115
116
  if (isNewer(latest, PKG_VERSION) && cache.notifiedVersion !== latest) {
116
- notifier('unsnooze update available', `${latest} is out (you have ${PKG_VERSION}) — npm i -g unsnooze`);
117
+ notifier('unsnooze update available', `${latest} is out (you have ${PKG_VERSION}) — run: unsnooze update`);
117
118
  writeCache({ notifiedVersion: latest });
118
119
  }
119
120
  return 0;
120
121
  }
122
+
123
+ // `unsnooze update` — self-update via npm, then show what changed. npm -g
124
+ // overwrites this install in place, so re-reading package.json/CHANGELOG.md
125
+ // after a successful install yields the NEW version's info.
126
+ export function runSelfUpdate({ runner = spawnSync, print = console.log } = {}) {
127
+ print(`unsnooze ${PKG_VERSION} — updating via npm install -g unsnooze@latest …`);
128
+ const r = runner('npm', ['install', '-g', 'unsnooze@latest'], { stdio: 'inherit' });
129
+ if (r.error || r.status !== 0) {
130
+ print(`unsnooze: update failed (${r.error ? r.error.message : `npm exited ${r.status}`}).`);
131
+ print('unsnooze: try it manually: npm install -g unsnooze@latest');
132
+ print('unsnooze: (permission errors usually mean your npm prefix needs sudo or a user-writable prefix)');
133
+ return r.status || 1;
134
+ }
135
+ let newVersion = PKG_VERSION;
136
+ try {
137
+ newVersion = JSON.parse(readFileSync(join(ROOT, 'package.json'), 'utf-8')).version;
138
+ } catch { /* moved install dir — the generic message below still holds */ }
139
+ if (newVersion === PKG_VERSION) {
140
+ print(`unsnooze: already up to date (${PKG_VERSION}).`);
141
+ } else {
142
+ const section = changelogSection(newVersion);
143
+ print(`unsnooze: updated to ${newVersion}.${section ? ` What's new:\n${section}` : ''}`);
144
+ }
145
+ // Don't repeat "what's new" on the next command.
146
+ writeCache({ lastRunVersion: newVersion });
147
+ return 0;
148
+ }