github-search-cli 9.2.1 → 9.4.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.
@@ -6,10 +6,15 @@
6
6
  */
7
7
  import { readJSON, writeJSON, debugLog } from "./storage";
8
8
  import { stateDir } from "./config";
9
+ import { readFileSync } from "fs";
10
+ import { join, dirname } from "path";
11
+ import { fileURLToPath } from "url";
9
12
 
10
13
  const REGISTRY_URL = "https://registry.npmjs.org/github-search-cli/latest";
11
14
  const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24 hours
12
15
  const REQUEST_TIMEOUT_MS = 5000;
16
+ const __dirname = dirname(fileURLToPath(import.meta.url));
17
+ const PKG_DIR = join(__dirname, "..");
13
18
 
14
19
  export interface UpdateState {
15
20
  /** Timestamp of last successful check. */
@@ -20,6 +25,8 @@ export interface UpdateState {
20
25
  suppressed: boolean;
21
26
  /** Latest version found on last check (for display). */
22
27
  latestVersion?: string;
28
+ /** Version at time of last successful install (populated before performUpdate). */
29
+ lastInstalledVersion?: string;
23
30
  }
24
31
 
25
32
  const STATE_FILE = "update-state.json";
@@ -160,3 +167,49 @@ export async function performUpdate(): Promise<boolean> {
160
167
  return false;
161
168
  }
162
169
  }
170
+
171
+
172
+ /**
173
+ * Record the current version as "last installed" before performing an update.
174
+ * This lets the post-upgrade startup detect the version change and show notes.
175
+ */
176
+ export function recordPreUpdateState(currentVersion: string): void {
177
+ writeUpdateState({
178
+ ...readUpdateState(),
179
+ lastInstalledVersion: currentVersion,
180
+ });
181
+ }
182
+
183
+ /**
184
+ * Fetch release notes for a given version.
185
+ * Tries release-notes/<version>.md first, then falls back to CHANGELOG.md section.
186
+ * Returns the markdown text or null if not found.
187
+ */
188
+ export function fetchReleaseNotes(version: string): string | null {
189
+ // ponytail: embedded notes are the primary source — they ship in the tarball, no network
190
+ try {
191
+ const notesPath = join(PKG_DIR, "release-notes", `${version}.md`);
192
+ const md = readFileSync(notesPath, "utf-8");
193
+ if (md.trim().length > 0) return md;
194
+ } catch {
195
+ // File doesn't exist for this version — fall through to CHANGELOG
196
+ }
197
+
198
+ // ponytail: CHANGELOG.md fallback — parse section for this version
199
+ try {
200
+ const changelogPath = join(PKG_DIR, "CHANGELOG.md");
201
+ const changelog = readFileSync(changelogPath, "utf-8");
202
+ // ponytail: find "## [version]" header, slice until next "## "
203
+ const header = "## [" + version + "]";
204
+ const start = changelog.indexOf(header);
205
+ if (start === -1) return null;
206
+ const bodyStart = start + header.length;
207
+ const rest = changelog.substring(bodyStart);
208
+ const nextHeaderIdx = rest.indexOf("\n## ");
209
+ const end = nextHeaderIdx === -1 ? changelog.length : bodyStart + nextHeaderIdx;
210
+ return changelog.substring(bodyStart, end).trim();
211
+ } catch {
212
+ // CHANGELOG.md doesn't exist either
213
+ }
214
+ return null;
215
+ }