@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,354 @@
1
+ import path from "node:path";
2
+ import { fileURLToPath } from "node:url";
3
+ import { realpath, lstat, access } from "node:fs/promises";
4
+ import { constants as fsConstants, existsSync, readFileSync } from "node:fs";
5
+ import os from "node:os";
6
+ /**
7
+ * Path safety for REWIND.
8
+ *
9
+ * Fail closed: only approved project-local sandboxes may be mutated
10
+ * (sandbox-test-project, sandbox-enforced-project). Checkpoint data lives
11
+ * under .rewind/ inside the *user project*, never inside the npm package.
12
+ */
13
+ export const SANDBOX_DIR_NAME = "sandbox-test-project";
14
+ export const ENFORCED_SANDBOX_DIR_NAME = "sandbox-enforced-project";
15
+ export const REWIND_DIR_NAME = ".rewind";
16
+ export const APPROVED_SANDBOX_NAMES = [
17
+ SANDBOX_DIR_NAME,
18
+ ENFORCED_SANDBOX_DIR_NAME,
19
+ ];
20
+ /**
21
+ * Absolute path to the installed REWIND *package* (read-only runtime).
22
+ * Never write user/project state here.
23
+ */
24
+ export function getPackageRoot() {
25
+ const here = path.dirname(fileURLToPath(import.meta.url));
26
+ const norm = here.replace(/\\/g, "/");
27
+ // dist/src/paths.js → package root is ../..
28
+ if (norm.endsWith("/dist/src")) {
29
+ return path.resolve(here, "../..");
30
+ }
31
+ // src/paths.ts (tsx/dev) → package root is ..
32
+ if (path.basename(here) === "src") {
33
+ return path.resolve(here, "..");
34
+ }
35
+ // Fallback: walk up for this package's package.json
36
+ let dir = here;
37
+ for (let i = 0; i < 6; i++) {
38
+ const pkg = path.join(dir, "package.json");
39
+ if (existsSync(pkg)) {
40
+ try {
41
+ const raw = JSON.parse(readFileSync(pkg, "utf8"));
42
+ if (raw.name === "@rewind-ai/cli" || raw.name === "rewind")
43
+ return dir;
44
+ }
45
+ catch {
46
+ /* continue */
47
+ }
48
+ }
49
+ const parent = path.dirname(dir);
50
+ if (parent === dir)
51
+ break;
52
+ dir = parent;
53
+ }
54
+ return path.resolve(here, "../..");
55
+ }
56
+ /**
57
+ * Absolute path to the *user project* REWIND operates on.
58
+ * Defaults to process.cwd() — never the npm package / dist tree.
59
+ */
60
+ export function getProjectRoot() {
61
+ if (process.env.REWIND_PROJECT_ROOT) {
62
+ return path.resolve(process.env.REWIND_PROJECT_ROOT);
63
+ }
64
+ return path.resolve(process.cwd());
65
+ }
66
+ /** Global user state directory (~/.rewind) — credentials, commercial, keys. */
67
+ export function getUserRewindDir(override = process.env.REWIND_USER_DIR) {
68
+ if (override)
69
+ return path.resolve(override);
70
+ return path.join(os.homedir(), ".rewind");
71
+ }
72
+ /**
73
+ * How to invoke the installed REWIND CLI (portable — no tsx / src paths).
74
+ */
75
+ export function resolveRewindCliInvocation(extraArgs = []) {
76
+ if (process.env.REWIND_BIN_PATH) {
77
+ return { command: process.env.REWIND_BIN_PATH, args: [...extraArgs] };
78
+ }
79
+ const entry = process.argv[1] ? path.resolve(process.argv[1]) : "";
80
+ if (entry.endsWith(`${path.sep}cli.js`)) {
81
+ return { command: process.execPath, args: [entry, ...extraArgs] };
82
+ }
83
+ // Dev: running via tsx src/cli.ts — prefer built dist if present
84
+ if (entry.endsWith(`${path.sep}cli.ts`)) {
85
+ const distCli = path.join(getPackageRoot(), "dist", "src", "cli.js");
86
+ if (existsSync(distCli)) {
87
+ return { command: process.execPath, args: [distCli, ...extraArgs] };
88
+ }
89
+ }
90
+ // Global / PATH install after `npm install -g @rewind-ai/cli`
91
+ return { command: "rewind", args: [...extraArgs] };
92
+ }
93
+ export function assertSandboxName(name) {
94
+ if (name === SANDBOX_DIR_NAME ||
95
+ name === ENFORCED_SANDBOX_DIR_NAME) {
96
+ return name;
97
+ }
98
+ throw new PathSafetyError(`Unknown sandbox name: ${name}`);
99
+ }
100
+ export function getSandboxPath(projectRoot = getProjectRoot(), sandboxName = SANDBOX_DIR_NAME) {
101
+ return path.join(projectRoot, assertSandboxName(sandboxName));
102
+ }
103
+ export function getEnforcedSandboxPath(projectRoot = getProjectRoot()) {
104
+ return getSandboxPath(projectRoot, ENFORCED_SANDBOX_DIR_NAME);
105
+ }
106
+ export function getPolicyDir(projectRoot = getProjectRoot()) {
107
+ return path.join(getRewindHome(projectRoot), "policy");
108
+ }
109
+ export function getTrustDir(projectRoot = getProjectRoot()) {
110
+ return path.join(getRewindHome(projectRoot), "trust");
111
+ }
112
+ export function getEnforcementDir(projectRoot = getProjectRoot()) {
113
+ return path.join(getRewindHome(projectRoot), "enforcement");
114
+ }
115
+ export function getRewindHome(projectRoot = getProjectRoot()) {
116
+ return path.join(projectRoot, REWIND_DIR_NAME);
117
+ }
118
+ export function getCheckpointsDir(projectRoot = getProjectRoot()) {
119
+ return path.join(getRewindHome(projectRoot), "checkpoints");
120
+ }
121
+ export function getTransactionsDir(projectRoot = getProjectRoot()) {
122
+ return path.join(getRewindHome(projectRoot), "transactions");
123
+ }
124
+ export function getSessionsDir(projectRoot = getProjectRoot()) {
125
+ return path.join(getRewindHome(projectRoot), "sessions");
126
+ }
127
+ export function getActionsDir(projectRoot = getProjectRoot()) {
128
+ return path.join(getRewindHome(projectRoot), "actions");
129
+ }
130
+ export function getObjectsDir(projectRoot = getProjectRoot()) {
131
+ return path.join(getRewindHome(projectRoot), "objects");
132
+ }
133
+ export function getMcpSessionsDir(projectRoot = getProjectRoot()) {
134
+ return path.join(getRewindHome(projectRoot), "mcp-sessions");
135
+ }
136
+ export class PathSafetyError extends Error {
137
+ name = "PathSafetyError";
138
+ constructor(message) {
139
+ super(message);
140
+ }
141
+ }
142
+ /** Normalize to absolute, resolved path without requiring existence. */
143
+ export function normalizeAbsolute(input) {
144
+ return path.resolve(input);
145
+ }
146
+ /**
147
+ * Returns true if `candidate` is exactly `root` or a path strictly inside it.
148
+ * Both arguments should be absolute. Does not follow symlinks.
149
+ * Also treats path strings as equal when they differ only by a shared
150
+ * realpath prefix mismatch that the caller already normalized.
151
+ */
152
+ export function isPathInside(root, candidate) {
153
+ const rootNorm = path.resolve(root);
154
+ const candNorm = path.resolve(candidate);
155
+ if (candNorm === rootNorm)
156
+ return true;
157
+ const prefix = rootNorm.endsWith(path.sep)
158
+ ? rootNorm
159
+ : rootNorm + path.sep;
160
+ return candNorm.startsWith(prefix);
161
+ }
162
+ /**
163
+ * Like isPathInside, but resolves both sides with realpath when they exist.
164
+ * Handles macOS /var vs /private/var discrepancies.
165
+ */
166
+ export async function isPathInsideAsync(root, candidate) {
167
+ if (isPathInside(root, candidate))
168
+ return true;
169
+ let realRoot = path.resolve(root);
170
+ let realCand = path.resolve(candidate);
171
+ try {
172
+ realRoot = await realpath(realRoot);
173
+ }
174
+ catch {
175
+ /* keep */
176
+ }
177
+ try {
178
+ realCand = await realpath(realCand);
179
+ }
180
+ catch {
181
+ // For non-existent candidates, realpath the parent and join basename.
182
+ try {
183
+ const parent = await realpath(path.dirname(realCand));
184
+ realCand = path.join(parent, path.basename(realCand));
185
+ }
186
+ catch {
187
+ /* keep */
188
+ }
189
+ }
190
+ return isPathInside(realRoot, realCand);
191
+ }
192
+ /** Forbidden roots that must never be targeted. */
193
+ export function getForbiddenRoots() {
194
+ const home = os.homedir();
195
+ return [
196
+ home,
197
+ path.join(home, "Desktop"),
198
+ path.join(home, "Documents"),
199
+ path.join(home, "Downloads"),
200
+ "/",
201
+ "/System",
202
+ "/Library",
203
+ "/usr",
204
+ "/bin",
205
+ "/sbin",
206
+ "/etc",
207
+ "/var",
208
+ "/private",
209
+ "/Applications",
210
+ ].map((p) => path.resolve(p));
211
+ }
212
+ /**
213
+ * Assert a relative path from sandbox has no traversal / absolute / null bytes.
214
+ * Returns a cleaned POSIX-style relative path.
215
+ */
216
+ export function assertSafeRelativePath(rel) {
217
+ if (rel.length === 0) {
218
+ throw new PathSafetyError("Empty relative path");
219
+ }
220
+ if (rel.includes("\0")) {
221
+ throw new PathSafetyError("Null byte in path");
222
+ }
223
+ if (path.isAbsolute(rel)) {
224
+ throw new PathSafetyError(`Absolute path not allowed: ${rel}`);
225
+ }
226
+ const normalized = path.posix.normalize(rel.replace(/\\/g, "/"));
227
+ if (normalized === ".." ||
228
+ normalized.startsWith("../") ||
229
+ normalized.split("/").includes("..")) {
230
+ throw new PathSafetyError(`Path traversal rejected: ${rel}`);
231
+ }
232
+ if (normalized.startsWith("./")) {
233
+ return normalized.slice(2);
234
+ }
235
+ return normalized;
236
+ }
237
+ /**
238
+ * Resolve a relative sandbox path to an absolute path and ensure it stays
239
+ * inside the approved sandbox. Does not follow the final component if it is
240
+ * a dangling symlink (uses join + resolve of parent).
241
+ */
242
+ export function resolveInsideSandbox(relativePath, sandboxRoot = getSandboxPath()) {
243
+ const safeRel = assertSafeRelativePath(relativePath);
244
+ const absolute = path.resolve(sandboxRoot, safeRel);
245
+ if (!isPathInside(sandboxRoot, absolute)) {
246
+ throw new PathSafetyError(`Resolved path escapes sandbox: ${relativePath} -> ${absolute}`);
247
+ }
248
+ return absolute;
249
+ }
250
+ /**
251
+ * Validate that `target` is exactly an approved sandbox directory
252
+ * (sandbox-test-project or sandbox-enforced-project).
253
+ * Fail closed on missing paths, wrong identity, or symlink escape.
254
+ */
255
+ export async function assertApprovedSandbox(target, projectRoot = getProjectRoot(), sandboxName) {
256
+ const targetAbs = normalizeAbsolute(target);
257
+ const basename = path.basename(targetAbs);
258
+ const resolvedName = sandboxName
259
+ ? assertSandboxName(sandboxName)
260
+ : assertSandboxName(basename);
261
+ const approvedAbs = normalizeAbsolute(getSandboxPath(projectRoot, resolvedName));
262
+ // Exact path identity (before realpath) — refuse siblings / parents.
263
+ if (targetAbs !== approvedAbs) {
264
+ throw new PathSafetyError(`Target is not the approved sandbox.\n` +
265
+ ` Target: ${targetAbs}\n` +
266
+ ` Approved: ${approvedAbs}`);
267
+ }
268
+ // Refuse if target equals a forbidden root (paranoia for misconfig).
269
+ for (const forbidden of getForbiddenRoots()) {
270
+ if (targetAbs === forbidden) {
271
+ throw new PathSafetyError(`Refusing forbidden root: ${targetAbs}`);
272
+ }
273
+ }
274
+ // Parent of sandbox must be the project root.
275
+ if (path.dirname(targetAbs) !== normalizeAbsolute(projectRoot)) {
276
+ throw new PathSafetyError(`Sandbox parent is not project root: ${path.dirname(targetAbs)}`);
277
+ }
278
+ let realTarget;
279
+ try {
280
+ await access(targetAbs, fsConstants.F_OK);
281
+ realTarget = await realpath(targetAbs);
282
+ }
283
+ catch (err) {
284
+ const code = err && typeof err === "object" && "code" in err
285
+ ? String(err.code)
286
+ : "";
287
+ if (code === "ENOENT") {
288
+ throw new PathSafetyError(`Sandbox does not exist: ${targetAbs}`);
289
+ }
290
+ throw new PathSafetyError(`Cannot access sandbox: ${targetAbs} (${String(err)})`);
291
+ }
292
+ const realApproved = await realpath(approvedAbs);
293
+ if (realTarget !== realApproved) {
294
+ throw new PathSafetyError(`Sandbox realpath mismatch (possible symlink escape).\n` +
295
+ ` Real target: ${realTarget}\n` +
296
+ ` Real approved: ${realApproved}`);
297
+ }
298
+ // Ensure resolved path still sits under project root realpath.
299
+ const realProject = await realpath(projectRoot);
300
+ if (!isPathInside(realProject, realTarget)) {
301
+ throw new PathSafetyError(`Sandbox realpath escapes project root: ${realTarget}`);
302
+ }
303
+ return {
304
+ ok: true,
305
+ target: targetAbs,
306
+ approvedSandbox: approvedAbs,
307
+ realTarget,
308
+ };
309
+ }
310
+ /**
311
+ * After resolving a path that may be a symlink, ensure the real target
312
+ * remains inside the sandbox. Used when reading/writing individual files.
313
+ */
314
+ export async function assertNoSymlinkEscape(absolutePath, sandboxRoot) {
315
+ if (!(await isPathInsideAsync(sandboxRoot, absolutePath))) {
316
+ throw new PathSafetyError(`Path outside sandbox: ${absolutePath}`);
317
+ }
318
+ let st;
319
+ try {
320
+ st = await lstat(absolutePath);
321
+ }
322
+ catch (err) {
323
+ const code = err && typeof err === "object" && "code" in err
324
+ ? String(err.code)
325
+ : "";
326
+ if (code === "ENOENT")
327
+ return; // creating new file is fine
328
+ throw err;
329
+ }
330
+ if (st.isSymbolicLink()) {
331
+ let real;
332
+ try {
333
+ real = await realpath(absolutePath);
334
+ }
335
+ catch {
336
+ // Dangling symlink: resolve the link text relative to parent.
337
+ const { readlink } = await import("node:fs/promises");
338
+ const target = await readlink(absolutePath);
339
+ real = path.resolve(path.dirname(absolutePath), target);
340
+ }
341
+ if (!(await isPathInsideAsync(sandboxRoot, real))) {
342
+ throw new PathSafetyError(`Symlink escape blocked: ${absolutePath} -> ${real}`);
343
+ }
344
+ }
345
+ }
346
+ /** Print chaos-test safety banner. Throws if not approved. */
347
+ export async function printChaosSafetyBanner(target, projectRoot = getProjectRoot()) {
348
+ const validation = await assertApprovedSandbox(target, projectRoot);
349
+ console.log("REWIND CHAOS TEST");
350
+ console.log(`Target: ${validation.target}`);
351
+ console.log("Approved sandbox: YES");
352
+ return validation;
353
+ }
354
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/paths.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Local permission decision layer.
3
+ * Default policy: ALLOW (preserves existing FS test usability).
4
+ * Evaluated BEFORE mutation.
5
+ */
6
+ import type { PermissionContext, PermissionEvaluation, PolicyDocument, PolicyRule } from "./types.js";
7
+ export declare function defaultPolicyDocument(): PolicyDocument;
8
+ export declare function policyPath(projectRoot?: string): string;
9
+ export declare function loadPolicy(projectRoot?: string): Promise<PolicyDocument>;
10
+ export declare function savePolicy(doc: PolicyDocument, projectRoot?: string): Promise<void>;
11
+ /** Glob match: ** / * / literals. Paths use POSIX separators. */
12
+ export declare function matchResourcePattern(pattern: string, resource: string): boolean;
13
+ export declare function evaluatePermission(doc: PolicyDocument, ctx: PermissionContext): PermissionEvaluation;
14
+ export declare function decidePermission(ctx: PermissionContext, projectRoot?: string): Promise<PermissionEvaluation>;
15
+ export declare function upsertRule(rule: PolicyRule, projectRoot?: string): Promise<PolicyDocument>;
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Local permission decision layer.
3
+ * Default policy: ALLOW (preserves existing FS test usability).
4
+ * Evaluated BEFORE mutation.
5
+ */
6
+ import path from "node:path";
7
+ import { mkdir, readFile, writeFile, rename } from "node:fs/promises";
8
+ import { getRewindHome, getProjectRoot } from "../paths.js";
9
+ export function defaultPolicyDocument() {
10
+ return {
11
+ version: 1,
12
+ updatedAt: new Date().toISOString(),
13
+ defaultEffect: "ALLOW",
14
+ rules: [
15
+ // Example future-shaped rules — disabled so defaults stay ALLOW.
16
+ {
17
+ id: "deny-outside-sandbox-marker",
18
+ priority: 10,
19
+ effect: "DENY",
20
+ reason: "Writes outside approved sandbox are denied by path safety (adapter); this rule is documentation-only",
21
+ adapter: "filesystem",
22
+ operation: "write",
23
+ resourcePattern: "../**",
24
+ enabled: false,
25
+ },
26
+ ],
27
+ };
28
+ }
29
+ export function policyPath(projectRoot = getProjectRoot()) {
30
+ return path.join(getRewindHome(projectRoot), "policy", "permissions.json");
31
+ }
32
+ async function writeJsonAtomic(file, data) {
33
+ await mkdir(path.dirname(file), { recursive: true });
34
+ const tmp = `${file}.tmp-${process.pid}`;
35
+ await writeFile(tmp, JSON.stringify(data, null, 2) + "\n", "utf8");
36
+ await rename(tmp, file);
37
+ }
38
+ export async function loadPolicy(projectRoot = getProjectRoot()) {
39
+ try {
40
+ const raw = await readFile(policyPath(projectRoot), "utf8");
41
+ const doc = JSON.parse(raw);
42
+ if (doc.version !== 1 || !Array.isArray(doc.rules)) {
43
+ return defaultPolicyDocument();
44
+ }
45
+ return doc;
46
+ }
47
+ catch {
48
+ return defaultPolicyDocument();
49
+ }
50
+ }
51
+ export async function savePolicy(doc, projectRoot = getProjectRoot()) {
52
+ doc.updatedAt = new Date().toISOString();
53
+ await writeJsonAtomic(policyPath(projectRoot), doc);
54
+ }
55
+ /** Glob match: ** / * / literals. Paths use POSIX separators. */
56
+ export function matchResourcePattern(pattern, resource) {
57
+ const norm = resource.replace(/\\/g, "/");
58
+ const pat = pattern.replace(/\\/g, "/");
59
+ if (pat === "**" || pat === "**/*")
60
+ return true;
61
+ // Escape regex specials except our glob tokens
62
+ let re = "";
63
+ for (let i = 0; i < pat.length; i++) {
64
+ const c = pat[i];
65
+ if (c === "*" && pat[i + 1] === "*") {
66
+ re += ".*";
67
+ i++;
68
+ if (pat[i + 1] === "/")
69
+ i++;
70
+ }
71
+ else if (c === "*") {
72
+ re += "[^/]*";
73
+ }
74
+ else if (c === "?") {
75
+ re += "[^/]";
76
+ }
77
+ else if (/[.+^${}()|[\]\\]/.test(c)) {
78
+ re += "\\" + c;
79
+ }
80
+ else {
81
+ re += c;
82
+ }
83
+ }
84
+ return new RegExp(`^${re}$`).test(norm);
85
+ }
86
+ function ruleMatches(rule, ctx) {
87
+ if (!rule.enabled)
88
+ return false;
89
+ if (rule.adapter && rule.adapter !== ctx.intent.adapter)
90
+ return false;
91
+ if (rule.operation && rule.operation !== ctx.intent.operation)
92
+ return false;
93
+ if (rule.actorClient &&
94
+ rule.actorClient !== ctx.intent.actor.client) {
95
+ return false;
96
+ }
97
+ if (rule.reversibility &&
98
+ ctx.reversibility &&
99
+ rule.reversibility !== ctx.reversibility) {
100
+ return false;
101
+ }
102
+ if (rule.risk && ctx.risk && rule.risk !== ctx.risk)
103
+ return false;
104
+ if (rule.resourcePattern) {
105
+ if (!matchResourcePattern(rule.resourcePattern, ctx.resource)) {
106
+ return false;
107
+ }
108
+ }
109
+ return true;
110
+ }
111
+ export function evaluatePermission(doc, ctx) {
112
+ const evaluatedAt = new Date().toISOString();
113
+ const rules = [...doc.rules].sort((a, b) => a.priority - b.priority);
114
+ for (const rule of rules) {
115
+ if (ruleMatches(rule, ctx)) {
116
+ return {
117
+ decision: rule.effect,
118
+ reason: rule.reason,
119
+ policyId: rule.id,
120
+ matchedRule: rule,
121
+ evaluatedAt,
122
+ };
123
+ }
124
+ }
125
+ return {
126
+ decision: doc.defaultEffect,
127
+ reason: `default:${doc.defaultEffect}`,
128
+ policyId: null,
129
+ matchedRule: null,
130
+ evaluatedAt,
131
+ };
132
+ }
133
+ export async function decidePermission(ctx, projectRoot = ctx.projectRoot) {
134
+ const doc = await loadPolicy(projectRoot);
135
+ return evaluatePermission(doc, ctx);
136
+ }
137
+ export async function upsertRule(rule, projectRoot = getProjectRoot()) {
138
+ const doc = await loadPolicy(projectRoot);
139
+ const idx = doc.rules.findIndex((r) => r.id === rule.id);
140
+ if (idx >= 0)
141
+ doc.rules[idx] = rule;
142
+ else
143
+ doc.rules.push(rule);
144
+ await savePolicy(doc, projectRoot);
145
+ return doc;
146
+ }
147
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../src/permission/engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /** Permission policy types — generic across adapters. */
2
+ import type { AdapterId, PermissionDecision, ReversibilityClass, TransactionIntent } from "../core/types.js";
3
+ export type PolicyEffect = PermissionDecision;
4
+ export interface PolicyRule {
5
+ id: string;
6
+ /** Lower number = higher priority. First match wins. */
7
+ priority: number;
8
+ effect: PolicyEffect;
9
+ reason: string;
10
+ /** Match filters — omitted means any. */
11
+ actorClient?: string | null | undefined;
12
+ adapter?: AdapterId | null | undefined;
13
+ operation?: string | null | undefined;
14
+ /** Glob-like path/resource pattern (**, *, literal). */
15
+ resourcePattern?: string | null | undefined;
16
+ reversibility?: ReversibilityClass | null | undefined;
17
+ /** Optional risk tag match. */
18
+ risk?: string | null | undefined;
19
+ enabled: boolean;
20
+ }
21
+ export interface PolicyDocument {
22
+ version: 1;
23
+ updatedAt: string;
24
+ /** Default when no rule matches. */
25
+ defaultEffect: PolicyEffect;
26
+ rules: PolicyRule[];
27
+ }
28
+ export interface PermissionEvaluation {
29
+ decision: PermissionDecision;
30
+ reason: string;
31
+ policyId: string | null;
32
+ matchedRule: PolicyRule | null;
33
+ evaluatedAt: string;
34
+ }
35
+ export interface PermissionContext {
36
+ intent: TransactionIntent;
37
+ projectRoot: string;
38
+ /** Resource path already identified by adapter. */
39
+ resource: string;
40
+ risk?: string;
41
+ reversibility?: ReversibilityClass;
42
+ }
@@ -0,0 +1,3 @@
1
+ /** Permission policy types — generic across adapters. */
2
+ export {};
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/permission/types.ts"],"names":[],"mappings":"AAAA,yDAAyD"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Product setup / doctor / uninstall / open — user-facing install path.
3
+ */
4
+ export declare const PRODUCT_VERSION = "0.6.2";
5
+ export interface DoctorCheck {
6
+ id: string;
7
+ status: "PASS" | "WARN" | "FAIL";
8
+ title: string;
9
+ detail: string;
10
+ }
11
+ export interface ProjectConfig {
12
+ version: 6;
13
+ initializedAt: string;
14
+ projectRoot: string;
15
+ product: "REWIND Personal";
16
+ mediation: "connected";
17
+ notes: string[];
18
+ }
19
+ export declare function loadProjectConfig(projectRoot?: string): Promise<ProjectConfig | null>;
20
+ export declare function runSetup(projectRoot?: string, opts?: {
21
+ skipMcp?: boolean;
22
+ skipSandbox?: boolean;
23
+ }): Promise<string>;
24
+ export declare function runDoctor(projectRoot?: string): Promise<{
25
+ checks: DoctorCheck[];
26
+ text: string;
27
+ }>;
28
+ export interface UninstallOptions {
29
+ /** Delete .rewind recovery data — requires explicit true */
30
+ deleteRecoveryData?: boolean;
31
+ removeMcp?: boolean;
32
+ projectRoot?: string;
33
+ }
34
+ export declare function runUninstall(opts?: UninstallOptions): Promise<string>;
35
+ export declare function versionText(): string;