@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,168 @@
1
+ import path from "node:path";
2
+ import { mkdir, writeFile, readFile, rm, chmod } from "node:fs/promises";
3
+ import { spawn } from "node:child_process";
4
+ import { ENFORCED_SANDBOX_DIR_NAME, PathSafetyError, getEnforcementDir, getEnforcedSandboxPath, getProjectRoot, isPathInside, } from "../paths.js";
5
+ import { SANDBOX_SEED } from "../sandbox.js";
6
+ import { planSandboxForRoot } from "./sandbox-clone.js";
7
+ import { lockEnforcedReadonly, unlockEnforcedWritable } from "./readonly.js";
8
+ import { recordPolicyEvent } from "./policy.js";
9
+ const STATE_FILE = "state.json";
10
+ async function writeJsonAtomic(file, data) {
11
+ await mkdir(path.dirname(file), { recursive: true });
12
+ const tmp = `${file}.tmp-${process.pid}`;
13
+ await writeFile(tmp, JSON.stringify(data, null, 2) + "\n", "utf8");
14
+ const { rename } = await import("node:fs/promises");
15
+ await rename(tmp, file);
16
+ }
17
+ export function enforcementStatePath(projectRoot = getProjectRoot()) {
18
+ return path.join(getEnforcementDir(projectRoot), STATE_FILE);
19
+ }
20
+ export async function loadEnforcementState(projectRoot = getProjectRoot()) {
21
+ try {
22
+ const raw = await readFile(enforcementStatePath(projectRoot), "utf8");
23
+ return JSON.parse(raw);
24
+ }
25
+ catch {
26
+ return null;
27
+ }
28
+ }
29
+ export async function saveEnforcementState(state, projectRoot = getProjectRoot()) {
30
+ await writeJsonAtomic(enforcementStatePath(projectRoot), state);
31
+ }
32
+ /**
33
+ * Create sandbox-enforced-project from the same deterministic plan as V0,
34
+ * without touching sandbox-test-project.
35
+ */
36
+ export async function createEnforcedSandbox(projectRoot = getProjectRoot()) {
37
+ const root = getEnforcedSandboxPath(projectRoot);
38
+ if (path.basename(root) !== ENFORCED_SANDBOX_DIR_NAME) {
39
+ throw new PathSafetyError("Refusing unexpected enforced sandbox name");
40
+ }
41
+ if (path.dirname(root) !== path.resolve(projectRoot)) {
42
+ throw new PathSafetyError("Enforced sandbox not under project root");
43
+ }
44
+ const testSandbox = path.join(projectRoot, "sandbox-test-project");
45
+ if (root === testSandbox) {
46
+ throw new PathSafetyError("Refusing to recreate test sandbox as enforced");
47
+ }
48
+ await chmod(root, 0o755).catch(() => undefined);
49
+ await unlockEnforcedWritable(projectRoot).catch(() => undefined);
50
+ const result = await planSandboxForRoot(root, SANDBOX_SEED);
51
+ return { root, ...result };
52
+ }
53
+ export async function writeSeatbeltProfile(projectRoot = getProjectRoot()) {
54
+ const dir = getEnforcementDir(projectRoot);
55
+ await mkdir(dir, { recursive: true });
56
+ const enforced = getEnforcedSandboxPath(projectRoot);
57
+ const profilePath = path.join(dir, "agent-deny-enforced-write.sb");
58
+ const body = `(version 1)
59
+ (allow default)
60
+ (deny file-write* (subpath "${enforced}"))
61
+ `;
62
+ await writeFile(profilePath, body, "utf8");
63
+ return profilePath;
64
+ }
65
+ /**
66
+ * Run a command under sandbox-exec with writes to enforced sandbox denied.
67
+ */
68
+ export function runUnderWriteDenySeatbelt(command, args, profilePath) {
69
+ return new Promise((resolve) => {
70
+ const child = spawn("sandbox-exec", ["-f", profilePath, command, ...args], {
71
+ stdio: ["ignore", "pipe", "pipe"],
72
+ });
73
+ let stdout = "";
74
+ let stderr = "";
75
+ child.stdout.on("data", (d) => {
76
+ stdout += d.toString("utf8");
77
+ });
78
+ child.stderr.on("data", (d) => {
79
+ stderr += d.toString("utf8");
80
+ });
81
+ child.on("close", (code) => {
82
+ resolve({ code: code ?? 1, stdout, stderr });
83
+ });
84
+ });
85
+ }
86
+ export async function enableEnforcement(projectRoot = getProjectRoot(), options = {}) {
87
+ const mechanism = options.mechanism ?? "combined";
88
+ await createEnforcedSandbox(projectRoot);
89
+ const profilePath = mechanism === "sandbox-exec" || mechanism === "combined"
90
+ ? await writeSeatbeltProfile(projectRoot)
91
+ : null;
92
+ if (mechanism === "fs-readonly" || mechanism === "combined") {
93
+ await lockEnforcedReadonly(projectRoot);
94
+ }
95
+ const hooksInstalled = options.installHooks !== false;
96
+ const now = new Date().toISOString();
97
+ const state = {
98
+ version: 3,
99
+ enabled: true,
100
+ mechanism,
101
+ sandboxName: ENFORCED_SANDBOX_DIR_NAME,
102
+ locked: mechanism === "fs-readonly" || mechanism === "combined",
103
+ createdAt: now,
104
+ updatedAt: now,
105
+ hooksInstalled,
106
+ seatbeltProfilePath: profilePath,
107
+ notes: [
108
+ "fs-readonly: same UID; broker unlocks for mediated writes",
109
+ "sandbox-exec: restricts child processes only; Cursor itself is not wrapped unless launched under it",
110
+ "cursor-hooks: vendor tool-loop enforcement; not OS filesystem enforcement",
111
+ "Human editor writes are NOT blocked by Cursor agent hooks",
112
+ ],
113
+ };
114
+ await saveEnforcementState(state, projectRoot);
115
+ await recordPolicyEvent({
116
+ type: "ENFORCEMENT_ENABLED",
117
+ path: ENFORCED_SANDBOX_DIR_NAME,
118
+ mechanism,
119
+ evidence: `Enforcement enabled mechanism=${mechanism} locked=${state.locked}`,
120
+ status: "RECORDED",
121
+ }, projectRoot);
122
+ return state;
123
+ }
124
+ export async function disableEnforcement(projectRoot = getProjectRoot(), options = {}) {
125
+ const state = await loadEnforcementState(projectRoot);
126
+ try {
127
+ await unlockEnforcedWritable(projectRoot);
128
+ }
129
+ catch {
130
+ /* may not exist */
131
+ }
132
+ if (options.removeTree) {
133
+ const root = getEnforcedSandboxPath(projectRoot);
134
+ if (path.basename(root) === ENFORCED_SANDBOX_DIR_NAME &&
135
+ isPathInside(path.resolve(projectRoot), root)) {
136
+ await chmod(root, 0o755).catch(() => undefined);
137
+ await unlockEnforcedWritable(projectRoot).catch(() => undefined);
138
+ await rm(root, { recursive: true, force: true });
139
+ }
140
+ }
141
+ const now = new Date().toISOString();
142
+ const next = {
143
+ version: 3,
144
+ enabled: false,
145
+ mechanism: "none",
146
+ sandboxName: ENFORCED_SANDBOX_DIR_NAME,
147
+ locked: false,
148
+ createdAt: state?.createdAt ?? now,
149
+ updatedAt: now,
150
+ hooksInstalled: false,
151
+ seatbeltProfilePath: null,
152
+ notes: ["Enforcement disabled"],
153
+ };
154
+ await saveEnforcementState(next, projectRoot);
155
+ await recordPolicyEvent({
156
+ type: "ENFORCEMENT_DISABLED",
157
+ path: ENFORCED_SANDBOX_DIR_NAME,
158
+ mechanism: state?.mechanism ?? "none",
159
+ evidence: "Enforcement disabled; tree unlocked",
160
+ status: "RECORDED",
161
+ }, projectRoot);
162
+ }
163
+ /** True when mediated writes to enforced sandbox must use broker unlock. */
164
+ export async function isEnforcedLocked(projectRoot = getProjectRoot()) {
165
+ const state = await loadEnforcementState(projectRoot);
166
+ return Boolean(state?.enabled && state.locked);
167
+ }
168
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../src/enforcement/setup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { PathTrustRecord, PathTrustState } from "./types.js";
2
+ export declare function setPathTrust(relPath: string, state: PathTrustState, meta?: {
3
+ lastMediatedActionId?: string | null;
4
+ lastPolicyEventId?: string | null;
5
+ note?: string | null;
6
+ }, projectRoot?: string): Promise<PathTrustRecord>;
7
+ export declare function markAuthoritative(relPath: string, actionId: string, projectRoot?: string): Promise<PathTrustRecord>;
8
+ export declare function markUntrusted(relPath: string, policyEventId: string, note: string, projectRoot?: string): Promise<PathTrustRecord>;
9
+ export declare function getPathTrust(relPath: string, projectRoot?: string): Promise<PathTrustRecord | null>;
10
+ export declare function listTrustRecords(projectRoot?: string): Promise<PathTrustRecord[]>;
@@ -0,0 +1,71 @@
1
+ import path from "node:path";
2
+ import { mkdir, writeFile, readFile, readdir, rename } from "node:fs/promises";
3
+ import { getProjectRoot, getTrustDir } from "../paths.js";
4
+ function trustKey(relPath) {
5
+ return relPath.replace(/[^A-Za-z0-9._-]+/g, "__").slice(0, 180);
6
+ }
7
+ async function writeJsonAtomic(file, data) {
8
+ await mkdir(path.dirname(file), { recursive: true });
9
+ const tmp = `${file}.tmp-${process.pid}`;
10
+ await writeFile(tmp, JSON.stringify(data, null, 2) + "\n", "utf8");
11
+ await rename(tmp, file);
12
+ }
13
+ export async function setPathTrust(relPath, state, meta = {}, projectRoot = getProjectRoot()) {
14
+ const record = {
15
+ path: relPath,
16
+ state,
17
+ updatedAt: new Date().toISOString(),
18
+ lastMediatedActionId: meta.lastMediatedActionId ?? null,
19
+ lastPolicyEventId: meta.lastPolicyEventId ?? null,
20
+ note: meta.note ?? null,
21
+ };
22
+ const dir = getTrustDir(projectRoot);
23
+ await mkdir(dir, { recursive: true });
24
+ await writeJsonAtomic(path.join(dir, `${trustKey(relPath)}.json`), record);
25
+ return record;
26
+ }
27
+ export async function markAuthoritative(relPath, actionId, projectRoot = getProjectRoot()) {
28
+ return setPathTrust(relPath, "AUTHORITATIVE", {
29
+ lastMediatedActionId: actionId,
30
+ note: "Updated by mediated REWIND action",
31
+ }, projectRoot);
32
+ }
33
+ export async function markUntrusted(relPath, policyEventId, note, projectRoot = getProjectRoot()) {
34
+ return setPathTrust(relPath, "UNTRUSTED", {
35
+ lastPolicyEventId: policyEventId,
36
+ note,
37
+ }, projectRoot);
38
+ }
39
+ export async function getPathTrust(relPath, projectRoot = getProjectRoot()) {
40
+ try {
41
+ const raw = await readFile(path.join(getTrustDir(projectRoot), `${trustKey(relPath)}.json`), "utf8");
42
+ return JSON.parse(raw);
43
+ }
44
+ catch {
45
+ return null;
46
+ }
47
+ }
48
+ export async function listTrustRecords(projectRoot = getProjectRoot()) {
49
+ const dir = getTrustDir(projectRoot);
50
+ let names;
51
+ try {
52
+ names = await readdir(dir);
53
+ }
54
+ catch {
55
+ return [];
56
+ }
57
+ const out = [];
58
+ for (const n of names) {
59
+ if (!n.endsWith(".json"))
60
+ continue;
61
+ try {
62
+ const raw = await readFile(path.join(dir, n), "utf8");
63
+ out.push(JSON.parse(raw));
64
+ }
65
+ catch {
66
+ /* skip */
67
+ }
68
+ }
69
+ return out.sort((a, b) => a.path.localeCompare(b.path));
70
+ }
71
+ //# sourceMappingURL=trust.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trust.js","sourceRoot":"","sources":["../../../src/enforcement/trust.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /** V3 enforcement / policy types. */
2
+ export type PolicyEventType = "BYPASS_ATTEMPT" | "BLOCKED_WRITE" | "UNKNOWN_MUTATION" | "ENFORCEMENT_ENABLED" | "ENFORCEMENT_DISABLED" | "WRAPPER_DENIED";
3
+ export type PolicyEventStatus = "RECORDED" | "BLOCKED" | "DETECTED" | "UNTRUSTED";
4
+ export interface PolicyEvent {
5
+ id: string;
6
+ version: 3;
7
+ time: string;
8
+ type: PolicyEventType;
9
+ path: string | null;
10
+ mechanism: string;
11
+ evidence: string;
12
+ status: PolicyEventStatus;
13
+ }
14
+ export type PathTrustState = "AUTHORITATIVE" | "UNTRUSTED";
15
+ export interface PathTrustRecord {
16
+ path: string;
17
+ state: PathTrustState;
18
+ updatedAt: string;
19
+ lastMediatedActionId: string | null;
20
+ lastPolicyEventId: string | null;
21
+ note: string | null;
22
+ }
23
+ export type EnforcementMechanism = "none" | "fs-readonly" | "sandbox-exec" | "cursor-hooks" | "combined";
24
+ export interface EnforcementState {
25
+ version: 3;
26
+ enabled: boolean;
27
+ mechanism: EnforcementMechanism;
28
+ sandboxName: "sandbox-enforced-project";
29
+ locked: boolean;
30
+ createdAt: string;
31
+ updatedAt: string;
32
+ hooksInstalled: boolean;
33
+ seatbeltProfilePath: string | null;
34
+ notes: string[];
35
+ }
36
+ export interface PerfSample {
37
+ name: string;
38
+ ms: number;
39
+ detail?: string;
40
+ }
@@ -0,0 +1,3 @@
1
+ /** V3 enforcement / policy types. */
2
+ export {};
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/enforcement/types.ts"],"names":[],"mappings":"AAAA,qCAAqC"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Entitlement boundary — commercial provider plugs in without Stripe in Core.
3
+ *
4
+ * INVARIANT: recovery of already-recorded transactions is never paywalled.
5
+ * `allowUndoExisting` is always true for any valid product configuration.
6
+ */
7
+ export type EntitlementTier = "DEVELOPMENT" | "UNLICENSED" | "FREE" | "PERSONAL" | "UNKNOWN";
8
+ export interface EntitlementSnapshot {
9
+ provider: string;
10
+ tier: EntitlementTier;
11
+ /** Human-readable status for CLI/API. */
12
+ label: string;
13
+ /** Whether NEW mediated mutations may proceed. */
14
+ allowMediatedMutations: boolean;
15
+ /**
16
+ * Always true. Existing locally recorded transactions remain undoable
17
+ * regardless of subscription state. NEVER set false in product code.
18
+ */
19
+ allowUndoExisting: true;
20
+ /** ISO timestamp when checked. */
21
+ checkedAt: string;
22
+ notes: string[];
23
+ plan?: string;
24
+ offline?: boolean;
25
+ inGrace?: boolean;
26
+ expiresAt?: string;
27
+ graceUntil?: string;
28
+ }
29
+ export interface EntitlementProvider {
30
+ readonly id: string;
31
+ check(): Promise<EntitlementSnapshot>;
32
+ }
33
+ /**
34
+ * Local development provider — never locks the developer out.
35
+ */
36
+ export declare class DevelopmentEntitlementProvider implements EntitlementProvider {
37
+ readonly id = "development";
38
+ check(): Promise<EntitlementSnapshot>;
39
+ }
40
+ export declare function resolveEntitlementProvider(): Promise<EntitlementProvider>;
41
+ export declare function getEntitlementProvider(): EntitlementProvider;
42
+ export declare function setEntitlementProvider(provider: EntitlementProvider): void;
43
+ export declare function requireMediationEntitlement(): Promise<EntitlementSnapshot>;
44
+ /**
45
+ * Undo entitlement check — ALWAYS allows if we got this far.
46
+ * Exists so callers explicitly assert the invariant.
47
+ */
48
+ export declare function requireUndoEntitlement(): Promise<EntitlementSnapshot>;
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Entitlement boundary — commercial provider plugs in without Stripe in Core.
3
+ *
4
+ * INVARIANT: recovery of already-recorded transactions is never paywalled.
5
+ * `allowUndoExisting` is always true for any valid product configuration.
6
+ */
7
+ /**
8
+ * Local development provider — never locks the developer out.
9
+ */
10
+ export class DevelopmentEntitlementProvider {
11
+ id = "development";
12
+ async check() {
13
+ return {
14
+ provider: this.id,
15
+ tier: "DEVELOPMENT",
16
+ label: "DEVELOPMENT / UNLICENSED (local build)",
17
+ allowMediatedMutations: true,
18
+ allowUndoExisting: true,
19
+ checkedAt: new Date().toISOString(),
20
+ notes: [
21
+ "Development provider — full access.",
22
+ "Commercial mode: REWIND_ENTITLEMENT_MODE=signed",
23
+ "UNDO of recorded work is never paywalled.",
24
+ ],
25
+ plan: "development",
26
+ };
27
+ }
28
+ }
29
+ let activeProvider = null;
30
+ export async function resolveEntitlementProvider() {
31
+ if (activeProvider)
32
+ return activeProvider;
33
+ const mode = process.env.REWIND_ENTITLEMENT_MODE ?? "auto";
34
+ if (mode === "development") {
35
+ activeProvider = new DevelopmentEntitlementProvider();
36
+ return activeProvider;
37
+ }
38
+ if (mode === "signed" || mode === "commercial" || mode === "auto") {
39
+ // auto: use signed when credentials/session exist, else development for repo work
40
+ if (mode === "signed" || mode === "commercial") {
41
+ const { SignedEntitlementProvider } = await import("../commercial/entitlement/provider.js");
42
+ activeProvider = new SignedEntitlementProvider();
43
+ return activeProvider;
44
+ }
45
+ // auto
46
+ try {
47
+ const { loadSession } = await import("../commercial/auth/provider.js");
48
+ const session = await loadSession();
49
+ if (session || process.env.REWIND_FORCE_COMMERCIAL === "1") {
50
+ const { SignedEntitlementProvider } = await import("../commercial/entitlement/provider.js");
51
+ activeProvider = new SignedEntitlementProvider();
52
+ return activeProvider;
53
+ }
54
+ }
55
+ catch {
56
+ /* fall through */
57
+ }
58
+ }
59
+ activeProvider = new DevelopmentEntitlementProvider();
60
+ return activeProvider;
61
+ }
62
+ export function getEntitlementProvider() {
63
+ if (!activeProvider) {
64
+ activeProvider = new DevelopmentEntitlementProvider();
65
+ }
66
+ return activeProvider;
67
+ }
68
+ export function setEntitlementProvider(provider) {
69
+ activeProvider = provider;
70
+ }
71
+ export async function requireMediationEntitlement() {
72
+ const provider = await resolveEntitlementProvider();
73
+ activeProvider = provider;
74
+ const snap = await provider.check();
75
+ if (!snap.allowMediatedMutations) {
76
+ throw new Error(`Entitlement denies new mediated mutations (${snap.tier}): ${snap.label}. ` +
77
+ `Existing recorded transactions remain undoable.`);
78
+ }
79
+ return snap;
80
+ }
81
+ /**
82
+ * Undo entitlement check — ALWAYS allows if we got this far.
83
+ * Exists so callers explicitly assert the invariant.
84
+ */
85
+ export async function requireUndoEntitlement() {
86
+ const provider = await resolveEntitlementProvider();
87
+ activeProvider = provider;
88
+ const snap = await provider.check();
89
+ if (snap.allowUndoExisting !== true) {
90
+ // Should be unreachable — defend in depth
91
+ throw new Error("INTERNAL: entitlement violated allowUndoExisting invariant");
92
+ }
93
+ return snap;
94
+ }
95
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../src/entitlement/provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /** SHA-256 hex digest of a Buffer or string. */
2
+ export declare function sha256(data: Buffer | string): string;
3
+ /** SHA-256 of file contents via streaming (memory-safe for larger files). */
4
+ export declare function sha256File(absolutePath: string): Promise<string>;
5
+ /** Read file and return both contents and hash. */
6
+ export declare function readAndHash(absolutePath: string): Promise<{
7
+ data: Buffer;
8
+ hash: string;
9
+ }>;
@@ -0,0 +1,23 @@
1
+ import { createHash } from "node:crypto";
2
+ import { createReadStream } from "node:fs";
3
+ import { readFile } from "node:fs/promises";
4
+ /** SHA-256 hex digest of a Buffer or string. */
5
+ export function sha256(data) {
6
+ return createHash("sha256").update(data).digest("hex");
7
+ }
8
+ /** SHA-256 of file contents via streaming (memory-safe for larger files). */
9
+ export async function sha256File(absolutePath) {
10
+ return new Promise((resolve, reject) => {
11
+ const hash = createHash("sha256");
12
+ const stream = createReadStream(absolutePath);
13
+ stream.on("data", (chunk) => hash.update(chunk));
14
+ stream.on("error", reject);
15
+ stream.on("end", () => resolve(hash.digest("hex")));
16
+ });
17
+ }
18
+ /** Read file and return both contents and hash. */
19
+ export async function readAndHash(absolutePath) {
20
+ const data = await readFile(absolutePath);
21
+ return { data, hash: sha256(data) };
22
+ }
23
+ //# sourceMappingURL=hash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,gDAAgD;AAChD,MAAM,UAAU,MAAM,CAAC,IAAqB;IAC1C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACzD,CAAC;AAED,6EAA6E;AAC7E,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,YAAoB;IACnD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;QAClC,MAAM,MAAM,GAAG,gBAAgB,CAAC,YAAY,CAAC,CAAC;QAC9C,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACjD,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC3B,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;AACL,CAAC;AAED,mDAAmD;AACnD,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,YAAoB;IAEpB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,YAAY,CAAC,CAAC;IAC1C,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;AACtC,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Query layer over transaction history.
3
+ * Prefers V5 overlays; falls back to v2 ActionRecords.
4
+ * Append-only: never silently rewrite historical facts.
5
+ */
6
+ import { type Transaction, type TransactionStatus } from "../core/types.js";
7
+ export interface TransactionQuery {
8
+ status?: TransactionStatus | undefined;
9
+ adapter?: string | undefined;
10
+ actorClient?: string | undefined;
11
+ limit?: number | undefined;
12
+ }
13
+ export declare function listTransactions(projectRoot?: string, query?: TransactionQuery): Promise<Transaction[]>;
14
+ export declare function getTransaction(id: string, projectRoot?: string): Promise<Transaction>;
15
+ export declare function formatTransaction(txn: Transaction): string;
16
+ export declare function formatTransactionList(txns: Transaction[]): string;
17
+ export declare function ledgerStatusSummary(projectRoot?: string): Promise<string>;
18
+ /** Load raw v2 action without upgrade — for compat tests. */
19
+ export declare function loadLegacyAction(id: string, projectRoot?: string): Promise<import("../action/types.js").ActionRecord>;