crewly 1.20.358 → 1.20.360

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.
Files changed (137) hide show
  1. package/config/roles/developer/prompt.md +3 -1
  2. package/config/skills/registry.json +125 -1
  3. package/dist/backend/backend/src/constants.d.ts +189 -2
  4. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  5. package/dist/backend/backend/src/constants.js +200 -3
  6. package/dist/backend/backend/src/constants.js.map +1 -1
  7. package/dist/backend/backend/src/index.d.ts +58 -0
  8. package/dist/backend/backend/src/index.d.ts.map +1 -1
  9. package/dist/backend/backend/src/index.js +263 -19
  10. package/dist/backend/backend/src/index.js.map +1 -1
  11. package/dist/backend/backend/src/services/agent/boot-pressure.d.ts +147 -0
  12. package/dist/backend/backend/src/services/agent/boot-pressure.d.ts.map +1 -0
  13. package/dist/backend/backend/src/services/agent/boot-pressure.js +212 -0
  14. package/dist/backend/backend/src/services/agent/boot-pressure.js.map +1 -0
  15. package/dist/backend/backend/src/services/agent/restore-queue.d.ts +50 -1
  16. package/dist/backend/backend/src/services/agent/restore-queue.d.ts.map +1 -1
  17. package/dist/backend/backend/src/services/agent/restore-queue.js +100 -5
  18. package/dist/backend/backend/src/services/agent/restore-queue.js.map +1 -1
  19. package/dist/backend/backend/src/services/memory/agent-memory-refresh.service.d.ts +11 -0
  20. package/dist/backend/backend/src/services/memory/agent-memory-refresh.service.d.ts.map +1 -1
  21. package/dist/backend/backend/src/services/memory/agent-memory-refresh.service.js +28 -2
  22. package/dist/backend/backend/src/services/memory/agent-memory-refresh.service.js.map +1 -1
  23. package/dist/backend/backend/src/services/memory/startup-briefing.service.d.ts +10 -0
  24. package/dist/backend/backend/src/services/memory/startup-briefing.service.d.ts.map +1 -1
  25. package/dist/backend/backend/src/services/memory/startup-briefing.service.js +65 -22
  26. package/dist/backend/backend/src/services/memory/startup-briefing.service.js.map +1 -1
  27. package/dist/backend/backend/src/services/messaging/deferred-start-retry.d.ts +8 -0
  28. package/dist/backend/backend/src/services/messaging/deferred-start-retry.d.ts.map +1 -1
  29. package/dist/backend/backend/src/services/messaging/deferred-start-retry.js +8 -0
  30. package/dist/backend/backend/src/services/messaging/deferred-start-retry.js.map +1 -1
  31. package/dist/backend/backend/src/services/session/session-binding.d.ts +25 -2
  32. package/dist/backend/backend/src/services/session/session-binding.d.ts.map +1 -1
  33. package/dist/backend/backend/src/services/session/session-binding.js +32 -4
  34. package/dist/backend/backend/src/services/session/session-binding.js.map +1 -1
  35. package/dist/backend/backend/src/services/wiki/wiki-ingest.service.d.ts +3 -1
  36. package/dist/backend/backend/src/services/wiki/wiki-ingest.service.d.ts.map +1 -1
  37. package/dist/backend/backend/src/services/wiki/wiki-ingest.service.js.map +1 -1
  38. package/dist/backend/backend/src/services/wiki/wiki-log-compile.service.d.ts +27 -2
  39. package/dist/backend/backend/src/services/wiki/wiki-log-compile.service.d.ts.map +1 -1
  40. package/dist/backend/backend/src/services/wiki/wiki-log-compile.service.js +105 -8
  41. package/dist/backend/backend/src/services/wiki/wiki-log-compile.service.js.map +1 -1
  42. package/dist/backend/backend/src/services/wiki/wiki-log-entries.d.ts +7 -0
  43. package/dist/backend/backend/src/services/wiki/wiki-log-entries.d.ts.map +1 -1
  44. package/dist/backend/backend/src/services/wiki/wiki-log-entries.js +10 -0
  45. package/dist/backend/backend/src/services/wiki/wiki-log-entries.js.map +1 -1
  46. package/dist/backend/backend/src/services/wiki/wiki-log-rotation.service.d.ts +24 -0
  47. package/dist/backend/backend/src/services/wiki/wiki-log-rotation.service.d.ts.map +1 -1
  48. package/dist/backend/backend/src/services/wiki/wiki-log-rotation.service.js +75 -9
  49. package/dist/backend/backend/src/services/wiki/wiki-log-rotation.service.js.map +1 -1
  50. package/dist/backend/backend/src/services/wiki/wiki-maintenance.service.d.ts +19 -0
  51. package/dist/backend/backend/src/services/wiki/wiki-maintenance.service.d.ts.map +1 -1
  52. package/dist/backend/backend/src/services/wiki/wiki-maintenance.service.js +23 -2
  53. package/dist/backend/backend/src/services/wiki/wiki-maintenance.service.js.map +1 -1
  54. package/dist/backend/backend/src/services/wiki/work-record-transcript.d.ts +64 -0
  55. package/dist/backend/backend/src/services/wiki/work-record-transcript.d.ts.map +1 -0
  56. package/dist/backend/backend/src/services/wiki/work-record-transcript.js +194 -0
  57. package/dist/backend/backend/src/services/wiki/work-record-transcript.js.map +1 -0
  58. package/dist/backend/backend/src/services/wiki/work-record.d.ts +239 -0
  59. package/dist/backend/backend/src/services/wiki/work-record.d.ts.map +1 -0
  60. package/dist/backend/backend/src/services/wiki/work-record.js +631 -0
  61. package/dist/backend/backend/src/services/wiki/work-record.js.map +1 -0
  62. package/dist/backend/backend/src/services/wiki/work-record.service.d.ts +231 -0
  63. package/dist/backend/backend/src/services/wiki/work-record.service.d.ts.map +1 -0
  64. package/dist/backend/backend/src/services/wiki/work-record.service.js +542 -0
  65. package/dist/backend/backend/src/services/wiki/work-record.service.js.map +1 -0
  66. package/dist/backend/backend/src/services/worktree/low-disk-guard.d.ts +92 -8
  67. package/dist/backend/backend/src/services/worktree/low-disk-guard.d.ts.map +1 -1
  68. package/dist/backend/backend/src/services/worktree/low-disk-guard.js +98 -14
  69. package/dist/backend/backend/src/services/worktree/low-disk-guard.js.map +1 -1
  70. package/dist/backend/backend/src/services/worktree/tmp-janitor.d.ts +138 -0
  71. package/dist/backend/backend/src/services/worktree/tmp-janitor.d.ts.map +1 -0
  72. package/dist/backend/backend/src/services/worktree/tmp-janitor.js +199 -0
  73. package/dist/backend/backend/src/services/worktree/tmp-janitor.js.map +1 -0
  74. package/dist/backend/backend/src/services/worktree/transcript-janitor.d.ts +154 -0
  75. package/dist/backend/backend/src/services/worktree/transcript-janitor.d.ts.map +1 -0
  76. package/dist/backend/backend/src/services/worktree/transcript-janitor.js +357 -0
  77. package/dist/backend/backend/src/services/worktree/transcript-janitor.js.map +1 -0
  78. package/dist/backend/backend/src/services/worktree/workitem-worktree.service.d.ts.map +1 -1
  79. package/dist/backend/backend/src/services/worktree/workitem-worktree.service.js +7 -2
  80. package/dist/backend/backend/src/services/worktree/workitem-worktree.service.js.map +1 -1
  81. package/dist/backend/backend/src/services/worktree/worktree-dirty.d.ts +16 -4
  82. package/dist/backend/backend/src/services/worktree/worktree-dirty.d.ts.map +1 -1
  83. package/dist/backend/backend/src/services/worktree/worktree-dirty.js +21 -5
  84. package/dist/backend/backend/src/services/worktree/worktree-dirty.js.map +1 -1
  85. package/dist/backend/backend/src/services/worktree/worktree-git.d.ts +18 -0
  86. package/dist/backend/backend/src/services/worktree/worktree-git.d.ts.map +1 -1
  87. package/dist/backend/backend/src/services/worktree/worktree-git.js +60 -0
  88. package/dist/backend/backend/src/services/worktree/worktree-git.js.map +1 -1
  89. package/dist/backend/backend/src/services/worktree/worktree-janitor.service.d.ts +164 -25
  90. package/dist/backend/backend/src/services/worktree/worktree-janitor.service.d.ts.map +1 -1
  91. package/dist/backend/backend/src/services/worktree/worktree-janitor.service.js +494 -55
  92. package/dist/backend/backend/src/services/worktree/worktree-janitor.service.js.map +1 -1
  93. package/dist/backend/backend/src/services/worktree/worktree-tiers.d.ts +186 -0
  94. package/dist/backend/backend/src/services/worktree/worktree-tiers.d.ts.map +1 -0
  95. package/dist/backend/backend/src/services/worktree/worktree-tiers.js +279 -0
  96. package/dist/backend/backend/src/services/worktree/worktree-tiers.js.map +1 -0
  97. package/dist/backend/build-info.json +2 -2
  98. package/dist/cli/backend/src/constants.d.ts +189 -2
  99. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  100. package/dist/cli/backend/src/constants.js +200 -3
  101. package/dist/cli/backend/src/constants.js.map +1 -1
  102. package/dist/cli/backend/src/services/agent/boot-pressure.d.ts +147 -0
  103. package/dist/cli/backend/src/services/agent/boot-pressure.d.ts.map +1 -0
  104. package/dist/cli/backend/src/services/agent/boot-pressure.js +212 -0
  105. package/dist/cli/backend/src/services/agent/boot-pressure.js.map +1 -0
  106. package/dist/cli/backend/src/services/agent/restore-queue.d.ts +50 -1
  107. package/dist/cli/backend/src/services/agent/restore-queue.d.ts.map +1 -1
  108. package/dist/cli/backend/src/services/agent/restore-queue.js +100 -5
  109. package/dist/cli/backend/src/services/agent/restore-queue.js.map +1 -1
  110. package/dist/cli/backend/src/services/memory/startup-briefing.service.d.ts +10 -0
  111. package/dist/cli/backend/src/services/memory/startup-briefing.service.d.ts.map +1 -1
  112. package/dist/cli/backend/src/services/memory/startup-briefing.service.js +65 -22
  113. package/dist/cli/backend/src/services/memory/startup-briefing.service.js.map +1 -1
  114. package/dist/cli/backend/src/services/wiki/wiki-ingest.service.d.ts +3 -1
  115. package/dist/cli/backend/src/services/wiki/wiki-ingest.service.d.ts.map +1 -1
  116. package/dist/cli/backend/src/services/wiki/wiki-ingest.service.js.map +1 -1
  117. package/dist/cli/backend/src/services/wiki/wiki-log-entries.d.ts +7 -0
  118. package/dist/cli/backend/src/services/wiki/wiki-log-entries.d.ts.map +1 -1
  119. package/dist/cli/backend/src/services/wiki/wiki-log-entries.js +10 -0
  120. package/dist/cli/backend/src/services/wiki/wiki-log-entries.js.map +1 -1
  121. package/dist/cli/backend/src/services/wiki/work-record-transcript.d.ts +64 -0
  122. package/dist/cli/backend/src/services/wiki/work-record-transcript.d.ts.map +1 -0
  123. package/dist/cli/backend/src/services/wiki/work-record-transcript.js +194 -0
  124. package/dist/cli/backend/src/services/wiki/work-record-transcript.js.map +1 -0
  125. package/dist/cli/backend/src/services/wiki/work-record.d.ts +239 -0
  126. package/dist/cli/backend/src/services/wiki/work-record.d.ts.map +1 -0
  127. package/dist/cli/backend/src/services/wiki/work-record.js +631 -0
  128. package/dist/cli/backend/src/services/wiki/work-record.js.map +1 -0
  129. package/dist/cli/backend/src/services/worktree/low-disk-guard.d.ts +92 -8
  130. package/dist/cli/backend/src/services/worktree/low-disk-guard.d.ts.map +1 -1
  131. package/dist/cli/backend/src/services/worktree/low-disk-guard.js +98 -14
  132. package/dist/cli/backend/src/services/worktree/low-disk-guard.js.map +1 -1
  133. package/dist/cli/backend/src/services/worktree/worktree-git.d.ts +18 -0
  134. package/dist/cli/backend/src/services/worktree/worktree-git.d.ts.map +1 -1
  135. package/dist/cli/backend/src/services/worktree/worktree-git.js +60 -0
  136. package/dist/cli/backend/src/services/worktree/worktree-git.js.map +1 -1
  137. package/package.json +1 -1
