hyperframes 0.8.136 → 0.8.138

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 (182) hide show
  1. package/dist/{add-MD4CNRQV.js → add-IZQPSHT5.js} +15 -15
  2. package/dist/{animatedGifPrep-3AKQSXPU.js → animatedGifPrep-MQF3GRFW.js} +6 -6
  3. package/dist/appHistory-TH3TL6N6.js +31 -0
  4. package/dist/{asset-UPNW7262.js → asset-RNZX4ISG.js} +2 -2
  5. package/dist/{assetCataloger-KBN5LNK4.js → assetCataloger-5YRUY3PJ.js} +2 -2
  6. package/dist/{auth-63PKUA76.js → auth-LUELYGJ4.js} +2 -2
  7. package/dist/{autoUpdate-CLB47L2W.js → autoUpdate-ECMQWUU5.js} +2 -2
  8. package/dist/{backgroundChecks-JW7XF7JA.js → backgroundChecks-PBEJMSA3.js} +3 -3
  9. package/dist/backgroundChecksWorker.js +3 -3
  10. package/dist/{batchRender-VFXGGGJG.js → batchRender-2GXKBPFQ.js} +3 -3
  11. package/dist/{beats-3CO6EGBG.js → beats-AAAZVDOY.js} +14 -14
  12. package/dist/{benchmark-CYTMATA7.js → benchmark-EI767IB4.js} +12 -12
  13. package/dist/{browser-QMLZJM2K.js → browser-KAA2VXYH.js} +9 -9
  14. package/dist/{bundleWithLocalizedFonts-5ATL25BF.js → bundleWithLocalizedFonts-MWDYAPGB.js} +2 -2
  15. package/dist/{capture-UEJG6BUX.js → capture-IRRHK6BT.js} +2 -2
  16. package/dist/{capture-DYBK5LGE.js → capture-VYT5NQQI.js} +13 -13
  17. package/dist/{catalog-G773J4K4.js → catalog-FYTZ2ET6.js} +22 -22
  18. package/dist/catch-up-XH3OAKQR.js +123 -0
  19. package/dist/{check-NCXITJWK.js → check-MUMIOK5K.js} +38 -38
  20. package/dist/{checkBrowser-IJQ2WCOB.js → checkBrowser-LKSZFOU6.js} +36 -36
  21. package/dist/{chunk-2EAXUCCE.js → chunk-2NCHQUPX.js} +1 -1
  22. package/dist/{chunk-XT5P4QMO.js → chunk-3DKN5WKL.js} +31 -11
  23. package/dist/{chunk-XLO327OK.js → chunk-3F6YLT72.js} +11 -11
  24. package/dist/{chunk-V2J2ZWPR.js → chunk-5K33TNUJ.js} +2 -2
  25. package/dist/{chunk-JBI43NRR.js → chunk-7OLMGFDN.js} +3 -3
  26. package/dist/{chunk-N3KRRPL7.js → chunk-7Y5SMPRV.js} +3 -3
  27. package/dist/{chunk-SXE656MT.js → chunk-APMG37MX.js} +1 -1
  28. package/dist/{chunk-37EDNWLQ.js → chunk-ASPTQ6DT.js} +1 -1
  29. package/dist/chunk-DCAI5DBR.js +218 -0
  30. package/dist/{chunk-KZJPREW7.js → chunk-DJMXTKKK.js} +1 -1
  31. package/dist/{chunk-YDBQRLRI.js → chunk-DXHYACUC.js} +3 -3
  32. package/dist/{chunk-GULOKZLI.js → chunk-EDUBJPGL.js} +14 -9
  33. package/dist/{chunk-527WRFUQ.js → chunk-FSSMOTMS.js} +1 -1
  34. package/dist/{chunk-FTR6KLIG.js → chunk-GJGVYREG.js} +59 -226
  35. package/dist/{chunk-V26IB6L2.js → chunk-GNHJ4ONK.js} +2 -2
  36. package/dist/{chunk-BQIFI4GV.js → chunk-HUZYBV2Z.js} +1 -1
  37. package/dist/{chunk-ECAXTQGU.js → chunk-HXXX6N2G.js} +2 -2
  38. package/dist/{chunk-2BJCQN7K.js → chunk-I3BRUEKD.js} +1 -1
  39. package/dist/{chunk-BSU7EOWJ.js → chunk-IC5L6L7K.js} +1 -1
  40. package/dist/{chunk-P3UNVJXX.js → chunk-IRYC5BRO.js} +4 -4
  41. package/dist/{chunk-V32SGDX7.js → chunk-JCRJBB4E.js} +10 -10
  42. package/dist/{chunk-H4UIYRZZ.js → chunk-JOUVZO7M.js} +1 -1
  43. package/dist/{chunk-XZABUQTX.js → chunk-JYYOAKHS.js} +1 -1
  44. package/dist/{chunk-Z3EFUXL5.js → chunk-KBUUCAIZ.js} +6 -6
  45. package/dist/{chunk-RTURM45Q.js → chunk-KRLYIT22.js} +1 -1
  46. package/dist/{chunk-5K573LFX.js → chunk-L5E5ZN6G.js} +1 -1
  47. package/dist/{chunk-4AXZWUQ6.js → chunk-MIOBYUXT.js} +1 -1
  48. package/dist/{chunk-ZBNFAZQB.js → chunk-MKVKVMUH.js} +7 -7
  49. package/dist/{chunk-XE6S5CE6.js → chunk-OBC75KXL.js} +1 -1
  50. package/dist/{chunk-PGFP4FLW.js → chunk-P5WDMFBB.js} +405 -205
  51. package/dist/{chunk-WFZEW4AC.js → chunk-P75OFLZN.js} +2 -2
  52. package/dist/{chunk-OSSVNAI5.js → chunk-PHRWQQOJ.js} +1 -1
  53. package/dist/{chunk-5ALWCRBU.js → chunk-PHXBLIKK.js} +10 -10
  54. package/dist/{chunk-OAF4XJOW.js → chunk-PXSM4HPB.js} +7 -2
  55. package/dist/{chunk-3E3WVNVP.js → chunk-QPOK6I32.js} +2 -2
  56. package/dist/{chunk-GK5W3SIJ.js → chunk-R6C6URKB.js} +3 -3
  57. package/dist/{chunk-EXNGSOQG.js → chunk-RH5VML6E.js} +12 -12
  58. package/dist/{chunk-BHOKLX4F.js → chunk-RLNB3JCY.js} +1 -1
  59. package/dist/{chunk-IQ3OUQ5Z.js → chunk-S3S2LSZX.js} +22 -2
  60. package/dist/{chunk-LO7L5PJ3.js → chunk-SDRKEYZV.js} +5 -5
  61. package/dist/{chunk-T5LPCY6I.js → chunk-SIMYRD5P.js} +27 -41
  62. package/dist/{chunk-VDQCNWQI.js → chunk-STA43FMY.js} +1 -1
  63. package/dist/{chunk-VNC6YQOC.js → chunk-SZITAGRK.js} +1 -1
  64. package/dist/chunk-UINDCCO7.js +3742 -0
  65. package/dist/{chunk-BWJ27MQP.js → chunk-UUMK6VME.js} +1 -1
  66. package/dist/{chunk-CG6OUDMX.js → chunk-VR5UQWGV.js} +3 -3
  67. package/dist/{chunk-RVG35AL2.js → chunk-W3KQCJVP.js} +217 -6
  68. package/dist/{chunk-X5HWXQPU.js → chunk-WCJGTLPF.js} +22 -10
  69. package/dist/{chunk-M5WGAAML.js → chunk-WH6PRFNX.js} +3 -3
  70. package/dist/{chunk-WTMA6JQD.js → chunk-XQODEVF3.js} +1 -1
  71. package/dist/{chunk-32QEFPDS.js → chunk-YGXLBX3N.js} +1 -1
  72. package/dist/{chunk-CYG3HXBE.js → chunk-YNBXJWSD.js} +1 -1
  73. package/dist/{clean-UCLCH4YA.js → clean-LZPDOAV4.js} +21 -21
  74. package/dist/cli.js +62 -52
  75. package/dist/{cloud-LVP33D4N.js → cloud-RVAH5NNL.js} +4 -4
  76. package/dist/{cloudrun-FA4XHPZS.js → cloudrun-NFGM6TRT.js} +3 -3
  77. package/dist/{compare-TOTN2CVX.js → compare-S3M5OAL2.js} +29 -29
  78. package/dist/{compiler-XZ654ZH2.js → compiler-SZ4GTYFB.js} +3 -3
  79. package/dist/{component-B5QZZJJA.js → component-PR2WZTQ4.js} +3 -3
  80. package/dist/{compositions-REMCVXXP.js → compositions-6RYXH2UA.js} +11 -11
  81. package/dist/{delete-H2P6PYT5.js → delete-EO7C3LQ6.js} +3 -3
  82. package/dist/{deterministicFonts-U2EXY2KQ.js → deterministicFonts-GTITFRSJ.js} +2 -2
  83. package/dist/{dist-QS5WEGBE.js → dist-OJTEVNJR.js} +1 -1
  84. package/dist/{dist-HVJAGLHF.js → dist-RVC3JTID.js} +2 -2
  85. package/dist/{doctor-HCGHEJDN.js → doctor-UTCCMN32.js} +12 -12
  86. package/dist/{events-2LS5WRYL.js → events-RCGWL4LI.js} +9 -9
  87. package/dist/{events-V5QLQAN4.js → events-RE3OR6KY.js} +8 -8
  88. package/dist/{feedback-WBOC7SAW.js → feedback-V7C64JIR.js} +12 -12
  89. package/dist/{figma-HRUWQ5FO.js → figma-26LOX5PV.js} +3 -3
  90. package/dist/fontLocalizeCli.js +10 -10
  91. package/dist/{get-FS5GMKBK.js → get-E2K2JRTV.js} +3 -3
  92. package/dist/{gpuPolicy-ON3RMSWD.js → gpuPolicy-Z3PQN6ZK.js} +6 -6
  93. package/dist/{grade-compare-G7Z5DWKW.js → grade-compare-OTZDU463.js} +26 -26
  94. package/dist/{help-27P7K7JZ.js → help-IRSQLNI5.js} +3 -2
  95. package/dist/{history-5E46VSDM.js → history-G44U6762.js} +18 -18
  96. package/dist/hyperframe-runtime.js +64 -182
  97. package/dist/hyperframe.manifest.json +1 -1
  98. package/dist/hyperframe.runtime.iife.js +64 -182
  99. package/dist/hyperframes-player.global.js +1 -1
  100. package/dist/{info-2ZYYJL3I.js → info-KXQ2TAHX.js} +11 -11
  101. package/dist/{init-ZI75FWLJ.js → init-7SXMLHJE.js} +27 -27
  102. package/dist/{inspect-YLQN7QL6.js → inspect-7JTINR25.js} +27 -27
  103. package/dist/{installer-DDJVY4TO.js → installer-RH4E6WXT.js} +4 -4
  104. package/dist/{keyframes-JONXVQWD.js → keyframes-PIV573S6.js} +12 -12
  105. package/dist/{lambda-LPLYOEYY.js → lambda-GO5HAA4S.js} +4 -4
  106. package/dist/{layout-ZP4WDRSA.js → layout-N2736OO3.js} +27 -27
  107. package/dist/{lint-XGMUBMLE.js → lint-WUXZ5WWZ.js} +14 -14
  108. package/dist/{lintProject-EPVG2EFE.js → lintProject-ANMPLBIT.js} +1 -1
  109. package/dist/{list-NBXJMDON.js → list-QF7AMX5F.js} +3 -3
  110. package/dist/{login-XIH4H4RH.js → login-6RGSXHQJ.js} +4 -4
  111. package/dist/{manager-GFN75DM4.js → manager-524RPYO7.js} +2 -2
  112. package/dist/{manager-67P2XFXQ.js → manager-DXB7JDHU.js} +2 -2
  113. package/dist/{media-treatment-QYKJDWHD.js → media-treatment-T4KDEDYW.js} +14 -14
  114. package/dist/{models-54NL5PRB.js → models-6JMNK3XI.js} +19 -12
  115. package/dist/{motionShot-Y4D7LHU4.js → motionShot-74WM7KF6.js} +12 -12
  116. package/dist/{normalize-audio-6RR6UGAJ.js → normalize-audio-ZZU36ZMD.js} +14 -14
  117. package/dist/{open-TYFT2DQC.js → open-G523K45B.js} +20 -13
  118. package/dist/{pipeline-P7QRGI5H.js → pipeline-AKDGCWRE.js} +10 -10
  119. package/dist/{play-IZXA4GO3.js → play-SHIGXVON.js} +30 -30
  120. package/dist/{preflight-X3XFRJPQ.js → preflight-6ERLORWK.js} +7 -7
  121. package/dist/{present-JS2KNZLT.js → present-QOYYNZCE.js} +19 -19
  122. package/dist/{preview-M6PED6DU.js → preview-KUXTDJL3.js} +26 -24
  123. package/dist/{producer-KQNJKM7F.js → producer-CH33JXHK.js} +1 -1
  124. package/dist/{projectConfig-EAAQYRMP.js → projectConfig-NKIPRWAE.js} +6 -6
  125. package/dist/{publication-H3G346EX.js → publication-4RBVVR5Z.js} +2 -2
  126. package/dist/{publish-NEGKIS35.js → publish-OLHR4Z4U.js} +12 -11
  127. package/dist/{remove-background-HU4S4HH5.js → remove-background-NPKZSIPY.js} +12 -12
  128. package/dist/{render-24OQFSYB.js → render-GYYGWYQC.js} +17 -17
  129. package/dist/{render-IZHBGVPP.js → render-P4NWFUS7.js} +29 -27
  130. package/dist/{render-F3CNO2IE.js → render-UOKPAJNH.js} +3 -3
  131. package/dist/{render-batch-63CBIJYR.js → render-batch-ZDG3EXSD.js} +3 -3
  132. package/dist/{renderCancellation-FT3JJ7GB.js → renderCancellation-QYQLWHZY.js} +6 -6
  133. package/dist/renderSetupWorker.js +1 -1
  134. package/dist/{resolver-YJJKOGQF.js → resolver-CWH3VVB7.js} +4 -4
  135. package/dist/{sherpa-3BQDMJPJ.js → sherpa-WEQE23S5.js} +130 -47
  136. package/dist/sherpaWorker.js +4 -8
  137. package/dist/skills/hyperframes/SKILL.md +2 -0
  138. package/dist/skills/hyperframes-cli/SKILL.md +1 -1
  139. package/dist/{skills-T2O7PD6Q.js → skills-BVONI6TC.js} +14 -14
  140. package/dist/{skillsUpdateCheck-VYEGOAEI.js → skillsUpdateCheck-KKDPTFM7.js} +3 -3
  141. package/dist/{snapshot-NLTL7ZOM.js → snapshot-PWZFJEDR.js} +36 -36
  142. package/dist/{src-ZPAJ44CP.js → src-HH4C5GZV.js} +9 -9
  143. package/dist/{src-CUR36DBE.js → src-YO7MAWGD.js} +5 -5
  144. package/dist/{staticProjectServer-WN4BSLI3.js → staticProjectServer-PR5INXSA.js} +14 -14
  145. package/dist/{status-6CGT2PJT.js → status-AK67DTED.js} +6 -6
  146. package/dist/studio/assets/{hyperframes-player-ukvUFqdg.js → hyperframes-player-B30apksz.js} +1 -1
  147. package/dist/studio/assets/{index-C-pD9_xY.js → index-BdjA0CLD.js} +147 -147
  148. package/dist/studio/assets/{index-syMK0_9C.css → index-CVd4O6eH.css} +1 -1
  149. package/dist/studio/assets/{index-CRRgIxsS.js → index-DIJuIBwI.js} +1 -1
  150. package/dist/studio/assets/{index-BY_myArg.js → index-DXVvWfQG.js} +1 -1
  151. package/dist/studio/{chunk-QRLKWENQ.js → chunk-4S3AYCOG.js} +2 -2
  152. package/dist/studio/{chunk-NM7BXNZ7.js → chunk-LOVBLSMR.js} +10 -4
  153. package/dist/studio/chunk-LOVBLSMR.js.map +1 -0
  154. package/dist/studio/index.html +2 -2
  155. package/dist/studio/index.js +2852 -2852
  156. package/dist/studio/index.js.map +1 -1
  157. package/dist/studio/player.js +2 -2
  158. package/dist/studio/styles.css +1 -1
  159. package/dist/studio/ui.d.ts +2 -1
  160. package/dist/studio/ui.js +1 -1
  161. package/dist/{studio-api-KTRRONOC.js → studio-api-NFJMFAB7.js} +13 -11
  162. package/dist/{studioServer-O6P3TBDJ.js → studioServer-TQZVCIEL.js} +51 -50
  163. package/dist/{synthesize-K62TIZWI.js → synthesize-77PTU6C5.js} +6 -6
  164. package/dist/{system-3BTZGJNK.js → system-ZWIBWWE6.js} +6 -6
  165. package/dist/{telemetry-G4QOG4OF.js → telemetry-63L2ORO3.js} +9 -9
  166. package/dist/templates/_shared/AGENTS.md +2 -0
  167. package/dist/templates/_shared/CLAUDE.md +2 -0
  168. package/dist/{timeline-JS5QNPLA.js → timeline-QKZQL5DJ.js} +18 -18
  169. package/dist/{tokens-JKLDRW7A.js → tokens-ELK62U4A.js} +2 -2
  170. package/dist/{transcribe-HC35FL6W.js → transcribe-OSK7HEOJ.js} +9 -9
  171. package/dist/{transcribe-CP6ZCDVR.js → transcribe-VKSXTM7K.js} +80 -24
  172. package/dist/{tts-P3LIPIL5.js → tts-FU35O6YB.js} +3 -3
  173. package/dist/{updateCheck-L2UJCCL4.js → updateCheck-PM4FEI7P.js} +2 -2
  174. package/dist/{upgrade-NW7YFVUM.js → upgrade-G635QCNO.js} +2 -2
  175. package/dist/{urlDownloader-A5TT3AFE.js → urlDownloader-MVYQTP73.js} +5 -5
  176. package/dist/{validate-D3ZH3JQ7.js → validate-AZTMI3HR.js} +16 -16
  177. package/dist/{video-USXMJDEZ.js → video-H56FK33V.js} +6 -6
  178. package/package.json +1 -1
  179. package/dist/chunk-SRXQEQWZ.js +0 -3742
  180. package/dist/studio/chunk-NM7BXNZ7.js.map +0 -1
  181. package/dist/{chunk-WJFCDDP7.js → chunk-R4QIE6UY.js} +3 -3
  182. /package/dist/studio/{chunk-QRLKWENQ.js.map → chunk-4S3AYCOG.js.map} +0 -0
