@oss-autopilot/core 3.3.0 → 3.4.1

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.
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * State persistence layer for the OSS Contribution Agent.
3
- * Handles file I/O, locking, backup/restore, and schema migration (v1→v2→v3).
3
+ * Handles file I/O, locking, backup/restore, and schema migration (v1→v2→v3→v4).
4
4
  * No module-level mutable state — functions accept/return AgentState objects.
5
5
  */
6
6
  import * as fs from 'node:fs';
@@ -170,7 +170,7 @@ export function migrateV3ToV4(rawState) {
170
170
  return rawState;
171
171
  }
172
172
  /**
173
- * Create a fresh state (v3).
173
+ * Create a fresh state (v4).
174
174
  * Leverages Zod schema defaults to produce a complete state.
175
175
  */
176
176
  export function createFreshState() {
@@ -275,7 +275,7 @@ function tryRestoreFromBackup() {
275
275
  try {
276
276
  const data = fs.readFileSync(backupPath, 'utf8');
277
277
  let raw = JSON.parse(data);
278
- // Chain migrations: v1 → v2 → v3
278
+ // Chain migrations: v1 → v2 → v3 → v4
279
279
  if (typeof raw === 'object' && raw !== null) {
280
280
  const rawObj = raw;
281
281
  if (rawObj.version === 1) {
@@ -306,8 +306,11 @@ function tryRestoreFromBackup() {
306
306
  debug(MODULE, `Backup ${backupFile} full validation errors:`, parsed.error.issues);
307
307
  }
308
308
  catch (backupErr) {
309
- // This backup is also corrupted, try the next one
310
- warn(MODULE, `Backup ${backupFile} is corrupted, trying next...`);
309
+ // This backup is also corrupted, try the next one. Include the error
310
+ // message in the warn so non-DEBUG users can diagnose without enabling
311
+ // DEBUG=1 (#1209 L7); the full stack still goes to debug.
312
+ const msg = backupErr instanceof Error ? backupErr.message : String(backupErr);
313
+ warn(MODULE, `Backup ${backupFile} is corrupted (${msg}), trying next...`);
311
314
  debug(MODULE, `Backup ${backupFile} parse failed`, backupErr);
312
315
  }
313
316
  }
@@ -45,18 +45,22 @@ export const StoredMergedPRSchema = z.object({
45
45
  title: z.string(),
46
46
  mergedAt: z.string(),
47
47
  /** When the raw review-comment bundle for this PR was last fetched (#867). */
48
- commentsFetchedAt: z.string().optional(),
48
+ // ISO-8601 datetime guards against `markPRCommentsFetched(url, "garbage")`
49
+ // poisoning state through the stamping API (#1209 L4).
50
+ commentsFetchedAt: z.string().datetime().optional(),
49
51
  /** When the host last ran LLM extraction over this PR's comment bundle (#867). */
50
- learningsExtractedAt: z.string().optional(),
52
+ learningsExtractedAt: z.string().datetime().optional(),
51
53
  });
52
54
  export const StoredClosedPRSchema = z.object({
53
55
  url: z.string(),
54
56
  title: z.string(),
55
57
  closedAt: z.string(),
56
58
  /** When the raw review-comment bundle for this PR was last fetched (#867). */
57
- commentsFetchedAt: z.string().optional(),
59
+ // ISO-8601 datetime guards against `markPRCommentsFetched(url, "garbage")`
60
+ // poisoning state through the stamping API (#1209 L4).
61
+ commentsFetchedAt: z.string().datetime().optional(),
58
62
  /** When the host last ran LLM extraction over this PR's comment bundle (#867). */
59
- learningsExtractedAt: z.string().optional(),
63
+ learningsExtractedAt: z.string().datetime().optional(),
60
64
  });
61
65
  export const AnalyzedIssueConversationSchema = z.object({
62
66
  url: z.string(),
@@ -345,7 +345,11 @@ export class StateManager {
345
345
  async refreshFromGist() {
346
346
  if (!this.gistStore)
347
347
  return false;
348
- const refreshed = await this.gistStore.refreshFromGist();
348
+ const result = await this.gistStore.refreshFromGist();
349
+ // StateManager keeps its boolean shape (callers rely on truthy-check
350
+ // semantics) but consults the discriminated union internally to know
351
+ // whether to reload state.json from the now-fresh cache (#1209 L9).
352
+ const refreshed = result.status === 'refreshed';
349
353
  if (refreshed) {
350
354
  const raw = this.gistStore.cachedFiles.get('state.json');
351
355
  if (!raw) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oss-autopilot/core",
3
- "version": "3.3.0",
3
+ "version": "3.4.1",
4
4
  "description": "CLI and core library for managing open source contributions",
5
5
  "type": "module",
6
6
  "bin": {
@@ -54,9 +54,9 @@
54
54
  "dependencies": {
55
55
  "@octokit/plugin-throttling": "^11.0.3",
56
56
  "@octokit/rest": "^22.0.1",
57
- "@oss-scout/core": "^0.7.1",
57
+ "@oss-scout/core": "^0.8.0",
58
58
  "commander": "^14.0.3",
59
- "zod": "^4.3.6"
59
+ "zod": "^4.4.3"
60
60
  },
61
61
  "devDependencies": {
62
62
  "@types/node": "^25.6.0",