@@ -1780,6 +1780,119 @@ export const AGENT_MEMORY_REFRESH_CONSTANTS = {
1780
1780
  /** Kill switch env var; the value `false` disables the refresh. */
1781
1781
  ENV_KILL_SWITCH: 'CREWLY_AGENT_MEMORY_REFRESH',
1782
1782
  };
1783
+ /**
1784
+ * Automatic per-task work records (#1349): one `(record)` entry per finished
1785
+ * WorkItem in the project vault log, compiled into the weekly digest.
1786
+ */
1787
+ export const WORK_RECORD_CONSTANTS = {
1788
+ /** Hourly tick: catch-up for finished items without a record, blocked items, deferred items. */
1789
+ TICK_MS: 60 * 60 * 1000,
1790
+ /** Delay before the boot-time pass, after the other wiki jobs settled. */
1791
+ BOOT_DELAY_MS: 3 * 60 * 1000,
1792
+ /** A terminal event waits this long before the record is assembled (ticket sync, verify item, evidence land first). */
1793
+ EVENT_DELAY_MS: 20 * 1000,
1794
+ /** Catch-up looks at items that ended within this many days. */
1795
+ CATCHUP_WINDOW_DAYS: 7,
1796
+ /** Cap on records written per pass (the rest wait for the next tick). */
1797
+ CATCHUP_MAX_PER_PASS: 200,
1798
+ /** A record waiting for the owner's OK on a ticket is written anyway after this long. */
1799
+ DEFER_MAX_MS: 72 * 60 * 60 * 1000,
1800
+ /** An item parked in `blocked` for longer than this gets a blocked record. */
1801
+ BLOCKED_AFTER_MS: 24 * 60 * 60 * 1000,
1802
+ /** Hard cap on one record's body (the `meta:` line always fits). */
1803
+ MAX_CHARS: 2_500,
1804
+ /** Characters of the ask quoted. */
1805
+ QUOTE_MAX_CHARS: 160,
1806
+ /** Characters of the result summary kept. */
1807
+ DID_MAX_CHARS: 400,
1808
+ /** Cap on output lines and characters per line. */
1809
+ MAX_OUTPUTS: 8,
1810
+ OUTPUT_MAX_CHARS: 160,
1811
+ /** Cap on error lines and characters per line. */
1812
+ MAX_ERRORS: 5,
1813
+ ERROR_MAX_CHARS: 160,
1814
+ /** Cap on helper lines and characters per line. */
1815
+ MAX_HELPERS: 6,
1816
+ HELPER_MAX_CHARS: 120,
1817
+ /** Bytes read from the end of the agent's transcript for the task window. */
1818
+ TRANSCRIPT_TAIL_BYTES: 2 * 1024 * 1024,
1819
+ /** Transcripts are consulted only for items that ended within this long (older windows are not in the tail). */
1820
+ TRANSCRIPT_MAX_AGE_MS: 48 * 60 * 60 * 1000,
1821
+ /** Slack around the task window when slicing the transcript. */
1822
+ TRANSCRIPT_WINDOW_SLACK_MS: 60 * 1000,
1823
+ /** Cap on trace events read per record. */
1824
+ TRACE_MAX_EVENTS: 2_000,
1825
+ /** State file (recorded keys), under CREWLY_HOME. */
1826
+ STATE_FILE: 'work-records-state.json',
1827
+ /** Cap on remembered record keys. */
1828
+ STATE_MAX_KEYS: 5_000,
1829
+ /** Kill switch env var; the value `false` disables work records. */
1830
+ ENV_KILL_SWITCH: 'CREWLY_WORK_RECORDS',
1831
+ /** Source type of a record entry in the vault log. */
1832
+ SOURCE_TYPE: 'work_record',
1833
+ /** Prefix of a record's `ref:` (`work-record:<workItemId>#<phase>`). */
1834
+ REF_PREFIX: 'work-record:',
1835
+ /** Records the startup briefing lists. */
1836
+ BRIEFING_MAX: 5,
1837
+ /** Characters of one record line in the briefing. */
1838
+ BRIEFING_LINE_MAX_CHARS: 240,
1839
+ /** WorkItem types that are bookkeeping, never recorded. */
1840
+ SKIPPED_TYPES: ['check', 'reconcile', 'confirm', 'ticket_triage', 'autopilot_retro', 'goal_replan', 'ticket_hygiene_review', 'autopilot_self_review'],
1841
+ };
1842
+ /**
1843
+ * Memory-aware boot (crewly#1353). On 2026-10-17 a 16 GB Mac kernel-panicked
1844
+ * a minute after a Crewly restart: 10 agents restored back-to-back, then the
1845
+ * wiki, memory and work-record boot passes on fixed delays, while the machine
1846
+ * was already swapping. Pressure mode only engages after two 30 s samples,
1847
+ * so the boot restore reads the raw snapshot itself and the boot maintenance
1848
+ * passes wait for a quiet machine. Env overrides exist for the two memory
1849
+ * thresholds and the launch spacing.
1850
+ */
1851
+ export const BOOT_PRESSURE_CONSTANTS = {
1852
+ /** Swap in use at or above this share counts as tight for the boot (`CREWLY_BOOT_PRESSURE_SWAP_PERCENT`). */
1853
+ SWAP_USED_PERCENT: 80,
1854
+ /** Free memory below this counts as tight for the boot (`CREWLY_BOOT_PRESSURE_MIN_FREE_MB`). */
1855
+ MIN_FREE_MB: 3 * 1024,
1856
+ /** Minimum gap between two boot launches, pressure or not, so RSS growth is visible before the next (`CREWLY_RESTORE_LAUNCH_SPACING_MS`). */
1857
+ MIN_LAUNCH_SPACING_MS: 15 * 1000,
1858
+ /** Under pressure: how long after an agent registered its process counts as settled before the next launch. */
1859
+ SETTLE_AFTER_READY_MS: 20 * 1000,
1860
+ /** Under pressure: how often the snapshot is re-read while a launch waits for the machine to calm down. */
1861
+ PRESSURE_POLL_MS: 10 * 1000,
1862
+ /** A held launch is logged on the first poll and then every this many polls (once a minute at the default poll). */
1863
+ PRESSURE_HOLD_LOG_EVERY_POLLS: 6,
1864
+ /** Under pressure: an owner-waiting agent waits at most this long for the machine to calm, then launches anyway. */
1865
+ PRESSURE_HOLD_MAX_MS: 10 * 60 * 1000,
1866
+ /** Under pressure: at most this many boot launches in flight at once. */
1867
+ PRESSURE_MAX_CONCURRENCY: 2,
1868
+ /** Boot maintenance passes re-check the restore queue and the snapshot this often. */
1869
+ MAINTENANCE_POLL_MS: 30 * 1000,
1870
+ /** Boot maintenance passes give up waiting after this long and run reduced. */
1871
+ MAINTENANCE_WAIT_MAX_MS: 30 * 60 * 1000,
1872
+ /** Work records written by the boot pass when it runs reduced (instead of CATCHUP_MAX_PER_PASS). */
1873
+ WORK_RECORD_REDUCED_BATCH: 50,
1874
+ /** A vault log larger than this is rotated by streaming (tail read, header count) instead of being read whole. */
1875
+ ROTATION_STREAM_BYTES: 10 * 1024 * 1024,
1876
+ /** Bytes read from the end of a streamed log to pick the entries carried forward. */
1877
+ ROTATION_TAIL_BYTES: 2 * 1024 * 1024,
1878
+ /** Chunk size of the streaming entry count. */
1879
+ ROTATION_CHUNK_BYTES: 1024 * 1024,
1880
+ /** The owner gets one line when boot restores have been held back for longer than this. */
1881
+ OWNER_NOTE_AFTER_MS: 10 * 60 * 1000,
1882
+ /**
1883
+ * Boot launches outside the restore queue (the deferred-start retry) are
1884
+ * held for memory at most this long after boot; afterwards the pressure
1885
+ * mode cap alone decides, because macOS swap stays full for hours after
1886
+ * the pressure is gone and a held agent is still owed something.
1887
+ */
1888
+ RETRY_HOLD_MAX_MS: 60 * 60 * 1000,
1889
+ /** Env override of SWAP_USED_PERCENT. */
1890
+ ENV_SWAP_PERCENT: 'CREWLY_BOOT_PRESSURE_SWAP_PERCENT',
1891
+ /** Env override of MIN_FREE_MB. */
1892
+ ENV_MIN_FREE_MB: 'CREWLY_BOOT_PRESSURE_MIN_FREE_MB',
1893
+ /** Env override of MIN_LAUNCH_SPACING_MS. */
1894
+ ENV_LAUNCH_SPACING_MS: 'CREWLY_RESTORE_LAUNCH_SPACING_MS',
1895
+ };
1783
1896
  /**
1784
1897
  * Startup briefing content (#1345): wiki pages, recent lessons and open
1785
1898
  * owner threads an agent gets at registration, on top of its session memory.
@@ -1883,6 +1996,16 @@ export const WORKTREE_CONSTANTS = {
1883
1996
  INCLUDE_MAX_ENTRIES: 50,
1884
1997
  /** Heavy directories symlinked (not copied) from the repo root when present and untracked. */
