@rewind-ai/cli 0.6.2

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 (244) hide show
  1. package/.env.example +8 -0
  2. package/LICENSE +21 -0
  3. package/README.md +39 -0
  4. package/dist/src/action/capture.d.ts +15 -0
  5. package/dist/src/action/capture.js +215 -0
  6. package/dist/src/action/capture.js.map +1 -0
  7. package/dist/src/action/mediate.d.ts +28 -0
  8. package/dist/src/action/mediate.js +109 -0
  9. package/dist/src/action/mediate.js.map +1 -0
  10. package/dist/src/action/mutate.d.ts +11 -0
  11. package/dist/src/action/mutate.js +189 -0
  12. package/dist/src/action/mutate.js.map +1 -0
  13. package/dist/src/action/objects.d.ts +5 -0
  14. package/dist/src/action/objects.js +50 -0
  15. package/dist/src/action/objects.js.map +1 -0
  16. package/dist/src/action/store.d.ts +24 -0
  17. package/dist/src/action/store.js +149 -0
  18. package/dist/src/action/store.js.map +1 -0
  19. package/dist/src/action/types.d.ts +84 -0
  20. package/dist/src/action/types.js +3 -0
  21. package/dist/src/action/types.js.map +1 -0
  22. package/dist/src/action/undo.d.ts +11 -0
  23. package/dist/src/action/undo.js +42 -0
  24. package/dist/src/action/undo.js.map +1 -0
  25. package/dist/src/adapters/filesystem.d.ts +35 -0
  26. package/dist/src/adapters/filesystem.js +499 -0
  27. package/dist/src/adapters/filesystem.js.map +1 -0
  28. package/dist/src/adapters/index.d.ts +7 -0
  29. package/dist/src/adapters/index.js +19 -0
  30. package/dist/src/adapters/index.js.map +1 -0
  31. package/dist/src/adapters/types.d.ts +54 -0
  32. package/dist/src/adapters/types.js +7 -0
  33. package/dist/src/adapters/types.js.map +1 -0
  34. package/dist/src/api/server.d.ts +25 -0
  35. package/dist/src/api/server.js +786 -0
  36. package/dist/src/api/server.js.map +1 -0
  37. package/dist/src/approval/store.d.ts +35 -0
  38. package/dist/src/approval/store.js +113 -0
  39. package/dist/src/approval/store.js.map +1 -0
  40. package/dist/src/checkpoint.d.ts +9 -0
  41. package/dist/src/checkpoint.js +140 -0
  42. package/dist/src/checkpoint.js.map +1 -0
  43. package/dist/src/cli/v5.d.ts +15 -0
  44. package/dist/src/cli/v5.js +110 -0
  45. package/dist/src/cli/v5.js.map +1 -0
  46. package/dist/src/cli.d.ts +2 -0
  47. package/dist/src/cli.js +823 -0
  48. package/dist/src/cli.js.map +1 -0
  49. package/dist/src/clients/types.d.ts +90 -0
  50. package/dist/src/clients/types.js +239 -0
  51. package/dist/src/clients/types.js.map +1 -0
  52. package/dist/src/commercial/auth/provider.d.ts +61 -0
  53. package/dist/src/commercial/auth/provider.js +227 -0
  54. package/dist/src/commercial/auth/provider.js.map +1 -0
  55. package/dist/src/commercial/entitlement/provider.d.ts +27 -0
  56. package/dist/src/commercial/entitlement/provider.js +192 -0
  57. package/dist/src/commercial/entitlement/provider.js.map +1 -0
  58. package/dist/src/commercial/entitlement/signing.d.ts +61 -0
  59. package/dist/src/commercial/entitlement/signing.js +124 -0
  60. package/dist/src/commercial/entitlement/signing.js.map +1 -0
  61. package/dist/src/commercial/env.d.ts +10 -0
  62. package/dist/src/commercial/env.js +40 -0
  63. package/dist/src/commercial/env.js.map +1 -0
  64. package/dist/src/commercial/product.d.ts +26 -0
  65. package/dist/src/commercial/product.js +39 -0
  66. package/dist/src/commercial/product.js.map +1 -0
  67. package/dist/src/commercial/store.d.ts +46 -0
  68. package/dist/src/commercial/store.js +104 -0
  69. package/dist/src/commercial/store.js.map +1 -0
  70. package/dist/src/commercial/stripe/checkout.d.ts +104 -0
  71. package/dist/src/commercial/stripe/checkout.js +469 -0
  72. package/dist/src/commercial/stripe/checkout.js.map +1 -0
  73. package/dist/src/core/compatibility.d.ts +15 -0
  74. package/dist/src/core/compatibility.js +226 -0
  75. package/dist/src/core/compatibility.js.map +1 -0
  76. package/dist/src/core/engine.d.ts +33 -0
  77. package/dist/src/core/engine.js +432 -0
  78. package/dist/src/core/engine.js.map +1 -0
  79. package/dist/src/core/lifecycle.d.ts +17 -0
  80. package/dist/src/core/lifecycle.js +56 -0
  81. package/dist/src/core/lifecycle.js.map +1 -0
  82. package/dist/src/core/types.d.ts +140 -0
  83. package/dist/src/core/types.js +37 -0
  84. package/dist/src/core/types.js.map +1 -0
  85. package/dist/src/destroy.d.ts +21 -0
  86. package/dist/src/destroy.js +219 -0
  87. package/dist/src/destroy.js.map +1 -0
  88. package/dist/src/diff.d.ts +13 -0
  89. package/dist/src/diff.js +251 -0
  90. package/dist/src/diff.js.map +1 -0
  91. package/dist/src/enforcement/detect.d.ts +13 -0
  92. package/dist/src/enforcement/detect.js +75 -0
  93. package/dist/src/enforcement/detect.js.map +1 -0
  94. package/dist/src/enforcement/hook-policy.d.ts +38 -0
  95. package/dist/src/enforcement/hook-policy.js +111 -0
  96. package/dist/src/enforcement/hook-policy.js.map +1 -0
  97. package/dist/src/enforcement/index.d.ts +8 -0
  98. package/dist/src/enforcement/index.js +8 -0
  99. package/dist/src/enforcement/index.js.map +1 -0
  100. package/dist/src/enforcement/perf.d.ts +6 -0
  101. package/dist/src/enforcement/perf.js +18 -0
  102. package/dist/src/enforcement/perf.js.map +1 -0
  103. package/dist/src/enforcement/policy.d.ts +12 -0
  104. package/dist/src/enforcement/policy.js +84 -0
  105. package/dist/src/enforcement/policy.js.map +1 -0
  106. package/dist/src/enforcement/readonly.d.ts +17 -0
  107. package/dist/src/enforcement/readonly.js +124 -0
  108. package/dist/src/enforcement/readonly.js.map +1 -0
  109. package/dist/src/enforcement/sandbox-clone.d.ts +6 -0
  110. package/dist/src/enforcement/sandbox-clone.js +11 -0
  111. package/dist/src/enforcement/sandbox-clone.js.map +1 -0
  112. package/dist/src/enforcement/setup.d.ts +33 -0
  113. package/dist/src/enforcement/setup.js +168 -0
  114. package/dist/src/enforcement/setup.js.map +1 -0
  115. package/dist/src/enforcement/trust.d.ts +10 -0
  116. package/dist/src/enforcement/trust.js +71 -0
  117. package/dist/src/enforcement/trust.js.map +1 -0
  118. package/dist/src/enforcement/types.d.ts +40 -0
  119. package/dist/src/enforcement/types.js +3 -0
  120. package/dist/src/enforcement/types.js.map +1 -0
  121. package/dist/src/entitlement/provider.d.ts +48 -0
  122. package/dist/src/entitlement/provider.js +95 -0
  123. package/dist/src/entitlement/provider.js.map +1 -0
  124. package/dist/src/hash.d.ts +9 -0
  125. package/dist/src/hash.js +23 -0
  126. package/dist/src/hash.js.map +1 -0
  127. package/dist/src/ledger/query.d.ts +19 -0
  128. package/dist/src/ledger/query.js +158 -0
  129. package/dist/src/ledger/query.js.map +1 -0
  130. package/dist/src/manifest.d.ts +32 -0
  131. package/dist/src/manifest.js +242 -0
  132. package/dist/src/manifest.js.map +1 -0
  133. package/dist/src/mcp/server.d.ts +7 -0
  134. package/dist/src/mcp/server.js +364 -0
  135. package/dist/src/mcp/server.js.map +1 -0
  136. package/dist/src/paths.d.ts +94 -0
  137. package/dist/src/paths.js +354 -0
  138. package/dist/src/paths.js.map +1 -0
  139. package/dist/src/permission/engine.d.ts +15 -0
  140. package/dist/src/permission/engine.js +147 -0
  141. package/dist/src/permission/engine.js.map +1 -0
  142. package/dist/src/permission/types.d.ts +42 -0
  143. package/dist/src/permission/types.js +3 -0
  144. package/dist/src/permission/types.js.map +1 -0
  145. package/dist/src/product/setup.d.ts +35 -0
  146. package/dist/src/product/setup.js +300 -0
  147. package/dist/src/product/setup.js.map +1 -0
  148. package/dist/src/protect/audit.d.ts +5 -0
  149. package/dist/src/protect/audit.js +26 -0
  150. package/dist/src/protect/audit.js.map +1 -0
  151. package/dist/src/protect/capture.d.ts +7 -0
  152. package/dist/src/protect/capture.js +250 -0
  153. package/dist/src/protect/capture.js.map +1 -0
  154. package/dist/src/protect/fingerprint.d.ts +4 -0
  155. package/dist/src/protect/fingerprint.js +49 -0
  156. package/dist/src/protect/fingerprint.js.map +1 -0
  157. package/dist/src/protect/hook-cli.d.ts +2 -0
  158. package/dist/src/protect/hook-cli.js +107 -0
  159. package/dist/src/protect/hook-cli.js.map +1 -0
  160. package/dist/src/protect/index.d.ts +12 -0
  161. package/dist/src/protect/index.js +12 -0
  162. package/dist/src/protect/index.js.map +1 -0
  163. package/dist/src/protect/install.d.ts +34 -0
  164. package/dist/src/protect/install.js +293 -0
  165. package/dist/src/protect/install.js.map +1 -0
  166. package/dist/src/protect/intercept.d.ts +11 -0
  167. package/dist/src/protect/intercept.js +390 -0
  168. package/dist/src/protect/intercept.js.map +1 -0
  169. package/dist/src/protect/protect.d.ts +17 -0
  170. package/dist/src/protect/protect.js +194 -0
  171. package/dist/src/protect/protect.js.map +1 -0
  172. package/dist/src/protect/root-paths.d.ts +13 -0
  173. package/dist/src/protect/root-paths.js +140 -0
  174. package/dist/src/protect/root-paths.js.map +1 -0
  175. package/dist/src/protect/shell-policy.d.ts +17 -0
  176. package/dist/src/protect/shell-policy.js +269 -0
  177. package/dist/src/protect/shell-policy.js.map +1 -0
  178. package/dist/src/protect/status.d.ts +11 -0
  179. package/dist/src/protect/status.js +165 -0
  180. package/dist/src/protect/status.js.map +1 -0
  181. package/dist/src/protect/store.d.ts +20 -0
  182. package/dist/src/protect/store.js +170 -0
  183. package/dist/src/protect/store.js.map +1 -0
  184. package/dist/src/protect/types.d.ts +116 -0
  185. package/dist/src/protect/types.js +3 -0
  186. package/dist/src/protect/types.js.map +1 -0
  187. package/dist/src/protect/undo-session.d.ts +14 -0
  188. package/dist/src/protect/undo-session.js +182 -0
  189. package/dist/src/protect/undo-session.js.map +1 -0
  190. package/dist/src/restore.d.ts +39 -0
  191. package/dist/src/restore.js +141 -0
  192. package/dist/src/restore.js.map +1 -0
  193. package/dist/src/sandbox.d.ts +23 -0
  194. package/dist/src/sandbox.js +198 -0
  195. package/dist/src/sandbox.js.map +1 -0
  196. package/dist/src/session/ambient.d.ts +10 -0
  197. package/dist/src/session/ambient.js +53 -0
  198. package/dist/src/session/ambient.js.map +1 -0
  199. package/dist/src/session/attribution.d.ts +27 -0
  200. package/dist/src/session/attribution.js +201 -0
  201. package/dist/src/session/attribution.js.map +1 -0
  202. package/dist/src/session/index.d.ts +25 -0
  203. package/dist/src/session/index.js +472 -0
  204. package/dist/src/session/index.js.map +1 -0
  205. package/dist/src/session/process.d.ts +34 -0
  206. package/dist/src/session/process.js +234 -0
  207. package/dist/src/session/process.js.map +1 -0
  208. package/dist/src/session/store.d.ts +14 -0
  209. package/dist/src/session/store.js +125 -0
  210. package/dist/src/session/store.js.map +1 -0
  211. package/dist/src/session/types.d.ts +111 -0
  212. package/dist/src/session/types.js +3 -0
  213. package/dist/src/session/types.js.map +1 -0
  214. package/dist/src/session/watcher.d.ts +32 -0
  215. package/dist/src/session/watcher.js +186 -0
  216. package/dist/src/session/watcher.js.map +1 -0
  217. package/dist/src/timing.d.ts +7 -0
  218. package/dist/src/timing.js +19 -0
  219. package/dist/src/timing.js.map +1 -0
  220. package/dist/src/types.d.ts +101 -0
  221. package/dist/src/types.js +3 -0
  222. package/dist/src/types.js.map +1 -0
  223. package/dist/src/verify.d.ts +8 -0
  224. package/dist/src/verify.js +126 -0
  225. package/dist/src/verify.js.map +1 -0
  226. package/docs/ADAPTERS.md +37 -0
  227. package/docs/APPROVALS.md +32 -0
  228. package/docs/ARCHITECTURE.md +57 -0
  229. package/docs/ATTRIBUTION.md +179 -0
  230. package/docs/COMMERCIAL.md +51 -0
  231. package/docs/CURSOR-ENFORCEMENT.md +73 -0
  232. package/docs/ENFORCEMENT.md +134 -0
  233. package/docs/FUTURE.md +91 -0
  234. package/docs/HUMAN-SETUP.md +98 -0
  235. package/docs/IDENTITY-AUTHORITY.md +35 -0
  236. package/docs/MCP.md +107 -0
  237. package/docs/PACKAGING.md +77 -0
  238. package/docs/PERMISSIONS.md +53 -0
  239. package/docs/PRODUCT-V5.md +63 -0
  240. package/docs/PRODUCT-V6.md +69 -0
  241. package/docs/PROTECTED-SESSIONS.md +155 -0
  242. package/docs/THREAT-MODEL.md +84 -0
  243. package/docs/TRANSACTIONS.md +57 -0
  244. package/package.json +85 -0