@@ -0,0 +1,218 @@
1
+ import { createRequire as __hf_createRequire } from "node:module";
2
+ import { fileURLToPath as __hf_fileURLToPath } from "node:url";
3
+ import { dirname as __hf_dirname } from "node:path";
4
+ var require = __hf_createRequire(import.meta.url);
5
+ var __filename = __hf_fileURLToPath(import.meta.url);
6
+ var __dirname = __hf_dirname(__filename);
7
+ import {
8
+ replaceFileAtomically
9
+ } from "./chunk-EOVYQ3IG.js";
10
+ import {
11
+ realpath
12
+ } from "./chunk-OFQWTKPW.js";
13
+
14
+ // src/utils/appHistory.ts
15
+ import { createHash } from "crypto";
16
+ import { lstatSync as lstatSync2, mkdirSync as mkdirSync2, readdirSync } from "fs";
17
+ import { homedir } from "os";
18
+ import { dirname, join as join2, relative, resolve, sep } from "path";
19
+
20
+ // src/utils/projectRecords.ts
21
+ import { closeSync, constants, fstatSync, lstatSync, mkdirSync, openSync, readSync } from "fs";
22
+ import { join } from "path";
23
+ var NO_FOLLOW = constants.O_NOFOLLOW ?? 0;
24
+ var NON_BLOCK = constants.O_NONBLOCK ?? 0;
25
+ function recordsDir(projectDir, create = false) {
26
+ const dir = join(projectDir, ".hyperframes");
27
+ try {
28
+ return lstatSync(dir).isDirectory() ? dir : null;
29
+ } catch {
30
+ if (!create) return null;
31
+ try {
32
+ mkdirSync(dir);
33
+ return dir;
34
+ } catch {
35
+ return null;
36
+ }
37
+ }
38
+ }
39
+ function readPlainFile(path, maxBytes) {
40
+ let fd;
41
+ try {
42
+ fd = openSync(path, constants.O_RDONLY | NO_FOLLOW | NON_BLOCK);
43
+ } catch {
44
+ return "";
45
+ }
46
+ try {
47
+ const stats = fstatSync(fd);
48
+ const named = lstatSync(path);
49
+ if (!stats.isFile() || !named.isFile() || named.ino !== stats.ino || named.dev !== stats.dev)
50
+ return "";
51
+ const length = Math.min(stats.size, maxBytes);
52
+ const buffer = Buffer.alloc(length);
53
+ readSync(fd, buffer, 0, length, stats.size - length);
54
+ return buffer.toString("utf8");
55
+ } catch {
56
+ return "";
57
+ } finally {
58
+ closeSync(fd);
59
+ }
60
+ }
61
+ function readRecord(projectDir, name, maxBytes) {
62
+ const dir = recordsDir(projectDir);
63
+ return dir ? readPlainFile(join(dir, name), maxBytes) : "";
64
+ }
65
+ function recordChangedAt(projectDir, name) {
66
+ const dir = recordsDir(projectDir);
67
+ try {
68
+ const stats = dir ? lstatSync(join(dir, name)) : null;
69
+ return stats?.isFile() ? stats.mtimeMs : 0;
70
+ } catch {
71
+ return 0;
72
+ }
73
+ }
74
+ function replaceFile(path, data, mode) {
75
+ try {
76
+ replaceFileAtomically(path, data, mode);
77
+ return true;
78
+ } catch {
79
+ return false;
80
+ }
81
+ }
82
+ function writeRecord(projectDir, name, data) {
83
+ const dir = recordsDir(projectDir, true);
84
+ return dir !== null && replaceFile(join(dir, name), data, 384);
85
+ }
86
+
87
+ // src/utils/appHistory.ts
88
+ var APP_HISTORY = "app-history.jsonl";
89
+ var MAX_READ_BYTES = 1024 * 1024;
90
+ var MAX_FIELD_CHARS = 2e3;
91
+ var MAX_WALKED_FILES = 5e3;
92
+ var SKIPPED_DIRS = /* @__PURE__ */ new Set(["node_modules", "renders", "snapshots"]);
93
+ var text = (value) => typeof value === "string" ? value.slice(0, MAX_FIELD_CHARS) : "";
94
+ function toTurn(line) {
95
+ let raw;
96
+ try {
97
+ raw = Object(JSON.parse(line));
98
+ } catch {
99
+ return null;
100
+ }
101
+ const at = text(raw.at);
102
+ if (Number.isNaN(Date.parse(at))) return null;
103
+ const files = Array.isArray(raw.files) ? raw.files.map(text).filter(Boolean) : [];
104
+ return { at, engine: text(raw.engine), asked: text(raw.asked), did: text(raw.did), files };
105
+ }
106
+ function readAppTurns(dir) {
107
+ return readRecord(dir, APP_HISTORY, MAX_READ_BYTES).split("\n").flatMap((line) => toTurn(line) ?? []);
108
+ }
109
+ var stamp = (value) => typeof value === "string" ? Date.parse(value) || 0 : 0;
110
+ function seenPath(dir) {
111
+ let real;
112
+ try {
113
+ real = realpath(dir);
114
+ } catch {
115
+ real = resolve(dir);
116
+ }
117
+ const key = createHash("sha256").update(real).digest("hex").slice(0, 32);
118
+ return join2(homedir(), ".hyperframes", "catch-up", `${key}.json`);
119
+ }
120
+ function readSeen(dir) {
121
+ try {
122
+ const seen = Object(JSON.parse(readPlainFile(seenPath(dir), 4096)));
123
+ const at = stamp(seen.at);
124
+ return { at, checked: stamp(seen.checked) || at };
125
+ } catch {
126
+ return { at: 0, checked: 0 };
127
+ }
128
+ }
129
+ function markSeen(dir, seen) {
130
+ const path = seenPath(dir);
131
+ const at = (time) => new Date(time).toISOString();
132
+ try {
133
+ mkdirSync2(dirname(path), { recursive: true, mode: 448 });
134
+ } catch {
135
+ return false;
136
+ }
137
+ return replaceFile(path, JSON.stringify({ at: at(seen.at), checked: at(seen.checked) }), 384);
138
+ }
139
+ function unseenTurns(dir, since, now = Date.now()) {
140
+ if (!since) return [];
141
+ return readAppTurns(dir).filter(
142
+ (turn) => Date.parse(turn.at) > since && Date.parse(turn.at) <= now
143
+ );
144
+ }
145
+ function filesChangedSince(dir, since) {
146
+ const changed = [];
147
+ let walked = 0;
148
+ const walk = (folder) => {
149
+ let entries;
150
+ try {
151
+ entries = readdirSync(folder, { withFileTypes: true });
152
+ } catch {
153
+ return;
154
+ }
155
+ for (const entry of entries) {
156
+ if (walked++ > MAX_WALKED_FILES) return;
157
+ if (entry.name.startsWith(".") || SKIPPED_DIRS.has(entry.name)) continue;
158
+ const path = join2(folder, entry.name);
159
+ if (entry.isDirectory()) walk(path);
160
+ else if (entry.isFile() && lstatSync2(path).mtimeMs > since)
161
+ changed.push(relative(dir, path).split(sep).join("/"));
162
+ }
163
+ };
164
+ walk(dir);
165
+ return changed.sort();
166
+ }
167
+ function projectsNamed(cwd, args) {
168
+ const candidates = [cwd, ...args.filter((arg) => !arg.startsWith("-"))].flatMap((arg) => {
169
+ const path = resolve(cwd, arg);
170
+ return [path, dirname(path)];
171
+ });
172
+ return [...new Set(candidates)];
173
+ }
174
+ function appHistoryNotice(cwd, args) {
175
+ for (const dir of projectsNamed(cwd, args)) {
176
+ const { at } = readSeen(dir);
177
+ if (!at || recordChangedAt(dir, APP_HISTORY) <= at) continue;
178
+ const count = unseenTurns(dir, at).length;
179
+ if (count === 0) continue;
180
+ const where = relative(cwd, dir);
181
+ const turns = count === 1 ? "1 chat turn" : `${count} chat turns`;
182
+ return `The HyperFrames desktop app has ${turns} on this project you haven't seen. Run \`npx hyperframes catch-up${where ? ` ${where}` : ""}\` before changing it.`;
183
+ }
184
+ return null;
185
+ }
186
+ var CATCH_UP_NOTE = "> **Back from the desktop app.** Once this project was opened in the HyperFrames desktop app, run `npx hyperframes catch-up` before your next change here: it lists what the person asked Framey in the app and which files changed since.";
187
+ var SCAFFOLD_TITLE = "# HyperFrames Composition Project";
188
+ var AFTER = "> alive through review, and stop it explicitly with `preview --stop` afterward.\n";
189
+ function addCatchUpNote(dir) {
190
+ for (const name of ["CLAUDE.md", "AGENTS.md"]) {
191
+ const path = join2(dir, name);
192
+ try {
193
+ const text2 = readPlainFile(path, MAX_READ_BYTES);
194
+ if (!text2.startsWith(SCAFFOLD_TITLE) || text2.includes("hyperframes catch-up")) continue;
195
+ const next = text2.includes(AFTER) ? text2.replace(AFTER, `${AFTER}
196
+ ${CATCH_UP_NOTE}
197
+ `) : `${text2.trimEnd()}
198
+
199
+ ${CATCH_UP_NOTE}
200
+ `;
201
+ replaceFile(path, next, lstatSync2(path).mode & 511);
202
+ } catch {
203
+ }
204
+ }
205
+ }
206
+
207
+ export {
208
+ writeRecord,
209
+ APP_HISTORY,
210
+ readAppTurns,
211
+ readSeen,
212
+ markSeen,
213
+ unseenTurns,
214
+ filesChangedSince,
215
+ appHistoryNotice,
216
+ CATCH_UP_NOTE,
217
+ addCatchUpNote
218
+ };
@@ -6,7 +6,7 @@ var __filename = __hf_fileURLToPath(import.meta.url);
6
6
  var __dirname = __hf_dirname(__filename);