1885
1998
  DEFAULT_SHARED_DIRS: ['node_modules'],
1999
+ /**
2000
+ * Workspace packages' install dirs (`backend/node_modules`,
2001
+ * `packages/ui/node_modules`) are symlinked too when the lock file is
2002
+ * identical in repo and worktree (crewly#1354): searched this deep.
2003
+ */
2004
+ NESTED_INSTALL_DEPTH: 2,
2005
+ /** Lock files compared (first one present in the repo decides). */
2006
+ LOCK_FILES: ['package-lock.json', 'pnpm-lock.yaml', 'yarn.lock'],
2007
+ /** Directories never descended into while looking for nested install dirs. */
2008
+ NESTED_INSTALL_SKIP_DIRS: ['node_modules', '.git', '.crewly', '.claude', 'dist', '.next'],
1886
2009
  /** Marker line for the entries this feature adds to `.git/info/exclude`. */
1887
2010
  EXCLUDE_MARKER: '# crewly worktree shared paths (#814) — never commit these',
1888
2011
  /** Timeout for local git commands (checkout of a large repo can take minutes under load). */
@@ -2753,7 +2876,7 @@ export const WORKTREE_JANITOR_CONSTANTS = {
2753
2876
  /** Timeout of the `lsof` that finds a file's writers (ms). */
2754
2877
  RUNAWAY_LSOF_TIMEOUT_MS: 10_000,
2755
2878
  /** One line added to every agent's start prompt. */
2756
- PROMPT_HINT: 'Disk hygiene: never let a command or script write an unbounded file. When you redirect or concatenate output (`> file`, `>> file`, `cat a b > all.md`), cap it (`| head -c 50M`, `| head -n 100000`) and never build a file from its own output. A file in your scratch dir or worktree that grows past a few GB is stopped by Crewly and the owner is alerted. Worktree hygiene: deploy only from a commit that is on main (merge first, never from a side branch); remove your worktree once its ticket is done.',
2879
+ PROMPT_HINT: 'Disk hygiene: never let a command or script write an unbounded file. When you redirect or concatenate output (`> file`, `>> file`, `cat a b > all.md`), cap it (`| head -c 50M`, `| head -n 100000`) and never build a file from its own output. A file in your scratch dir or worktree that grows past a few GB is stopped by Crewly and the owner is alerted. Worktree hygiene: deploy only from a commit that is on main (merge first, never from a side branch); remove your worktree once its ticket is done. In a new worktree, do not run `npm install` when package-lock.json is unchanged: symlink `node_modules` (root and per-package) from the main checkout instead (`ln -s <main>/node_modules node_modules`). Crewly strips node_modules from worktrees untouched for 3 days and archives untouched ones as a patch after 14 days.',
2757
2880
  /** State file under CREWLY_HOME remembering when the owner was last told about low disk. */
2758
2881
  STATE_FILENAME: 'disk-janitor-state.json',
2759
2882
  /** File (in CREWLY_HOME) remembering which unmerged worktrees their lead was already told about. */
@@ -2792,8 +2915,12 @@ export const WORKTREE_JANITOR_CONSTANTS = {
2792
2915
  REGENERABLE_DIRS: ['node_modules', '.next', 'dist', 'build', '.turbo', 'coverage', '.cache', 'logs'],
2793
2916
  /** File suffixes treated as regenerable output (logs). */
2794
2917
  REGENERABLE_FILE_SUFFIXES: ['.log'],
2795
- /** Directories deleted from kept (dirty / not-merged) worktrees under low disk — reinstalled by `npm install` / rebuilt by `next build`. */
2796
- RECLAIM_DIRS: ['node_modules', '.next'],
2918
+ /**
2919
+ * Directories deleted from kept (dirty / not-merged) worktrees by the strip
2920
+ * tier — reinstalled by `npm install` / rebuilt by the build. A directory
2921
+ * git tracks anything under is never deleted (a repo that commits `dist`).
2922
+ */
2923
+ RECLAIM_DIRS: ['node_modules', '.next', 'dist', '.turbo', '.cache'],
2797
2924
  /** A kept worktree must be idle this long before its regenerable dirs are reclaimed under low disk (24 hours). */
2798
2925
  RECLAIM_MIN_IDLE_MS: 24 * 60 * 60 * 1000,
2799
2926
  /** How deep under a worktree reclaimable dirs are searched for (root = 0; `web/node_modules` = 1). */
@@ -2818,6 +2945,76 @@ export const WORKTREE_JANITOR_CONSTANTS = {
2818
2945
  GH_PR_LIMIT: 20,
2819
2946
  /** Max bytes of command output kept (stdout/stderr each). */
2820
2947
  MAX_OUTPUT_BYTES: 16 * 1024 * 1024,
2948
+ // --- Age tiers for kept (unmerged / dirty) worktrees (crewly#1354) ---
2949
+ /** A kept worktree untouched (no file, index or commit newer) for this long loses its regenerable dirs (3 days). */
2950
+ STRIP_MIN_IDLE_MS: 3 * 24 * 60 * 60 * 1000,
2951
+ /** Under low disk, or once its WorkItem finished, the strip tier needs only this much idle (1 day). */
2952
+ STRIP_MIN_IDLE_LOW_DISK_MS: 24 * 60 * 60 * 1000,
2953
+ /** A kept worktree untouched for this long is archived as a patch and removed (14 days). */
2954
+ ARCHIVE_MIN_IDLE_MS: 14 * 24 * 60 * 60 * 1000,
2955
+ /** Directory under CREWLY_HOME holding archived worktree patches (`<repo>/<name>-<date>.patch`). */
2956
+ ARCHIVE_DIR: 'worktree-archive',
2957
+ /** Cap on one archive patch; untracked files that would push it past the cap are listed in the header instead (64 MB). */
2958
+ ARCHIVE_PATCH_MAX_BYTES: 64 * 1024 ** 2,
2959
+ /** Cap on untracked files written into one archive patch. */
2960
+ ARCHIVE_MAX_UNTRACKED_FILES: 2000,
2961
+ /** Ref namespace that keeps the commits of an archived detached worktree alive (`refs/crewly-archive/<name>-<date>`). */
2962
+ ARCHIVE_REF_PREFIX: 'refs/crewly-archive/',
2963
+ /** How many levels below a worktree root count for its "last touched" time in the tier decision. */
2964
+ TIER_MTIME_DEPTH: 2,
2965
+ /** State file under CREWLY_HOME: per-worktree strip / archive / finished-work timestamps. */
2966
+ TIER_STATE_FILENAME: 'worktree-tiers.json',
2967
+ /** Finished-work records (task-end hook) older than this are dropped from the state file (30 days). */
2968
+ TIER_STATE_MAX_AGE_MS: 30 * 24 * 60 * 60 * 1000,
2969
+ /**
2970
+ * Every delete added in crewly#1354 (strip, archive, transcripts, tmp, logs)
2971
+ * is dry-run only until this long after the first real pass that saw it
2972
+ * (one day): the first pass logs what it would do, the next day it does it.
2973
+ */
2974
+ RETENTION_ARM_DELAY_MS: 24 * 60 * 60 * 1000,
2975
+ // --- Transcript retention (Claude Code conversations Crewly launched) ---
2976
+ /** An agent transcript (and its sibling tool-results dir) untouched for this long is pruned (14 days). */
2977
+ TRANSCRIPT_MAX_AGE_MS: 14 * 24 * 60 * 60 * 1000,
2978
+ /** The transcript sweep runs at most this often (24 hours). */
2979
+ TRANSCRIPT_SWEEP_INTERVAL_MS: 24 * 60 * 60 * 1000,
2980
+ /** Bytes read from the head of a transcript to find Claude Code's `agentSetting` entry. */
2981
+ TRANSCRIPT_HEAD_BYTES: 256 * 1024,
2982
+ /** Handover files newer than this are scanned for conversation ids (30 days). */
2983
+ TRANSCRIPT_HANDOVER_SCAN_MAX_AGE_MS: 30 * 24 * 60 * 60 * 1000,
2984
+ /** Kinds that handover file names carry between the session name and the timestamp (`<session>-<kind>-<ISO>.md`). */
2985
+ HANDOVER_KINDS: ['restart', 'runtime-switch', 'runtime-revert', 'runtime-upgrade'],
2986
+ /** Sub-directory of a Claude home that holds per-cwd transcript folders. */
2987
+ TRANSCRIPT_PROJECTS_DIR: 'projects',
2988
+ /** Transcript file extension. */
2989
+ TRANSCRIPT_EXT: '.jsonl',
2990
+ // --- CREWLY_HOME/tmp and logs retention ---
2991
+ /** Directory under CREWLY_HOME that agents and skills use as scratch space. */
2992
+ TMP_DIR: 'tmp',
2993
+ /** A top-level entry of CREWLY_HOME/tmp untouched for this long is removed (7 days). */
2994
+ TMP_MAX_AGE_MS: 7 * 24 * 60 * 60 * 1000,
2995
+ /** Sub-directories of CREWLY_HOME/tmp swept per child with their own age (ms); the directory itself stays. */
2996
+ TMP_CHILD_POLICIES: {
2997
+ 'slack-files': 30 * 24 * 60 * 60 * 1000,
2998
+ 'slack-images': 30 * 24 * 60 * 60 * 1000,
2999
+ 'slack-pdfs': 30 * 24 * 60 * 60 * 1000,
3000
+ 'crewly-web-release': 2 * 24 * 60 * 60 * 1000,
3001
+ 'skill-output': 7 * 24 * 60 * 60 * 1000,
3002
+ },
3003
+ /** How many levels below a tmp entry count for its "last touched" time. */
3004
+ TMP_MTIME_DEPTH: 2,
3005
+ /** The tmp / logs sweep runs at most this often (6 hours). */
3006
+ TMP_SWEEP_INTERVAL_MS: 6 * 60 * 60 * 1000,
3007
+ /** Cap on CREWLY_HOME/logs/archive; the oldest archives go first (300 MB). */
3008
+ LOG_ARCHIVE_CAP_BYTES: 300 * 1024 ** 2,
3009
+ /** Cap on CREWLY_HOME/logs/sessions; the oldest logs of sessions that are not live go first (100 MB). */
3010
+ LOG_SESSIONS_CAP_BYTES: 100 * 1024 ** 2,
3011
+ /** A log written within this long is never deleted by the cap (1 hour). */
3012
+ LOG_CAP_MIN_AGE_MS: 60 * 60 * 1000,
3013
+ // --- Low-disk thresholds relative to the disk size (crewly#1354) ---
3014
+ /** Low disk is free < max(LOW_DISK_BYTES, this fraction of the disk) (8 %). */
3015
+ LOW_DISK_FRACTION: 0.08,
3016
+ /** Critical is free < max(CRITICAL_DISK_BYTES, this fraction of the disk) (3 %). */
3017
+ CRITICAL_DISK_FRACTION: 0.03,
2821
3018
  };
2822
3019
  /**
2823
3020
  * Constants for cron next-run computation (`getNextRunTime`).