@@ -0,0 +1,234 @@
1
+ import { execFile } from "node:child_process";
2
+ import { promisify } from "node:util";
3
+ const execFileAsync = promisify(execFile);
4
+ async function run(cmd, args, timeoutMs = 5000) {
5
+ try {
6
+ const { stdout, stderr } = await execFileAsync(cmd, args, {
7
+ timeout: timeoutMs,
8
+ maxBuffer: 8 * 1024 * 1024,
9
+ encoding: "utf8",
10
+ });
11
+ return { stdout: stdout ?? "", stderr: stderr ?? "" };
12
+ }
13
+ catch (err) {
14
+ const e = err;
15
+ return {
16
+ stdout: e.stdout ?? "",
17
+ stderr: e.stderr ?? "",
18
+ error: e.message ?? String(err),
19
+ };
20
+ }
21
+ }
22
+ function parsePs(stdout) {
23
+ const lines = stdout.split("\n").filter((l) => l.trim().length > 0);
24
+ // Expect: PID PPID USER COMMAND... (command may contain spaces if we use -o args=)
25
+ const out = [];
26
+ for (const line of lines) {
27
+ const m = line.match(/^\s*(\d+)\s+(\d+)\s+(\S+)\s+(.*)$/);
28
+ if (!m)
29
+ continue;
30
+ const pid = Number(m[1]);
31
+ const ppid = Number(m[2]);
32
+ const user = m[3];
33
+ const rest = m[4].trim();
34
+ if (!Number.isFinite(pid))
35
+ continue;
36
+ out.push({
37
+ pid,
38
+ ppid,
39
+ user,
40
+ command: rest.split(/\s+/)[0] ?? rest,
41
+ args: rest,
42
+ });
43
+ }
44
+ return out;
45
+ }
46
+ function isCursorRelated(p) {
47
+ const hay = `${p.command} ${p.args ?? ""}`.toLowerCase();
48
+ return (hay.includes("cursor") ||
49
+ hay.includes("cursor helper") ||
50
+ hay.includes("cursor agent") ||
51
+ /\/cursor\.app\//i.test(hay));
52
+ }
53
+ function buildTrees(processes, rootPids) {
54
+ const byParent = new Map();
55
+ for (const p of processes) {
56
+ const list = byParent.get(p.ppid) ?? [];
57
+ list.push(p);
58
+ byParent.set(p.ppid, list);
59
+ }
60
+ const build = (p, depth) => {
61
+ const children = depth > 12
62
+ ? []
63
+ : (byParent.get(p.pid) ?? []).map((c) => build(c, depth + 1));
64
+ return {
65
+ pid: p.pid,
66
+ ppid: p.ppid,
67
+ command: p.args ?? p.command,
68
+ children,
69
+ };
70
+ };
71
+ const byPid = new Map(processes.map((p) => [p.pid, p]));
72
+ const roots = [];
73
+ for (const pid of rootPids) {
74
+ const p = byPid.get(pid);
75
+ if (p)
76
+ roots.push(build(p, 0));
77
+ }
78
+ return roots;
79
+ }
80
+ export function formatProcessTree(nodes, indent = "") {
81
+ const lines = [];
82
+ for (const n of nodes) {
83
+ lines.push(`${indent}${n.command} (pid ${n.pid})`);
84
+ if (n.children.length) {
85
+ lines.push(formatProcessTree(n.children, indent + " "));
86
+ }
87
+ }
88
+ return lines.join("\n");
89
+ }
90
+ /**
91
+ * Snapshot process table and attempt to identify Cursor-related hierarchy.
92
+ * Honest: may fail under sandbox/TCC; errors are recorded, not invented.
93
+ */
94
+ export async function captureProcessSnapshot() {
95
+ const notes = [];
96
+ const errors = [];
97
+ const capturedAt = new Date().toISOString();
98
+ // Prefer args-capable listing; fall back to comm-only.
99
+ let ps = await run("/bin/ps", ["-axo", "pid=,ppid=,user=,args="]);
100
+ if (ps.error && !ps.stdout) {
101
+ errors.push(`ps args failed: ${ps.error}`);
102
+ ps = await run("/bin/ps", ["-axo", "pid=,ppid=,user=,comm="]);
103
+ }
104
+ if (ps.error && !ps.stdout) {
105
+ errors.push(`ps failed: ${ps.error}`);
106
+ }
107
+ const processes = parsePs(ps.stdout);
108
+ if (processes.length === 0) {
109
+ notes.push("Process list empty or inaccessible — TCC/sandbox may block process enumeration.");
110
+ }
111
+ const cursorRelated = processes.filter(isCursorRelated);
112
+ notes.push(cursorRelated.length > 0
113
+ ? `Found ${cursorRelated.length} Cursor-related process(es).`
114
+ : "No Cursor-related processes matched name heuristics in process table.");
115
+ // Root candidates: Cursor main app processes (shortest path / no Cursor parent)
116
+ const cursorPids = new Set(cursorRelated.map((p) => p.pid));
117
+ const roots = new Set();
118
+ for (const p of cursorRelated) {
119
+ if (!cursorPids.has(p.ppid))
120
+ roots.add(p.pid);
121
+ }
122
+ const treeRoots = buildTrees(processes, roots);
123
+ // lsof probe: who has the sandbox open? Caller may pass path via separate fn.
124
+ return {
125
+ capturedAt,
126
+ processes: cursorRelated.length
127
+ ? // Keep full table only if manageable; otherwise store cursor-related + sample
128
+ processes.length > 2000
129
+ ? cursorRelated
130
+ : processes
131
+ : processes.slice(0, 500),
132
+ cursorRelated,
133
+ treeRoots,
134
+ notes,
135
+ errors,
136
+ };
137
+ }
138
+ /**
139
+ * Use lsof to find processes with open handles under a path.
140
+ * This is correlative / weak: short writes often leave no open handle.
141
+ * Avoid `lsof +D` — it recursively walks and can hang on large trees.
142
+ */
143
+ export async function lsofSandboxHolders(sandboxPath) {
144
+ // Bound tightly: lsof without +D on the directory node + a filtered full listing sample.
145
+ const direct = await run("/usr/sbin/lsof", ["-nP", sandboxPath], 2500);
146
+ const filtered = await run("/bin/sh", [
147
+ "-c",
148
+ // shell-escape path lightly
149
+ `lsof -nP 2>/dev/null | grep -F -- ${JSON.stringify(sandboxPath)} | head -n 40`,
150
+ ], 3000);
151
+ const combined = [direct.stdout, filtered.stdout]
152
+ .join("\n")
153
+ .split("\n")
154
+ .map((l) => l.trim())
155
+ .filter(Boolean);
156
+ const data = combined.filter((l) => !l.startsWith("COMMAND"));
157
+ const pids = [];
158
+ for (const line of data) {
159
+ const parts = line.split(/\s+/);
160
+ const pid = Number(parts[1]);
161
+ if (Number.isFinite(pid))
162
+ pids.push(pid);
163
+ }
164
+ const err = direct.error && filtered.error
165
+ ? `${direct.error}; ${filtered.error}`
166
+ : direct.error || filtered.error;
167
+ if (err && data.length === 0) {
168
+ return {
169
+ lines: [],
170
+ pids: [],
171
+ error: err,
172
+ note: "lsof failed or denied — cannot correlate open handles.",
173
+ };
174
+ }
175
+ return {
176
+ lines: [...new Set(data)].slice(0, 100),
177
+ pids: [...new Set(pids)],
178
+ note: data.length === 0
179
+ ? "lsof found no open handles under sandbox (common for completed short writes)."
180
+ : `lsof found ${data.length} open handle line(s) (non-recursive probe).`,
181
+ };
182
+ }
183
+ /**
184
+ * Probe whether eslogger / Endpoint Security is usable without entitlements.
185
+ */
186
+ export async function probeEndpointSecurityAccess() {
187
+ const which = await run("/usr/bin/which", ["eslogger"]);
188
+ if (!which.stdout.trim()) {
189
+ return {
190
+ available: false,
191
+ detail: "eslogger binary not found",
192
+ tested: true,
193
+ };
194
+ }
195
+ const probe = await run("/usr/bin/eslogger", ["--list-events"], 3000);
196
+ // Creating an ES client requires root; this call should fail fast when unprivileged.
197
+ // Do not leave eslogger running as an event stream.
198
+ const create = await run("/usr/bin/eslogger", ["create"], 1500);
199
+ const createText = `${create.stdout} ${create.stderr} ${create.error ?? ""}`;
200
+ const detail = [
201
+ `eslogger present: ${which.stdout.trim()}`,
202
+ probe.error
203
+ ? `list-events: ${probe.error}`
204
+ : `list-events: ok (${probe.stdout.split("\n").filter(Boolean).length} event types)`,
205
+ `create-probe: ${createText.trim().slice(0, 300) || "no output"}`,
206
+ ].join(" | ");
207
+ const available = !/Not privileged|NOT_PRIVILEGED|Full Disk Access|NOT_PERMITTED|Operation not permitted|killed|ETIMEOUT|timeout/i.test(createText) && /\{|"event"/.test(createText);
208
+ return {
209
+ available,
210
+ detail,
211
+ tested: true,
212
+ };
213
+ }
214
+ /**
215
+ * Try fs_usage briefly — usually requires root.
216
+ */
217
+ export async function probeFsUsage() {
218
+ // fs_usage usually needs root; execFile timeout kills the child on macOS (no GNU timeout).
219
+ const result = await run("/usr/bin/fs_usage", ["-w", "-t", "1"], 2000);
220
+ const text = `${result.stdout} ${result.stderr} ${result.error ?? ""}`;
221
+ if (/permission|privileged|sudo|must be root|not permitted/i.test(text)) {
222
+ return {
223
+ usable: false,
224
+ detail: text.trim().slice(0, 400) || "fs_usage failed",
225
+ tested: true,
226
+ };
227
+ }
228
+ return {
229
+ usable: /open|write|read|fs_usage/i.test(result.stdout),
230
+ detail: text.trim().slice(0, 400) || "fs_usage produced no usable output",
231
+ tested: true,
232
+ };
233
+ }
234
+ //# sourceMappingURL=process.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.js","sourceRoot":"","sources":["../../../src/session/process.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { ActiveSessionPointer, ObservedEvent, RewindSession } from "./types.js";
2
+ export declare function sessionDir(sessionId: string, projectRoot?: string): string;
3
+ export declare function ensureSessionsRoot(projectRoot?: string): Promise<string>;
4
+ export declare function saveSession(session: RewindSession, projectRoot?: string): Promise<string>;
5
+ export declare function loadSession(sessionId?: string | "latest", projectRoot?: string): Promise<RewindSession>;
6
+ export declare function appendEvent(sessionId: string, event: ObservedEvent, projectRoot?: string): Promise<void>;
7
+ export declare function readEvents(sessionId: string, projectRoot?: string): Promise<ObservedEvent[]>;
8
+ export declare function activePointerPath(projectRoot?: string): string;
9
+ export declare function writeActivePointer(pointer: ActiveSessionPointer, projectRoot?: string): Promise<void>;
10
+ export declare function readActivePointer(projectRoot?: string): Promise<ActiveSessionPointer | null>;
11
+ export declare function clearActivePointer(projectRoot?: string): Promise<void>;
12
+ export declare function requestStop(projectRoot?: string): Promise<ActiveSessionPointer>;
13
+ export declare function stopFlagExists(sessionId: string, projectRoot?: string): Promise<boolean>;
14
+ export declare function clearStopFlag(sessionId: string, projectRoot?: string): Promise<void>;
@@ -0,0 +1,125 @@
1
+ import path from "node:path";
2
+ import { mkdir, readFile, writeFile, appendFile, rm, access, } from "node:fs/promises";
3
+ import { constants as fsConstants } from "node:fs";
4
+ import { getProjectRoot, getSessionsDir, PathSafetyError, } from "../paths.js";
5
+ function assertSafeSessionId(id) {
6
+ if (id.includes("..") ||
7
+ id.includes("/") ||
8
+ id.includes("\\") ||
9
+ id.includes("\0") ||
10
+ id.length === 0 ||
11
+ id.length > 120 ||
12
+ !/^sess-[A-Za-z0-9-]+$/.test(id)) {
13
+ throw new PathSafetyError(`Invalid session id: ${id}`);
14
+ }
15
+ return id;
16
+ }
17
+ export function sessionDir(sessionId, projectRoot = getProjectRoot()) {
18
+ return path.join(getSessionsDir(projectRoot), assertSafeSessionId(sessionId));
19
+ }
20
+ export async function ensureSessionsRoot(projectRoot = getProjectRoot()) {
21
+ const dir = getSessionsDir(projectRoot);
22
+ await mkdir(dir, { recursive: true });
23
+ return dir;
24
+ }
25
+ async function writeJsonAtomic(file, data) {
26
+ await mkdir(path.dirname(file), { recursive: true });
27
+ const tmp = `${file}.tmp-${process.pid}`;
28
+ await writeFile(tmp, JSON.stringify(data, null, 2) + "\n", "utf8");
29
+ const { rename } = await import("node:fs/promises");
30
+ await rename(tmp, file);
31
+ }
32
+ export async function saveSession(session, projectRoot = getProjectRoot()) {
33
+ const dir = sessionDir(session.id, projectRoot);
34
+ await mkdir(dir, { recursive: true });
35
+ const file = path.join(dir, "session.json");
36
+ await writeJsonAtomic(file, session);
37
+ await writeJsonAtomic(path.join(getSessionsDir(projectRoot), "latest.json"), {
38
+ id: session.id,
39
+ });
40
+ return file;
41
+ }
42
+ export async function loadSession(sessionId = "latest", projectRoot = getProjectRoot()) {
43
+ let id = sessionId;
44
+ if (sessionId === "latest") {
45
+ const latestPath = path.join(getSessionsDir(projectRoot), "latest.json");
46
+ try {
47
+ const raw = await readFile(latestPath, "utf8");
48
+ id = JSON.parse(raw).id;
49
+ }
50
+ catch {
51
+ throw new PathSafetyError("No session found. Start one with session start.");
52
+ }
53
+ }
54
+ const file = path.join(sessionDir(id, projectRoot), "session.json");
55
+ try {
56
+ const raw = await readFile(file, "utf8");
57
+ return JSON.parse(raw);
58
+ }
59
+ catch {
60
+ throw new PathSafetyError(`Session not found or unreadable: ${id}`);
61
+ }
62
+ }
63
+ export async function appendEvent(sessionId, event, projectRoot = getProjectRoot()) {
64
+ const file = path.join(sessionDir(sessionId, projectRoot), "events.jsonl");
65
+ await mkdir(path.dirname(file), { recursive: true });
66
+ await appendFile(file, JSON.stringify(event) + "\n", "utf8");
67
+ }
68
+ export async function readEvents(sessionId, projectRoot = getProjectRoot()) {
69
+ const file = path.join(sessionDir(sessionId, projectRoot), "events.jsonl");
70
+ try {
71
+ const raw = await readFile(file, "utf8");
72
+ return raw
73
+ .split("\n")
74
+ .filter((l) => l.trim())
75
+ .map((l) => JSON.parse(l));
76
+ }
77
+ catch {
78
+ return [];
79
+ }
80
+ }
81
+ export function activePointerPath(projectRoot = getProjectRoot()) {
82
+ return path.join(getSessionsDir(projectRoot), "active.json");
83
+ }
84
+ export async function writeActivePointer(pointer, projectRoot = getProjectRoot()) {
85
+ await ensureSessionsRoot(projectRoot);
86
+ await writeJsonAtomic(activePointerPath(projectRoot), pointer);
87
+ }
88
+ export async function readActivePointer(projectRoot = getProjectRoot()) {
89
+ try {
90
+ const raw = await readFile(activePointerPath(projectRoot), "utf8");
91
+ return JSON.parse(raw);
92
+ }
93
+ catch {
94
+ return null;
95
+ }
96
+ }
97
+ export async function clearActivePointer(projectRoot = getProjectRoot()) {
98
+ await rm(activePointerPath(projectRoot), { force: true });
99
+ }
100
+ export async function requestStop(projectRoot = getProjectRoot()) {
101
+ const active = await readActivePointer(projectRoot);
102
+ if (!active) {
103
+ throw new PathSafetyError("No active session to stop.");
104
+ }
105
+ active.stopRequested = true;
106
+ await writeActivePointer(active, projectRoot);
107
+ // Also write a stop flag file the watcher polls
108
+ await writeFile(path.join(sessionDir(active.id, projectRoot), "STOP"), new Date().toISOString() + "\n", "utf8");
109
+ return active;
110
+ }
111
+ export async function stopFlagExists(sessionId, projectRoot = getProjectRoot()) {
112
+ try {
113
+ await access(path.join(sessionDir(sessionId, projectRoot), "STOP"), fsConstants.F_OK);
114
+ return true;
115
+ }
116
+ catch {
117
+ return false;
118
+ }
119
+ }
120
+ export async function clearStopFlag(sessionId, projectRoot = getProjectRoot()) {
121
+ await rm(path.join(sessionDir(sessionId, projectRoot), "STOP"), {
122
+ force: true,
123
+ });
124
+ }
125
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/session/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,111 @@
1
+ /** V1 session / attribution types. Extends V0 concepts without replacing them. */
2
+ import type { Change } from "../types.js";
3
+ export type ObservedEventType = "CREATE" | "MODIFY" | "DELETE" | "RENAME" | "DIRECTORY_CREATE" | "DIRECTORY_DELETE" | "UNKNOWN";
4
+ export type ActorKind = "AGENT" | "USER" | "SYSTEM" | "UNKNOWN";
5
+ export type AttributionConfidence = "HIGH" | "MEDIUM" | "LOW" | "NONE";
6
+ export type SessionStatus = "watching" | "stopping" | "completed" | "rewound" | "failed" | "crashed";
7
+ export interface AttributionEvidence {
8
+ kind: string;
9
+ detail: string;
10
+ observedAt?: string;
11
+ }
12
+ export interface ProcessInfo {
13
+ pid: number;
14
+ ppid: number;
15
+ user: string;
16
+ command: string;
17
+ args?: string;
18
+ }
19
+ export interface ProcessSnapshot {
20
+ capturedAt: string;
21
+ processes: ProcessInfo[];
22
+ cursorRelated: ProcessInfo[];
23
+ treeRoots: ProcessTreeNode[];
24
+ notes: string[];
25
+ errors: string[];
26
+ }
27
+ export interface ProcessTreeNode {
28
+ pid: number;
29
+ ppid: number;
30
+ command: string;
31
+ children: ProcessTreeNode[];
32
+ }
33
+ export interface ObservedEvent {
34
+ id: string;
35
+ at: string;
36
+ type: ObservedEventType;
37
+ path: string;
38
+ pathFrom?: string;
39
+ /** Coalesced raw watcher signals that produced this event. */
40
+ rawCount: number;
41
+ /** Attribution guess at observation time — often UNKNOWN. */
42
+ actor: ActorKind;
43
+ confidence: AttributionConfidence;
44
+ evidence: AttributionEvidence[];
45
+ ambientSuspect: boolean;
46
+ }
47
+ export interface AttributedChange {
48
+ change: Change;
49
+ actor: ActorKind;
50
+ confidence: AttributionConfidence;
51
+ evidence: AttributionEvidence[];
52
+ ambient: boolean;
53
+ correlatedEvents: string[];
54
+ }
55
+ export interface AttributionSummary {
56
+ total: number;
57
+ likelyAgent: number;
58
+ likelyHuman: number;
59
+ ambientSystem: number;
60
+ unknown: number;
61
+ confidenceHigh: number;
62
+ confidenceMedium: number;
63
+ confidenceLow: number;
64
+ confidenceNone: number;
65
+ }
66
+ export interface SessionMetrics {
67
+ watcherIdleCpuSample?: number;
68
+ eventsObserved: number;
69
+ eventsPerSecondPeak: number;
70
+ memoryRssMbStart?: number;
71
+ memoryRssMbEnd?: number;
72
+ checkpointMs?: number;
73
+ finalDiffMs?: number;
74
+ rewindMs?: number;
75
+ watchDurationMs: number;
76
+ }
77
+ export interface RewindSession {
78
+ id: string;
79
+ version: 1;
80
+ targetPath: string;
81
+ checkpointId: string;
82
+ checkpointFingerprint: string;
83
+ startedAt: string;
84
+ endedAt: string | null;
85
+ watcherPid: number | null;
86
+ observedEvents: ObservedEvent[];
87
+ finalChanges: Change[];
88
+ attributedChanges: AttributedChange[];
89
+ processes: ProcessSnapshot[];
90
+ attributionConfidenceOverall: AttributionConfidence;
91
+ attributionSummary: AttributionSummary | null;
92
+ status: SessionStatus;
93
+ metrics: SessionMetrics;
94
+ notes: string[];
95
+ /** Selective agent-only rewind is intentionally gated. */
96
+ selectiveRewindEnabled: boolean;
97
+ selectiveRewindReason: string;
98
+ }
99
+ export interface ActiveSessionPointer {
100
+ id: string;
101
+ watcherPid: number;
102
+ startedAt: string;
103
+ targetPath: string;
104
+ checkpointId: string;
105
+ stopRequested: boolean;
106
+ }
107
+ export interface SessionReport {
108
+ session: RewindSession;
109
+ lines: string[];
110
+ }
111
+ export type { Change };
@@ -0,0 +1,3 @@
1
+ /** V1 session / attribution types. Extends V0 concepts without replacing them. */
2
+ export {};
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/session/types.ts"],"names":[],"mappings":"AAAA,kFAAkF"}
@@ -0,0 +1,32 @@
1
+ import type { ObservedEvent } from "./types.js";
2
+ export interface WatcherStats {
3
+ rawSignals: number;
4
+ emittedEvents: number;
5
+ peakEventsPerSec: number;
6
+ }
7
+ export type WatchEventHandler = (event: ObservedEvent) => void;
8
+ /**
9
+ * Live sandbox watcher.
10
+ * Uses chokidar (FSEvents on macOS) with debounce/coalesce.
11
+ * Events are signals — final manifest diff remains authoritative.
12
+ */
13
+ export declare class SandboxWatcher {
14
+ private readonly sandboxRoot;
15
+ private readonly onEvent;
16
+ private watcher;
17
+ private pending;
18
+ private closed;
19
+ private readonly debounceMs;
20
+ readonly stats: WatcherStats;
21
+ private windowCount;
22
+ private windowTimer;
23
+ constructor(sandboxRoot: string, onEvent: WatchEventHandler, options?: {
24
+ debounceMs?: number;
25
+ projectRoot?: string;
26
+ });
27
+ start(projectRoot?: string): Promise<void>;
28
+ private handleRaw;
29
+ private flush;
30
+ private classify;
31
+ stop(): Promise<WatcherStats>;
32
+ }