7
7
  import {
8
8
  setHostHandlesSigint
9
- } from "./chunk-N3KRRPL7.js";
9
+ } from "./chunk-7Y5SMPRV.js";
10
10
  import {
11
11
  processAncestorSnapshot,
12
12
  processIdentity,
@@ -7,7 +7,7 @@ var __dirname = __hf_dirname(__filename);
7
7
  import {
8
8
  getMimeType,
9
9
  injectMediaCodecMapIntoHtml
10
- } from "./chunk-FTR6KLIG.js";
10
+ } from "./chunk-GJGVYREG.js";
11
11
  import {
12
12
  PROXY_VARIANT_CONFIG,
13
13
  ProxyCapacityError,
@@ -18,10 +18,10 @@ import {
18
18
  recordProxyRequest,
19
19
  resolveProxy,
20
20
  resolveProxyVariantRequest
21
- } from "./chunk-RVG35AL2.js";
21
+ } from "./chunk-W3KQCJVP.js";
22
22
  import {
23
23
  resolveAutoProxy
24
- } from "./chunk-VNC6YQOC.js";
24
+ } from "./chunk-SZITAGRK.js";
25
25
 
26
26
  // src/utils/staticProjectServer.ts
27
27
  import { createServer } from "http";
@@ -4,10 +4,16 @@ import { dirname as __hf_dirname } from "node:path";
4
4
  var require = __hf_createRequire(import.meta.url);
