@kenkaiiii/gg-boss 4.8.0 → 4.8.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.
@@ -74730,7 +74730,9 @@ var SettingsSchema = external_exports.object({
74730
74730
  ]).default("auto"),
74731
74731
  showTokenUsage: external_exports.boolean().default(true),
74732
74732
  idealReviewEnabled: external_exports.boolean().default(true),
74733
- enabledTools: external_exports.array(external_exports.string()).optional()
74733
+ enabledTools: external_exports.array(external_exports.string()).optional(),
74734
+ /** Delete session transcripts older than this many days at startup. 0 disables pruning. */
74735
+ sessionRetentionDays: external_exports.number().int().min(0).default(30)
74734
74736
  });
74735
74737
  var DEFAULT_SETTINGS = {
74736
74738
  autoCompact: true,
@@ -74740,7 +74742,8 @@ var DEFAULT_SETTINGS = {
74740
74742
  thinkingEnabled: false,
74741
74743
  theme: "auto",
74742
74744
  showTokenUsage: true,
74743
- idealReviewEnabled: true
74745
+ idealReviewEnabled: true,
74746
+ sessionRetentionDays: 30
74744
74747
  };
74745
74748
  var SettingsManager = class {
74746
74749
  settings = { ...DEFAULT_SETTINGS };
@@ -74792,9 +74795,29 @@ function encodeCwd(cwd2) {
74792
74795
  }
74793
74796
  var SessionManager = class _SessionManager {
74794
74797
  sessionsDir;
74798
+ warnedPersistCodes = /* @__PURE__ */ new Set();
74799
+ /** Called once per error code when session persistence fails (e.g. ENOSPC). */
74800
+ onPersistError;
74795
74801
  constructor(sessionsDir) {
74796
74802
  this.sessionsDir = sessionsDir;
74797
74803
  }
74804
+ /**
74805
+ * Session persistence must never crash a live session. Disk-full (ENOSPC),
74806
+ * permission, or quota errors during transcript writes are reported once
74807
+ * per error code and otherwise swallowed — the in-memory session keeps going.
74808
+ */
74809
+ handlePersistError(error51, op) {
74810
+ const err = error51;
74811
+ const code = err?.code ?? "UNKNOWN";
74812
+ if (this.warnedPersistCodes.has(code))
74813
+ return;
74814
+ this.warnedPersistCodes.add(code);
74815
+ log("WARN", "session", `Session persistence failed (${op}); continuing without saving`, {
74816
+ code,
74817
+ message: err?.message ?? String(error51)
74818
+ });
74819
+ this.onPersistError?.(err);
74820
+ }
74798
74821
  dirForCwd(cwd2) {
74799
74822
  return path27.join(this.sessionsDir, encodeCwd(cwd2));
74800
74823
  }
@@ -74923,10 +74946,76 @@ var SessionManager = class _SessionManager {
74923
74946
  const sessions = await this.list(cwd2);
74924
74947
  return sessions.find((session) => session.id === sessionId2)?.path ?? null;
74925
74948
  }
74949
+ /**
74950
+ * Delete session files older than `maxAgeDays` across ALL project dirs.
74951
+ * Age is judged by file mtime, so a session that's still being appended to
74952
+ * is never considered old. Best-effort: per-file errors are skipped so a
74953
+ * locked or vanished file can't break startup. Empty project dirs left
74954
+ * behind are removed. Returns what was freed for logging.
74955
+ */
74956
+ async pruneOldSessions(options) {
74957
+ const result = { deletedFiles: 0, freedBytes: 0 };
74958
+ if (options.maxAgeDays <= 0)
74959
+ return result;
74960
+ const cutoffMs = Date.now() - options.maxAgeDays * 864e5;
74961
+ const keep = new Set((options.keepPaths ?? []).map((p) => path27.resolve(p)));
74962
+ let cwdDirs;
74963
+ try {
74964
+ cwdDirs = await fs23.readdir(this.sessionsDir);
74965
+ } catch {
74966
+ return result;
74967
+ }
74968
+ for (const dirName of cwdDirs) {
74969
+ const dir = path27.join(this.sessionsDir, dirName);
74970
+ let files;
74971
+ try {
74972
+ const stat = await fs23.stat(dir);
74973
+ if (!stat.isDirectory())
74974
+ continue;
74975
+ files = await fs23.readdir(dir);
74976
+ } catch {
74977
+ continue;
74978
+ }
74979
+ let remaining = files.length;
74980
+ for (const file2 of files) {
74981
+ if (!file2.endsWith(".jsonl"))
74982
+ continue;
74983
+ const filePath = path27.join(dir, file2);
74984
+ if (keep.has(path27.resolve(filePath)))
74985
+ continue;
74986
+ try {
74987
+ const stat = await fs23.stat(filePath);
74988
+ if (stat.mtimeMs >= cutoffMs)
74989
+ continue;
74990
+ await fs23.unlink(filePath);
74991
+ result.deletedFiles += 1;
74992
+ result.freedBytes += stat.size;
74993
+ remaining -= 1;
74994
+ } catch {
74995
+ }
74996
+ }
74997
+ if (remaining === 0) {
74998
+ await fs23.rmdir(dir).catch(() => {
74999
+ });
75000
+ }
75001
+ }
75002
+ return result;
75003
+ }
74926
75004
  async appendEntry(sessionPath, entry) {
74927
- await fs23.appendFile(sessionPath, JSON.stringify(entry) + "\n", "utf-8");
75005
+ try {
75006
+ await fs23.appendFile(sessionPath, JSON.stringify(entry) + "\n", "utf-8");
75007
+ } catch (error51) {
75008
+ this.handlePersistError(error51, "appendEntry");
75009
+ }
74928
75010
  }
74929
75011
  async updateLeaf(sessionPath, leafId) {
75012
+ try {
75013
+ await this.updateLeafUnsafe(sessionPath, leafId);
75014
+ } catch (error51) {
75015
+ this.handlePersistError(error51, "updateLeaf");
75016
+ }
75017
+ }
75018
+ async updateLeafUnsafe(sessionPath, leafId) {
74930
75019
  const fd2 = await fs23.open(sessionPath, "r+");
74931
75020
  try {
74932
75021
  const buf = Buffer.alloc(4096);
@@ -114607,4 +114696,4 @@ react/cjs/react-jsx-runtime.development.js:
114607
114696
  * LICENSE file in the root directory of this source tree.
114608
114697
  *)
114609
114698
  */
114610
- //# sourceMappingURL=chunk-JZC6MVWQ.js.map
114699
+ //# sourceMappingURL=chunk-HRWFW5HH.js.map