5
5
  var __filename = __hf_fileURLToPath(import.meta.url);
6
6
  var __dirname = __hf_dirname(__filename);
7
+ import {
8
+ addCatchUpNote,
9
+ markSeen,
10
+ readSeen,
11
+ writeRecord
12
+ } from "./chunk-DCAI5DBR.js";
7
13
 
8
14
  // src/utils/desktopApp.ts
9
15
  import { spawn, spawnSync } from "child_process";
10
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
16
+ import { existsSync, readFileSync } from "fs";
11
17
  import { homedir } from "os";
12
18
  import { basename, isAbsolute, join, relative, win32 } from "path";
13
19
  var DESKTOP_BUNDLE_IDS = ["dev.hyperframes.desktop", "dev.hyperframes.desktop.canary"];
@@ -26,6 +32,7 @@ function agentSession(env = process.env) {
26
32
  if (env.CLAUDE_CODE_SESSION_ID)
27
33
  return { engine: "claude", sessionId: env.CLAUDE_CODE_SESSION_ID };
28
34
  if (env.CODEX_THREAD_ID) return { engine: "codex", sessionId: env.CODEX_THREAD_ID };
35
+ if (env.GROK_SESSION_ID) return { engine: "grok", sessionId: env.GROK_SESSION_ID };
29
36
  return null;
30
37
  }
31
38
  var openWithBundle = (bundleId, dir) => spawnSync("open", ["-b", bundleId, dir], { stdio: "ignore" }).status === 0;
@@ -76,14 +83,12 @@ function desktopApps({
76
83
  });
77
84
  }
78
85
  function leaveHandoff(dir, session) {
79
- if (!session) return null;
80
- try {
81
- mkdirSync(join(dir, ".hyperframes"), { recursive: true });
82
- writeFileSync(join(dir, AGENT_HANDOFF_FILE), JSON.stringify(session));
83
- return session;
84
- } catch {
85
- return null;
86
- }
86
+ if (!session || !writeRecord(dir, "agent-handoff.json", JSON.stringify(session))) return null;
87
+ const now = Date.now();
88
+ if (!readSeen(dir).at && !markSeen(dir, { at: now, checked: now }))
89
+ console.warn("\u25C7 Couldn't note the hand-off in ~/.hyperframes, so `catch-up` won't see it.");
90
+ addCatchUpNote(dir);
91
+ return session;
87
92
  }
88
93
  function openInDesktop(dir, {
89
94
  ready = HANDOFF_READY,
@@ -7,7 +7,7 @@ var __dirname = __hf_dirname(__filename);
7
7
 
8
8
  // src/utils/producer.ts
9
9
  async function loadProducer() {
10
- return await import("./src-ZPAJ44CP.js");
10
+ return await import("./src-HH4C5GZV.js");
11
11
  }
12
12
 
13
13
  export {